summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Network/Lossless.hs38
-rw-r--r--src/Network/Tox/Session.hs29
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
28lossless :: Show addr => 28lossless :: 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
15import Network.QueryResponse 15import Network.QueryResponse
16import Network.SessionTransports 16import Network.SessionTransports
17import Network.Tox.Crypto.Transport 17import Network.Tox.Crypto.Transport
18import Network.Tox.DHT.Transport (Cookie) 18import Network.Tox.DHT.Transport (Cookie,key2id)
19import Network.Tox.Handshake 19import Network.Tox.Handshake
20 20
21type SessionKey = SecretKey 21type 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
102decryptPacket :: SessionKeys -> SockAddr -> CryptoPacket Encrypted -> IO (Maybe (CryptoPacket Identity, ())) 104decryptPacket :: SessionKeys -> SockAddr -> CryptoPacket Encrypted -> IO (Maybe (CryptoPacket Identity, ()))
103decryptPacket sk saddr (CryptoPacket n16 ciphered) = do 105decryptPacket 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
116encryptPacket :: SessionKeys -> CryptoData -> IO (CryptoPacket Encrypted) 124encryptPacket :: 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
126data SessionKeys = SessionKeys 139data 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 }