diff options
Diffstat (limited to 'dht/src/Network/Tox/Relay.hs')
-rw-r--r-- | dht/src/Network/Tox/Relay.hs | 39 |
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 | |||
30 | import Network.StreamServer | 30 | import Network.StreamServer |
31 | import Network.Tox.Onion.Transport hiding (encrypt,decrypt) | 31 | import Network.Tox.Onion.Transport hiding (encrypt,decrypt) |
32 | 32 | ||
33 | import DPut | ||
34 | import DebugTag | ||
33 | 35 | ||
34 | 36 | ||
35 | hGetPrefixed :: Serialize a => Handle -> IO (Either String a) | 37 | hGetPrefixed :: 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. | ||
46 | data RelaySession = RelaySession | 49 | data 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 | ||
72 | relaySession :: TransportCrypto | 75 | relaySession :: 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 () |
79 | relaySession crypto cons sendOnion _ conid h = do | 83 | relaySession 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 | ||
144 | handlePacket :: TVar (Map PublicKey (RelayPacket -> IO (), TVar RelaySession)) | 163 | handlePacket :: 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 | ||
220 | tcpRelay :: SockAddr -> (SockAddr -> OnionRequest N1 -> IO ()) -> IO (ServerHandle, Int -> OnionMessage Encrypted -> IO ()) | 240 | tcpRelay :: TransportCrypto |
221 | tcpRelay 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 | ) | ||
246 | tcpRelay 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 | ||