summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
authorCoren[m] <Break@Ocean>2013-11-06 14:50:46 +0100
committerCoren[m] <Break@Ocean>2013-11-06 14:50:55 +0100
commitaee50435c849058c658f1a33486faea3d0fa0e3e (patch)
tree9fc4ddd35906adc9cda9ce6f115f104175db8724 /toxcore/DHT.c
parent71f7a4940247db6fd1b6f74418fd775f0f4c2bd3 (diff)
addto_lists(): store the IP/Port that was used to *send*.
Avoids a DOS of sending a copy of a valid response with an invalid IP.
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index c286567f..12f38f18 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
@@ -570,25 +572,26 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint
570 } 572 }
571} 573}
572 574
575/* checks if ip/port or ping_id are already in the list to get nodes
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 */
573static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) 581static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id)
574{ 582{
575 uint32_t i; 583 uint8_t ip_valid = ip_isset(&ip_port.ip);
576 uint8_t pinging;
577 584
578 for (i = 0; i < LSEND_NODES_ARRAY; ++i ) { 585 if (!ip_valid && !ping_id)
579 if (!is_timeout(dht->send_nodes[i].timestamp, PING_TIMEOUT)) { 586 return 0;
580 pinging = 0;
581
582 if (ping_id != 0 && dht->send_nodes[i].id == ping_id)
583 ++pinging;
584 587
585 if (ip_isset(&ip_port.ip) && ipport_equal(&dht->send_nodes[i].ip_port, &ip_port)) 588 uint32_t i;
586 ++pinging;
587 589
588 if (pinging == (ping_id != 0) + ip_isset(&ip_port.ip)) 590 for (i = 0; i < LSEND_NODES_ARRAY; i++)
589 return 1; 591 if (!is_timeout(dht->send_nodes[i].timestamp, PING_TIMEOUT))
590 } 592 if (!ping_id || (dht->send_nodes[i].id == ping_id))
591 } 593 if (!ip_valid || ipport_equal(&dht->send_nodes[i].ip_port, &ip_port))
594 return i + 1;
592 595
593 return 0; 596 return 0;
594} 597}
@@ -835,7 +838,9 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
835 838
836 memcpy(&ping_id, plain, sizeof(ping_id)); 839 memcpy(&ping_id, plain, sizeof(ping_id));
837 840
838 if (!is_gettingnodes(dht, source, ping_id)) 841 int send_nodes_index = is_gettingnodes(dht, source, ping_id);
842
843 if (!send_nodes_index)
839 return 1; 844 return 1;
840 845
841 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); 846 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
@@ -858,7 +863,8 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
858 num_nodes = num_nodes_ok; 863 num_nodes = num_nodes_ok;
859 } 864 }
860 865
861 addto_lists(dht, source, packet + 1); 866 /* store the address the *request* was sent to */
867 addto_lists(dht, dht->send_nodes[send_nodes_index - 1].ip_port, packet + 1);
862 868
863 for (i = 0; i < num_nodes; ++i) { 869 for (i = 0; i < num_nodes; ++i) {
864 send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id); 870 send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id);
@@ -1193,12 +1199,15 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
1193 1199
1194#ifdef FRIEND_IPLIST_PAD 1200#ifdef FRIEND_IPLIST_PAD
1195 memcpy(ip_portlist, ipv6s, num_ipv6s * sizeof(IP_Port)); 1201 memcpy(ip_portlist, ipv6s, num_ipv6s * sizeof(IP_Port));
1202
1196 if (num_ipv6s == MAX_FRIEND_CLIENTS) 1203 if (num_ipv6s == MAX_FRIEND_CLIENTS)
1197 return MAX_FRIEND_CLIENTS; 1204 return MAX_FRIEND_CLIENTS;
1198 1205
1199 int num_ipv4s_used = MAX_FRIEND_CLIENTS - num_ipv6s; 1206 int num_ipv4s_used = MAX_FRIEND_CLIENTS - num_ipv6s;
1207
1200 if (num_ipv4s_used > num_ipv4s) 1208 if (num_ipv4s_used > num_ipv4s)
1201 num_ipv4s_used = num_ipv4s; 1209 num_ipv4s_used = num_ipv4s;
1210
1202 memcpy(&ip_portlist[num_ipv6s], ipv4s, num_ipv4s_used * sizeof(IP_Port)); 1211 memcpy(&ip_portlist[num_ipv6s], ipv4s, num_ipv4s_used * sizeof(IP_Port));
1203 return num_ipv6s + num_ipv4s_used; 1212 return num_ipv6s + num_ipv4s_used;
1204 1213
@@ -1808,6 +1817,7 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length,
1808 break; 1817 break;
1809 1818
1810#ifdef DEBUG 1819#ifdef DEBUG
1820
1811 default: 1821 default:
1812 fprintf(stderr, "Load state (DHT): contains unrecognized part (len %u, type %u)\n", 1822 fprintf(stderr, "Load state (DHT): contains unrecognized part (len %u, type %u)\n",
1813 length, type); 1823 length, type);