summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-08-11 01:08:30 -0400
committerjoe <joe@jerkface.net>2017-08-11 01:08:30 -0400
commitcd5091c4a3ab1c05b48ff3ad2fea666d77b8e39c (patch)
tree45bd1073d40830e6311bbaf8021899fec236abbc
parent85a004ac92cac382a8c2824ca6b584764ab7782d (diff)
Reply to Announce with AnnounceResponse.
-rw-r--r--Tox.hs144
-rw-r--r--ToxMessage.hs124
-rw-r--r--src/Network/QueryResponse.hs10
3 files changed, 182 insertions, 96 deletions
diff --git a/Tox.hs b/Tox.hs
index a14e223b..4459a08f 100644
--- a/Tox.hs
+++ b/Tox.hs
@@ -3,6 +3,7 @@
3{-# LANGUAGE DeriveFunctor #-} 3{-# LANGUAGE DeriveFunctor #-}
4{-# LANGUAGE DeriveGeneric #-} 4{-# LANGUAGE DeriveGeneric #-}
5{-# LANGUAGE DeriveTraversable #-} 5{-# LANGUAGE DeriveTraversable #-}
6{-# LANGUAGE ExistentialQuantification #-}
6{-# LANGUAGE FlexibleInstances #-} 7{-# LANGUAGE FlexibleInstances #-}
7{-# LANGUAGE GeneralizedNewtypeDeriving #-} 8{-# LANGUAGE GeneralizedNewtypeDeriving #-}
8{-# LANGUAGE NamedFieldPuns #-} 9{-# LANGUAGE NamedFieldPuns #-}
@@ -12,6 +13,8 @@
12{-# LANGUAGE TupleSections #-} 13{-# LANGUAGE TupleSections #-}
13module Tox where 14module Tox where
14 15
16import Debug.Trace
17import Control.Exception hiding (Handler)
15import Control.Applicative 18import Control.Applicative
16import Control.Arrow 19import Control.Arrow
17import Control.Concurrent (MVar) 20import Control.Concurrent (MVar)
@@ -75,10 +78,11 @@ import System.IO
75import qualified Text.ParserCombinators.ReadP as RP 78import qualified Text.ParserCombinators.ReadP as RP
76import Text.Printf 79import Text.Printf
77import Text.Read 80import Text.Read
78import qualified ToxMessage as Tox 81import ToxMessage as Tox hiding (Ping,Pong,SendNodes,GetNodes,AnnounceResponse)
79 ;import ToxMessage (bin2hex, quoted) 82 ;import ToxMessage (bin2hex, quoted)
80import TriadCommittee 83import TriadCommittee
81import Network.BitTorrent.DHT.Token as Token 84import Network.BitTorrent.DHT.Token as Token
85import GHC.TypeLits
82 86
83{- 87{-
84newtype NodeId = NodeId ByteString 88newtype NodeId = NodeId ByteString
@@ -235,53 +239,13 @@ data TransactionId = TransactionId
235 , cryptoNonce :: Tox.Nonce24 -- ^ Used during the encryption layer. 239 , cryptoNonce :: Tox.Nonce24 -- ^ Used during the encryption layer.
236 } 240 }
237 241
238pattern PingType = Tox.PacketKind 0 -- 0x00 Ping Request
239pattern PongType = Tox.PacketKind 1 -- 0x01 Ping Response
240pattern GetNodesType = Tox.PacketKind 2 -- 0x02 Nodes Request
241pattern SendNodesType = Tox.PacketKind 4 -- 0x04 Nodes Response
242-- 0x18 Cookie Request 242-- 0x18 Cookie Request
243-- 0x19 Cookie Response 243-- 0x19 Cookie Response
244-- 0x1a Crypto Handshake 244-- 0x1a Crypto Handshake
245-- 0x1b Crypto Data 245-- 0x1b Crypto Data
246 246
247-- TODO: Auth fail:
248pattern DHTRequestType = Tox.PacketKind 32 -- 0x20 DHT Request
249
250-- 0x21 LAN Discovery 247-- 0x21 LAN Discovery
251 248
252-- TODO: Auth fail:
253pattern OnionRequest0 = Tox.PacketKind 128 -- 0x80 Onion Request 0
254pattern OnionRequest1 = Tox.PacketKind 129 -- 0x81 Onion Request 1
255pattern OnionRequest2 = Tox.PacketKind 130 -- 0x82 Onion Request 2
256pattern AnnounceType = Tox.PacketKind 131 -- 0x83 Announce Request
257pattern AnnounceResponseType = Tox.PacketKind 132 -- 0x84 Announce Response
258-- 0x85 Onion Data Request (data to route request packet)
259-- 0x86 Onion Data Response (data to route response packet)
260-- 0x8c Onion Response 3
261-- 0x8d Onion Response 2
262pattern OnionResponse1 = Tox.PacketKind 142 -- 0x8e Onion Response 1
263-- 0xf0 Bootstrap Info
264
265-- TODO Fix these fails...
266-- GetNodesType decipherAndAuth: auth fail
267-- MessageType 128 decipherAndAuth: auth fail
268-- MessageType 129 decipherAndAuth: auth fail
269-- MessageType 130 decipherAndAuth: auth fail
270-- MessageType 131 decipherAndAuth: auth fail
271-- MessageType 32 decipherAndAuth: auth fail
272
273
274instance Show Tox.PacketKind where
275 showsPrec d PingType = mappend "PingType"
276 showsPrec d PongType = mappend "PongType"
277 showsPrec d GetNodesType = mappend "GetNodesType"
278 showsPrec d SendNodesType = mappend "SendNodesType"
279 showsPrec d DHTRequestType = mappend "DHTRequestType"
280 showsPrec d OnionRequest0 = mappend "OnionRequest0"
281 showsPrec d OnionResponse1 = mappend "OnionResponse1"
282 showsPrec d AnnounceType = mappend "AnnounceType"
283 showsPrec d (Tox.PacketKind x) = mappend "PacketKind " . showsPrec (d+1) x
284
285{- 249{-
286newtype Tox.Nonce24 = Tox.Nonce24 ByteString 250newtype Tox.Nonce24 = Tox.Nonce24 ByteString
287 deriving (Eq, Ord, ByteArrayAccess) 251 deriving (Eq, Ord, ByteArrayAccess)
@@ -317,8 +281,8 @@ data Msg = Msg
317 deriving Show 281 deriving Show
318 282
319 283
320typeHasEncryptedPayload OnionResponse1 = False 284-- typeHasEncryptedPayload OnionResponse1Type = False
321typeHasEncryptedPayload _ = True 285-- typeHasEncryptedPayload _ = True
322 286
323{- 287{-
324msgDHTKey Message{ msgOrigin, msgType = PingType } = Just msgOrigin 288msgDHTKey Message{ msgOrigin, msgType = PingType } = Just msgOrigin
@@ -579,42 +543,60 @@ encodePacket sk cache msg ni = ( S.runPut . putMessage $ encryptMessage sk cache
579 , nodeAddr ni ) 543 , nodeAddr ni )
580-} 544-}
581 545
546data ToxPath = forall n. (Tox.OnionPacket n) => ToxPath NodeInfo (Tox.ReturnPath n)
547
548instance Show ToxPath where
549 show (ToxPath ni rpath)
550 | natVal rpath == 0 = show ni
551 | otherwise = "Aliased("++show ni++")"
552
582msgLayer :: SecretKey 553msgLayer :: SecretKey
583 -> NodeId 554 -> NodeId
584 -> Transport String NodeInfo (Tox.PacketKind,InterediateRep) 555 -> Transport String ToxPath (Tox.PacketKind,InterediateRep)
585 -> Transport String NodeInfo Msg 556 -> Transport String ToxPath Msg
586msgLayer sk pk = layerTransport parse serialize 557msgLayer sk pk = layerTransport parse serialize
587 where 558 where
559 parse :: (Tox.PacketKind,InterediateRep) -> ToxPath -> Either String (Msg,ToxPath)
588 parse (typ,Assym x) addr = fmap (,addr) $ decryptAssymetric sk typ x 560 parse (typ,Assym x) addr = fmap (,addr) $ decryptAssymetric sk typ x
589 parse (typ,Assym' x) addr = fmap (,addr) $ decryptAssymetric sk typ x 561 parse (typ,Assym' x) addr = fmap (,addr) $ decryptAssymetric sk typ x
590 parse (typ,Unclm n x) addr = Right ( Msg typ (Tox.assymetricNonce x) (S.encode (Tox.assymetricData x)) n 562 parse (typ,Unclm n x) addr = Right ( Msg typ (Tox.assymetricNonce x) (S.encode (Tox.assymetricData x)) n
591 , addr) 563 , addr)
592 serialize x addr = case Tox.pktClass (msgType x) of 564 serialize :: Msg -> ToxPath -> ((Tox.PacketKind,InterediateRep),ToxPath)
593 Tox.AssymetricClass {} -> ((msgType x, Assym $ encryptAssymetric sk pk (nodeId addr) x), addr) 565 serialize x addr@(ToxPath ni _) = case Tox.pktClass (msgType x) of
594 Tox.AliasedClass {} -> ((msgType x, Assym' $ encryptAssymetric sk pk (nodeId addr) x), addr) 566 Tox.AssymetricClass {} -> ((msgType x, Assym $ encryptAssymetric sk pk (nodeId ni) x), addr)
595 Tox.NoncedUnclaimedClass {} -> ((msgType x, Unclm (msgSendBack x) $ encryptUnclm sk pk (nodeId addr) x),addr) 567 Tox.AliasedClass {} -> ((msgType x, Assym' $ encryptAssymetric sk pk (nodeId ni) x), addr)
568 Tox.NoncedUnclaimedClass {} -> ((msgType x, Unclm (msgSendBack x) $ encryptUnclm sk pk (nodeId ni) x),addr)
596 569
597data InterediateRep = Assym Tox.Assymetric 570data InterediateRep = Assym Tox.Assymetric
598 | Assym' Tox.Assymetric 571 | Assym' Tox.Assymetric
599 | Unclm Tox.Nonce8 Tox.UnclaimedAssymetric 572 | Unclm Tox.Nonce8 Tox.UnclaimedAssymetric
600 573
601asymLayer :: Transport String SockAddr Tox.Packet -> Transport String NodeInfo (Tox.PacketKind,InterediateRep) 574asymLayer :: Transport String SockAddr Tox.Packet -> Transport String ToxPath (Tox.PacketKind,InterediateRep)
602asymLayer = layerTransport parse serialize 575asymLayer = layerTransport parse (\p@(typ,_) -> trace ("SERIALIZE "++show typ) $ serialize p)
603 where 576 where
577 parse :: Tox.Packet -> SockAddr -> Either String ((Tox.PacketKind,InterediateRep),ToxPath)
604 parse x addr = case Tox.pktClass (Tox.pktKind x) of 578 parse x addr = case Tox.pktClass (Tox.pktKind x) of
605 Tox.AssymetricClass top fromp -> go Tox.senderKey fromp Assym 579 Tox.AssymetricClass top fromp -> go Tox.senderKey fromp Assym
606 Tox.AliasedClass top fromp -> go Tox.senderKey ((\(Tox.Aliased a) -> a) . fromp) Assym' 580 Tox.AliasedClass top fromp -> let (Tox.Aliased a,rpath) = fromp x
581 in fmap (\ni -> ( (Tox.pktKind x, Assym' a)
582 , ToxPath ni rpath ))
583 $ nodeInfo (Tox.senderKey a) addr
607 Tox.NoncedUnclaimedClass top fromp -> go (const zeroID) fromp (uncurry Unclm) 584 Tox.NoncedUnclaimedClass top fromp -> go (const zeroID) fromp (uncurry Unclm)
585 -- OnionClass
608 where go mkaddr fromp c = let y = fromp x 586 where go mkaddr fromp c = let y = fromp x
609 in fmap ((Tox.pktKind x,c y),) 587 in fmap ( ((Tox.pktKind x,c y),)
610 $ nodeInfo (mkaddr y) addr 588 . (\ni -> ToxPath ni Tox.emptyReturnPath)
589 )
590 $ nodeInfo (mkaddr y) addr
611 591
612 serialize (typ,Assym assym) addr = (x,nodeAddr addr) 592 serialize :: (Tox.PacketKind,InterediateRep) -> ToxPath -> (Tox.Packet,SockAddr)
593 serialize (typ,Assym assym) (ToxPath addr rpath) = (x,nodeAddr addr)
613 where x = case Tox.pktClass typ of Tox.AssymetricClass top _ -> top assym 594 where x = case Tox.pktClass typ of Tox.AssymetricClass top _ -> top assym
614 serialize (typ,Assym' assym) addr = (x,nodeAddr addr) 595 serialize (typ,Assym' assym) (ToxPath addr rpath) = (x,nodeAddr addr) -- TODO rpath
615 where x = case Tox.pktClass typ of Tox.AliasedClass top _ -> top (Tox.Aliased assym) 596 where x = case Tox.pktClass typ of Tox.AliasedClass top _ -> top (Tox.Aliased assym, error "todo: ReturnPath")
616 serialize (typ,Unclm nonce unclm) addr = (x,nodeAddr addr) 597 serialize (typ,Unclm nonce unclm) (ToxPath addr rpath) = (Tox.mkOnion rpath x,nodeAddr addr)
617 where x = case Tox.pktClass typ of Tox.NoncedUnclaimedClass top _ -> top nonce unclm 598 where x = case Tox.pktClass typ of Tox.NoncedUnclaimedClass top _ -> top nonce unclm
599 -- OnionClass
618 600
619toxLayer :: Transport String SockAddr ByteString -> Transport String SockAddr Tox.Packet 601toxLayer :: Transport String SockAddr ByteString -> Transport String SockAddr Tox.Packet
620toxLayer = layerTransport (\x addr -> (,addr) <$> S.decode x) 602toxLayer = layerTransport (\x addr -> (,addr) <$> S.decode x)
@@ -630,7 +612,7 @@ data Routing = Routing
630 , committee6 :: TriadCommittee NodeId SockAddr 612 , committee6 :: TriadCommittee NodeId SockAddr
631 } 613 }
632 614
633type ToxClient = Client String Tox.PacketKind TransactionId NodeInfo Msg 615type ToxClient = Client String Tox.PacketKind TransactionId ToxPath Msg
634 616
635encodePayload :: S.Serialize b => Tox.PacketKind -> TransactionId -> addr -> addr -> b -> Msg 617encodePayload :: S.Serialize b => Tox.PacketKind -> TransactionId -> addr -> addr -> b -> Msg
636encodePayload typ (TransactionId nonce8 nonce24) _ _ b = Msg typ nonce24 (S.encode b) nonce8 618encodePayload typ (TransactionId nonce8 nonce24) _ _ b = Msg typ nonce24 (S.encode b) nonce8
@@ -645,6 +627,7 @@ trimPackets addr bs = do
645 GetNodesType -> Just id 627 GetNodesType -> Just id
646 AnnounceType -> Just id 628 AnnounceType -> Just id
647 AnnounceResponseType -> Just id 629 AnnounceResponseType -> Just id
630 OnionResponse3Type -> Just id
648 _ -> Nothing 631 _ -> Nothing
649 632
650newClient :: SockAddr -> IO (ToxClient, Routing) 633newClient :: SockAddr -> IO (ToxClient, Routing)
@@ -767,14 +750,15 @@ newClient addr = do
767 -> ToxClient 750 -> ToxClient
768 mkclient (tbl,var) handlers = Client 751 mkclient (tbl,var) handlers = Client
769 { clientNet = net 752 { clientNet = net
770 , clientDispatcher = dispatch tbl var handlers 753 , clientDispatcher = dispatch tbl var (fmap (contramapAddr (\(ToxPath ni _) -> ni)) . handlers)
771 , clientErrorReporter = (printErrors stderr) { reportTimeout = reportTimeout ignoreErrors } 754 , clientErrorReporter = (printErrors stderr) { reportTimeout = reportTimeout ignoreErrors }
772 , clientPending = var 755 , clientPending = var
773 , clientAddress = \maddr -> atomically $ do 756 , clientAddress = \maddr -> atomically $ do
774 let var = case flip prefer4or6 Nothing <$> maddr of 757 let var = case flip prefer4or6 Nothing . (\(ToxPath ni _) -> ni) <$> maddr of
775 Just Want_IP6 -> routing6 routing 758 Just Want_IP6 -> routing6 routing
776 _ -> routing4 routing 759 _ -> routing4 routing
777 R.thisNode <$> readTVar var 760 a <- readTVar var
761 return $ ToxPath (R.thisNode a) Tox.emptyReturnPath
778 , clientResponseId = genNonce24 var 762 , clientResponseId = genNonce24 var
779 } 763 }
780 764
@@ -847,6 +831,7 @@ addVerbosity2 tr =
847 forM_ m $ mapM_ $ \(msg,addr) -> do 831 forM_ m $ mapM_ $ \(msg,addr) -> do
848 hPutStrLn stderr ( (show addr) 832 hPutStrLn stderr ( (show addr)
849 ++ " -2-> " ++ show (Tox.PacketKind $ B.head msg)) 833 ++ " -2-> " ++ show (Tox.PacketKind $ B.head msg))
834 -- forM_ (xxd 0 msg) (hPutStrLn stderr)
850 kont m 835 kont m
851 , sendMessage = \addr msg -> do 836 , sendMessage = \addr msg -> do
852 hPutStrLn stderr ( (show addr) 837 hPutStrLn stderr ( (show addr)
@@ -863,16 +848,19 @@ classify (Msg { msgType = typ
863 , msgNonce = nonce24 }) = go $ TransactionId nonce8 nonce24 848 , msgNonce = nonce24 }) = go $ TransactionId nonce8 nonce24
864 where 849 where
865 go = case typ of 850 go = case typ of
866 PingType -> IsQuery typ 851 PingType -> IsQuery typ
867 GetNodesType -> IsQuery typ 852 GetNodesType -> IsQuery typ
868 PongType -> IsResponse 853 PongType -> IsResponse
869 SendNodesType -> IsResponse 854 SendNodesType -> IsResponse
870 DHTRequestType -> IsQuery typ 855 OnionResponse1Type -> IsResponse
871 OnionRequest0 -> IsQuery typ 856 OnionResponse2Type -> IsResponse
872 OnionRequest1 -> IsQuery typ 857 OnionResponse3Type -> IsResponse
873 OnionRequest2 -> IsQuery typ 858 DHTRequestType -> IsQuery typ
874 AnnounceType -> IsQuery typ 859 OnionRequest0Type -> IsQuery typ
875 _ -> const $ IsUnknown ("Unknown message type: "++show typ) 860 OnionRequest1Type -> IsQuery typ
861 OnionRequest2Type -> IsQuery typ
862 AnnounceType -> IsQuery typ
863 _ -> const $ IsUnknown ("Unknown message type: "++show typ)
876 864
877{- 865{-
878encodePayload typ (TransactionId (Tox.Nonce8 tid) nonce) self dest b 866encodePayload typ (TransactionId (Tox.Nonce8 tid) nonce) self dest b
@@ -905,13 +893,14 @@ transitionCommittee committee (RoutingTransition ni Stranger) = do
905 hPutStrLn stderr $ "delVote "++show (nodeId ni) 893 hPutStrLn stderr $ "delVote "++show (nodeId ni)
906transitionCommittee committee _ = return $ return () 894transitionCommittee committee _ = return $ return ()
907 895
908updateRouting :: ToxClient -> Routing -> NodeInfo -> (Tox.PacketKind, InterediateRep) -> IO () 896updateRouting :: ToxClient -> Routing -> ToxPath -> (Tox.PacketKind, InterediateRep) -> IO ()
909updateRouting client routing naddr (typ,Assym msg) = do 897updateRouting client routing (ToxPath naddr _) (typ,Assym msg) = do
910 hPutStrLn stderr $ "updateRouting "++show typ 898 hPutStrLn stderr $ "updateRouting "++show typ
911 case prefer4or6 naddr Nothing of 899 case prefer4or6 naddr Nothing of
912 Want_IP4 -> updateTable client naddr (routing4 routing) (committee4 routing) (sched4 routing) 900 Want_IP4 -> updateTable client naddr (routing4 routing) (committee4 routing) (sched4 routing)
913 Want_IP6 -> updateTable client naddr (routing6 routing) (committee6 routing) (sched6 routing) 901 Want_IP6 -> updateTable client naddr (routing6 routing) (committee6 routing) (sched6 routing)
914updateRouting _ _ _ _ = return () 902updateRouting _ _ _ (typ,_) = do
903 hPutStrLn stderr $ "updateRouting (ignored) "++show typ
915 904
916updateTable client naddr tbl committee sched = do 905updateTable client naddr tbl committee sched = do
917 self <- atomically $ R.thisNode <$> readTVar tbl 906 self <- atomically $ R.thisNode <$> readTVar tbl
@@ -1180,6 +1169,7 @@ announceH routing toks keydb naddr req = do
1180 _ | Nonce32 bs <- announcePingId req 1169 _ | Nonce32 bs <- announcePingId req
1181 , let tok = fromPaddedByteString 32 bs 1170 , let tok = fromPaddedByteString 32 bs
1182 -> checkToken toks naddr tok >>= go 1171 -> checkToken toks naddr tok >>= go
1172 `catch` (\(SomeException e) -> hPutStrLn stderr ("announceH Exception! "++show e) >> throw e)
1183 where 1173 where
1184 go withTok = do 1174 go withTok = do
1185 ns <- getNodesH routing naddr (GetNodes (announceSeeking req)) 1175 ns <- getNodesH routing naddr (GetNodes (announceSeeking req))
@@ -1302,7 +1292,7 @@ gen g = let (bs, g') = randomBytesGenerate 24 g
1302 1292
1303 1293
1304toxSend meth unwrap msg client nid addr = do 1294toxSend meth unwrap msg client nid addr = do
1305 reply <- sendQuery client serializer (msg nid) addr 1295 reply <- sendQuery client serializer (msg nid) (ToxPath addr Tox.emptyReturnPath)
1306 -- sendQuery will return (Just (Left _)) on a parse error. We're going to 1296 -- sendQuery will return (Just (Left _)) on a parse error. We're going to
1307 -- blow it away with the join-either sequence. 1297 -- blow it away with the join-either sequence.
1308 -- TODO: Do something with parse errors. 1298 -- TODO: Do something with parse errors.
diff --git a/ToxMessage.hs b/ToxMessage.hs
index 9ea57d27..06026b49 100644
--- a/ToxMessage.hs
+++ b/ToxMessage.hs
@@ -1,9 +1,15 @@
1{-# LANGUAGE PatternSynonyms #-}
1{-# LANGUAGE GeneralizedNewtypeDeriving #-} 2{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2{-# LANGUAGE DeriveFunctor, DeriveTraversable,DeriveDataTypeable #-} 3{-# LANGUAGE DeriveFunctor, DeriveTraversable,DeriveDataTypeable #-}
3{-# LANGUAGE GADTs #-} 4{-# LANGUAGE GADTs #-}
4{-# LANGUAGE FlexibleInstances #-} 5{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE ScopedTypeVariables #-}
7{-# LANGUAGE TypeApplications #-}
8{-# LANGUAGE ExistentialQuantification #-}
9{-# LANGUAGE DataKinds, KindSignatures #-}
5module ToxMessage where 10module ToxMessage where
6 11
12import Debug.Trace
7import Data.ByteString (ByteString) 13import Data.ByteString (ByteString)
8import qualified Crypto.MAC.Poly1305 as Poly1305 (Auth(..)) 14import qualified Crypto.MAC.Poly1305 as Poly1305 (Auth(..))
9import qualified Crypto.PubKey.Curve25519 as Curve25519 15import qualified Crypto.PubKey.Curve25519 as Curve25519
@@ -23,6 +29,8 @@ import Foreign.Ptr
23import Foreign.Marshal.Alloc 29import Foreign.Marshal.Alloc
24import System.Endian 30import System.Endian
25import Foreign.Storable 31import Foreign.Storable
32import GHC.TypeLits
33import Data.Tuple
26 34
27newtype Auth = Auth Poly1305.Auth 35newtype Auth = Auth Poly1305.Auth
28 deriving (Eq, ByteArrayAccess) 36 deriving (Eq, ByteArrayAccess)
@@ -165,6 +173,17 @@ instance Serialize (Aliased Assymetric) where
165newtype Cookie = Cookie UnclaimedAssymetric 173newtype Cookie = Cookie UnclaimedAssymetric
166 deriving (Eq, Ord,Data) 174 deriving (Eq, Ord,Data)
167 175
176newtype ReturnPath (n::Nat) = ReturnPath ByteString
177 deriving (Eq, Ord,Data)
178
179emptyReturnPath :: ReturnPath 0
180emptyReturnPath = ReturnPath B.empty
181
182instance KnownNat n => Serialize (ReturnPath n) where
183 -- Size: 59 = 1(family) + 16(ip) + 2(port) +16(mac) + 24(nonce)
184 get = ReturnPath <$> getBytes ( 59 * (fromIntegral $ natVal $ Proxy @n) )
185 put (ReturnPath bs) = putByteString bs
186
168data Symmetric = Symmetric 187data Symmetric = Symmetric
169 { symmetricNonce :: Nonce24 188 { symmetricNonce :: Nonce24
170 , symmetricAuth :: Auth 189 , symmetricAuth :: Auth
@@ -209,10 +228,10 @@ data Packet where
209 -- 228 --
210 -- If the return path is non empty, we should respond with OnionResponse3 229 -- If the return path is non empty, we should respond with OnionResponse3
211 -- rather than AnnounceResponse directly. 230 -- rather than AnnounceResponse directly.
212 Announce :: Aliased Assymetric -> Packet --0x83 231 Announce :: Aliased Assymetric -> ReturnPath 3 -> Packet --0x83
213 AnnounceResponse :: Nonce8 -> UnclaimedAssymetric -> Packet -- 0x84 232 AnnounceResponse :: Nonce8 -> UnclaimedAssymetric -> Packet -- 0x84
214 233
215 OnionResponse3 :: Symmetric -> ByteString -> Packet -- 0x8c 234 OnionResponse3 :: ReturnPath 3 -> Packet -> Packet -- 0x8c
216 OnionResponse2 :: Symmetric -> ByteString -> Packet -- 0x8d 235 OnionResponse2 :: Symmetric -> ByteString -> Packet -- 0x8d
217 OnionResponse1 :: Symmetric -> ByteString -> Packet -- 0x8e 236 OnionResponse1 :: Symmetric -> ByteString -> Packet -- 0x8e
218 237
@@ -222,9 +241,59 @@ data Packet where
222 241
223 deriving (Eq, Ord,Data) 242 deriving (Eq, Ord,Data)
224 243
244class KnownNat n => OnionPacket n where
245 mkOnion :: ReturnPath n -> Packet -> Packet
246
247instance OnionPacket 0 where mkOnion _ = id
248instance OnionPacket 3 where mkOnion = OnionResponse3
249
225newtype PacketKind = PacketKind Word8 250newtype PacketKind = PacketKind Word8
226 deriving (Eq, Ord, Serialize) 251 deriving (Eq, Ord, Serialize)
227 252
253-- TODO: Auth fail:
254pattern OnionRequest0Type = PacketKind 128 -- 0x80 Onion Request 0
255pattern OnionRequest1Type = PacketKind 129 -- 0x81 Onion Request 1
256pattern OnionRequest2Type = PacketKind 130 -- 0x82 Onion Request 2
257pattern AnnounceType = PacketKind 131 -- 0x83 Announce Request
258pattern AnnounceResponseType = PacketKind 132 -- 0x84 Announce Response
259-- 0x85 Onion Data Request (data to route request packet)
260-- 0x86 Onion Data Response (data to route response packet)
261-- 0x8c Onion Response 3
262-- 0x8d Onion Response 2
263pattern OnionResponse3Type = PacketKind 140 -- 0x8c Onion Response 3
264pattern OnionResponse2Type = PacketKind 141 -- 0x8d Onion Response 2
265pattern OnionResponse1Type = PacketKind 142 -- 0x8e Onion Response 1
266-- 0xf0 Bootstrap Info
267
268-- TODO Fix these fails...
269-- GetNodesType decipherAndAuth: auth fail
270-- MessageType 128 decipherAndAuth: auth fail
271-- MessageType 129 decipherAndAuth: auth fail
272-- MessageType 130 decipherAndAuth: auth fail
273-- MessageType 131 decipherAndAuth: auth fail
274-- MessageType 32 decipherAndAuth: auth fail
275
276-- TODO: Auth fail:
277pattern DHTRequestType = PacketKind 32 -- 0x20 DHT Request
278
279pattern PingType = PacketKind 0 -- 0x00 Ping Request
280pattern PongType = PacketKind 1 -- 0x01 Ping Response
281pattern GetNodesType = PacketKind 2 -- 0x02 Nodes Request
282pattern SendNodesType = PacketKind 4 -- 0x04 Nodes Response
283
284
285instance Show PacketKind where
286 showsPrec d PingType = mappend "PingType"
287 showsPrec d PongType = mappend "PongType"
288 showsPrec d GetNodesType = mappend "GetNodesType"
289 showsPrec d SendNodesType = mappend "SendNodesType"
290 showsPrec d DHTRequestType = mappend "DHTRequestType"
291 showsPrec d OnionRequest0Type = mappend "OnionRequest0"
292 showsPrec d OnionResponse1Type = mappend "OnionResponse1"
293 showsPrec d OnionResponse3Type = mappend "OnionResponse3"
294 showsPrec d AnnounceType = mappend "AnnounceType"
295 showsPrec d (PacketKind x) = mappend "PacketKind " . showsPrec (d+1) x
296
228pktKind :: Packet -> PacketKind 297pktKind :: Packet -> PacketKind
229 298
230-- These are (Assymetric -> Assymetric) queries. 299-- These are (Assymetric -> Assymetric) queries.
@@ -286,10 +355,25 @@ pktKind OnionResponse3 {} = PacketKind 0x8c
286 355
287data PacketClass = 356data PacketClass =
288 AssymetricClass (Assymetric -> Packet) (Packet -> Assymetric) 357 AssymetricClass (Assymetric -> Packet) (Packet -> Assymetric)
289 | AliasedClass (Aliased Assymetric -> Packet) (Packet -> Aliased Assymetric) 358 | forall n. OnionPacket n => AliasedClass ((Aliased Assymetric,ReturnPath n) -> Packet) (Packet -> (Aliased Assymetric,ReturnPath n))
359 | forall n. OnionPacket n => OnionClass ((Packet,ReturnPath n) -> Packet) (Packet -> (Packet,ReturnPath n))
290 | NoncedUnclaimedClass (Nonce8 -> UnclaimedAssymetric -> Packet) 360 | NoncedUnclaimedClass (Nonce8 -> UnclaimedAssymetric -> Packet)
291 (Packet -> (Nonce8, UnclaimedAssymetric)) 361 (Packet -> (Nonce8, UnclaimedAssymetric))
292 | Unclassified 362 | Unclassified
363{-
364data Packet' where
365 :: Assymetric -> Packet
366 :: UnclaimedAssymetric -> Packet
367 :: Word16 -> ImplicitAssymetric -> Packet
368 :: PubKey -> Assymetric -> Packet
369 :: PubKey -> Packet
370 :: Aliased Assymetric -> Symmetric -> Packet
371 :: ByteString -> Symmetric -> Packet
372 :: Aliased Assymetric -> Packet
373 :: Symmetric -> ByteString -> Packet
374 :: ByteString -> Packet
375 :: Word32 -> ByteString -> Packet
376-}
293 377
294pktClass :: PacketKind -> PacketClass 378pktClass :: PacketKind -> PacketClass
295pktClass (PacketKind 0) = AssymetricClass Ping (\(Ping a) -> a) 379pktClass (PacketKind 0) = AssymetricClass Ping (\(Ping a) -> a)
@@ -301,9 +385,11 @@ pktClass (PacketKind 0x18) = AssymetricClass CookieRequest (\(CookieRequest a) -
301pktClass (PacketKind 0x80) = AssymetricClass OnionRequest0 (\(OnionRequest0 a) -> a) 385pktClass (PacketKind 0x80) = AssymetricClass OnionRequest0 (\(OnionRequest0 a) -> a)
302-- pktClass (PacketKind 0x86) = AssymetricClass (DataToRouteResponse . Aliased) (\(DataToRouteResponse (Aliased a)) -> a) 386-- pktClass (PacketKind 0x86) = AssymetricClass (DataToRouteResponse . Aliased) (\(DataToRouteResponse (Aliased a)) -> a)
303 387
304pktClass (PacketKind 0x83) = AliasedClass Announce (\(Announce a)-> a) 388pktClass (PacketKind 0x83) = AliasedClass (uncurry Announce) (\(Announce a r)-> (a,r))
305pktClass (PacketKind 0x84) = NoncedUnclaimedClass AnnounceResponse (\(AnnounceResponse n8 uncl)-> (n8,uncl)) 389pktClass (PacketKind 0x84) = NoncedUnclaimedClass AnnounceResponse (\(AnnounceResponse n8 uncl)-> (n8,uncl))
306 390
391pktClass (PacketKind 0x8c) = OnionClass (uncurry OnionResponse3 . swap) (\(OnionResponse3 r a)-> (a,r))
392
307pktClass _ = Unclassified 393pktClass _ = Unclassified
308 394
309 395
@@ -315,27 +401,27 @@ getPacket = do
315 typ <- get 401 typ <- get
316 case pktClass typ of 402 case pktClass typ of
317 AssymetricClass toPacket _ -> toPacket <$> get 403 AssymetricClass toPacket _ -> toPacket <$> get
318 AliasedClass toPacket _ -> toPacket <$> get 404 AliasedClass toPacket _ -> do
405 trace ("PARSE "++show typ) $ return ()
406 cnt <- remaining
407 a <- isolate (cnt - 59*3) get
408 r <- get
409 trace ("PARSED "++show typ) $ return ()
410 return $ toPacket (a,r)
411 OnionClass toPacket _ -> do
412 trace ("ONION-PARSE "++show typ) $ return ()
413 p <- get
414 trace ("ONION-PARSED "++show typ) $ return ()
415 return $ toPacket p
319 NoncedUnclaimedClass toPacket _ -> toPacket <$> get <*> get 416 NoncedUnclaimedClass toPacket _ -> toPacket <$> get <*> get
417 Unclassified -> fail $ "todo: unserialize packet "++show typ
320 418
321putPacket p = do 419putPacket p = do
322 put $ pktKind p 420 put $ pktKind p
323 case pktClass (pktKind p) of 421 case pktClass (pktKind p) of
324 AssymetricClass _ fromPacket -> put $ fromPacket p 422 AssymetricClass _ fromPacket -> put $ fromPacket p
325 AliasedClass _ fromPacket -> put $ fromPacket p 423 AliasedClass _ fromPacket -> put $ fromPacket p
424 OnionClass _ fromPacket -> put $ swap $ fromPacket p
326 NoncedUnclaimedClass _ fromPacket -> put $ fromPacket p -- putting a pair. 425 NoncedUnclaimedClass _ fromPacket -> put $ fromPacket p -- putting a pair.
426 Unclassified -> fail $ "todo: serialize packet "++show (pktKind p)
327 427
328{-
329data Packet' where
330 :: Assymetric -> Packet
331 :: UnclaimedAssymetric -> Packet
332 :: Word16 -> ImplicitAssymetric -> Packet
333 :: PubKey -> Assymetric -> Packet
334 :: PubKey -> Packet
335 :: Aliased Assymetric -> Symmetric -> Packet
336 :: ByteString -> Symmetric -> Packet
337 :: Aliased Assymetric -> Packet
338 :: Symmetric -> ByteString -> Packet
339 :: ByteString -> Packet
340 :: Word32 -> ByteString -> Packet
341-}
diff --git a/src/Network/QueryResponse.hs b/src/Network/QueryResponse.hs
index 190cc73e..11fe7c32 100644
--- a/src/Network/QueryResponse.hs
+++ b/src/Network/QueryResponse.hs
@@ -181,6 +181,16 @@ data MethodHandler err tid addr x = forall a b. MethodHandler
181 , noreplyAction :: addr -> a -> IO () 181 , noreplyAction :: addr -> a -> IO ()
182 } 182 }
183 183
184contramapAddr :: (a -> b) -> MethodHandler err tid b x -> MethodHandler err tid a x
185contramapAddr f (MethodHandler p s a)
186 = MethodHandler
187 p
188 (\tid src dst result -> s tid (f src) (f dst) result)
189 (\addr arg -> a (f addr) arg)
190contramapAddr f (NoReply p a)
191 = NoReply p (\addr arg -> a (f addr) arg)
192
193
184-- | Attempt to invoke a 'MethodHandler' upon a given inbound query. If the 194-- | Attempt to invoke a 'MethodHandler' upon a given inbound query. If the
185-- parse is successful, the returned IO action will construct our reply if 195-- parse is successful, the returned IO action will construct our reply if
186-- there is one. Otherwise, a parse err is returned. 196-- there is one. Otherwise, a parse err is returned.