diff options
Diffstat (limited to 'src/Network')
-rw-r--r-- | src/Network/Lossless.hs | 38 | ||||
-rw-r--r-- | src/Network/Tox/Session.hs | 29 |
2 files changed, 45 insertions, 22 deletions
diff --git a/src/Network/Lossless.hs b/src/Network/Lossless.hs index bdbeb3a2..f48dc8fd 100644 --- a/src/Network/Lossless.hs +++ b/src/Network/Lossless.hs | |||
@@ -27,7 +27,7 @@ data SequenceInfo = SequenceInfo | |||
27 | 27 | ||
28 | lossless :: Show addr => | 28 | lossless :: Show addr => |
29 | (x -> addr -> IO (PacketInboundEvent (x',addr'))) | 29 | (x -> addr -> IO (PacketInboundEvent (x',addr'))) |
30 | -> (SequenceInfo -> x' -> addr' -> IO y) | 30 | -> (SequenceInfo -> x' -> addr' -> IO (Bool,y)) |
31 | -> addr | 31 | -> addr |
32 | -> TransportA String addr x y | 32 | -> TransportA String addr x y |
33 | -> IO ( Transport String addr' x' | 33 | -> IO ( Transport String addr' x' |
@@ -39,44 +39,54 @@ lossless isLossless encode saddr udp = do | |||
39 | oob <- atomically newTChan -- Out-of-band channel, these packets (or | 39 | oob <- atomically newTChan -- Out-of-band channel, these packets (or |
40 | -- errors) bypass the packet buffer to be | 40 | -- errors) bypass the packet buffer to be |
41 | -- received immediately. | 41 | -- received immediately. |
42 | rloop <- forkIO $ fix $ \loop -> do | 42 | rloop <- forkIO $ do |
43 | -- This thread enqueues inbound packets or writes them to the oob | 43 | -- This thread enqueues inbound packets or writes them to the oob |
44 | -- channel. | 44 | -- channel. |
45 | myThreadId >>= flip labelThread ("lossless."++show saddr) | 45 | myThreadId >>= flip labelThread ("lossless."++show saddr) |
46 | fix $ \loop -> do | ||
46 | awaitMessage udp $ \m -> do | 47 | awaitMessage udp $ \m -> do |
47 | forM_ m $ \raw -> do | 48 | m' <- mapM (mapM $ uncurry isLossless) m |
48 | m' <- mapM (uncurry isLossless) raw | ||
49 | case m' of | 49 | case m' of |
50 | Left e -> do | 50 | Nothing -> do |
51 | atomically $ writeTChan oob (Left e) | 51 | atomically $ writeTChan oob Nothing |
52 | -- Quit thread here. | ||
53 | Just (Left e) -> do | ||
54 | atomically $ writeTChan oob (Just $ Left e) | ||
52 | loop | 55 | loop |
53 | Right event -> do | 56 | Just (Right event) -> do |
54 | atomically $ do | 57 | atomically $ do |
55 | -- x' <- isLossless xaddr x | 58 | -- x' <- isLossless xaddr x |
56 | PB.grokInboundPacket pb event | 59 | PB.grokInboundPacket pb event |
57 | case event of | 60 | case event of |
58 | PacketReceivedLossy {} -> writeTChan oob (Right $ peReceivedPayload event) | 61 | PacketReceivedLossy {} -> writeTChan oob (Just $ Right $ peReceivedPayload event) |
59 | _ -> do | 62 | _ -> do |
60 | report <- pbReport "enqueued" pb | 63 | report <- pbReport "enqueued" pb |
61 | writeTChan oob (Left report) | 64 | writeTChan oob (Just $ Left report) |
62 | loop | 65 | loop |
63 | let tr = Transport | 66 | let tr = Transport |
64 | { awaitMessage = \kont -> do | 67 | { awaitMessage = \kont -> do |
65 | join $ atomically $ orElse | 68 | join $ atomically $ orElse |
66 | (do x <- readTChan oob | 69 | (do x <- readTChan oob |
67 | return $ kont $! Just x) | 70 | return $ kont $! x) |
68 | (do x <- PB.awaitReadyPacket pb | 71 | (do x <- PB.awaitReadyPacket pb |
69 | report <- pbReport "dequeued" pb | 72 | report <- pbReport "dequeued" pb |
70 | return $ do | 73 | return $ do |
71 | dput XNetCrypto report | 74 | atomically $ writeTChan oob (Just $ Left report) |
72 | kont $! Just (Right x)) | 75 | kont $! Just (Right x)) |
73 | , sendMessage = \a' x' -> do | 76 | , sendMessage = \a' x' -> do |
74 | seqno <- atomically $ do | 77 | seqno <- atomically $ do |
75 | seqno <- PB.nextToSendSequenceNumber pb | 78 | seqno <- PB.nextToSendSequenceNumber pb |
76 | ack <- PB.expectingSequenceNumber pb | 79 | ack <- PB.expectingSequenceNumber pb |
77 | return $ SequenceInfo seqno ack | 80 | return $ SequenceInfo seqno ack |
78 | x <- encode seqno x' a' | 81 | (islossy,x) <- encode seqno x' a' |
79 | (isfull,nn) <- atomically $ PB.grokOutboundPacket pb (PacketSent (sequenceNumber seqno) x) | 82 | (isfull,nn) <- |
83 | if islossy | ||
84 | then do | ||
85 | dput XNetCrypto $ shows saddr $ " <-- Lossy packet " ++ show seqno | ||
86 | return (False,(0,0)) -- avoid updating seqno on lossy packets. | ||
87 | else do | ||
88 | dput XNetCrypto $ shows saddr $ " <-- Lossless packet " ++ show seqno | ||
89 | atomically $ PB.grokOutboundPacket pb (PacketSent (sequenceNumber seqno) x) | ||
80 | when isfull $ do | 90 | when isfull $ do |
81 | dput XNetCrypto $ shows saddr $ " <-- Outbound queue is full! Retrying... " ++ show (nn,seqno) | 91 | dput XNetCrypto $ shows saddr $ " <-- Outbound queue is full! Retrying... " ++ show (nn,seqno) |
82 | atomically $ do | 92 | atomically $ do |
@@ -84,7 +94,7 @@ lossless isLossless encode saddr udp = do | |||
84 | when isfull retry | 94 | when isfull retry |
85 | sendMessage udp saddr x | 95 | sendMessage udp saddr x |
86 | , closeTransport = do | 96 | , closeTransport = do |
87 | killThread rloop | 97 | atomically $ writeTChan oob Nothing -- quit rloop thread |
88 | closeTransport udp | 98 | closeTransport udp |
89 | } | 99 | } |
90 | resend ns = do | 100 | resend ns = do |
diff --git a/src/Network/Tox/Session.hs b/src/Network/Tox/Session.hs index 88221b11..7b84ba80 100644 --- a/src/Network/Tox/Session.hs +++ b/src/Network/Tox/Session.hs | |||
@@ -15,7 +15,7 @@ import Network.Lossless | |||
15 | import Network.QueryResponse | 15 | import Network.QueryResponse |
16 | import Network.SessionTransports | 16 | import Network.SessionTransports |
17 | import Network.Tox.Crypto.Transport | 17 | import Network.Tox.Crypto.Transport |
18 | import Network.Tox.DHT.Transport (Cookie) | 18 | import Network.Tox.DHT.Transport (Cookie,key2id) |
19 | import Network.Tox.Handshake | 19 | import Network.Tox.Handshake |
20 | 20 | ||
21 | type SessionKey = SecretKey | 21 | type SessionKey = SecretKey |
@@ -69,7 +69,7 @@ plainHandshakeH sp saddr skey handshake = do | |||
69 | dput XNetCrypto $ prelude ++ "handshake: " ++ show (otherCookie hd, baseNonce hd) | 69 | dput XNetCrypto $ prelude ++ "handshake: " ++ show (otherCookie hd, baseNonce hd) |
70 | sent <- spGetSentHandshake sp skey saddr (handshakeCookie handshake) (otherCookie hd) | 70 | sent <- spGetSentHandshake sp skey saddr (handshakeCookie handshake) (otherCookie hd) |
71 | -- TODO: this is always returning sent = Nothing | 71 | -- TODO: this is always returning sent = Nothing |
72 | dput XNetCrypto $ prelude ++ "plainHandshakeH: cached outgoing: " ++ show (fmap (baseNonce . snd) sent) | 72 | dput XNetCrypto $ " <-- (cached) handshake baseNonce" ++ show (fmap (baseNonce . snd) sent) |
73 | forM_ sent $ \(hd_skey,hd_sent) -> do | 73 | forM_ sent $ \(hd_skey,hd_sent) -> do |
74 | sk <- SessionKeys (spCrypto sp) | 74 | sk <- SessionKeys (spCrypto sp) |
75 | hd_skey | 75 | hd_skey |
@@ -81,7 +81,9 @@ plainHandshakeH sp saddr skey handshake = do | |||
81 | forM_ m $ \(sid, t) -> do | 81 | forM_ m $ \(sid, t) -> do |
82 | (t2,resend,getMissing) | 82 | (t2,resend,getMissing) |
83 | <- lossless (\cp a -> return $ fmap (,a) $ checkLossless $ runIdentity $ pktData cp) | 83 | <- lossless (\cp a -> return $ fmap (,a) $ checkLossless $ runIdentity $ pktData cp) |
84 | (\seqno p _ -> encryptPacket sk $ bookKeeping seqno p) | 84 | (\seqno p _ -> do |
85 | y <- encryptPacket sk $ bookKeeping seqno p | ||
86 | return (lossyness (msgID p) == Lossy, y)) | ||
85 | () | 87 | () |
86 | t | 88 | t |
87 | let _ = t :: TransportA String () (CryptoPacket Identity) (CryptoPacket Encrypted) | 89 | let _ = t :: TransportA String () (CryptoPacket Identity) (CryptoPacket Encrypted) |
@@ -101,16 +103,22 @@ plainHandshakeH sp saddr skey handshake = do | |||
101 | 103 | ||
102 | decryptPacket :: SessionKeys -> SockAddr -> CryptoPacket Encrypted -> IO (Maybe (CryptoPacket Identity, ())) | 104 | decryptPacket :: SessionKeys -> SockAddr -> CryptoPacket Encrypted -> IO (Maybe (CryptoPacket Identity, ())) |
103 | decryptPacket sk saddr (CryptoPacket n16 ciphered) = do | 105 | decryptPacket sk saddr (CryptoPacket n16 ciphered) = do |
104 | (n,δ) <- atomically $ do | 106 | (n24,δ) <- atomically $ do |
105 | n <- readTVar (skNonceIncoming sk) | 107 | n <- readTVar (skNonceIncoming sk) |
106 | let δ = n16 - nonce24ToWord16 n | 108 | let δ = n16 - nonce24ToWord16 n |
107 | return ( n `addtoNonce24` fromIntegral δ, δ ) | 109 | return ( n `addtoNonce24` fromIntegral δ, δ ) |
108 | secret <- lookupSharedSecret (skCrypto sk) (skMe sk) (skThem sk) n | 110 | secret <- lookupSharedSecret (skCrypto sk) (skMe sk) (skThem sk) n24 |
109 | case decodePlain =<< decrypt secret ciphered of | 111 | case decodePlain =<< decrypt secret ciphered of |
110 | Left e -> return Nothing | 112 | Left e -> return Nothing |
111 | Right x -> do | 113 | Right x -> do |
112 | when ( δ > 43690 ) | 114 | when ( δ > 43690 ) |
113 | $ atomically $ writeTVar (skNonceIncoming sk) (n `addtoNonce24` 21845) | 115 | $ atomically $ writeTVar (skNonceIncoming sk) (n24 `addtoNonce24` 21845) |
116 | |||
117 | do let them = key2id $ skThem sk | ||
118 | CryptoData ack seqno _ = x | ||
119 | cm = decodeRawCryptoMsg x | ||
120 | dput XNetCrypto $ unwords [take 8 (show them),"-->",show (msgID cm),show (n24,ack,seqno)] | ||
121 | |||
114 | return $ Just ( CryptoPacket n16 (pure x), () ) | 122 | return $ Just ( CryptoPacket n16 (pure x), () ) |
115 | 123 | ||
116 | encryptPacket :: SessionKeys -> CryptoData -> IO (CryptoPacket Encrypted) | 124 | encryptPacket :: SessionKeys -> CryptoData -> IO (CryptoPacket Encrypted) |
@@ -121,12 +129,17 @@ encryptPacket sk plain = do | |||
121 | return n24 | 129 | return n24 |
122 | secret <- lookupSharedSecret (skCrypto sk) (skMe sk) (skThem sk) n24 | 130 | secret <- lookupSharedSecret (skCrypto sk) (skMe sk) (skThem sk) n24 |
123 | let ciphered = encrypt secret $ encodePlain $ plain | 131 | let ciphered = encrypt secret $ encodePlain $ plain |
132 | |||
133 | do let them = key2id $ skThem sk | ||
134 | CryptoData ack seqno cm = plain | ||
135 | dput XNetCrypto $ unwords [take 8 (show them),"<--",show (msgID cm),show (n24,ack,seqno)] | ||
136 | |||
124 | return $ CryptoPacket (nonce24ToWord16 n24) ciphered | 137 | return $ CryptoPacket (nonce24ToWord16 n24) ciphered |
125 | 138 | ||
126 | data SessionKeys = SessionKeys | 139 | data SessionKeys = SessionKeys |
127 | { skCrypto :: TransportCrypto | 140 | { skCrypto :: TransportCrypto |
128 | , skMe :: SecretKey | 141 | , skMe :: SecretKey -- My session key |
129 | , skThem :: PublicKey | 142 | , skThem :: PublicKey -- Their session key |
130 | , skNonceIncoming :: TVar Nonce24 -- +21845 when a threshold is reached. | 143 | , skNonceIncoming :: TVar Nonce24 -- +21845 when a threshold is reached. |
131 | , skNonceOutgoing :: TVar Nonce24 -- +1 on every packet | 144 | , skNonceOutgoing :: TVar Nonce24 -- +1 on every packet |
132 | } | 145 | } |