diff options
Diffstat (limited to 'src/Network/Tox/DHT')
-rw-r--r-- | src/Network/Tox/DHT/Transport.hs | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/src/Network/Tox/DHT/Transport.hs b/src/Network/Tox/DHT/Transport.hs index 79643fad..dd2838f2 100644 --- a/src/Network/Tox/DHT/Transport.hs +++ b/src/Network/Tox/DHT/Transport.hs | |||
@@ -38,12 +38,14 @@ import qualified Crypto.Tox as ToxCrypto | |||
38 | import Network.QueryResponse | 38 | import Network.QueryResponse |
39 | 39 | ||
40 | import Control.Arrow | 40 | import Control.Arrow |
41 | import Control.Concurrent.STM | ||
41 | import Control.Monad | 42 | import Control.Monad |
42 | import Data.Bool | 43 | import Data.Bool |
43 | import qualified Data.ByteString.Char8 as B8 | 44 | import qualified Data.ByteString.Char8 as B8 |
44 | import qualified Data.ByteString as B | 45 | import qualified Data.ByteString as B |
45 | ;import Data.ByteString (ByteString) | 46 | ;import Data.ByteString (ByteString) |
46 | import Data.Functor.Contravariant | 47 | import Data.Functor.Contravariant |
48 | import Data.Maybe | ||
47 | import Data.Monoid | 49 | import Data.Monoid |
48 | import Data.Serialize as S | 50 | import Data.Serialize as S |
49 | import Data.Tuple | 51 | import Data.Tuple |
@@ -89,23 +91,28 @@ mapMessage f (DHTCookie nonce fcookie) = f nonce fcookie | |||
89 | instance Sized Ping where size = ConstSize 1 | 91 | instance Sized Ping where size = ConstSize 1 |
90 | instance Sized Pong where size = ConstSize 1 | 92 | instance Sized Pong where size = ConstSize 1 |
91 | 93 | ||
92 | parseDHTAddr :: (ByteString, SockAddr) -> Either (DHTMessage Encrypted8,NodeInfo) (ByteString,SockAddr) | 94 | parseDHTAddr :: TransportCrypto -> (ByteString, SockAddr) -> IO (Either (DHTMessage Encrypted8,NodeInfo) (ByteString,SockAddr)) |
93 | parseDHTAddr (msg,saddr) | 95 | parseDHTAddr crypto (msg,saddr) |
94 | | Just (typ,bs) <- B.uncons msg | 96 | | Just (typ,bs) <- B.uncons msg |
95 | , let right = Right (msg,saddr) | 97 | , let right = return $ Right (msg,saddr) |
96 | left = either (const right) Left | 98 | left = either (const right) (return . Left) |
97 | = case typ of | 99 | = case typ of |
98 | 0x00 -> left $ direct bs saddr DHTPing | 100 | 0x00 -> left $ direct bs saddr DHTPing |
99 | 0x01 -> left $ direct bs saddr DHTPong | 101 | 0x01 -> left $ direct bs saddr DHTPong |
100 | 0x02 -> left $ direct bs saddr DHTGetNodes | 102 | 0x02 -> left $ direct bs saddr DHTGetNodes |
101 | 0x04 -> left $ direct bs saddr DHTSendNodes | 103 | 0x04 -> left $ direct bs saddr DHTSendNodes |
102 | 0x18 -> left $ direct bs saddr DHTCookieRequest | 104 | 0x18 -> left $ direct bs saddr DHTCookieRequest |
103 | 0x19 -> left $ fanGet bs getCookie (uncurry DHTCookie) (const $ noReplyAddr saddr) | 105 | 0x19 -> do |
106 | cs <- atomically $ readTVar (pendingCookies crypto) | ||
107 | let ni = fromMaybe (noReplyAddr saddr) $ do | ||
108 | (cnt,key) <- lookup saddr cs | ||
109 | either (const Nothing) Just $ nodeInfo (key2id key) saddr | ||
110 | left $ fanGet bs getCookie (uncurry DHTCookie) (const $ ni) | ||
104 | 0x20 -> left $ fanGet bs getDHTReqest (uncurry DHTDHTRequest) (asymNodeInfo saddr . snd) | 111 | 0x20 -> left $ fanGet bs getDHTReqest (uncurry DHTDHTRequest) (asymNodeInfo saddr . snd) |
105 | _ -> right | 112 | _ -> right |
106 | 113 | ||
107 | encodeDHTAddr :: (DHTMessage Encrypted8,NodeInfo) -> (ByteString, SockAddr) | 114 | encodeDHTAddr :: (DHTMessage Encrypted8,NodeInfo) -> IO (ByteString, SockAddr) |
108 | encodeDHTAddr (msg,ni) = (runPut $ putMessage msg, nodeAddr ni) | 115 | encodeDHTAddr (msg,ni) = return (runPut $ putMessage msg, nodeAddr ni) |
109 | 116 | ||
110 | dhtMessageType :: DHTMessage Encrypted8 -> ( Word8, Put ) | 117 | dhtMessageType :: DHTMessage Encrypted8 -> ( Word8, Put ) |
111 | dhtMessageType (DHTPing a) = (0x00, putAsymm a) | 118 | dhtMessageType (DHTPing a) = (0x00, putAsymm a) |
@@ -416,26 +423,26 @@ encryptMessage :: Serialize a => | |||
416 | TransportCrypto -> | 423 | TransportCrypto -> |
417 | PublicKey -> | 424 | PublicKey -> |
418 | Nonce24 -> Either (Nonce8,a) (Asymm (Nonce8,a)) -> Encrypted8 a | 425 | Nonce24 -> Either (Nonce8,a) (Asymm (Nonce8,a)) -> Encrypted8 a |
419 | encryptMessage crypto destKey n (Right asymm) = E8 $ ToxCrypto.encrypt secret plain | 426 | encryptMessage crypto destKey n arg = E8 $ ToxCrypto.encrypt secret plain |
420 | where | 427 | where |
421 | secret = computeSharedSecret (transportSecret crypto) destKey n | 428 | secret = computeSharedSecret (transportSecret crypto) destKey n |
422 | plain = encodePlain $ swap $ asymmData asymm | 429 | plain = encodePlain $ swap $ either id asymmData arg |
423 | encryptMessage crypto destKey n (Left plain) = _todo -- need cached public key. | ||
424 | 430 | ||
425 | decrypt :: TransportCrypto -> DHTMessage Encrypted8 -> NodeInfo -> Either String (DHTMessage ((,) Nonce8), NodeInfo) | 431 | decrypt :: TransportCrypto -> DHTMessage Encrypted8 -> NodeInfo -> Either String (DHTMessage ((,) Nonce8), NodeInfo) |
426 | decrypt crypto msg ni = (, ni) <$> (sequenceMessage $ transcode (decryptMessage crypto) msg) | 432 | decrypt crypto msg ni = do |
433 | msg' <- sequenceMessage $ transcode (\n -> decryptMessage crypto n . left ((,) $ id2key $ nodeId ni)) msg | ||
434 | return (msg', ni) | ||
427 | 435 | ||
428 | decryptMessage :: Serialize x => | 436 | decryptMessage :: Serialize x => |
429 | TransportCrypto | 437 | TransportCrypto |
430 | -> Nonce24 | 438 | -> Nonce24 |
431 | -> Either (Encrypted8 x) (Asymm (Encrypted8 x)) | 439 | -> Either (PublicKey, Encrypted8 x) (Asymm (Encrypted8 x)) |
432 | -> (Either String ∘ ((,) Nonce8)) x | 440 | -> (Either String ∘ ((,) Nonce8)) x |
433 | decryptMessage crypto n (Right asymmE) = plain8 $ ToxCrypto.decrypt secret e | 441 | decryptMessage crypto n arg = plain8 $ ToxCrypto.decrypt secret e |
434 | where | 442 | where |
435 | secret = computeSharedSecret (transportSecret crypto) (senderKey asymmE) n | 443 | secret = computeSharedSecret (transportSecret crypto) remotekey n |
436 | E8 e = asymmData asymmE | 444 | (remotekey,E8 e) = either id (senderKey &&& asymmData) arg |
437 | plain8 = Composed . fmap swap . (>>= decodePlain) | 445 | plain8 = Composed . fmap swap . (>>= decodePlain) |
438 | decryptMessage crypto n (Left (E8 e)) = _todo -- need cached public key | ||
439 | 446 | ||
440 | sequenceMessage :: Applicative m => DHTMessage (m ∘ f) -> m (DHTMessage f) | 447 | sequenceMessage :: Applicative m => DHTMessage (m ∘ f) -> m (DHTMessage f) |
441 | sequenceMessage (DHTPing asym) = fmap DHTPing $ sequenceA $ fmap uncomposed asym | 448 | sequenceMessage (DHTPing asym) = fmap DHTPing $ sequenceA $ fmap uncomposed asym |