summaryrefslogtreecommitdiff
path: root/dht/src/Network/Tox/Relay.hs
diff options
context:
space:
mode:
Diffstat (limited to 'dht/src/Network/Tox/Relay.hs')
-rw-r--r--dht/src/Network/Tox/Relay.hs39
1 files changed, 32 insertions, 7 deletions
diff --git a/dht/src/Network/Tox/Relay.hs b/dht/src/Network/Tox/Relay.hs
index 2842fcc2..2ecd7ddf 100644
--- a/dht/src/Network/Tox/Relay.hs
+++ b/dht/src/Network/Tox/Relay.hs
@@ -30,6 +30,8 @@ import Network.SocketLike
30import Network.StreamServer 30import Network.StreamServer
31import Network.Tox.Onion.Transport hiding (encrypt,decrypt) 31import Network.Tox.Onion.Transport hiding (encrypt,decrypt)
32 32
33import DPut
34import DebugTag
33 35
34 36
35hGetPrefixed :: Serialize a => Handle -> IO (Either String a) 37hGetPrefixed :: Serialize a => Handle -> IO (Either String a)
@@ -43,6 +45,7 @@ hGetSized h = runGet get <$> B.hGet h len -- We treat parse-fail the same as EOF
43 where 45 where
44 ConstSize len = size :: Size x 46 ConstSize len = size :: Size x
45 47
48-- This type manages ConId assignments.
46data RelaySession = RelaySession 49data RelaySession = RelaySession
47 { indexPool :: IntSet -- ^ Ints that are either solicited or associated. 50 { indexPool :: IntSet -- ^ Ints that are either solicited or associated.
48 , solicited :: Map PublicKey Int -- ^ Reserved ids, not yet in associated. 51 , solicited :: Map PublicKey Int -- ^ Reserved ids, not yet in associated.
@@ -70,17 +73,19 @@ disconnect cons who = join $ atomically $ do
70 in IntMap.foldrWithKey notifyPeer (return ()) cs 73 in IntMap.foldrWithKey notifyPeer (return ()) cs
71 74
72relaySession :: TransportCrypto 75relaySession :: TransportCrypto
76 -> TVar (IntMap (RelayPacket -> IO ()))
73 -> TVar (Map PublicKey (RelayPacket -> IO (),TVar RelaySession)) 77 -> TVar (Map PublicKey (RelayPacket -> IO (),TVar RelaySession))
74 -> (SockAddr -> OnionRequest N1 -> IO ()) 78 -> (SockAddr -> OnionRequest N1 -> IO ())
75 -> sock 79 -> sock
76 -> Int 80 -> Int
77 -> Handle 81 -> Handle
78 -> IO () 82 -> IO ()
79relaySession crypto cons sendOnion _ conid h = do 83relaySession crypto clients cons sendOnion _ conid h = do
80 -- atomically $ modifyTVar' cons $ IntMap.insert conid h 84 -- atomically $ modifyTVar' cons $ IntMap.insert conid h
81 85
82 -- mhello <- fmap (>>= \h -> decryptPayload (computeSharedSecret me (helloFrom h) (helloNonce h)) h) $ hGetSized h 86 -- mhello <- fmap (>>= \h -> decryptPayload (computeSharedSecret me (helloFrom h) (helloNonce h)) h) $ hGetSized h
83 87
88 dput XOnion $ "Relay client session conid=" ++ show conid
84 (hGetSized h >>=) $ mapM_ $ \helloE -> do 89 (hGetSized h >>=) $ mapM_ $ \helloE -> do
85 90
86 let me = transportSecret crypto 91 let me = transportSecret crypto
@@ -88,17 +93,24 @@ relaySession crypto cons sendOnion _ conid h = do
88 93
89 noncef <- lookupNonceFunction crypto me them 94 noncef <- lookupNonceFunction crypto me them
90 let mhello = decryptPayload (noncef $ helloNonce helloE) helloE 95 let mhello = decryptPayload (noncef $ helloNonce helloE) helloE
96 dput XOnion $ "Relay client (conid=" ++ show conid ++ ") decrypted hello = " ++ show mhello
91 forM_ mhello $ \hello -> do 97 forM_ mhello $ \hello -> do
92 let _ = hello :: Hello Identity 98 let _ = hello :: Hello Identity
93 99
100 dput XOnion $ "Relay client sent hello. conid=" ++ show conid
94 (me',welcome) <- atomically $ do 101 (me',welcome) <- atomically $ do
95 skey <- transportNewKey crypto 102 skey <- transportNewKey crypto
96 dta <- HelloData (toPublic skey) <$> transportNewNonce crypto 103 dta <- HelloData (toPublic skey) <$> transportNewNonce crypto
97 w24 <- transportNewNonce crypto 104 w24 <- transportNewNonce crypto
98 return (skey, Welcome w24 $ pure dta) 105 return (skey, Welcome w24 $ pure dta)
99 106
107 dput XOnion $ unlines [ "Relay client to receive welcome. conid=" ++ show conid
108 , show welcome
109 ]
100 B.hPut h $ encode $ encryptPayload (noncef $ welcomeNonce welcome) welcome 110 B.hPut h $ encode $ encryptPayload (noncef $ welcomeNonce welcome) welcome
101 111
112 dput XOnion $ "Relay client welcome sent. conid=" ++ show conid
113
102 noncef' <- let them' = sessionPublicKey (runIdentity $ helloData hello) 114 noncef' <- let them' = sessionPublicKey (runIdentity $ helloData hello)
103 in lookupNonceFunction crypto me' them' 115 in lookupNonceFunction crypto me' them'
104 116
@@ -133,13 +145,20 @@ relaySession crypto cons sendOnion _ conid h = do
133 145
134 handlePacket cons conid (helloFrom hello) crypto sendOnion sendPacket session pkt0 146 handlePacket cons conid (helloFrom hello) crypto sendOnion sendPacket session pkt0
135 147
148 atomically $ modifyTVar' clients $ IntMap.insert conid $
149 \p -> do
150 dput XOnion $ "Sending onion reply to TCP client conid="++show conid
151 sendPacket p
152
136 flip fix (incrementNonce24 base) $ \loop n24 -> do 153 flip fix (incrementNonce24 base) $ \loop n24 -> do
137 m <- readPacket n24 154 m <- readPacket n24
138 forM_ m $ \p -> do 155 forM_ m $ \p -> do
139 handlePacket cons conid (helloFrom hello) crypto sendOnion sendPacket session p 156 handlePacket cons conid (helloFrom hello) crypto sendOnion sendPacket session p
140 loop (incrementNonce24 n24) 157 loop (incrementNonce24 n24)
141 `finally` 158 `finally` do
159 atomically $ modifyTVar' clients $ IntMap.delete conid
142 disconnect cons (helloFrom hello) 160 disconnect cons (helloFrom hello)
161 dput XOnion $ "Relay client session closed. conid=" ++ show conid
143 162
144handlePacket :: TVar (Map PublicKey (RelayPacket -> IO (), TVar RelaySession)) 163handlePacket :: TVar (Map PublicKey (RelayPacket -> IO (), TVar RelaySession))
145 -> Int 164 -> Int
@@ -202,6 +221,7 @@ handlePacket cons thistcp me crypto sendOnion sendToMe session = \case
202 return $ sendToThem' $ RelayData bs 221 return $ sendToThem' $ RelayData bs
203 222
204 OnionPacket n24 (Addressed addr req) -> do 223 OnionPacket n24 (Addressed addr req) -> do
224 dput XOnion $ "Received onion request via TCP client conid="++show thistcp
205 rpath <- atomically $ do 225 rpath <- atomically $ do
206 sym <- transportSymmetric crypto 226 sym <- transportSymmetric crypto
207 n <- transportNewNonce crypto 227 n <- transportNewNonce crypto
@@ -217,19 +237,24 @@ sendTCP_ st addr x = join $ atomically
217 Nothing -> return $ return () 237 Nothing -> return $ return ()
218 Just send -> return $ send $ OnionPacketResponse x 238 Just send -> return $ send $ OnionPacketResponse x
219 239
220tcpRelay :: SockAddr -> (SockAddr -> OnionRequest N1 -> IO ()) -> IO (ServerHandle, Int -> OnionMessage Encrypted -> IO ()) 240tcpRelay :: TransportCrypto
221tcpRelay udp_addr sendOnion = do 241 -> SockAddr -- ^ UDP bind address (this port may be tried for TCP if hardcoded defaults dont work).
222 crypto <- newCrypto 242 -> (SockAddr -> OnionRequest N1 -> IO ()) -- ^ This callback will be used to forward onion messages over udp.
243 -> IO ( ServerHandle -- Handle to the Tox Tcp-Relay server.
244 , Int -> OnionMessage Encrypted -> IO () -- forward onion response to tcp client.
245 )
246tcpRelay crypto udp_addr sendOnion = do
223 cons <- newTVarIO Map.empty 247 cons <- newTVarIO Map.empty
224 clients <- newTVarIO IntMap.empty 248 clients <- newTVarIO IntMap.empty
225 b443 <- getBindAddress "443" True 249 b443 <- getBindAddress "443" True
226 b80 <- getBindAddress "80" True 250 b80 <- getBindAddress "80" True
251 b3389 <- getBindAddress "3389" True
227 b33445 <- getBindAddress "33445" True 252 b33445 <- getBindAddress "33445" True
228 bany <- getBindAddress "" True 253 bany <- getBindAddress "" True
229 h <- streamServer ServerConfig 254 h <- streamServer ServerConfig
230 { serverWarn = hPutStrLn stderr 255 { serverWarn = hPutStrLn stderr
231 , serverSession = relaySession crypto cons sendOnion 256 , serverSession = relaySession crypto clients cons sendOnion
232 } 257 }
233 [b443,b80,udp_addr,b33445,bany] 258 [b443,b80,b3389,udp_addr,b33445,bany]
234 return (h,sendTCP_ clients) 259 return (h,sendTCP_ clients)
235 260