ffi-tox 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/ProjectTox-Core/AUTHORS +0 -0
  3. data/ProjectTox-Core/ChangeLog +0 -0
  4. data/ProjectTox-Core/INSTALL +370 -0
  5. data/ProjectTox-Core/INSTALL.md +455 -56
  6. data/ProjectTox-Core/Makefile.am +35 -0
  7. data/ProjectTox-Core/NEWS +0 -0
  8. data/ProjectTox-Core/README +43 -0
  9. data/ProjectTox-Core/README.md +34 -44
  10. data/ProjectTox-Core/auto_tests/Makefile.inc +110 -0
  11. data/ProjectTox-Core/auto_tests/TCP_test.c +519 -0
  12. data/ProjectTox-Core/auto_tests/assoc_test.c +160 -0
  13. data/ProjectTox-Core/auto_tests/crypto_test.c +302 -0
  14. data/ProjectTox-Core/auto_tests/dht_test.c +362 -0
  15. data/ProjectTox-Core/auto_tests/encryptsave_test.c +104 -0
  16. data/ProjectTox-Core/auto_tests/friends_test.c +238 -0
  17. data/ProjectTox-Core/auto_tests/helpers.h +15 -0
  18. data/ProjectTox-Core/auto_tests/messenger_test.c +365 -0
  19. data/ProjectTox-Core/auto_tests/network_test.c +171 -0
  20. data/ProjectTox-Core/auto_tests/onion_test.c +363 -0
  21. data/ProjectTox-Core/auto_tests/skeleton_test.c +49 -0
  22. data/ProjectTox-Core/auto_tests/tox_test.c +454 -0
  23. data/ProjectTox-Core/auto_tests/toxav_basic_test.c +597 -0
  24. data/ProjectTox-Core/auto_tests/toxav_many_test.c +402 -0
  25. data/ProjectTox-Core/autogen.sh +6 -0
  26. data/ProjectTox-Core/build/Makefile.am +14 -0
  27. data/ProjectTox-Core/configure.ac +694 -0
  28. data/ProjectTox-Core/dist-build/android-arm.sh +3 -0
  29. data/ProjectTox-Core/dist-build/android-armv7.sh +3 -0
  30. data/ProjectTox-Core/dist-build/android-build.sh +59 -0
  31. data/ProjectTox-Core/dist-build/android-mips.sh +3 -0
  32. data/ProjectTox-Core/dist-build/android-x86.sh +3 -0
  33. data/ProjectTox-Core/docs/Group-Chats.md +71 -0
  34. data/ProjectTox-Core/docs/Hardening.txt +60 -0
  35. data/ProjectTox-Core/docs/Hardening_docs.txt +30 -0
  36. data/ProjectTox-Core/docs/Prevent_Tracking.txt +160 -0
  37. data/ProjectTox-Core/docs/TCP_Network.txt +154 -0
  38. data/ProjectTox-Core/docs/TODO +62 -0
  39. data/ProjectTox-Core/docs/Tox_middle_level_network_protocol.txt +120 -0
  40. data/ProjectTox-Core/docs/av_api.md +194 -0
  41. data/ProjectTox-Core/libtoxav.pc.in +11 -0
  42. data/ProjectTox-Core/libtoxcore.pc.in +11 -0
  43. data/ProjectTox-Core/m4/ax_have_epoll.m4 +104 -0
  44. data/ProjectTox-Core/m4/ax_pthread.m4 +317 -0
  45. data/ProjectTox-Core/m4/pkg.m4 +199 -0
  46. data/ProjectTox-Core/other/DHT_bootstrap.c +121 -58
  47. data/ProjectTox-Core/other/DHTnodes +3 -0
  48. data/ProjectTox-Core/other/Makefile.inc +20 -0
  49. data/ProjectTox-Core/other/bootstrap_node_packets.c +65 -0
  50. data/ProjectTox-Core/other/tox.png +0 -0
  51. data/ProjectTox-Core/testing/DHT_test.c +170 -98
  52. data/ProjectTox-Core/testing/Makefile.inc +112 -0
  53. data/ProjectTox-Core/testing/Messenger_test.c +133 -69
  54. data/ProjectTox-Core/testing/dns3_test.c +115 -0
  55. data/ProjectTox-Core/testing/misc_tools.c +59 -13
  56. data/ProjectTox-Core/testing/nTox.c +1127 -264
  57. data/ProjectTox-Core/testing/nTox.h +10 -19
  58. data/ProjectTox-Core/testing/tox_shell.c +159 -0
  59. data/ProjectTox-Core/testing/tox_sync.c +299 -0
  60. data/ProjectTox-Core/tools/README +11 -0
  61. data/ProjectTox-Core/tools/astylerc +11 -0
  62. data/ProjectTox-Core/tools/pre-commit +17 -0
  63. data/ProjectTox-Core/toxav/Makefile.inc +36 -0
  64. data/ProjectTox-Core/toxav/codec.c +357 -0
  65. data/ProjectTox-Core/toxav/codec.h +116 -0
  66. data/ProjectTox-Core/toxav/msi.c +1949 -0
  67. data/ProjectTox-Core/toxav/msi.h +267 -0
  68. data/ProjectTox-Core/toxav/rtp.c +600 -0
  69. data/ProjectTox-Core/toxav/rtp.h +196 -0
  70. data/ProjectTox-Core/toxav/toxav.c +1148 -0
  71. data/ProjectTox-Core/toxav/toxav.h +389 -0
  72. data/ProjectTox-Core/toxcore/DHT.c +2521 -0
  73. data/ProjectTox-Core/toxcore/DHT.h +412 -0
  74. data/ProjectTox-Core/toxcore/LAN_discovery.c +322 -0
  75. data/ProjectTox-Core/{core → toxcore}/LAN_discovery.h +17 -12
  76. data/ProjectTox-Core/toxcore/Makefile.inc +67 -0
  77. data/ProjectTox-Core/toxcore/Messenger.c +3006 -0
  78. data/ProjectTox-Core/toxcore/Messenger.h +818 -0
  79. data/ProjectTox-Core/toxcore/TCP_client.c +858 -0
  80. data/ProjectTox-Core/toxcore/TCP_client.h +156 -0
  81. data/ProjectTox-Core/toxcore/TCP_server.c +1332 -0
  82. data/ProjectTox-Core/toxcore/TCP_server.h +181 -0
  83. data/ProjectTox-Core/toxcore/assoc.c +1033 -0
  84. data/ProjectTox-Core/toxcore/assoc.h +104 -0
  85. data/ProjectTox-Core/toxcore/crypto_core.c +278 -0
  86. data/ProjectTox-Core/toxcore/crypto_core.h +151 -0
  87. data/ProjectTox-Core/toxcore/friend_requests.c +175 -0
  88. data/ProjectTox-Core/toxcore/friend_requests.h +83 -0
  89. data/ProjectTox-Core/toxcore/group_chats.c +837 -0
  90. data/ProjectTox-Core/toxcore/group_chats.h +199 -0
  91. data/ProjectTox-Core/toxcore/list.c +256 -0
  92. data/ProjectTox-Core/toxcore/list.h +85 -0
  93. data/ProjectTox-Core/toxcore/logger.c +153 -0
  94. data/ProjectTox-Core/toxcore/logger.h +84 -0
  95. data/ProjectTox-Core/toxcore/misc_tools.h +70 -0
  96. data/ProjectTox-Core/toxcore/net_crypto.c +2753 -0
  97. data/ProjectTox-Core/toxcore/net_crypto.h +410 -0
  98. data/ProjectTox-Core/toxcore/network.c +979 -0
  99. data/ProjectTox-Core/toxcore/network.h +367 -0
  100. data/ProjectTox-Core/toxcore/onion.c +540 -0
  101. data/ProjectTox-Core/toxcore/onion.h +150 -0
  102. data/ProjectTox-Core/toxcore/onion_announce.c +433 -0
  103. data/ProjectTox-Core/toxcore/onion_announce.h +139 -0
  104. data/ProjectTox-Core/toxcore/onion_client.c +1347 -0
  105. data/ProjectTox-Core/toxcore/onion_client.h +253 -0
  106. data/ProjectTox-Core/toxcore/ping.c +346 -0
  107. data/ProjectTox-Core/toxcore/ping.h +47 -0
  108. data/ProjectTox-Core/toxcore/ping_array.c +162 -0
  109. data/ProjectTox-Core/toxcore/ping_array.h +75 -0
  110. data/ProjectTox-Core/toxcore/tox.c +940 -0
  111. data/ProjectTox-Core/toxcore/tox.h +734 -0
  112. data/ProjectTox-Core/toxcore/util.c +193 -0
  113. data/ProjectTox-Core/toxcore/util.h +63 -0
  114. data/ProjectTox-Core/toxdns/Makefile.inc +29 -0
  115. data/ProjectTox-Core/toxdns/toxdns.c +238 -0
  116. data/ProjectTox-Core/toxdns/toxdns.h +88 -0
  117. data/ProjectTox-Core/toxencryptsave/Makefile.inc +45 -0
  118. data/ProjectTox-Core/toxencryptsave/toxencryptsave.c +179 -0
  119. data/ProjectTox-Core/toxencryptsave/toxencryptsave.h +74 -0
  120. data/interfaces/libtox.i +2 -6
  121. data/lib/ffi-tox/libtox.rb +406 -28
  122. metadata +124 -46
  123. data/ProjectTox-Core/CMakeLists.txt +0 -50
  124. data/ProjectTox-Core/cmake/FindLIBCONFIG.cmake +0 -15
  125. data/ProjectTox-Core/cmake/FindNaCl.cmake +0 -17
  126. data/ProjectTox-Core/cmake/FindSODIUM.cmake +0 -15
  127. data/ProjectTox-Core/core/CMakeLists.txt +0 -19
  128. data/ProjectTox-Core/core/DHT.c +0 -1104
  129. data/ProjectTox-Core/core/DHT.h +0 -111
  130. data/ProjectTox-Core/core/LAN_discovery.c +0 -79
  131. data/ProjectTox-Core/core/Lossless_UDP.c +0 -755
  132. data/ProjectTox-Core/core/Lossless_UDP.h +0 -106
  133. data/ProjectTox-Core/core/Messenger.c +0 -596
  134. data/ProjectTox-Core/core/Messenger.h +0 -165
  135. data/ProjectTox-Core/core/friend_requests.c +0 -131
  136. data/ProjectTox-Core/core/friend_requests.h +0 -51
  137. data/ProjectTox-Core/core/net_crypto.c +0 -575
  138. data/ProjectTox-Core/core/net_crypto.h +0 -134
  139. data/ProjectTox-Core/core/network.c +0 -205
  140. data/ProjectTox-Core/core/network.h +0 -134
  141. data/ProjectTox-Core/docs/commands.md +0 -25
  142. data/ProjectTox-Core/docs/start_guide.de.md +0 -40
  143. data/ProjectTox-Core/docs/start_guide.md +0 -38
  144. data/ProjectTox-Core/other/CMakeLists.txt +0 -9
  145. data/ProjectTox-Core/testing/CMakeLists.txt +0 -18
  146. data/ProjectTox-Core/testing/DHT_cryptosendfiletest.c +0 -228
  147. data/ProjectTox-Core/testing/DHT_sendfiletest.c +0 -176
  148. data/ProjectTox-Core/testing/Lossless_UDP_testclient.c +0 -214
  149. data/ProjectTox-Core/testing/Lossless_UDP_testserver.c +0 -201
  150. data/ProjectTox-Core/testing/misc_tools.h +0 -29
  151. data/ProjectTox-Core/testing/nTox_win32.c +0 -387
  152. data/ProjectTox-Core/testing/nTox_win32.h +0 -40
  153. data/ProjectTox-Core/testing/rect.py +0 -45
@@ -0,0 +1,412 @@
1
+ /* DHT.h
2
+ *
3
+ * An implementation of the DHT as seen in http://wiki.tox.im/index.php/DHT
4
+ *
5
+ * Copyright (C) 2013 Tox project All Rights Reserved.
6
+ *
7
+ * This file is part of Tox.
8
+ *
9
+ * Tox is free software: you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation, either version 3 of the License, or
12
+ * (at your option) any later version.
13
+ *
14
+ * Tox is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ * GNU General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU General Public License
20
+ * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21
+ *
22
+ */
23
+
24
+ #ifndef DHT_H
25
+ #define DHT_H
26
+
27
+ #include "crypto_core.h"
28
+ #include "network.h"
29
+ #include "ping_array.h"
30
+
31
+ /* Size of the client_id in bytes. */
32
+ #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
33
+
34
+ /* Maximum number of clients stored per friend. */
35
+ #define MAX_FRIEND_CLIENTS 8
36
+
37
+ /* A list of the clients mathematically closest to ours. */
38
+ #define LCLIENT_LIST 32
39
+
40
+ /* The max number of nodes to send with send nodes. */
41
+ #define MAX_SENT_NODES 4
42
+
43
+ /* Ping timeout in seconds */
44
+ #define PING_TIMEOUT 3
45
+
46
+ /* size of DHT ping arrays. */
47
+ #define DHT_PING_ARRAY_SIZE 512
48
+
49
+ /* Ping interval in seconds for each node in our lists. */
50
+ #define PING_INTERVAL 60
51
+
52
+ /* The number of seconds for a non responsive node to become bad. */
53
+ #define PINGS_MISSED_NODE_GOES_BAD 1
54
+ #define PING_ROUNDTRIP 2
55
+ #define BAD_NODE_TIMEOUT (PING_INTERVAL + PINGS_MISSED_NODE_GOES_BAD * (PING_INTERVAL + PING_ROUNDTRIP))
56
+
57
+ /* Redefinitions of variables for safe transfer over wire. */
58
+ #define TOX_AF_INET 2
59
+ #define TOX_AF_INET6 10
60
+ #define TOX_TCP_INET 130
61
+ #define TOX_TCP_INET6 138
62
+
63
+ /* The number of "fake" friends to add (for optimization purposes and so our paths for the onion part are more random) */
64
+ #define DHT_FAKE_FRIEND_NUMBER 4
65
+
66
+ /* Functions to transfer ips safely across wire. */
67
+ void to_net_family(IP *ip);
68
+ void to_host_family(IP *ip);
69
+
70
+ typedef struct {
71
+ IP_Port ip_port;
72
+ uint64_t timestamp;
73
+ } IPPTs;
74
+
75
+ typedef struct {
76
+ /* Node routes request correctly (true (1) or false/didn't check (0)) */
77
+ uint8_t routes_requests_ok;
78
+ /* Time which we last checked this.*/
79
+ uint64_t routes_requests_timestamp;
80
+ uint8_t routes_requests_pingedid[CLIENT_ID_SIZE];
81
+ /* Node sends correct send_node (true (1) or false/didn't check (0)) */
82
+ uint8_t send_nodes_ok;
83
+ /* Time which we last checked this.*/
84
+ uint64_t send_nodes_timestamp;
85
+ uint8_t send_nodes_pingedid[CLIENT_ID_SIZE];
86
+ /* Node can be used to test other nodes (true (1) or false/didn't check (0)) */
87
+ uint8_t testing_requests;
88
+ /* Time which we last checked this.*/
89
+ uint64_t testing_timestamp;
90
+ uint8_t testing_pingedid[CLIENT_ID_SIZE];
91
+ } Hardening;
92
+
93
+ typedef struct {
94
+ IP_Port ip_port;
95
+ uint64_t timestamp;
96
+ uint64_t last_pinged;
97
+
98
+ Hardening hardening;
99
+ /* Returned by this node. Either our friend or us. */
100
+ IP_Port ret_ip_port;
101
+ uint64_t ret_timestamp;
102
+ } IPPTsPng;
103
+
104
+ typedef struct {
105
+ uint8_t client_id[CLIENT_ID_SIZE];
106
+ IPPTsPng assoc4;
107
+ IPPTsPng assoc6;
108
+ } Client_data;
109
+
110
+ /*----------------------------------------------------------------------------------*/
111
+
112
+ typedef struct {
113
+ /* 1 if currently hole punching, otherwise 0 */
114
+ uint8_t hole_punching;
115
+ uint32_t punching_index;
116
+ uint32_t tries;
117
+ uint32_t punching_index2;
118
+
119
+ uint64_t punching_timestamp;
120
+ uint64_t recvNATping_timestamp;
121
+ uint64_t NATping_id;
122
+ uint64_t NATping_timestamp;
123
+ } NAT;
124
+
125
+ typedef struct {
126
+ uint8_t client_id[CLIENT_ID_SIZE];
127
+ Client_data client_list[MAX_FRIEND_CLIENTS];
128
+
129
+ /* Time at which the last get_nodes request was sent. */
130
+ uint64_t lastgetnode;
131
+ /* number of times get_node packets were sent. */
132
+ uint32_t bootstrap_times;
133
+
134
+ /* Symetric NAT hole punching stuff. */
135
+ NAT nat;
136
+ } DHT_Friend;
137
+
138
+ typedef struct __attribute__ ((__packed__))
139
+ {
140
+ uint8_t client_id[CLIENT_ID_SIZE];
141
+ IP_Port ip_port;
142
+ }
143
+ Node_format;
144
+
145
+ /* Pack number of nodes into data of maxlength length.
146
+ *
147
+ * return length of packed nodes on success.
148
+ * return -1 on failure.
149
+ */
150
+ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_t number);
151
+
152
+ /* Unpack data of length into nodes of size max_num_nodes.
153
+ * Put the length of the data processed in processed_data_len.
154
+ * tcp_enabled sets if TCP nodes are expected (true) or not (false).
155
+ *
156
+ * return number of unpacked nodes on success.
157
+ * return -1 on failure.
158
+ */
159
+ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed_data_len, const uint8_t *data,
160
+ uint16_t length, uint8_t tcp_enabled);
161
+
162
+
163
+ /*----------------------------------------------------------------------------------*/
164
+ /* struct to store some shared keys so we don't have to regenerate them for each request. */
165
+ #define MAX_KEYS_PER_SLOT 4
166
+ #define KEYS_TIMEOUT 600
167
+ typedef struct {
168
+ struct {
169
+ uint8_t client_id[CLIENT_ID_SIZE];
170
+ uint8_t shared_key[crypto_box_BEFORENMBYTES];
171
+ uint32_t times_requested;
172
+ uint8_t stored; /* 0 if not, 1 if is */
173
+ uint64_t time_last_requested;
174
+ } keys[256 * MAX_KEYS_PER_SLOT];
175
+ } Shared_Keys;
176
+
177
+ /*----------------------------------------------------------------------------------*/
178
+
179
+ typedef int (*cryptopacket_handler_callback)(void *object, IP_Port ip_port, const uint8_t *source_pubkey,
180
+ const uint8_t *data, uint32_t len);
181
+
182
+ typedef struct {
183
+ cryptopacket_handler_callback function;
184
+ void *object;
185
+ } Cryptopacket_Handles;
186
+
187
+ typedef struct {
188
+ Networking_Core *net;
189
+
190
+ Client_data close_clientlist[LCLIENT_LIST];
191
+ uint64_t close_lastgetnodes;
192
+ uint32_t close_bootstrap_times;
193
+
194
+ /* Note: this key should not be/is not used to transmit any sensitive materials */
195
+ uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
196
+ /* DHT keypair */
197
+ uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
198
+ uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
199
+
200
+ DHT_Friend *friends_list;
201
+ uint16_t num_friends;
202
+
203
+ // Used after loading of file (tox_load), but no longer needed after connect (tox_connect)
204
+ // Unsure if friends_list and num_friends could just be used instead?
205
+ int has_loaded_friends_clients; // Whether or not we have loaded on the first do_DHT
206
+ DHT_Friend *loaded_friends_list;
207
+ uint32_t loaded_num_friends;
208
+ Client_data *loaded_clients_list;
209
+ uint32_t loaded_num_clients;
210
+
211
+ Shared_Keys shared_keys_recv;
212
+ Shared_Keys shared_keys_sent;
213
+
214
+ struct PING *ping;
215
+ Ping_Array dht_ping_array;
216
+ Ping_Array dht_harden_ping_array;
217
+ #ifdef ENABLE_ASSOC_DHT
218
+ struct Assoc *assoc;
219
+ #endif
220
+ uint64_t last_run;
221
+
222
+ Cryptopacket_Handles cryptopackethandlers[256];
223
+ } DHT;
224
+ /*----------------------------------------------------------------------------------*/
225
+
226
+ /* Shared key generations are costly, it is therefor smart to store commonly used
227
+ * ones so that they can re used later without being computed again.
228
+ *
229
+ * If shared key is already in shared_keys, copy it to shared_key.
230
+ * else generate it into shared_key and copy it to shared_keys
231
+ */
232
+ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t *secret_key, const uint8_t *client_id);
233
+
234
+ /* Copy shared_key to encrypt/decrypt DHT packet from client_id into shared_key
235
+ * for packets that we receive.
236
+ */
237
+ void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *client_id);
238
+
239
+ /* Copy shared_key to encrypt/decrypt DHT packet from client_id into shared_key
240
+ * for packets that we send.
241
+ */
242
+ void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *client_id);
243
+
244
+ void DHT_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, const uint8_t *which_id);
245
+
246
+ /* Add a new friend to the friends list.
247
+ * client_id must be CLIENT_ID_SIZE bytes long.
248
+ *
249
+ * return 0 if success.
250
+ * return 1 if failure (friends list is full).
251
+ */
252
+ int DHT_addfriend(DHT *dht, const uint8_t *client_id);
253
+
254
+ /* Delete a friend from the friends list.
255
+ * client_id must be CLIENT_ID_SIZE bytes long.
256
+ *
257
+ * return 0 if success.
258
+ * return 1 if failure (client_id not in friends list).
259
+ */
260
+ int DHT_delfriend(DHT *dht, const uint8_t *client_id);
261
+
262
+ /* Get ip of friend.
263
+ * client_id must be CLIENT_ID_SIZE bytes long.
264
+ * ip must be 4 bytes long.
265
+ * port must be 2 bytes long.
266
+ *
267
+ * !!! Signature changed !!!
268
+ *
269
+ * OLD: IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id);
270
+ *
271
+ * return ip if success.
272
+ * return ip of 0 if failure (This means the friend is either offline or we have not found him yet).
273
+ * return ip of 1 if friend is not in list.
274
+ *
275
+ * NEW: int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port);
276
+ *
277
+ * return -1, -- if client_id does NOT refer to a friend
278
+ * return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
279
+ * return 1, ip if client_id refers to a friend and we found him
280
+ */
281
+ int DHT_getfriendip(const DHT *dht, const uint8_t *client_id, IP_Port *ip_port);
282
+
283
+ /* Compares client_id1 and client_id2 with client_id.
284
+ *
285
+ * return 0 if both are same distance.
286
+ * return 1 if client_id1 is closer.
287
+ * return 2 if client_id2 is closer.
288
+ */
289
+ int id_closest(const uint8_t *id, const uint8_t *id1, const uint8_t *id2);
290
+
291
+ /* Get the (maximum MAX_SENT_NODES) closest nodes to client_id we know
292
+ * and put them in nodes_list (must be MAX_SENT_NODES big).
293
+ *
294
+ * sa_family = family (IPv4 or IPv6) (0 if we don't care)?
295
+ * is_LAN = return some LAN ips (true or false)
296
+ * want_good = do we want tested nodes or not? (TODO)
297
+ *
298
+ * return the number of nodes returned.
299
+ *
300
+ */
301
+ int get_close_nodes(const DHT *dht, const uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family,
302
+ uint8_t is_LAN, uint8_t want_good);
303
+
304
+
305
+ /* Put up to max_num nodes in nodes from the closelist.
306
+ *
307
+ * return the number of nodes.
308
+ */
309
+ uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num);
310
+
311
+ /* Put up to max_num random nodes in nodes.
312
+ *
313
+ * return the number of nodes.
314
+ *
315
+ * NOTE:this is used to pick nodes for paths.
316
+ */
317
+ uint16_t random_nodes_path(const DHT *dht, Node_format *nodes, uint16_t max_num);
318
+
319
+ /* Run this function at least a couple times per second (It's the main loop). */
320
+ void do_DHT(DHT *dht);
321
+
322
+ /*
323
+ * Use these two functions to bootstrap the client.
324
+ */
325
+ /* Sends a "get nodes" request to the given node with ip, port and public_key
326
+ * to setup connections
327
+ */
328
+ void DHT_bootstrap(DHT *dht, IP_Port ip_port, const uint8_t *public_key);
329
+ /* Resolves address into an IP address. If successful, sends a "get nodes"
330
+ * request to the given node with ip, port and public_key to setup connections
331
+ *
332
+ * address can be a hostname or an IP address (IPv4 or IPv6).
333
+ * if ipv6enabled is 0 (zero), the resolving sticks STRICTLY to IPv4 addresses
334
+ * if ipv6enabled is not 0 (zero), the resolving looks for IPv6 addresses first,
335
+ * then IPv4 addresses.
336
+ *
337
+ * returns 1 if the address could be converted into an IP address
338
+ * returns 0 otherwise
339
+ */
340
+ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
341
+ uint16_t port, const uint8_t *public_key);
342
+
343
+ /* Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.
344
+ *
345
+ * returns 0 if successful
346
+ * returns -1 otherwise
347
+ */
348
+ int DHT_connect_after_load(DHT *dht);
349
+
350
+ /* ROUTING FUNCTIONS */
351
+
352
+ /* Send the given packet to node with client_id.
353
+ *
354
+ * return -1 if failure.
355
+ */
356
+ int route_packet(const DHT *dht, const uint8_t *client_id, const uint8_t *packet, uint32_t length);
357
+
358
+ /* Send the following packet to everyone who tells us they are connected to friend_id.
359
+ *
360
+ * return number of nodes it sent the packet to.
361
+ */
362
+ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *packet, uint32_t length);
363
+
364
+ /* Function to handle crypto packets.
365
+ */
366
+ void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_callback cb, void *object);
367
+
368
+ /* NAT PUNCHING FUNCTIONS */
369
+
370
+ /* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist.
371
+ * ip_portlist must be at least MAX_FRIEND_CLIENTS big.
372
+ *
373
+ * returns number of ips returned.
374
+ * returns -1 if no such friend.
375
+ */
376
+ int friend_ips(const DHT *dht, IP_Port *ip_portlist, const uint8_t *friend_id);
377
+
378
+ /* SAVE/LOAD functions */
379
+
380
+ /* Get the size of the DHT (for saving). */
381
+ uint32_t DHT_size(const DHT *dht);
382
+
383
+ /* Save the DHT in data where data is an array of size DHT_size(). */
384
+ void DHT_save(DHT *dht, uint8_t *data);
385
+
386
+ /* Load the DHT from data of size size.
387
+ *
388
+ * return -1 if failure.
389
+ * return 0 if success.
390
+ */
391
+ int DHT_load(DHT *dht, const uint8_t *data, uint32_t length);
392
+
393
+ /* Initialize DHT. */
394
+ DHT *new_DHT(Networking_Core *net);
395
+
396
+ void kill_DHT(DHT *dht);
397
+
398
+ /* return 0 if we are not connected to the DHT.
399
+ * return 1 if we are.
400
+ */
401
+ int DHT_isconnected(const DHT *dht);
402
+
403
+ /* return 0 if we are not connected or only connected to lan peers with the DHT.
404
+ * return 1 if we are.
405
+ */
406
+ int DHT_non_lan_connected(const DHT *dht);
407
+
408
+
409
+ int addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *client_id);
410
+
411
+ #endif
412
+
@@ -0,0 +1,322 @@
1
+ /* LAN_discovery.c
2
+ *
3
+ * LAN discovery implementation.
4
+ *
5
+ * Copyright (C) 2013 Tox project All Rights Reserved.
6
+ *
7
+ * This file is part of Tox.
8
+ *
9
+ * Tox is free software: you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation, either version 3 of the License, or
12
+ * (at your option) any later version.
13
+ *
14
+ * Tox is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ * GNU General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU General Public License
20
+ * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21
+ *
22
+ */
23
+
24
+ #ifdef HAVE_CONFIG_H
25
+ #include "config.h"
26
+ #endif
27
+
28
+ #include "LAN_discovery.h"
29
+ #include "util.h"
30
+
31
+ #define MAX_INTERFACES 16
32
+
33
+
34
+ static int broadcast_count = -1;
35
+ static IP_Port broadcast_ip_port[MAX_INTERFACES];
36
+
37
+ #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
38
+
39
+ #include <iphlpapi.h>
40
+
41
+ static void fetch_broadcast_info(uint16_t port)
42
+ {
43
+ broadcast_count = 0;
44
+
45
+ IP_ADAPTER_INFO *pAdapterInfo = malloc(sizeof(pAdapterInfo));
46
+ unsigned long ulOutBufLen = sizeof(pAdapterInfo);
47
+
48
+ if (pAdapterInfo == NULL) {
49
+ return;
50
+ }
51
+
52
+ if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
53
+ free(pAdapterInfo);
54
+ pAdapterInfo = malloc(ulOutBufLen);
55
+
56
+ if (pAdapterInfo == NULL) {
57
+ return;
58
+ }
59
+ }
60
+
61
+ int ret;
62
+
63
+ if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
64
+ IP_ADAPTER_INFO *pAdapter = pAdapterInfo;
65
+
66
+ while (pAdapter) {
67
+ IP gateway = {0}, subnet_mask = {0};
68
+
69
+ if (addr_parse_ip(pAdapter->IpAddressList.IpMask.String, &subnet_mask)
70
+ && addr_parse_ip(pAdapter->GatewayList.IpAddress.String, &gateway)) {
71
+ if (gateway.family == AF_INET && subnet_mask.family == AF_INET) {
72
+ IP_Port *ip_port = &broadcast_ip_port[broadcast_count];
73
+ ip_port->ip.family = AF_INET;
74
+ uint32_t gateway_ip = ntohl(gateway.ip4.uint32), subnet_ip = ntohl(subnet_mask.ip4.uint32);
75
+ uint32_t broadcast_ip = gateway_ip + ~subnet_ip - 1;
76
+ ip_port->ip.ip4.uint32 = htonl(broadcast_ip);
77
+ ip_port->port = port;
78
+ broadcast_count++;
79
+
80
+ if (broadcast_count >= MAX_INTERFACES) {
81
+ return;
82
+ }
83
+ }
84
+ }
85
+
86
+ pAdapter = pAdapter->Next;
87
+ }
88
+ }
89
+ }
90
+
91
+ #elif defined(__linux__)
92
+
93
+ static void fetch_broadcast_info(uint16_t port)
94
+ {
95
+ /* Not sure how many platforms this will run on,
96
+ * so it's wrapped in __linux for now.
97
+ * Definitely won't work like this on Windows...
98
+ */
99
+ broadcast_count = 0;
100
+ sock_t sock = 0;
101
+
102
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
103
+ return;
104
+
105
+ /* Configure ifconf for the ioctl call. */
106
+ struct ifreq i_faces[MAX_INTERFACES];
107
+ memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES);
108
+
109
+ struct ifconf ifconf;
110
+ ifconf.ifc_buf = (char *)i_faces;
111
+ ifconf.ifc_len = sizeof(i_faces);
112
+
113
+ if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0) {
114
+ close(sock);
115
+ return;
116
+ }
117
+
118
+ /* ifconf.ifc_len is set by the ioctl() to the actual length used;
119
+ * on usage of the complete array the call should be repeated with
120
+ * a larger array, not done (640kB and 16 interfaces shall be
121
+ * enough, for everybody!)
122
+ */
123
+ int i, count = ifconf.ifc_len / sizeof(struct ifreq);
124
+
125
+ for (i = 0; i < count; i++) {
126
+ /* there are interfaces with are incapable of broadcast */
127
+ if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0)
128
+ continue;
129
+
130
+ /* moot check: only AF_INET returned (backwards compat.) */
131
+ if (i_faces[i].ifr_broadaddr.sa_family != AF_INET)
132
+ continue;
133
+
134
+ struct sockaddr_in *sock4 = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr;
135
+
136
+ if (broadcast_count >= MAX_INTERFACES) {
137
+ close(sock);
138
+ return;
139
+ }
140
+
141
+ IP_Port *ip_port = &broadcast_ip_port[broadcast_count];
142
+ ip_port->ip.family = AF_INET;
143
+ ip_port->ip.ip4.in_addr = sock4->sin_addr;
144
+ ip_port->port = port;
145
+ broadcast_count++;
146
+ }
147
+
148
+ close(sock);
149
+ }
150
+
151
+ #else //TODO: Other platforms?
152
+
153
+ static void fetch_broadcast_info(uint16_t port)
154
+ {
155
+ broadcast_count = 0;
156
+ }
157
+
158
+ #endif
159
+ /* Send packet to all IPv4 broadcast addresses
160
+ *
161
+ * return 1 if sent to at least one broadcast target.
162
+ * return 0 on failure to find any valid broadcast target.
163
+ */
164
+ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, const uint8_t *data, uint16_t length)
165
+ {
166
+ /* fetch only once? on every packet? every X seconds?
167
+ * old: every packet, new: once */
168
+ if (broadcast_count < 0)
169
+ fetch_broadcast_info(port);
170
+
171
+ if (!broadcast_count)
172
+ return 0;
173
+
174
+ int i;
175
+
176
+ for (i = 0; i < broadcast_count; i++)
177
+ sendpacket(net, broadcast_ip_port[i], data, length);
178
+
179
+ return 1;
180
+ }
181
+
182
+ /* Return the broadcast ip. */
183
+ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
184
+ {
185
+ IP ip;
186
+ ip_reset(&ip);
187
+
188
+ if (family_socket == AF_INET6) {
189
+ if (family_broadcast == AF_INET6) {
190
+ ip.family = AF_INET6;
191
+ /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */
192
+ /* FE80::*: MUST be exact, for that we would need to look over all
193
+ * interfaces and check in which status they are */
194
+ ip.ip6.uint8[ 0] = 0xFF;
195
+ ip.ip6.uint8[ 1] = 0x02;
196
+ ip.ip6.uint8[15] = 0x01;
197
+ } else if (family_broadcast == AF_INET) {
198
+ ip.family = AF_INET6;
199
+ ip.ip6.uint32[0] = 0;
200
+ ip.ip6.uint32[1] = 0;
201
+ ip.ip6.uint32[2] = htonl(0xFFFF);
202
+ ip.ip6.uint32[3] = INADDR_BROADCAST;
203
+ }
204
+ } else if (family_socket == AF_INET) {
205
+ if (family_broadcast == AF_INET) {
206
+ ip.family = AF_INET;
207
+ ip.ip4.uint32 = INADDR_BROADCAST;
208
+ }
209
+ }
210
+
211
+ return ip;
212
+ }
213
+
214
+ /* return 0 if ip is a LAN ip.
215
+ * return -1 if it is not.
216
+ */
217
+ int LAN_ip(IP ip)
218
+ {
219
+ if (ip.family == AF_INET) {
220
+ IP4 ip4 = ip.ip4;
221
+
222
+ /* Loopback. */
223
+ if (ip4.uint8[0] == 127)
224
+ return 0;
225
+
226
+ /* 10.0.0.0 to 10.255.255.255 range. */
227
+ if (ip4.uint8[0] == 10)
228
+ return 0;
229
+
230
+ /* 172.16.0.0 to 172.31.255.255 range. */
231
+ if (ip4.uint8[0] == 172 && ip4.uint8[1] >= 16 && ip4.uint8[1] <= 31)
232
+ return 0;
233
+
234
+ /* 192.168.0.0 to 192.168.255.255 range. */
235
+ if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168)
236
+ return 0;
237
+
238
+ /* 169.254.1.0 to 169.254.254.255 range. */
239
+ if (ip4.uint8[0] == 169 && ip4.uint8[1] == 254 && ip4.uint8[2] != 0
240
+ && ip4.uint8[2] != 255)
241
+ return 0;
242
+
243
+ /* RFC 6598: 100.64.0.0 to 100.127.255.255 (100.64.0.0/10)
244
+ * (shared address space to stack another layer of NAT) */
245
+ if ((ip4.uint8[0] == 100) && ((ip4.uint8[1] & 0xC0) == 0x40))
246
+ return 0;
247
+
248
+ } else if (ip.family == AF_INET6) {
249
+
250
+ /* autogenerated for each interface: FE80::* (up to FEBF::*)
251
+ FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */
252
+ if (((ip.ip6.uint8[0] == 0xFF) && (ip.ip6.uint8[1] < 3) && (ip.ip6.uint8[15] == 1)) ||
253
+ ((ip.ip6.uint8[0] == 0xFE) && ((ip.ip6.uint8[1] & 0xC0) == 0x80)))
254
+ return 0;
255
+
256
+ /* embedded IPv4-in-IPv6 */
257
+ if (IPV6_IPV4_IN_V6(ip.ip6)) {
258
+ IP ip4;
259
+ ip4.family = AF_INET;
260
+ ip4.ip4.uint32 = ip.ip6.uint32[3];
261
+ return LAN_ip(ip4);
262
+ }
263
+
264
+ /* localhost in IPv6 (::1) */
265
+ if (ip.ip6.uint64[0] == 0 && ip.ip6.uint32[2] == 0 && ip.ip6.uint32[3] == htonl(1))
266
+ return 0;
267
+ }
268
+
269
+ return -1;
270
+ }
271
+
272
+ static int handle_LANdiscovery(void *object, IP_Port source, const uint8_t *packet, uint32_t length)
273
+ {
274
+ DHT *dht = object;
275
+
276
+ if (LAN_ip(source.ip) == -1)
277
+ return 1;
278
+
279
+ if (length != crypto_box_PUBLICKEYBYTES + 1)
280
+ return 1;
281
+
282
+ DHT_bootstrap(dht, source, packet + 1);
283
+ return 0;
284
+ }
285
+
286
+
287
+ int send_LANdiscovery(uint16_t port, DHT *dht)
288
+ {
289
+ uint8_t data[crypto_box_PUBLICKEYBYTES + 1];
290
+ data[0] = NET_PACKET_LAN_DISCOVERY;
291
+ id_copy(data + 1, dht->self_public_key);
292
+
293
+ send_broadcasts(dht->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
294
+
295
+ int res = -1;
296
+ IP_Port ip_port;
297
+ ip_port.port = port;
298
+
299
+ /* IPv6 multicast */
300
+ if (dht->net->family == AF_INET6) {
301
+ ip_port.ip = broadcast_ip(AF_INET6, AF_INET6);
302
+
303
+ if (ip_isset(&ip_port.ip))
304
+ if (sendpacket(dht->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES) > 0)
305
+ res = 1;
306
+ }
307
+
308
+ /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is AF_INET6 */
309
+ ip_port.ip = broadcast_ip(dht->net->family, AF_INET);
310
+
311
+ if (ip_isset(&ip_port.ip))
312
+ if (sendpacket(dht->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES))
313
+ res = 1;
314
+
315
+ return res;
316
+ }
317
+
318
+
319
+ void LANdiscovery_init(DHT *dht)
320
+ {
321
+ networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht);
322
+ }