summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-01-02 00:34:47 -0500
committerjoe <joe@jerkface.net>2017-01-02 00:37:07 -0500
commit5c2140807ceaa97a90c947437ecf5ef225f27c8d (patch)
tree650b6021af1b4c7a6c00ab4e5567424db959ece0 /src/Network/BitTorrent
parent80c860df8c29f99e0a82b454c1c0f0c6902764ef (diff)
Parse IPv4 addresses even when using variadic IP type.
Diffstat (limited to 'src/Network/BitTorrent')
-rw-r--r--src/Network/BitTorrent/Address.hs8
-rw-r--r--src/Network/BitTorrent/DHT/Message.hs13
2 files changed, 15 insertions, 6 deletions
diff --git a/src/Network/BitTorrent/Address.hs b/src/Network/BitTorrent/Address.hs
index 8dbe1583..c0c0a3f8 100644
--- a/src/Network/BitTorrent/Address.hs
+++ b/src/Network/BitTorrent/Address.hs
@@ -18,6 +18,8 @@
18{-# LANGUAGE MultiParamTypeClasses #-} 18{-# LANGUAGE MultiParamTypeClasses #-}
19{-# LANGUAGE DeriveDataTypeable #-} 19{-# LANGUAGE DeriveDataTypeable #-}
20{-# LANGUAGE DeriveFunctor #-} 20{-# LANGUAGE DeriveFunctor #-}
21{-# LANGUAGE DeriveFoldable #-}
22{-# LANGUAGE DeriveTraversable #-}
21{-# LANGUAGE TemplateHaskell #-} 23{-# LANGUAGE TemplateHaskell #-}
22{-# OPTIONS -fno-warn-orphans #-} 24{-# OPTIONS -fno-warn-orphans #-}
23module Network.BitTorrent.Address 25module Network.BitTorrent.Address
@@ -443,7 +445,7 @@ instance Serialize IP where
443 case n of 445 case n of
444 4 -> IPv4 <$> get 446 4 -> IPv4 <$> get
445 16 -> IPv6 <$> get 447 16 -> IPv6 <$> get
446 _ -> fail "Wrong number of bytes remaining to parse IP" 448 _ -> fail (show n ++ " is the wrong number of remaining bytes to parse IP")
447 449
448instance Serialize IPv4 where 450instance Serialize IPv4 where
449 put = putWord32host . toHostAddress 451 put = putWord32host . toHostAddress
@@ -693,7 +695,7 @@ distance (NodeId a) (NodeId b) = NodeDistance (BS.pack (BS.zipWith xor a b))
693data NodeAddr a = NodeAddr 695data NodeAddr a = NodeAddr
694 { nodeHost :: !a 696 { nodeHost :: !a
695 , nodePort :: {-# UNPACK #-} !PortNumber 697 , nodePort :: {-# UNPACK #-} !PortNumber
696 } deriving (Eq, Typeable, Functor) 698 } deriving (Eq, Typeable, Functor, Foldable, Traversable)
697 699
698instance Show a => Show (NodeAddr a) where 700instance Show a => Show (NodeAddr a) where
699 showsPrec i NodeAddr {..} 701 showsPrec i NodeAddr {..}
@@ -745,7 +747,7 @@ fromPeerAddr PeerAddr {..} = NodeAddr
745data NodeInfo a = NodeInfo 747data NodeInfo a = NodeInfo
746 { nodeId :: !NodeId 748 { nodeId :: !NodeId
747 , nodeAddr :: !(NodeAddr a) 749 , nodeAddr :: !(NodeAddr a)
748 } deriving (Show, Eq, Functor) 750 } deriving (Show, Eq, Functor, Foldable, Traversable)
749 751
750instance Eq a => Ord (NodeInfo a) where 752instance Eq a => Ord (NodeInfo a) where
751 compare = comparing nodeId 753 compare = comparing nodeId
diff --git a/src/Network/BitTorrent/DHT/Message.hs b/src/Network/BitTorrent/DHT/Message.hs
index 145141ee..008145de 100644
--- a/src/Network/BitTorrent/DHT/Message.hs
+++ b/src/Network/BitTorrent/DHT/Message.hs
@@ -59,6 +59,7 @@
59{-# LANGUAGE FlexibleInstances #-} 59{-# LANGUAGE FlexibleInstances #-}
60{-# LANGUAGE MultiParamTypeClasses #-} 60{-# LANGUAGE MultiParamTypeClasses #-}
61{-# LANGUAGE UndecidableInstances #-} 61{-# LANGUAGE UndecidableInstances #-}
62{-# LANGUAGE ScopedTypeVariables #-}
62module Network.BitTorrent.DHT.Message 63module Network.BitTorrent.DHT.Message
63 ( -- * Envelopes 64 ( -- * Envelopes
64 Query (..) 65 Query (..)
@@ -184,21 +185,27 @@ newtype NodeFound ip = NodeFound [NodeInfo ip]
184nodes_key :: BKey 185nodes_key :: BKey
185nodes_key = "nodes" 186nodes_key = "nodes"
186 187
188-- Convert IPv4 address. Useful for using variadic IP type.
189from4 :: forall s. Address s => NodeInfo IPv4 -> Either String (NodeInfo s)
190from4 n = maybe (Left "Error converting IPv4") Right
191 $ traverse (fromAddr :: IPv4 -> Maybe s) n
192
187binary :: Serialize a => BKey -> BE.Get [a] 193binary :: Serialize a => BKey -> BE.Get [a]
188binary k = field (req k) >>= either (fail . format) return . 194binary k = field (req k) >>= either (fail . format) return .
189 runGet (many get) 195 runGet (many get)
190 where 196 where
191 format str = "fail to deserialize " ++ show k ++ " field: " ++ str 197 format str = "fail to deserialize " ++ show k ++ " field: " ++ str
192 198
193instance (Typeable ip, Serialize ip) => BEncode (NodeFound ip) where 199instance (Typeable ip, Address ip) => BEncode (NodeFound ip) where
194 toBEncode (NodeFound ns) = toDict $ 200 toBEncode (NodeFound ns) = toDict $
195 nodes_key .=! runPut (mapM_ put ns) 201 nodes_key .=! runPut (mapM_ put ns)
196 .: endDict 202 .: endDict
197 203
198 fromBEncode = fromDict $ NodeFound <$> binary nodes_key 204 -- TODO: handle IPv6 by reading the "nodes6" key (see bep 32)
205 fromBEncode bval = NodeFound <$> (traverse from4 =<< fromDict (binary nodes_key) bval)
199 206
200-- | \"q\" == \"find_node\" 207-- | \"q\" == \"find_node\"
201instance (Serialize ip, Typeable ip) 208instance (Address ip, Typeable ip)
202 => KRPC (Query FindNode) (Response (NodeFound ip)) where 209 => KRPC (Query FindNode) (Response (NodeFound ip)) where
203 method = "find_node" 210 method = "find_node"
204 211