diff options
author | joe <joe@jerkface.net> | 2017-06-04 22:39:14 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-06-04 22:39:14 -0400 |
commit | 219d72ebde4bab5a516a86608dcb3aede75c1611 (patch) | |
tree | df111d38c3532b9342f30c1bad98ef095569d54f /src/Data | |
parent | 713cee07450697e40811e74059739da02dd604c7 (diff) |
WIP: Adapting DHT to Tox network.
Diffstat (limited to 'src/Data')
-rw-r--r-- | src/Data/Torrent.hs | 44 | ||||
-rw-r--r-- | src/Data/Tox.hs | 196 |
2 files changed, 233 insertions, 7 deletions
diff --git a/src/Data/Torrent.hs b/src/Data/Torrent.hs index c22ca189..8746fff5 100644 --- a/src/Data/Torrent.hs +++ b/src/Data/Torrent.hs | |||
@@ -100,7 +100,9 @@ module Data.Torrent | |||
100 | , layoutInfo | 100 | , layoutInfo |
101 | , pieceInfo | 101 | , pieceInfo |
102 | , isPrivate | 102 | , isPrivate |
103 | #ifdef VERSION_bencoding | ||
103 | , infoDictionary | 104 | , infoDictionary |
105 | #endif | ||
104 | 106 | ||
105 | -- * Torrent file | 107 | -- * Torrent file |
106 | , Torrent(..) | 108 | , Torrent(..) |
@@ -122,8 +124,10 @@ module Data.Torrent | |||
122 | , typeTorrent | 124 | , typeTorrent |
123 | , torrentExt | 125 | , torrentExt |
124 | , isTorrentPath | 126 | , isTorrentPath |
127 | #ifdef VERSION_bencoding | ||
125 | , fromFile | 128 | , fromFile |
126 | , toFile | 129 | , toFile |
130 | #endif | ||
127 | 131 | ||
128 | -- * Magnet | 132 | -- * Magnet |
129 | -- $magnet-link | 133 | -- $magnet-link |
@@ -150,8 +154,10 @@ import Control.Exception | |||
150 | import Control.Lens | 154 | import Control.Lens |
151 | import Control.Monad | 155 | import Control.Monad |
152 | import Crypto.Hash.SHA1 as SHA1 | 156 | import Crypto.Hash.SHA1 as SHA1 |
157 | #ifdef VERSION_bencoding | ||
153 | import Data.BEncode as BE | 158 | import Data.BEncode as BE |
154 | import Data.BEncode.Types as BE | 159 | import Data.BEncode.Types as BE |
160 | #endif | ||
155 | import Data.Bits | 161 | import Data.Bits |
156 | #ifdef VERSION_bits_extras | 162 | #ifdef VERSION_bits_extras |
157 | import Data.Bits.Extras | 163 | import Data.Bits.Extras |
@@ -223,10 +229,12 @@ instance Hashable InfoHash where | |||
223 | hashWithSalt s (InfoHash ih) = hashWithSalt s ih | 229 | hashWithSalt s (InfoHash ih) = hashWithSalt s ih |
224 | {-# INLINE hashWithSalt #-} | 230 | {-# INLINE hashWithSalt #-} |
225 | 231 | ||
232 | #ifdef VERSION_bencoding | ||
226 | -- | Convert to\/from raw bencoded string. (no encoding) | 233 | -- | Convert to\/from raw bencoded string. (no encoding) |
227 | instance BEncode InfoHash where | 234 | instance BEncode InfoHash where |
228 | toBEncode = toBEncode . getInfoHash | 235 | toBEncode = toBEncode . getInfoHash |
229 | fromBEncode be = InfoHash <$> fromBEncode be | 236 | fromBEncode be = InfoHash <$> fromBEncode be |
237 | #endif | ||
230 | 238 | ||
231 | -- | Convert to\/from raw bytestring. (no encoding) | 239 | -- | Convert to\/from raw bytestring. (no encoding) |
232 | instance Serialize InfoHash where | 240 | instance Serialize InfoHash where |
@@ -321,7 +329,9 @@ shortHex = T.take 7 . longHex | |||
321 | -- | Size of a file in bytes. | 329 | -- | Size of a file in bytes. |
322 | type FileSize = FileOffset | 330 | type FileSize = FileOffset |
323 | 331 | ||
332 | #ifdef VERSION_bencoding | ||
324 | deriving instance BEncode FileOffset | 333 | deriving instance BEncode FileOffset |
334 | #endif | ||
325 | 335 | ||
326 | -- | Contain metainfo about one single file. | 336 | -- | Contain metainfo about one single file. |
327 | data FileInfo a = FileInfo { | 337 | data FileInfo a = FileInfo { |
@@ -360,6 +370,7 @@ instance NFData a => NFData (FileInfo a) where | |||
360 | rnf FileInfo {..} = rnf fiName | 370 | rnf FileInfo {..} = rnf fiName |
361 | {-# INLINE rnf #-} | 371 | {-# INLINE rnf #-} |
362 | 372 | ||
373 | #ifdef VERSION_bencoding | ||
363 | instance BEncode (FileInfo [BS.ByteString]) where | 374 | instance BEncode (FileInfo [BS.ByteString]) where |
364 | toBEncode FileInfo {..} = toDict $ | 375 | toBEncode FileInfo {..} = toDict $ |
365 | "length" .=! fiLength | 376 | "length" .=! fiLength |
@@ -375,7 +386,9 @@ instance BEncode (FileInfo [BS.ByteString]) where | |||
375 | {-# INLINE fromBEncode #-} | 386 | {-# INLINE fromBEncode #-} |
376 | 387 | ||
377 | type Put a = a -> BDict -> BDict | 388 | type Put a = a -> BDict -> BDict |
389 | #endif | ||
378 | 390 | ||
391 | #ifdef VERSION_bencoding | ||
379 | putFileInfoSingle :: Data.Torrent.Put (FileInfo BS.ByteString) | 392 | putFileInfoSingle :: Data.Torrent.Put (FileInfo BS.ByteString) |
380 | putFileInfoSingle FileInfo {..} cont = | 393 | putFileInfoSingle FileInfo {..} cont = |
381 | "length" .=! fiLength | 394 | "length" .=! fiLength |
@@ -395,6 +408,7 @@ instance BEncode (FileInfo BS.ByteString) where | |||
395 | 408 | ||
396 | fromBEncode = fromDict getFileInfoSingle | 409 | fromBEncode = fromDict getFileInfoSingle |
397 | {-# INLINE fromBEncode #-} | 410 | {-# INLINE fromBEncode #-} |
411 | #endif | ||
398 | 412 | ||
399 | instance Pretty (FileInfo BS.ByteString) where | 413 | instance Pretty (FileInfo BS.ByteString) where |
400 | pPrint FileInfo {..} = | 414 | pPrint FileInfo {..} = |
@@ -447,6 +461,7 @@ instance NFData LayoutInfo where | |||
447 | instance Default LayoutInfo where | 461 | instance Default LayoutInfo where |
448 | def = MultiFile [] "" | 462 | def = MultiFile [] "" |
449 | 463 | ||
464 | #ifdef VERSION_bencoding | ||
450 | getLayoutInfo :: BE.Get LayoutInfo | 465 | getLayoutInfo :: BE.Get LayoutInfo |
451 | getLayoutInfo = single <|> multi | 466 | getLayoutInfo = single <|> multi |
452 | where | 467 | where |
@@ -463,6 +478,7 @@ putLayoutInfo MultiFile {..} = \ cont -> | |||
463 | instance BEncode LayoutInfo where | 478 | instance BEncode LayoutInfo where |
464 | toBEncode = toDict . (`putLayoutInfo` endDict) | 479 | toBEncode = toDict . (`putLayoutInfo` endDict) |
465 | fromBEncode = fromDict getLayoutInfo | 480 | fromBEncode = fromDict getLayoutInfo |
481 | #endif | ||
466 | 482 | ||
467 | instance Pretty LayoutInfo where | 483 | instance Pretty LayoutInfo where |
468 | pPrint SingleFile {..} = pPrint liFile | 484 | pPrint SingleFile {..} = pPrint liFile |
@@ -637,7 +653,11 @@ hashPiece Piece {..} = SHA1.hashlazy pieceData | |||
637 | 653 | ||
638 | -- | A flat array of SHA1 hash for each piece. | 654 | -- | A flat array of SHA1 hash for each piece. |
639 | newtype HashList = HashList { unHashList :: BS.ByteString } | 655 | newtype HashList = HashList { unHashList :: BS.ByteString } |
640 | deriving (Show, Read, Eq, BEncode, Typeable) | 656 | deriving ( Show, Read, Eq, Typeable |
657 | #ifdef VERSION_bencoding | ||
658 | , BEncode | ||
659 | #endif | ||
660 | ) | ||
641 | 661 | ||
642 | -- | Empty hash list. | 662 | -- | Empty hash list. |
643 | instance Default HashList where | 663 | instance Default HashList where |
@@ -665,6 +685,7 @@ instance Default PieceInfo where | |||
665 | def = PieceInfo 1 def | 685 | def = PieceInfo 1 def |
666 | 686 | ||
667 | 687 | ||
688 | #ifdef VERSION_bencoding | ||
668 | putPieceInfo :: Data.Torrent.Put PieceInfo | 689 | putPieceInfo :: Data.Torrent.Put PieceInfo |
669 | putPieceInfo PieceInfo {..} cont = | 690 | putPieceInfo PieceInfo {..} cont = |
670 | "piece length" .=! piPieceLength | 691 | "piece length" .=! piPieceLength |
@@ -679,6 +700,7 @@ getPieceInfo = do | |||
679 | instance BEncode PieceInfo where | 700 | instance BEncode PieceInfo where |
680 | toBEncode = toDict . (`putPieceInfo` endDict) | 701 | toBEncode = toDict . (`putPieceInfo` endDict) |
681 | fromBEncode = fromDict getPieceInfo | 702 | fromBEncode = fromDict getPieceInfo |
703 | #endif | ||
682 | 704 | ||
683 | -- | Hashes are omitted. | 705 | -- | Hashes are omitted. |
684 | instance Pretty PieceInfo where | 706 | instance Pretty PieceInfo where |
@@ -750,6 +772,13 @@ instance Hashable InfoDict where | |||
750 | hashWithSalt = Hashable.hashUsing idInfoHash | 772 | hashWithSalt = Hashable.hashUsing idInfoHash |
751 | {-# INLINE hashWithSalt #-} | 773 | {-# INLINE hashWithSalt #-} |
752 | 774 | ||
775 | -- | Hash lazy bytestring using SHA1 algorithm. | ||
776 | hashLazyIH :: BL.ByteString -> InfoHash | ||
777 | hashLazyIH = either (const (error msg)) id . safeConvert . SHA1.hashlazy | ||
778 | where | ||
779 | msg = "Infohash.hash: impossible: SHA1 is always 20 bytes long" | ||
780 | |||
781 | #ifdef VERSION_bencoding | ||
753 | -- | Empty info dictionary with zero-length content. | 782 | -- | Empty info dictionary with zero-length content. |
754 | instance Default InfoDict where | 783 | instance Default InfoDict where |
755 | def = infoDictionary def def False | 784 | def = infoDictionary def def False |
@@ -767,12 +796,6 @@ putPrivate :: Bool -> BDict -> BDict | |||
767 | putPrivate False = id | 796 | putPrivate False = id |
768 | putPrivate True = \ cont -> "private" .=! True .: cont | 797 | putPrivate True = \ cont -> "private" .=! True .: cont |
769 | 798 | ||
770 | -- | Hash lazy bytestring using SHA1 algorithm. | ||
771 | hashLazyIH :: BL.ByteString -> InfoHash | ||
772 | hashLazyIH = either (const (error msg)) id . safeConvert . SHA1.hashlazy | ||
773 | where | ||
774 | msg = "Infohash.hash: impossible: SHA1 is always 20 bytes long" | ||
775 | |||
776 | instance BEncode InfoDict where | 799 | instance BEncode InfoDict where |
777 | toBEncode InfoDict {..} = toDict $ | 800 | toBEncode InfoDict {..} = toDict $ |
778 | putLayoutInfo idLayoutInfo $ | 801 | putLayoutInfo idLayoutInfo $ |
@@ -786,6 +809,7 @@ instance BEncode InfoDict where | |||
786 | <*> getPrivate | 809 | <*> getPrivate |
787 | where | 810 | where |
788 | ih = hashLazyIH (BE.encode dict) | 811 | ih = hashLazyIH (BE.encode dict) |
812 | #endif | ||
789 | 813 | ||
790 | ppPrivacy :: Bool -> Doc | 814 | ppPrivacy :: Bool -> Doc |
791 | ppPrivacy privacy = "Privacy: " <> if privacy then "private" else "public" | 815 | ppPrivacy privacy = "Privacy: " <> if privacy then "private" else "public" |
@@ -868,6 +892,7 @@ makeLensesFor | |||
868 | instance NFData Torrent where | 892 | instance NFData Torrent where |
869 | rnf Torrent {..} = rnf tInfoDict | 893 | rnf Torrent {..} = rnf tInfoDict |
870 | 894 | ||
895 | #ifdef VERSION_bencoding | ||
871 | -- TODO move to bencoding | 896 | -- TODO move to bencoding |
872 | instance BEncode URI where | 897 | instance BEncode URI where |
873 | toBEncode uri = toBEncode (BC.pack (uriToString id uri "")) | 898 | toBEncode uri = toBEncode (BC.pack (uriToString id uri "")) |
@@ -918,6 +943,7 @@ instance BEncode Torrent where | |||
918 | <*>? "publisher" | 943 | <*>? "publisher" |
919 | <*>? "publisher-url" | 944 | <*>? "publisher-url" |
920 | <*>? "signature" | 945 | <*>? "signature" |
946 | #endif | ||
921 | 947 | ||
922 | (<:>) :: Doc -> Doc -> Doc | 948 | (<:>) :: Doc -> Doc -> Doc |
923 | name <:> v = name <> ":" <+> v | 949 | name <:> v = name <> ":" <+> v |
@@ -949,9 +975,11 @@ instance Pretty Torrent where | |||
949 | "Publisher URL" <:>? ((text . show) <$> tPublisherURL) $$ | 975 | "Publisher URL" <:>? ((text . show) <$> tPublisherURL) $$ |
950 | "Signature" <:>? ((text . show) <$> tSignature) | 976 | "Signature" <:>? ((text . show) <$> tSignature) |
951 | 977 | ||
978 | #ifdef VERSION_bencoding | ||
952 | -- | No files, no trackers, no nodes, etc... | 979 | -- | No files, no trackers, no nodes, etc... |
953 | instance Default Torrent where | 980 | instance Default Torrent where |
954 | def = nullTorrent def | 981 | def = nullTorrent def |
982 | #endif | ||
955 | 983 | ||
956 | -- | A simple torrent contains only required fields. | 984 | -- | A simple torrent contains only required fields. |
957 | nullTorrent :: InfoDict -> Torrent | 985 | nullTorrent :: InfoDict -> Torrent |
@@ -971,6 +999,7 @@ torrentExt = "torrent" | |||
971 | isTorrentPath :: FilePath -> Bool | 999 | isTorrentPath :: FilePath -> Bool |
972 | isTorrentPath filepath = takeExtension filepath == extSeparator : torrentExt | 1000 | isTorrentPath filepath = takeExtension filepath == extSeparator : torrentExt |
973 | 1001 | ||
1002 | #ifdef VERSION_bencoding | ||
974 | -- | Read and decode a .torrent file. | 1003 | -- | Read and decode a .torrent file. |
975 | fromFile :: FilePath -> IO Torrent | 1004 | fromFile :: FilePath -> IO Torrent |
976 | fromFile filepath = do | 1005 | fromFile filepath = do |
@@ -982,6 +1011,7 @@ fromFile filepath = do | |||
982 | -- | Encode and write a .torrent file. | 1011 | -- | Encode and write a .torrent file. |
983 | toFile :: FilePath -> Torrent -> IO () | 1012 | toFile :: FilePath -> Torrent -> IO () |
984 | toFile filepath = BL.writeFile filepath . BE.encode | 1013 | toFile filepath = BL.writeFile filepath . BE.encode |
1014 | #endif | ||
985 | 1015 | ||
986 | {----------------------------------------------------------------------- | 1016 | {----------------------------------------------------------------------- |
987 | -- URN | 1017 | -- URN |
diff --git a/src/Data/Tox.hs b/src/Data/Tox.hs new file mode 100644 index 00000000..448b39eb --- /dev/null +++ b/src/Data/Tox.hs | |||
@@ -0,0 +1,196 @@ | |||
1 | {-# LANGUAGE DeriveDataTypeable #-} | ||
2 | {-# LANGUAGE DeriveGeneric #-} | ||
3 | {-# LANGUAGE PatternSynonyms #-} | ||
4 | {-# LANGUAGE RecordWildCards #-} | ||
5 | {-# LANGUAGE TupleSections #-} | ||
6 | {-# LANGUAGE UnboxedTuples #-} | ||
7 | module Data.Tox where | ||
8 | |||
9 | import Data.ByteString (ByteString) | ||
10 | import Data.Data (Data) | ||
11 | import Data.Word | ||
12 | import Data.LargeWord | ||
13 | import Data.IP | ||
14 | import Data.Serialize | ||
15 | import Network.BitTorrent.Address () -- Serialize IP | ||
16 | import GHC.Generics (Generic) | ||
17 | import Network.Socket | ||
18 | |||
19 | type Key32 = Word256 -- 32 byte key | ||
20 | type Nonce8 = Word64 -- 8 bytes | ||
21 | type Nonce24 = Word192 -- 24 bytes | ||
22 | type NodeId = Word256 -- 32 bytes (mainline uses only 20-byte node IDs) | ||
23 | |||
24 | |||
25 | data NodeFormat = NodeFormat | ||
26 | { nodePublicKey :: Key32 -- 32 byte public key | ||
27 | , nodeIsTCP :: Bool -- This has no analog in mainline NodeInfo structure | ||
28 | , nodeIP :: IP -- IPv4 or IPv6 address | ||
29 | , nodePort :: PortNumber | ||
30 | } | ||
31 | deriving (Eq, Ord, Show) | ||
32 | |||
33 | encodeFamily :: (Family, SocketType) -> Word8 | ||
34 | encodeFamily (AF_INET , Datagram) = 2 | ||
35 | encodeFamily (AF_INET6 , Datagram) = 10 | ||
36 | encodeFamily (AF_INET , Stream ) = 130 | ||
37 | encodeFamily (AF_INET6 , Stream ) = 138 | ||
38 | encodeFamily _ = error "Unsupported protocol" | ||
39 | |||
40 | newtype MessageType = MessageType Word8 | ||
41 | deriving (Eq, Ord, Show, Read) | ||
42 | |||
43 | instance Serialize MessageType where | ||
44 | put (MessageType b) = put b | ||
45 | get = MessageType <$> get | ||
46 | |||
47 | pattern Ping = MessageType 0 | ||
48 | pattern Pong = MessageType 1 | ||
49 | pattern GetNodes = MessageType 2 | ||
50 | pattern SendNodes = MessageType 4 | ||
51 | {- | ||
52 | #define NET_PACKET_PING_REQUEST 0 /* Ping request packet ID. */ | ||
53 | #define NET_PACKET_PING_RESPONSE 1 /* Ping response packet ID. */ | ||
54 | #define NET_PACKET_GET_NODES 2 /* Get nodes request packet ID. */ | ||
55 | #define NET_PACKET_SEND_NODES_IPV6 4 /* Send nodes response packet ID for other addresses. */ | ||
56 | #define NET_PACKET_COOKIE_REQUEST 24 /* Cookie request packet */ | ||
57 | #define NET_PACKET_COOKIE_RESPONSE 25 /* Cookie response packet */ | ||
58 | #define NET_PACKET_CRYPTO_HS 26 /* Crypto handshake packet */ | ||
59 | #define NET_PACKET_CRYPTO_DATA 27 /* Crypto data packet */ | ||
60 | #define NET_PACKET_CRYPTO 32 /* Encrypted data packet ID. */ | ||
61 | #define NET_PACKET_LAN_DISCOVERY 33 /* LAN discovery packet ID. */ | ||
62 | |||
63 | /* See: docs/Prevent_Tracking.txt and onion.{c, h} */ | ||
64 | #define NET_PACKET_ONION_SEND_INITIAL 128 | ||
65 | #define NET_PACKET_ONION_SEND_1 129 | ||
66 | #define NET_PACKET_ONION_SEND_2 130 | ||
67 | |||
68 | #define NET_PACKET_ANNOUNCE_REQUEST 131 | ||
69 | #define NET_PACKET_ANNOUNCE_RESPONSE 132 | ||
70 | #define NET_PACKET_ONION_DATA_REQUEST 133 | ||
71 | #define NET_PACKET_ONION_DATA_RESPONSE 134 | ||
72 | |||
73 | #define NET_PACKET_ONION_RECV_3 140 | ||
74 | #define NET_PACKET_ONION_RECV_2 141 | ||
75 | #define NET_PACKET_ONION_RECV_1 142 | ||
76 | -} | ||
77 | |||
78 | |||
79 | -- FIXME Orphan Serialize intance for large words | ||
80 | instance (Serialize a, Serialize b) => Serialize (LargeKey a b) where | ||
81 | put (LargeKey lo hi) = put hi >> put lo | ||
82 | get = flip LargeKey <$> get <*> get | ||
83 | |||
84 | -- | Use with 'PingPayload', 'GetNodesPayload', or 'SendNodesPayload' | ||
85 | data Message a = Message | ||
86 | { msgType :: MessageType | ||
87 | , msgClient :: NodeId | ||
88 | , msgNonce :: Nonce24 | ||
89 | , msgPayload :: a | ||
90 | } | ||
91 | deriving (Show, Generic) | ||
92 | |||
93 | isQuery :: Message a -> Bool | ||
94 | isQuery (Message { msgType = SendNodes }) = False | ||
95 | isQuery (Message { msgType = MessageType typ }) | even typ = True | ||
96 | isQuery _ = False | ||
97 | |||
98 | isResponse :: Message a -> Bool | ||
99 | isResponse m = not (isQuery m) | ||
100 | |||
101 | isError :: Message a -> Bool | ||
102 | isError _ = False | ||
103 | |||
104 | instance Serialize a => Serialize (Message a) where -- TODO TOX | ||
105 | |||
106 | data PingPayload = PingPayload | ||
107 | { isPong :: Bool | ||
108 | , pingId :: Nonce8 | ||
109 | } | ||
110 | |||
111 | data GetNodesPayload = GetNodesPayload | ||
112 | { nodesForWho :: NodeId | ||
113 | , nodesNonce :: Nonce8 | ||
114 | } | ||
115 | |||
116 | data SendNodesPayload = SendNodesPayload | ||
117 | |||
118 | -- From: docs/updates/DHT.md | ||
119 | -- | ||
120 | -- Node format: | ||
121 | -- [uint8_t family (2 == IPv4, 10 == IPv6, 130 == TCP IPv4, 138 == TCP IPv6)] | ||
122 | -- [ip (in network byte order), length=4 bytes if ipv4, 16 bytes if ipv6] | ||
123 | -- [port (in network byte order), length=2 bytes] | ||
124 | -- [char array (node_id), length=32 bytes] | ||
125 | -- | ||
126 | -- see also: DHT.h (pack_nodes() and unpack_nodes()) | ||
127 | instance Serialize NodeFormat where | ||
128 | |||
129 | get = do | ||
130 | typ <- get :: Get Word8 | ||
131 | (ip,istcp) <- | ||
132 | case typ :: Word8 of | ||
133 | 2 -> (,False) . IPv4 <$> get | ||
134 | 130 -> (,True) . IPv4 <$> get | ||
135 | 10 -> (,False) . IPv6 <$> get | ||
136 | 138 -> (,True) . IPv6 <$> get | ||
137 | _ -> fail "Unsupported type of Tox node_format structure" | ||
138 | port <- get | ||
139 | pubkey <- get | ||
140 | return $ NodeFormat { nodeIsTCP = istcp | ||
141 | , nodeIP = ip | ||
142 | , nodePort = port | ||
143 | , nodePublicKey = pubkey | ||
144 | } | ||
145 | |||
146 | put (NodeFormat{..}) = do | ||
147 | put $ case (# nodeIP, nodeIsTCP #) of | ||
148 | (# IPv4 _, False #) -> 2 | ||
149 | (# IPv4 _, True #) -> 130 | ||
150 | (# IPv6 _, False #) -> 10 | ||
151 | (# IPv6 _, True #) -> 138 :: Word8 | ||
152 | put nodeIP | ||
153 | put nodePort | ||
154 | put nodePublicKey | ||
155 | |||
156 | -- Note: the char array is a public key, the 32-bytes is provided by libsodium-dev | ||
157 | -- in /usr/include/sodium/crypto_box.h as the symbol crypto_box_PUBLICKEYBYTES | ||
158 | -- but toxcore/crypto_core.c will fail to compile if it is not 32. | ||
159 | |||
160 | |||
161 | -- Ping(Request and response): | ||
162 | -- | ||
163 | -- [byte with value: 00 for request, 01 for response] | ||
164 | -- [char array (client node_id), length=32 bytes] | ||
165 | -- [random 24 byte nonce] | ||
166 | -- [Encrypted with the nonce and private key of the sender: | ||
167 | -- [1 byte type (0 for request, 1 for response)] | ||
168 | -- [random 8 byte (ping_id)] | ||
169 | -- ] | ||
170 | -- | ||
171 | -- ping_id = a random integer, the response must contain the exact same number as the request | ||
172 | |||
173 | |||
174 | -- Get nodes (Request): | ||
175 | -- | ||
176 | -- [byte with value: 02] | ||
177 | -- [char array (client node_id), length=32 bytes] | ||
178 | -- [random 24 byte nonce] | ||
179 | -- [Encrypted with the nonce and private key of the sender: | ||
180 | -- [char array: requested_node_id (node_id of which we want the ip), length=32 bytes] | ||
181 | -- [Sendback data (must be sent back unmodified by in the response), length=8 bytes] | ||
182 | -- ] | ||
183 | -- | ||
184 | -- Valid replies: a send_nodes packet | ||
185 | |||
186 | -- Send_nodes (response (for all addresses)): | ||
187 | -- | ||
188 | -- [byte with value: 04] | ||
189 | -- [char array (client node_id), length=32 bytes] | ||
190 | -- [random 24 byte nonce] | ||
191 | -- [Encrypted with the nonce and private key of the sender: | ||
192 | -- [uint8_t number of nodes in this packet] | ||
193 | -- [Nodes in node format, length=?? * (number of nodes (maximum of 4 nodes)) bytes] | ||
194 | -- [Sendback data, length=8 bytes] | ||
195 | -- ] | ||
196 | |||