diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2013-12-26 00:47:10 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2013-12-26 00:47:10 +0400 |
commit | b4d3b295f75538234d82025617bc7cad6b4e9d19 (patch) | |
tree | a28645ff75566e4cd681006d820059d944aba8cc /src | |
parent | 70aa9d716fe82b1f4d603b67fedae3241e3784f6 (diff) |
Add IsString instance to NodeInfos
Diffstat (limited to 'src')
-rw-r--r-- | src/Network/BitTorrent/Core/Node.hs | 58 | ||||
-rw-r--r-- | src/Network/BitTorrent/Core/PeerAddr.hs | 1 |
2 files changed, 54 insertions, 5 deletions
diff --git a/src/Network/BitTorrent/Core/Node.hs b/src/Network/BitTorrent/Core/Node.hs index 0cb95dd2..f6ab7d82 100644 --- a/src/Network/BitTorrent/Core/Node.hs +++ b/src/Network/BitTorrent/Core/Node.hs | |||
@@ -1,4 +1,21 @@ | |||
1 | -- | | ||
2 | -- Module : Network.BitTorrent.Core.Node | ||
3 | -- Copyright : (c) Sam Truzjan 2013 | ||
4 | -- (c) Daniel Gröber 2013 | ||
5 | -- License : BSD3 | ||
6 | -- Maintainer : pxqr.sta@gmail.com | ||
7 | -- Stability : experimental | ||
8 | -- Portability : portable | ||
9 | -- | ||
10 | -- A \"node\" is a client\/server listening on a UDP port | ||
11 | -- implementing the distributed hash table protocol. The DHT is | ||
12 | -- composed of nodes and stores the location of peers. BitTorrent | ||
13 | -- clients include a DHT node, which is used to contact other nodes | ||
14 | -- in the DHT to get the location of peers to download from using | ||
15 | -- the BitTorrent protocol. | ||
16 | -- | ||
1 | {-# LANGUAGE RecordWildCards #-} | 17 | {-# LANGUAGE RecordWildCards #-} |
18 | {-# LANGUAGE FlexibleInstances #-} | ||
2 | {-# LANGUAGE TemplateHaskell #-} | 19 | {-# LANGUAGE TemplateHaskell #-} |
3 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} | 20 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} |
4 | {-# LANGUAGE DeriveDataTypeable #-} | 21 | {-# LANGUAGE DeriveDataTypeable #-} |
@@ -22,23 +39,29 @@ import Data.Bits | |||
22 | import Data.ByteString as BS | 39 | import Data.ByteString as BS |
23 | import Data.BEncode as BE | 40 | import Data.BEncode as BE |
24 | import Data.Default | 41 | import Data.Default |
42 | import Data.IP | ||
43 | import Data.List as L | ||
25 | import Data.Ord | 44 | import Data.Ord |
26 | import Data.Typeable | ||
27 | import Data.Serialize as S | 45 | import Data.Serialize as S |
46 | import Data.String | ||
47 | import Data.Typeable | ||
28 | import Data.Word | 48 | import Data.Word |
29 | import Network | 49 | import Network |
30 | import System.Entropy | 50 | import System.Entropy |
31 | 51 | ||
32 | import Data.Torrent.JSON | 52 | import Data.Torrent.JSON |
33 | import Network.BitTorrent.Core.PeerAddr () | 53 | import Network.BitTorrent.Core.PeerAddr (PeerAddr (..)) |
34 | 54 | ||
35 | {----------------------------------------------------------------------- | 55 | {----------------------------------------------------------------------- |
36 | -- Node id | 56 | -- Node id |
37 | -----------------------------------------------------------------------} | 57 | -----------------------------------------------------------------------} |
38 | -- TODO more compact representation ('ShortByteString's?) | 58 | -- TODO more compact representation ('ShortByteString's?) |
39 | 59 | ||
40 | -- | Normally, /this/ node id should we saved between invocations of | 60 | -- | Each node has a globally unique identifier known as the \"node |
41 | -- the client software. | 61 | -- ID.\" |
62 | -- | ||
63 | -- Normally, /this/ node id should we saved between invocations | ||
64 | -- of the client software. | ||
42 | newtype NodeId = NodeId ByteString | 65 | newtype NodeId = NodeId ByteString |
43 | deriving (Show, Eq, Ord, BEncode, FromJSON, ToJSON, Typeable) | 66 | deriving (Show, Eq, Ord, BEncode, FromJSON, ToJSON, Typeable) |
44 | 67 | ||
@@ -55,6 +78,13 @@ instance Serialize NodeId where | |||
55 | put (NodeId bs) = putByteString bs | 78 | put (NodeId bs) = putByteString bs |
56 | {-# INLINE put #-} | 79 | {-# INLINE put #-} |
57 | 80 | ||
81 | -- | ASCII encoded. | ||
82 | instance IsString NodeId where | ||
83 | fromString str | ||
84 | | L.length str == nodeIdSize = NodeId (fromString str) | ||
85 | | otherwise = error "fromString: invalid NodeId length" | ||
86 | {-# INLINE fromString #-} | ||
87 | |||
58 | -- | Test if the nth bit is set. | 88 | -- | Test if the nth bit is set. |
59 | testIdBit :: NodeId -> Word -> Bool | 89 | testIdBit :: NodeId -> Word -> Bool |
60 | testIdBit (NodeId bs) i | 90 | testIdBit (NodeId bs) i |
@@ -85,7 +115,9 @@ $(deriveJSON omitRecordPrefix ''NodeAddr) | |||
85 | -- | KRPC compatible encoding. | 115 | -- | KRPC compatible encoding. |
86 | instance Serialize a => Serialize (NodeAddr a) where | 116 | instance Serialize a => Serialize (NodeAddr a) where |
87 | get = NodeAddr <$> get <*> get | 117 | get = NodeAddr <$> get <*> get |
118 | {-# INLINE get #-} | ||
88 | put NodeAddr {..} = put nodeHost >> put nodePort | 119 | put NodeAddr {..} = put nodeHost >> put nodePort |
120 | {-# INLINE put #-} | ||
89 | 121 | ||
90 | -- | Torrent file compatible encoding. | 122 | -- | Torrent file compatible encoding. |
91 | instance BEncode a => BEncode (NodeAddr a) where | 123 | instance BEncode a => BEncode (NodeAddr a) where |
@@ -94,6 +126,19 @@ instance BEncode a => BEncode (NodeAddr a) where | |||
94 | fromBEncode b = uncurry NodeAddr <$> fromBEncode b | 126 | fromBEncode b = uncurry NodeAddr <$> fromBEncode b |
95 | {-# INLINE fromBEncode #-} | 127 | {-# INLINE fromBEncode #-} |
96 | 128 | ||
129 | -- | Example: | ||
130 | -- | ||
131 | -- @nodePort \"127.0.0.1:6881\" == 6881@ | ||
132 | -- | ||
133 | instance IsString (NodeAddr IPv4) where | ||
134 | fromString = fromPeerAddr . fromString | ||
135 | |||
136 | fromPeerAddr :: PeerAddr a -> NodeAddr a | ||
137 | fromPeerAddr PeerAddr {..} = NodeAddr | ||
138 | { nodeHost = peerHost | ||
139 | , nodePort = peerPort | ||
140 | } | ||
141 | |||
97 | {----------------------------------------------------------------------- | 142 | {----------------------------------------------------------------------- |
98 | -- Node info | 143 | -- Node info |
99 | -----------------------------------------------------------------------} | 144 | -----------------------------------------------------------------------} |
@@ -108,7 +153,10 @@ $(deriveJSON omitRecordPrefix ''NodeInfo) | |||
108 | instance Eq a => Ord (NodeInfo a) where | 153 | instance Eq a => Ord (NodeInfo a) where |
109 | compare = comparing nodeId | 154 | compare = comparing nodeId |
110 | 155 | ||
111 | -- | KRPC 'compact list' compatible encoding. | 156 | -- | KRPC 'compact list' compatible encoding: contact information for |
157 | -- nodes is encoded as a 26-byte string. Also known as "Compact node | ||
158 | -- info" the 20-byte Node ID in network byte order has the compact | ||
159 | -- IP-address/port info concatenated to the end. | ||
112 | instance Serialize a => Serialize (NodeInfo a) where | 160 | instance Serialize a => Serialize (NodeInfo a) where |
113 | get = NodeInfo <$> get <*> get | 161 | get = NodeInfo <$> get <*> get |
114 | put NodeInfo {..} = put nodeId >> put nodeAddr | 162 | put NodeInfo {..} = put nodeId >> put nodeAddr |
diff --git a/src/Network/BitTorrent/Core/PeerAddr.hs b/src/Network/BitTorrent/Core/PeerAddr.hs index 86b88491..63ae04b9 100644 --- a/src/Network/BitTorrent/Core/PeerAddr.hs +++ b/src/Network/BitTorrent/Core/PeerAddr.hs | |||
@@ -1,4 +1,5 @@ | |||
1 | -- | | 1 | -- | |
2 | -- Module : Network.BitTorrent.Core.PeerAddr | ||
2 | -- Copyright : (c) Sam Truzjan 2013 | 3 | -- Copyright : (c) Sam Truzjan 2013 |
3 | -- (c) Daniel Gröber 2013 | 4 | -- (c) Daniel Gröber 2013 |
4 | -- License : BSD3 | 5 | -- License : BSD3 |