diff options
Diffstat (limited to 'src/Network/Tox/Onion/Transport.hs')
-rw-r--r-- | src/Network/Tox/Onion/Transport.hs | 72 |
1 files changed, 69 insertions, 3 deletions
diff --git a/src/Network/Tox/Onion/Transport.hs b/src/Network/Tox/Onion/Transport.hs index 989b06fd..3e3596a6 100644 --- a/src/Network/Tox/Onion/Transport.hs +++ b/src/Network/Tox/Onion/Transport.hs | |||
@@ -17,9 +17,12 @@ | |||
17 | module Network.Tox.Onion.Transport | 17 | module Network.Tox.Onion.Transport |
18 | ( parseOnionAddr | 18 | ( parseOnionAddr |
19 | , encodeOnionAddr | 19 | , encodeOnionAddr |
20 | , parseDataToRoute | ||
21 | , encodeDataToRoute | ||
20 | , forwardOnions | 22 | , forwardOnions |
21 | , OnionDestination(..) | 23 | , OnionDestination(..) |
22 | , OnionMessage(..) | 24 | , OnionMessage(..) |
25 | , Rendezvous(..) | ||
23 | , DataToRoute(..) | 26 | , DataToRoute(..) |
24 | , AnnounceResponse(..) | 27 | , AnnounceResponse(..) |
25 | , AnnounceRequest(..) | 28 | , AnnounceRequest(..) |
@@ -44,7 +47,7 @@ import Network.QueryResponse | |||
44 | import Crypto.Tox hiding (encrypt,decrypt) | 47 | import Crypto.Tox hiding (encrypt,decrypt) |
45 | import Network.Tox.NodeId | 48 | import Network.Tox.NodeId |
46 | import qualified Crypto.Tox as ToxCrypto | 49 | import qualified Crypto.Tox as ToxCrypto |
47 | import Network.Tox.DHT.Transport (NodeInfo(..),NodeId(..),SendNodes(..),nodeInfo,DHTPublicKey,asymNodeInfo) | 50 | import Network.Tox.DHT.Transport (NodeInfo(..),NodeId(..),SendNodes(..),nodeInfo,DHTPublicKey,FriendRequest,asymNodeInfo) |
48 | 51 | ||
49 | import Debug.Trace | 52 | import Debug.Trace |
50 | import Control.Arrow | 53 | import Control.Arrow |
@@ -561,13 +564,39 @@ instance Serialize DataToRoute where | |||
561 | get = DataToRoute <$> getPublicKey <*> get | 564 | get = DataToRoute <$> getPublicKey <*> get |
562 | put (DataToRoute k dta) = putPublicKey k >> put dta | 565 | put (DataToRoute k dta) = putPublicKey k >> put dta |
563 | 566 | ||
564 | data OnionData = OnionDHTPublicKey DHTPublicKey -- 0x9c | 567 | data OnionData |
568 | = -- | type 0x9c | ||
569 | -- | ||
570 | -- We send this packet every 30 seconds if there is more than one peer (in | ||
571 | -- the 8) that says they our friend is announced on them. This packet can | ||
572 | -- also be sent through the DHT module as a DHT request packet (see DHT) if | ||
573 | -- we know the DHT public key of the friend and are looking for them in the | ||
574 | -- DHT but have not connected to them yet. 30 second is a reasonable | ||
575 | -- timeout to not flood the network with too many packets while making sure | ||
576 | -- the other will eventually receive the packet. Since packets are sent | ||
577 | -- through every peer that knows the friend, resending it right away | ||
578 | -- without waiting has a high likelihood of failure as the chances of | ||
579 | -- packet loss happening to all (up to to 8) packets sent is low. | ||
580 | -- | ||
581 | -- If a friend is online and connected to us, the onion will stop all of | ||
582 | -- its actions for that friend. If the peer goes offline it will restart | ||
583 | -- searching for the friend as if toxcore was just started. | ||
584 | OnionDHTPublicKey DHTPublicKey | ||
585 | | -- | type 0x20 | ||
586 | -- | ||
587 | -- | ||
588 | OnionFriendRequest FriendRequest -- 0x20 | ||
565 | 589 | ||
566 | instance Sized OnionData where | 590 | instance Sized OnionData where |
567 | size = VarSize $ \(OnionDHTPublicKey dhtpk) -> case size of | 591 | size = VarSize $ \case |
592 | OnionDHTPublicKey dhtpk -> case size of | ||
568 | ConstSize n -> n -- Override because OnionData probably | 593 | ConstSize n -> n -- Override because OnionData probably |
569 | -- should be treated as variable sized. | 594 | -- should be treated as variable sized. |
570 | VarSize f -> f dhtpk | 595 | VarSize f -> f dhtpk |
596 | -- FIXME: inconsitantly, we have to add in the tag byte for this case. | ||
597 | OnionFriendRequest req -> 1 + case size of | ||
598 | ConstSize n -> n | ||
599 | VarSize f -> f req | ||
571 | 600 | ||
572 | encrypt :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> (OnionMessage Encrypted, OnionDestination r) | 601 | encrypt :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> (OnionMessage Encrypted, OnionDestination r) |
573 | encrypt crypto msg rpath = ( transcode ( (. (runIdentity . either id assymData)) | 602 | encrypt crypto msg rpath = ( transcode ( (. (runIdentity . either id assymData)) |
@@ -625,12 +654,14 @@ sequenceMessage (OnionAnnounce a) = fmap OnionAnnounce $ sequenceA $ fmap | |||
625 | sequenceMessage (OnionAnnounceResponse n8 n24 dta) = OnionAnnounceResponse n8 n24 <$> uncomposed dta | 654 | sequenceMessage (OnionAnnounceResponse n8 n24 dta) = OnionAnnounceResponse n8 n24 <$> uncomposed dta |
626 | sequenceMessage (OnionToRoute pub a) = pure $ OnionToRoute pub a | 655 | sequenceMessage (OnionToRoute pub a) = pure $ OnionToRoute pub a |
627 | sequenceMessage (OnionToRouteResponse a) = pure $ OnionToRouteResponse a | 656 | sequenceMessage (OnionToRouteResponse a) = pure $ OnionToRouteResponse a |
657 | -- sequenceMessage (OnionToRouteResponse a) = fmap OnionToRouteResponse $ sequenceA $ fmap uncomposed a | ||
628 | 658 | ||
629 | transcode :: forall f g. (forall a. Serialize a => Nonce24 -> Either (f a) (Assym (f a)) -> g a) -> OnionMessage f -> OnionMessage g | 659 | transcode :: forall f g. (forall a. Serialize a => Nonce24 -> Either (f a) (Assym (f a)) -> g a) -> OnionMessage f -> OnionMessage g |
630 | transcode f (OnionAnnounce a) = OnionAnnounce $ a { assymData = f (assymNonce a) (Right a) } | 660 | transcode f (OnionAnnounce a) = OnionAnnounce $ a { assymData = f (assymNonce a) (Right a) } |
631 | transcode f (OnionAnnounceResponse n8 n24 dta) = OnionAnnounceResponse n8 n24 $ f n24 $ Left dta | 661 | transcode f (OnionAnnounceResponse n8 n24 dta) = OnionAnnounceResponse n8 n24 $ f n24 $ Left dta |
632 | transcode f (OnionToRoute pub a) = OnionToRoute pub a | 662 | transcode f (OnionToRoute pub a) = OnionToRoute pub a |
633 | transcode f (OnionToRouteResponse a) = OnionToRouteResponse a | 663 | transcode f (OnionToRouteResponse a) = OnionToRouteResponse a |
664 | -- transcode f (OnionToRouteResponse a) = OnionToRouteResponse $ a { assymData = f (assymNonce a) (Right a) } | ||
634 | 665 | ||
635 | 666 | ||
636 | data OnionRoute = OnionRoute | 667 | data OnionRoute = OnionRoute |
@@ -673,3 +704,38 @@ wrapOnion :: Serialize (Forwarding n msg) => | |||
673 | -> Forwarding (S n) msg | 704 | -> Forwarding (S n) msg |
674 | wrapOnion skey nonce destkey saddr fwd = | 705 | wrapOnion skey nonce destkey saddr fwd = |
675 | Forwarding (toPublic skey) $ encryptMessage skey destkey nonce (Addressed saddr fwd) | 706 | Forwarding (toPublic skey) $ encryptMessage skey destkey nonce (Addressed saddr fwd) |
707 | |||
708 | |||
709 | -- TODO | ||
710 | -- Two types of packets may be sent to Rendezvous via OnionToRoute requests. | ||
711 | -- | ||
712 | -- (1) DHT public key packet (0x9c) | ||
713 | -- | ||
714 | -- (2) Friend request | ||
715 | data Rendezvous = Rendezvous | ||
716 | { rendezvousKey :: PublicKey | ||
717 | , rendezvousNode :: NodeInfo | ||
718 | } | ||
719 | deriving Eq | ||
720 | |||
721 | instance Show Rendezvous where | ||
722 | show (Rendezvous k ni) = concat [show $ key2id k, ":", show ni] | ||
723 | |||
724 | |||
725 | |||
726 | parseDataToRoute | ||
727 | :: TransportCrypto | ||
728 | -> (OnionMessage Encrypted,OnionDestination r) | ||
729 | -> Either (Assym (Encrypted DataToRoute),Rendezvous) (OnionMessage Encrypted, OnionDestination r) | ||
730 | parseDataToRoute crypto (OnionToRouteResponse dta, od) | ||
731 | = Left ( dta | ||
732 | , Rendezvous (onionAliasPublic crypto) $ onionNodeInfo od ) | ||
733 | parseDataToRoute _ msg = Right msg | ||
734 | |||
735 | encodeDataToRoute :: TransportCrypto | ||
736 | -> (Assym (Encrypted DataToRoute),Rendezvous) | ||
737 | -> Maybe (OnionMessage Encrypted,OnionDestination r) | ||
738 | encodeDataToRoute crypto (dta, Rendezvous pub ni) | ||
739 | = Just ( OnionToRoute pub -- Public key of destination node | ||
740 | dta | ||
741 | , OnionDestination ni Nothing ) | ||