diff options
Diffstat (limited to 'src/Network/BitTorrent/Core.hs')
-rw-r--r-- | src/Network/BitTorrent/Core.hs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/Network/BitTorrent/Core.hs b/src/Network/BitTorrent/Core.hs index 9cfb3dd7..6024f5a5 100644 --- a/src/Network/BitTorrent/Core.hs +++ b/src/Network/BitTorrent/Core.hs | |||
@@ -9,6 +9,7 @@ | |||
9 | -- | 9 | -- |
10 | module Network.BitTorrent.Core | 10 | module Network.BitTorrent.Core |
11 | ( module Core | 11 | ( module Core |
12 | , Address (..) | ||
12 | 13 | ||
13 | -- * Re-exports from Data.IP | 14 | -- * Re-exports from Data.IP |
14 | , IPv4 | 15 | , IPv4 |
@@ -16,9 +17,58 @@ module Network.BitTorrent.Core | |||
16 | , IP (..) | 17 | , IP (..) |
17 | ) where | 18 | ) where |
18 | 19 | ||
20 | import Control.Applicative | ||
19 | import Data.IP | 21 | import Data.IP |
22 | import Data.Serialize | ||
23 | import Data.Typeable | ||
24 | import Network.Socket (SockAddr (..), PortNumber) | ||
20 | 25 | ||
21 | import Network.BitTorrent.Core.Fingerprint as Core | 26 | import Network.BitTorrent.Core.Fingerprint as Core |
22 | import Network.BitTorrent.Core.Node as Core | 27 | import Network.BitTorrent.Core.Node as Core |
23 | import Network.BitTorrent.Core.PeerId as Core | 28 | import Network.BitTorrent.Core.PeerId as Core |
24 | import Network.BitTorrent.Core.PeerAddr as Core | 29 | import Network.BitTorrent.Core.PeerAddr as Core |
30 | |||
31 | |||
32 | class (Eq a, Serialize a, Typeable a) => Address a where | ||
33 | toSockAddr :: a -> SockAddr | ||
34 | fromSockAddr :: SockAddr -> Maybe a | ||
35 | |||
36 | -- | Note that port is zeroed. | ||
37 | instance Address IPv4 where | ||
38 | toSockAddr = SockAddrInet 0 . toHostAddress | ||
39 | fromSockAddr (SockAddrInet _ h) = Just (fromHostAddress h) | ||
40 | fromSockAddr _ = Nothing | ||
41 | |||
42 | -- | Note that port is zeroed. | ||
43 | instance Address IPv6 where | ||
44 | toSockAddr h = SockAddrInet6 0 0 (toHostAddress6 h) 0 | ||
45 | fromSockAddr (SockAddrInet6 _ _ h _) = Just (fromHostAddress6 h) | ||
46 | fromSockAddr _ = Nothing | ||
47 | |||
48 | -- | Note that port is zeroed. | ||
49 | instance Address IP where | ||
50 | toSockAddr (IPv4 h) = toSockAddr h | ||
51 | toSockAddr (IPv6 h) = toSockAddr h | ||
52 | fromSockAddr sa = | ||
53 | IPv4 <$> fromSockAddr sa | ||
54 | <|> IPv6 <$> fromSockAddr sa | ||
55 | |||
56 | setPort :: PortNumber -> SockAddr -> SockAddr | ||
57 | setPort port (SockAddrInet _ h ) = SockAddrInet port h | ||
58 | setPort port (SockAddrInet6 _ f h s) = SockAddrInet6 port f h s | ||
59 | setPort _ (SockAddrUnix s ) = SockAddrUnix s | ||
60 | {-# INLINE setPort #-} | ||
61 | |||
62 | getPort :: SockAddr -> Maybe PortNumber | ||
63 | getPort (SockAddrInet p _ ) = Just p | ||
64 | getPort (SockAddrInet6 p _ _ _) = Just p | ||
65 | getPort (SockAddrUnix _ ) = Nothing | ||
66 | {-# INLINE getPort #-} | ||
67 | |||
68 | instance Address a => Address (NodeAddr a) where | ||
69 | toSockAddr NodeAddr {..} = setPort nodePort $ toSockAddr nodeHost | ||
70 | fromSockAddr sa = NodeAddr <$> fromSockAddr sa <*> getPort sa | ||
71 | |||
72 | instance Address a => Address (PeerAddr a) where | ||
73 | toSockAddr PeerAddr {..} = setPort peerPort $ toSockAddr peerHost | ||
74 | fromSockAddr sa = PeerAddr Nothing <$> fromSockAddr sa <*> getPort sa | ||