diff options
Diffstat (limited to 'dht/src/Network/Tox/TCP.hs')
-rw-r--r-- | dht/src/Network/Tox/TCP.hs | 60 |
1 files changed, 51 insertions, 9 deletions
diff --git a/dht/src/Network/Tox/TCP.hs b/dht/src/Network/Tox/TCP.hs index c4727a20..04119164 100644 --- a/dht/src/Network/Tox/TCP.hs +++ b/dht/src/Network/Tox/TCP.hs | |||
@@ -43,7 +43,7 @@ import Data.Tox.Relay | |||
43 | import qualified Data.Word64Map | 43 | import qualified Data.Word64Map |
44 | import DebugTag | 44 | import DebugTag |
45 | import DPut | 45 | import DPut |
46 | import Network.Address (setPort,PortNumber,localhost4,fromSockAddr) | 46 | import Network.Address (setPort,PortNumber,localhost4,fromSockAddr,nullAddress4) |
47 | import Network.Kademlia.Routing | 47 | import Network.Kademlia.Routing |
48 | import Network.Kademlia.Search hiding (sendQuery) | 48 | import Network.Kademlia.Search hiding (sendQuery) |
49 | import Network.QueryResponse | 49 | import Network.QueryResponse |
@@ -319,21 +319,25 @@ type RelayCache = TCPCache (SessionProtocol (SessionData,RelayPacket) RelayPacke | |||
319 | -- defaults are 'id' and 'tryPutMVar'. The resulting customized table state | 319 | -- defaults are 'id' and 'tryPutMVar'. The resulting customized table state |
320 | -- will be returned to the caller along with the new client. | 320 | -- will be returned to the caller along with the new client. |
321 | newClient :: TransportCrypto | 321 | newClient :: TransportCrypto |
322 | -> ((Maybe (Bool,RelayPacket) -> IO ()) -> a) -- ^ store mvar for query | 322 | -> ((Maybe (Bool,RelayPacket) -> IO ()) -> a) -- ^ store mvar for relay query |
323 | -> (a -> RelayPacket -> IO void) -- ^ load mvar for query | 323 | -> (a -> RelayPacket -> IO void) -- ^ load mvar for relay query |
324 | -> (SockAddr -> Nonce8 -> IO (Maybe (OnionDestination RouteId))) -- ^ lookup sender of onion query | ||
325 | -> (UDP.NodeInfo -> RouteId -> IO (Maybe OnionRoute)) -- ^ lookup OnionRoute by id | ||
324 | -> IO ( ( TVar (ChaChaDRG, Data.Word64Map.Word64Map a) | 326 | -> IO ( ( TVar (ChaChaDRG, Data.Word64Map.Word64Map a) |
325 | , RelayCache | 327 | , RelayCache |
326 | , Transport String ViaRelay ByteString ) | 328 | , Transport String ViaRelay ByteString |
329 | , Transport String (OnionDestination RouteId) (OnionMessage Encrypted) ) | ||
327 | , Client String PacketNumber Nonce8 NodeInfo (Bool,RelayPacket)) | 330 | , Client String PacketNumber Nonce8 NodeInfo (Bool,RelayPacket)) |
328 | newClient crypto store load = do | 331 | newClient crypto store load lookupSender getRoute = do |
329 | (tcpcache,net0) <- toxTCP crypto | 332 | (tcpcache,net0) <- toxTCP crypto |
330 | (relaynet,net1) <- partitionRelay net0 | 333 | (relaynet,net1) <- partitionRelay net0 |
331 | let net2 = {- XXX: Client type forces this pointless layering. -} | 334 | (onionnet,net2) <- partitionOnion crypto lookupSender getRoute net1 |
332 | layerTransport ((Right .) . (,) . (,) False . snd) (,) net1 | 335 | let net3 = {- XXX: Client type forces this pointless layering. -} |
336 | layerTransport ((Right .) . (,) . (,) False . snd) (,) net2 | ||
333 | drg <- drgNew | 337 | drg <- drgNew |
334 | map_var <- atomically $ newTVar (drg, Data.Word64Map.empty) | 338 | map_var <- atomically $ newTVar (drg, Data.Word64Map.empty) |
335 | return $ (,) (map_var,tcpcache,relaynet) Client | 339 | return $ (,) (map_var,tcpcache,relaynet,onionnet) Client |
336 | { clientNet = net2 | 340 | { clientNet = net3 |
337 | , clientDispatcher = DispatchMethods | 341 | , clientDispatcher = DispatchMethods |
338 | { classifyInbound = (. snd) $ \case | 342 | { classifyInbound = (. snd) $ \case |
339 | RelayPing n -> IsQuery PingPacket n | 343 | RelayPing n -> IsQuery PingPacket n |
@@ -393,3 +397,41 @@ partitionRelay tr = partitionTransportM parse encode tr | |||
393 | encode :: (ByteString, ViaRelay) -> IO (Maybe ((Bool,RelayPacket), NodeInfo)) | 397 | encode :: (ByteString, ViaRelay) -> IO (Maybe ((Bool,RelayPacket), NodeInfo)) |
394 | encode (bs, ViaRelay (Just conid) _ ni) = return $ Just ((False,RelayData bs conid), ni) | 398 | encode (bs, ViaRelay (Just conid) _ ni) = return $ Just ((False,RelayData bs conid), ni) |
395 | encode (bs, ViaRelay Nothing nid ni) = return $ Just ((False,OOBSend (UDP.id2key nid) bs), ni) | 399 | encode (bs, ViaRelay Nothing nid ni) = return $ Just ((False,OOBSend (UDP.id2key nid) bs), ni) |
400 | |||
401 | |||
402 | partitionOnion :: TransportCrypto | ||
403 | -> (SockAddr -> Nonce8 -> IO (Maybe (OnionDestination RouteId))) | ||
404 | -> (UDP.NodeInfo -> RouteId -> IO (Maybe OnionRoute)) | ||
405 | -> TransportA err NodeInfo (SessionData,RelayPacket) (Bool,RelayPacket) | ||
406 | -> IO ( Transport err (OnionDestination RouteId) (OnionMessage Encrypted) | ||
407 | , TransportA err NodeInfo (SessionData,RelayPacket) (Bool,RelayPacket)) | ||
408 | partitionOnion crypto lookupSender getRoute tr = partitionTransportM parse encode tr | ||
409 | where | ||
410 | parse :: ((SessionData,RelayPacket), NodeInfo) | ||
411 | -> IO (Either (OnionMessage Encrypted , OnionDestination RouteId) | ||
412 | ((SessionData,RelayPacket), NodeInfo)) | ||
413 | parse pass@((_,OnionPacketResponse msg@(OnionAnnounceResponse n8 _ _)), nodeA) = do | ||
414 | m <- lookupSender (nodeAddr nodeA) n8 | ||
415 | case m of | ||
416 | Nothing -> return $ Right pass | ||
417 | Just od -> return $ Left (msg, od) | ||
418 | parse ((_,OnionPacketResponse msg@(OnionToRouteResponse asym)), nodeA) = | ||
419 | return $ | ||
420 | let Right ni = UDP.nodeInfo (UDP.key2id $ senderKey asym) nullAddress4 | ||
421 | -- -- We have this information, but currently, we're discarding it... | ||
422 | -- r = dummyRoute { routeNodeA = udpNodeInfo nodeA | ||
423 | -- , routeRelayPort = Just $ tcpPort nodeA } | ||
424 | tryAllKeys = SearchingAlias -- We unfortunately don't know what toxid was used to encrypt this. | ||
425 | -- Toxcore only supports a single toxid per DHT node and in that case, | ||
426 | -- it is unambiguous. | ||
427 | in Left (msg, OnionDestination tryAllKeys ni Nothing) | ||
428 | parse pass = return $ Right pass | ||
429 | |||
430 | encode :: (OnionMessage Encrypted,OnionDestination RouteId) -> IO (Maybe ((Bool,RelayPacket),NodeInfo)) | ||
431 | encode (msg,OnionDestination _ ni (Just rid)) = do | ||
432 | moroute <- getRoute ni rid | ||
433 | forM (moroute >>= \r -> (,) r <$> routeRelayPort r) $ \(oroute,tcpport) -> | ||
434 | wrapIndirectHops crypto msg ni oroute $ \nonce saddr fwd -> | ||
435 | return ( (True,OnionPacket nonce $ Addressed saddr fwd) | ||
436 | , NodeInfo (routeNodeA oroute) tcpport ) | ||
437 | encode _ = return Nothing | ||