summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-09-13 17:08:54 -0400
committerirungentoo <irungentoo@gmail.com>2013-09-14 12:41:14 -0400
commit64d000cdfaed710d3e22fa5444b8c2883b9f09d6 (patch)
tree591157a8f430636eda3897561e4191131fb77fa8 /toxcore/DHT.c
parent36e5636406c019390f96c2a02c17c850143d21b9 (diff)
Some fixes.
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c165
1 files changed, 90 insertions, 75 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 8557a5e0..df3b2f76 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -31,7 +31,6 @@
31#include "network.h" 31#include "network.h"
32#include "ping.h" 32#include "ping.h"
33#include "misc_tools.h" 33#include "misc_tools.h"
34#include "Messenger.h"
35#include "util.h" 34#include "util.h"
36 35
37/* The number of seconds for a non responsive node to become bad. */ 36/* The number of seconds for a non responsive node to become bad. */
@@ -197,73 +196,75 @@ static int friend_number(DHT *dht, uint8_t *client_id)
197 * helper for get_close_nodes(). argument list is a monster :D 196 * helper for get_close_nodes(). argument list is a monster :D
198 */ 197 */
199static int get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list, 198static int get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list,
200 sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, 199 sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length,
201 time_t timestamp, int *num_nodes_ptr) 200 time_t timestamp, int *num_nodes_ptr)
202{ 201{
203 int num_nodes = 0; 202 int num_nodes = 0;
204 int i, tout, inlist, ipv46x, j, closest; 203 int i, tout, inlist, ipv46x, j, closest;
205 for(i = 0; i < client_list_length; i++) { 204
206 Client_data *client = &client_list[i]; 205 for (i = 0; i < client_list_length; i++) {
207 tout = is_timeout(timestamp, client->timestamp, BAD_NODE_TIMEOUT); 206 Client_data *client = &client_list[i];
208 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, client->client_id); 207 tout = is_timeout(timestamp, client->timestamp, BAD_NODE_TIMEOUT);
208 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, client->client_id);
209 209
210#ifdef TOX_ENABLE_IPV6 210#ifdef TOX_ENABLE_IPV6
211 IP *client_ip = &client->ip_port.ip; 211 IP *client_ip = &client->ip_port.ip;
212 212
213 /* 213 /*
214 * Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for 214 * Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for
215 * our connections, instead we have to look if it is an embedded 215 * our connections, instead we have to look if it is an embedded
216 * IPv4-in-IPv6 here and convert it down in sendnodes(). 216 * IPv4-in-IPv6 here and convert it down in sendnodes().
217 */ 217 */
218 sa_family_t ip_treat_as_family = client_ip->family; 218 sa_family_t ip_treat_as_family = client_ip->family;
219 if ((dht->c->lossless_udp->net->family == AF_INET6) && 219
220 (client_ip->family == AF_INET6)) { 220 if ((dht->c->lossless_udp->net->family == AF_INET6) &&
221 /* socket is AF_INET6, address claims AF_INET6: 221 (client_ip->family == AF_INET6)) {
222 * check for embedded IPv4-in-IPv6 */ 222 /* socket is AF_INET6, address claims AF_INET6:
223 if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6)) 223 * check for embedded IPv4-in-IPv6 */
224 ip_treat_as_family = AF_INET; 224 if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6))
225 } 225 ip_treat_as_family = AF_INET;
226 226 }
227 ipv46x = !(sa_family == ip_treat_as_family); 227
228 ipv46x = !(sa_family == ip_treat_as_family);
228#else 229#else
229 ipv46x = !(sa_family == AF_INET); 230 ipv46x = !(sa_family == AF_INET);
230#endif 231#endif
231 232
232 /* If node isn't good or is already in list. */ 233 /* If node isn't good or is already in list. */
233 if (tout || inlist || ipv46x) 234 if (tout || inlist || ipv46x)
234 continue; 235 continue;
235 236
236 if (num_nodes < MAX_SENT_NODES) { 237 if (num_nodes < MAX_SENT_NODES) {
237 memcpy(nodes_list[num_nodes].client_id, 238 memcpy(nodes_list[num_nodes].client_id,
238 client->client_id, 239 client->client_id,
239 CLIENT_ID_SIZE ); 240 CLIENT_ID_SIZE );
240 241
241 nodes_list[num_nodes].ip_port = client->ip_port; 242 nodes_list[num_nodes].ip_port = client->ip_port;
242 num_nodes++; 243 num_nodes++;
243 } else { 244 } else {
244 /* see if node_list contains a client_id that's "further away" 245 /* see if node_list contains a client_id that's "further away"
245 * compared to the one we're looking at at the moment, if there 246 * compared to the one we're looking at at the moment, if there
246 * is, replace it 247 * is, replace it
247 */ 248 */
248 for (j = 0; j < MAX_SENT_NODES; ++j) { 249 for (j = 0; j < MAX_SENT_NODES; ++j) {
249 closest = id_closest( client_id, 250 closest = id_closest( client_id,
250 nodes_list[j].client_id, 251 nodes_list[j].client_id,
251 client->client_id ); 252 client->client_id );
252 253
253 /* second client_id is closer than current: change to it */ 254 /* second client_id is closer than current: change to it */
254 if (closest == 2) { 255 if (closest == 2) {
255 memcpy( nodes_list[j].client_id, 256 memcpy( nodes_list[j].client_id,
256 client->client_id, 257 client->client_id,
257 CLIENT_ID_SIZE); 258 CLIENT_ID_SIZE);
258 259
259 nodes_list[j].ip_port = client->ip_port; 260 nodes_list[j].ip_port = client->ip_port;
260 break; 261 break;
261 } 262 }
262 } 263 }
263 } 264 }
264 } 265 }
265 266
266 *num_nodes_ptr = num_nodes; 267 *num_nodes_ptr = num_nodes;
267} 268}
268 269
269/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: 270/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request:
@@ -274,15 +275,15 @@ static int get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *node
274 */ 275 */
275static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family) 276static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family)
276{ 277{
277 time_t timestamp = unix_time(); 278 time_t timestamp = unix_time();
278 int num_nodes = 0, i; 279 int num_nodes = 0, i;
279 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 280 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
280 dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes); 281 dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes);
281 282
282 for (i = 0; i < dht->num_friends; ++i) 283 for (i = 0; i < dht->num_friends; ++i)
283 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 284 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
284 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, 285 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
285 timestamp, &num_nodes); 286 timestamp, &num_nodes);
286 287
287 return num_nodes; 288 return num_nodes;
288} 289}
@@ -554,11 +555,13 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
554#ifdef TOX_ENABLE_IPV6 555#ifdef TOX_ENABLE_IPV6
555 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); 556 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
556 int i, num_nodes_ok = 0; 557 int i, num_nodes_ok = 0;
557 for(i = 0; i < num_nodes; i++) { 558
559 for (i = 0; i < num_nodes; i++) {
558 memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); 560 memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE);
559 nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; 561 nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port;
560 562
561 IP *node_ip = &nodes_list[i].ip_port.ip; 563 IP *node_ip = &nodes_list[i].ip_port.ip;
564
562 if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6)) 565 if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6))
563 /* embedded IPv4-in-IPv6 address: return it in regular sendnodes packet */ 566 /* embedded IPv4-in-IPv6 address: return it in regular sendnodes packet */
564 nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip6.s6_addr32[3]; 567 nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip6.s6_addr32[3];
@@ -574,6 +577,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
574 /* shouldn't happen */ 577 /* shouldn't happen */
575 num_nodes = num_nodes_ok; 578 num_nodes = num_nodes_ok;
576 } 579 }
580
577#else 581#else
578 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node4_format_size); 582 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node4_format_size);
579#endif 583#endif
@@ -620,7 +624,7 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
620 uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; 624 uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES];
621 uint8_t encrypt[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; 625 uint8_t encrypt[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING];
622 uint8_t nonce[crypto_box_NONCEBYTES]; 626 uint8_t nonce[crypto_box_NONCEBYTES];
623 random_nonce(nonce); 627 new_nonce(nonce);
624 628
625 memcpy(plain, &ping_id, sizeof(ping_id)); 629 memcpy(plain, &ping_id, sizeof(ping_id));
626 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node_format_size); 630 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node_format_size);
@@ -691,6 +695,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
691 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; 695 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
692 696
693 size_t Node4_format_size = sizeof(Node4_format); 697 size_t Node4_format_size = sizeof(Node4_format);
698
694 if (length > (cid_size + Node4_format_size * MAX_SENT_NODES) || 699 if (length > (cid_size + Node4_format_size * MAX_SENT_NODES) ||
695 ((length - cid_size) % Node4_format_size) != 0 || 700 ((length - cid_size) % Node4_format_size) != 0 ||
696 (length < cid_size + Node4_format_size)) 701 (length < cid_size + Node4_format_size))
@@ -721,7 +726,8 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
721 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); 726 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
722 727
723 int num_nodes_ok = 0; 728 int num_nodes_ok = 0;
724 for(i = 0; i < num_nodes; i++) 729
730 for (i = 0; i < num_nodes; i++)
725 if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != ~0)) { 731 if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != ~0)) {
726 memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); 732 memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE);
727 nodes_list[num_nodes_ok].ip_port.ip.family = AF_INET; 733 nodes_list[num_nodes_ok].ip_port.ip.family = AF_INET;
@@ -735,6 +741,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
735 /* shouldn't happen */ 741 /* shouldn't happen */
736 num_nodes = num_nodes_ok; 742 num_nodes = num_nodes_ok;
737 } 743 }
744
738#else 745#else
739 memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); 746 memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format));
740#endif 747#endif
@@ -758,6 +765,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
758 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; 765 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
759 766
760 size_t Node_format_size = sizeof(Node4_format); 767 size_t Node_format_size = sizeof(Node4_format);
768
761 if (length > (cid_size + Node_format_size * MAX_SENT_NODES) || 769 if (length > (cid_size + Node_format_size * MAX_SENT_NODES) ||
762 ((length - cid_size) % Node_format_size) != 0 || 770 ((length - cid_size) % Node_format_size) != 0 ||
763 (length < cid_size + Node_format_size)) 771 (length < cid_size + Node_format_size))
@@ -964,17 +972,19 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
964 send_ping_request(dht->ping, dht->c, ip_port, public_key); 972 send_ping_request(dht->ping, dht->c, ip_port, public_key);
965} 973}
966int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, 974int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
967 uint16_t port, uint8_t *public_key) 975 uint16_t port, uint8_t *public_key)
968{ 976{
969 IP_Port ip_port_v64, ip_port_v4; 977 IP_Port ip_port_v64, ip_port_v4;
970 IP *ip_extra = NULL; 978 IP *ip_extra = NULL;
971#ifdef TOX_ENABLE_IPV6 979#ifdef TOX_ENABLE_IPV6
972 ip_init(&ip_port_v64.ip, ipv6enabled); 980 ip_init(&ip_port_v64.ip, ipv6enabled);
981
973 if (ipv6enabled) { 982 if (ipv6enabled) {
974 ip_port_v64.ip.family = AF_UNSPEC; 983 ip_port_v64.ip.family = AF_UNSPEC;
975 ip_reset(&ip_port_v4.ip); 984 ip_reset(&ip_port_v4.ip);
976 ip_extra = &ip_port_v4.ip; 985 ip_extra = &ip_port_v4.ip;
977 } 986 }
987
978#else 988#else
979 ip_init(&ip_port_v64.ip, 0); 989 ip_init(&ip_port_v64.ip, 0);
980#endif 990#endif
@@ -983,14 +993,15 @@ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable
983 ip_port_v64.port = port; 993 ip_port_v64.port = port;
984 DHT_bootstrap(dht, ip_port_v64, public_key); 994 DHT_bootstrap(dht, ip_port_v64, public_key);
985#ifdef TOX_ENABLE_IPV6 995#ifdef TOX_ENABLE_IPV6
996
986 if ((ip_extra != NULL) && ip_isset(ip_extra)) { 997 if ((ip_extra != NULL) && ip_isset(ip_extra)) {
987 ip_port_v4.port = port; 998 ip_port_v4.port = port;
988 DHT_bootstrap(dht, ip_port_v4, public_key); 999 DHT_bootstrap(dht, ip_port_v4, public_key);
989 } 1000 }
1001
990#endif 1002#endif
991 return 1; 1003 return 1;
992 } 1004 } else
993 else
994 return 0; 1005 return 0;
995} 1006}
996 1007
@@ -1303,6 +1314,7 @@ static void do_NAT(DHT *dht)
1303 dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { 1314 dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) {
1304 1315
1305 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); 1316 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2);
1317
1306 if (!ip_isset(&ip)) 1318 if (!ip_isset(&ip))
1307 continue; 1319 continue;
1308 1320
@@ -1443,12 +1455,13 @@ void DHT_save(DHT *dht, uint8_t *data)
1443 */ 1455 */
1444int DHT_load(DHT *dht, uint8_t *data, uint32_t size) 1456int DHT_load(DHT *dht, uint8_t *data, uint32_t size)
1445{ 1457{
1446 if (size < sizeof(dht->close_clientlist)) { 1458 if (size < sizeof(dht->close_clientlist)) {
1447 fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size); 1459 fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size);
1448 return -1; 1460 return -1;
1449 } 1461 }
1450 1462
1451 uint32_t friendlistsize = size - sizeof(dht->close_clientlist); 1463 uint32_t friendlistsize = size - sizeof(dht->close_clientlist);
1464
1452 if (friendlistsize % sizeof(DHT_Friend) != 0) { 1465 if (friendlistsize % sizeof(DHT_Friend) != 0) {
1453 fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize); 1466 fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize);
1454 return -1; 1467 return -1;
@@ -1457,6 +1470,7 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size)
1457 uint32_t i, j; 1470 uint32_t i, j;
1458 Client_data *client; 1471 Client_data *client;
1459 uint16_t friends_num = friendlistsize / sizeof(DHT_Friend); 1472 uint16_t friends_num = friendlistsize / sizeof(DHT_Friend);
1473
1460 if (friends_num != 0) { 1474 if (friends_num != 0) {
1461 DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist)); 1475 DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist));
1462 1476
@@ -1473,6 +1487,7 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size)
1473 } 1487 }
1474 1488
1475 Client_data *tempclose_clientlist = (Client_data *)data; 1489 Client_data *tempclose_clientlist = (Client_data *)data;
1490
1476 for (i = 0; i < LCLIENT_LIST; ++i) { 1491 for (i = 0; i < LCLIENT_LIST; ++i) {
1477 if (tempclose_clientlist[i].timestamp != 0) 1492 if (tempclose_clientlist[i].timestamp != 0)
1478 DHT_bootstrap(dht, tempclose_clientlist[i].ip_port, 1493 DHT_bootstrap(dht, tempclose_clientlist[i].ip_port,