summaryrefslogtreecommitdiff
path: root/ToxTransport.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-08-31 14:37:35 -0400
committerjoe <joe@jerkface.net>2017-08-31 14:37:35 -0400
commit74de5c3d86dfdc000f0abab0d465109417932ffe (patch)
tree1b94e4684a58bf1d85b9fd85f991d29eca757f12 /ToxTransport.hs
parent538edb705c9f3ffed25603f96ed118f9c41494aa (diff)
Forward DHTRequest messages.
Diffstat (limited to 'ToxTransport.hs')
-rw-r--r--ToxTransport.hs191
1 files changed, 84 insertions, 107 deletions
diff --git a/ToxTransport.hs b/ToxTransport.hs
index 855b0c7e..694d9d79 100644
--- a/ToxTransport.hs
+++ b/ToxTransport.hs
@@ -8,13 +8,43 @@
8{-# LANGUAGE TypeOperators #-} 8{-# LANGUAGE TypeOperators #-}
9module ToxTransport 9module ToxTransport
10 ( toxTransport 10 ( toxTransport
11 , TransportCrypto 11
12 , TransportCrypto(..)
13 , SymmetricKey(..)
14 , Encrypted8(..)
15
12 , UDPTransport 16 , UDPTransport
13 , DirectMessage 17
14 , Encrypted8 18 -- DHTTransport
15 , OnionToOwner 19 , DHTMessage(..)
16 , OnionMessage 20 , Ping
17 , NetCrypto 21 , Pong
22 , GetNodes
23 , SendNodes
24 , CookieRequest
25 , Cookie
26 , DHTRequest
27
28 -- OnionTransport
29 , OnionToOwner(..)
30 , OnionMessage(..)
31 , DataToRoute(..)
32 , AnnounceResponse(..)
33 , AnnounceRequest(..)
34 , Forwarding(..)
35 , ReturnPath(..)
36 , OnionRequest(..)
37 , OnionResponse(..)
38 , Addressed(..)
39
40 -- CryptoTransport
41 , NetCrypto(..)
42 , CryptoData(..)
43 , CryptoMessage(..)
44 , CryptoPacket(..)
45 , HandshakeData(..)
46 , Handshake(..)
47
18 ) where 48 ) where
19 49
20import Network.QueryResponse 50import Network.QueryResponse
@@ -25,6 +55,7 @@ import ToxPacket
25import Control.Applicative 55import Control.Applicative
26import Control.Arrow 56import Control.Arrow
27import Control.Concurrent.STM 57import Control.Concurrent.STM
58import Control.Monad
28import Crypto.Hash 59import Crypto.Hash
29import Crypto.Hash.Algorithms 60import Crypto.Hash.Algorithms
30import qualified Data.ByteString as B 61import qualified Data.ByteString as B
@@ -44,59 +75,37 @@ data TransportCrypto = TransportCrypto
44 , transportSymmetric :: STM SymmetricKey 75 , transportSymmetric :: STM SymmetricKey
45 } 76 }
46 77
47transportDecrypt :: TransportCrypto -> Assym (Encrypted a) -> Either String a
48transportDecrypt = _todo
49
50-- layer :: TransportCrypto
51 -- -> Transport String SockAddr ByteString
52 -- -> Transport String Tox.Address ByteString
53-- layer crypto = layerTransport (toxParse crypto) (toxEncode crypto)
54
55toxEncode :: TransportCrypto -> ByteString -> Tox.Address -> (ByteString, SockAddr)
56toxEncode = _todo
57
58-- toxParse :: TransportCrypto -> ByteString -> SockAddr -> Either String (ByteString, Tox.Address)
59-- toxParse crypto bs saddr = case B.head bs of _todo
60
61data Message = Todo | DHTReq DHTRequest | AnnounceReq AnnounceRequest
62
63-- awaitMessage :: forall a. (Maybe (Either err (x, addr)) -> IO a) -> IO a
64
65type UDPTransport = Transport String SockAddr ByteString 78type UDPTransport = Transport String SockAddr ByteString
79type DHTTransport = Transport String NodeInfo (DHTMessage Encrypted8)
66 80
67{-
68toxTransport :: TransportCrypto -> Transport String SockAddr ByteString -> Transport String Tox.Address Message
69toxTransport crypto (Transport await send close) = Transport await' send' close
70 where
71 await' :: HandleHi a -> IO a
72 await' forMe = fix $ await . handleOnion crypto forMe
73
74 send' = _todo
75-}
76toxTransport :: 81toxTransport ::
77 TransportCrypto 82 TransportCrypto
83 -> (PublicKey -> IO (Maybe NodeInfo))
78 -> UDPTransport 84 -> UDPTransport
79 -> IO ( Transport String NodeInfo (DirectMessage Encrypted8) 85 -> IO ( Transport String NodeInfo (DHTMessage Encrypted8)
80 , Transport String OnionToOwner (OnionMessage Encrypted) 86 , Transport String OnionToOwner (OnionMessage Encrypted)
81 , Transport String SockAddr NetCrypto ) 87 , Transport String SockAddr NetCrypto )
82toxTransport crypto udp = do 88toxTransport crypto closeLookup udp = do
83 (dht,udp1) <- partitionTransport parseDHTAddr encodeDHTAddr id $ handleOnion crypto udp 89 (dht,udp1) <- partitionTransport parseDHTAddr encodeDHTAddr id $ forwardOnions crypto udp
84 (onion,udp2) <- partitionTransport parseOnionAddr encodeOnionAddr id udp1 90 (onion,udp2) <- partitionTransport parseOnionAddr encodeOnionAddr id udp1
85 let netcrypto = layerTransport parseNetCrypto encodeNetCrypto udp2 91 let netcrypto = layerTransport parseNetCrypto encodeNetCrypto udp2
86 return (dht,onion,netcrypto) 92 return ( forwardDHTRequests crypto closeLookup dht
93 , onion
94 , netcrypto
95 )
87 96
88 97
89type HandleHi a = Maybe (Either String (Message, Tox.Address)) -> IO a 98type HandleHi a = Maybe (Either String (DHTMessage Encrypted8, NodeInfo)) -> IO a
90type HandleLo a = Maybe (Either String (ByteString, SockAddr)) -> IO a 99type HandleLo a = Maybe (Either String (ByteString, SockAddr)) -> IO a
91 100
92data DirectMessage (f :: * -> *) 101data DHTMessage (f :: * -> *)
93 = DirectPing (Assym (f Ping)) 102 = DHTPing (Assym (f Ping))
94 | DirectPong (Assym (f Pong)) 103 | DHTPong (Assym (f Pong))
95 | DirectGetNodes (Assym (f GetNodes)) 104 | DHTGetNodes (Assym (f GetNodes))
96 | DirectSendNodes (Assym (f SendNodes)) 105 | DHTSendNodes (Assym (f SendNodes))
97 | DirectCookieRequest (Assym (f CookieRequest)) 106 | DHTCookieRequest (Assym (f CookieRequest))
98 | DirectCookie Nonce24 (f Cookie) 107 | DHTCookie Nonce24 (f Cookie)
99 | DirectDHTRequest PublicKey (Assym (f DHTRequest)) 108 | DHTDHTRequest PublicKey (Assym (f DHTRequest))
100 109
101instance Sized GetNodes where 110instance Sized GetNodes where
102 size = ConstSize 32 -- TODO This right? 111 size = ConstSize 32 -- TODO This right?
@@ -112,8 +121,8 @@ newtype Encrypted8 a = E8 (Encrypted (a,Nonce8))
112 121
113-- instance (Sized a, Sized b) => Sized (a,b) where size = _todo 122-- instance (Sized a, Sized b) => Sized (a,b) where size = _todo
114 123
115getDirect :: Sized a => Get (Assym (Encrypted8 a)) 124getDHT :: Sized a => Get (Assym (Encrypted8 a))
116getDirect = _todo 125getDHT = _todo
117 126
118getOnionAssym :: Get (Assym (Encrypted DataToRoute)) 127getOnionAssym :: Get (Assym (Encrypted DataToRoute))
119getOnionAssym = _todo 128getOnionAssym = _todo
@@ -131,9 +140,9 @@ fanGet bs getIt f nid = fmap (f &&& nid) $ runGet getIt bs
131direct :: Sized a => ByteString 140direct :: Sized a => ByteString
132 -> SockAddr 141 -> SockAddr
133 -> (Assym (Encrypted8 a) 142 -> (Assym (Encrypted8 a)
134 -> DirectMessage Encrypted8) 143 -> DHTMessage Encrypted8)
135 -> Either String (DirectMessage Encrypted8, NodeInfo) 144 -> Either String (DHTMessage Encrypted8, NodeInfo)
136direct bs saddr f = fanGet bs getDirect f (asymNodeInfo saddr) 145direct bs saddr f = fanGet bs getDHT f (asymNodeInfo saddr)
137 146
138-- Throws an error if called with a non-internet socket. 147-- Throws an error if called with a non-internet socket.
139asymNodeInfo saddr asym = either (error . mappend "asymNodeInfo: ") id $ nodeInfo (NodeId $ senderKey asym) saddr 148asymNodeInfo saddr asym = either (error . mappend "asymNodeInfo: ") id $ nodeInfo (NodeId $ senderKey asym) saddr
@@ -141,22 +150,22 @@ asymNodeInfo saddr asym = either (error . mappend "asymNodeInfo: ") id $ nodeInf
141-- Throws an error if called with a non-internet socket. 150-- Throws an error if called with a non-internet socket.
142noReplyAddr saddr = either (error . mappend "noReplyAddr: ") id $ nodeInfo zeroID saddr 151noReplyAddr saddr = either (error . mappend "noReplyAddr: ") id $ nodeInfo zeroID saddr
143 152
144parseDHTAddr :: (ByteString, SockAddr) -> Either (DirectMessage Encrypted8,NodeInfo) (ByteString,SockAddr) 153parseDHTAddr :: (ByteString, SockAddr) -> Either (DHTMessage Encrypted8,NodeInfo) (ByteString,SockAddr)
145parseDHTAddr (msg,saddr) 154parseDHTAddr (msg,saddr)
146 | Just (typ,bs) <- B.uncons msg 155 | Just (typ,bs) <- B.uncons msg
147 , let right = Right (msg,saddr) 156 , let right = Right (msg,saddr)
148 left = either (const right) Left 157 left = either (const right) Left
149 = case typ of 158 = case typ of
150 0x00 -> left $ direct bs saddr DirectPing 159 0x00 -> left $ direct bs saddr DHTPing
151 0x01 -> left $ direct bs saddr DirectPong 160 0x01 -> left $ direct bs saddr DHTPong
152 0x02 -> left $ direct bs saddr DirectGetNodes 161 0x02 -> left $ direct bs saddr DHTGetNodes
153 0x04 -> left $ direct bs saddr DirectSendNodes 162 0x04 -> left $ direct bs saddr DHTSendNodes
154 0x18 -> left $ direct bs saddr DirectCookieRequest 163 0x18 -> left $ direct bs saddr DHTCookieRequest
155 0x19 -> left $ fanGet bs getCookie (uncurry DirectCookie) (const $ noReplyAddr saddr) 164 0x19 -> left $ fanGet bs getCookie (uncurry DHTCookie) (const $ noReplyAddr saddr)
156 0x20 -> left $ fanGet bs getDHTReqest (uncurry DirectDHTRequest) (asymNodeInfo saddr . snd) 165 0x20 -> left $ fanGet bs getDHTReqest (uncurry DHTDHTRequest) (asymNodeInfo saddr . snd)
157 _ -> right 166 _ -> right
158 167
159encodeDHTAddr :: (DirectMessage Encrypted8,NodeInfo) -> (ByteString, SockAddr) 168encodeDHTAddr :: (DHTMessage Encrypted8,NodeInfo) -> (ByteString, SockAddr)
160encodeDHTAddr = _todo 169encodeDHTAddr = _todo
161 170
162 171
@@ -327,8 +336,8 @@ data CryptoMessage -- First byte indicates data
327-- `0x8d` Onion Response 2 -return 336-- `0x8d` Onion Response 2 -return
328-- `0x8e` Onion Response 1 -return 337-- `0x8e` Onion Response 1 -return
329 338
330handleOnion :: TransportCrypto -> UDPTransport -> UDPTransport -- HandleHi a -> IO a -> HandleLo a 339forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport -- HandleHi a -> IO a -> HandleLo a
331handleOnion crypto udp = udp { awaitMessage = await' } 340forwardOnions crypto udp = udp { awaitMessage = await' }
332 where 341 where
333 -- forMe :: HandleHi 342 -- forMe :: HandleHi
334 -- forThem :: handleLo 343 -- forThem :: handleLo
@@ -349,45 +358,24 @@ forward :: forall c b b1.
349 (Maybe (Either String b1) -> c) -> ByteString -> (b -> c) -> c 358 (Maybe (Either String b1) -> c) -> ByteString -> (b -> c) -> c
350forward forMe bs f = either (forMe . Just . Left) f $ decode $ B.tail bs 359forward forMe bs f = either (forMe . Just . Left) f $ decode $ B.tail bs
351 360
352parseMessage :: Word8 -> ByteString -> Either String (Message,Address)
353-- Announce :: Aliased Assymetric -> ReturnPath 3 -> Packet --0x83
354parseMessage 0x83 bs = _todo -- Announce Request OnionToOwner
355parseMessage _ _ = _todo
356 361
357handleDHTRequest :: forall a. TransportCrypto -> SockAddr -> HandleHi a -> IO a -> DHTRequestPacket -> IO a 362forwardDHTRequests :: TransportCrypto -> (PublicKey -> IO (Maybe NodeInfo)) -> DHTTransport -> DHTTransport
358handleDHTRequest crypto saddr forMe forThem (DHTRequestPacket target payload) 363forwardDHTRequests crypto closeLookup dht = dht { awaitMessage = await' }
359 | target == transportPublic crypto = forMe' payload
360 | otherwise = _todo -- lookup target in close list, forward message
361 >> forThem
362 where 364 where
363 forMe' :: Assym (Encrypted DHTRequest) -> IO a 365 await' :: HandleHi a -> IO a
364 forMe' payload = do 366 await' pass = awaitMessage dht $ \case
365 case (,) <$> transportDecrypt crypto payload <*> eaddr of 367 Just (Right (m@(DHTDHTRequest target payload),src)) | target /= transportPublic crypto
366 Left e -> forMe (Just (Left e)) 368 -> do mni <- closeLookup target
367 Right (p,addr) -> forMe (Just (Right (DHTReq p,addr))) 369 -- Forward the message if the target is in our close list.
368 370 forM_ mni $ \ni -> sendMessage dht ni m
369 eaddr :: Either String Tox.Address 371 await' pass
370 eaddr = fmap DHTNode $ nodeInfo (NodeId $ senderKey payload) saddr 372 m -> pass m
371
372data Attributed a = Attributed
373 { author :: PublicKey
374 , attributedNonce :: Nonce24
375 , attributed :: a
376 }
377
378-- `0x83` Announce Request OnionToOwner
379-- `0x85` Onion Data Request OnionToOwner
380data OPacket -- payload of an onion request
381
382 373
383-- `0x84` Announce Response -
384-- `0x86` Onion Data Response -
385data RPacket -- payload of an onion response
386 374
387-- n = 0, 1, 2 375-- n = 0, 1, 2
388data OnionRequest (n :: Nat) = OnionRequest 376data OnionRequest (n :: Nat) = OnionRequest
389 { onionNonce :: Nonce24 377 { onionNonce :: Nonce24
390 , onionForward :: Forwarding (3 - n) OPacket 378 , onionForward :: Forwarding (3 - n) (OnionMessage Encrypted)
391 , pathFromOwner :: ReturnPath n 379 , pathFromOwner :: ReturnPath n
392 } 380 }
393 381
@@ -399,7 +387,7 @@ instance Serialize (OnionResponse n) where { get = _todo; put = _todo }
399 387
400data OnionResponse (n :: Nat) = OnionResponse 388data OnionResponse (n :: Nat) = OnionResponse
401 { pathToOwner :: ReturnPath n 389 { pathToOwner :: ReturnPath n
402 , msgToOwner :: RPacket 390 , msgToOwner :: OnionMessage Encrypted
403 } 391 }
404 392
405data Addressed a = Addressed { sockAddr :: SockAddr, unaddressed :: a } 393data Addressed a = Addressed { sockAddr :: SockAddr, unaddressed :: a }
@@ -410,7 +398,7 @@ data ReturnPath (n :: Nat) where
410 398
411data Forwarding (n :: Nat) msg where 399data Forwarding (n :: Nat) msg where
412 NotForwarded :: msg -> Forwarding 0 msg 400 NotForwarded :: msg -> Forwarding 0 msg
413 Forwarding :: Attributed (Encrypted (Addressed (Forwarding n msg))) -> Forwarding (n + 1) msg 401 Forwarding :: Assym (Encrypted (Addressed (Forwarding n msg))) -> Forwarding (n + 1) msg
414 402
415handleOnionRequest :: KnownNat n => proxy n -> TransportCrypto -> SockAddr -> IO a -> OnionRequest n -> IO a 403handleOnionRequest :: KnownNat n => proxy n -> TransportCrypto -> SockAddr -> IO a -> OnionRequest n -> IO a
416handleOnionRequest = _todo 404handleOnionRequest = _todo
@@ -418,17 +406,6 @@ handleOnionRequest = _todo
418handleOnionResponse :: KnownNat n => proxy n -> TransportCrypto -> SockAddr -> IO a -> OnionResponse n -> IO a 406handleOnionResponse :: KnownNat n => proxy n -> TransportCrypto -> SockAddr -> IO a -> OnionResponse n -> IO a
419handleOnionResponse = _todo 407handleOnionResponse = _todo
420 408
421{-
422data Size a = ConstSize Int
423 | VarSize (a -> Int)
424
425data PacketChunk a
426 = Plain a
427 | Assymetric a
428 | Symmetric a
429 -}
430
431
432data AnnounceRequest = AnnounceRequest 409data AnnounceRequest = AnnounceRequest
433 { announcePingId :: Nonce32 -- Ping ID 410 { announcePingId :: Nonce32 -- Ping ID
434 , announceSeeking :: NodeId -- Public key we are searching for 411 , announceSeeking :: NodeId -- Public key we are searching for