diff options
Diffstat (limited to 'core/DHT.c')
-rw-r--r-- | core/DHT.c | 498 |
1 files changed, 228 insertions, 270 deletions
@@ -27,17 +27,6 @@ | |||
27 | #include "packets.h" | 27 | #include "packets.h" |
28 | #include "ping.h" | 28 | #include "ping.h" |
29 | 29 | ||
30 | /* maximum number of clients stored per friend. */ | ||
31 | #define MAX_FRIEND_CLIENTS 8 | ||
32 | |||
33 | /* A list of the clients mathematically closest to ours. */ | ||
34 | #define LCLIENT_LIST 32 | ||
35 | |||
36 | /* The list of ip ports along with the ping_id of what we sent them and a timestamp */ | ||
37 | #define LPING_ARRAY 256 | ||
38 | |||
39 | #define LSEND_NODES_ARRAY LPING_ARRAY/2 | ||
40 | |||
41 | /* the number of seconds for a non responsive node to become bad. */ | 30 | /* the number of seconds for a non responsive node to become bad. */ |
42 | #define BAD_NODE_TIMEOUT 70 | 31 | #define BAD_NODE_TIMEOUT 70 |
43 | 32 | ||
@@ -61,59 +50,13 @@ | |||
61 | /*Interval in seconds between punching attempts*/ | 50 | /*Interval in seconds between punching attempts*/ |
62 | #define PUNCH_INTERVAL 10 | 51 | #define PUNCH_INTERVAL 10 |
63 | 52 | ||
64 | /*Maximum newly announced nodes to ping per TIME_TOPING seconds*/ | 53 | /*Ping newly announced nodes to ping per TIME_TOPING seconds*/ |
65 | #define MAX_TOPING 16 | ||
66 | |||
67 | #define TIME_TOPING 5 | 54 | #define TIME_TOPING 5 |
68 | /*----------------------------------------------------------------------------------*/ | ||
69 | |||
70 | typedef struct { | ||
71 | uint8_t client_id[CLIENT_ID_SIZE]; | ||
72 | Client_data client_list[MAX_FRIEND_CLIENTS]; | ||
73 | |||
74 | /* time at which the last get_nodes request was sent. */ | ||
75 | uint64_t lastgetnode; | ||
76 | |||
77 | /* Symetric NAT hole punching stuff */ | ||
78 | |||
79 | /* 1 if currently hole punching, otherwise 0 */ | ||
80 | uint8_t hole_punching; | ||
81 | uint32_t punching_index; | ||
82 | uint64_t punching_timestamp; | ||
83 | uint64_t recvNATping_timestamp; | ||
84 | uint64_t NATping_id; | ||
85 | uint64_t NATping_timestamp; | ||
86 | } Friend; | ||
87 | |||
88 | typedef struct { | ||
89 | uint8_t client_id[CLIENT_ID_SIZE]; | ||
90 | IP_Port ip_port; | ||
91 | } Node_format; | ||
92 | 55 | ||
93 | typedef struct { | ||
94 | IP_Port ip_port; | ||
95 | uint64_t ping_id; | ||
96 | uint64_t timestamp; | ||
97 | } Pinged; | ||
98 | 56 | ||
99 | /*----------------------------------------------------------------------------------*/ | 57 | Client_data *DHT_get_close_list(DHT * dht) |
100 | |||
101 | /* Our client id/public key */ | ||
102 | uint8_t self_public_key[CLIENT_ID_SIZE]; | ||
103 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
104 | static Client_data close_clientlist[LCLIENT_LIST]; | ||
105 | static Friend *friends_list; | ||
106 | static uint16_t num_friends; | ||
107 | static Pinged send_nodes[LSEND_NODES_ARRAY]; | ||
108 | static Node_format toping[MAX_TOPING]; | ||
109 | static uint64_t last_toping; | ||
110 | |||
111 | /*----------------------------------------------------------------------------------*/ | ||
112 | |||
113 | |||
114 | Client_data *DHT_get_close_list(void) | ||
115 | { | 58 | { |
116 | return close_clientlist; | 59 | return dht->close_clientlist; |
117 | } | 60 | } |
118 | 61 | ||
119 | /* Compares client_id1 and client_id2 with client_id | 62 | /* Compares client_id1 and client_id2 with client_id |
@@ -203,12 +146,12 @@ static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *clien | |||
203 | 146 | ||
204 | /* Returns the friend number from the client_id, or -1 if a failure occurs | 147 | /* Returns the friend number from the client_id, or -1 if a failure occurs |
205 | */ | 148 | */ |
206 | static int friend_number(uint8_t *client_id) | 149 | static int friend_number(DHT * dht, uint8_t *client_id) |
207 | { | 150 | { |
208 | uint32_t i; | 151 | uint32_t i; |
209 | 152 | ||
210 | for (i = 0; i < num_friends; ++i) { | 153 | for (i = 0; i < dht->num_friends; ++i) { |
211 | if (id_equal(friends_list[i].client_id, client_id)) | 154 | if (id_equal(dht->friends_list[i].client_id, client_id)) |
212 | return i; | 155 | return i; |
213 | } | 156 | } |
214 | 157 | ||
@@ -220,15 +163,15 @@ static int friend_number(uint8_t *client_id) | |||
220 | * | 163 | * |
221 | * TODO: For the love of based Allah make this function cleaner and much more efficient. | 164 | * TODO: For the love of based Allah make this function cleaner and much more efficient. |
222 | */ | 165 | */ |
223 | static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | 166 | static int get_close_nodes(DHT * dht, uint8_t *client_id, Node_format *nodes_list) |
224 | { | 167 | { |
225 | uint32_t i, j, k; | 168 | uint32_t i, j, k; |
226 | uint64_t temp_time = unix_time(); | 169 | uint64_t temp_time = unix_time(); |
227 | int num_nodes = 0, closest, tout, inlist; | 170 | int num_nodes = 0, closest, tout, inlist; |
228 | 171 | ||
229 | for (i = 0; i < LCLIENT_LIST; ++i) { | 172 | for (i = 0; i < LCLIENT_LIST; ++i) { |
230 | tout = is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); | 173 | tout = is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); |
231 | inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id); | 174 | inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, dht->close_clientlist[i].client_id); |
232 | 175 | ||
233 | /* if node isn't good or is already in list. */ | 176 | /* if node isn't good or is already in list. */ |
234 | if (tout || inlist) | 177 | if (tout || inlist) |
@@ -237,10 +180,10 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | |||
237 | if (num_nodes < MAX_SENT_NODES) { | 180 | if (num_nodes < MAX_SENT_NODES) { |
238 | 181 | ||
239 | memcpy( nodes_list[num_nodes].client_id, | 182 | memcpy( nodes_list[num_nodes].client_id, |
240 | close_clientlist[i].client_id, | 183 | dht->close_clientlist[i].client_id, |
241 | CLIENT_ID_SIZE ); | 184 | CLIENT_ID_SIZE ); |
242 | 185 | ||
243 | nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; | 186 | nodes_list[num_nodes].ip_port = dht->close_clientlist[i].ip_port; |
244 | num_nodes++; | 187 | num_nodes++; |
245 | 188 | ||
246 | } else { | 189 | } else { |
@@ -248,27 +191,27 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | |||
248 | for (j = 0; j < MAX_SENT_NODES; ++j) { | 191 | for (j = 0; j < MAX_SENT_NODES; ++j) { |
249 | closest = id_closest( client_id, | 192 | closest = id_closest( client_id, |
250 | nodes_list[j].client_id, | 193 | nodes_list[j].client_id, |
251 | close_clientlist[i].client_id ); | 194 | dht->close_clientlist[i].client_id ); |
252 | 195 | ||
253 | if (closest == 2) { | 196 | if (closest == 2) { |
254 | memcpy( nodes_list[j].client_id, | 197 | memcpy( nodes_list[j].client_id, |
255 | close_clientlist[i].client_id, | 198 | dht->close_clientlist[i].client_id, |
256 | CLIENT_ID_SIZE); | 199 | CLIENT_ID_SIZE); |
257 | 200 | ||
258 | nodes_list[j].ip_port = close_clientlist[i].ip_port; | 201 | nodes_list[j].ip_port = dht->close_clientlist[i].ip_port; |
259 | break; | 202 | break; |
260 | } | 203 | } |
261 | } | 204 | } |
262 | } | 205 | } |
263 | } | 206 | } |
264 | 207 | ||
265 | for (i = 0; i < num_friends; ++i) { | 208 | for (i = 0; i < dht->num_friends; ++i) { |
266 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 209 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
267 | 210 | ||
268 | tout = is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT); | 211 | tout = is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT); |
269 | inlist = client_in_nodelist( nodes_list, | 212 | inlist = client_in_nodelist( nodes_list, |
270 | MAX_SENT_NODES, | 213 | MAX_SENT_NODES, |
271 | friends_list[i].client_list[j].client_id); | 214 | dht->friends_list[i].client_list[j].client_id); |
272 | 215 | ||
273 | /* if node isn't good or is already in list. */ | 216 | /* if node isn't good or is already in list. */ |
274 | if (tout || inlist) | 217 | if (tout || inlist) |
@@ -277,24 +220,24 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | |||
277 | if (num_nodes < MAX_SENT_NODES) { | 220 | if (num_nodes < MAX_SENT_NODES) { |
278 | 221 | ||
279 | memcpy( nodes_list[num_nodes].client_id, | 222 | memcpy( nodes_list[num_nodes].client_id, |
280 | friends_list[i].client_list[j].client_id, | 223 | dht->friends_list[i].client_list[j].client_id, |
281 | CLIENT_ID_SIZE); | 224 | CLIENT_ID_SIZE); |
282 | 225 | ||
283 | nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; | 226 | nodes_list[num_nodes].ip_port = dht->friends_list[i].client_list[j].ip_port; |
284 | num_nodes++; | 227 | num_nodes++; |
285 | } else { | 228 | } else { |
286 | for (k = 0; k < MAX_SENT_NODES; ++k) { | 229 | for (k = 0; k < MAX_SENT_NODES; ++k) { |
287 | 230 | ||
288 | closest = id_closest( client_id, | 231 | closest = id_closest( client_id, |
289 | nodes_list[k].client_id, | 232 | nodes_list[k].client_id, |
290 | friends_list[i].client_list[j].client_id ); | 233 | dht->friends_list[i].client_list[j].client_id ); |
291 | 234 | ||
292 | if (closest == 2) { | 235 | if (closest == 2) { |
293 | memcpy( nodes_list[k].client_id, | 236 | memcpy( nodes_list[k].client_id, |
294 | friends_list[i].client_list[j].client_id, | 237 | dht->friends_list[i].client_list[j].client_id, |
295 | CLIENT_ID_SIZE ); | 238 | CLIENT_ID_SIZE ); |
296 | 239 | ||
297 | nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; | 240 | nodes_list[k].ip_port = dht->friends_list[i].client_list[j].ip_port; |
298 | break; | 241 | break; |
299 | } | 242 | } |
300 | } | 243 | } |
@@ -387,40 +330,40 @@ static int replace_good( Client_data *list, | |||
387 | /* Attempt to add client with ip_port and client_id to the friends client list | 330 | /* Attempt to add client with ip_port and client_id to the friends client list |
388 | * and close_clientlist | 331 | * and close_clientlist |
389 | */ | 332 | */ |
390 | void addto_lists(IP_Port ip_port, uint8_t *client_id) | 333 | void addto_lists(DHT * dht, IP_Port ip_port, uint8_t *client_id) |
391 | { | 334 | { |
392 | uint32_t i; | 335 | uint32_t i; |
393 | 336 | ||
394 | /* NOTE: current behavior if there are two clients with the same id is | 337 | /* NOTE: current behavior if there are two clients with the same id is |
395 | * to replace the first ip by the second. | 338 | * to replace the first ip by the second. |
396 | */ | 339 | */ |
397 | if (!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 340 | if (!client_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
398 | if (replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 341 | if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
399 | /* if we can't replace bad nodes we try replacing good ones */ | 342 | /* if we can't replace bad nodes we try replacing good ones */ |
400 | replace_good( close_clientlist, | 343 | replace_good( dht->close_clientlist, |
401 | LCLIENT_LIST, | 344 | LCLIENT_LIST, |
402 | client_id, | 345 | client_id, |
403 | ip_port, | 346 | ip_port, |
404 | self_public_key ); | 347 | dht->c->self_public_key ); |
405 | } | 348 | } |
406 | } | 349 | } |
407 | 350 | ||
408 | for (i = 0; i < num_friends; ++i) { | 351 | for (i = 0; i < dht->num_friends; ++i) { |
409 | if (!client_in_list( friends_list[i].client_list, | 352 | if (!client_in_list( dht->friends_list[i].client_list, |
410 | MAX_FRIEND_CLIENTS, | 353 | MAX_FRIEND_CLIENTS, |
411 | client_id, | 354 | client_id, |
412 | ip_port )) { | 355 | ip_port )) { |
413 | 356 | ||
414 | if (replace_bad( friends_list[i].client_list, | 357 | if (replace_bad( dht->friends_list[i].client_list, |
415 | MAX_FRIEND_CLIENTS, | 358 | MAX_FRIEND_CLIENTS, |
416 | client_id, | 359 | client_id, |
417 | ip_port )) { | 360 | ip_port )) { |
418 | /* if we can't replace bad nodes we try replacing good ones. */ | 361 | /* if we can't replace bad nodes we try replacing good ones. */ |
419 | replace_good( friends_list[i].client_list, | 362 | replace_good( dht->friends_list[i].client_list, |
420 | MAX_FRIEND_CLIENTS, | 363 | MAX_FRIEND_CLIENTS, |
421 | client_id, | 364 | client_id, |
422 | ip_port, | 365 | ip_port, |
423 | friends_list[i].client_id ); | 366 | dht->friends_list[i].client_id ); |
424 | } | 367 | } |
425 | } | 368 | } |
426 | } | 369 | } |
@@ -429,30 +372,30 @@ void addto_lists(IP_Port ip_port, uint8_t *client_id) | |||
429 | /* If client_id is a friend or us, update ret_ip_port | 372 | /* If client_id is a friend or us, update ret_ip_port |
430 | * nodeclient_id is the id of the node that sent us this info | 373 | * nodeclient_id is the id of the node that sent us this info |
431 | */ | 374 | */ |
432 | static void returnedip_ports(IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) | 375 | static void returnedip_ports(DHT * dht, IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) |
433 | { | 376 | { |
434 | uint32_t i, j; | 377 | uint32_t i, j; |
435 | uint64_t temp_time = unix_time(); | 378 | uint64_t temp_time = unix_time(); |
436 | 379 | ||
437 | if (id_equal(client_id, self_public_key)) { | 380 | if (id_equal(client_id, dht->c->self_public_key)) { |
438 | 381 | ||
439 | for (i = 0; i < LCLIENT_LIST; ++i) { | 382 | for (i = 0; i < LCLIENT_LIST; ++i) { |
440 | if (id_equal(nodeclient_id, close_clientlist[i].client_id)) { | 383 | if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) { |
441 | close_clientlist[i].ret_ip_port = ip_port; | 384 | dht->close_clientlist[i].ret_ip_port = ip_port; |
442 | close_clientlist[i].ret_timestamp = temp_time; | 385 | dht->close_clientlist[i].ret_timestamp = temp_time; |
443 | return; | 386 | return; |
444 | } | 387 | } |
445 | } | 388 | } |
446 | 389 | ||
447 | } else { | 390 | } else { |
448 | 391 | ||
449 | for (i = 0; i < num_friends; ++i) { | 392 | for (i = 0; i < dht->num_friends; ++i) { |
450 | if (id_equal(client_id, friends_list[i].client_id)) { | 393 | if (id_equal(client_id, dht->friends_list[i].client_id)) { |
451 | 394 | ||
452 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 395 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
453 | if (id_equal(nodeclient_id, friends_list[i].client_list[j].client_id)) { | 396 | if (id_equal(nodeclient_id, dht->friends_list[i].client_list[j].client_id)) { |
454 | friends_list[i].client_list[j].ret_ip_port = ip_port; | 397 | dht->friends_list[i].client_list[j].ret_ip_port = ip_port; |
455 | friends_list[i].client_list[j].ret_timestamp = temp_time; | 398 | dht->friends_list[i].client_list[j].ret_timestamp = temp_time; |
456 | return; | 399 | return; |
457 | } | 400 | } |
458 | } | 401 | } |
@@ -463,20 +406,20 @@ static void returnedip_ports(IP_Port ip_port, uint8_t *client_id, uint8_t *nodec | |||
463 | } | 406 | } |
464 | 407 | ||
465 | /* Same as last function but for get_node requests. */ | 408 | /* Same as last function but for get_node requests. */ |
466 | static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | 409 | static int is_gettingnodes(DHT * dht, IP_Port ip_port, uint64_t ping_id) |
467 | { | 410 | { |
468 | uint32_t i; | 411 | uint32_t i; |
469 | uint8_t pinging; | 412 | uint8_t pinging; |
470 | uint64_t temp_time = unix_time(); | 413 | uint64_t temp_time = unix_time(); |
471 | 414 | ||
472 | for (i = 0; i < LSEND_NODES_ARRAY; ++i ) { | 415 | for (i = 0; i < LSEND_NODES_ARRAY; ++i ) { |
473 | if (!is_timeout(temp_time, send_nodes[i].timestamp, PING_TIMEOUT)) { | 416 | if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { |
474 | pinging = 0; | 417 | pinging = 0; |
475 | 418 | ||
476 | if (ip_port.ip.i != 0 && ipport_equal(send_nodes[i].ip_port, ip_port)) | 419 | if (ip_port.ip.i != 0 && ipport_equal(dht->send_nodes[i].ip_port, ip_port)) |
477 | ++pinging; | 420 | ++pinging; |
478 | 421 | ||
479 | if (ping_id != 0 && send_nodes[i].ping_id == ping_id) | 422 | if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id) |
480 | ++pinging; | 423 | ++pinging; |
481 | 424 | ||
482 | if (pinging == (ping_id != 0) + (ip_port.ip.i != 0)) | 425 | if (pinging == (ping_id != 0) + (ip_port.ip.i != 0)) |
@@ -488,7 +431,7 @@ static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | |||
488 | } | 431 | } |
489 | 432 | ||
490 | /* Same but for get node requests */ | 433 | /* Same but for get node requests */ |
491 | static uint64_t add_gettingnodes(IP_Port ip_port) | 434 | static uint64_t add_gettingnodes(DHT * dht, IP_Port ip_port) |
492 | { | 435 | { |
493 | uint32_t i, j; | 436 | uint32_t i, j; |
494 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); | 437 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
@@ -496,10 +439,10 @@ static uint64_t add_gettingnodes(IP_Port ip_port) | |||
496 | 439 | ||
497 | for (i = 0; i < PING_TIMEOUT; ++i ) { | 440 | for (i = 0; i < PING_TIMEOUT; ++i ) { |
498 | for (j = 0; j < LSEND_NODES_ARRAY; ++j ) { | 441 | for (j = 0; j < LSEND_NODES_ARRAY; ++j ) { |
499 | if (is_timeout(temp_time, send_nodes[j].timestamp, PING_TIMEOUT - i)) { | 442 | if (is_timeout(temp_time, dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) { |
500 | send_nodes[j].timestamp = temp_time; | 443 | dht->send_nodes[j].timestamp = temp_time; |
501 | send_nodes[j].ip_port = ip_port; | 444 | dht->send_nodes[j].ip_port = ip_port; |
502 | send_nodes[j].ping_id = ping_id; | 445 | dht->send_nodes[j].ping_id = ping_id; |
503 | return ping_id; | 446 | return ping_id; |
504 | } | 447 | } |
505 | } | 448 | } |
@@ -509,13 +452,13 @@ static uint64_t add_gettingnodes(IP_Port ip_port) | |||
509 | } | 452 | } |
510 | 453 | ||
511 | /* send a getnodes request */ | 454 | /* send a getnodes request */ |
512 | static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | 455 | static int getnodes(DHT * dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) |
513 | { | 456 | { |
514 | /* check if packet is gonna be sent to ourself */ | 457 | /* check if packet is gonna be sent to ourself */ |
515 | if (id_equal(public_key, self_public_key) || is_gettingnodes(ip_port, 0)) | 458 | if (id_equal(public_key, dht->c->self_public_key) || is_gettingnodes(dht, ip_port, 0)) |
516 | return 1; | 459 | return 1; |
517 | 460 | ||
518 | uint64_t ping_id = add_gettingnodes(ip_port); | 461 | uint64_t ping_id = add_gettingnodes(dht, ip_port); |
519 | 462 | ||
520 | if (ping_id == 0) | 463 | if (ping_id == 0) |
521 | return 1; | 464 | return 1; |
@@ -530,7 +473,7 @@ static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | |||
530 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); | 473 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); |
531 | 474 | ||
532 | int len = encrypt_data( public_key, | 475 | int len = encrypt_data( public_key, |
533 | self_secret_key, | 476 | dht->c->self_secret_key, |
534 | nonce, | 477 | nonce, |
535 | plain, | 478 | plain, |
536 | sizeof(ping_id) + CLIENT_ID_SIZE, | 479 | sizeof(ping_id) + CLIENT_ID_SIZE, |
@@ -540,25 +483,25 @@ static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | |||
540 | return -1; | 483 | return -1; |
541 | 484 | ||
542 | data[0] = 2; | 485 | data[0] = 2; |
543 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 486 | memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); |
544 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 487 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
545 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 488 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
546 | 489 | ||
547 | return sendpacket(temp_net->sock, ip_port, data, sizeof(data)); | 490 | return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, sizeof(data)); |
548 | } | 491 | } |
549 | 492 | ||
550 | /* send a send nodes response */ | 493 | /* send a send nodes response */ |
551 | static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) | 494 | static int sendnodes(DHT * dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) |
552 | { | 495 | { |
553 | /* check if packet is gonna be sent to ourself */ | 496 | /* check if packet is gonna be sent to ourself */ |
554 | if (id_equal(public_key, self_public_key)) | 497 | if (id_equal(public_key, dht->c->self_public_key)) |
555 | return 1; | 498 | return 1; |
556 | 499 | ||
557 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | 500 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
558 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; | 501 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; |
559 | 502 | ||
560 | Node_format nodes_list[MAX_SENT_NODES]; | 503 | Node_format nodes_list[MAX_SENT_NODES]; |
561 | int num_nodes = get_close_nodes(client_id, nodes_list); | 504 | int num_nodes = get_close_nodes(dht, client_id, nodes_list); |
562 | 505 | ||
563 | if (num_nodes == 0) | 506 | if (num_nodes == 0) |
564 | return 0; | 507 | return 0; |
@@ -572,7 +515,7 @@ static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, u | |||
572 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); | 515 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); |
573 | 516 | ||
574 | int len = encrypt_data( public_key, | 517 | int len = encrypt_data( public_key, |
575 | self_secret_key, | 518 | dht->c->self_secret_key, |
576 | nonce, | 519 | nonce, |
577 | plain, | 520 | plain, |
578 | sizeof(ping_id) + num_nodes * sizeof(Node_format), | 521 | sizeof(ping_id) + num_nodes * sizeof(Node_format), |
@@ -582,15 +525,16 @@ static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, u | |||
582 | return -1; | 525 | return -1; |
583 | 526 | ||
584 | data[0] = 3; | 527 | data[0] = 3; |
585 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 528 | memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); |
586 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 529 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
587 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 530 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
588 | 531 | ||
589 | return sendpacket(temp_net->sock, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | 532 | return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); |
590 | } | 533 | } |
591 | 534 | ||
592 | static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) | 535 | static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
593 | { | 536 | { |
537 | DHT * dht = object; | ||
594 | uint64_t ping_id; | 538 | uint64_t ping_id; |
595 | 539 | ||
596 | if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES | 540 | if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES |
@@ -598,13 +542,13 @@ static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint3 | |||
598 | return 1; | 542 | return 1; |
599 | 543 | ||
600 | /* check if packet is from ourself. */ | 544 | /* check if packet is from ourself. */ |
601 | if (id_equal(packet + 1, self_public_key)) | 545 | if (id_equal(packet + 1, dht->c->self_public_key)) |
602 | return 1; | 546 | return 1; |
603 | 547 | ||
604 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; | 548 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; |
605 | 549 | ||
606 | int len = decrypt_data( packet + 1, | 550 | int len = decrypt_data( packet + 1, |
607 | self_secret_key, | 551 | dht->c->self_secret_key, |
608 | packet + 1 + CLIENT_ID_SIZE, | 552 | packet + 1 + CLIENT_ID_SIZE, |
609 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 553 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
610 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, | 554 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, |
@@ -614,15 +558,16 @@ static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint3 | |||
614 | return 1; | 558 | return 1; |
615 | 559 | ||
616 | memcpy(&ping_id, plain, sizeof(ping_id)); | 560 | memcpy(&ping_id, plain, sizeof(ping_id)); |
617 | sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); | 561 | sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); |
618 | 562 | ||
619 | //send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ | 563 | //send_ping_request(dht, source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ |
620 | 564 | ||
621 | return 0; | 565 | return 0; |
622 | } | 566 | } |
623 | 567 | ||
624 | static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) | 568 | static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
625 | { | 569 | { |
570 | DHT * dht = object; | ||
626 | uint64_t ping_id; | 571 | uint64_t ping_id; |
627 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; | 572 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; |
628 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; | 573 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; |
@@ -637,7 +582,7 @@ static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint | |||
637 | 582 | ||
638 | int len = decrypt_data( | 583 | int len = decrypt_data( |
639 | packet + 1, | 584 | packet + 1, |
640 | self_secret_key, | 585 | dht->c->self_secret_key, |
641 | packet + 1 + CLIENT_ID_SIZE, | 586 | packet + 1 + CLIENT_ID_SIZE, |
642 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 587 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
643 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain ); | 588 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain ); |
@@ -647,19 +592,19 @@ static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint | |||
647 | 592 | ||
648 | memcpy(&ping_id, plain, sizeof(ping_id)); | 593 | memcpy(&ping_id, plain, sizeof(ping_id)); |
649 | 594 | ||
650 | if (!is_gettingnodes(source, ping_id)) | 595 | if (!is_gettingnodes(dht, source, ping_id)) |
651 | return 1; | 596 | return 1; |
652 | 597 | ||
653 | Node_format nodes_list[MAX_SENT_NODES]; | 598 | Node_format nodes_list[MAX_SENT_NODES]; |
654 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); | 599 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); |
655 | 600 | ||
656 | addto_lists(source, packet + 1); | 601 | addto_lists(dht, source, packet + 1); |
657 | 602 | ||
658 | uint32_t i; | 603 | uint32_t i; |
659 | 604 | ||
660 | for (i = 0; i < num_nodes; ++i) { | 605 | for (i = 0; i < num_nodes; ++i) { |
661 | send_ping_request(nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id); | 606 | send_ping_request(nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id); |
662 | returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | 607 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); |
663 | } | 608 | } |
664 | 609 | ||
665 | return 0; | 610 | return 0; |
@@ -668,54 +613,54 @@ static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint | |||
668 | /*----------------------------------------------------------------------------------*/ | 613 | /*----------------------------------------------------------------------------------*/ |
669 | /*------------------------END of packet handling functions--------------------------*/ | 614 | /*------------------------END of packet handling functions--------------------------*/ |
670 | 615 | ||
671 | int DHT_addfriend(uint8_t *client_id) | 616 | int DHT_addfriend(DHT * dht, uint8_t *client_id) |
672 | { | 617 | { |
673 | if (friend_number(client_id) != -1) /*Is friend already in DHT?*/ | 618 | if (friend_number(dht, client_id) != -1) /*Is friend already in DHT?*/ |
674 | return 1; | 619 | return 1; |
675 | 620 | ||
676 | Friend *temp; | 621 | DHT_Friend *temp; |
677 | temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); | 622 | temp = realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends + 1)); |
678 | 623 | ||
679 | if (temp == NULL) | 624 | if (temp == NULL) |
680 | return 1; | 625 | return 1; |
681 | 626 | ||
682 | friends_list = temp; | 627 | dht->friends_list = temp; |
683 | memset(&friends_list[num_friends], 0, sizeof(Friend)); | 628 | memset(&dht->friends_list[dht->num_friends], 0, sizeof(DHT_Friend)); |
684 | memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); | 629 | memcpy(dht->friends_list[dht->num_friends].client_id, client_id, CLIENT_ID_SIZE); |
685 | 630 | ||
686 | friends_list[num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int(); | 631 | dht->friends_list[dht->num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int(); |
687 | ++num_friends; | 632 | ++dht->num_friends; |
688 | return 0; | 633 | return 0; |
689 | } | 634 | } |
690 | 635 | ||
691 | int DHT_delfriend(uint8_t *client_id) | 636 | int DHT_delfriend(DHT * dht, uint8_t *client_id) |
692 | { | 637 | { |
693 | uint32_t i; | 638 | uint32_t i; |
694 | Friend *temp; | 639 | DHT_Friend *temp; |
695 | 640 | ||
696 | for (i = 0; i < num_friends; ++i) { | 641 | for (i = 0; i < dht->num_friends; ++i) { |
697 | /* Equal */ | 642 | /* Equal */ |
698 | if (id_equal(friends_list[i].client_id, client_id)) { | 643 | if (id_equal(dht->friends_list[i].client_id, client_id)) { |
699 | --num_friends; | 644 | --dht->num_friends; |
700 | 645 | ||
701 | if (num_friends != i) { | 646 | if (dht->num_friends != i) { |
702 | memcpy( friends_list[i].client_id, | 647 | memcpy( dht->friends_list[i].client_id, |
703 | friends_list[num_friends].client_id, | 648 | dht->friends_list[dht->num_friends].client_id, |
704 | CLIENT_ID_SIZE ); | 649 | CLIENT_ID_SIZE ); |
705 | } | 650 | } |
706 | 651 | ||
707 | if (num_friends == 0) { | 652 | if (dht->num_friends == 0) { |
708 | free(friends_list); | 653 | free(dht->friends_list); |
709 | friends_list = NULL; | 654 | dht->friends_list = NULL; |
710 | return 0; | 655 | return 0; |
711 | } | 656 | } |
712 | 657 | ||
713 | temp = realloc(friends_list, sizeof(Friend) * (num_friends)); | 658 | temp = realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends)); |
714 | 659 | ||
715 | if (temp == NULL) | 660 | if (temp == NULL) |
716 | return 1; | 661 | return 1; |
717 | 662 | ||
718 | friends_list = temp; | 663 | dht->friends_list = temp; |
719 | return 0; | 664 | return 0; |
720 | } | 665 | } |
721 | } | 666 | } |
@@ -724,19 +669,19 @@ int DHT_delfriend(uint8_t *client_id) | |||
724 | } | 669 | } |
725 | 670 | ||
726 | /* TODO: Optimize this. */ | 671 | /* TODO: Optimize this. */ |
727 | IP_Port DHT_getfriendip(uint8_t *client_id) | 672 | IP_Port DHT_getfriendip(DHT * dht, uint8_t *client_id) |
728 | { | 673 | { |
729 | uint32_t i, j; | 674 | uint32_t i, j; |
730 | uint64_t temp_time = unix_time(); | 675 | uint64_t temp_time = unix_time(); |
731 | IP_Port empty = {{{0}}, 0}; | 676 | IP_Port empty = {{{0}}, 0}; |
732 | 677 | ||
733 | for (i = 0; i < num_friends; ++i) { | 678 | for (i = 0; i < dht->num_friends; ++i) { |
734 | /* Equal */ | 679 | /* Equal */ |
735 | if (id_equal(friends_list[i].client_id, client_id)) { | 680 | if (id_equal(dht->friends_list[i].client_id, client_id)) { |
736 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 681 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
737 | if (id_equal(friends_list[i].client_list[j].client_id, client_id) | 682 | if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id) |
738 | && !is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) | 683 | && !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) |
739 | return friends_list[i].client_list[j].ip_port; | 684 | return dht->friends_list[i].client_list[j].ip_port; |
740 | } | 685 | } |
741 | 686 | ||
742 | return empty; | 687 | return empty; |
@@ -750,49 +695,47 @@ IP_Port DHT_getfriendip(uint8_t *client_id) | |||
750 | /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request | 695 | /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request |
751 | * every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list. | 696 | * every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list. |
752 | */ | 697 | */ |
753 | static void doDHTFriends(void) | 698 | static void do_DHT_friends(DHT * dht) |
754 | { | 699 | { |
755 | uint32_t i, j; | 700 | uint32_t i, j; |
756 | uint64_t temp_time = unix_time(); | 701 | uint64_t temp_time = unix_time(); |
757 | uint32_t rand_node; | 702 | uint32_t rand_node; |
758 | uint32_t index[MAX_FRIEND_CLIENTS]; | 703 | uint32_t index[MAX_FRIEND_CLIENTS]; |
759 | 704 | ||
760 | for (i = 0; i < num_friends; ++i) { | 705 | for (i = 0; i < dht->num_friends; ++i) { |
761 | uint32_t num_nodes = 0; | 706 | uint32_t num_nodes = 0; |
762 | 707 | ||
763 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 708 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
764 | /* if node is not dead. */ | 709 | /* if node is not dead. */ |
765 | if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { | 710 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { |
766 | if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { | 711 | if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { |
767 | send_ping_request( friends_list[i].client_list[j].ip_port, | 712 | send_ping_request( dht->friends_list[i].client_list[j].ip_port, |
768 | (clientid_t *) &friends_list[i].client_list[j].client_id ); | 713 | (clientid_t *) &dht->friends_list[i].client_list[j].client_id ); |
769 | friends_list[i].client_list[j].last_pinged = temp_time; | 714 | dht->friends_list[i].client_list[j].last_pinged = temp_time; |
770 | } | 715 | } |
771 | 716 | ||
772 | /* if node is good. */ | 717 | /* if node is good. */ |
773 | if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { | 718 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { |
774 | index[num_nodes] = j; | 719 | index[num_nodes] = j; |
775 | ++num_nodes; | 720 | ++num_nodes; |
776 | } | 721 | } |
777 | } | 722 | } |
778 | } | 723 | } |
779 | 724 | ||
780 | if (friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { | 725 | if (dht->friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { |
781 | rand_node = rand() % num_nodes; | 726 | rand_node = rand() % num_nodes; |
782 | getnodes( friends_list[i].client_list[index[rand_node]].ip_port, | 727 | getnodes(dht, dht->friends_list[i].client_list[index[rand_node]].ip_port, |
783 | friends_list[i].client_list[index[rand_node]].client_id, | 728 | dht->friends_list[i].client_list[index[rand_node]].client_id, |
784 | friends_list[i].client_id ); | 729 | dht->friends_list[i].client_id ); |
785 | friends_list[i].lastgetnode = temp_time; | 730 | dht->friends_list[i].lastgetnode = temp_time; |
786 | } | 731 | } |
787 | } | 732 | } |
788 | } | 733 | } |
789 | 734 | ||
790 | static uint64_t close_lastgetnodes; | ||
791 | |||
792 | /* Ping each client in the close nodes list every PING_INTERVAL seconds. | 735 | /* Ping each client in the close nodes list every PING_INTERVAL seconds. |
793 | * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list. | 736 | * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list. |
794 | */ | 737 | */ |
795 | static void doClose(void) | 738 | static void do_Close(DHT * dht) |
796 | { | 739 | { |
797 | uint32_t i; | 740 | uint32_t i; |
798 | uint64_t temp_time = unix_time(); | 741 | uint64_t temp_time = unix_time(); |
@@ -802,46 +745,47 @@ static void doClose(void) | |||
802 | 745 | ||
803 | for (i = 0; i < LCLIENT_LIST; ++i) { | 746 | for (i = 0; i < LCLIENT_LIST; ++i) { |
804 | /* if node is not dead. */ | 747 | /* if node is not dead. */ |
805 | if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { | 748 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { |
806 | if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { | 749 | if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { |
807 | send_ping_request( close_clientlist[i].ip_port, | 750 | send_ping_request( dht->close_clientlist[i].ip_port, |
808 | (clientid_t *) &close_clientlist[i].client_id ); | 751 | (clientid_t *) &dht->close_clientlist[i].client_id ); |
809 | close_clientlist[i].last_pinged = temp_time; | 752 | dht->close_clientlist[i].last_pinged = temp_time; |
810 | } | 753 | } |
811 | 754 | ||
812 | /* if node is good. */ | 755 | /* if node is good. */ |
813 | if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) { | 756 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) { |
814 | index[num_nodes] = i; | 757 | index[num_nodes] = i; |
815 | ++num_nodes; | 758 | ++num_nodes; |
816 | } | 759 | } |
817 | } | 760 | } |
818 | } | 761 | } |
819 | 762 | ||
820 | if (close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { | 763 | if (dht->close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { |
821 | rand_node = rand() % num_nodes; | 764 | rand_node = rand() % num_nodes; |
822 | getnodes( close_clientlist[index[rand_node]].ip_port, | 765 | getnodes(dht, dht->close_clientlist[index[rand_node]].ip_port, |
823 | close_clientlist[index[rand_node]].client_id, | 766 | dht->close_clientlist[index[rand_node]].client_id, |
824 | self_public_key ); | 767 | dht->c->self_public_key ); |
825 | close_lastgetnodes = temp_time; | 768 | dht->close_lastgetnodes = temp_time; |
826 | } | 769 | } |
827 | } | 770 | } |
828 | 771 | ||
829 | void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key) | 772 | void DHT_bootstrap(DHT * dht, IP_Port ip_port, uint8_t *public_key) |
830 | { | 773 | { |
831 | getnodes(ip_port, public_key, self_public_key); | 774 | getnodes(dht, ip_port, public_key, dht->c->self_public_key); |
775 | //send_ping_request(dht, ip_port, (clientid_t *) public_key); | ||
832 | send_ping_request(ip_port, (clientid_t *) public_key); | 776 | send_ping_request(ip_port, (clientid_t *) public_key); |
833 | } | 777 | } |
834 | 778 | ||
835 | /* send the given packet to node with client_id | 779 | /* send the given packet to node with client_id |
836 | * returns -1 if failure | 780 | * returns -1 if failure |
837 | */ | 781 | */ |
838 | int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length) | 782 | int route_packet(DHT * dht, uint8_t *client_id, uint8_t *packet, uint32_t length) |
839 | { | 783 | { |
840 | uint32_t i; | 784 | uint32_t i; |
841 | 785 | ||
842 | for (i = 0; i < LCLIENT_LIST; ++i) { | 786 | for (i = 0; i < LCLIENT_LIST; ++i) { |
843 | if (id_equal(client_id, close_clientlist[i].client_id)) | 787 | if (id_equal(client_id, dht->close_clientlist[i].client_id)) |
844 | return sendpacket(temp_net->sock, close_clientlist[i].ip_port, packet, length); | 788 | return sendpacket(dht->c->lossless_udp->net->sock, dht->close_clientlist[i].ip_port, packet, length); |
845 | } | 789 | } |
846 | 790 | ||
847 | return -1; | 791 | return -1; |
@@ -853,16 +797,16 @@ int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length) | |||
853 | * return 0 if we are connected to friend or if no ips were found. | 797 | * return 0 if we are connected to friend or if no ips were found. |
854 | * returns -1 if no such friend | 798 | * returns -1 if no such friend |
855 | */ | 799 | */ |
856 | static int friend_iplist(IP_Port *ip_portlist, uint16_t friend_num) | 800 | static int friend_iplist(DHT * dht, IP_Port *ip_portlist, uint16_t friend_num) |
857 | { | 801 | { |
858 | int num_ips = 0; | 802 | int num_ips = 0; |
859 | uint32_t i; | 803 | uint32_t i; |
860 | uint64_t temp_time = unix_time(); | 804 | uint64_t temp_time = unix_time(); |
861 | 805 | ||
862 | if (friend_num >= num_friends) | 806 | if (friend_num >= dht->num_friends) |
863 | return -1; | 807 | return -1; |
864 | 808 | ||
865 | Friend *friend = &friends_list[friend_num]; | 809 | DHT_Friend *friend = &dht->friends_list[friend_num]; |
866 | Client_data *client; | 810 | Client_data *client; |
867 | 811 | ||
868 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 812 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { |
@@ -888,9 +832,9 @@ static int friend_iplist(IP_Port *ip_portlist, uint16_t friend_num) | |||
888 | * | 832 | * |
889 | * Only works if more than (MAX_FRIEND_CLIENTS / 2) return an ip for friend. | 833 | * Only works if more than (MAX_FRIEND_CLIENTS / 2) return an ip for friend. |
890 | */ | 834 | */ |
891 | int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | 835 | int route_tofriend(DHT * dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) |
892 | { | 836 | { |
893 | int num = friend_number(friend_id); | 837 | int num = friend_number(dht, friend_id); |
894 | 838 | ||
895 | if (num == -1) | 839 | if (num == -1) |
896 | return 0; | 840 | return 0; |
@@ -898,13 +842,13 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | |||
898 | uint32_t i, sent = 0; | 842 | uint32_t i, sent = 0; |
899 | 843 | ||
900 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 844 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
901 | int ip_num = friend_iplist(ip_list, num); | 845 | int ip_num = friend_iplist(dht, ip_list, num); |
902 | 846 | ||
903 | if (ip_num < (MAX_FRIEND_CLIENTS / 2)) | 847 | if (ip_num < (MAX_FRIEND_CLIENTS / 2)) |
904 | return 0; | 848 | return 0; |
905 | 849 | ||
906 | uint64_t temp_time = unix_time(); | 850 | uint64_t temp_time = unix_time(); |
907 | Friend *friend = &friends_list[num]; | 851 | DHT_Friend *friend = &dht->friends_list[num]; |
908 | Client_data *client; | 852 | Client_data *client; |
909 | 853 | ||
910 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 854 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { |
@@ -912,7 +856,7 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | |||
912 | 856 | ||
913 | /*If ip is not zero and node is good */ | 857 | /*If ip is not zero and node is good */ |
914 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { | 858 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { |
915 | if (sendpacket(temp_net->sock, client->ip_port, packet, length) == length) | 859 | if (sendpacket(dht->c->lossless_udp->net->sock, client->ip_port, packet, length) == length) |
916 | ++sent; | 860 | ++sent; |
917 | } | 861 | } |
918 | } | 862 | } |
@@ -923,14 +867,14 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | |||
923 | /* Send the following packet to one random person who tells us they are connected to friend_id | 867 | /* Send the following packet to one random person who tells us they are connected to friend_id |
924 | * returns the number of nodes it sent the packet to | 868 | * returns the number of nodes it sent the packet to |
925 | */ | 869 | */ |
926 | static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | 870 | static int routeone_tofriend(DHT * dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) |
927 | { | 871 | { |
928 | int num = friend_number(friend_id); | 872 | int num = friend_number(dht, friend_id); |
929 | 873 | ||
930 | if (num == -1) | 874 | if (num == -1) |
931 | return 0; | 875 | return 0; |
932 | 876 | ||
933 | Friend *friend = &friends_list[num]; | 877 | DHT_Friend *friend = &dht->friends_list[num]; |
934 | Client_data *client; | 878 | Client_data *client; |
935 | 879 | ||
936 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 880 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
@@ -951,7 +895,7 @@ static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
951 | if (n < 1) | 895 | if (n < 1) |
952 | return 0; | 896 | return 0; |
953 | 897 | ||
954 | if (sendpacket(temp_net->sock, ip_list[rand() % n], packet, length) == length) | 898 | if (sendpacket(dht->c->lossless_udp->net->sock, ip_list[rand() % n], packet, length) == length) |
955 | return 1; | 899 | return 1; |
956 | 900 | ||
957 | return 0; | 901 | return 0; |
@@ -963,14 +907,14 @@ static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
963 | * return 0 if we are connected to friend or if no ips were found. | 907 | * return 0 if we are connected to friend or if no ips were found. |
964 | * returns -1 if no such friend | 908 | * returns -1 if no such friend |
965 | */ | 909 | */ |
966 | int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id) | 910 | int friend_ips(DHT * dht, IP_Port *ip_portlist, uint8_t *friend_id) |
967 | { | 911 | { |
968 | uint32_t i; | 912 | uint32_t i; |
969 | 913 | ||
970 | for (i = 0; i < num_friends; ++i) { | 914 | for (i = 0; i < dht->num_friends; ++i) { |
971 | /* Equal */ | 915 | /* Equal */ |
972 | if (id_equal(friends_list[i].client_id, friend_id)) | 916 | if (id_equal(dht->friends_list[i].client_id, friend_id)) |
973 | return friend_iplist(ip_portlist, i); | 917 | return friend_iplist(dht, ip_portlist, i); |
974 | } | 918 | } |
975 | 919 | ||
976 | return -1; | 920 | return -1; |
@@ -979,7 +923,7 @@ int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id) | |||
979 | /*----------------------------------------------------------------------------------*/ | 923 | /*----------------------------------------------------------------------------------*/ |
980 | /*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/ | 924 | /*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/ |
981 | 925 | ||
982 | static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type) | 926 | static int send_NATping(DHT * dht, uint8_t *public_key, uint64_t ping_id, uint8_t type) |
983 | { | 927 | { |
984 | uint8_t data[sizeof(uint64_t) + 1]; | 928 | uint8_t data[sizeof(uint64_t) + 1]; |
985 | uint8_t packet[MAX_DATA_SIZE]; | 929 | uint8_t packet[MAX_DATA_SIZE]; |
@@ -989,15 +933,15 @@ static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type) | |||
989 | data[0] = type; | 933 | data[0] = type; |
990 | memcpy(data + 1, &ping_id, sizeof(uint64_t)); | 934 | memcpy(data + 1, &ping_id, sizeof(uint64_t)); |
991 | /* 254 is NAT ping request packet id */ | 935 | /* 254 is NAT ping request packet id */ |
992 | int len = create_request(self_public_key, self_secret_key, packet, public_key, data, sizeof(uint64_t) + 1, 254); | 936 | int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, data, sizeof(uint64_t) + 1, 254); |
993 | 937 | ||
994 | if (len == -1) | 938 | if (len == -1) |
995 | return -1; | 939 | return -1; |
996 | 940 | ||
997 | if (type == 0) /*If packet is request use many people to route it*/ | 941 | if (type == 0) /*If packet is request use many people to route it*/ |
998 | num = route_tofriend(public_key, packet, len); | 942 | num = route_tofriend(dht, public_key, packet, len); |
999 | else if (type == 1) /*If packet is response use only one person to route it*/ | 943 | else if (type == 1) /*If packet is response use only one person to route it*/ |
1000 | num = routeone_tofriend(public_key, packet, len); | 944 | num = routeone_tofriend(dht, public_key, packet, len); |
1001 | 945 | ||
1002 | if (num == 0) | 946 | if (num == 0) |
1003 | return -1; | 947 | return -1; |
@@ -1006,21 +950,22 @@ static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type) | |||
1006 | } | 950 | } |
1007 | 951 | ||
1008 | /* Handle a received ping request for */ | 952 | /* Handle a received ping request for */ |
1009 | static int handle_NATping(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) | 953 | static int handle_NATping(void * object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) |
1010 | { | 954 | { |
955 | DHT * dht = object; | ||
1011 | uint64_t ping_id; | 956 | uint64_t ping_id; |
1012 | memcpy(&ping_id, packet + 1, sizeof(uint64_t)); | 957 | memcpy(&ping_id, packet + 1, sizeof(uint64_t)); |
1013 | 958 | ||
1014 | int friendnumber = friend_number(source_pubkey); | 959 | int friendnumber = friend_number(dht, source_pubkey); |
1015 | 960 | ||
1016 | if (friendnumber == -1) | 961 | if (friendnumber == -1) |
1017 | return 1; | 962 | return 1; |
1018 | 963 | ||
1019 | Friend *friend = &friends_list[friendnumber]; | 964 | DHT_Friend *friend = &dht->friends_list[friendnumber]; |
1020 | 965 | ||
1021 | if (packet[0] == 0) { | 966 | if (packet[0] == 0) { |
1022 | /* 1 is reply */ | 967 | /* 1 is reply */ |
1023 | send_NATping(source_pubkey, ping_id, 1); | 968 | send_NATping(dht, source_pubkey, ping_id, 1); |
1024 | friend->recvNATping_timestamp = unix_time(); | 969 | friend->recvNATping_timestamp = unix_time(); |
1025 | return 0; | 970 | return 0; |
1026 | } else if (packet[0] == 1) { | 971 | } else if (packet[0] == 1) { |
@@ -1082,45 +1027,46 @@ static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t | |||
1082 | return num; | 1027 | return num; |
1083 | } | 1028 | } |
1084 | 1029 | ||
1085 | static void punch_holes(IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) | 1030 | static void punch_holes(DHT * dht, IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) |
1086 | { | 1031 | { |
1087 | if (numports > MAX_FRIEND_CLIENTS || numports == 0) | 1032 | if (numports > MAX_FRIEND_CLIENTS || numports == 0) |
1088 | return; | 1033 | return; |
1089 | 1034 | ||
1090 | uint32_t i; | 1035 | uint32_t i; |
1091 | uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; | 1036 | uint32_t top = dht->friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; |
1092 | 1037 | ||
1093 | for (i = friends_list[friend_num].punching_index; i != top; i++) { | 1038 | for (i = dht->friends_list[friend_num].punching_index; i != top; i++) { |
1094 | /*TODO: improve port guessing algorithm*/ | 1039 | /*TODO: improve port guessing algorithm*/ |
1095 | uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); | 1040 | uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); |
1096 | IP_Port pinging = {ip, htons(port)}; | 1041 | IP_Port pinging = {ip, htons(port)}; |
1097 | send_ping_request(pinging, (clientid_t *) &friends_list[friend_num].client_id); | 1042 | //send_ping_request(dht, pinging, (clientid_t *) &dht->friends_list[friend_num].client_id); |
1043 | send_ping_request(pinging, (clientid_t *) &dht->friends_list[friend_num].client_id); | ||
1098 | } | 1044 | } |
1099 | 1045 | ||
1100 | friends_list[friend_num].punching_index = i; | 1046 | dht->friends_list[friend_num].punching_index = i; |
1101 | } | 1047 | } |
1102 | 1048 | ||
1103 | static void doNAT(void) | 1049 | static void do_NAT(DHT * dht) |
1104 | { | 1050 | { |
1105 | uint32_t i; | 1051 | uint32_t i; |
1106 | uint64_t temp_time = unix_time(); | 1052 | uint64_t temp_time = unix_time(); |
1107 | 1053 | ||
1108 | for (i = 0; i < num_friends; ++i) { | 1054 | for (i = 0; i < dht->num_friends; ++i) { |
1109 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 1055 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
1110 | int num = friend_iplist(ip_list, i); | 1056 | int num = friend_iplist(dht, ip_list, i); |
1111 | 1057 | ||
1112 | /*If already connected or friend is not online don't try to hole punch*/ | 1058 | /*If already connected or friend is not online don't try to hole punch*/ |
1113 | if (num < MAX_FRIEND_CLIENTS / 2) | 1059 | if (num < MAX_FRIEND_CLIENTS / 2) |
1114 | continue; | 1060 | continue; |
1115 | 1061 | ||
1116 | if (friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { | 1062 | if (dht->friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { |
1117 | send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ | 1063 | send_NATping(dht, dht->friends_list[i].client_id, dht->friends_list[i].NATping_id, 0); /*0 is request*/ |
1118 | friends_list[i].NATping_timestamp = temp_time; | 1064 | dht->friends_list[i].NATping_timestamp = temp_time; |
1119 | } | 1065 | } |
1120 | 1066 | ||
1121 | if (friends_list[i].hole_punching == 1 && | 1067 | if (dht->friends_list[i].hole_punching == 1 && |
1122 | friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && | 1068 | dht->friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && |
1123 | friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { | 1069 | dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { |
1124 | 1070 | ||
1125 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); | 1071 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); |
1126 | 1072 | ||
@@ -1129,10 +1075,10 @@ static void doNAT(void) | |||
1129 | 1075 | ||
1130 | uint16_t port_list[MAX_FRIEND_CLIENTS]; | 1076 | uint16_t port_list[MAX_FRIEND_CLIENTS]; |
1131 | uint16_t numports = NAT_getports(port_list, ip_list, num, ip); | 1077 | uint16_t numports = NAT_getports(port_list, ip_list, num, ip); |
1132 | punch_holes(ip, port_list, numports, i); | 1078 | punch_holes(dht, ip, port_list, numports, i); |
1133 | 1079 | ||
1134 | friends_list[i].punching_timestamp = temp_time; | 1080 | dht->friends_list[i].punching_timestamp = temp_time; |
1135 | friends_list[i].hole_punching = 0; | 1081 | dht->friends_list[i].hole_punching = 0; |
1136 | } | 1082 | } |
1137 | } | 1083 | } |
1138 | } | 1084 | } |
@@ -1149,7 +1095,7 @@ static void doNAT(void) | |||
1149 | network while preventing amplification attacks. | 1095 | network while preventing amplification attacks. |
1150 | return 0 if node was added | 1096 | return 0 if node was added |
1151 | return -1 if node was not added */ | 1097 | return -1 if node was not added */ |
1152 | int add_toping(uint8_t *client_id, IP_Port ip_port) | 1098 | int add_toping(DHT * dht, uint8_t *client_id, IP_Port ip_port) |
1153 | { | 1099 | { |
1154 | if (ip_port.ip.i == 0) | 1100 | if (ip_port.ip.i == 0) |
1155 | return -1; | 1101 | return -1; |
@@ -1157,19 +1103,19 @@ int add_toping(uint8_t *client_id, IP_Port ip_port) | |||
1157 | uint32_t i; | 1103 | uint32_t i; |
1158 | 1104 | ||
1159 | for (i = 0; i < MAX_TOPING; ++i) { | 1105 | for (i = 0; i < MAX_TOPING; ++i) { |
1160 | if (toping[i].ip_port.ip.i == 0) { | 1106 | if (dht->toping[i].ip_port.ip.i == 0) { |
1161 | memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); | 1107 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); |
1162 | toping[i].ip_port.ip.i = ip_port.ip.i; | 1108 | dht->toping[i].ip_port.ip.i = ip_port.ip.i; |
1163 | toping[i].ip_port.port = ip_port.port; | 1109 | dht->toping[i].ip_port.port = ip_port.port; |
1164 | return 0; | 1110 | return 0; |
1165 | } | 1111 | } |
1166 | } | 1112 | } |
1167 | 1113 | ||
1168 | for (i = 0; i < MAX_TOPING; ++i) { | 1114 | for (i = 0; i < MAX_TOPING; ++i) { |
1169 | if (id_closest(self_public_key, toping[i].client_id, client_id) == 2) { | 1115 | if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) { |
1170 | memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); | 1116 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); |
1171 | toping[i].ip_port.ip.i = ip_port.ip.i; | 1117 | dht->toping[i].ip_port.ip.i = ip_port.ip.i; |
1172 | toping[i].ip_port.port = ip_port.port; | 1118 | dht->toping[i].ip_port.port = ip_port.port; |
1173 | return 0; | 1119 | return 0; |
1174 | } | 1120 | } |
1175 | } | 1121 | } |
@@ -1179,68 +1125,80 @@ int add_toping(uint8_t *client_id, IP_Port ip_port) | |||
1179 | 1125 | ||
1180 | /*Ping all the valid nodes in the toping list every TIME_TOPING seconds | 1126 | /*Ping all the valid nodes in the toping list every TIME_TOPING seconds |
1181 | this function must be run at least once every TIME_TOPING seconds*/ | 1127 | this function must be run at least once every TIME_TOPING seconds*/ |
1182 | static void do_toping() | 1128 | static void do_toping(DHT * dht) |
1183 | { | 1129 | { |
1184 | uint64_t temp_time = unix_time(); | 1130 | uint64_t temp_time = unix_time(); |
1185 | 1131 | ||
1186 | if (!is_timeout(temp_time, last_toping, TIME_TOPING)) | 1132 | if (!is_timeout(temp_time, dht->last_toping, TIME_TOPING)) |
1187 | return; | 1133 | return; |
1188 | 1134 | ||
1189 | last_toping = temp_time; | 1135 | dht->last_toping = temp_time; |
1190 | uint32_t i; | 1136 | uint32_t i; |
1191 | 1137 | ||
1192 | for (i = 0; i < MAX_TOPING; ++i) { | 1138 | for (i = 0; i < MAX_TOPING; ++i) { |
1193 | if (toping[i].ip_port.ip.i == 0) | 1139 | if (dht->toping[i].ip_port.ip.i == 0) |
1194 | return; | 1140 | return; |
1195 | 1141 | ||
1196 | send_ping_request(toping[i].ip_port, (clientid_t *) toping[i].client_id); | 1142 | //send_ping_request(dht, dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id); |
1197 | toping[i].ip_port.ip.i = 0; | 1143 | send_ping_request(dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id); |
1144 | dht->toping[i].ip_port.ip.i = 0; | ||
1198 | } | 1145 | } |
1199 | } | 1146 | } |
1200 | 1147 | ||
1201 | 1148 | ||
1202 | void DHT_init(void) | 1149 | DHT * new_DHT(Net_Crypto *c) |
1203 | { | 1150 | { |
1204 | networking_registerhandler(temp_net, 0, &handle_ping_request, NULL); | 1151 | DHT * temp = calloc(1, sizeof(DHT)); |
1205 | networking_registerhandler(temp_net, 1, &handle_ping_response, NULL); | 1152 | if (temp == NULL) |
1206 | networking_registerhandler(temp_net, 2, &handle_getnodes, NULL); | 1153 | return NULL; |
1207 | networking_registerhandler(temp_net, 3, &handle_sendnodes, NULL); | 1154 | temp->c = c; |
1208 | cryptopacket_registerhandler(temp_net_crypto, 254, &handle_NATping); | 1155 | networking_registerhandler(c->lossless_udp->net, 0, &handle_ping_request, temp); |
1156 | networking_registerhandler(c->lossless_udp->net, 1, &handle_ping_response, temp); | ||
1157 | networking_registerhandler(c->lossless_udp->net, 2, &handle_getnodes, temp); | ||
1158 | networking_registerhandler(c->lossless_udp->net, 3, &handle_sendnodes, temp); | ||
1159 | cryptopacket_registerhandler(c, 254, &handle_NATping, temp); | ||
1160 | temp_DHT = temp; | ||
1161 | return temp; | ||
1209 | } | 1162 | } |
1210 | 1163 | ||
1211 | void doDHT(void) | 1164 | void do_DHT(DHT * dht) |
1165 | { | ||
1166 | do_Close(dht); | ||
1167 | do_DHT_friends(dht); | ||
1168 | do_NAT(dht); | ||
1169 | do_toping(dht); | ||
1170 | } | ||
1171 | void kill_DHT(DHT * dht) | ||
1212 | { | 1172 | { |
1213 | doClose(); | 1173 | free(dht->friends_list); |
1214 | doDHTFriends(); | 1174 | free(dht); |
1215 | doNAT(); | ||
1216 | do_toping(); | ||
1217 | } | 1175 | } |
1218 | 1176 | ||
1219 | /* get the size of the DHT (for saving) */ | 1177 | /* get the size of the DHT (for saving) */ |
1220 | uint32_t DHT_size(void) | 1178 | uint32_t DHT_size(DHT * dht) |
1221 | { | 1179 | { |
1222 | return sizeof(close_clientlist) + sizeof(Friend) * num_friends; | 1180 | return sizeof(dht->close_clientlist) + sizeof(DHT_Friend) * dht->num_friends; |
1223 | } | 1181 | } |
1224 | 1182 | ||
1225 | /* save the DHT in data where data is an array of size DHT_size() */ | 1183 | /* save the DHT in data where data is an array of size DHT_size() */ |
1226 | void DHT_save(uint8_t *data) | 1184 | void DHT_save(DHT * dht, uint8_t *data) |
1227 | { | 1185 | { |
1228 | memcpy(data, close_clientlist, sizeof(close_clientlist)); | 1186 | memcpy(data, dht->close_clientlist, sizeof(dht->close_clientlist)); |
1229 | memcpy(data + sizeof(close_clientlist), friends_list, sizeof(Friend) * num_friends); | 1187 | memcpy(data + sizeof(dht->close_clientlist), dht->friends_list, sizeof(DHT_Friend) * dht->num_friends); |
1230 | } | 1188 | } |
1231 | 1189 | ||
1232 | /* load the DHT from data of size size; | 1190 | /* load the DHT from data of size size; |
1233 | * return -1 if failure | 1191 | * return -1 if failure |
1234 | * return 0 if success | 1192 | * return 0 if success |
1235 | */ | 1193 | */ |
1236 | int DHT_load(uint8_t *data, uint32_t size) | 1194 | int DHT_load(DHT * dht, uint8_t *data, uint32_t size) |
1237 | { | 1195 | { |
1238 | init_ping(); | 1196 | init_ping(); |
1239 | 1197 | ||
1240 | if (size < sizeof(close_clientlist)) | 1198 | if (size < sizeof(dht->close_clientlist)) |
1241 | return -1; | 1199 | return -1; |
1242 | 1200 | ||
1243 | if ((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) | 1201 | if ((size - sizeof(dht->close_clientlist)) % sizeof(DHT_Friend) != 0) |
1244 | return -1; | 1202 | return -1; |
1245 | 1203 | ||
1246 | uint32_t i, j; | 1204 | uint32_t i, j; |
@@ -1249,19 +1207,19 @@ int DHT_load(uint8_t *data, uint32_t size) | |||
1249 | 1207 | ||
1250 | Client_data *client; | 1208 | Client_data *client; |
1251 | 1209 | ||
1252 | temp = (size - sizeof(close_clientlist)) / sizeof(Friend); | 1210 | temp = (size - sizeof(dht->close_clientlist)) / sizeof(DHT_Friend); |
1253 | 1211 | ||
1254 | if (temp != 0) { | 1212 | if (temp != 0) { |
1255 | Friend *tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); | 1213 | DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist)); |
1256 | 1214 | ||
1257 | for (i = 0; i < temp; ++i) { | 1215 | for (i = 0; i < temp; ++i) { |
1258 | DHT_addfriend(tempfriends_list[i].client_id); | 1216 | DHT_addfriend(dht, tempfriends_list[i].client_id); |
1259 | 1217 | ||
1260 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 1218 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
1261 | client = &tempfriends_list[i].client_list[j]; | 1219 | client = &tempfriends_list[i].client_list[j]; |
1262 | 1220 | ||
1263 | if (client->timestamp != 0) | 1221 | if (client->timestamp != 0) |
1264 | getnodes(client->ip_port, client->client_id, tempfriends_list[i].client_id); | 1222 | getnodes(dht, client->ip_port, client->client_id, tempfriends_list[i].client_id); |
1265 | } | 1223 | } |
1266 | } | 1224 | } |
1267 | } | 1225 | } |
@@ -1270,7 +1228,7 @@ int DHT_load(uint8_t *data, uint32_t size) | |||
1270 | 1228 | ||
1271 | for (i = 0; i < LCLIENT_LIST; ++i) { | 1229 | for (i = 0; i < LCLIENT_LIST; ++i) { |
1272 | if (tempclose_clientlist[i].timestamp != 0) | 1230 | if (tempclose_clientlist[i].timestamp != 0) |
1273 | DHT_bootstrap( tempclose_clientlist[i].ip_port, | 1231 | DHT_bootstrap(dht, tempclose_clientlist[i].ip_port, |
1274 | tempclose_clientlist[i].client_id ); | 1232 | tempclose_clientlist[i].client_id ); |
1275 | } | 1233 | } |
1276 | 1234 | ||
@@ -1280,13 +1238,13 @@ int DHT_load(uint8_t *data, uint32_t size) | |||
1280 | /* returns 0 if we are not connected to the DHT | 1238 | /* returns 0 if we are not connected to the DHT |
1281 | * returns 1 if we are | 1239 | * returns 1 if we are |
1282 | */ | 1240 | */ |
1283 | int DHT_isconnected(void) | 1241 | int DHT_isconnected(DHT * dht) |
1284 | { | 1242 | { |
1285 | uint32_t i; | 1243 | uint32_t i; |
1286 | uint64_t temp_time = unix_time(); | 1244 | uint64_t temp_time = unix_time(); |
1287 | 1245 | ||
1288 | for (i = 0; i < LCLIENT_LIST; ++i) { | 1246 | for (i = 0; i < LCLIENT_LIST; ++i) { |
1289 | if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) | 1247 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) |
1290 | return 1; | 1248 | return 1; |
1291 | } | 1249 | } |
1292 | 1250 | ||