diff options
Diffstat (limited to 'src/Network/Tox/TCP.hs')
-rw-r--r-- | src/Network/Tox/TCP.hs | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/Network/Tox/TCP.hs b/src/Network/Tox/TCP.hs index 71050fe8..36200586 100644 --- a/src/Network/Tox/TCP.hs +++ b/src/Network/Tox/TCP.hs | |||
@@ -11,6 +11,7 @@ import Debug.Trace | |||
11 | import Control.Arrow | 11 | import Control.Arrow |
12 | import Control.Concurrent | 12 | import Control.Concurrent |
13 | import Control.Concurrent.STM | 13 | import Control.Concurrent.STM |
14 | import Control.Exception | ||
14 | import Control.Monad | 15 | import Control.Monad |
15 | import Crypto.Random | 16 | import Crypto.Random |
16 | import Data.Aeson (ToJSON(..),FromJSON(..)) | 17 | import Data.Aeson (ToJSON(..),FromJSON(..)) |
@@ -92,7 +93,7 @@ tcpStream crypto = StreamHandshake | |||
92 | nil = SessionProtocol | 93 | nil = SessionProtocol |
93 | { streamGoodbye = return () | 94 | { streamGoodbye = return () |
94 | , streamDecode = return Nothing | 95 | , streamDecode = return Nothing |
95 | , streamEncode = \y -> return () | 96 | , streamEncode = \y -> dput XTCP $ "TCP nil <-- " ++ show y |
96 | } | 97 | } |
97 | either (\_ -> return nil) id $ mwelcome <&> \welcome -> do | 98 | either (\_ -> return nil) id $ mwelcome <&> \welcome -> do |
98 | dput XTCP $ "TCP:" ++ show addr ++ " --> " ++ show welcome | 99 | dput XTCP $ "TCP:" ++ show addr ++ " --> " ++ show welcome |
@@ -100,12 +101,13 @@ tcpStream crypto = StreamHandshake | |||
100 | nsend <- newMVar (sessionBaseNonce $ runIdentity $ helloData hello) | 101 | nsend <- newMVar (sessionBaseNonce $ runIdentity $ helloData hello) |
101 | nread <- newMVar (sessionBaseNonce $ runIdentity $ welcomeData welcome) | 102 | nread <- newMVar (sessionBaseNonce $ runIdentity $ welcomeData welcome) |
102 | let them = sessionPublicKey $ runIdentity $ welcomeData welcome | 103 | let them = sessionPublicKey $ runIdentity $ welcomeData welcome |
104 | hvar <- newMVar h | ||
103 | return SessionProtocol | 105 | return SessionProtocol |
104 | { streamGoodbye = do | 106 | { streamGoodbye = do |
105 | dput XTCP $ "Closing " ++ show addr | 107 | dput XTCP $ "Closing " ++ show addr |
106 | return () -- No goodbye packet? Seems rude. | 108 | return () -- No goodbye packet? Seems rude. |
107 | , streamDecode = | 109 | , streamDecode = |
108 | let go = decode <$> hGet h 2 >>= \case | 110 | let go h = decode <$> hGet h 2 >>= \case |
109 | Left e -> do | 111 | Left e -> do |
110 | dput XTCP $ "TCP: Failed to get length: " ++ e | 112 | dput XTCP $ "TCP: Failed to get length: " ++ e |
111 | return Nothing | 113 | return Nothing |
@@ -115,25 +117,27 @@ tcpStream crypto = StreamHandshake | |||
115 | dput XTCP $ "TCP: Failed to decode packet." | 117 | dput XTCP $ "TCP: Failed to decode packet." |
116 | return Nothing | 118 | return Nothing |
117 | Right x -> do | 119 | Right x -> do |
118 | m24 <- timeout 100000 (takeMVar nread) | 120 | m24 <- timeout 1000000 (takeMVar nread) |
119 | fmap join $ forM m24 $ \n24 -> do | 121 | fmap join $ forM m24 $ \n24 -> do |
120 | let r = decrypt (noncef' n24) x >>= decodePlain | 122 | let r = decrypt (noncef' n24) x >>= decodePlain |
121 | putMVar nread (incrementNonce24 n24) | 123 | putMVar nread (incrementNonce24 n24) |
122 | either (dput XTCP) | 124 | either (dput XTCP . ("TCP decryption: " ++)) |
123 | (\x' -> do | 125 | (\x' -> do |
124 | dput XTCP $ "TCP:" ++ show addr ++ " --> " ++ show x' | 126 | dput XTCP $ "TCP:" ++ show addr ++ " --> " ++ show x' |
125 | return ()) | 127 | return ()) |
126 | r | 128 | r |
127 | return $ either (const Nothing) Just r | 129 | return $ either (const Nothing) Just r |
128 | in go `catchIOError` \e -> do | 130 | in bracket (takeMVar hvar) (putMVar hvar) |
129 | dput XTCP $ "TCP exception: " ++ show e | 131 | $ \h -> go h `catchIOError` \e -> do |
130 | return Nothing | 132 | dput XTCP $ "TCP exception: " ++ show e |
133 | return Nothing | ||
131 | , streamEncode = \y -> do | 134 | , streamEncode = \y -> do |
132 | n24 <- takeMVar nsend | 135 | n24 <- takeMVar nsend |
133 | dput XTCP $ "TCP:" ++ show addr ++ " <-- " ++ show y | 136 | dput XTCP $ "TCP:" ++ show addr ++ " <-- " ++ show y |
134 | let bs = encode $ encrypt (noncef' n24) $ encodePlain y | 137 | let bs = encode $ encrypt (noncef' n24) $ encodePlain y |
135 | hPut h (encode (fromIntegral $ Data.ByteString.length bs :: Word16) <> bs) | 138 | ($ h) -- bracket (takeMVar hvar) (putMVar hvar) |
136 | `catchIOError` \e -> dput XTCP $ "TCP write exception: " ++ show e | 139 | $ \h -> hPut h (encode (fromIntegral $ Data.ByteString.length bs :: Word16) <> bs) |
140 | `catchIOError` \e -> dput XTCP $ "TCP write exception: " ++ show e | ||
137 | putMVar nsend (incrementNonce24 n24) | 141 | putMVar nsend (incrementNonce24 n24) |
138 | } | 142 | } |
139 | , streamAddr = nodeAddr | 143 | , streamAddr = nodeAddr |
@@ -154,7 +158,7 @@ nodeSearch tcp = Search | |||
154 | } | 158 | } |
155 | -} | 159 | -} |
156 | 160 | ||
157 | data TCPClient err meth tid = TCPClient | 161 | data TCPClient err tid = TCPClient |
158 | { tcpCrypto :: TransportCrypto | 162 | { tcpCrypto :: TransportCrypto |
159 | , tcpClient :: Client err PacketNumber tid NodeInfo (Bool,RelayPacket) | 163 | , tcpClient :: Client err PacketNumber tid NodeInfo (Bool,RelayPacket) |
160 | , tcpGetGateway :: UDP.NodeInfo -> STM (Maybe NodeInfo) | 164 | , tcpGetGateway :: UDP.NodeInfo -> STM (Maybe NodeInfo) |
@@ -181,10 +185,10 @@ getTCPNodes tcp seeking dst = do | |||
181 | return $ Just ts | 185 | return $ Just ts |
182 | -} | 186 | -} |
183 | 187 | ||
184 | getUDPNodes :: TCPClient err () Nonce8 -> NodeId -> UDP.NodeInfo -> IO (Maybe ([UDP.NodeInfo], [UDP.NodeInfo], Maybe ())) | 188 | getUDPNodes :: TCPClient err Nonce8 -> NodeId -> UDP.NodeInfo -> IO (Maybe ([UDP.NodeInfo], [UDP.NodeInfo], Maybe ())) |
185 | getUDPNodes tcp seeking dst = fmap fst <$> getUDPNodes' tcp seeking dst | 189 | getUDPNodes tcp seeking dst = fmap fst <$> getUDPNodes' tcp seeking dst |
186 | 190 | ||
187 | getUDPNodes' :: TCPClient err () Nonce8 -> NodeId -> UDP.NodeInfo -> IO (Maybe (([UDP.NodeInfo], [UDP.NodeInfo], Maybe ()), NodeInfo)) | 191 | getUDPNodes' :: TCPClient err Nonce8 -> NodeId -> UDP.NodeInfo -> IO (Maybe (([UDP.NodeInfo], [UDP.NodeInfo], Maybe ()), NodeInfo)) |
188 | getUDPNodes' tcp seeking dst0 = do | 192 | getUDPNodes' tcp seeking dst0 = do |
189 | mgateway <- atomically $ tcpGetGateway tcp dst0 | 193 | mgateway <- atomically $ tcpGetGateway tcp dst0 |
190 | fmap join $ forM mgateway $ \gateway -> do | 194 | fmap join $ forM mgateway $ \gateway -> do |
@@ -201,7 +205,14 @@ getUDPNodes' tcp seeking dst0 = do | |||
201 | wrap2 <- lookupNonceFunction (tcpCrypto tcp) b (UDP.id2key $ UDP.nodeId dst) | 205 | wrap2 <- lookupNonceFunction (tcpCrypto tcp) b (UDP.id2key $ UDP.nodeId dst) |
202 | wrap1 <- lookupNonceFunction (tcpCrypto tcp) c (UDP.id2key $ nodeId gateway) | 206 | wrap1 <- lookupNonceFunction (tcpCrypto tcp) c (UDP.id2key $ nodeId gateway) |
203 | wrap0 <- lookupNonceFunction (tcpCrypto tcp) (transportSecret $ tcpCrypto tcp) (UDP.id2key $ UDP.nodeId dst) | 207 | wrap0 <- lookupNonceFunction (tcpCrypto tcp) (transportSecret $ tcpCrypto tcp) (UDP.id2key $ UDP.nodeId dst) |
204 | let meth = MethodSerializer -- MethodSerializer Nonce8 NodeInfo RelayPacket meth AnnounceRequest (Either String AnnounceResponse) | 208 | let meth :: MethodSerializer |
209 | Nonce8 | ||
210 | a -- NodeInfo | ||
211 | (Bool, RelayPacket) | ||
212 | PacketNumber | ||
213 | AnnounceRequest | ||
214 | (Either String AnnounceResponse) | ||
215 | meth = MethodSerializer | ||
205 | { methodTimeout = \tid addr -> return (addr,12000000) -- 12 second timeout | 216 | { methodTimeout = \tid addr -> return (addr,12000000) -- 12 second timeout |
206 | , method = OnionPacketID -- meth | 217 | , method = OnionPacketID -- meth |
207 | , wrapQuery = \n8 src gateway x -> (,) True $ | 218 | , wrapQuery = \n8 src gateway x -> (,) True $ |
@@ -271,6 +282,7 @@ newClient crypto store load = do | |||
271 | OnionPacketResponse (OnionAnnounceResponse n8 n24 ciphered) -> IsResponse n8 | 282 | OnionPacketResponse (OnionAnnounceResponse n8 n24 ciphered) -> IsResponse n8 |
272 | OnionPacketResponse o@(OnionToRouteResponse _) -> IsUnsolicited $ handle2route o | 283 | OnionPacketResponse o@(OnionToRouteResponse _) -> IsUnsolicited $ handle2route o |
273 | OOBRecv k bs -> IsUnsolicited $ handleOOB k bs | 284 | OOBRecv k bs -> IsUnsolicited $ handleOOB k bs |
285 | wut -> IsUnknown (show wut) | ||
274 | , lookupHandler = \case | 286 | , lookupHandler = \case |
275 | PingPacket -> Just MethodHandler | 287 | PingPacket -> Just MethodHandler |
276 | { methodParse = \(_,RelayPing n8) -> Right () | 288 | { methodParse = \(_,RelayPing n8) -> Right () |