summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c148
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 */
138static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *client_id) 138static 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. */
283static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_id) 283static 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 */
309static int replace_good( Client_data *list, 309static 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 */
378static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) 378static 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. */
437static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port) 437static 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. */
458static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) 458static 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. */
497static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) 497static 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
619int DHT_addfriend(DHT *dht, uint8_t *client_id) 619int 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 */
784int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length) 784int 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*/
872static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) 872static 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. */
956static int handle_NATping(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) 956static 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 */
990static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) 990static 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 */
1018static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip) 1018static 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 */
1100int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) 1101int 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 */
1130static void do_toping(DHT *dht) 1132static 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). */
1192uint32_t DHT_size(DHT *dht) 1194uint32_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(). */
1198void DHT_save(DHT *dht, uint8_t *data) 1200void 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 */
1208int DHT_load(DHT *dht, uint8_t *data, uint32_t size) 1210int 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 */
1253int DHT_isconnected(DHT *dht) 1255int DHT_isconnected(DHT *dht)
1254{ 1256{