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,253 @@
1
+ /*
2
+ * onion_client.h -- Implementation of the client part of docs/Prevent_Tracking.txt
3
+ * (The part that uses the onion stuff to connect to the friend)
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 ONION_CLIENT_H
25
+ #define ONION_CLIENT_H
26
+
27
+ #include "onion_announce.h"
28
+ #include "net_crypto.h"
29
+ #include "ping_array.h"
30
+
31
+ #define MAX_ONION_CLIENTS 8
32
+ #define ONION_NODE_PING_INTERVAL 30
33
+ #define ONION_NODE_TIMEOUT (ONION_NODE_PING_INTERVAL * 4)
34
+
35
+ /* The interval in seconds at which to tell our friends where we are */
36
+ #define ONION_FAKEID_INTERVAL 30
37
+ #define DHT_FAKEID_INTERVAL 20
38
+
39
+ #define NUMBER_ONION_PATHS 3
40
+
41
+ /* The timeout the first time the path is added and
42
+ then for all the next consecutive times */
43
+ #define ONION_PATH_FIRST_TIMEOUT 5
44
+ #define ONION_PATH_TIMEOUT 30
45
+ #define ONION_PATH_MAX_LIFETIME 600
46
+
47
+ #define MAX_STORED_PINGED_NODES 9
48
+ #define MIN_NODE_PING_TIME 10
49
+
50
+ #define MAX_PATH_NODES 32
51
+
52
+ typedef struct {
53
+ uint8_t client_id[CLIENT_ID_SIZE];
54
+ IP_Port ip_port;
55
+ uint8_t ping_id[ONION_PING_ID_SIZE];
56
+ uint8_t data_public_key[crypto_box_PUBLICKEYBYTES];
57
+ uint8_t is_stored;
58
+
59
+ uint64_t timestamp;
60
+
61
+ uint64_t last_pinged;
62
+
63
+ uint32_t path_used;
64
+ } Onion_Node;
65
+
66
+ typedef struct {
67
+ Onion_Path paths[NUMBER_ONION_PATHS];
68
+ uint64_t last_path_success[NUMBER_ONION_PATHS];
69
+ uint64_t path_creation_time[NUMBER_ONION_PATHS];
70
+ } Onion_Client_Paths;
71
+
72
+ typedef struct {
73
+ uint8_t client_id[CLIENT_ID_SIZE];
74
+ uint64_t timestamp;
75
+ } Last_Pinged;
76
+
77
+ typedef struct {
78
+ uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/
79
+ uint8_t is_online; /* Set by the onion_set_friend_status function. */
80
+
81
+ uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */
82
+ uint64_t fake_client_id_timestamp;
83
+ uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES];
84
+ uint8_t real_client_id[crypto_box_PUBLICKEYBYTES];
85
+
86
+ Onion_Node clients_list[MAX_ONION_CLIENTS];
87
+ uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
88
+ uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
89
+
90
+ uint64_t last_fakeid_onion_sent;
91
+ uint64_t last_fakeid_dht_sent;
92
+
93
+ uint64_t last_noreplay;
94
+
95
+ uint64_t last_seen;
96
+
97
+ Onion_Client_Paths onion_paths;
98
+
99
+ Last_Pinged last_pinged[MAX_STORED_PINGED_NODES];
100
+ uint8_t last_pinged_index;
101
+
102
+ int (*tcp_relay_node_callback)(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key);
103
+ void *tcp_relay_node_callback_object;
104
+ uint32_t tcp_relay_node_callback_number;
105
+
106
+ uint32_t run_count;
107
+ } Onion_Friend;
108
+
109
+ typedef int (*oniondata_handler_callback)(void *object, const uint8_t *source_pubkey, const uint8_t *data,
110
+ uint32_t len);
111
+
112
+ typedef struct {
113
+ DHT *dht;
114
+ Net_Crypto *c;
115
+ Networking_Core *net;
116
+ Onion_Friend *friends_list;
117
+ uint16_t num_friends;
118
+
119
+ Onion_Node clients_announce_list[MAX_ONION_CLIENTS];
120
+
121
+ Onion_Client_Paths onion_paths;
122
+
123
+ uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
124
+ uint64_t last_run;
125
+
126
+ uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
127
+ uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
128
+
129
+ Last_Pinged last_pinged[MAX_STORED_PINGED_NODES];
130
+
131
+ Node_format path_nodes[MAX_PATH_NODES];
132
+ uint16_t path_nodes_index;
133
+
134
+ Ping_Array announce_ping_array;
135
+ uint8_t last_pinged_index;
136
+ struct {
137
+ oniondata_handler_callback function;
138
+ void *object;
139
+ } Onion_Data_Handlers[256];
140
+ } Onion_Client;
141
+
142
+
143
+ /* Add a node to the path_nodes array.
144
+ *
145
+ * return -1 on failure
146
+ * return 0 on success
147
+ */
148
+ int onion_add_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *client_id);
149
+
150
+ /* Put up to max_num nodes in nodes.
151
+ *
152
+ * return the number of nodes.
153
+ */
154
+ uint16_t onion_backup_nodes(const Onion_Client *onion_c, Node_format *nodes, uint16_t max_num);
155
+
156
+ /* Add a friend who we want to connect to.
157
+ *
158
+ * return -1 on failure.
159
+ * return the friend number on success or if the friend was already added.
160
+ */
161
+ int onion_friend_num(const Onion_Client *onion_c, const uint8_t *client_id);
162
+
163
+ /* Add a friend who we want to connect to.
164
+ *
165
+ * return -1 on failure.
166
+ * return the friend number on success.
167
+ */
168
+ int onion_addfriend(Onion_Client *onion_c, const uint8_t *client_id);
169
+
170
+ /* Delete a friend.
171
+ *
172
+ * return -1 on failure.
173
+ * return the deleted friend number on success.
174
+ */
175
+ int onion_delfriend(Onion_Client *onion_c, int friend_num);
176
+
177
+ /* Set if friend is online or not.
178
+ * NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
179
+ *
180
+ * is_online 1 means friend is online.
181
+ * is_online 0 means friend is offline
182
+ *
183
+ * return -1 on failure.
184
+ * return 0 on success.
185
+ */
186
+ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_online);
187
+
188
+ /* Get the ip of friend friendnum and put it in ip_port
189
+ *
190
+ * return -1, -- if client_id does NOT refer to a friend
191
+ * return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
192
+ * return 1, ip if client_id refers to a friend and we found him
193
+ *
194
+ */
195
+ int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
196
+
197
+ /* Set the function for this friend that will be callbacked with object and number
198
+ * when that friends gives us one of the TCP relays he is connected to.
199
+ *
200
+ * object and number will be passed as argument to this function.
201
+ *
202
+ * return -1 on failure.
203
+ * return 0 on success.
204
+ */
205
+ int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object,
206
+ uint32_t number, IP_Port ip_port, const uint8_t *public_key), void *object, uint32_t number);
207
+
208
+ /* Set a friends DHT public key.
209
+ * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
210
+ * the other peer.
211
+ *
212
+ * return -1 on failure.
213
+ * return 0 on success.
214
+ */
215
+ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key, uint64_t timestamp);
216
+
217
+ /* Copy friends DHT public key into dht_key.
218
+ *
219
+ * return 0 on failure (no key copied).
220
+ * return timestamp on success (key copied).
221
+ */
222
+ uint64_t onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key);
223
+
224
+ #define ONION_DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
225
+ #define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
226
+
227
+ /* Send data of length length to friendnum.
228
+ * Maximum length of data is ONION_CLIENT_MAX_DATA_SIZE.
229
+ * This data will be received by the friend using the Onion_Data_Handlers callbacks.
230
+ *
231
+ * Even if this function succeeds, the friend might not receive any data.
232
+ *
233
+ * return the number of packets sent on success
234
+ * return -1 on failure.
235
+ */
236
+ int send_onion_data(const Onion_Client *onion_c, int friend_num, const uint8_t *data, uint32_t length);
237
+
238
+ /* Function to call when onion data packet with contents beginning with byte is received. */
239
+ void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object);
240
+
241
+ void do_onion_client(Onion_Client *onion_c);
242
+
243
+ Onion_Client *new_onion_client(Net_Crypto *c);
244
+
245
+ void kill_onion_client(Onion_Client *onion_c);
246
+
247
+
248
+ /* return 0 if we are not connected to the network.
249
+ * return 1 if we are.
250
+ */
251
+ int onion_isconnected(const Onion_Client *onion_c);
252
+
253
+ #endif
@@ -0,0 +1,346 @@
1
+ /*
2
+ * ping.c -- Buffered pinging using cyclic arrays.
3
+ *
4
+ * This file is donated to the Tox Project.
5
+ * Copyright 2013 plutooo
6
+ *
7
+ * Copyright (C) 2013 Tox project All Rights Reserved.
8
+ *
9
+ * This file is part of Tox.
10
+ *
11
+ * Tox is free software: you can redistribute it and/or modify
12
+ * it under the terms of the GNU General Public License as published by
13
+ * the Free Software Foundation, either version 3 of the License, or
14
+ * (at your option) any later version.
15
+ *
16
+ * Tox is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License
22
+ * along with Tox. If not, see <http://www.gnu.org/licenses/>.
23
+ *
24
+ */
25
+
26
+ #ifdef HAVE_CONFIG_H
27
+ #include "config.h"
28
+ #endif
29
+
30
+ #include <stdint.h>
31
+
32
+ #include "DHT.h"
33
+ #include "ping.h"
34
+
35
+ #include "network.h"
36
+ #include "util.h"
37
+ #include "ping_array.h"
38
+
39
+ #define PING_NUM_MAX 512
40
+
41
+ /* Maximum newly announced nodes to ping per TIME_TO_PING seconds. */
42
+ #define MAX_TO_PING 16
43
+
44
+ /* Ping newly announced nodes to ping per TIME_TO_PING seconds*/
45
+ #define TIME_TO_PING 4
46
+
47
+
48
+ struct PING {
49
+ DHT *dht;
50
+
51
+ Ping_Array ping_array;
52
+ Node_format to_ping[MAX_TO_PING];
53
+ uint64_t last_to_ping;
54
+ };
55
+
56
+
57
+ #define PING_PLAIN_SIZE (1 + sizeof(uint64_t))
58
+ #define DHT_PING_SIZE (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + PING_PLAIN_SIZE + crypto_box_MACBYTES)
59
+ #define PING_DATA_SIZE (CLIENT_ID_SIZE + sizeof(IP_Port))
60
+
61
+ int send_ping_request(PING *ping, IP_Port ipp, const uint8_t *client_id)
62
+ {
63
+ uint8_t pk[DHT_PING_SIZE];
64
+ int rc;
65
+ uint64_t ping_id;
66
+
67
+ if (id_equal(client_id, ping->dht->self_public_key))
68
+ return 1;
69
+
70
+ uint8_t shared_key[crypto_box_BEFORENMBYTES];
71
+
72
+ // generate key to encrypt ping_id with recipient privkey
73
+ DHT_get_shared_key_sent(ping->dht, shared_key, client_id);
74
+ // Generate random ping_id.
75
+ uint8_t data[PING_DATA_SIZE];
76
+ id_copy(data, client_id);
77
+ memcpy(data + CLIENT_ID_SIZE, &ipp, sizeof(IP_Port));
78
+ ping_id = ping_array_add(&ping->ping_array, data, sizeof(data));
79
+
80
+ if (ping_id == 0)
81
+ return 1;
82
+
83
+ uint8_t ping_plain[PING_PLAIN_SIZE];
84
+ ping_plain[0] = NET_PACKET_PING_REQUEST;
85
+ memcpy(ping_plain + 1, &ping_id, sizeof(ping_id));
86
+
87
+ pk[0] = NET_PACKET_PING_REQUEST;
88
+ id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey
89
+ new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
90
+
91
+
92
+ rc = encrypt_data_symmetric(shared_key,
93
+ pk + 1 + CLIENT_ID_SIZE,
94
+ ping_plain, sizeof(ping_plain),
95
+ pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES);
96
+
97
+ if (rc != PING_PLAIN_SIZE + crypto_box_MACBYTES)
98
+ return 1;
99
+
100
+ return sendpacket(ping->dht->net, ipp, pk, sizeof(pk));
101
+ }
102
+
103
+ static int send_ping_response(PING *ping, IP_Port ipp, const uint8_t *client_id, uint64_t ping_id,
104
+ uint8_t *shared_encryption_key)
105
+ {
106
+ uint8_t pk[DHT_PING_SIZE];
107
+ int rc;
108
+
109
+ if (id_equal(client_id, ping->dht->self_public_key))
110
+ return 1;
111
+
112
+ uint8_t ping_plain[PING_PLAIN_SIZE];
113
+ ping_plain[0] = NET_PACKET_PING_RESPONSE;
114
+ memcpy(ping_plain + 1, &ping_id, sizeof(ping_id));
115
+
116
+ pk[0] = NET_PACKET_PING_RESPONSE;
117
+ id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey
118
+ new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
119
+
120
+ // Encrypt ping_id using recipient privkey
121
+ rc = encrypt_data_symmetric(shared_encryption_key,
122
+ pk + 1 + CLIENT_ID_SIZE,
123
+ ping_plain, sizeof(ping_plain),
124
+ pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES );
125
+
126
+ if (rc != PING_PLAIN_SIZE + crypto_box_MACBYTES)
127
+ return 1;
128
+
129
+ return sendpacket(ping->dht->net, ipp, pk, sizeof(pk));
130
+ }
131
+
132
+ static int handle_ping_request(void *_dht, IP_Port source, const uint8_t *packet, uint32_t length)
133
+ {
134
+ DHT *dht = _dht;
135
+ int rc;
136
+
137
+ if (length != DHT_PING_SIZE)
138
+ return 1;
139
+
140
+ PING *ping = dht->ping;
141
+
142
+ if (id_equal(packet + 1, ping->dht->self_public_key))
143
+ return 1;
144
+
145
+ uint8_t shared_key[crypto_box_BEFORENMBYTES];
146
+
147
+ uint8_t ping_plain[PING_PLAIN_SIZE];
148
+ // Decrypt ping_id
149
+ DHT_get_shared_key_recv(dht, shared_key, packet + 1);
150
+ rc = decrypt_data_symmetric(shared_key,
151
+ packet + 1 + CLIENT_ID_SIZE,
152
+ packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
153
+ PING_PLAIN_SIZE + crypto_box_MACBYTES,
154
+ ping_plain );
155
+
156
+ if (rc != sizeof(ping_plain))
157
+ return 1;
158
+
159
+ if (ping_plain[0] != NET_PACKET_PING_REQUEST)
160
+ return 1;
161
+
162
+ uint64_t ping_id;
163
+ memcpy(&ping_id, ping_plain + 1, sizeof(ping_id));
164
+ // Send response
165
+ send_ping_response(ping, source, packet + 1, ping_id, shared_key);
166
+ add_to_ping(ping, packet + 1, source);
167
+
168
+ return 0;
169
+ }
170
+
171
+ static int handle_ping_response(void *_dht, IP_Port source, const uint8_t *packet, uint32_t length)
172
+ {
173
+ DHT *dht = _dht;
174
+ int rc;
175
+
176
+ if (length != DHT_PING_SIZE)
177
+ return 1;
178
+
179
+ PING *ping = dht->ping;
180
+
181
+ if (id_equal(packet + 1, ping->dht->self_public_key))
182
+ return 1;
183
+
184
+ uint8_t shared_key[crypto_box_BEFORENMBYTES];
185
+
186
+ // generate key to encrypt ping_id with recipient privkey
187
+ DHT_get_shared_key_sent(ping->dht, shared_key, packet + 1);
188
+
189
+ uint8_t ping_plain[PING_PLAIN_SIZE];
190
+ // Decrypt ping_id
191
+ rc = decrypt_data_symmetric(shared_key,
192
+ packet + 1 + CLIENT_ID_SIZE,
193
+ packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
194
+ PING_PLAIN_SIZE + crypto_box_MACBYTES,
195
+ ping_plain);
196
+
197
+ if (rc != sizeof(ping_plain))
198
+ return 1;
199
+
200
+ if (ping_plain[0] != NET_PACKET_PING_RESPONSE)
201
+ return 1;
202
+
203
+ uint64_t ping_id;
204
+ memcpy(&ping_id, ping_plain + 1, sizeof(ping_id));
205
+ uint8_t data[PING_DATA_SIZE];
206
+
207
+ if (ping_array_check(data, sizeof(data), &ping->ping_array, ping_id) != sizeof(data))
208
+ return 1;
209
+
210
+ if (!id_equal(packet + 1, data))
211
+ return 1;
212
+
213
+ IP_Port ipp;
214
+ memcpy(&ipp, data + CLIENT_ID_SIZE, sizeof(IP_Port));
215
+
216
+ if (!ipport_equal(&ipp, &source))
217
+ return 1;
218
+
219
+ addto_lists(dht, source, packet + 1);
220
+ return 0;
221
+ }
222
+
223
+ /* Check if client_id with ip_port is in the list.
224
+ *
225
+ * return 1 if it is.
226
+ * return 0 if it isn't.
227
+ */
228
+ static int in_list(const Client_data *list, uint32_t length, const uint8_t *client_id, IP_Port ip_port)
229
+ {
230
+ uint32_t i;
231
+
232
+ for (i = 0; i < length; ++i) {
233
+ if (id_equal(list[i].client_id, client_id)) {
234
+ const IPPTsPng *ipptp;
235
+
236
+ if (ip_port.ip.family == AF_INET) {
237
+ ipptp = &list[i].assoc4;
238
+ } else {
239
+ ipptp = &list[i].assoc6;
240
+ }
241
+
242
+ if (!is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT) && ipport_equal(&ipptp->ip_port, &ip_port))
243
+ return 1;
244
+ }
245
+ }
246
+
247
+ return 0;
248
+ }
249
+
250
+ /* Add nodes to the to_ping list.
251
+ * All nodes in this list are pinged every TIME_TO_PING seconds
252
+ * and are then removed from the list.
253
+ * If the list is full the nodes farthest from our client_id are replaced.
254
+ * The purpose of this list is to enable quick integration of new nodes into the
255
+ * network while preventing amplification attacks.
256
+ *
257
+ * return 0 if node was added.
258
+ * return -1 if node was not added.
259
+ */
260
+ int add_to_ping(PING *ping, const uint8_t *client_id, IP_Port ip_port)
261
+ {
262
+ if (!ip_isset(&ip_port.ip))
263
+ return -1;
264
+
265
+ if (in_list(ping->dht->close_clientlist, LCLIENT_LIST, client_id, ip_port))
266
+ return -1;
267
+
268
+ uint32_t i;
269
+
270
+ for (i = 0; i < MAX_TO_PING; ++i) {
271
+ if (!ip_isset(&ping->to_ping[i].ip_port.ip)) {
272
+ memcpy(ping->to_ping[i].client_id, client_id, CLIENT_ID_SIZE);
273
+ ipport_copy(&ping->to_ping[i].ip_port, &ip_port);
274
+ return 0;
275
+ }
276
+
277
+ if (memcmp(ping->to_ping[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
278
+ return -1;
279
+ }
280
+ }
281
+
282
+ uint32_t r = rand();
283
+
284
+ for (i = 0; i < MAX_TO_PING; ++i) {
285
+ if (id_closest(ping->dht->self_public_key, ping->to_ping[(i + r) % MAX_TO_PING].client_id, client_id) == 2) {
286
+ memcpy(ping->to_ping[(i + r) % MAX_TO_PING].client_id, client_id, CLIENT_ID_SIZE);
287
+ ipport_copy(&ping->to_ping[(i + r) % MAX_TO_PING].ip_port, &ip_port);
288
+ return 0;
289
+ }
290
+ }
291
+
292
+ return -1;
293
+ }
294
+
295
+
296
+ /* Ping all the valid nodes in the to_ping list every TIME_TO_PING seconds.
297
+ * This function must be run at least once every TIME_TO_PING seconds.
298
+ */
299
+ void do_to_ping(PING *ping)
300
+ {
301
+ if (!is_timeout(ping->last_to_ping, TIME_TO_PING))
302
+ return;
303
+
304
+ if (!ip_isset(&ping->to_ping[0].ip_port.ip))
305
+ return;
306
+
307
+ ping->last_to_ping = unix_time();
308
+ uint32_t i;
309
+
310
+ for (i = 0; i < MAX_TO_PING; ++i) {
311
+ if (!ip_isset(&ping->to_ping[i].ip_port.ip))
312
+ return;
313
+
314
+ send_ping_request(ping, ping->to_ping[i].ip_port, ping->to_ping[i].client_id);
315
+ ip_reset(&ping->to_ping[i].ip_port.ip);
316
+ }
317
+ }
318
+
319
+
320
+ PING *new_ping(DHT *dht)
321
+ {
322
+ PING *ping = calloc(1, sizeof(PING));
323
+
324
+ if (ping == NULL)
325
+ return NULL;
326
+
327
+ if (ping_array_init(&ping->ping_array, PING_NUM_MAX, PING_TIMEOUT) != 0) {
328
+ free(ping);
329
+ return NULL;
330
+ }
331
+
332
+ ping->dht = dht;
333
+ networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, &handle_ping_request, dht);
334
+ networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, dht);
335
+
336
+ return ping;
337
+ }
338
+
339
+ void kill_ping(PING *ping)
340
+ {
341
+ networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, NULL, NULL);
342
+ networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, NULL, NULL);
343
+ ping_array_free_all(&ping->ping_array);
344
+
345
+ free(ping);
346
+ }