diff options
-rw-r--r-- | bittorrent.cabal | 1 | ||||
-rw-r--r-- | examples/dhtd.hs | 66 | ||||
-rw-r--r-- | src/Network/BitTorrent/DHT/Query.hs | 1 | ||||
-rw-r--r-- | src/Network/DatagramServer/Tox.hs | 8 |
4 files changed, 61 insertions, 15 deletions
diff --git a/bittorrent.cabal b/bittorrent.cabal index c46ed17f..936b022a 100644 --- a/bittorrent.cabal +++ b/bittorrent.cabal | |||
@@ -395,6 +395,7 @@ executable dhtd | |||
395 | , stm | 395 | , stm |
396 | , cereal | 396 | , cereal |
397 | , bencoding | 397 | , bencoding |
398 | , random | ||
398 | if flag(thread-debug) | 399 | if flag(thread-debug) |
399 | build-depends: time | 400 | build-depends: time |
400 | cpp-options: -DTHREAD_DEBUG | 401 | cpp-options: -DTHREAD_DEBUG |
diff --git a/examples/dhtd.hs b/examples/dhtd.hs index 3fca5482..4c8cefb5 100644 --- a/examples/dhtd.hs +++ b/examples/dhtd.hs | |||
@@ -68,6 +68,7 @@ import Network.KRPC.Method | |||
68 | import Data.Typeable | 68 | import Data.Typeable |
69 | import GHC.Generics | 69 | import GHC.Generics |
70 | import Data.Bool | 70 | import Data.Bool |
71 | import System.Random | ||
71 | 72 | ||
72 | mkNodeAddr :: SockAddr -> NodeAddr IPv4 | 73 | mkNodeAddr :: SockAddr -> NodeAddr IPv4 |
73 | mkNodeAddr addr = NodeAddr (fromJust $ fromSockAddr addr) | 74 | mkNodeAddr addr = NodeAddr (fromJust $ fromSockAddr addr) |
@@ -252,23 +253,66 @@ instance Serialize (Response Tox.Message (Ping Tox.Message)) where | |||
252 | get = getToxPing True Network.DHT.Types.Response Tox.ResponseNonce | 253 | get = getToxPing True Network.DHT.Types.Response Tox.ResponseNonce |
253 | put (Network.DHT.Types.Response extra Ping) = putToxPing True (Tox.rspNonce extra) | 254 | put (Network.DHT.Types.Response extra Ping) = putToxPing True (Tox.rspNonce extra) |
254 | 255 | ||
255 | instance Serialize (Query Tox.Message (FindNode Tox.Message IPv4)) where | 256 | nodeFormatToNodeInfo nf = NodeInfo nid addr u |
256 | get = error "TODO get 7" | 257 | where |
257 | put = error "TODO put 8" | 258 | u = Tox.nodeIsTCP nf |
259 | addr = NodeAddr (Tox.nodeIP nf) (Tox.nodePort nf) | ||
260 | nid = Tox.nodePublicKey nf | ||
261 | |||
262 | instance Serialize (Query Tox.Message (FindNode Tox.Message ip)) where | ||
263 | get = do | ||
264 | nid <- get | ||
265 | n8 <- get | ||
266 | return $ Network.DHT.Types.Query (Tox.QueryNonce n8) (FindNode nid) | ||
267 | put (Network.DHT.Types.Query (Tox.QueryNonce n8) (FindNode nid)) = do | ||
268 | put nid | ||
269 | put n8 | ||
258 | instance Serialize (Response Tox.Message (NodeFound Tox.Message IPv4)) where | 270 | instance Serialize (Response Tox.Message (NodeFound Tox.Message IPv4)) where |
259 | get = error "TODO get 11" | 271 | get = do |
260 | put = error "TODO put 12" | 272 | num <- get :: Get Word8 |
273 | when (num > 4) $ fail "Too many nodes in Tox get-nodes reply" | ||
274 | ns0 <- sequence $ replicate (fromIntegral num) (nodeFormatToNodeInfo <$> get) | ||
275 | -- TODO: Allow tcp and ipv6. For now filtering to udp ip4... | ||
276 | let ns = flip mapMaybe ns0 $ \(NodeInfo nid addr u) -> do | ||
277 | guard $ not u | ||
278 | ip4 <- fromAddr addr | ||
279 | return $ NodeInfo nid ip4 () | ||
280 | n8 <- get | ||
281 | return $ Network.DHT.Types.Response (Tox.ResponseNonce n8) $ NodeFound ns | ||
282 | put (Network.DHT.Types.Response (Tox.ResponseNonce n8) (NodeFound ns)) = do | ||
283 | put ( fromIntegral (length ns) :: Word8 ) | ||
284 | forM_ ns $ \(NodeInfo nid ip4 ()) -> do | ||
285 | put Tox.NodeFormat { nodePublicKey = nid | ||
286 | , nodeIsTCP = False | ||
287 | , nodeIP = IPv4 (nodeHost ip4) | ||
288 | , nodePort = nodePort ip4 | ||
289 | } | ||
290 | put n8 | ||
291 | |||
292 | validateToxExchange q r = qnonce == rnonce | ||
293 | where | ||
294 | qnonce = Tox.qryNonce . queryExtra . Tox.msgPayload $ q | ||
295 | rnonce = Tox.rspNonce . responseExtra . Tox.msgPayload $ r | ||
261 | 296 | ||
262 | instance KRPC Tox.Message (Query Tox.Message (FindNode Tox.Message IPv4)) | 297 | instance KRPC Tox.Message (Query Tox.Message (FindNode Tox.Message IPv4)) |
263 | (Response Tox.Message (NodeFound Tox.Message IPv4)) where | 298 | (Response Tox.Message (NodeFound Tox.Message IPv4)) where |
264 | method = error "TODO method 15" | 299 | method = Method Tox.GetNodes |
300 | validateExchange = validateToxExchange | ||
301 | makeQueryExtra _ _ _ _ = Tox.QueryNonce <$> randomIO | ||
302 | makeResponseExtra _ _ q _ = return $ Tox.ResponseNonce $ Tox.qryNonce $ queryExtra q | ||
303 | messageSender q _ = Tox.msgClient q | ||
304 | messageResponder _ r = Tox.msgClient r | ||
305 | |||
265 | instance KRPC Tox.Message (Query Tox.Message (Ping Tox.Message)) | 306 | instance KRPC Tox.Message (Query Tox.Message (Ping Tox.Message)) |
266 | (Response Tox.Message (Ping Tox.Message)) where | 307 | (Response Tox.Message (Ping Tox.Message)) where |
267 | method = error "TODO method 16" | 308 | method = Method Tox.Ping |
268 | instance DataHandlers ByteString Tox.Message where | 309 | validateExchange = validateToxExchange |
269 | 310 | makeQueryExtra _ _ _ _ = Tox.QueryNonce <$> randomIO | |
270 | 311 | makeResponseExtra _ _ q _ = return $ Tox.ResponseNonce $ Tox.qryNonce $ queryExtra q | |
271 | -- instance Generic (Response Tox.Message (NodeFound Tox.Message IPv4)) where -- TODO | 312 | messageSender q _ = Tox.msgClient q |
313 | messageResponder _ r = Tox.msgClient r | ||
314 | |||
315 | instance DataHandlers ByteString Tox.Message | ||
272 | 316 | ||
273 | instance Default Bool where def = False | 317 | instance Default Bool where def = False |
274 | 318 | ||
diff --git a/src/Network/BitTorrent/DHT/Query.hs b/src/Network/BitTorrent/DHT/Query.hs index 330b5478..ad29adb6 100644 --- a/src/Network/BitTorrent/DHT/Query.hs +++ b/src/Network/BitTorrent/DHT/Query.hs | |||
@@ -232,6 +232,7 @@ class DataHandlers raw dht where | |||
232 | (NodeId dht -> IO [NodeInfo dht ip ()]) | 232 | (NodeId dht -> IO [NodeInfo dht ip ()]) |
233 | -> DHTData dht ip | 233 | -> DHTData dht ip |
234 | -> [MethodHandler raw dht ip] | 234 | -> [MethodHandler raw dht ip] |
235 | dataHandlers _ _ = [] | ||
235 | 236 | ||
236 | instance DataHandlers BValue KMessageOf where | 237 | instance DataHandlers BValue KMessageOf where |
237 | dataHandlers = bthandlers | 238 | dataHandlers = bthandlers |
diff --git a/src/Network/DatagramServer/Tox.hs b/src/Network/DatagramServer/Tox.hs index 83701b6b..3a6135cc 100644 --- a/src/Network/DatagramServer/Tox.hs +++ b/src/Network/DatagramServer/Tox.hs | |||
@@ -37,7 +37,7 @@ type Nonce24 = Word192 -- 24 bytes | |||
37 | 37 | ||
38 | 38 | ||
39 | data NodeFormat = NodeFormat | 39 | data NodeFormat = NodeFormat |
40 | { nodePublicKey :: Key32 -- 32 byte public key | 40 | { nodePublicKey :: NodeId Message -- 32 byte public key |
41 | , nodeIsTCP :: Bool -- This has no analog in mainline NodeInfo structure | 41 | , nodeIsTCP :: Bool -- This has no analog in mainline NodeInfo structure |
42 | , nodeIP :: IP -- IPv4 or IPv6 address | 42 | , nodeIP :: IP -- IPv4 or IPv6 address |
43 | , nodePort :: PortNumber | 43 | , nodePort :: PortNumber |
@@ -149,10 +149,10 @@ instance Serialize NodeFormat where | |||
149 | return $ NodeFormat { nodeIsTCP = istcp | 149 | return $ NodeFormat { nodeIsTCP = istcp |
150 | , nodeIP = ip | 150 | , nodeIP = ip |
151 | , nodePort = port | 151 | , nodePort = port |
152 | , nodePublicKey = pubkey | 152 | , nodePublicKey = NodeId pubkey |
153 | } | 153 | } |
154 | 154 | ||
155 | put (NodeFormat{..}) = do | 155 | put (NodeFormat{ nodePublicKey = NodeId pubkey, ..}) = do |
156 | put $ case (# nodeIP, nodeIsTCP #) of | 156 | put $ case (# nodeIP, nodeIsTCP #) of |
157 | (# IPv4 _, False #) -> 2 | 157 | (# IPv4 _, False #) -> 2 |
158 | (# IPv4 _, True #) -> 130 | 158 | (# IPv4 _, True #) -> 130 |
@@ -160,7 +160,7 @@ instance Serialize NodeFormat where | |||
160 | (# IPv6 _, True #) -> 138 :: Word8 | 160 | (# IPv6 _, True #) -> 138 :: Word8 |
161 | put nodeIP | 161 | put nodeIP |
162 | put nodePort | 162 | put nodePort |
163 | put nodePublicKey | 163 | put pubkey |
164 | 164 | ||
165 | -- Note: the char array is a public key, the 32-bytes is provided by libsodium-dev | 165 | -- Note: the char array is a public key, the 32-bytes is provided by libsodium-dev |
166 | -- in /usr/include/sodium/crypto_box.h as the symbol crypto_box_PUBLICKEYBYTES | 166 | -- in /usr/include/sodium/crypto_box.h as the symbol crypto_box_PUBLICKEYBYTES |