diff options
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r-- | toxcore/DHT.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 085f93ed..2a5b03a4 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "ping.h" | 32 | #include "ping.h" |
33 | #include "misc_tools.h" | 33 | #include "misc_tools.h" |
34 | #include "Messenger.h" | 34 | #include "Messenger.h" |
35 | #include "util.h" | ||
35 | 36 | ||
36 | /* The number of seconds for a non responsive node to become bad. */ | 37 | /* The number of seconds for a non responsive node to become bad. */ |
37 | #define BAD_NODE_TIMEOUT 70 | 38 | #define BAD_NODE_TIMEOUT 70 |
@@ -215,15 +216,25 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list | |||
215 | * sent anyways for backwards compatibility) | 216 | * sent anyways for backwards compatibility) |
216 | * we COULD send ALL as NET_PACKET_SEND_NODES_EX if we KNEW that the | 217 | * we COULD send ALL as NET_PACKET_SEND_NODES_EX if we KNEW that the |
217 | * partner node understands - that's true if *they* are on IPv6 | 218 | * partner node understands - that's true if *they* are on IPv6 |
219 | * | ||
220 | * Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for | ||
221 | * our connections, instead we have to look if it is an embedded | ||
222 | * IPv4-in-IPv6 here and convert it down in sendnodes(). | ||
218 | */ | 223 | */ |
219 | #ifdef TOX_ENABLE_IPV6 | 224 | #ifdef TOX_ENABLE_IPV6 |
220 | ipv46x = 0; | 225 | IP *client_ip = &dht->close_clientlist[i].ip_port.ip; |
221 | if (sa_family == AF_INET) | 226 | sa_family_t ip_treat_as_family = client_ip->family; |
222 | ipv46x = dht->close_clientlist[i].ip_port.ip.family != AF_INET; | 227 | if ((dht->c->lossless_udp->net->family == AF_INET6) && |
223 | else | 228 | (client_ip->family == AF_INET6)) { |
224 | ipv46x = dht->close_clientlist[i].ip_port.ip.family == AF_INET; | 229 | /* socket is AF_INET6, address claims AF_INET6: |
230 | * check for embedded IPv4-in-IPv6 */ | ||
231 | if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6)) | ||
232 | ip_treat_as_family = AF_INET; | ||
233 | } | ||
234 | |||
235 | ipv46x = !(sa_family == ip_treat_as_family); | ||
225 | #else | 236 | #else |
226 | ipv46x = sa_family != AF_INET; | 237 | ipv46x = !(sa_family == AF_INET); |
227 | #endif | 238 | #endif |
228 | 239 | ||
229 | /* If node isn't good or is already in list. */ | 240 | /* If node isn't good or is already in list. */ |
@@ -267,11 +278,17 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list | |||
267 | dht->friends_list[i].client_list[j].client_id); | 278 | dht->friends_list[i].client_list[j].client_id); |
268 | 279 | ||
269 | #ifdef TOX_ENABLE_IPV6 | 280 | #ifdef TOX_ENABLE_IPV6 |
270 | ipv46x = 0; | 281 | IP *client_ip = &dht->friends_list[i].client_list[j].ip_port.ip; |
271 | if (sa_family == AF_INET) | 282 | sa_family_t ip_treat_as_family = client_ip->family; |
272 | ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family != AF_INET; | 283 | if ((dht->c->lossless_udp->net->family == AF_INET6) && |
273 | else | 284 | (client_ip->family == AF_INET6)) { |
274 | ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family == AF_INET; | 285 | /* socket is AF_INET6, address claims AF_INET6: |
286 | * check for embedded IPv4-in-IPv6 */ | ||
287 | if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6)) | ||
288 | ip_treat_as_family = AF_INET; | ||
289 | } | ||
290 | |||
291 | ipv46x = !(sa_family == ip_treat_as_family); | ||
275 | #else | 292 | #else |
276 | ipv46x = sa_family != AF_INET; | 293 | ipv46x = sa_family != AF_INET; |
277 | #endif | 294 | #endif |
@@ -578,14 +595,21 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl | |||
578 | #ifdef TOX_ENABLE_IPV6 | 595 | #ifdef TOX_ENABLE_IPV6 |
579 | Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); | 596 | Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); |
580 | int i, num_nodes_ok = 0; | 597 | int i, num_nodes_ok = 0; |
581 | for(i = 0; i < num_nodes; i++) | 598 | for(i = 0; i < num_nodes; i++) { |
582 | if (nodes_list[i].ip_port.ip.family == AF_INET) { | 599 | memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); |
583 | memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); | 600 | nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; |
584 | nodes4_list[num_nodes_ok].ip_port.ip.uint32 = nodes_list[i].ip_port.ip.ip4.uint32; | 601 | |
585 | nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; | 602 | IP *node_ip = &nodes_list[i].ip_port.ip; |
603 | if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6)) | ||
604 | /* embedded IPv4-in-IPv6 address: return it in regular sendnodes packet */ | ||
605 | nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip6.s6_addr32[3]; | ||
606 | else if (node_ip->family == AF_INET) | ||
607 | nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip4.uint32; | ||
608 | else /* shouldn't happen */ | ||
609 | continue; | ||
586 | 610 | ||
587 | num_nodes_ok++; | 611 | num_nodes_ok++; |
588 | } | 612 | } |
589 | 613 | ||
590 | if (num_nodes_ok < num_nodes) { | 614 | if (num_nodes_ok < num_nodes) { |
591 | /* shouldn't happen */ | 615 | /* shouldn't happen */ |
@@ -1461,13 +1485,13 @@ void DHT_save(DHT *dht, uint8_t *data) | |||
1461 | int DHT_load(DHT *dht, uint8_t *data, uint32_t size) | 1485 | int DHT_load(DHT *dht, uint8_t *data, uint32_t size) |
1462 | { | 1486 | { |
1463 | if (size < sizeof(dht->close_clientlist)) { | 1487 | if (size < sizeof(dht->close_clientlist)) { |
1464 | fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size); | 1488 | fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size); |
1465 | return -1; | 1489 | return -1; |
1466 | } | 1490 | } |
1467 | 1491 | ||
1468 | uint32_t friendlistsize = size - sizeof(dht->close_clientlist); | 1492 | uint32_t friendlistsize = size - sizeof(dht->close_clientlist); |
1469 | if (friendlistsize % sizeof(DHT_Friend) != 0) { | 1493 | if (friendlistsize % sizeof(DHT_Friend) != 0) { |
1470 | fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize); | 1494 | fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize); |
1471 | return -1; | 1495 | return -1; |
1472 | } | 1496 | } |
1473 | 1497 | ||