summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c613
1 files changed, 383 insertions, 230 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index eb50cc43..b9ba7e1d 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -41,7 +41,7 @@
41#define MAX_SENT_NODES 8 41#define MAX_SENT_NODES 8
42 42
43/* Ping timeout in seconds */ 43/* Ping timeout in seconds */
44#define PING_TIMEOUT 5 44#define PING_TIMEOUT 3
45 45
46/* The timeout after which a node is discarded completely. */ 46/* The timeout after which a node is discarded completely. */
47#define KILL_NODE_TIMEOUT 300 47#define KILL_NODE_TIMEOUT 300
@@ -313,7 +313,8 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
313 if (ipv46x) 313 if (ipv46x)
314 continue; 314 continue;
315 315
316 if (!LAN_ip(ipptp->ip_port.ip) && !is_LAN) 316 /* don't send LAN ips to non LAN peers */
317 if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN)
317 continue; 318 continue;
318 319
319 if (num_nodes < MAX_SENT_NODES) { 320 if (num_nodes < MAX_SENT_NODES) {
@@ -572,79 +573,58 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint
572 } 573 }
573} 574}
574 575
575/* checks if ip/port or ping_id are already in the list to get nodes 576#define NODES_ENCRYPTED_MESSAGE_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint64_t) + sizeof(Node_format) + sizeof(Node_format) + crypto_secretbox_MACBYTES)
576 * if both are set, both must match, otherwise the set must match
577 *
578 * returns 0 if neither is set or no match was found
579 * returns the (index + 1) of the match if one was found
580 */
581static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id)
582{
583 uint8_t ip_valid = ip_isset(&ip_port.ip);
584
585 if (!ip_valid && !ping_id)
586 return 0;
587 577
588 uint32_t i; 578/* Send a getnodes request.
589 579 sendback_node is the node that it will send back the response to (set to NULL to disable this) */
590 for (i = 0; i < LSEND_NODES_ARRAY; i++) 580static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, Node_format *sendback_node)
591 if (!is_timeout(dht->send_nodes[i].timestamp, PING_TIMEOUT))
592 if (!ping_id || (dht->send_nodes[i].id == ping_id))
593 if (!ip_valid || ipport_equal(&dht->send_nodes[i].ip_port, &ip_port))
594 return i + 1;
595
596 return 0;
597}
598
599/* Same but for get node requests. */
600static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port)
601{
602 uint32_t i, j;
603 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
604
605 for (i = 0; i < PING_TIMEOUT; ++i ) {
606 for (j = 0; j < LSEND_NODES_ARRAY; ++j ) {
607 if (is_timeout(dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) {
608 dht->send_nodes[j].timestamp = unix_time();
609 dht->send_nodes[j].ip_port = ip_port;
610 dht->send_nodes[j].id = ping_id;
611 return ping_id;
612 }
613 }
614 }
615
616 return 0;
617}
618
619/* Send a getnodes request. */
620static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id)
621{ 581{
622 /* Check if packet is going to be sent to ourself. */ 582 /* Check if packet is going to be sent to ourself. */
623 if (id_equal(public_key, dht->c->self_public_key) || is_gettingnodes(dht, ip_port, 0)) 583 if (id_equal(public_key, dht->c->self_public_key))
624 return -1; 584 return -1;
625 585
626 uint64_t ping_id = add_gettingnodes(dht, ip_port); 586 uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH] = {0};
587 uint8_t encrypted_message[NODES_ENCRYPTED_MESSAGE_LENGTH];
588 uint8_t nonce[crypto_box_NONCEBYTES];
589
590 new_nonce(nonce);
591 memcpy(encrypted_message, nonce, crypto_box_NONCEBYTES);
627 592
628 if (ping_id == 0) 593 uint64_t temp_time = unix_time();
594 memcpy(plain_message, &temp_time, sizeof(temp_time));
595 Node_format reciever;
596 memcpy(reciever.client_id, public_key, CLIENT_ID_SIZE);
597 reciever.ip_port = ip_port;
598 memcpy(plain_message + sizeof(temp_time), &reciever, sizeof(reciever));
599
600 if (sendback_node != NULL)
601 memcpy(plain_message + sizeof(temp_time) + sizeof(reciever), sendback_node, sizeof(Node_format));
602
603 int len_m = encrypt_data_symmetric(dht->secret_symmetric_key,
604 nonce,
605 plain_message,
606 sizeof(temp_time) + sizeof(reciever) + sizeof(Node_format),
607 encrypted_message + crypto_secretbox_NONCEBYTES);
608
609 if (len_m != NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES)
629 return -1; 610 return -1;
630 611
631 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; 612 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
632 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 613 uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH];
633 uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; 614 uint8_t encrypt[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
634 uint8_t nonce[crypto_box_NONCEBYTES];
635 new_nonce(nonce);
636 615
637 memcpy(plain, &ping_id, sizeof(ping_id)); 616
638 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); 617 memcpy(plain, client_id, CLIENT_ID_SIZE);
618 memcpy(plain + CLIENT_ID_SIZE, encrypted_message, NODES_ENCRYPTED_MESSAGE_LENGTH);
639 619
640 int len = encrypt_data( public_key, 620 int len = encrypt_data( public_key,
641 dht->c->self_secret_key, 621 dht->c->self_secret_key,
642 nonce, 622 nonce,
643 plain, 623 plain,
644 sizeof(ping_id) + CLIENT_ID_SIZE, 624 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH,
645 encrypt ); 625 encrypt );
646 626
647 if (len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 627 if (len != CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES)
648 return -1; 628 return -1;
649 629
650 data[0] = NET_PACKET_GET_NODES; 630 data[0] = NET_PACKET_GET_NODES;
@@ -655,18 +635,20 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
655 return sendpacket(dht->c->lossless_udp->net, ip_port, data, sizeof(data)); 635 return sendpacket(dht->c->lossless_udp->net, ip_port, data, sizeof(data));
656} 636}
657 637
638
658/* Send a send nodes response. */ 639/* Send a send nodes response. */
659/* because of BINARY compatibility, the Node_format MUST BE Node4_format, 640/* because of BINARY compatibility, the Node_format MUST BE Node4_format,
660 * IPv6 nodes are sent in a different message */ 641 * IPv6 nodes are sent in a different message
661static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) 642 * encrypted_data must be of size NODES_ENCRYPTED_MESSAGE_LENGTH */
643static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data)
662{ 644{
663 /* Check if packet is going to be sent to ourself. */ 645 /* Check if packet is going to be sent to ourself. */
664 if (id_equal(public_key, dht->c->self_public_key)) 646 if (id_equal(public_key, dht->c->self_public_key))
665 return -1; 647 return -1;
666 648
667 size_t Node4_format_size = sizeof(Node4_format); 649 size_t Node4_format_size = sizeof(Node4_format);
668 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 650 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
669 + Node4_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; 651 + Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
670 652
671 Node_format nodes_list[MAX_SENT_NODES]; 653 Node_format nodes_list[MAX_SENT_NODES];
672 int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET, LAN_ip(ip_port.ip) == 0); 654 int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET, LAN_ip(ip_port.ip) == 0);
@@ -674,14 +656,12 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
674 if (num_nodes == 0) 656 if (num_nodes == 0)
675 return 0; 657 return 0;
676 658
677 uint8_t plain[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES]; 659 uint8_t plain[Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH];
678 uint8_t encrypt[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; 660 uint8_t encrypt[Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
679 uint8_t nonce[crypto_box_NONCEBYTES]; 661 uint8_t nonce[crypto_box_NONCEBYTES];
680 new_nonce(nonce); 662 new_nonce(nonce);
681 663
682 memcpy(plain, &ping_id, sizeof(ping_id)); 664 Node4_format *nodes4_list = (Node4_format *)(plain);
683
684 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
685 int i, num_nodes_ok = 0; 665 int i, num_nodes_ok = 0;
686 666
687 for (i = 0; i < num_nodes; i++) { 667 for (i = 0; i < num_nodes; i++) {
@@ -706,17 +686,16 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
706 num_nodes = num_nodes_ok; 686 num_nodes = num_nodes_ok;
707 } 687 }
708 688
689 memcpy(plain + num_nodes * Node4_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH);
709 int len = encrypt_data( public_key, 690 int len = encrypt_data( public_key,
710 dht->c->self_secret_key, 691 dht->c->self_secret_key,
711 nonce, 692 nonce,
712 plain, 693 plain,
713 sizeof(ping_id) + num_nodes * Node4_format_size, 694 num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH,
714 encrypt ); 695 encrypt );
715 696
716 if (len == -1) 697 if ((unsigned int)len != num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH +
717 return -1; 698 crypto_box_MACBYTES)
718
719 if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node4_format_size + ENCRYPTION_PADDING)
720 return -1; 699 return -1;
721 700
722 data[0] = NET_PACKET_SEND_NODES; 701 data[0] = NET_PACKET_SEND_NODES;
@@ -728,15 +707,15 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
728} 707}
729 708
730/* Send a send nodes response: message for IPv6 nodes */ 709/* Send a send nodes response: message for IPv6 nodes */
731static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) 710static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data)
732{ 711{
733 /* Check if packet is going to be sent to ourself. */ 712 /* Check if packet is going to be sent to ourself. */
734 if (id_equal(public_key, dht->c->self_public_key)) 713 if (id_equal(public_key, dht->c->self_public_key))
735 return -1; 714 return -1;
736 715
737 size_t Node_format_size = sizeof(Node_format); 716 size_t Node_format_size = sizeof(Node_format);
738 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 717 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
739 + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; 718 + Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
740 719
741 Node_format nodes_list[MAX_SENT_NODES]; 720 Node_format nodes_list[MAX_SENT_NODES];
742 int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET6, LAN_ip(ip_port.ip) == 0); 721 int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET6, LAN_ip(ip_port.ip) == 0);
@@ -744,25 +723,21 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
744 if (num_nodes == 0) 723 if (num_nodes == 0)
745 return 0; 724 return 0;
746 725
747 uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; 726 uint8_t plain[Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH];
748 uint8_t encrypt[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; 727 uint8_t encrypt[Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
749 uint8_t nonce[crypto_box_NONCEBYTES]; 728 uint8_t nonce[crypto_box_NONCEBYTES];
750 new_nonce(nonce); 729 new_nonce(nonce);
751 730
752 memcpy(plain, &ping_id, sizeof(ping_id)); 731 memcpy(plain, nodes_list, num_nodes * Node_format_size);
753 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node_format_size); 732 memcpy(plain + num_nodes * Node_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH);
754
755 int len = encrypt_data( public_key, 733 int len = encrypt_data( public_key,
756 dht->c->self_secret_key, 734 dht->c->self_secret_key,
757 nonce, 735 nonce,
758 plain, 736 plain,
759 sizeof(ping_id) + num_nodes * Node_format_size, 737 num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH,
760 encrypt ); 738 encrypt );
761 739
762 if (len == -1) 740 if ((unsigned int)len != num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES)
763 return -1;
764
765 if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node_format_size + ENCRYPTION_PADDING)
766 return -1; 741 return -1;
767 742
768 data[0] = NET_PACKET_SEND_NODES_IPV6; 743 data[0] = NET_PACKET_SEND_NODES_IPV6;
@@ -776,45 +751,77 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
776static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 751static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
777{ 752{
778 DHT *dht = object; 753 DHT *dht = object;
779 uint64_t ping_id;
780 754
781 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES 755 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH +
782 + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING )) 756 crypto_box_MACBYTES ))
783 return 1; 757 return 1;
784 758
785 /* Check if packet is from ourself. */ 759 /* Check if packet is from ourself. */
786 if (id_equal(packet + 1, dht->c->self_public_key)) 760 if (id_equal(packet + 1, dht->c->self_public_key))
787 return 1; 761 return 1;
788 762
789 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 763 uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH];
790 764
791 int len = decrypt_data( packet + 1, 765 int len = decrypt_data( packet + 1,
792 dht->c->self_secret_key, 766 dht->c->self_secret_key,
793 packet + 1 + CLIENT_ID_SIZE, 767 packet + 1 + CLIENT_ID_SIZE,
794 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 768 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
795 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, 769 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES,
796 plain ); 770 plain );
797 771
798 if (len != sizeof(ping_id) + CLIENT_ID_SIZE) 772 if (len != CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH)
799 return 1; 773 return 1;
800 774
801 memcpy(&ping_id, plain, sizeof(ping_id)); 775 sendnodes(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE);
802 sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); 776 sendnodes_ipv6(dht, source, packet + 1, plain,
803 sendnodes_ipv6(dht, source, packet + 1, plain + sizeof(ping_id), 777 plain + CLIENT_ID_SIZE); /* TODO: prevent possible amplification attacks */
804 ping_id); /* TODO: prevent possible amplification attacks */
805 778
806 add_toping(dht->ping, packet + 1, source); 779 add_toping(dht->ping, packet + 1, source);
807 //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ 780 //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */
808 781
809 return 0; 782 return 0;
810} 783}
784/* return 0 if no
785 return 1 if yes
786 encrypted_data must be of size NODES_ENCRYPTED_MESSAGE_LENGTH*/
787static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_ip_port, uint8_t *encrypted_data,
788 Node_format *sendback_node)
789{
790 uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH];
791
792 if (decrypt_data_symmetric(dht->secret_symmetric_key, encrypted_data, encrypted_data + crypto_secretbox_NONCEBYTES,
793 NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES,
794 plain_message) != sizeof(uint64_t) + sizeof(Node_format) * 2)
795 return 0;
796
797 uint64_t comp_time;
798 memcpy(&comp_time, plain_message, sizeof(uint64_t));
799 uint64_t temp_time = unix_time();
800
801 if (comp_time + PING_TIMEOUT < temp_time || temp_time < comp_time)
802 return 0;
803
804 Node_format test;
805 memcpy(&test, plain_message + sizeof(uint64_t), sizeof(Node_format));
806
807 if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.client_id, client_id, CLIENT_ID_SIZE) != 0)
808 return 0;
809
810 memcpy(sendback_node, plain_message + sizeof(uint64_t) + sizeof(Node_format), sizeof(Node_format));
811 return 1;
812}
813
814/* Function is needed in following functions. */
815static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes);
811 816
812static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet, uint32_t length, 817static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet, uint32_t length,
813 size_t node_format_size, uint8_t *plain, uint32_t *num_nodes_out) 818 size_t node_format_size, uint8_t *plain, uint16_t plain_length, uint32_t *num_nodes_out, Node_format *sendback_node)
814{ 819{
820 if (plain_length != MAX_SENT_NODES * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH)
821 return 1;
822
815 DHT *dht = object; 823 DHT *dht = object;
816 uint64_t ping_id; 824 uint32_t cid_size = 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES;
817 uint32_t cid_size = 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
818 825
819 if (length <= cid_size) /* too short */ 826 if (length <= cid_size) /* too short */
820 return 1; 827 return 1;
@@ -834,21 +841,17 @@ static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet,
834 dht->c->self_secret_key, 841 dht->c->self_secret_key,
835 packet + 1 + CLIENT_ID_SIZE, 842 packet + 1 + CLIENT_ID_SIZE,
836 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 843 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
837 sizeof(ping_id) + num_nodes * node_format_size + ENCRYPTION_PADDING, 844 num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES,
838 plain); 845 plain);
839 846
840 if ((unsigned int)len != sizeof(ping_id) + num_nodes * node_format_size) 847 if ((unsigned int)len != num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH)
841 return 1; 848 return 1;
842 849
843 memcpy(&ping_id, plain, sizeof(ping_id)); 850 if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * node_format_size, sendback_node))
844
845 int send_nodes_index = is_gettingnodes(dht, source, ping_id);
846
847 if (!send_nodes_index)
848 return 1; 851 return 1;
849 852
850 /* store the address the *request* was sent to */ 853 /* store the address the *request* was sent to */
851 addto_lists(dht, dht->send_nodes[send_nodes_index - 1].ip_port, packet + 1); 854 addto_lists(dht, source, packet + 1);
852 855
853 *num_nodes_out = num_nodes; 856 *num_nodes_out = num_nodes;
854 857
@@ -858,20 +861,24 @@ static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet,
858static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 861static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
859{ 862{
860 DHT *dht = object; 863 DHT *dht = object;
861 uint64_t ping_id;
862 size_t node4_format_size = sizeof(Node4_format); 864 size_t node4_format_size = sizeof(Node4_format);
863 uint8_t plain[sizeof(ping_id) + node4_format_size * MAX_SENT_NODES]; 865 uint8_t plain[node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH];
864 uint32_t num_nodes; 866 uint32_t num_nodes;
865 867
866 if (handle_sendnodes_core(object, source, packet, length, node4_format_size, plain, &num_nodes)) 868 Node_format sendback_node;
869
870 if (handle_sendnodes_core(object, source, packet, length, node4_format_size, plain, sizeof(plain), &num_nodes,
871 &sendback_node))
867 return 1; 872 return 1;
868 873
869 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); 874 Node4_format *nodes4_list = (Node4_format *)(plain);
870 uint32_t i; 875 uint32_t i;
871 876
872 IP_Port ipp; 877 IP_Port ipp;
873 ipp.ip.family = AF_INET; 878 ipp.ip.family = AF_INET;
874 879
880 Node_format nodes_list[MAX_SENT_NODES];
881
875 for (i = 0; i < num_nodes; i++) 882 for (i = 0; i < num_nodes; i++)
876 if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != (uint32_t)~0)) { 883 if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != (uint32_t)~0)) {
877 ipp.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32; 884 ipp.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32;
@@ -879,24 +886,31 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
879 886
880 send_ping_request(dht->ping, ipp, nodes4_list[i].client_id); 887 send_ping_request(dht->ping, ipp, nodes4_list[i].client_id);
881 returnedip_ports(dht, ipp, nodes4_list[i].client_id, packet + 1); 888 returnedip_ports(dht, ipp, nodes4_list[i].client_id, packet + 1);
889
890 memcpy(nodes_list[i].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE);
891 ipport_copy(&nodes_list[i].ip_port, &ipp);
882 } 892 }
883 893
894 send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes);
884 return 0; 895 return 0;
885} 896}
886 897
887static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length) 898static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length)
888{ 899{
889 DHT *dht = object; 900 DHT *dht = object;
890 uint64_t ping_id;
891 size_t node_format_size = sizeof(Node_format); 901 size_t node_format_size = sizeof(Node_format);
892 uint8_t plain[sizeof(ping_id) + node_format_size * MAX_SENT_NODES]; 902 uint8_t plain[node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH];
893 uint32_t num_nodes; 903 uint32_t num_nodes;
894 904
895 if (handle_sendnodes_core(object, source, packet, length, node_format_size, plain, &num_nodes)) 905 Node_format sendback_node;
906
907 if (handle_sendnodes_core(object, source, packet, length, node_format_size, plain, sizeof(plain), &num_nodes,
908 &sendback_node))
896 return 1; 909 return 1;
897 910
898 Node_format *nodes_list = (Node_format *)(plain + sizeof(ping_id)); 911 Node_format *nodes_list = (Node_format *)(plain);
899 uint32_t i; 912 uint32_t i;
913 send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes);
900 914
901 for (i = 0; i < num_nodes; i++) 915 for (i = 0; i < num_nodes; i++)
902 if (ipport_isset(&nodes_list[i].ip_port)) { 916 if (ipport_isset(&nodes_list[i].ip_port)) {
@@ -924,7 +938,7 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_
924 for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4) 938 for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4)
925 if (ipport_isset(&(assoc->ip_port)) && 939 if (ipport_isset(&(assoc->ip_port)) &&
926 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 940 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
927 getnodes(dht, assoc->ip_port, list[i].client_id, client_id); 941 getnodes(dht, assoc->ip_port, list[i].client_id, client_id, NULL);
928 ++num; 942 ++num;
929 943
930 if (num >= max_num) 944 if (num >= max_num)
@@ -1057,7 +1071,7 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8
1057 if ((num_nodes != 0) && is_timeout(*lastgetnode, GET_NODE_INTERVAL)) { 1071 if ((num_nodes != 0) && is_timeout(*lastgetnode, GET_NODE_INTERVAL)) {
1058 uint32_t rand_node = rand() % num_nodes; 1072 uint32_t rand_node = rand() % num_nodes;
1059 getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id, 1073 getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id,
1060 client_id); 1074 client_id, NULL);
1061 *lastgetnode = temp_time; 1075 *lastgetnode = temp_time;
1062 } 1076 }
1063} 1077}
@@ -1085,7 +1099,7 @@ static void do_Close(DHT *dht)
1085 1099
1086void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) 1100void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
1087{ 1101{
1088 getnodes(dht, ip_port, public_key, dht->c->self_public_key); 1102 getnodes(dht, ip_port, public_key, dht->c->self_public_key, NULL);
1089} 1103}
1090int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, 1104int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
1091 uint16_t port, uint8_t *public_key) 1105 uint16_t port, uint8_t *public_key)
@@ -1528,6 +1542,251 @@ static void do_NAT(DHT *dht)
1528/*----------------------------------------------------------------------------------*/ 1542/*----------------------------------------------------------------------------------*/
1529/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ 1543/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/
1530 1544
1545#define HARDREQ_DATA_SIZE 768 /* Attempt to prevent amplification/other attacks*/
1546
1547#define CHECK_TYPE_ROUTE_REQ 0
1548#define CHECK_TYPE_ROUTE_RES 1
1549#define CHECK_TYPE_GETNODE_REQ 2
1550#define CHECK_TYPE_GETNODE_RES 3
1551#define CHECK_TYPE_TEST_REQ 4
1552#define CHECK_TYPE_TEST_RES 5
1553
1554static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8_t *contents, uint16_t length)
1555{
1556 if (length > HARDREQ_DATA_SIZE - 1)
1557 return -1;
1558
1559 uint8_t packet[MAX_DATA_SIZE];
1560 uint8_t data[HARDREQ_DATA_SIZE] = {0};
1561 data[0] = type;
1562 memcpy(data + 1, contents, length);
1563 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data,
1564 sizeof(data), CRYPTO_PACKET_HARDENING);
1565
1566 if (len == -1)
1567 return -1;
1568
1569 return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len);
1570}
1571
1572/* Send a get node hardening request */
1573static int send_hardening_getnode_req(DHT *dht, Node_format *dest, Node_format *node_totest, uint8_t *search_id)
1574{
1575 uint8_t data[sizeof(Node_format) + CLIENT_ID_SIZE];
1576 memcpy(data, node_totest, sizeof(Node_format));
1577 memcpy(data + sizeof(Node_format), search_id, CLIENT_ID_SIZE);
1578 return send_hardening_req(dht, dest, CHECK_TYPE_GETNODE_REQ, data, sizeof(Node_format) + CLIENT_ID_SIZE);
1579}
1580
1581/* Send a get node hardening response */
1582static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes)
1583{
1584 if (!ip_isset(&sendto->ip_port.ip))
1585 return -1;
1586
1587 uint8_t packet[MAX_DATA_SIZE];
1588 uint8_t data[1 + num_nodes * sizeof(Node_format)];
1589 data[0] = CHECK_TYPE_GETNODE_RES;
1590 memcpy(data + 1, list, num_nodes * sizeof(Node_format));
1591 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data,
1592 sizeof(data), CRYPTO_PACKET_HARDENING);
1593
1594 if (len == -1)
1595 return -1;
1596
1597 return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len);
1598}
1599/*
1600 * check how many nodes in nodes are also present in the closelist.
1601 * TODO: make this function better.
1602 */
1603static int have_nodes_closelist(DHT *dht, Node_format *nodes, uint16_t num, sa_family_t sa_family)
1604{
1605 Node_format nodes_list[MAX_SENT_NODES];
1606 int num_nodes = get_close_nodes(dht, dht->c->self_public_key, nodes_list, sa_family, 1);
1607
1608 if (num_nodes < 1)
1609 return -1;
1610
1611 int counter = 0;
1612 uint32_t i, j;
1613
1614 for (i = 0; i < num; ++i) {
1615 if (id_equal(nodes[i].client_id, dht->c->self_public_key)) {
1616 ++counter;
1617 }
1618
1619 for (j = 0; j < (uint32_t)num_nodes; ++j) {
1620 if (id_equal(nodes[i].client_id, nodes_list[j].client_id)) {
1621 if (ipport_equal(&nodes[i].ip_port, &nodes_list[j].ip_port)) {
1622 ++counter;
1623 break;
1624 }
1625 }
1626 }
1627 }
1628
1629 return counter;
1630}
1631/* TODO: improve */
1632static IPPTsPng *get_closelist_IPPTsPng(DHT *dht, uint8_t *client_id, sa_family_t sa_family)
1633{
1634 uint32_t i;
1635
1636 for (i = 0; i < LCLIENT_LIST; ++i) {
1637 if (memcmp(dht->close_clientlist[i].client_id, client_id, CLIENT_ID_SIZE) != 0)
1638 continue;
1639
1640 if (sa_family == AF_INET)
1641 return &dht->close_clientlist[i].assoc4;
1642 else if (sa_family == AF_INET6)
1643 return &dht->close_clientlist[i].assoc6;
1644 }
1645
1646 return NULL;
1647}
1648
1649/* Interval in seconds between hardening checks */
1650#define HARDENING_INTERVAL 5
1651#define HARDEN_TIMEOUT 500
1652
1653/* Handle a received hardening packet */
1654static int handle_hardening(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
1655{
1656 DHT *dht = object;
1657
1658 if (length < 2) {
1659 return 1;
1660 }
1661
1662 switch (packet[0]) {
1663 case CHECK_TYPE_GETNODE_REQ: {
1664 if (length != HARDREQ_DATA_SIZE)
1665 return 1;
1666
1667 Node_format node, tocheck_node;
1668 node.ip_port = source;
1669 memcpy(node.client_id, source_pubkey, CLIENT_ID_SIZE);
1670 memcpy(&tocheck_node, packet + 1, sizeof(Node_format));
1671
1672 if (getnodes(dht, tocheck_node.ip_port, tocheck_node.client_id, packet + 1 + sizeof(Node_format), &node) == -1)
1673 return 1;
1674
1675 return 0;
1676 }
1677
1678 case CHECK_TYPE_GETNODE_RES: {
1679 if ((length - 1) % sizeof(Node_format) != 0)
1680 return 1;
1681
1682 uint16_t num = (length - 1) / sizeof(Node_format);
1683
1684 /* TODO: MAX_SENT_NODES nodes should be returned at all times
1685 (right now we have a small network size so it could cause problems for testing and etc..) */
1686 if (num > MAX_SENT_NODES || num == 0)
1687 return 1;
1688
1689 Node_format nodes[num];
1690 memcpy(nodes, packet + 1, sizeof(Node_format)*num);
1691
1692 /* NOTE: This should work for now but should be changed to something better. */
1693 if (have_nodes_closelist(dht, nodes, num, nodes[0].ip_port.ip.family) < (num + 1) / 2)
1694 return 1;
1695
1696
1697 IPPTsPng *temp = get_closelist_IPPTsPng(dht, source_pubkey, source.ip.family);
1698
1699 if (temp == NULL)
1700 return 1;
1701
1702 if (is_timeout(temp->hardening.send_nodes_timestamp, HARDENING_INTERVAL))
1703 return 1;
1704
1705 if (memcmp(temp->hardening.send_nodes_pingedid, source_pubkey, CLIENT_ID_SIZE) != 0)
1706 return 1;
1707
1708 /* If Nodes look good and the request checks out */
1709 temp->hardening.routes_requests_ok = 1;
1710 return 0;/* success*/
1711 }
1712 }
1713
1714 return 1;
1715}
1716
1717/* Return a random node from all the nodes we are connected to.
1718 * TODO: improve this function.
1719 */
1720Node_format random_node(DHT *dht, sa_family_t sa_family)
1721{
1722 uint8_t id[CLIENT_ID_SIZE];
1723 uint32_t i;
1724
1725 for (i = 0; i < CLIENT_ID_SIZE / 4; ++i) { /* populate the id with pseudorandom bytes.*/
1726 uint32_t t = rand();
1727 memcpy(id + i * sizeof(t), &t, sizeof(t));
1728 }
1729
1730 Node_format nodes_list[MAX_SENT_NODES];
1731 memset(nodes_list, 0, sizeof(nodes_list));
1732 int num_nodes = get_close_nodes(dht, id, nodes_list, sa_family, 1);
1733
1734 if (num_nodes < 1)
1735 return nodes_list[0];
1736 else
1737 return nodes_list[rand() % num_nodes];
1738}
1739
1740
1741void do_hardening(DHT *dht)
1742{
1743 uint32_t i;
1744
1745 for (i = 0; i < LCLIENT_LIST * 2; ++i) {
1746 IPPTsPng *cur_iptspng;
1747 sa_family_t sa_family;
1748 uint8_t *client_id = dht->close_clientlist[i / 2].client_id;
1749
1750 if (i % 2 == 0) {
1751 cur_iptspng = &dht->close_clientlist[i / 2].assoc4;
1752 sa_family = AF_INET;
1753 } else {
1754 cur_iptspng = &dht->close_clientlist[i / 2].assoc6;
1755 sa_family = AF_INET6;
1756 }
1757
1758 if (is_timeout(cur_iptspng->timestamp, BAD_NODE_TIMEOUT))
1759 continue;
1760
1761 if (cur_iptspng->hardening.send_nodes_ok == 0) {
1762 if (is_timeout(cur_iptspng->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) {
1763 Node_format rand_node = random_node(dht, sa_family);
1764
1765 if (!ipport_isset(&rand_node.ip_port))
1766 continue;
1767
1768 Node_format to_test;
1769 to_test.ip_port = cur_iptspng->ip_port;
1770 memcpy(to_test.client_id, client_id, CLIENT_ID_SIZE);
1771
1772 //TODO: The search id should maybe not be ours?
1773 if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->c->self_public_key) != -1) {
1774 memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.client_id, CLIENT_ID_SIZE);
1775 cur_iptspng->hardening.send_nodes_timestamp = unix_time();
1776 }
1777 }
1778 } else {
1779 if (is_timeout(cur_iptspng->hardening.send_nodes_timestamp, HARDEN_TIMEOUT)) {
1780 cur_iptspng->hardening.send_nodes_ok = 0;
1781 }
1782 }
1783
1784 //TODO: add the 2 other testers.
1785 }
1786}
1787
1788/*----------------------------------------------------------------------------------*/
1789
1531DHT *new_DHT(Net_Crypto *c) 1790DHT *new_DHT(Net_Crypto *c)
1532{ 1791{
1533 /* init time */ 1792 /* init time */
@@ -1552,10 +1811,11 @@ DHT *new_DHT(Net_Crypto *c)
1552 networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); 1811 networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
1553 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht); 1812 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht);
1554 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); 1813 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
1555
1556 init_cryptopackets(dht); 1814 init_cryptopackets(dht);
1557 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); 1815 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
1816 cryptopacket_registerhandler(c, CRYPTO_PACKET_HARDENING, &handle_hardening, dht);
1558 1817
1818 new_symmetric_key(dht->secret_symmetric_key);
1559 return dht; 1819 return dht;
1560} 1820}
1561 1821
@@ -1567,6 +1827,7 @@ void do_DHT(DHT *dht)
1567 do_DHT_friends(dht); 1827 do_DHT_friends(dht);
1568 do_NAT(dht); 1828 do_NAT(dht);
1569 do_toping(dht->ping); 1829 do_toping(dht->ping);
1830 do_hardening(dht);
1570} 1831}
1571void kill_DHT(DHT *dht) 1832void kill_DHT(DHT *dht)
1572{ 1833{
@@ -1575,82 +1836,11 @@ void kill_DHT(DHT *dht)
1575 free(dht); 1836 free(dht);
1576} 1837}
1577 1838
1578/* Get the size of the DHT (for saving). */
1579uint32_t DHT_size_old(DHT *dht)
1580{
1581 return sizeof(dht->close_clientlist) + sizeof(DHT_Friend) * dht->num_friends;
1582}
1583
1584/* Save the DHT in data where data is an array of size DHT_size(). */
1585void DHT_save_old(DHT *dht, uint8_t *data)
1586{
1587 memcpy(data, dht->close_clientlist, sizeof(dht->close_clientlist));
1588 memcpy(data + sizeof(dht->close_clientlist), dht->friends_list, sizeof(DHT_Friend) * dht->num_friends);
1589}
1590
1591/* Load the DHT from data of size size.
1592 *
1593 * return -1 if failure.
1594 * return 0 if success.
1595 */
1596int DHT_load_old(DHT *dht, uint8_t *data, uint32_t size)
1597{
1598 size_t clientlist_oldsize = sizeof(Client_data_old) * LCLIENT_LIST;
1599
1600 if (size < clientlist_oldsize) {
1601#ifdef DEBUG
1602 fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size);
1603#endif
1604 return -1;
1605 }
1606
1607 uint32_t friendlistsize = size - clientlist_oldsize;
1608
1609 if (friendlistsize % sizeof(DHT_Friend_old) != 0) {
1610#ifdef DEBUG
1611 fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize);
1612#endif
1613 return -1;
1614 }
1615
1616 uint32_t i, j;
1617 Client_data_old *client;
1618 uint16_t friends_num = friendlistsize / sizeof(DHT_Friend_old);
1619
1620 if (friends_num != 0) {
1621 DHT_Friend_old *tempfriends_list = (DHT_Friend_old *)(data + sizeof(dht->close_clientlist));
1622
1623 for (i = 0; i < friends_num; ++i) {
1624 DHT_addfriend(dht, tempfriends_list[i].client_id);
1625
1626 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1627 client = &tempfriends_list[i].client_list[j];
1628
1629 if (client->assoc.timestamp != 0)
1630 getnodes(dht, client->assoc.ip_port, client->client_id, tempfriends_list[i].client_id);
1631 }
1632 }
1633 }
1634
1635 Client_data_old *tempclose_clientlist = (Client_data_old *)data;
1636
1637 for (i = 0; i < LCLIENT_LIST; ++i) {
1638 if (tempclose_clientlist[i].assoc.timestamp != 0)
1639 DHT_bootstrap(dht, tempclose_clientlist[i].assoc.ip_port,
1640 tempclose_clientlist[i].client_id );
1641 }
1642
1643 return 0;
1644}
1645
1646
1647/* new DHT format for load/save, more robust and forward compatible */ 1839/* new DHT format for load/save, more robust and forward compatible */
1648 1840
1649#define DHT_STATE_COOKIE_GLOBAL 0x159000d 1841#define DHT_STATE_COOKIE_GLOBAL 0x159000d
1650 1842
1651#define DHT_STATE_COOKIE_TYPE 0x11ce 1843#define DHT_STATE_COOKIE_TYPE 0x11ce
1652#define DHT_STATE_TYPE_FRIENDS 1
1653#define DHT_STATE_TYPE_CLIENTS 2
1654#define DHT_STATE_TYPE_FRIENDS_ASSOC46 3 1844#define DHT_STATE_TYPE_FRIENDS_ASSOC46 3
1655#define DHT_STATE_TYPE_CLIENTS_ASSOC46 4 1845#define DHT_STATE_TYPE_CLIENTS_ASSOC46 4
1656 1846
@@ -1722,43 +1912,6 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length,
1722 uint32_t num, i, j; 1912 uint32_t num, i, j;
1723 1913
1724 switch (type) { 1914 switch (type) {
1725 case DHT_STATE_TYPE_FRIENDS:
1726 if (length % sizeof(DHT_Friend_old) != 0)
1727 break;
1728
1729 { /* localize declarations */
1730 DHT_Friend_old *friend_list = (DHT_Friend_old *)data;
1731 num = length / sizeof(DHT_Friend_old);
1732
1733 for (i = 0; i < num; ++i) {
1734 DHT_addfriend(dht, friend_list[i].client_id);
1735
1736 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1737 Client_data_old *client = &friend_list[i].client_list[j];
1738
1739 if (client->assoc.timestamp != 0)
1740 getnodes(dht, client->assoc.ip_port, client->client_id, friend_list[i].client_id);
1741 }
1742 }
1743 } /* localize declarations */
1744
1745 break;
1746
1747 case DHT_STATE_TYPE_CLIENTS:
1748 if ((length % sizeof(Client_data_old)) != 0)
1749 break;
1750
1751 { /* localize declarations */
1752 num = length / sizeof(Client_data_old);
1753 Client_data_old *client_list = (Client_data_old *)data;
1754
1755 for (i = 0; i < num; ++i)
1756 if (client_list[i].assoc.timestamp != 0)
1757 DHT_bootstrap(dht, client_list[i].assoc.ip_port, client_list[i].client_id);
1758 } /* localize declarations */
1759
1760 break;
1761
1762 case DHT_STATE_TYPE_FRIENDS_ASSOC46: 1915 case DHT_STATE_TYPE_FRIENDS_ASSOC46:
1763 if (length % sizeof(DHT_Friend) != 0) 1916 if (length % sizeof(DHT_Friend) != 0)
1764 break; 1917 break;
@@ -1774,10 +1927,10 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length,
1774 Client_data *client = &friend_list[i].client_list[j]; 1927 Client_data *client = &friend_list[i].client_list[j];
1775 1928
1776 if (client->assoc4.timestamp != 0) 1929 if (client->assoc4.timestamp != 0)
1777 getnodes(dht, client->assoc4.ip_port, client->client_id, friend_list[i].client_id); 1930 getnodes(dht, client->assoc4.ip_port, client->client_id, friend_list[i].client_id, NULL);
1778 1931
1779 if (client->assoc6.timestamp != 0) 1932 if (client->assoc6.timestamp != 0)
1780 getnodes(dht, client->assoc6.ip_port, client->client_id, friend_list[i].client_id); 1933 getnodes(dht, client->assoc6.ip_port, client->client_id, friend_list[i].client_id, NULL);
1781 } 1934 }
1782 } 1935 }
1783 } /* localize declarations */ 1936 } /* localize declarations */
@@ -1832,7 +1985,7 @@ int DHT_load_new(DHT *dht, uint8_t *data, uint32_t length)
1832 length - cookie_len, DHT_STATE_COOKIE_TYPE); 1985 length - cookie_len, DHT_STATE_COOKIE_TYPE);
1833 } 1986 }
1834 1987
1835 return DHT_load_old(dht, data, length); 1988 return -1;
1836} 1989}
1837/* return 0 if we are not connected to the DHT. 1990/* return 0 if we are not connected to the DHT.
1838 * return 1 if we are. 1991 * return 1 if we are.