summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c119
1 files changed, 56 insertions, 63 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index c286567f..3ce2fe84 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -120,6 +120,7 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id
120 uint32_t i; 120 uint32_t i;
121 121
122 for (i = 0; i < length; i++) 122 for (i = 0; i < length; i++)
123
123 /* Dead nodes are considered dead (not in the list)*/ 124 /* Dead nodes are considered dead (not in the list)*/
124 if (!is_timeout(list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) || 125 if (!is_timeout(list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) ||
125 !is_timeout(list[i].assoc6.timestamp, KILL_NODE_TIMEOUT)) 126 !is_timeout(list[i].assoc6.timestamp, KILL_NODE_TIMEOUT))
@@ -278,6 +279,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
278 continue; 279 continue;
279 280
280 IPPTsPng *ipptp = NULL; 281 IPPTsPng *ipptp = NULL;
282
281 if (sa_family == AF_INET) 283 if (sa_family == AF_INET)
282 ipptp = &client->assoc4; 284 ipptp = &client->assoc4;
283 else 285 else
@@ -806,31 +808,35 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32
806 return 0; 808 return 0;
807} 809}
808 810
809static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 811static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet, uint32_t length,
812 size_t node_format_size, uint8_t *plain, uint32_t *num_nodes_out)
810{ 813{
811 DHT *dht = object; 814 DHT *dht = object;
812 uint64_t ping_id; 815 uint64_t ping_id;
813 uint32_t cid_size = 1 + CLIENT_ID_SIZE; 816 uint32_t cid_size = 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
814 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
815 817
816 size_t Node4_format_size = sizeof(Node4_format); 818 if (length <= cid_size) /* too short */
819 return 1;
820
821 uint32_t data_size = length - cid_size;
817 822
818 if (length > (cid_size + Node4_format_size * MAX_SENT_NODES) || 823 if ((data_size % node_format_size) != 0) /* invalid length */
819 ((length - cid_size) % Node4_format_size) != 0 ||
820 (length < cid_size + Node4_format_size))
821 return 1; 824 return 1;
822 825
823 uint32_t num_nodes = (length - cid_size) / Node4_format_size; 826 uint32_t num_nodes = data_size / node_format_size;
824 uint8_t plain[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES]; 827
828 if (num_nodes > MAX_SENT_NODES) /* too long */
829 return 1;
825 830
826 int len = decrypt_data( 831 int len = decrypt_data(
827 packet + 1, 832 packet + 1,
828 dht->c->self_secret_key, 833 dht->c->self_secret_key,
829 packet + 1 + CLIENT_ID_SIZE, 834 packet + 1 + CLIENT_ID_SIZE,
830 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 835 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
831 sizeof(ping_id) + num_nodes * Node4_format_size + ENCRYPTION_PADDING, plain ); 836 sizeof(ping_id) + num_nodes * node_format_size + ENCRYPTION_PADDING,
837 plain);
832 838
833 if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node4_format_size) 839 if ((unsigned int)len != sizeof(ping_id) + num_nodes * node_format_size)
834 return 1; 840 return 1;
835 841
836 memcpy(&ping_id, plain, sizeof(ping_id)); 842 memcpy(&ping_id, plain, sizeof(ping_id));
@@ -838,78 +844,61 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
838 if (!is_gettingnodes(dht, source, ping_id)) 844 if (!is_gettingnodes(dht, source, ping_id))
839 return 1; 845 return 1;
840 846
841 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
842 Node_format nodes_list[MAX_SENT_NODES];
843 uint32_t i, num_nodes_ok = 0;
844
845 /* blow up from Node4 (IPv4) wire format to Node (IPv4/IPv6) structure */
846 for (i = 0; i < num_nodes; i++)
847 if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != (uint32_t)~0)) {
848 memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE);
849 nodes_list[num_nodes_ok].ip_port.ip.family = AF_INET;
850 nodes_list[num_nodes_ok].ip_port.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32;
851 nodes_list[num_nodes_ok].ip_port.port = nodes4_list[i].ip_port.port;
852
853 num_nodes_ok++;
854 }
855
856 if (num_nodes_ok < num_nodes) {
857 /* shouldn't happen */
858 num_nodes = num_nodes_ok;
859 }
860
861 addto_lists(dht, source, packet + 1); 847 addto_lists(dht, source, packet + 1);
862 848
863 for (i = 0; i < num_nodes; ++i) { 849 *num_nodes_out = num_nodes;
864 send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id);
865 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
866 }
867 850
868 return 0; 851 return 0;
869} 852}
870 853
871static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length) 854static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
872{ 855{
873 DHT *dht = object; 856 DHT *dht = object;
874 uint64_t ping_id; 857 uint64_t ping_id;
875 uint32_t cid_size = 1 + CLIENT_ID_SIZE; 858 size_t node4_format_size = sizeof(Node4_format);
876 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; 859 uint8_t plain[sizeof(ping_id) + node4_format_size * MAX_SENT_NODES];
877 860 uint32_t num_nodes;
878 size_t Node_format_size = sizeof(Node_format);
879 861
880 if (length > (cid_size + Node_format_size * MAX_SENT_NODES) || 862 if (handle_sendnodes_core(object, source, packet, length, node4_format_size, plain, &num_nodes))
881 ((length - cid_size) % Node_format_size) != 0 ||
882 (length < cid_size + Node_format_size))
883 return 1; 863 return 1;
884 864
885 uint32_t num_nodes = (length - cid_size) / Node_format_size; 865 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
886 uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; 866 uint32_t i;
887 867
888 int len = decrypt_data( 868 IP_Port ipp;
889 packet + 1, 869 ipp.ip.family = AF_INET;
890 dht->c->self_secret_key,
891 packet + 1 + CLIENT_ID_SIZE,
892 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
893 sizeof(ping_id) + num_nodes * Node_format_size + ENCRYPTION_PADDING, plain );
894 870
895 if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node_format_size) 871 for (i = 0; i < num_nodes; i++)
896 return 1; 872 if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != (uint32_t)~0)) {
873 ipp.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32;
874 ipp.port = nodes4_list[i].ip_port.port;
897 875
898 memcpy(&ping_id, plain, sizeof(ping_id)); 876 send_ping_request(dht->ping, ipp, nodes4_list[i].client_id);
877 returnedip_ports(dht, ipp, nodes4_list[i].client_id, packet + 1);
878 }
899 879
900 if (!is_gettingnodes(dht, source, ping_id)) 880 return 0;
881}
882
883static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length)
884{
885 DHT *dht = object;
886 uint64_t ping_id;
887 size_t node_format_size = sizeof(Node_format);
888 uint8_t plain[sizeof(ping_id) + node_format_size * MAX_SENT_NODES];
889 uint32_t num_nodes;
890
891 if (handle_sendnodes_core(object, source, packet, length, node_format_size, plain, &num_nodes))
901 return 1; 892 return 1;
902 893
894 Node_format *nodes_list = (Node_format *)(plain + sizeof(ping_id));
903 uint32_t i; 895 uint32_t i;
904 Node_format nodes_list[MAX_SENT_NODES];
905 memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format));
906
907 addto_lists(dht, source, packet + 1);
908 896
909 for (i = 0; i < num_nodes; ++i) { 897 for (i = 0; i < num_nodes; i++)
910 send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id); 898 if (ipport_isset(&nodes_list[i].ip_port)) {
911 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 899 send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id);
912 } 900 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
901 }
913 902
914 return 0; 903 return 0;
915} 904}
@@ -1193,12 +1182,15 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
1193 1182
1194#ifdef FRIEND_IPLIST_PAD 1183#ifdef FRIEND_IPLIST_PAD
1195 memcpy(ip_portlist, ipv6s, num_ipv6s * sizeof(IP_Port)); 1184 memcpy(ip_portlist, ipv6s, num_ipv6s * sizeof(IP_Port));
1185
1196 if (num_ipv6s == MAX_FRIEND_CLIENTS) 1186 if (num_ipv6s == MAX_FRIEND_CLIENTS)
1197 return MAX_FRIEND_CLIENTS; 1187 return MAX_FRIEND_CLIENTS;
1198 1188
1199 int num_ipv4s_used = MAX_FRIEND_CLIENTS - num_ipv6s; 1189 int num_ipv4s_used = MAX_FRIEND_CLIENTS - num_ipv6s;
1190
1200 if (num_ipv4s_used > num_ipv4s) 1191 if (num_ipv4s_used > num_ipv4s)
1201 num_ipv4s_used = num_ipv4s; 1192 num_ipv4s_used = num_ipv4s;
1193
1202 memcpy(&ip_portlist[num_ipv6s], ipv4s, num_ipv4s_used * sizeof(IP_Port)); 1194 memcpy(&ip_portlist[num_ipv6s], ipv4s, num_ipv4s_used * sizeof(IP_Port));
1203 return num_ipv6s + num_ipv4s_used; 1195 return num_ipv6s + num_ipv4s_used;
1204 1196
@@ -1808,6 +1800,7 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length,
1808 break; 1800 break;
1809 1801
1810#ifdef DEBUG 1802#ifdef DEBUG
1803
1811 default: 1804 default:
1812 fprintf(stderr, "Load state (DHT): contains unrecognized part (len %u, type %u)\n", 1805 fprintf(stderr, "Load state (DHT): contains unrecognized part (len %u, type %u)\n",
1813 length, type); 1806 length, type);