diff options
author | joe <joe@jerkface.net> | 2017-01-02 00:34:47 -0500 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-01-02 00:37:07 -0500 |
commit | 5c2140807ceaa97a90c947437ecf5ef225f27c8d (patch) | |
tree | 650b6021af1b4c7a6c00ab4e5567424db959ece0 /src/Network/BitTorrent | |
parent | 80c860df8c29f99e0a82b454c1c0f0c6902764ef (diff) |
Parse IPv4 addresses even when using variadic IP type.
Diffstat (limited to 'src/Network/BitTorrent')
-rw-r--r-- | src/Network/BitTorrent/Address.hs | 8 | ||||
-rw-r--r-- | src/Network/BitTorrent/DHT/Message.hs | 13 |
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 #-} |
23 | module Network.BitTorrent.Address | 25 | module 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 | ||
448 | instance Serialize IPv4 where | 450 | instance 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)) | |||
693 | data NodeAddr a = NodeAddr | 695 | data 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 | ||
698 | instance Show a => Show (NodeAddr a) where | 700 | instance Show a => Show (NodeAddr a) where |
699 | showsPrec i NodeAddr {..} | 701 | showsPrec i NodeAddr {..} |
@@ -745,7 +747,7 @@ fromPeerAddr PeerAddr {..} = NodeAddr | |||
745 | data NodeInfo a = NodeInfo | 747 | data 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 | ||
750 | instance Eq a => Ord (NodeInfo a) where | 752 | instance 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 #-} | ||
62 | module Network.BitTorrent.DHT.Message | 63 | module Network.BitTorrent.DHT.Message |
63 | ( -- * Envelopes | 64 | ( -- * Envelopes |
64 | Query (..) | 65 | Query (..) |
@@ -184,21 +185,27 @@ newtype NodeFound ip = NodeFound [NodeInfo ip] | |||
184 | nodes_key :: BKey | 185 | nodes_key :: BKey |
185 | nodes_key = "nodes" | 186 | nodes_key = "nodes" |
186 | 187 | ||
188 | -- Convert IPv4 address. Useful for using variadic IP type. | ||
189 | from4 :: forall s. Address s => NodeInfo IPv4 -> Either String (NodeInfo s) | ||
190 | from4 n = maybe (Left "Error converting IPv4") Right | ||
191 | $ traverse (fromAddr :: IPv4 -> Maybe s) n | ||
192 | |||
187 | binary :: Serialize a => BKey -> BE.Get [a] | 193 | binary :: Serialize a => BKey -> BE.Get [a] |
188 | binary k = field (req k) >>= either (fail . format) return . | 194 | binary 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 | ||
193 | instance (Typeable ip, Serialize ip) => BEncode (NodeFound ip) where | 199 | instance (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\" |
201 | instance (Serialize ip, Typeable ip) | 208 | instance (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 | ||