diff options
author | Coren[m] <Break@Ocean> | 2013-11-06 14:50:46 +0100 |
---|---|---|
committer | Coren[m] <Break@Ocean> | 2013-11-06 14:50:55 +0100 |
commit | aee50435c849058c658f1a33486faea3d0fa0e3e (patch) | |
tree | 9fc4ddd35906adc9cda9ce6f115f104175db8724 /toxcore/DHT.c | |
parent | 71f7a4940247db6fd1b6f74418fd775f0f4c2bd3 (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.c | 42 |
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 | */ | ||
573 | static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) | 581 | static 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); |