diff options
Diffstat (limited to 'src/Data')
-rw-r--r-- | src/Data/Tox/Relay.hs | 96 |
1 files changed, 95 insertions, 1 deletions
diff --git a/src/Data/Tox/Relay.hs b/src/Data/Tox/Relay.hs index e35f49f0..a5366f85 100644 --- a/src/Data/Tox/Relay.hs +++ b/src/Data/Tox/Relay.hs | |||
@@ -1,10 +1,19 @@ | |||
1 | {-# LANGUAGE DeriveDataTypeable #-} | 1 | {-# LANGUAGE DeriveDataTypeable #-} |
2 | {-# LANGUAGE FlexibleInstances #-} | ||
3 | {-# LANGUAGE KindSignatures #-} | ||
4 | {-# LANGUAGE MultiParamTypeClasses #-} | ||
5 | {-# LANGUAGE ConstraintKinds #-} | ||
2 | module Data.Tox.Relay where | 6 | module Data.Tox.Relay where |
3 | 7 | ||
4 | import Data.ByteString | 8 | import Crypto.Error |
9 | import Data.ByteArray as BA | ||
10 | import Data.ByteString as B | ||
5 | import Data.Data | 11 | import Data.Data |
12 | import Data.Functor.Contravariant | ||
13 | import Data.Monoid | ||
6 | import Data.Serialize | 14 | import Data.Serialize |
7 | import Data.Word | 15 | import Data.Word |
16 | import qualified Rank2 | ||
8 | 17 | ||
9 | import Crypto.Tox | 18 | import Crypto.Tox |
10 | import Network.Tox.Onion.Transport | 19 | import Network.Tox.Onion.Transport |
@@ -29,6 +38,24 @@ packetNumber :: RelayPacket -> Word8 | |||
29 | packetNumber (RelayData conid _) = conid -- 0 to 15 not allowed. | 38 | packetNumber (RelayData conid _) = conid -- 0 to 15 not allowed. |
30 | packetNumber rp = fromIntegral $ pred $ constrIndex $ toConstr rp | 39 | packetNumber rp = fromIntegral $ pred $ constrIndex $ toConstr rp |
31 | 40 | ||
41 | instance Sized RelayPacket where | ||
42 | size = mappend (ConstSize 1) $ VarSize $ \x -> case x of | ||
43 | RoutingRequest k -> 32 | ||
44 | RoutingResponse rpid k -> 33 | ||
45 | ConnectNotification conid -> 1 | ||
46 | DisconnectNotification conid -> 1 | ||
47 | RelayPing pingid -> 8 | ||
48 | RelayPong pingid -> 8 | ||
49 | OOBSend k bs -> 32 + B.length bs | ||
50 | OOBRecv k bs -> 32 + B.length bs | ||
51 | OnionPacket query -> case contramap (`asTypeOf` query) size of | ||
52 | ConstSize n -> n | ||
53 | VarSize f -> f query | ||
54 | OnionPacketResponse answer -> case contramap (`asTypeOf` answer) size of | ||
55 | ConstSize n -> n | ||
56 | VarSize f -> f answer | ||
57 | RelayData _ bs -> B.length bs | ||
58 | |||
32 | instance Serialize RelayPacket where | 59 | instance Serialize RelayPacket where |
33 | 60 | ||
34 | get = do | 61 | get = do |
@@ -60,3 +87,70 @@ instance Serialize RelayPacket where | |||
60 | OnionPacket query -> put query | 87 | OnionPacket query -> put query |
61 | OnionPacketResponse answer -> put answer | 88 | OnionPacketResponse answer -> put answer |
62 | RelayData _ bs -> putByteString bs | 89 | RelayData _ bs -> putByteString bs |
90 | |||
91 | -- | Initial client-to-server handshake message. | ||
92 | data Hello (f :: * -> *) = Hello | ||
93 | { helloFrom :: PublicKey | ||
94 | , helloNonce :: Nonce24 | ||
95 | , helloData :: f HelloData | ||
96 | } | ||
97 | |||
98 | instance Rank2.Functor Hello where | ||
99 | f <$> Hello k n dta = Hello k n (f dta) | ||
100 | |||
101 | instance Payload Serialize Hello where | ||
102 | mapPayload _ f (Hello k n dta) = Hello k n (f dta) | ||
103 | |||
104 | instance Rank2.Foldable Hello where | ||
105 | foldMap f (Hello k n dta) = f dta | ||
106 | |||
107 | instance Rank2.Traversable Hello where | ||
108 | traverse f (Hello k n dta) = Hello k n <$> f dta | ||
109 | |||
110 | instance Sized (Hello Encrypted) where | ||
111 | size = ConstSize 56 <> contramap helloData size | ||
112 | |||
113 | instance Serialize (Hello Encrypted) where | ||
114 | get = do CryptoPassed k <- publicKey <$> getBytes 32 | ||
115 | n <- get | ||
116 | dta <- get | ||
117 | return $ Hello k n dta | ||
118 | put (Hello k n dta) = do mapM_ putWord8 $ BA.unpack k | ||
119 | put n | ||
120 | put dta | ||
121 | |||
122 | data HelloData = HelloData | ||
123 | { sessionPublicKey :: PublicKey | ||
124 | , sessionBaseNonce :: Nonce24 | ||
125 | } | ||
126 | |||
127 | instance Sized HelloData where size = ConstSize 56 | ||
128 | |||
129 | instance Serialize HelloData where | ||
130 | get = HelloData <$> (id2key <$> get) <*> get | ||
131 | put (HelloData k n) = put (key2id k) >> put n | ||
132 | |||
133 | -- | Handshake server-to-client response packet. | ||
134 | data Welcome (f :: * -> *) = Welcome | ||
135 | { welcomeNonce :: Nonce24 | ||
136 | , welcomeData :: f HelloData | ||
137 | } | ||
138 | |||
139 | instance Rank2.Functor Welcome where | ||
140 | f <$> Welcome n dta = Welcome n (f dta) | ||
141 | |||
142 | instance Payload Serialize Welcome where | ||
143 | mapPayload _ f (Welcome n dta) = Welcome n (f dta) | ||
144 | |||
145 | instance Rank2.Foldable Welcome where | ||
146 | foldMap f (Welcome _ dta) = f dta | ||
147 | |||
148 | instance Rank2.Traversable Welcome where | ||
149 | traverse f (Welcome n dta) = Welcome n <$> f dta | ||
150 | |||
151 | instance Sized (Welcome Encrypted) where | ||
152 | size = ConstSize 24 <> contramap welcomeData size | ||
153 | |||
154 | instance Serialize (Welcome Encrypted) where | ||
155 | get = Welcome <$> get <*> get | ||
156 | put (Welcome n dta) = put n >> put dta | ||