diff options
author | Joe Crayne <joe@jerkface.net> | 2019-12-11 04:57:49 -0500 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2020-01-01 23:26:04 -0500 |
commit | 458d053dcff411179d52d437087cce76b8af4a9c (patch) | |
tree | 024160df41772f0516e6449a3bfabdabfcd5e269 /dht/src/Network/Tox | |
parent | 5b9374c79de82025bbb0ce47e0a93e6ddc0ece6c (diff) |
Share TCP Relays with remote via onion message.
Diffstat (limited to 'dht/src/Network/Tox')
-rw-r--r-- | dht/src/Network/Tox/DHT/Handlers.hs | 9 | ||||
-rw-r--r-- | dht/src/Network/Tox/DHT/Transport.hs | 3 | ||||
-rw-r--r-- | dht/src/Network/Tox/NodeId.hs | 4 | ||||
-rw-r--r-- | dht/src/Network/Tox/Onion/Handlers.hs | 3 | ||||
-rw-r--r-- | dht/src/Network/Tox/TCP.hs | 5 | ||||
-rw-r--r-- | dht/src/Network/Tox/TCP/NodeId.hs | 89 |
6 files changed, 102 insertions, 11 deletions
diff --git a/dht/src/Network/Tox/DHT/Handlers.hs b/dht/src/Network/Tox/DHT/Handlers.hs index e93f565b..323d5f5e 100644 --- a/dht/src/Network/Tox/DHT/Handlers.hs +++ b/dht/src/Network/Tox/DHT/Handlers.hs | |||
@@ -7,6 +7,7 @@ module Network.Tox.DHT.Handlers where | |||
7 | 7 | ||
8 | import Debug.Trace | 8 | import Debug.Trace |
9 | import Network.Tox.DHT.Transport as DHTTransport | 9 | import Network.Tox.DHT.Transport as DHTTransport |
10 | import Network.Tox.TCP.NodeId as TCP (fromUDPNode, udpNodeInfo) | ||
10 | import Network.QueryResponse as QR hiding (Client) | 11 | import Network.QueryResponse as QR hiding (Client) |
11 | import qualified Network.QueryResponse as QR (Client) | 12 | import qualified Network.QueryResponse as QR (Client) |
12 | import Crypto.Tox | 13 | import Crypto.Tox |
@@ -257,6 +258,7 @@ getNodesH routing addr (GetNodes nid) = do | |||
257 | Want_IP4 -> (ks,ks6) | 258 | Want_IP4 -> (ks,ks6) |
258 | Want_Both -> error $ "BUG:unreachable at " ++ __FILE__ ++ ":" ++ show __LINE__ | 259 | Want_Both -> error $ "BUG:unreachable at " ++ __FILE__ ++ ":" ++ show __LINE__ |
259 | return $ SendNodes | 260 | return $ SendNodes |
261 | $ map fromUDPNode | ||
260 | $ if null ns2 then ns1 | 262 | $ if null ns2 then ns1 |
261 | else take 4 (take 3 ns1 ++ ns2) | 263 | else take 4 (take 3 ns1 ++ ns2) |
262 | where | 264 | where |
@@ -397,8 +399,9 @@ unsendNodes :: Message -> Maybe (Asymm (Nonce8,SendNodes)) | |||
397 | unsendNodes (DHTSendNodes asymm) = Just asymm | 399 | unsendNodes (DHTSendNodes asymm) = Just asymm |
398 | unsendNodes _ = Nothing | 400 | unsendNodes _ = Nothing |
399 | 401 | ||
402 | -- XXX: map udpNodeInfo is probably not right | ||
400 | unwrapNodes :: SendNodes -> ( [NodeInfo], [NodeInfo], Maybe () ) | 403 | unwrapNodes :: SendNodes -> ( [NodeInfo], [NodeInfo], Maybe () ) |
401 | unwrapNodes (SendNodes ns) = (ns,ns,Just ()) | 404 | unwrapNodes (SendNodes ns) = (map udpNodeInfo ns,map udpNodeInfo ns,Just ()) |
402 | 405 | ||
403 | getNodes :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> NodeId -> NodeInfo -> IO (Maybe ([NodeInfo],[NodeInfo],Maybe ())) | 406 | getNodes :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> NodeId -> NodeInfo -> IO (Maybe ([NodeInfo],[NodeInfo],Maybe ())) |
404 | getNodes client cbvar nid addr = do | 407 | getNodes client cbvar nid addr = do |
@@ -409,10 +412,10 @@ getNodes client cbvar nid addr = do | |||
409 | forM_ ns $ \n -> do | 412 | forM_ ns $ \n -> do |
410 | now <- getPOSIXTime | 413 | now <- getPOSIXTime |
411 | atomically $ do | 414 | atomically $ do |
412 | mcbs <- HashMap.lookup (nodeId n) <$> readTVar cbvar | 415 | mcbs <- HashMap.lookup (nodeId . udpNodeInfo $ n) <$> readTVar cbvar |
413 | forM_ mcbs $ \cbs -> do | 416 | forM_ mcbs $ \cbs -> do |
414 | forM_ cbs $ \cb -> do | 417 | forM_ cbs $ \cb -> do |
415 | rumoredAddress cb now (nodeAddr addr) n | 418 | rumoredAddress cb now (nodeAddr addr) (udpNodeInfo n) |
416 | return $ fmap unwrapNodes $ join reply | 419 | return $ fmap unwrapNodes $ join reply |
417 | 420 | ||
418 | updateRouting :: Client -> Routing | 421 | updateRouting :: Client -> Routing |
diff --git a/dht/src/Network/Tox/DHT/Transport.hs b/dht/src/Network/Tox/DHT/Transport.hs index b9b63165..7475b3b1 100644 --- a/dht/src/Network/Tox/DHT/Transport.hs +++ b/dht/src/Network/Tox/DHT/Transport.hs | |||
@@ -36,6 +36,7 @@ module Network.Tox.DHT.Transport | |||
36 | ) where | 36 | ) where |
37 | 37 | ||
38 | import Network.Tox.NodeId | 38 | import Network.Tox.NodeId |
39 | import qualified Network.Tox.TCP.NodeId as TCP | ||
39 | import Crypto.Tox hiding (encrypt,decrypt) | 40 | import Crypto.Tox hiding (encrypt,decrypt) |
40 | import qualified Crypto.Tox as ToxCrypto | 41 | import qualified Crypto.Tox as ToxCrypto |
41 | import Network.QueryResponse | 42 | import Network.QueryResponse |
@@ -315,7 +316,7 @@ newtype GetNodes = GetNodes NodeId | |||
315 | instance Sized GetNodes where | 316 | instance Sized GetNodes where |
316 | size = ConstSize 32 -- TODO This right? | 317 | size = ConstSize 32 -- TODO This right? |
317 | 318 | ||
318 | newtype SendNodes = SendNodes [NodeInfo] | 319 | newtype SendNodes = SendNodes [TCP.NodeInfo] |
319 | deriving (Eq,Ord,Show,Read) | 320 | deriving (Eq,Ord,Show,Read) |
320 | 321 | ||
321 | instance Sized SendNodes where | 322 | instance Sized SendNodes where |
diff --git a/dht/src/Network/Tox/NodeId.hs b/dht/src/Network/Tox/NodeId.hs index 6c82ce09..8567e77d 100644 --- a/dht/src/Network/Tox/NodeId.hs +++ b/dht/src/Network/Tox/NodeId.hs | |||
@@ -252,8 +252,8 @@ nodeInfoFromJSON prefer4 (JSON.Object v) = do | |||
252 | getIP :: Word8 -> S.Get IP | 252 | getIP :: Word8 -> S.Get IP |
253 | getIP 0x02 = IPv4 <$> S.get | 253 | getIP 0x02 = IPv4 <$> S.get |
254 | getIP 0x0a = IPv6 <$> S.get | 254 | getIP 0x0a = IPv6 <$> S.get |
255 | getIP 0x82 = IPv4 <$> S.get -- TODO: TCP | 255 | getIP 0x82 = IPv4 <$> S.get -- TODO: TCP TOX_TCP_INET |
256 | getIP 0x8a = IPv6 <$> S.get -- TODO: TCP | 256 | getIP 0x8a = IPv6 <$> S.get -- TODO: TCP TOX_TCP_INET6 |
257 | getIP x = fail ("unsupported address family ("++show x++")") | 257 | getIP x = fail ("unsupported address family ("++show x++")") |
258 | 258 | ||
259 | instance Sized NodeInfo where | 259 | instance Sized NodeInfo where |
diff --git a/dht/src/Network/Tox/Onion/Handlers.hs b/dht/src/Network/Tox/Onion/Handlers.hs index b35631a3..52dcf536 100644 --- a/dht/src/Network/Tox/Onion/Handlers.hs +++ b/dht/src/Network/Tox/Onion/Handlers.hs | |||
@@ -4,6 +4,7 @@ | |||
4 | module Network.Tox.Onion.Handlers where | 4 | module Network.Tox.Onion.Handlers where |
5 | 5 | ||
6 | import Network.Kademlia.Search | 6 | import Network.Kademlia.Search |
7 | import Network.Tox.TCP.NodeId (udpNodeInfo) | ||
7 | import Network.Tox.DHT.Transport | 8 | import Network.Tox.DHT.Transport |
8 | import Network.Tox.DHT.Handlers hiding (Message,Client) | 9 | import Network.Tox.DHT.Handlers hiding (Message,Client) |
9 | import Network.Tox.Onion.Transport | 10 | import Network.Tox.Onion.Transport |
@@ -251,7 +252,7 @@ announceSerializer getTimeout = MethodSerializer | |||
251 | } | 252 | } |
252 | 253 | ||
253 | unwrapAnnounceResponse :: Maybe NodeId -> NodeInfo -> AnnounceResponse -> ([NodeInfo], [Rendezvous], Maybe Nonce32) | 254 | unwrapAnnounceResponse :: Maybe NodeId -> NodeInfo -> AnnounceResponse -> ([NodeInfo], [Rendezvous], Maybe Nonce32) |
254 | unwrapAnnounceResponse alias ni (AnnounceResponse is_stored (SendNodes ns)) | 255 | unwrapAnnounceResponse alias ni (AnnounceResponse is_stored (SendNodes ns0)) | let ns = map udpNodeInfo ns0 |
255 | = case is_stored of | 256 | = case is_stored of |
256 | NotStored n32 -> ( ns , [] , Just n32) | 257 | NotStored n32 -> ( ns , [] , Just n32) |
257 | SendBackKey k -> ( ns , [Rendezvous k ni] , Nothing ) | 258 | SendBackKey k -> ( ns , [Rendezvous k ni] , Nothing ) |
diff --git a/dht/src/Network/Tox/TCP.hs b/dht/src/Network/Tox/TCP.hs index e80a22d1..1531dfb4 100644 --- a/dht/src/Network/Tox/TCP.hs +++ b/dht/src/Network/Tox/TCP.hs | |||
@@ -44,6 +44,7 @@ import Network.Kademlia.Routing | |||
44 | import Network.Kademlia.Search hiding (sendQuery) | 44 | import Network.Kademlia.Search hiding (sendQuery) |
45 | import Network.QueryResponse | 45 | import Network.QueryResponse |
46 | import Network.QueryResponse.TCP | 46 | import Network.QueryResponse.TCP |
47 | import Network.Tox.TCP.NodeId () | ||
47 | import Network.Tox.DHT.Handlers (toxSpace) | 48 | import Network.Tox.DHT.Handlers (toxSpace) |
48 | import Network.Tox.Onion.Transport hiding (encrypt,decrypt) | 49 | import Network.Tox.Onion.Transport hiding (encrypt,decrypt) |
49 | import Network.Tox.Onion.Handlers (unwrapAnnounceResponse) | 50 | import Network.Tox.Onion.Handlers (unwrapAnnounceResponse) |
@@ -57,10 +58,6 @@ withSize f = case size of len -> f len | |||
57 | 58 | ||
58 | type NodeId = UDP.NodeId | 59 | type NodeId = UDP.NodeId |
59 | 60 | ||
60 | -- example: | ||
61 | -- KEyW2Bm.S-DpIGp72380BAfgintUWX1KX.6ZU.4m5Ex@80.99.99.99:33400{tcp:443} | ||
62 | instance Show NodeInfo where | ||
63 | show (NodeInfo udp port) = show udp ++ "{tcp:"++show port++"}" | ||
64 | 61 | ||
65 | nodeId :: NodeInfo -> NodeId | 62 | nodeId :: NodeInfo -> NodeId |
66 | nodeId ni = UDP.nodeId $ udpNodeInfo ni | 63 | nodeId ni = UDP.nodeId $ udpNodeInfo ni |
diff --git a/dht/src/Network/Tox/TCP/NodeId.hs b/dht/src/Network/Tox/TCP/NodeId.hs new file mode 100644 index 00000000..c218c88f --- /dev/null +++ b/dht/src/Network/Tox/TCP/NodeId.hs | |||
@@ -0,0 +1,89 @@ | |||
1 | {-# LANGUAGE CPP #-} | ||
2 | module Network.Tox.TCP.NodeId where | ||
3 | |||
4 | import Crypto.Tox | ||
5 | import qualified Network.Tox.NodeId as UDP | ||
6 | |||
7 | import qualified Data.Aeson as JSON | ||
8 | ;import Data.Aeson (FromJSON (..), ToJSON (..)) | ||
9 | import Data.Functor.Contravariant | ||
10 | import Data.Hashable | ||
11 | import qualified Data.HashMap.Strict as HashMap | ||
12 | import qualified Data.Vector as Vector | ||
13 | import Data.Word | ||
14 | import Network.Socket | ||
15 | import qualified Text.ParserCombinators.ReadP as RP | ||
16 | import Data.Serialize as S | ||
17 | |||
18 | #if MIN_VERSION_iproute(1,7,4) | ||
19 | import Data.IP hiding (fromSockAddr) | ||
20 | #else | ||
21 | import Data.IP | ||
22 | #endif | ||
23 | |||
24 | data NodeInfo = NodeInfo | ||
25 | { udpNodeInfo :: UDP.NodeInfo | ||
26 | , tcpPort :: PortNumber | ||
27 | } | ||
28 | deriving (Eq,Ord) | ||
29 | |||
30 | instance Read NodeInfo where | ||
31 | readsPrec _ = RP.readP_to_S $ do | ||
32 | udp <- RP.readS_to_P reads | ||
33 | port <- RP.between (RP.char '{') (RP.char '}') $ do | ||
34 | mapM_ RP.char ("tcp:" :: String) | ||
35 | w16 <- RP.readS_to_P reads | ||
36 | return $ fromIntegral (w16 :: Word16) | ||
37 | return $ NodeInfo udp port | ||
38 | |||
39 | instance ToJSON NodeInfo where | ||
40 | toJSON (NodeInfo udp port) = case (toJSON udp) of | ||
41 | JSON.Object tbl -> JSON.Object $ HashMap.insert "tcp_ports" | ||
42 | (JSON.Array $ Vector.fromList | ||
43 | [JSON.Number (fromIntegral port)]) | ||
44 | tbl | ||
45 | x -> x -- Shouldn't happen. | ||
46 | |||
47 | -- example: | ||
48 | -- KEyW2Bm.S-DpIGp72380BAfgintUWX1KX.6ZU.4m5Ex@80.99.99.99:33400{tcp:443} | ||
49 | instance Show NodeInfo where | ||
50 | show (NodeInfo udp port) = show udp ++ "{tcp:"++show port++"}" | ||
51 | |||
52 | instance Sized NodeInfo where | ||
53 | size = contramap udpNodeInfo size | ||
54 | |||
55 | |||
56 | getIP :: Word8 -> S.Get (Bool, IP) | ||
57 | getIP 0x02 = (,) False . IPv4 <$> S.get -- UDP 4 | ||
58 | getIP 0x0a = (,) False . IPv6 <$> S.get -- UDP 6 | ||
59 | getIP 0x82 = (,) True . IPv4 <$> S.get -- TCP 4 | ||
60 | getIP 0x8a = (,) True . IPv6 <$> S.get -- TCP 6 | ||
61 | getIP x = fail ("unsupported address family ("++show x++")") | ||
62 | |||
63 | instance S.Serialize NodeInfo where | ||
64 | get = do | ||
65 | addrfam <- S.get :: S.Get Word8 | ||
66 | (istcp, ip) <- getIP addrfam | ||
67 | port <- S.get :: S.Get PortNumber | ||
68 | nid <- S.get | ||
69 | let (udpport, tcpport) = if istcp | ||
70 | then (0, port) | ||
71 | else (port, 0) | ||
72 | return $ NodeInfo (UDP.NodeInfo nid ip udpport) tcpport | ||
73 | |||
74 | put (NodeInfo (UDP.NodeInfo nid ip udpport) tcpport) = do | ||
75 | if tcpport==0 | ||
76 | then do | ||
77 | case ip of | ||
78 | IPv4 ip4 -> S.put (2 :: Word8) >> S.put ip4 | ||
79 | IPv6 ip6 -> S.put (10 :: Word8) >> S.put ip6 | ||
80 | S.put udpport | ||
81 | else do | ||
82 | case ip of | ||
83 | IPv4 ip4 -> S.put (0x82 :: Word8) >> S.put ip4 | ||
84 | IPv6 ip6 -> S.put (0x8a :: Word8) >> S.put ip6 | ||
85 | S.put tcpport | ||
86 | S.put nid | ||
87 | |||
88 | fromUDPNode :: UDP.NodeInfo -> NodeInfo | ||
89 | fromUDPNode ni = NodeInfo ni 0 | ||