summaryrefslogtreecommitdiff
path: root/core/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/DHT.c')
-rw-r--r--core/DHT.c605
1 files changed, 203 insertions, 402 deletions
diff --git a/core/DHT.c b/core/DHT.c
index 58cffdba..857ac5e8 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -1,33 +1,28 @@
1/* DHT.c 1/* DHT.c
2* 2 *
3* An implementation of the DHT as seen in docs/DHT.txt 3 * An implementation of the DHT as seen in docs/DHT.txt
4* 4 *
5 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 Copyright (C) 2013 Tox project All Rights Reserved. 6 *
7 7 * This file is part of Tox.
8 This file is part of Tox. 8 *
9 9 * Tox is free software: you can redistribute it and/or modify
10 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 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 the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version.
13 (at your option) any later version. 13 *
14 14 * Tox is distributed in the hope that it will be useful,
15 Tox is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details.
18 GNU General Public License for more details. 18 *
19 19 * You should have received a copy of the GNU General Public License
20 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 along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 *
22 22 */
23*/
24
25
26
27 23
28#include "DHT.h" 24#include "DHT.h"
29 25
30
31typedef struct 26typedef struct
32{ 27{
33 uint8_t client_id[CLIENT_ID_SIZE]; 28 uint8_t client_id[CLIENT_ID_SIZE];
@@ -38,8 +33,10 @@ typedef struct
38 (for nodes in friends_list) or us (for nodes in close_clientlist) */ 33 (for nodes in friends_list) or us (for nodes in close_clientlist) */
39 uint32_t ret_timestamp; 34 uint32_t ret_timestamp;
40}Client_data; 35}Client_data;
36
41/* maximum number of clients stored per friend. */ 37/* maximum number of clients stored per friend. */
42#define MAX_FRIEND_CLIENTS 8 38#define MAX_FRIEND_CLIENTS 8
39
43typedef struct 40typedef struct
44{ 41{
45 uint8_t client_id[CLIENT_ID_SIZE]; 42 uint8_t client_id[CLIENT_ID_SIZE];
@@ -54,7 +51,6 @@ typedef struct
54 uint32_t NATping_timestamp; 51 uint32_t NATping_timestamp;
55}Friend; 52}Friend;
56 53
57
58typedef struct 54typedef struct
59{ 55{
60 uint8_t client_id[CLIENT_ID_SIZE]; 56 uint8_t client_id[CLIENT_ID_SIZE];
@@ -78,8 +74,6 @@ uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
78#define LCLIENT_LIST 32 74#define LCLIENT_LIST 32
79static Client_data close_clientlist[LCLIENT_LIST]; 75static Client_data close_clientlist[LCLIENT_LIST];
80 76
81
82
83static Friend * friends_list; 77static Friend * friends_list;
84static uint16_t num_friends; 78static uint16_t num_friends;
85 79
@@ -92,7 +86,6 @@ static Pinged pings[LPING_ARRAY];
92 86
93static Pinged send_nodes[LSEND_NODES_ARRAY]; 87static Pinged send_nodes[LSEND_NODES_ARRAY];
94 88
95
96/* Compares client_id1 and client_id2 with client_id 89/* Compares client_id1 and client_id2 with client_id
97 return 0 if both are same distance 90 return 0 if both are same distance
98 return 1 if client_id1 is closer 91 return 1 if client_id1 is closer
@@ -100,17 +93,12 @@ static Pinged send_nodes[LSEND_NODES_ARRAY];
100int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */ 93int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */
101{ 94{
102 uint32_t i; 95 uint32_t i;
103 for(i = 0; i < CLIENT_ID_SIZE; ++i) 96 for(i = 0; i < CLIENT_ID_SIZE; ++i) {
104 { 97 if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i])) {
105 if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i]))
106 {
107 return 1; 98 return 1;
108 } 99 } else if(abs(client_id[i] ^ client_id1[i]) > abs(client_id[i] ^ client_id2[i])) {
109 else if(abs(client_id[i] ^ client_id1[i]) > abs(client_id[i] ^ client_id2[i]))
110 {
111 return 2; 100 return 2;
112 } 101 }
113
114 } 102 }
115 103
116 return 0; 104 return 0;
@@ -127,17 +115,14 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
127 uint32_t i; 115 uint32_t i;
128 uint32_t temp_time = unix_time(); 116 uint32_t temp_time = unix_time();
129 117
130 for(i = 0; i < length; ++i) 118 for(i = 0; i < length; ++i) {
131 {
132 /*If ip_port is assigned to a different client_id replace it*/ 119 /*If ip_port is assigned to a different client_id replace it*/
133 if(list[i].ip_port.ip.i == ip_port.ip.i && 120 if(list[i].ip_port.ip.i == ip_port.ip.i &&
134 list[i].ip_port.port == ip_port.port) 121 list[i].ip_port.port == ip_port.port) {
135 {
136 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 122 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
137 } 123 }
138 124
139 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) 125 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
140 {
141 /* Refresh the client timestamp. */ 126 /* Refresh the client timestamp. */
142 list[i].timestamp = temp_time; 127 list[i].timestamp = temp_time;
143 list[i].ip_port.ip.i = ip_port.ip.i; 128 list[i].ip_port.ip.i = ip_port.ip.i;
@@ -154,10 +139,8 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
154int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) 139int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
155{ 140{
156 uint32_t i; 141 uint32_t i;
157 for(i = 0; i < length; ++i) 142 for(i = 0; i < length; ++i) {
158 { 143 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
159 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0)
160 {
161 144
162 return 1; 145 return 1;
163 } 146 }
@@ -171,8 +154,7 @@ int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
171static int friend_number(uint8_t * client_id) 154static int friend_number(uint8_t * client_id)
172{ 155{
173 uint32_t i; 156 uint32_t i;
174 for(i = 0; i < num_friends; ++i) 157 for(i = 0; i < num_friends; ++i) {
175 {
176 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ 158 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */
177 { 159 {
178 return i; 160 return i;
@@ -181,13 +163,11 @@ static int friend_number(uint8_t * client_id)
181 return -1; 163 return -1;
182} 164}
183 165
184
185/* the number of seconds for a non responsive node to become bad. */ 166/* the number of seconds for a non responsive node to become bad. */
186#define BAD_NODE_TIMEOUT 70 167#define BAD_NODE_TIMEOUT 70
187/* the max number of nodes to send with send nodes. */ 168/* the max number of nodes to send with send nodes. */
188#define MAX_SENT_NODES 8 169#define MAX_SENT_NODES 8
189 170
190
191/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: 171/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request:
192 put them in the nodes_list and return how many were found. 172 put them in the nodes_list and return how many were found.
193 TODO: Make this function much more efficient. */ 173 TODO: Make this function much more efficient. */
@@ -196,48 +176,35 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
196 uint32_t i, j, k; 176 uint32_t i, j, k;
197 int num_nodes=0; 177 int num_nodes=0;
198 uint32_t temp_time = unix_time(); 178 uint32_t temp_time = unix_time();
199 for(i = 0; i < LCLIENT_LIST; ++i) 179 for(i = 0; i < LCLIENT_LIST; ++i) {
200 {
201 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && 180 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time &&
202 !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) 181 !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) {
203 /* if node is good and not already in list. */ 182 /* if node is good and not already in list. */
204 { 183 if(num_nodes < MAX_SENT_NODES) {
205 if(num_nodes < MAX_SENT_NODES)
206 {
207 memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 184 memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
208 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; 185 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
209 num_nodes++; 186 num_nodes++;
210 } 187 }
211 else for(j = 0; j < MAX_SENT_NODES; ++j) 188 else for(j = 0; j < MAX_SENT_NODES; ++j) {
212 { 189 if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) {
213 if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2)
214 {
215 memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 190 memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
216 nodes_list[j].ip_port = close_clientlist[i].ip_port; 191 nodes_list[j].ip_port = close_clientlist[i].ip_port;
217 break; 192 break;
218 } 193 }
219 } 194 }
220 } 195 }
221
222 } 196 }
223 for(i = 0; i < num_friends; ++i) 197 for(i = 0; i < num_friends; ++i) {
224 { 198 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
225 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
226 {
227 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time && 199 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time &&
228 !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) 200 !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) {
229 /* if node is good and not already in list. */ 201 /* if node is good and not already in list. */
230 { 202 if(num_nodes < MAX_SENT_NODES) {
231 if(num_nodes < MAX_SENT_NODES)
232 {
233 memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); 203 memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
234 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; 204 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
235 num_nodes++; 205 num_nodes++;
236 } 206 } else for(k = 0; k < MAX_SENT_NODES; ++k) {
237 else for(k = 0; k < MAX_SENT_NODES; ++k) 207 if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) {
238 {
239 if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2)
240 {
241 memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); 208 memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
242 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; 209 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
243 break; 210 break;
@@ -247,12 +214,9 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
247 } 214 }
248 } 215 }
249 216
250 return num_nodes; 217 return num_nodes;
251
252} 218}
253 219
254
255
256/* replace first bad (or empty) node with this one 220/* replace first bad (or empty) node with this one
257 return 0 if successful 221 return 0 if successful
258 return 1 if not (list contains no bad nodes) */ 222 return 1 if not (list contains no bad nodes) */
@@ -260,10 +224,8 @@ int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Por
260{ 224{
261 uint32_t i; 225 uint32_t i;
262 uint32_t temp_time = unix_time(); 226 uint32_t temp_time = unix_time();
263 for(i = 0; i < length; ++i) 227 for(i = 0; i < length; ++i) {
264 { 228 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) /* if node is bad. */ {
265 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) /* if node is bad. */
266 {
267 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 229 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
268 list[i].ip_port = ip_port; 230 list[i].ip_port = ip_port;
269 list[i].timestamp = temp_time; 231 list[i].timestamp = temp_time;
@@ -283,10 +245,8 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po
283 uint32_t i; 245 uint32_t i;
284 uint32_t temp_time = unix_time(); 246 uint32_t temp_time = unix_time();
285 247
286 for(i = 0; i < length; ++i) 248 for(i = 0; i < length; ++i) {
287 { 249 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) {
288 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2)
289 {
290 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 250 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
291 list[i].ip_port = ip_port; 251 list[i].ip_port = ip_port;
292 list[i].timestamp = temp_time; 252 list[i].timestamp = temp_time;
@@ -306,23 +266,16 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
306 uint32_t i; 266 uint32_t i;
307 267
308 /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */ 268 /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */
309 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 269 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
310 {
311 270
312 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 271 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
313 {
314 /* if we can't replace bad nodes we try replacing good ones */ 272 /* if we can't replace bad nodes we try replacing good ones */
315 replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key); 273 replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key);
316 } 274 }
317
318 } 275 }
319 for(i = 0; i < num_friends; ++i) 276 for(i = 0; i < num_friends; ++i) {
320 { 277 if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) {
321 if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) 278 if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) {
322 {
323
324 if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port))
325 {
326 /* if we can't replace bad nodes we try replacing good ones. */ 279 /* if we can't replace bad nodes we try replacing good ones. */
327 replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id); 280 replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id);
328 } 281 }
@@ -336,12 +289,9 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
336{ 289{
337 uint32_t i, j; 290 uint32_t i, j;
338 uint32_t temp_time = unix_time(); 291 uint32_t temp_time = unix_time();
339 if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) 292 if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) {
340 { 293 for(i = 0; i < LCLIENT_LIST; ++i) {
341 for(i = 0; i < LCLIENT_LIST; ++i) 294 if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) {
342 {
343 if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0)
344 {
345 close_clientlist[i].ret_ip_port = ip_port; 295 close_clientlist[i].ret_ip_port = ip_port;
346 close_clientlist[i].ret_timestamp = temp_time; 296 close_clientlist[i].ret_timestamp = temp_time;
347 return; 297 return;
@@ -349,14 +299,10 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
349 } 299 }
350 } 300 }
351 else 301 else
352 for(i = 0; i < num_friends; ++i) 302 for(i = 0; i < num_friends; ++i) {
353 { 303 if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) {
354 if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) 304 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
355 { 305 if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) {
356 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
357 {
358 if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0)
359 {
360 friends_list[i].client_list[j].ret_ip_port = ip_port; 306 friends_list[i].client_list[j].ret_ip_port = ip_port;
361 friends_list[i].client_list[j].ret_timestamp = temp_time; 307 friends_list[i].client_list[j].ret_timestamp = temp_time;
362 return; 308 return;
@@ -368,6 +314,7 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
368 314
369/* ping timeout in seconds */ 315/* ping timeout in seconds */
370#define PING_TIMEOUT 5 316#define PING_TIMEOUT 5
317
371/* check if we are currently pinging an ip_port and/or a ping_id 318/* check if we are currently pinging an ip_port and/or a ping_id
372 variables with values of zero will not be checked. 319 variables with values of zero will not be checked.
373 if we are already, return 1 320 if we are already, return 1
@@ -379,28 +326,22 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id)
379 uint8_t pinging; 326 uint8_t pinging;
380 uint32_t temp_time = unix_time(); 327 uint32_t temp_time = unix_time();
381 328
382 for(i = 0; i < LPING_ARRAY; ++i ) 329 for(i = 0; i < LPING_ARRAY; ++i ) {
383 { 330 if((pings[i].timestamp + PING_TIMEOUT) > temp_time) {
384 if((pings[i].timestamp + PING_TIMEOUT) > temp_time)
385 {
386 pinging = 0; 331 pinging = 0;
387 if(ip_port.ip.i != 0) 332 if(ip_port.ip.i != 0) {
388 {
389 if(pings[i].ip_port.ip.i == ip_port.ip.i && 333 if(pings[i].ip_port.ip.i == ip_port.ip.i &&
390 pings[i].ip_port.port == ip_port.port) 334 pings[i].ip_port.port == ip_port.port) {
391 {
392 ++pinging; 335 ++pinging;
393 } 336 }
394 } 337 }
395 if(ping_id != 0) 338 if(ping_id != 0) {
396 {
397 if(pings[i].ping_id == ping_id) 339 if(pings[i].ping_id == ping_id)
398 { 340 {
399 ++pinging; 341 ++pinging;
400 } 342 }
401 } 343 }
402 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 344 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) {
403 {
404 return 1; 345 return 1;
405 } 346 }
406 347
@@ -411,7 +352,6 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id)
411 352
412} 353}
413 354
414
415/* Same as last function but for get_node requests. */ 355/* Same as last function but for get_node requests. */
416int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) 356int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
417{ 357{
@@ -419,28 +359,21 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
419 uint8_t pinging; 359 uint8_t pinging;
420 uint32_t temp_time = unix_time(); 360 uint32_t temp_time = unix_time();
421 361
422 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) 362 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) {
423 { 363 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) {
424 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time)
425 {
426 pinging = 0; 364 pinging = 0;
427 if(ip_port.ip.i != 0) 365 if(ip_port.ip.i != 0) {
428 {
429 if(send_nodes[i].ip_port.ip.i == ip_port.ip.i && 366 if(send_nodes[i].ip_port.ip.i == ip_port.ip.i &&
430 send_nodes[i].ip_port.port == ip_port.port) 367 send_nodes[i].ip_port.port == ip_port.port) {
431 {
432 ++pinging; 368 ++pinging;
433 } 369 }
434 } 370 }
435 if(ping_id != 0) 371 if(ping_id != 0) {
436 { 372 if(send_nodes[i].ping_id == ping_id) {
437 if(send_nodes[i].ping_id == ping_id)
438 {
439 ++pinging; 373 ++pinging;
440 } 374 }
441 } 375 }
442 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 376 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) {
443 {
444 return 1; 377 return 1;
445 } 378 }
446 379
@@ -451,7 +384,6 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
451 384
452} 385}
453 386
454
455/* Add a new ping request to the list of ping requests 387/* Add a new ping request to the list of ping requests
456 returns the ping_id to put in the ping request 388 returns the ping_id to put in the ping request
457 returns 0 if problem. 389 returns 0 if problem.
@@ -462,12 +394,9 @@ uint64_t add_pinging(IP_Port ip_port)
462 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 394 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
463 uint32_t temp_time = unix_time(); 395 uint32_t temp_time = unix_time();
464 396
465 for(i = 0; i < PING_TIMEOUT; ++i ) 397 for(i = 0; i < PING_TIMEOUT; ++i ) {
466 { 398 for(j = 0; j < LPING_ARRAY; ++j ) {
467 for(j = 0; j < LPING_ARRAY; ++j ) 399 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) {
468 {
469 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time)
470 {
471 pings[j].timestamp = temp_time; 400 pings[j].timestamp = temp_time;
472 pings[j].ip_port = ip_port; 401 pings[j].ip_port = ip_port;
473 pings[j].ping_id = ping_id; 402 pings[j].ping_id = ping_id;
@@ -486,12 +415,9 @@ uint64_t add_gettingnodes(IP_Port ip_port)
486 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 415 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
487 uint32_t temp_time = unix_time(); 416 uint32_t temp_time = unix_time();
488 417
489 for(i = 0; i < PING_TIMEOUT; ++i ) 418 for(i = 0; i < PING_TIMEOUT; ++i ) {
490 { 419 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) {
491 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) 420 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) {
492 {
493 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time)
494 {
495 send_nodes[j].timestamp = temp_time; 421 send_nodes[j].timestamp = temp_time;
496 send_nodes[j].ip_port = ip_port; 422 send_nodes[j].ip_port = ip_port;
497 send_nodes[j].ping_id = ping_id; 423 send_nodes[j].ping_id = ping_id;
@@ -503,25 +429,20 @@ uint64_t add_gettingnodes(IP_Port ip_port)
503 429
504} 430}
505 431
506
507
508/* send a ping request 432/* send a ping request
509 Ping request only works if none has been sent to that ip/port in the last 5 seconds. */ 433 Ping request only works if none has been sent to that ip/port in the last 5 seconds. */
510static int pingreq(IP_Port ip_port, uint8_t * public_key) 434static int pingreq(IP_Port ip_port, uint8_t * public_key)
511{ 435{
512 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 436 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ {
513 {
514 return 1; 437 return 1;
515 } 438 }
516 439
517 if(is_pinging(ip_port, 0)) 440 if(is_pinging(ip_port, 0)) {
518 {
519 return 1; 441 return 1;
520 } 442 }
521 443
522 uint64_t ping_id = add_pinging(ip_port); 444 uint64_t ping_id = add_pinging(ip_port);
523 if(ping_id == 0) 445 if(ping_id == 0) {
524 {
525 return 1; 446 return 1;
526 } 447 }
527 448
@@ -531,8 +452,7 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key)
531 random_nonce(nonce); 452 random_nonce(nonce);
532 453
533 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); 454 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt);
534 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) 455 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) {
535 {
536 return -1; 456 return -1;
537 } 457 }
538 data[0] = 0; 458 data[0] = 0;
@@ -544,12 +464,11 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key)
544 464
545} 465}
546 466
547
548/* send a ping response */ 467/* send a ping response */
549static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) 468static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
550{ 469{
551 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 470 /* check if packet is gonna be sent to ourself */
552 { 471 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) {
553 return 1; 472 return 1;
554 } 473 }
555 474
@@ -559,8 +478,7 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
559 random_nonce(nonce); 478 random_nonce(nonce);
560 479
561 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); 480 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt);
562 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) 481 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) {
563 {
564 return -1; 482 return -1;
565 } 483 }
566 data[0] = 1; 484 data[0] = 1;
@@ -575,20 +493,18 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
575/* send a getnodes request */ 493/* send a getnodes request */
576static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) 494static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
577{ 495{
578 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 496 /* check if packet is gonna be sent to ourself */
579 { 497 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) {
580 return 1; 498 return 1;
581 } 499 }
582 500
583 if(is_gettingnodes(ip_port, 0)) 501 if(is_gettingnodes(ip_port, 0)) {
584 {
585 return 1; 502 return 1;
586 } 503 }
587 504
588 uint64_t ping_id = add_gettingnodes(ip_port); 505 uint64_t ping_id = add_gettingnodes(ip_port);
589 506
590 if(ping_id == 0) 507 if(ping_id == 0) {
591 {
592 return 1; 508 return 1;
593 } 509 }
594 510
@@ -603,8 +519,7 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
603 519
604 int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); 520 int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt);
605 521
606 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 522 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) {
607 {
608 return -1; 523 return -1;
609 } 524 }
610 data[0] = 2; 525 data[0] = 2;
@@ -615,12 +530,10 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
615 530
616} 531}
617 532
618
619/* send a send nodes response */ 533/* send a send nodes response */
620static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) 534static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id)
621{ 535{
622 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 536 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ {
623 {
624 return 1; 537 return 1;
625 } 538 }
626 539
@@ -630,8 +543,7 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
630 Node_format nodes_list[MAX_SENT_NODES]; 543 Node_format nodes_list[MAX_SENT_NODES];
631 int num_nodes = get_close_nodes(client_id, nodes_list); 544 int num_nodes = get_close_nodes(client_id, nodes_list);
632 545
633 if(num_nodes == 0) 546 if(num_nodes == 0) {
634 {
635 return 0; 547 return 0;
636 } 548 }
637 549
@@ -646,8 +558,7 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
646 int len = encrypt_data(public_key, self_secret_key, nonce, plain, 558 int len = encrypt_data(public_key, self_secret_key, nonce, plain,
647 sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); 559 sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt);
648 560
649 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) 561 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) {
650 {
651 return -1; 562 return -1;
652 } 563 }
653 564
@@ -660,20 +571,17 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
660 571
661} 572}
662 573
663
664
665/* Packet handling functions 574/* Packet handling functions
666 One to handle each types of packets we receive 575 One to handle each types of packets we receive
667 return 0 if handled correctly, 1 if packet is bad. */ 576 return 0 if handled correctly, 1 if packet is bad. */
668int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) 577int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
669{ 578{
670 uint64_t ping_id; 579 uint64_t ping_id;
671 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) 580 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) {
672 {
673 return 1; 581 return 1;
674 } 582 }
675 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 583 /* check if packet is from ourself. */
676 { 584 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) {
677 return 1; 585 return 1;
678 } 586 }
679 587
@@ -682,8 +590,7 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
682 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 590 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
683 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 591 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
684 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 592 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
685 if(len != sizeof(ping_id)) 593 if(len != sizeof(ping_id)) {
686 {
687 return 1; 594 return 1;
688 } 595 }
689 596
@@ -699,12 +606,10 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
699int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) 606int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
700{ 607{
701 uint64_t ping_id; 608 uint64_t ping_id;
702 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) 609 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) {
703 {
704 return 1; 610 return 1;
705 } 611 }
706 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 612 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ {
707 {
708 return 1; 613 return 1;
709 } 614 }
710 615
@@ -713,13 +618,11 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
713 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 618 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
714 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 619 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
715 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 620 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
716 if(len != sizeof(ping_id)) 621 if(len != sizeof(ping_id)) {
717 {
718 return 1; 622 return 1;
719 } 623 }
720 624
721 if(is_pinging(source, ping_id)) 625 if(is_pinging(source, ping_id)) {
722 {
723 addto_lists(source, packet + 1); 626 addto_lists(source, packet + 1);
724 return 0; 627 return 0;
725 } 628 }
@@ -730,12 +633,11 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
730int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) 633int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
731{ 634{
732 uint64_t ping_id; 635 uint64_t ping_id;
733 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 636 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) {
734 {
735 return 1; 637 return 1;
736 } 638 }
737 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 639 /* check if packet is from ourself. */
738 { 640 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) {
739 return 1; 641 return 1;
740 } 642 }
741 643
@@ -745,8 +647,7 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
745 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 647 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
746 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); 648 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain);
747 649
748 if(len != sizeof(ping_id) + CLIENT_ID_SIZE) 650 if(len != sizeof(ping_id) + CLIENT_ID_SIZE) {
749 {
750 return 1; 651 return 1;
751 } 652 }
752 653
@@ -768,8 +669,7 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
768 (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 669 (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
769 + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || 670 + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 ||
770 length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 671 length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
771 + sizeof(Node_format) + ENCRYPTION_PADDING) 672 + sizeof(Node_format) + ENCRYPTION_PADDING) {
772 {
773 return 1; 673 return 1;
774 } 674 }
775 uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES 675 uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
@@ -782,14 +682,12 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
782 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); 682 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain);
783 683
784 684
785 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) 685 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) {
786 {
787 return 1; 686 return 1;
788 } 687 }
789 688
790 memcpy(&ping_id, plain, sizeof(ping_id)); 689 memcpy(&ping_id, plain, sizeof(ping_id));
791 if(!is_gettingnodes(source, ping_id)) 690 if(!is_gettingnodes(source, ping_id)) {
792 {
793 return 1; 691 return 1;
794 } 692 }
795 693
@@ -799,8 +697,7 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
799 addto_lists(source, packet + 1); 697 addto_lists(source, packet + 1);
800 698
801 uint32_t i; 699 uint32_t i;
802 for(i = 0; i < num_nodes; ++i) 700 for(i = 0; i < num_nodes; ++i) {
803 {
804 pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); 701 pingreq(nodes_list[i].ip_port, nodes_list[i].client_id);
805 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 702 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
806 } 703 }
@@ -813,16 +710,12 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
813int DHT_addfriend(uint8_t * client_id) 710int DHT_addfriend(uint8_t * client_id)
814{ 711{
815 Friend * temp; 712 Friend * temp;
816 if(num_friends == 0) 713 if(num_friends == 0) {
817 {
818 temp = malloc(sizeof(Friend)); 714 temp = malloc(sizeof(Friend));
819 } 715 } else {
820 else
821 {
822 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); 716 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1));
823 } 717 }
824 if(temp == NULL) 718 if(temp == NULL) {
825 {
826 return 1; 719 return 1;
827 } 720 }
828 721
@@ -834,24 +727,19 @@ int DHT_addfriend(uint8_t * client_id)
834 return 0; 727 return 0;
835} 728}
836 729
837
838
839int DHT_delfriend(uint8_t * client_id) 730int DHT_delfriend(uint8_t * client_id)
840{ 731{
841 uint32_t i; 732 uint32_t i;
842 Friend * temp; 733 Friend * temp;
843 for(i = 0; i < num_friends; ++i) 734 for(i = 0; i < num_friends; ++i) {
844 { 735 /* Equal */
845 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ 736 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0){
846 {
847 --num_friends; 737 --num_friends;
848 if(num_friends != i) 738 if(num_friends != i) {
849 {
850 memcpy(friends_list[i].client_id, friends_list[num_friends].client_id, CLIENT_ID_SIZE); 739 memcpy(friends_list[i].client_id, friends_list[num_friends].client_id, CLIENT_ID_SIZE);
851 } 740 }
852 temp = realloc(friends_list, sizeof(Friend) * (num_friends)); 741 temp = realloc(friends_list, sizeof(Friend) * (num_friends));
853 if(temp != NULL) 742 if(temp != NULL) {
854 {
855 friends_list = temp; 743 friends_list = temp;
856 } 744 }
857 return 0; 745 return 0;
@@ -860,38 +748,28 @@ int DHT_delfriend(uint8_t * client_id)
860 return 1; 748 return 1;
861} 749}
862 750
863
864
865
866/* TODO: Optimize this. */ 751/* TODO: Optimize this. */
867IP_Port DHT_getfriendip(uint8_t * client_id) 752IP_Port DHT_getfriendip(uint8_t * client_id)
868{ 753{
869 uint32_t i, j; 754 uint32_t i, j;
870 IP_Port empty = {{{0}}, 0}; 755 IP_Port empty = {{{0}}, 0};
871 uint32_t temp_time = unix_time(); 756 uint32_t temp_time = unix_time();
872 for(i = 0; i < num_friends; ++i) 757 for(i = 0; i < num_friends; ++i) {
873 { 758 /* Equal */
874 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ 759 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
875 { 760 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
876 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
877 {
878 if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 && 761 if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 &&
879 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) 762 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) {
880 {
881 return friends_list[i].client_list[j].ip_port; 763 return friends_list[i].client_list[j].ip_port;
882 } 764 }
883 765 }
884 }
885
886 return empty; 766 return empty;
887 } 767 }
888 } 768 }
889 empty.ip.i = 1; 769 empty.ip.i = 1;
890 return empty; 770 return empty;
891 771
892} 772}
893
894
895 773
896/* The timeout after which a node is discarded completely. */ 774/* The timeout after which a node is discarded completely. */
897#define Kill_NODE_TIMEOUT 300 775#define Kill_NODE_TIMEOUT 300
@@ -904,8 +782,6 @@ IP_Port DHT_getfriendip(uint8_t * client_id)
904 782
905/* Ping each client in the "friends" list every 60 seconds. 783/* Ping each client in the "friends" list every 60 seconds.
906 Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. */ 784 Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. */
907
908
909void doDHTFriends() 785void doDHTFriends()
910{ 786{
911 uint32_t i, j; 787 uint32_t i, j;
@@ -913,27 +789,21 @@ void doDHTFriends()
913 uint32_t rand_node; 789 uint32_t rand_node;
914 uint32_t index[MAX_FRIEND_CLIENTS]; 790 uint32_t index[MAX_FRIEND_CLIENTS];
915 791
916 for(i = 0; i < num_friends; ++i) 792 for(i = 0; i < num_friends; ++i) {
917 {
918 uint32_t num_nodes = 0; 793 uint32_t num_nodes = 0;
919 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 794 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
920 { 795 if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ {
921 if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ 796 if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
922 {
923 if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time)
924 {
925 pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); 797 pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id);
926 friends_list[i].client_list[j].last_pinged = temp_time; 798 friends_list[i].client_list[j].last_pinged = temp_time;
927 } 799 }
928 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ 800 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ {
929 {
930 index[num_nodes] = j; 801 index[num_nodes] = j;
931 ++num_nodes; 802 ++num_nodes;
932 } 803 }
933 } 804 }
934 } 805 }
935 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) 806 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
936 {
937 rand_node = rand() % num_nodes; 807 rand_node = rand() % num_nodes;
938 getnodes(friends_list[i].client_list[index[rand_node]].ip_port, 808 getnodes(friends_list[i].client_list[index[rand_node]].ip_port,
939 friends_list[i].client_list[index[rand_node]].client_id, 809 friends_list[i].client_list[index[rand_node]].client_id,
@@ -955,62 +825,49 @@ void doClose() /* tested */
955 uint32_t rand_node; 825 uint32_t rand_node;
956 uint32_t index[LCLIENT_LIST]; 826 uint32_t index[LCLIENT_LIST];
957 827
958 for(i = 0; i < LCLIENT_LIST; ++i) 828 for(i = 0; i < LCLIENT_LIST; ++i) {
959 { 829 /* if node is not dead. */
960 if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ 830 if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) {
961 {
962 if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) 831 if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time)
963 { 832 {
964 pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); 833 pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id);
965 close_clientlist[i].last_pinged = temp_time; 834 close_clientlist[i].last_pinged = temp_time;
966 } 835 }
967 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ 836 /* if node is good. */
968 { 837 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) {
969 index[num_nodes] = i; 838 index[num_nodes] = i;
970 ++num_nodes; 839 ++num_nodes;
971 } 840 }
972 } 841 }
973 } 842 }
974 843
975 if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) 844 if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
976 {
977 rand_node = rand() % num_nodes; 845 rand_node = rand() % num_nodes;
978 getnodes(close_clientlist[index[rand_node]].ip_port, 846 getnodes(close_clientlist[index[rand_node]].ip_port,
979 close_clientlist[index[rand_node]].client_id, 847 close_clientlist[index[rand_node]].client_id,
980 self_public_key); 848 self_public_key);
981 close_lastgetnodes = temp_time; 849 close_lastgetnodes = temp_time;
982 } 850 }
983
984} 851}
985 852
986
987
988
989
990
991void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) 853void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key)
992{ 854{
993 getnodes(ip_port, public_key, self_public_key); 855 getnodes(ip_port, public_key, self_public_key);
994} 856}
995 857
996
997
998/* send the given packet to node with client_id 858/* send the given packet to node with client_id
999 returns -1 if failure */ 859 returns -1 if failure */
1000int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) 860int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
1001{ 861{
1002 uint32_t i; 862 uint32_t i;
1003 for(i = 0; i < LCLIENT_LIST; ++i) 863 for(i = 0; i < LCLIENT_LIST; ++i) {
1004 { 864 if(memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) {
1005 if(memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0)
1006 {
1007 return sendpacket(close_clientlist[i].ip_port, packet, length); 865 return sendpacket(close_clientlist[i].ip_port, packet, length);
1008 } 866 }
1009 } 867 }
1010 return -1; 868 return -1;
1011} 869}
1012 870
1013
1014/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist 871/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist
1015 ip_portlist must be at least MAX_FRIEND_CLIENTS big 872 ip_portlist must be at least MAX_FRIEND_CLIENTS big
1016 returns the number of ips returned 873 returns the number of ips returned
@@ -1021,18 +878,15 @@ static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
1021 int num_ips = 0; 878 int num_ips = 0;
1022 uint32_t i; 879 uint32_t i;
1023 uint32_t temp_time = unix_time(); 880 uint32_t temp_time = unix_time();
1024 if(friend_num >= num_friends) 881 if(friend_num >= num_friends) {
1025 {
1026 return -1; 882 return -1;
1027 } 883 }
1028 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) 884 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i)
1029 { 885 {
886 /*If ip is not zero and node is good */
1030 if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 && 887 if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 &&
1031 friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) 888 friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
1032 /*If ip is not zero and node is good */ 889 if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 ) {
1033 {
1034 if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 )
1035 {
1036 return 0; 890 return 0;
1037 } 891 }
1038 ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port; 892 ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port;
@@ -1042,7 +896,6 @@ static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
1042 return num_ips; 896 return num_ips;
1043} 897}
1044 898
1045
1046/* Send the following packet to everyone who tells us they are connected to friend_id 899/* Send the following packet to everyone who tells us they are connected to friend_id
1047 returns the number of nodes it sent the packet to */ 900 returns the number of nodes it sent the packet to */
1048int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 901int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
@@ -1050,18 +903,14 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
1050 uint32_t i, j; 903 uint32_t i, j;
1051 uint32_t sent = 0; 904 uint32_t sent = 0;
1052 uint32_t temp_time = unix_time(); 905 uint32_t temp_time = unix_time();
1053 for(i = 0; i < num_friends; ++i) 906 for(i = 0; i < num_friends; ++i) {
1054 { 907 /* Equal */
1055 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) /* Equal */ 908 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) {
1056 { 909 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1057 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 910 /*If ip is not zero and node is good */
1058 {
1059 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && 911 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 &&
1060 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) 912 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
1061 /*If ip is not zero and node is good */ 913 if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length) {
1062 {
1063 if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length)
1064 {
1065 ++sent; 914 ++sent;
1066 } 915 }
1067 } 916 }
@@ -1077,8 +926,7 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
1077int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 926int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
1078{ 927{
1079 int num = friend_number(friend_id); 928 int num = friend_number(friend_id);
1080 if(num == -1) 929 if(num == -1) {
1081 {
1082 return 0; 930 return 0;
1083 } 931 }
1084 932
@@ -1086,22 +934,18 @@ int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
1086 int n = 0; 934 int n = 0;
1087 uint32_t i; 935 uint32_t i;
1088 uint32_t temp_time = unix_time(); 936 uint32_t temp_time = unix_time();
1089 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) 937 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
1090 { 938 /*If ip is not zero and node is good */
1091 if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 && 939 if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 &&
1092 friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) 940 friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
1093 /*If ip is not zero and node is good */
1094 {
1095 ip_list[n] = friends_list[num].client_list[i].ip_port; 941 ip_list[n] = friends_list[num].client_list[i].ip_port;
1096 ++n; 942 ++n;
1097 } 943 }
1098 } 944 }
1099 if(n < 1) 945 if(n < 1) {
1100 {
1101 return 0; 946 return 0;
1102 } 947 }
1103 if(sendpacket(ip_list[rand() % n], packet, length) == length) 948 if(sendpacket(ip_list[rand() % n], packet, length) == length) {
1104 {
1105 return 1; 949 return 1;
1106 } 950 }
1107 return 0; 951 return 0;
@@ -1116,10 +960,9 @@ int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id)
1116{ 960{
1117 961
1118 uint32_t i; 962 uint32_t i;
1119 for(i = 0; i < num_friends; ++i) 963 for(i = 0; i < num_friends; ++i) {
1120 { 964 /* Equal */
1121 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) /* Equal */ 965 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) {
1122 {
1123 return friend_iplist(ip_portlist, i); 966 return friend_iplist(ip_portlist, i);
1124 } 967 }
1125 } 968 }
@@ -1136,60 +979,49 @@ int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
1136 979
1137 uint8_t packet[MAX_DATA_SIZE]; 980 uint8_t packet[MAX_DATA_SIZE];
1138 int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */ 981 int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */
1139 if(len == -1) 982 if(len == -1) {
1140 {
1141 return -1; 983 return -1;
1142 } 984 }
1143 int num = 0; 985 int num = 0;
1144 if(type == 0) 986 if(type == 0) {
1145 {
1146 num = route_tofriend(public_key, packet, len);/*If packet is request use many people to route it*/ 987 num = route_tofriend(public_key, packet, len);/*If packet is request use many people to route it*/
1147 } 988 }
1148 else if(type == 1) 989 else if(type == 1) {
1149 {
1150 num = routeone_tofriend(public_key, packet, len);/*If packet is response use only one person to route it*/ 990 num = routeone_tofriend(public_key, packet, len);/*If packet is response use only one person to route it*/
1151 } 991 }
1152 if(num == 0) 992 if(num == 0) {
1153 {
1154 return -1; 993 return -1;
1155 } 994 }
1156 return num; 995 return num;
1157} 996}
1158 997
1159
1160/* Handle a recieved ping request for */ 998/* Handle a recieved ping request for */
1161int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) 999int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
1162{ 1000{
1163 if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && 1001 if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
1164 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) 1002 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) {
1165 {
1166 return 1; 1003 return 1;
1167 } 1004 }
1168 if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)//check if request is for us. 1005 /* check if request is for us. */
1169 { 1006 if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
1170 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 1007 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
1171 uint8_t data[MAX_DATA_SIZE]; 1008 uint8_t data[MAX_DATA_SIZE];
1172 int len = handle_request(public_key, data, packet, length); 1009 int len = handle_request(public_key, data, packet, length);
1173 if(len != sizeof(uint64_t) + 1) 1010 if(len != sizeof(uint64_t) + 1) {
1174 {
1175 return 1; 1011 return 1;
1176 } 1012 }
1177 uint64_t ping_id; 1013 uint64_t ping_id;
1178 memcpy(&ping_id, data + 1, sizeof(uint64_t)); 1014 memcpy(&ping_id, data + 1, sizeof(uint64_t));
1179 1015
1180 int friendnumber = friend_number(public_key); 1016 int friendnumber = friend_number(public_key);
1181 if(friendnumber == -1) 1017 if(friendnumber == -1) {
1182 {
1183 return 1; 1018 return 1;
1184 } 1019 }
1185 1020
1186 if(data[0] == 0) 1021 if(data[0] == 0) {
1187 {
1188 send_NATping(public_key, ping_id, 1);/*1 is reply*/ 1022 send_NATping(public_key, ping_id, 1);/*1 is reply*/
1189 return 0; 1023 return 0;
1190 } 1024 } else if (data[0] == 1) {
1191 else if (data[0] == 1)
1192 {
1193 if(friends_list[friendnumber].NATping_id == ping_id) 1025 if(friends_list[friendnumber].NATping_id == ping_id)
1194 { 1026 {
1195 friends_list[friendnumber].NATping_id = ((uint64_t)random_int() << 32) + random_int(); 1027 friends_list[friendnumber].NATping_id = ((uint64_t)random_int() << 32) + random_int();
@@ -1199,10 +1031,9 @@ int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
1199 } 1031 }
1200 return 1; 1032 return 1;
1201 } 1033 }
1202 else//if request is not for us, try routing it. 1034 /* if request is not for us, try routing it. */
1203 { 1035 else {
1204 if(route_packet(packet + 1, packet, length) == length) 1036 if(route_packet(packet + 1, packet, length) == length) {
1205 {
1206 return 0; 1037 return 0;
1207 } 1038 }
1208 } 1039 }
@@ -1216,24 +1047,19 @@ int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
1216static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num) 1047static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
1217{ 1048{
1218 IP zero = {{0}}; 1049 IP zero = {{0}};
1219 if(len > MAX_FRIEND_CLIENTS) 1050 if(len > MAX_FRIEND_CLIENTS) {
1220 {
1221 return zero; 1051 return zero;
1222 } 1052 }
1223 1053
1224 uint32_t i, j; 1054 uint32_t i, j;
1225 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0}; 1055 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0};
1226 for(i = 0; i < len; ++i) 1056 for(i = 0; i < len; ++i) {
1227 { 1057 for(j = 0; j < len; ++j) {
1228 for(j = 0; j < len; ++j) 1058 if(ip_portlist[i].ip.i == ip_portlist[j].ip.i) {
1229 {
1230 if(ip_portlist[i].ip.i == ip_portlist[j].ip.i)
1231 {
1232 ++numbers[i]; 1059 ++numbers[i];
1233 } 1060 }
1234 } 1061 }
1235 if(numbers[i] >= min_num) 1062 if(numbers[i] >= min_num) {
1236 {
1237 return ip_portlist[i].ip; 1063 return ip_portlist[i].ip;
1238 } 1064 }
1239 } 1065 }
@@ -1248,10 +1074,8 @@ static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_
1248{ 1074{
1249 uint32_t i; 1075 uint32_t i;
1250 uint16_t num = 0; 1076 uint16_t num = 0;
1251 for(i = 0; i < len; ++i) 1077 for(i = 0; i < len; ++i) {
1252 { 1078 if(ip_portlist[i].ip.i == ip.i) {
1253 if(ip_portlist[i].ip.i == ip.i)
1254 {
1255 portlist[num] = ntohs(ip_portlist[i].port); 1079 portlist[num] = ntohs(ip_portlist[i].port);
1256 ++num; 1080 ++num;
1257 } 1081 }
@@ -1263,14 +1087,12 @@ static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_
1263 1087
1264static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t friend_num) 1088static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t friend_num)
1265{ 1089{
1266 if(numports > MAX_FRIEND_CLIENTS || numports == 0) 1090 if(numports > MAX_FRIEND_CLIENTS || numports == 0) {
1267 {
1268 return; 1091 return;
1269 } 1092 }
1270 uint32_t i; 1093 uint32_t i;
1271 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; 1094 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS;
1272 for(i = friends_list[friend_num].punching_index; i != top; i++) 1095 for(i = friends_list[friend_num].punching_index; i != top; i++) {
1273 {
1274 /*TODO: improve port guessing algorithm*/ 1096 /*TODO: improve port guessing algorithm*/
1275 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1); 1097 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1);
1276 IP_Port pinging = {ip, htons(port)}; 1098 IP_Port pinging = {ip, htons(port)};
@@ -1286,28 +1108,22 @@ static void doNAT()
1286{ 1108{
1287 uint32_t i; 1109 uint32_t i;
1288 uint32_t temp_time = unix_time(); 1110 uint32_t temp_time = unix_time();
1289 for(i = 0; i < num_friends; ++i) 1111 for(i = 0; i < num_friends; ++i) {
1290 {
1291 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 1112 IP_Port ip_list[MAX_FRIEND_CLIENTS];
1292 int num = friend_iplist(ip_list, i); 1113 int num = friend_iplist(ip_list, i);
1293 /*If we are connected to friend or if friend is not online don't try to hole punch with him*/ 1114 /*If we are connected to friend or if friend is not online don't try to hole punch with him*/
1294 if(num < MAX_FRIEND_CLIENTS/2) 1115 if(num < MAX_FRIEND_CLIENTS/2) {
1295 {
1296 continue; 1116 continue;
1297 } 1117 }
1298 if(friends_list[i].hole_punching != 1) 1118 if(friends_list[i].hole_punching != 1) {
1299 { 1119 if(friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) {
1300 if(friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time)
1301 {
1302 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ 1120 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/
1303 friends_list[i].NATping_timestamp = temp_time; 1121 friends_list[i].NATping_timestamp = temp_time;
1304 } 1122 }
1305 } 1123 }
1306 else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) 1124 else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) {
1307 {
1308 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2); 1125 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2);
1309 if(ip.i == 0) 1126 if(ip.i == 0) {
1310 {
1311 continue; 1127 continue;
1312 } 1128 }
1313 uint16_t port_list[MAX_FRIEND_CLIENTS]; 1129 uint16_t port_list[MAX_FRIEND_CLIENTS];
@@ -1322,7 +1138,6 @@ static void doNAT()
1322 1138
1323/*END OF NAT PUNCHING FUNCTIONS*/ 1139/*END OF NAT PUNCHING FUNCTIONS*/
1324 1140
1325
1326int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) 1141int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
1327{ 1142{
1328 switch (packet[0]) { 1143 switch (packet[0]) {
@@ -1350,7 +1165,6 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
1350 1165
1351} 1166}
1352 1167
1353
1354void doDHT() 1168void doDHT()
1355{ 1169{
1356 doClose(); 1170 doClose();
@@ -1358,8 +1172,6 @@ void doDHT()
1358 doNAT(); 1172 doNAT();
1359} 1173}
1360 1174
1361
1362
1363/* get the size of the DHT (for saving) */ 1175/* get the size of the DHT (for saving) */
1364uint32_t DHT_size() 1176uint32_t DHT_size()
1365{ 1177{
@@ -1378,12 +1190,10 @@ void DHT_save(uint8_t * data)
1378 return 0 if success */ 1190 return 0 if success */
1379int DHT_load(uint8_t * data, uint32_t size) 1191int DHT_load(uint8_t * data, uint32_t size)
1380{ 1192{
1381 if(size < sizeof(close_clientlist)) 1193 if(size < sizeof(close_clientlist)) {
1382 {
1383 return -1; 1194 return -1;
1384 } 1195 }
1385 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) 1196 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) {
1386 {
1387 return -1; 1197 return -1;
1388 } 1198 }
1389 uint32_t i, j; 1199 uint32_t i, j;
@@ -1392,17 +1202,13 @@ int DHT_load(uint8_t * data, uint32_t size)
1392 1202
1393 temp = (size - sizeof(close_clientlist))/sizeof(Friend); 1203 temp = (size - sizeof(close_clientlist))/sizeof(Friend);
1394 1204
1395 if(temp != 0) 1205 if(temp != 0) {
1396 {
1397 Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); 1206 Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist));
1398 1207
1399 for(i = 0; i < temp; ++i) 1208 for(i = 0; i < temp; ++i) {
1400 {
1401 DHT_addfriend(tempfriends_list[i].client_id); 1209 DHT_addfriend(tempfriends_list[i].client_id);
1402 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 1210 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1403 { 1211 if(tempfriends_list[i].client_list[j].timestamp != 0) {
1404 if(tempfriends_list[i].client_list[j].timestamp != 0)
1405 {
1406 getnodes(tempfriends_list[i].client_list[j].ip_port, 1212 getnodes(tempfriends_list[i].client_list[j].ip_port,
1407 tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id); 1213 tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id);
1408 } 1214 }
@@ -1411,10 +1217,8 @@ int DHT_load(uint8_t * data, uint32_t size)
1411 } 1217 }
1412 Client_data * tempclose_clientlist = (Client_data *)data; 1218 Client_data * tempclose_clientlist = (Client_data *)data;
1413 1219
1414 for(i = 0; i < LCLIENT_LIST; ++i) 1220 for(i = 0; i < LCLIENT_LIST; ++i) {
1415 { 1221 if(tempclose_clientlist[i].timestamp != 0) {
1416 if(tempclose_clientlist[i].timestamp != 0)
1417 {
1418 DHT_bootstrap(tempclose_clientlist[i].ip_port, tempclose_clientlist[i].client_id); 1222 DHT_bootstrap(tempclose_clientlist[i].ip_port, tempclose_clientlist[i].client_id);
1419 } 1223 }
1420 } 1224 }
@@ -1427,13 +1231,10 @@ int DHT_isconnected()
1427{ 1231{
1428 uint32_t i; 1232 uint32_t i;
1429 uint32_t temp_time = unix_time(); 1233 uint32_t temp_time = unix_time();
1430 for(i = 0; i < LCLIENT_LIST; ++i) 1234 for(i = 0; i < LCLIENT_LIST; ++i) {
1431 { 1235 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) {
1432 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)
1433 {
1434 return 1; 1236 return 1;
1435 } 1237 }
1436 } 1238 }
1437 return 0; 1239 return 0;
1438} 1240} \ No newline at end of file
1439