diff options
author | joe <joe@jerkface.net> | 2017-08-31 14:37:35 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-08-31 14:37:35 -0400 |
commit | 74de5c3d86dfdc000f0abab0d465109417932ffe (patch) | |
tree | 1b94e4684a58bf1d85b9fd85f991d29eca757f12 /ToxTransport.hs | |
parent | 538edb705c9f3ffed25603f96ed118f9c41494aa (diff) |
Forward DHTRequest messages.
Diffstat (limited to 'ToxTransport.hs')
-rw-r--r-- | ToxTransport.hs | 191 |
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 #-} |
9 | module ToxTransport | 9 | module 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 | ||
20 | import Network.QueryResponse | 50 | import Network.QueryResponse |
@@ -25,6 +55,7 @@ import ToxPacket | |||
25 | import Control.Applicative | 55 | import Control.Applicative |
26 | import Control.Arrow | 56 | import Control.Arrow |
27 | import Control.Concurrent.STM | 57 | import Control.Concurrent.STM |
58 | import Control.Monad | ||
28 | import Crypto.Hash | 59 | import Crypto.Hash |
29 | import Crypto.Hash.Algorithms | 60 | import Crypto.Hash.Algorithms |
30 | import qualified Data.ByteString as B | 61 | import qualified Data.ByteString as B |
@@ -44,59 +75,37 @@ data TransportCrypto = TransportCrypto | |||
44 | , transportSymmetric :: STM SymmetricKey | 75 | , transportSymmetric :: STM SymmetricKey |
45 | } | 76 | } |
46 | 77 | ||
47 | transportDecrypt :: TransportCrypto -> Assym (Encrypted a) -> Either String a | ||
48 | transportDecrypt = _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 | |||
55 | toxEncode :: TransportCrypto -> ByteString -> Tox.Address -> (ByteString, SockAddr) | ||
56 | toxEncode = _todo | ||
57 | |||
58 | -- toxParse :: TransportCrypto -> ByteString -> SockAddr -> Either String (ByteString, Tox.Address) | ||
59 | -- toxParse crypto bs saddr = case B.head bs of _todo | ||
60 | |||
61 | data Message = Todo | DHTReq DHTRequest | AnnounceReq AnnounceRequest | ||
62 | |||
63 | -- awaitMessage :: forall a. (Maybe (Either err (x, addr)) -> IO a) -> IO a | ||
64 | |||
65 | type UDPTransport = Transport String SockAddr ByteString | 78 | type UDPTransport = Transport String SockAddr ByteString |
79 | type DHTTransport = Transport String NodeInfo (DHTMessage Encrypted8) | ||
66 | 80 | ||
67 | {- | ||
68 | toxTransport :: TransportCrypto -> Transport String SockAddr ByteString -> Transport String Tox.Address Message | ||
69 | toxTransport 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 | -} | ||
76 | toxTransport :: | 81 | toxTransport :: |
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 ) |
82 | toxTransport crypto udp = do | 88 | toxTransport 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 | ||
89 | type HandleHi a = Maybe (Either String (Message, Tox.Address)) -> IO a | 98 | type HandleHi a = Maybe (Either String (DHTMessage Encrypted8, NodeInfo)) -> IO a |
90 | type HandleLo a = Maybe (Either String (ByteString, SockAddr)) -> IO a | 99 | type HandleLo a = Maybe (Either String (ByteString, SockAddr)) -> IO a |
91 | 100 | ||
92 | data DirectMessage (f :: * -> *) | 101 | data 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 | ||
101 | instance Sized GetNodes where | 110 | instance 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 | ||
115 | getDirect :: Sized a => Get (Assym (Encrypted8 a)) | 124 | getDHT :: Sized a => Get (Assym (Encrypted8 a)) |
116 | getDirect = _todo | 125 | getDHT = _todo |
117 | 126 | ||
118 | getOnionAssym :: Get (Assym (Encrypted DataToRoute)) | 127 | getOnionAssym :: Get (Assym (Encrypted DataToRoute)) |
119 | getOnionAssym = _todo | 128 | getOnionAssym = _todo |
@@ -131,9 +140,9 @@ fanGet bs getIt f nid = fmap (f &&& nid) $ runGet getIt bs | |||
131 | direct :: Sized a => ByteString | 140 | direct :: 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) |
136 | direct bs saddr f = fanGet bs getDirect f (asymNodeInfo saddr) | 145 | direct 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. |
139 | asymNodeInfo saddr asym = either (error . mappend "asymNodeInfo: ") id $ nodeInfo (NodeId $ senderKey asym) saddr | 148 | asymNodeInfo 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. |
142 | noReplyAddr saddr = either (error . mappend "noReplyAddr: ") id $ nodeInfo zeroID saddr | 151 | noReplyAddr saddr = either (error . mappend "noReplyAddr: ") id $ nodeInfo zeroID saddr |
143 | 152 | ||
144 | parseDHTAddr :: (ByteString, SockAddr) -> Either (DirectMessage Encrypted8,NodeInfo) (ByteString,SockAddr) | 153 | parseDHTAddr :: (ByteString, SockAddr) -> Either (DHTMessage Encrypted8,NodeInfo) (ByteString,SockAddr) |
145 | parseDHTAddr (msg,saddr) | 154 | parseDHTAddr (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 | ||
159 | encodeDHTAddr :: (DirectMessage Encrypted8,NodeInfo) -> (ByteString, SockAddr) | 168 | encodeDHTAddr :: (DHTMessage Encrypted8,NodeInfo) -> (ByteString, SockAddr) |
160 | encodeDHTAddr = _todo | 169 | encodeDHTAddr = _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 | ||
330 | handleOnion :: TransportCrypto -> UDPTransport -> UDPTransport -- HandleHi a -> IO a -> HandleLo a | 339 | forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport -- HandleHi a -> IO a -> HandleLo a |
331 | handleOnion crypto udp = udp { awaitMessage = await' } | 340 | forwardOnions 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 |
350 | forward forMe bs f = either (forMe . Just . Left) f $ decode $ B.tail bs | 359 | forward forMe bs f = either (forMe . Just . Left) f $ decode $ B.tail bs |
351 | 360 | ||
352 | parseMessage :: Word8 -> ByteString -> Either String (Message,Address) | ||
353 | -- Announce :: Aliased Assymetric -> ReturnPath 3 -> Packet --0x83 | ||
354 | parseMessage 0x83 bs = _todo -- Announce Request OnionToOwner | ||
355 | parseMessage _ _ = _todo | ||
356 | 361 | ||
357 | handleDHTRequest :: forall a. TransportCrypto -> SockAddr -> HandleHi a -> IO a -> DHTRequestPacket -> IO a | 362 | forwardDHTRequests :: TransportCrypto -> (PublicKey -> IO (Maybe NodeInfo)) -> DHTTransport -> DHTTransport |
358 | handleDHTRequest crypto saddr forMe forThem (DHTRequestPacket target payload) | 363 | forwardDHTRequests 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 | |||
372 | data 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 | ||
380 | data OPacket -- payload of an onion request | ||
381 | |||
382 | 373 | ||
383 | -- `0x84` Announce Response - | ||
384 | -- `0x86` Onion Data Response - | ||
385 | data RPacket -- payload of an onion response | ||
386 | 374 | ||
387 | -- n = 0, 1, 2 | 375 | -- n = 0, 1, 2 |
388 | data OnionRequest (n :: Nat) = OnionRequest | 376 | data 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 | ||
400 | data OnionResponse (n :: Nat) = OnionResponse | 388 | data OnionResponse (n :: Nat) = OnionResponse |
401 | { pathToOwner :: ReturnPath n | 389 | { pathToOwner :: ReturnPath n |
402 | , msgToOwner :: RPacket | 390 | , msgToOwner :: OnionMessage Encrypted |
403 | } | 391 | } |
404 | 392 | ||
405 | data Addressed a = Addressed { sockAddr :: SockAddr, unaddressed :: a } | 393 | data Addressed a = Addressed { sockAddr :: SockAddr, unaddressed :: a } |
@@ -410,7 +398,7 @@ data ReturnPath (n :: Nat) where | |||
410 | 398 | ||
411 | data Forwarding (n :: Nat) msg where | 399 | data 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 | ||
415 | handleOnionRequest :: KnownNat n => proxy n -> TransportCrypto -> SockAddr -> IO a -> OnionRequest n -> IO a | 403 | handleOnionRequest :: KnownNat n => proxy n -> TransportCrypto -> SockAddr -> IO a -> OnionRequest n -> IO a |
416 | handleOnionRequest = _todo | 404 | handleOnionRequest = _todo |
@@ -418,17 +406,6 @@ handleOnionRequest = _todo | |||
418 | handleOnionResponse :: KnownNat n => proxy n -> TransportCrypto -> SockAddr -> IO a -> OnionResponse n -> IO a | 406 | handleOnionResponse :: KnownNat n => proxy n -> TransportCrypto -> SockAddr -> IO a -> OnionResponse n -> IO a |
419 | handleOnionResponse = _todo | 407 | handleOnionResponse = _todo |
420 | 408 | ||
421 | {- | ||
422 | data Size a = ConstSize Int | ||
423 | | VarSize (a -> Int) | ||
424 | |||
425 | data PacketChunk a | ||
426 | = Plain a | ||
427 | | Assymetric a | ||
428 | | Symmetric a | ||
429 | -} | ||
430 | |||
431 | |||
432 | data AnnounceRequest = AnnounceRequest | 409 | data 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 |