summaryrefslogtreecommitdiff
path: root/dht/src/Network/Tox/TCP.hs
diff options
context:
space:
mode:
Diffstat (limited to 'dht/src/Network/Tox/TCP.hs')
-rw-r--r--dht/src/Network/Tox/TCP.hs60
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
43import qualified Data.Word64Map 43import qualified Data.Word64Map
44import DebugTag 44import DebugTag
45import DPut 45import DPut
46import Network.Address (setPort,PortNumber,localhost4,fromSockAddr) 46import Network.Address (setPort,PortNumber,localhost4,fromSockAddr,nullAddress4)
47import Network.Kademlia.Routing 47import Network.Kademlia.Routing
48import Network.Kademlia.Search hiding (sendQuery) 48import Network.Kademlia.Search hiding (sendQuery)
49import Network.QueryResponse 49import 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.
321newClient :: TransportCrypto 321newClient :: 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))
328newClient crypto store load = do 331newClient 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
402partitionOnion :: 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))
408partitionOnion 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