diff options
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r-- | toxcore/DHT.c | 77 |
1 files changed, 30 insertions, 47 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index ee51f16c..c286567f 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -115,25 +115,14 @@ static int client_id_cmp(ClientPair p1, ClientPair p2) | |||
115 | return c; | 115 | return c; |
116 | } | 116 | } |
117 | 117 | ||
118 | static int id_equal(uint8_t *a, uint8_t *b) | ||
119 | { | ||
120 | return memcmp(a, b, CLIENT_ID_SIZE) == 0; | ||
121 | } | ||
122 | |||
123 | static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout) | ||
124 | { | ||
125 | return timestamp + timeout <= time_now; | ||
126 | } | ||
127 | |||
128 | static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id) | 118 | static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id) |
129 | { | 119 | { |
130 | uint32_t i; | 120 | uint32_t i; |
131 | uint64_t temp_time = unix_time(); | ||
132 | 121 | ||
133 | for (i = 0; i < length; i++) | 122 | for (i = 0; i < length; i++) |
134 | /* Dead nodes are considered dead (not in the list)*/ | 123 | /* Dead nodes are considered dead (not in the list)*/ |
135 | if (!is_timeout(temp_time, list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) || | 124 | if (!is_timeout(list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) || |
136 | !is_timeout(temp_time, list[i].assoc6.timestamp, KILL_NODE_TIMEOUT)) | 125 | !is_timeout(list[i].assoc6.timestamp, KILL_NODE_TIMEOUT)) |
137 | if (id_equal(list[i].client_id, client_id)) | 126 | if (id_equal(list[i].client_id, client_id)) |
138 | return 1; | 127 | return 1; |
139 | 128 | ||
@@ -272,7 +261,7 @@ static int friend_number(DHT *dht, uint8_t *client_id) | |||
272 | */ | 261 | */ |
273 | static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list, | 262 | static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list, |
274 | sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, | 263 | sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, |
275 | time_t timestamp, int *num_nodes_ptr, uint8_t is_LAN) | 264 | int *num_nodes_ptr, uint8_t is_LAN) |
276 | { | 265 | { |
277 | if ((sa_family != AF_INET) && (sa_family != AF_INET6)) | 266 | if ((sa_family != AF_INET) && (sa_family != AF_INET6)) |
278 | return; | 267 | return; |
@@ -295,7 +284,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod | |||
295 | ipptp = &client->assoc6; | 284 | ipptp = &client->assoc6; |
296 | 285 | ||
297 | /* node not in a good condition? */ | 286 | /* node not in a good condition? */ |
298 | if (is_timeout(timestamp, ipptp->timestamp, BAD_NODE_TIMEOUT)) | 287 | if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT)) |
299 | continue; | 288 | continue; |
300 | 289 | ||
301 | IP *client_ip = &ipptp->ip_port.ip; | 290 | IP *client_ip = &ipptp->ip_port.ip; |
@@ -366,15 +355,14 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod | |||
366 | */ | 355 | */ |
367 | static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN) | 356 | static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN) |
368 | { | 357 | { |
369 | time_t timestamp = unix_time(); | ||
370 | int num_nodes = 0, i; | 358 | int num_nodes = 0, i; |
371 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, | 359 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, |
372 | dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes, is_LAN); | 360 | dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN); |
373 | 361 | ||
374 | for (i = 0; i < dht->num_friends; ++i) | 362 | for (i = 0; i < dht->num_friends; ++i) |
375 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, | 363 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, |
376 | dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, | 364 | dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, |
377 | timestamp, &num_nodes, is_LAN); | 365 | &num_nodes, is_LAN); |
378 | 366 | ||
379 | return num_nodes; | 367 | return num_nodes; |
380 | } | 368 | } |
@@ -393,7 +381,6 @@ static int replace_bad( Client_data *list, | |||
393 | return 1; | 381 | return 1; |
394 | 382 | ||
395 | uint32_t i; | 383 | uint32_t i; |
396 | uint64_t temp_time = unix_time(); | ||
397 | 384 | ||
398 | for (i = 0; i < length; ++i) { | 385 | for (i = 0; i < length; ++i) { |
399 | /* If node is bad */ | 386 | /* If node is bad */ |
@@ -405,10 +392,10 @@ static int replace_bad( Client_data *list, | |||
405 | else | 392 | else |
406 | ipptp = &client->assoc6; | 393 | ipptp = &client->assoc6; |
407 | 394 | ||
408 | if (is_timeout(temp_time, ipptp->timestamp, BAD_NODE_TIMEOUT)) { | 395 | if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT)) { |
409 | memcpy(client->client_id, client_id, CLIENT_ID_SIZE); | 396 | memcpy(client->client_id, client_id, CLIENT_ID_SIZE); |
410 | ipptp->ip_port = ip_port; | 397 | ipptp->ip_port = ip_port; |
411 | ipptp->timestamp = temp_time; | 398 | ipptp->timestamp = unix_time(); |
412 | 399 | ||
413 | ip_reset(&ipptp->ret_ip_port.ip); | 400 | ip_reset(&ipptp->ret_ip_port.ip); |
414 | ipptp->ret_ip_port.port = 0; | 401 | ipptp->ret_ip_port.port = 0; |
@@ -587,10 +574,9 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) | |||
587 | { | 574 | { |
588 | uint32_t i; | 575 | uint32_t i; |
589 | uint8_t pinging; | 576 | uint8_t pinging; |
590 | uint64_t temp_time = unix_time(); | ||
591 | 577 | ||
592 | for (i = 0; i < LSEND_NODES_ARRAY; ++i ) { | 578 | for (i = 0; i < LSEND_NODES_ARRAY; ++i ) { |
593 | if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { | 579 | if (!is_timeout(dht->send_nodes[i].timestamp, PING_TIMEOUT)) { |
594 | pinging = 0; | 580 | pinging = 0; |
595 | 581 | ||
596 | if (ping_id != 0 && dht->send_nodes[i].id == ping_id) | 582 | if (ping_id != 0 && dht->send_nodes[i].id == ping_id) |
@@ -612,12 +598,11 @@ static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port) | |||
612 | { | 598 | { |
613 | uint32_t i, j; | 599 | uint32_t i, j; |
614 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); | 600 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
615 | uint64_t temp_time = unix_time(); | ||
616 | 601 | ||
617 | for (i = 0; i < PING_TIMEOUT; ++i ) { | 602 | for (i = 0; i < PING_TIMEOUT; ++i ) { |
618 | for (j = 0; j < LSEND_NODES_ARRAY; ++j ) { | 603 | for (j = 0; j < LSEND_NODES_ARRAY; ++j ) { |
619 | if (is_timeout(temp_time, dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) { | 604 | if (is_timeout(dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) { |
620 | dht->send_nodes[j].timestamp = temp_time; | 605 | dht->send_nodes[j].timestamp = unix_time(); |
621 | dht->send_nodes[j].ip_port = ip_port; | 606 | dht->send_nodes[j].ip_port = ip_port; |
622 | dht->send_nodes[j].id = ping_id; | 607 | dht->send_nodes[j].id = ping_id; |
623 | return ping_id; | 608 | return ping_id; |
@@ -937,7 +922,6 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, | |||
937 | */ | 922 | */ |
938 | static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id) | 923 | static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id) |
939 | { | 924 | { |
940 | uint64_t temp_time = unix_time(); | ||
941 | uint32_t i, num = 0; | 925 | uint32_t i, num = 0; |
942 | 926 | ||
943 | for (i = 0; i < length; ++i) { | 927 | for (i = 0; i < length; ++i) { |
@@ -946,7 +930,7 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_ | |||
946 | 930 | ||
947 | for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4) | 931 | for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4) |
948 | if (ipport_isset(&(assoc->ip_port)) && | 932 | if (ipport_isset(&(assoc->ip_port)) && |
949 | !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { | 933 | !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { |
950 | getnodes(dht, assoc->ip_port, list[i].client_id, client_id); | 934 | getnodes(dht, assoc->ip_port, list[i].client_id, client_id); |
951 | ++num; | 935 | ++num; |
952 | 936 | ||
@@ -1016,7 +1000,6 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id) | |||
1016 | int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port) | 1000 | int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port) |
1017 | { | 1001 | { |
1018 | uint32_t i, j; | 1002 | uint32_t i, j; |
1019 | uint64_t temp_time = unix_time(); | ||
1020 | 1003 | ||
1021 | ip_reset(&ip_port->ip); | 1004 | ip_reset(&ip_port->ip); |
1022 | ip_port->port = 0; | 1005 | ip_port->port = 0; |
@@ -1032,7 +1015,7 @@ int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port) | |||
1032 | uint32_t a; | 1015 | uint32_t a; |
1033 | 1016 | ||
1034 | for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) | 1017 | for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) |
1035 | if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { | 1018 | if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) { |
1036 | *ip_port = assoc->ip_port; | 1019 | *ip_port = assoc->ip_port; |
1037 | return 1; | 1020 | return 1; |
1038 | } | 1021 | } |
@@ -1063,14 +1046,14 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8 | |||
1063 | uint32_t a; | 1046 | uint32_t a; |
1064 | 1047 | ||
1065 | for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) | 1048 | for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) |
1066 | if (!is_timeout(temp_time, assoc->timestamp, KILL_NODE_TIMEOUT)) { | 1049 | if (!is_timeout(assoc->timestamp, KILL_NODE_TIMEOUT)) { |
1067 | if (is_timeout(temp_time, assoc->last_pinged, PING_INTERVAL)) { | 1050 | if (is_timeout(assoc->last_pinged, PING_INTERVAL)) { |
1068 | send_ping_request(dht->ping, assoc->ip_port, client->client_id ); | 1051 | send_ping_request(dht->ping, assoc->ip_port, client->client_id ); |
1069 | assoc->last_pinged = temp_time; | 1052 | assoc->last_pinged = temp_time; |
1070 | } | 1053 | } |
1071 | 1054 | ||
1072 | /* If node is good. */ | 1055 | /* If node is good. */ |
1073 | if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { | 1056 | if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) { |
1074 | client_list[num_nodes] = client; | 1057 | client_list[num_nodes] = client; |
1075 | assoc_list[num_nodes] = assoc; | 1058 | assoc_list[num_nodes] = assoc; |
1076 | ++num_nodes; | 1059 | ++num_nodes; |
@@ -1078,8 +1061,7 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8 | |||
1078 | } | 1061 | } |
1079 | } | 1062 | } |
1080 | 1063 | ||
1081 | if ((num_nodes != 0) && | 1064 | if ((num_nodes != 0) && is_timeout(*lastgetnode, GET_NODE_INTERVAL)) { |
1082 | is_timeout(temp_time, *lastgetnode, GET_NODE_INTERVAL)) { | ||
1083 | uint32_t rand_node = rand() % num_nodes; | 1065 | uint32_t rand_node = rand() % num_nodes; |
1084 | getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id, | 1066 | getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id, |
1085 | client_id); | 1067 | client_id); |
@@ -1174,9 +1156,6 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length) | |||
1174 | */ | 1156 | */ |
1175 | static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) | 1157 | static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) |
1176 | { | 1158 | { |
1177 | int i; | ||
1178 | uint64_t temp_time = unix_time(); | ||
1179 | |||
1180 | if (friend_num >= dht->num_friends) | 1159 | if (friend_num >= dht->num_friends) |
1181 | return -1; | 1160 | return -1; |
1182 | 1161 | ||
@@ -1187,20 +1166,21 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) | |||
1187 | IP_Port ipv6s[MAX_FRIEND_CLIENTS]; | 1166 | IP_Port ipv6s[MAX_FRIEND_CLIENTS]; |
1188 | int num_ipv6s = 0; | 1167 | int num_ipv6s = 0; |
1189 | uint8_t connected; | 1168 | uint8_t connected; |
1169 | int i; | ||
1190 | 1170 | ||
1191 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 1171 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { |
1192 | client = &(friend->client_list[i]); | 1172 | client = &(friend->client_list[i]); |
1193 | connected = 0; | 1173 | connected = 0; |
1194 | 1174 | ||
1195 | /* If ip is not zero and node is good. */ | 1175 | /* If ip is not zero and node is good. */ |
1196 | if (ip_isset(&client->assoc4.ret_ip_port.ip) && !is_timeout(temp_time, client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) { | 1176 | if (ip_isset(&client->assoc4.ret_ip_port.ip) && !is_timeout(client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) { |
1197 | ipv4s[num_ipv4s] = client->assoc4.ret_ip_port; | 1177 | ipv4s[num_ipv4s] = client->assoc4.ret_ip_port; |
1198 | ++num_ipv4s; | 1178 | ++num_ipv4s; |
1199 | 1179 | ||
1200 | connected = 1; | 1180 | connected = 1; |
1201 | } | 1181 | } |
1202 | 1182 | ||
1203 | if (ip_isset(&client->assoc6.ret_ip_port.ip) && !is_timeout(temp_time, client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) { | 1183 | if (ip_isset(&client->assoc6.ret_ip_port.ip) && !is_timeout(client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) { |
1204 | ipv6s[num_ipv6s] = client->assoc6.ret_ip_port; | 1184 | ipv6s[num_ipv6s] = client->assoc6.ret_ip_port; |
1205 | ++num_ipv6s; | 1185 | ++num_ipv6s; |
1206 | 1186 | ||
@@ -1260,7 +1240,6 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
1260 | if (ip_num < (MAX_FRIEND_CLIENTS / 2)) | 1240 | if (ip_num < (MAX_FRIEND_CLIENTS / 2)) |
1261 | return 0; /* Reason for that? */ | 1241 | return 0; /* Reason for that? */ |
1262 | 1242 | ||
1263 | uint64_t temp_time = unix_time(); | ||
1264 | DHT_Friend *friend = &dht->friends_list[num]; | 1243 | DHT_Friend *friend = &dht->friends_list[num]; |
1265 | Client_data *client; | 1244 | Client_data *client; |
1266 | 1245 | ||
@@ -1283,7 +1262,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
1283 | 1262 | ||
1284 | /* If ip is not zero and node is good. */ | 1263 | /* If ip is not zero and node is good. */ |
1285 | if (ip_isset(&assoc->ret_ip_port.ip) && | 1264 | if (ip_isset(&assoc->ret_ip_port.ip) && |
1286 | !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { | 1265 | !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { |
1287 | int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length); | 1266 | int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length); |
1288 | 1267 | ||
1289 | if ((unsigned int)retval == length) { | 1268 | if ((unsigned int)retval == length) { |
@@ -1313,7 +1292,6 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint | |||
1313 | IP_Port ip_list[MAX_FRIEND_CLIENTS * 2]; | 1292 | IP_Port ip_list[MAX_FRIEND_CLIENTS * 2]; |
1314 | int n = 0; | 1293 | int n = 0; |
1315 | uint32_t i; | 1294 | uint32_t i; |
1316 | uint64_t temp_time = unix_time(); | ||
1317 | 1295 | ||
1318 | /* extra legwork, because having the outside allocating the space for us | 1296 | /* extra legwork, because having the outside allocating the space for us |
1319 | * is *usually* good(tm) (bites us in the behind in this case though) */ | 1297 | * is *usually* good(tm) (bites us in the behind in this case though) */ |
@@ -1330,7 +1308,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint | |||
1330 | assoc = &client->assoc6; | 1308 | assoc = &client->assoc6; |
1331 | 1309 | ||
1332 | /* If ip is not zero and node is good. */ | 1310 | /* If ip is not zero and node is good. */ |
1333 | if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { | 1311 | if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { |
1334 | ip_list[n] = assoc->ip_port; | 1312 | ip_list[n] = assoc->ip_port; |
1335 | ++n; | 1313 | ++n; |
1336 | } | 1314 | } |
@@ -1556,6 +1534,9 @@ static void do_NAT(DHT *dht) | |||
1556 | 1534 | ||
1557 | DHT *new_DHT(Net_Crypto *c) | 1535 | DHT *new_DHT(Net_Crypto *c) |
1558 | { | 1536 | { |
1537 | /* init time */ | ||
1538 | unix_time_update(); | ||
1539 | |||
1559 | if (c == NULL) | 1540 | if (c == NULL) |
1560 | return NULL; | 1541 | return NULL; |
1561 | 1542 | ||
@@ -1584,6 +1565,8 @@ DHT *new_DHT(Net_Crypto *c) | |||
1584 | 1565 | ||
1585 | void do_DHT(DHT *dht) | 1566 | void do_DHT(DHT *dht) |
1586 | { | 1567 | { |
1568 | unix_time_update(); | ||
1569 | |||
1587 | do_Close(dht); | 1570 | do_Close(dht); |
1588 | do_DHT_friends(dht); | 1571 | do_DHT_friends(dht); |
1589 | do_NAT(dht); | 1572 | do_NAT(dht); |
@@ -1860,13 +1843,13 @@ int DHT_load_new(DHT *dht, uint8_t *data, uint32_t length) | |||
1860 | int DHT_isconnected(DHT *dht) | 1843 | int DHT_isconnected(DHT *dht) |
1861 | { | 1844 | { |
1862 | uint32_t i; | 1845 | uint32_t i; |
1863 | uint64_t temp_time = unix_time(); | 1846 | unix_time_update(); |
1864 | 1847 | ||
1865 | for (i = 0; i < LCLIENT_LIST; ++i) { | 1848 | for (i = 0; i < LCLIENT_LIST; ++i) { |
1866 | Client_data *client = &dht->close_clientlist[i]; | 1849 | Client_data *client = &dht->close_clientlist[i]; |
1867 | 1850 | ||
1868 | if (!is_timeout(temp_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) || | 1851 | if (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) || |
1869 | !is_timeout(temp_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)) | 1852 | !is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) |
1870 | return 1; | 1853 | return 1; |
1871 | } | 1854 | } |
1872 | 1855 | ||