summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c201
1 files changed, 139 insertions, 62 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index e2d91256..a4734747 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -115,11 +115,6 @@ static int client_id_cmp(ClientPair p1, ClientPair p2)
115 return c; 115 return c;
116} 116}
117 117
118static int ipport_equal(IP_Port a, IP_Port b)
119{
120 return (a.ip.uint32 == b.ip.uint32) && (a.port == b.port);
121}
122
123static int id_equal(uint8_t *a, uint8_t *b) 118static int id_equal(uint8_t *a, uint8_t *b)
124{ 119{
125 return memcmp(a, b, CLIENT_ID_SIZE) == 0; 120 return memcmp(a, b, CLIENT_ID_SIZE) == 0;
@@ -144,15 +139,14 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id
144 139
145 for (i = 0; i < length; ++i) { 140 for (i = 0; i < length; ++i) {
146 /* If ip_port is assigned to a different client_id replace it */ 141 /* If ip_port is assigned to a different client_id replace it */
147 if (ipport_equal(list[i].ip_port, ip_port)) { 142 if (ipport_equal(&list[i].ip_port, &ip_port)) {
148 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 143 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
149 } 144 }
150 145
151 if (id_equal(list[i].client_id, client_id)) { 146 if (id_equal(list[i].client_id, client_id)) {
152 /* Refresh the client timestamp. */ 147 /* Refresh the client timestamp. */
153 list[i].timestamp = temp_time; 148 list[i].timestamp = temp_time;
154 list[i].ip_port.ip.uint32 = ip_port.ip.uint32; 149 ipport_copy(&list[i].ip_port, &ip_port);
155 list[i].ip_port.port = ip_port.port;
156 return 1; 150 return 1;
157 } 151 }
158 } 152 }
@@ -197,18 +191,37 @@ static int friend_number(DHT *dht, uint8_t *client_id)
197 * 191 *
198 * TODO: For the love of based Allah make this function cleaner and much more efficient. 192 * TODO: For the love of based Allah make this function cleaner and much more efficient.
199 */ 193 */
200static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list) 194static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family)
201{ 195{
202 uint32_t i, j, k; 196 uint32_t i, j, k;
203 uint64_t temp_time = unix_time(); 197 uint64_t temp_time = unix_time();
204 int num_nodes = 0, closest, tout, inlist; 198 int num_nodes = 0, closest, tout, inlist, ipv46x;
205 199
206 for (i = 0; i < LCLIENT_LIST; ++i) { 200 for (i = 0; i < LCLIENT_LIST; ++i) {
207 tout = is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); 201 tout = is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT);
208 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, dht->close_clientlist[i].client_id); 202 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, dht->close_clientlist[i].client_id);
209 203
204 /*
205 * NET_PACKET_SEND_NODES sends ONLY AF_INET
206 * NET_PACKET_SEND_NODES_EX sends ALL BUT AF_INET (i.e. AF_INET6),
207 * it could send both, but then a) packet size is an issue and
208 * b) duplicates the traffic (NET_PACKET_SEND_NODES has to be
209 * sent anyways for backwards compatibility)
210 * we COULD send ALL as NET_PACKET_SEND_NODES_EX if we KNEW that the
211 * partner node understands - that's true if *they* are on IPv6
212 */
213#ifdef TOX_ENABLE_IPV6
214 ipv46x = 0;
215 if (sa_family == AF_INET)
216 ipv46x = dht->close_clientlist[i].ip_port.ip.family != AF_INET;
217 else
218 ipv46x = dht->close_clientlist[i].ip_port.ip.family == AF_INET;
219#else
220 ipv46x = sa_family != AF_INET;
221#endif
222
210 /* If node isn't good or is already in list. */ 223 /* If node isn't good or is already in list. */
211 if (tout || inlist) 224 if (tout || inlist || ipv46x)
212 continue; 225 continue;
213 226
214 if (num_nodes < MAX_SENT_NODES) { 227 if (num_nodes < MAX_SENT_NODES) {
@@ -247,8 +260,18 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list
247 MAX_SENT_NODES, 260 MAX_SENT_NODES,
248 dht->friends_list[i].client_list[j].client_id); 261 dht->friends_list[i].client_list[j].client_id);
249 262
263#ifdef TOX_ENABLE_IPV6
264 ipv46x = 0;
265 if (sa_family == AF_INET)
266 ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family != AF_INET;
267 else
268 ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family == AF_INET;
269#else
270 ipv46x = sa_family != AF_INET;
271#endif
272
250 /* If node isn't good or is already in list. */ 273 /* If node isn't good or is already in list. */
251 if (tout || inlist) 274 if (tout || inlist || ipv46x)
252 continue; 275 continue;
253 276
254 if (num_nodes < MAX_SENT_NODES) { 277 if (num_nodes < MAX_SENT_NODES) {
@@ -301,7 +324,7 @@ static int replace_bad( Client_data *list,
301 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 324 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
302 list[i].ip_port = ip_port; 325 list[i].ip_port = ip_port;
303 list[i].timestamp = temp_time; 326 list[i].timestamp = temp_time;
304 list[i].ret_ip_port.ip.uint32 = 0; 327 ip_reset(&list[i].ret_ip_port.ip);
305 list[i].ret_ip_port.port = 0; 328 list[i].ret_ip_port.port = 0;
306 list[i].ret_timestamp = 0; 329 list[i].ret_timestamp = 0;
307 return 0; 330 return 0;
@@ -349,7 +372,7 @@ static int replace_good( Client_data *list,
349 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 372 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
350 list[i].ip_port = ip_port; 373 list[i].ip_port = ip_port;
351 list[i].timestamp = temp_time; 374 list[i].timestamp = temp_time;
352 list[i].ret_ip_port.ip.uint32 = 0; 375 ip_reset(&list[i].ret_ip_port.ip);
353 list[i].ret_ip_port.port = 0; 376 list[i].ret_ip_port.port = 0;
354 list[i].ret_timestamp = 0; 377 list[i].ret_timestamp = 0;
355 return 0; 378 return 0;
@@ -447,13 +470,13 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id)
447 if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { 470 if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) {
448 pinging = 0; 471 pinging = 0;
449 472
450 if (ip_port.ip.uint32 != 0 && ipport_equal(dht->send_nodes[i].ip_port, ip_port)) 473 if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id)
451 ++pinging; 474 ++pinging;
452 475
453 if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id) 476 if (ip_isset(&ip_port.ip) && ipport_equal(&dht->send_nodes[i].ip_port, &ip_port))
454 ++pinging; 477 ++pinging;
455 478
456 if (pinging == (ping_id != 0) + (ip_port.ip.uint32 != 0)) 479 if (pinging == (ping_id != 0) + (ip_isset(&ip_port.ip) != 0))
457 return 1; 480 return 1;
458 } 481 }
459 } 482 }
@@ -518,44 +541,65 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
518 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 541 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
519 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 542 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
520 543
521 return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, sizeof(data)); 544 return sendpacket(dht->c->lossless_udp->net, ip_port, data, sizeof(data));
522} 545}
523 546
524/* Send a send nodes response. */ 547/* Send a send nodes response. */
548/* because of BINARY compatibility, the Node_format MUST BE Node4_format,
549 * IPv6 nodes are sent in a different message */
525static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) 550static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id)
526{ 551{
527 /* Check if packet is going to be sent to ourself. */ 552 /* Check if packet is going to be sent to ourself. */
528 if (id_equal(public_key, dht->c->self_public_key)) 553 if (id_equal(public_key, dht->c->self_public_key))
529 return -1; 554 return -1;
530 555
556 size_t Node4_format_size = sizeof(Node4_format);
531 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 557 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
532 + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; 558 + Node4_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING];
533 559
534 Node_format nodes_list[MAX_SENT_NODES]; 560 Node_format nodes_list[MAX_SENT_NODES];
535 int num_nodes = get_close_nodes(dht, client_id, nodes_list); 561 int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET);
536 562
537 if (num_nodes == 0) 563 if (num_nodes == 0)
538 return 0; 564 return 0;
539 565
540 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; 566 uint8_t plain[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES];
541 uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; 567 uint8_t encrypt[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING];
542 uint8_t nonce[crypto_box_NONCEBYTES]; 568 uint8_t nonce[crypto_box_NONCEBYTES];
543 random_nonce(nonce); 569 random_nonce(nonce);
544 570
545 memcpy(plain, &ping_id, sizeof(ping_id)); 571 memcpy(plain, &ping_id, sizeof(ping_id));
546 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); 572#ifdef TOX_ENABLE_IPV6
573 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
574 int i, num_nodes_ok = 0;
575 for(i = 0; i < num_nodes; i++)
576 if (nodes_list[i].ip_port.ip.family == AF_INET) {
577 memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE);
578 nodes4_list[num_nodes_ok].ip_port.ip.uint32 = nodes_list[i].ip_port.ip.ip4.uint32;
579 nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port;
580
581 num_nodes_ok++;
582 }
583
584 if (num_nodes_ok < num_nodes) {
585 /* shouldn't happen */
586 num_nodes = num_nodes_ok;
587 }
588#else
589 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node4_format_size);
590#endif
547 591
548 int len = encrypt_data( public_key, 592 int len = encrypt_data( public_key,
549 dht->c->self_secret_key, 593 dht->c->self_secret_key,
550 nonce, 594 nonce,
551 plain, 595 plain,
552 sizeof(ping_id) + num_nodes * sizeof(Node_format), 596 sizeof(ping_id) + num_nodes * Node4_format_size,
553 encrypt ); 597 encrypt );
554 598
555 if (len == -1) 599 if (len == -1)
556 return -1; 600 return -1;
557 601
558 if ((unsigned int)len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) 602 if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node4_format_size + ENCRYPTION_PADDING)
559 return -1; 603 return -1;
560 604
561 data[0] = NET_PACKET_SEND_NODES; 605 data[0] = NET_PACKET_SEND_NODES;
@@ -563,7 +607,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
563 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 607 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
564 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 608 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
565 609
566 return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 610 return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
567} 611}
568 612
569static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 613static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
@@ -606,22 +650,23 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
606 uint32_t cid_size = 1 + CLIENT_ID_SIZE; 650 uint32_t cid_size = 1 + CLIENT_ID_SIZE;
607 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; 651 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
608 652
609 if (length > (cid_size + sizeof(Node_format) * MAX_SENT_NODES) || 653 size_t Node4_format_size = sizeof(Node4_format);
610 ((length - cid_size) % sizeof(Node_format)) != 0 || 654 if (length > (cid_size + Node4_format_size * MAX_SENT_NODES) ||
611 (length < cid_size + sizeof(Node_format))) 655 ((length - cid_size) % Node4_format_size) != 0 ||
656 (length < cid_size + Node4_format_size))
612 return 1; 657 return 1;
613 658
614 uint32_t num_nodes = (length - cid_size) / sizeof(Node_format); 659 uint32_t num_nodes = (length - cid_size) / Node4_format_size;
615 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; 660 uint8_t plain[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES];
616 661
617 int len = decrypt_data( 662 int len = decrypt_data(
618 packet + 1, 663 packet + 1,
619 dht->c->self_secret_key, 664 dht->c->self_secret_key,
620 packet + 1 + CLIENT_ID_SIZE, 665 packet + 1 + CLIENT_ID_SIZE,
621 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 666 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
622 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain ); 667 sizeof(ping_id) + num_nodes * Node4_format_size + ENCRYPTION_PADDING, plain );
623 668
624 if ((unsigned int)len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) 669 if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node4_format_size)
625 return 1; 670 return 1;
626 671
627 memcpy(&ping_id, plain, sizeof(ping_id)); 672 memcpy(&ping_id, plain, sizeof(ping_id));
@@ -629,13 +674,33 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
629 if (!is_gettingnodes(dht, source, ping_id)) 674 if (!is_gettingnodes(dht, source, ping_id))
630 return 1; 675 return 1;
631 676
677 uint32_t i;
632 Node_format nodes_list[MAX_SENT_NODES]; 678 Node_format nodes_list[MAX_SENT_NODES];
679
680#ifdef TOX_ENABLE_IPV6
681 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
682
683 int num_nodes_ok = 0;
684 for(i = 0; i < num_nodes; i++)
685 if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != ~0)) {
686 memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE);
687 nodes_list[num_nodes_ok].ip_port.ip.family = AF_INET;
688 nodes_list[num_nodes_ok].ip_port.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32;
689 nodes_list[num_nodes_ok].ip_port.port = nodes4_list[i].ip_port.port;
690
691 num_nodes_ok++;
692 }
693
694 if (num_nodes_ok < num_nodes) {
695 /* shouldn't happen */
696 num_nodes = num_nodes_ok;
697 }
698#else
633 memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); 699 memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format));
700#endif
634 701
635 addto_lists(dht, source, packet + 1); 702 addto_lists(dht, source, packet + 1);
636 703
637 uint32_t i;
638
639 for (i = 0; i < num_nodes; ++i) { 704 for (i = 0; i < num_nodes; ++i) {
640 send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id); 705 send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id);
641 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 706 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
@@ -703,27 +768,30 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id)
703} 768}
704 769
705/* TODO: Optimize this. */ 770/* TODO: Optimize this. */
706IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id) 771int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port)
707{ 772{
708 uint32_t i, j; 773 uint32_t i, j;
709 uint64_t temp_time = unix_time(); 774 uint64_t temp_time = unix_time();
710 IP_Port empty = {{{{0}}, 0, 0}}; 775
776 ip_reset(&ip_port->ip);
777 ip_port->port = 0;
711 778
712 for (i = 0; i < dht->num_friends; ++i) { 779 for (i = 0; i < dht->num_friends; ++i) {
713 /* Equal */ 780 /* Equal */
714 if (id_equal(dht->friends_list[i].client_id, client_id)) { 781 if (id_equal(dht->friends_list[i].client_id, client_id)) {
715 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 782 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
716 if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id) 783 if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id)
717 && !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) 784 && !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) {
718 return dht->friends_list[i].client_list[j].ip_port; 785 *ip_port = dht->friends_list[i].client_list[j].ip_port;
786 return 1;
787 }
719 } 788 }
720 789
721 return empty; 790 return 0;
722 } 791 }
723 } 792 }
724 793
725 empty.ip.uint32 = 1; 794 return -1;
726 return empty;
727} 795}
728 796
729/* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request 797/* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request
@@ -808,6 +876,15 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
808 getnodes(dht, ip_port, public_key, dht->c->self_public_key); 876 getnodes(dht, ip_port, public_key, dht->c->self_public_key);
809 send_ping_request(dht->ping, dht->c, ip_port, public_key); 877 send_ping_request(dht->ping, dht->c, ip_port, public_key);
810} 878}
879void DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key)
880{
881 IP_Port ip_port;
882 ip_init(&ip_port.ip, ipv6enabled);
883 if (addr_resolve_or_parse_ip(address, &ip_port.ip)) {
884 ip_port.port = port;
885 DHT_bootstrap(dht, ip_port, public_key);
886 }
887}
811 888
812/* Send the given packet to node with client_id 889/* Send the given packet to node with client_id
813 * 890 *
@@ -819,7 +896,7 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
819 896
820 for (i = 0; i < LCLIENT_LIST; ++i) { 897 for (i = 0; i < LCLIENT_LIST; ++i) {
821 if (id_equal(client_id, dht->close_clientlist[i].client_id)) 898 if (id_equal(client_id, dht->close_clientlist[i].client_id))
822 return sendpacket(dht->c->lossless_udp->net->sock, dht->close_clientlist[i].ip_port, packet, length); 899 return sendpacket(dht->c->lossless_udp->net, dht->close_clientlist[i].ip_port, packet, length);
823 } 900 }
824 901
825 return -1; 902 return -1;
@@ -848,7 +925,7 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
848 client = &friend->client_list[i]; 925 client = &friend->client_list[i];
849 926
850 /* If ip is not zero and node is good. */ 927 /* If ip is not zero and node is good. */
851 if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { 928 if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
852 929
853 if (id_equal(client->client_id, friend->client_id)) 930 if (id_equal(client->client_id, friend->client_id))
854 return 0; 931 return 0;
@@ -890,8 +967,8 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
890 client = &friend->client_list[i]; 967 client = &friend->client_list[i];
891 968
892 /* If ip is not zero and node is good. */ 969 /* If ip is not zero and node is good. */
893 if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { 970 if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
894 int retval = sendpacket(dht->c->lossless_udp->net->sock, client->ip_port, packet, length); 971 int retval = sendpacket(dht->c->lossless_udp->net, client->ip_port, packet, length);
895 972
896 if ((unsigned int)retval == length) 973 if ((unsigned int)retval == length)
897 ++sent; 974 ++sent;
@@ -924,7 +1001,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
924 client = &friend->client_list[i]; 1001 client = &friend->client_list[i];
925 1002
926 /* If ip is not zero and node is good. */ 1003 /* If ip is not zero and node is good. */
927 if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { 1004 if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
928 ip_list[n] = client->ip_port; 1005 ip_list[n] = client->ip_port;
929 ++n; 1006 ++n;
930 } 1007 }
@@ -933,7 +1010,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
933 if (n < 1) 1010 if (n < 1)
934 return 0; 1011 return 0;
935 1012
936 int retval = sendpacket(dht->c->lossless_udp->net->sock, ip_list[rand() % n], packet, length); 1013 int retval = sendpacket(dht->c->lossless_udp->net, ip_list[rand() % n], packet, length);
937 1014
938 if ((unsigned int)retval == length) 1015 if ((unsigned int)retval == length)
939 return 1; 1016 return 1;
@@ -1032,7 +1109,8 @@ static int handle_NATping(void *object, IP_Port source, uint8_t *source_pubkey,
1032 */ 1109 */
1033static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) 1110static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num)
1034{ 1111{
1035 IP zero = {{0}}; 1112 IP zero;
1113 ip_reset(&zero);
1036 1114
1037 if (len > MAX_FRIEND_CLIENTS) 1115 if (len > MAX_FRIEND_CLIENTS)
1038 return zero; 1116 return zero;
@@ -1042,7 +1120,7 @@ static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num)
1042 1120
1043 for (i = 0; i < len; ++i) { 1121 for (i = 0; i < len; ++i) {
1044 for (j = 0; j < len; ++j) { 1122 for (j = 0; j < len; ++j) {
1045 if (ip_portlist[i].ip.uint32 == ip_portlist[j].ip.uint32) 1123 if (ip_equal(&ip_portlist[i].ip, &ip_portlist[j].ip))
1046 ++numbers[i]; 1124 ++numbers[i];
1047 } 1125 }
1048 1126
@@ -1065,7 +1143,7 @@ static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t
1065 uint16_t num = 0; 1143 uint16_t num = 0;
1066 1144
1067 for (i = 0; i < len; ++i) { 1145 for (i = 0; i < len; ++i) {
1068 if (ip_portlist[i].ip.uint32 == ip.uint32) { 1146 if (ip_equal(&ip_portlist[i].ip, &ip)) {
1069 portlist[num] = ntohs(ip_portlist[i].port); 1147 portlist[num] = ntohs(ip_portlist[i].port);
1070 ++num; 1148 ++num;
1071 } 1149 }
@@ -1085,7 +1163,9 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports,
1085 for (i = dht->friends_list[friend_num].punching_index; i != top; i++) { 1163 for (i = dht->friends_list[friend_num].punching_index; i != top; i++) {
1086 /* TODO: Improve port guessing algorithm. */ 1164 /* TODO: Improve port guessing algorithm. */
1087 uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); 1165 uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1);
1088 IP_Port pinging = {{ip, htons(port), 0}}; 1166 IP_Port pinging;
1167 ip_copy(&pinging.ip, &ip);
1168 pinging.port = htons(port);
1089 send_ping_request(dht->ping, dht->c, pinging, dht->friends_list[friend_num].client_id); 1169 send_ping_request(dht->ping, dht->c, pinging, dht->friends_list[friend_num].client_id);
1090 } 1170 }
1091 1171
@@ -1115,8 +1195,7 @@ static void do_NAT(DHT *dht)
1115 dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { 1195 dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) {
1116 1196
1117 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); 1197 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2);
1118 1198 if (!ip_isset(&ip))
1119 if (ip.uint32 == 0)
1120 continue; 1199 continue;
1121 1200
1122 uint16_t port_list[MAX_FRIEND_CLIENTS]; 1201 uint16_t port_list[MAX_FRIEND_CLIENTS];
@@ -1145,16 +1224,15 @@ static void do_NAT(DHT *dht)
1145 */ 1224 */
1146int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) 1225int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port)
1147{ 1226{
1148 if (ip_port.ip.uint32 == 0) 1227 if (!ip_isset(&ip_port.ip))
1149 return -1; 1228 return -1;
1150 1229
1151 uint32_t i; 1230 uint32_t i;
1152 1231
1153 for (i = 0; i < MAX_TOPING; ++i) { 1232 for (i = 0; i < MAX_TOPING; ++i) {
1154 if (dht->toping[i].ip_port.ip.uint32 == 0) { 1233 if (!ip_isset(&dht->toping[i].ip_port.ip)) {
1155 memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); 1234 memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE);
1156 dht->toping[i].ip_port.ip.uint32 = ip_port.ip.uint32; 1235 ipport_copy(&dht->toping[i].ip_port, &ip_port);
1157 dht->toping[i].ip_port.port = ip_port.port;
1158 return 0; 1236 return 0;
1159 } 1237 }
1160 } 1238 }
@@ -1162,8 +1240,7 @@ int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port)
1162 for (i = 0; i < MAX_TOPING; ++i) { 1240 for (i = 0; i < MAX_TOPING; ++i) {
1163 if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) { 1241 if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) {
1164 memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); 1242 memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE);
1165 dht->toping[i].ip_port.ip.uint32 = ip_port.ip.uint32; 1243 ipport_copy(&dht->toping[i].ip_port, &ip_port);
1166 dht->toping[i].ip_port.port = ip_port.port;
1167 return 0; 1244 return 0;
1168 } 1245 }
1169 } 1246 }
@@ -1185,11 +1262,11 @@ static void do_toping(DHT *dht)
1185 uint32_t i; 1262 uint32_t i;
1186 1263
1187 for (i = 0; i < MAX_TOPING; ++i) { 1264 for (i = 0; i < MAX_TOPING; ++i) {
1188 if (dht->toping[i].ip_port.ip.uint32 == 0) 1265 if (!ip_isset(&dht->toping[i].ip_port.ip))
1189 return; 1266 return;
1190 1267
1191 send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, dht->toping[i].client_id); 1268 send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, dht->toping[i].client_id);
1192 dht->toping[i].ip_port.ip.uint32 = 0; 1269 ip_reset(&dht->toping[i].ip_port.ip);
1193 } 1270 }
1194} 1271}
1195 1272