diff options
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r-- | toxcore/DHT.c | 148 |
1 files changed, 75 insertions, 73 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 533425c4..56e8b052 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -27,30 +27,30 @@ | |||
27 | #include "packets.h" | 27 | #include "packets.h" |
28 | #include "ping.h" | 28 | #include "ping.h" |
29 | 29 | ||
30 | /* 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. */ |
31 | #define BAD_NODE_TIMEOUT 70 | 31 | #define BAD_NODE_TIMEOUT 70 |
32 | 32 | ||
33 | /* the max number of nodes to send with send nodes. */ | 33 | /* The max number of nodes to send with send nodes. */ |
34 | #define MAX_SENT_NODES 8 | 34 | #define MAX_SENT_NODES 8 |
35 | 35 | ||
36 | /* ping timeout in seconds */ | 36 | /* Ping timeout in seconds */ |
37 | #define PING_TIMEOUT 5 | 37 | #define PING_TIMEOUT 5 |
38 | 38 | ||
39 | /* The timeout after which a node is discarded completely. */ | 39 | /* The timeout after which a node is discarded completely. */ |
40 | #define Kill_NODE_TIMEOUT 300 | 40 | #define Kill_NODE_TIMEOUT 300 |
41 | 41 | ||
42 | /* ping interval in seconds for each node in our lists. */ | 42 | /* Ping interval in seconds for each node in our lists. */ |
43 | #define PING_INTERVAL 60 | 43 | #define PING_INTERVAL 60 |
44 | 44 | ||
45 | /* ping interval in seconds for each random sending of a get nodes request. */ | 45 | /* Ping interval in seconds for each random sending of a get nodes request. */ |
46 | #define GET_NODE_INTERVAL 10 | 46 | #define GET_NODE_INTERVAL 10 |
47 | 47 | ||
48 | #define MAX_PUNCHING_PORTS 32 | 48 | #define MAX_PUNCHING_PORTS 32 |
49 | 49 | ||
50 | /*Interval in seconds between punching attempts*/ | 50 | /* Interval in seconds between punching attempts*/ |
51 | #define PUNCH_INTERVAL 10 | 51 | #define PUNCH_INTERVAL 10 |
52 | 52 | ||
53 | /*Ping newly announced nodes to ping per TIME_TOPING seconds*/ | 53 | /* Ping newly announced nodes to ping per TIME_TOPING seconds*/ |
54 | #define TIME_TOPING 5 | 54 | #define TIME_TOPING 5 |
55 | 55 | ||
56 | #define NAT_PING_REQUEST 0 | 56 | #define NAT_PING_REQUEST 0 |
@@ -102,9 +102,9 @@ static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout) | |||
102 | return timestamp + timeout <= time_now; | 102 | return timestamp + timeout <= time_now; |
103 | } | 103 | } |
104 | 104 | ||
105 | /* check if client with client_id is already in list of length length. | 105 | /* Check if client with client_id is already in list of length length. |
106 | * if it is then set its corresponding timestamp to current time. | 106 | * If it is then set its corresponding timestamp to current time. |
107 | * if the id is already in the list with a different ip_port, update it. | 107 | * If the id is already in the list with a different ip_port, update it. |
108 | * return True(1) or False(0) | 108 | * return True(1) or False(0) |
109 | * | 109 | * |
110 | * TODO: maybe optimize this. | 110 | * TODO: maybe optimize this. |
@@ -115,7 +115,7 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id | |||
115 | uint64_t temp_time = unix_time(); | 115 | uint64_t temp_time = unix_time(); |
116 | 116 | ||
117 | for (i = 0; i < length; ++i) { | 117 | for (i = 0; i < length; ++i) { |
118 | /*If ip_port is assigned to a different client_id replace it*/ | 118 | /* If ip_port is assigned to a different client_id replace it */ |
119 | if (ipport_equal(list[i].ip_port, ip_port)) { | 119 | if (ipport_equal(list[i].ip_port, ip_port)) { |
120 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 120 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
121 | } | 121 | } |
@@ -132,7 +132,7 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id | |||
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
135 | /* check if client with client_id is already in node format list of length length. | 135 | /* Check if client with client_id is already in node format list of length length. |
136 | * return True(1) or False(0) | 136 | * return True(1) or False(0) |
137 | */ | 137 | */ |
138 | static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *client_id) | 138 | static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *client_id) |
@@ -176,7 +176,7 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list | |||
176 | tout = is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); | 176 | tout = is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); |
177 | inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, dht->close_clientlist[i].client_id); | 177 | inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, dht->close_clientlist[i].client_id); |
178 | 178 | ||
179 | /* if node isn't good or is already in list. */ | 179 | /* If node isn't good or is already in list. */ |
180 | if (tout || inlist) | 180 | if (tout || inlist) |
181 | continue; | 181 | continue; |
182 | 182 | ||
@@ -216,7 +216,7 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list | |||
216 | MAX_SENT_NODES, | 216 | MAX_SENT_NODES, |
217 | dht->friends_list[i].client_list[j].client_id); | 217 | dht->friends_list[i].client_list[j].client_id); |
218 | 218 | ||
219 | /* if node isn't good or is already in list. */ | 219 | /* If node isn't good or is already in list. */ |
220 | if (tout || inlist) | 220 | if (tout || inlist) |
221 | continue; | 221 | continue; |
222 | 222 | ||
@@ -251,7 +251,7 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list | |||
251 | return num_nodes; | 251 | return num_nodes; |
252 | } | 252 | } |
253 | 253 | ||
254 | /* replace first bad (or empty) node with this one | 254 | /* Replace first bad (or empty) node with this one |
255 | * return 0 if successful | 255 | * return 0 if successful |
256 | * return 1 if not (list contains no bad nodes) | 256 | * return 1 if not (list contains no bad nodes) |
257 | */ | 257 | */ |
@@ -264,7 +264,7 @@ static int replace_bad( Client_data *list, | |||
264 | uint64_t temp_time = unix_time(); | 264 | uint64_t temp_time = unix_time(); |
265 | 265 | ||
266 | for (i = 0; i < length; ++i) { | 266 | for (i = 0; i < length; ++i) { |
267 | /* if node is bad */ | 267 | /* If node is bad */ |
268 | if (is_timeout(temp_time, list[i].timestamp, BAD_NODE_TIMEOUT)) { | 268 | if (is_timeout(temp_time, list[i].timestamp, BAD_NODE_TIMEOUT)) { |
269 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 269 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
270 | list[i].ip_port = ip_port; | 270 | list[i].ip_port = ip_port; |
@@ -278,8 +278,8 @@ static int replace_bad( Client_data *list, | |||
278 | 278 | ||
279 | return 1; | 279 | return 1; |
280 | } | 280 | } |
281 | /*Sort the list. It will be sorted from furthest to closest. | 281 | /* Sort the list. It will be sorted from furthest to closest. |
282 | TODO: this is innefficient and needs to be optimized.*/ | 282 | TODO: this is innefficient and needs to be optimized. */ |
283 | static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_id) | 283 | static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_id) |
284 | { | 284 | { |
285 | if (length == 0) | 285 | if (length == 0) |
@@ -305,7 +305,7 @@ static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_i | |||
305 | } | 305 | } |
306 | 306 | ||
307 | 307 | ||
308 | /* replace the first good node that is further to the comp_client_id than that of the client_id in the list */ | 308 | /* Replace the first good node that is further to the comp_client_id than that of the client_id in the list */ |
309 | static int replace_good( Client_data *list, | 309 | static int replace_good( Client_data *list, |
310 | uint32_t length, | 310 | uint32_t length, |
311 | uint8_t *client_id, | 311 | uint8_t *client_id, |
@@ -337,12 +337,12 @@ void addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id) | |||
337 | { | 337 | { |
338 | uint32_t i; | 338 | uint32_t i; |
339 | 339 | ||
340 | /* NOTE: current behavior if there are two clients with the same id is | 340 | /* NOTE: Current behavior if there are two clients with the same id is |
341 | * to replace the first ip by the second. | 341 | * to replace the first ip by the second. |
342 | */ | 342 | */ |
343 | if (!client_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 343 | if (!client_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
344 | if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 344 | if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
345 | /* if we can't replace bad nodes we try replacing good ones */ | 345 | /* If we can't replace bad nodes we try replacing good ones */ |
346 | replace_good( dht->close_clientlist, | 346 | replace_good( dht->close_clientlist, |
347 | LCLIENT_LIST, | 347 | LCLIENT_LIST, |
348 | client_id, | 348 | client_id, |
@@ -361,7 +361,7 @@ void addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id) | |||
361 | MAX_FRIEND_CLIENTS, | 361 | MAX_FRIEND_CLIENTS, |
362 | client_id, | 362 | client_id, |
363 | ip_port )) { | 363 | ip_port )) { |
364 | /* if we can't replace bad nodes we try replacing good ones. */ | 364 | /* If we can't replace bad nodes we try replacing good ones. */ |
365 | replace_good( dht->friends_list[i].client_list, | 365 | replace_good( dht->friends_list[i].client_list, |
366 | MAX_FRIEND_CLIENTS, | 366 | MAX_FRIEND_CLIENTS, |
367 | client_id, | 367 | client_id, |
@@ -373,7 +373,7 @@ void addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id) | |||
373 | } | 373 | } |
374 | 374 | ||
375 | /* If client_id is a friend or us, update ret_ip_port | 375 | /* If client_id is a friend or us, update ret_ip_port |
376 | * nodeclient_id is the id of the node that sent us this info | 376 | * nodeclient_id is the id of the node that sent us this info. |
377 | */ | 377 | */ |
378 | static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) | 378 | static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) |
379 | { | 379 | { |
@@ -433,7 +433,7 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) | |||
433 | return 0; | 433 | return 0; |
434 | } | 434 | } |
435 | 435 | ||
436 | /* Same but for get node requests */ | 436 | /* Same but for get node requests. */ |
437 | static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port) | 437 | static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port) |
438 | { | 438 | { |
439 | uint32_t i, j; | 439 | uint32_t i, j; |
@@ -454,10 +454,10 @@ static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port) | |||
454 | return 0; | 454 | return 0; |
455 | } | 455 | } |
456 | 456 | ||
457 | /* send a getnodes request */ | 457 | /* Send a getnodes request. */ |
458 | static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | 458 | static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) |
459 | { | 459 | { |
460 | /* check if packet is gonna be sent to ourself */ | 460 | /* Check if packet is going to be sent to ourself. */ |
461 | if (id_equal(public_key, dht->c->self_public_key) || is_gettingnodes(dht, ip_port, 0)) | 461 | if (id_equal(public_key, dht->c->self_public_key) || is_gettingnodes(dht, ip_port, 0)) |
462 | return 1; | 462 | return 1; |
463 | 463 | ||
@@ -493,10 +493,10 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli | |||
493 | return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, sizeof(data)); | 493 | return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, sizeof(data)); |
494 | } | 494 | } |
495 | 495 | ||
496 | /* send a send nodes response */ | 496 | /* Send a send nodes response. */ |
497 | static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) | 497 | static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) |
498 | { | 498 | { |
499 | /* check if packet is gonna be sent to ourself */ | 499 | /* Check if packet is going to be sent to ourself. */ |
500 | if (id_equal(public_key, dht->c->self_public_key)) | 500 | if (id_equal(public_key, dht->c->self_public_key)) |
501 | return 1; | 501 | return 1; |
502 | 502 | ||
@@ -544,7 +544,7 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32 | |||
544 | + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING )) | 544 | + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING )) |
545 | return 1; | 545 | return 1; |
546 | 546 | ||
547 | /* check if packet is from ourself. */ | 547 | /* Check if packet is from ourself. */ |
548 | if (id_equal(packet + 1, dht->c->self_public_key)) | 548 | if (id_equal(packet + 1, dht->c->self_public_key)) |
549 | return 1; | 549 | return 1; |
550 | 550 | ||
@@ -563,7 +563,7 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32 | |||
563 | memcpy(&ping_id, plain, sizeof(ping_id)); | 563 | memcpy(&ping_id, plain, sizeof(ping_id)); |
564 | sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); | 564 | sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); |
565 | 565 | ||
566 | //send_ping_request(dht, source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ | 566 | // send_ping_request(dht, source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ |
567 | 567 | ||
568 | return 0; | 568 | return 0; |
569 | } | 569 | } |
@@ -618,7 +618,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 | |||
618 | 618 | ||
619 | int DHT_addfriend(DHT *dht, uint8_t *client_id) | 619 | int DHT_addfriend(DHT *dht, uint8_t *client_id) |
620 | { | 620 | { |
621 | if (friend_number(dht, client_id) != -1) /*Is friend already in DHT?*/ | 621 | if (friend_number(dht, client_id) != -1) /* Is friend already in DHT? */ |
622 | return 1; | 622 | return 1; |
623 | 623 | ||
624 | DHT_Friend *temp; | 624 | DHT_Friend *temp; |
@@ -709,7 +709,7 @@ static void do_DHT_friends(DHT *dht) | |||
709 | uint32_t num_nodes = 0; | 709 | uint32_t num_nodes = 0; |
710 | 710 | ||
711 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 711 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
712 | /* if node is not dead. */ | 712 | /* If node is not dead. */ |
713 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { | 713 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { |
714 | if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { | 714 | if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { |
715 | send_ping_request(dht->ping, dht->c, dht->friends_list[i].client_list[j].ip_port, | 715 | send_ping_request(dht->ping, dht->c, dht->friends_list[i].client_list[j].ip_port, |
@@ -717,7 +717,7 @@ static void do_DHT_friends(DHT *dht) | |||
717 | dht->friends_list[i].client_list[j].last_pinged = temp_time; | 717 | dht->friends_list[i].client_list[j].last_pinged = temp_time; |
718 | } | 718 | } |
719 | 719 | ||
720 | /* if node is good. */ | 720 | /* If node is good. */ |
721 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { | 721 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { |
722 | index[num_nodes] = j; | 722 | index[num_nodes] = j; |
723 | ++num_nodes; | 723 | ++num_nodes; |
@@ -747,7 +747,7 @@ static void do_Close(DHT *dht) | |||
747 | uint32_t index[LCLIENT_LIST]; | 747 | uint32_t index[LCLIENT_LIST]; |
748 | 748 | ||
749 | for (i = 0; i < LCLIENT_LIST; ++i) { | 749 | for (i = 0; i < LCLIENT_LIST; ++i) { |
750 | /* if node is not dead. */ | 750 | /* If node is not dead. */ |
751 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { | 751 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { |
752 | if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { | 752 | if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { |
753 | send_ping_request(dht->ping, dht->c, dht->close_clientlist[i].ip_port, | 753 | send_ping_request(dht->ping, dht->c, dht->close_clientlist[i].ip_port, |
@@ -755,7 +755,7 @@ static void do_Close(DHT *dht) | |||
755 | dht->close_clientlist[i].last_pinged = temp_time; | 755 | dht->close_clientlist[i].last_pinged = temp_time; |
756 | } | 756 | } |
757 | 757 | ||
758 | /* if node is good. */ | 758 | /* If node is good. */ |
759 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) { | 759 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) { |
760 | index[num_nodes] = i; | 760 | index[num_nodes] = i; |
761 | ++num_nodes; | 761 | ++num_nodes; |
@@ -778,8 +778,8 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) | |||
778 | send_ping_request(dht->ping, dht->c, ip_port, (clientid_t *) public_key); | 778 | send_ping_request(dht->ping, dht->c, ip_port, (clientid_t *) public_key); |
779 | } | 779 | } |
780 | 780 | ||
781 | /* send the given packet to node with client_id | 781 | /* Send the given packet to node with client_id |
782 | * returns -1 if failure | 782 | * returns -1 if failure. |
783 | */ | 783 | */ |
784 | int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length) | 784 | int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length) |
785 | { | 785 | { |
@@ -814,7 +814,7 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) | |||
814 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 814 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { |
815 | client = &friend->client_list[i]; | 815 | client = &friend->client_list[i]; |
816 | 816 | ||
817 | /*If ip is not zero and node is good */ | 817 | /* If ip is not zero and node is good */ |
818 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { | 818 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { |
819 | 819 | ||
820 | if (id_equal(client->client_id, friend->client_id)) | 820 | if (id_equal(client->client_id, friend->client_id)) |
@@ -829,8 +829,8 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) | |||
829 | } | 829 | } |
830 | 830 | ||
831 | 831 | ||
832 | /* Send the following packet to everyone who tells us they are connected to friend_id | 832 | /* Send the following packet to everyone who tells us they are connected to friend_id. |
833 | * returns the number of nodes it sent the packet to | 833 | * returns the number of nodes it sent the packet to. |
834 | * | 834 | * |
835 | * Only works if more than (MAX_FRIEND_CLIENTS / 2) return an ip for friend. | 835 | * Only works if more than (MAX_FRIEND_CLIENTS / 2) return an ip for friend. |
836 | */ | 836 | */ |
@@ -856,7 +856,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
856 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 856 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { |
857 | client = &friend->client_list[i]; | 857 | client = &friend->client_list[i]; |
858 | 858 | ||
859 | /*If ip is not zero and node is good */ | 859 | /* If ip is not zero and node is good */ |
860 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { | 860 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { |
861 | if (sendpacket(dht->c->lossless_udp->net->sock, client->ip_port, packet, length) == length) | 861 | if (sendpacket(dht->c->lossless_udp->net->sock, client->ip_port, packet, length) == length) |
862 | ++sent; | 862 | ++sent; |
@@ -866,7 +866,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
866 | return sent; | 866 | return sent; |
867 | } | 867 | } |
868 | 868 | ||
869 | /* Send the following packet to one random person who tells us they are connected to friend_id | 869 | /* Send the following packet to one random person who tells us they are connected to friend_id. |
870 | * returns the number of nodes it sent the packet to | 870 | * returns the number of nodes it sent the packet to |
871 | */ | 871 | */ |
872 | static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) | 872 | static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) |
@@ -887,7 +887,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint | |||
887 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 887 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { |
888 | client = &friend->client_list[i]; | 888 | client = &friend->client_list[i]; |
889 | 889 | ||
890 | /*If ip is not zero and node is good */ | 890 | /* If ip is not zero and node is good. */ |
891 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { | 891 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { |
892 | ip_list[n] = client->ip_port; | 892 | ip_list[n] = client->ip_port; |
893 | ++n; | 893 | ++n; |
@@ -903,8 +903,8 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint | |||
903 | return 0; | 903 | return 0; |
904 | } | 904 | } |
905 | 905 | ||
906 | /* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist | 906 | /* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist. |
907 | * ip_portlist must be at least MAX_FRIEND_CLIENTS big | 907 | * ip_portlist must be at least MAX_FRIEND_CLIENTS big. |
908 | * returns the number of ips returned | 908 | * returns the number of ips returned |
909 | * return 0 if we are connected to friend or if no ips were found. | 909 | * return 0 if we are connected to friend or if no ips were found. |
910 | * returns -1 if no such friend | 910 | * returns -1 if no such friend |
@@ -941,9 +941,9 @@ static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t | |||
941 | if (len == -1) | 941 | if (len == -1) |
942 | return -1; | 942 | return -1; |
943 | 943 | ||
944 | if (type == 0) /*If packet is request use many people to route it*/ | 944 | if (type == 0) /* If packet is request use many people to route it. */ |
945 | num = route_tofriend(dht, public_key, packet, len); | 945 | num = route_tofriend(dht, public_key, packet, len); |
946 | else if (type == 1) /*If packet is response use only one person to route it*/ | 946 | else if (type == 1) /* If packet is response use only one person to route it */ |
947 | num = routeone_tofriend(dht, public_key, packet, len); | 947 | num = routeone_tofriend(dht, public_key, packet, len); |
948 | 948 | ||
949 | if (num == 0) | 949 | if (num == 0) |
@@ -952,7 +952,7 @@ static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t | |||
952 | return num; | 952 | return num; |
953 | } | 953 | } |
954 | 954 | ||
955 | /* Handle a received ping request for */ | 955 | /* Handle a received ping request for. */ |
956 | static int handle_NATping(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) | 956 | static int handle_NATping(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) |
957 | { | 957 | { |
958 | DHT *dht = object; | 958 | DHT *dht = object; |
@@ -982,10 +982,10 @@ static int handle_NATping(void *object, IP_Port source, uint8_t *source_pubkey, | |||
982 | return 1; | 982 | return 1; |
983 | } | 983 | } |
984 | 984 | ||
985 | /* Get the most common ip in the ip_portlist | 985 | /* Get the most common ip in the ip_portlist. |
986 | * Only return ip if it appears in list min_num or more | 986 | * Only return ip if it appears in list min_num or more. |
987 | * len must not be bigger than MAX_FRIEND_CLIENTS | 987 | * len must not be bigger than MAX_FRIEND_CLIENTS. |
988 | * return ip of 0 if failure | 988 | * return ip of 0 if failure. |
989 | */ | 989 | */ |
990 | static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) | 990 | static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) |
991 | { | 991 | { |
@@ -1010,10 +1010,10 @@ static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) | |||
1010 | return zero; | 1010 | return zero; |
1011 | } | 1011 | } |
1012 | 1012 | ||
1013 | /* Return all the ports for one ip in a list | 1013 | /* Return all the ports for one ip in a list. |
1014 | * portlist must be at least len long | 1014 | * portlist must be at least len long |
1015 | * where len is the length of ip_portlist | 1015 | * where len is the length of ip_portlist |
1016 | * returns the number of ports and puts the list of ports in portlist | 1016 | * returns the number of ports and puts the list of ports in portlist. |
1017 | */ | 1017 | */ |
1018 | static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip) | 1018 | static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip) |
1019 | { | 1019 | { |
@@ -1039,7 +1039,7 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports, | |||
1039 | uint32_t top = dht->friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; | 1039 | uint32_t top = dht->friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; |
1040 | 1040 | ||
1041 | for (i = dht->friends_list[friend_num].punching_index; i != top; i++) { | 1041 | for (i = dht->friends_list[friend_num].punching_index; i != top; i++) { |
1042 | /*TODO: improve port guessing algorithm*/ | 1042 | /* TODO: improve port guessing algorithm */ |
1043 | uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); | 1043 | uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); |
1044 | IP_Port pinging = {ip, htons(port)}; | 1044 | IP_Port pinging = {ip, htons(port)}; |
1045 | send_ping_request(dht->ping, dht->c, pinging, (clientid_t *) &dht->friends_list[friend_num].client_id); | 1045 | send_ping_request(dht->ping, dht->c, pinging, (clientid_t *) &dht->friends_list[friend_num].client_id); |
@@ -1057,7 +1057,7 @@ static void do_NAT(DHT *dht) | |||
1057 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 1057 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
1058 | int num = friend_iplist(dht, ip_list, i); | 1058 | int num = friend_iplist(dht, ip_list, i); |
1059 | 1059 | ||
1060 | /*If already connected or friend is not online don't try to hole punch*/ | 1060 | /* If already connected or friend is not online don't try to hole punch */ |
1061 | if (num < MAX_FRIEND_CLIENTS / 2) | 1061 | if (num < MAX_FRIEND_CLIENTS / 2) |
1062 | continue; | 1062 | continue; |
1063 | 1063 | ||
@@ -1089,14 +1089,15 @@ static void do_NAT(DHT *dht) | |||
1089 | /*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ | 1089 | /*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ |
1090 | 1090 | ||
1091 | 1091 | ||
1092 | /* Add nodes to the toping list | 1092 | /* Add nodes to the toping list. |
1093 | all nodes in this list are pinged every TIME_TOPING seconds | 1093 | * All nodes in this list are pinged every TIME_TOPING seconds |
1094 | and are then removed from the list. | 1094 | * and are then removed from the list. |
1095 | if the list is full the nodes farthest from our client_id are replaced | 1095 | * If the list is full the nodes farthest from our client_id are replaced. |
1096 | the purpose of this list is to enable quick integration of new nodes into the | 1096 | * The purpose of this list is to enable quick integration of new nodes into the |
1097 | network while preventing amplification attacks. | 1097 | * network while preventing amplification attacks. |
1098 | return 0 if node was added | 1098 | * return 0 if node was added. |
1099 | return -1 if node was not added */ | 1099 | * return -1 if node was not added. |
1100 | */ | ||
1100 | int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) | 1101 | int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) |
1101 | { | 1102 | { |
1102 | if (ip_port.ip.i == 0) | 1103 | if (ip_port.ip.i == 0) |
@@ -1125,8 +1126,9 @@ int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) | |||
1125 | return -1; | 1126 | return -1; |
1126 | } | 1127 | } |
1127 | 1128 | ||
1128 | /*Ping all the valid nodes in the toping list every TIME_TOPING seconds | 1129 | /* Ping all the valid nodes in the toping list every TIME_TOPING seconds. |
1129 | this function must be run at least once every TIME_TOPING seconds*/ | 1130 | * This function must be run at least once every TIME_TOPING seconds |
1131 | */ | ||
1130 | static void do_toping(DHT *dht) | 1132 | static void do_toping(DHT *dht) |
1131 | { | 1133 | { |
1132 | uint64_t temp_time = unix_time(); | 1134 | uint64_t temp_time = unix_time(); |
@@ -1188,22 +1190,22 @@ void kill_DHT(DHT *dht) | |||
1188 | free(dht); | 1190 | free(dht); |
1189 | } | 1191 | } |
1190 | 1192 | ||
1191 | /* get the size of the DHT (for saving) */ | 1193 | /* Get the size of the DHT (for saving). */ |
1192 | uint32_t DHT_size(DHT *dht) | 1194 | uint32_t DHT_size(DHT *dht) |
1193 | { | 1195 | { |
1194 | return sizeof(dht->close_clientlist) + sizeof(DHT_Friend) * dht->num_friends; | 1196 | return sizeof(dht->close_clientlist) + sizeof(DHT_Friend) * dht->num_friends; |
1195 | } | 1197 | } |
1196 | 1198 | ||
1197 | /* save the DHT in data where data is an array of size DHT_size() */ | 1199 | /* Save the DHT in data where data is an array of size DHT_size(). */ |
1198 | void DHT_save(DHT *dht, uint8_t *data) | 1200 | void DHT_save(DHT *dht, uint8_t *data) |
1199 | { | 1201 | { |
1200 | memcpy(data, dht->close_clientlist, sizeof(dht->close_clientlist)); | 1202 | memcpy(data, dht->close_clientlist, sizeof(dht->close_clientlist)); |
1201 | memcpy(data + sizeof(dht->close_clientlist), dht->friends_list, sizeof(DHT_Friend) * dht->num_friends); | 1203 | memcpy(data + sizeof(dht->close_clientlist), dht->friends_list, sizeof(DHT_Friend) * dht->num_friends); |
1202 | } | 1204 | } |
1203 | 1205 | ||
1204 | /* load the DHT from data of size size; | 1206 | /* Load the DHT from data of size size. |
1205 | * return -1 if failure | 1207 | * return -1 if failure. |
1206 | * return 0 if success | 1208 | * return 0 if success. |
1207 | */ | 1209 | */ |
1208 | int DHT_load(DHT *dht, uint8_t *data, uint32_t size) | 1210 | int DHT_load(DHT *dht, uint8_t *data, uint32_t size) |
1209 | { | 1211 | { |
@@ -1247,8 +1249,8 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size) | |||
1247 | return 0; | 1249 | return 0; |
1248 | } | 1250 | } |
1249 | 1251 | ||
1250 | /* returns 0 if we are not connected to the DHT | 1252 | /* returns 0 if we are not connected to the DHT. |
1251 | * returns 1 if we are | 1253 | * returns 1 if we are. |
1252 | */ | 1254 | */ |
1253 | int DHT_isconnected(DHT *dht) | 1255 | int DHT_isconnected(DHT *dht) |
1254 | { | 1256 | { |