summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c112
1 files changed, 28 insertions, 84 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 2f468632..5232deed 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -115,26 +115,15 @@ static int client_id_cmp(ClientPair p1, ClientPair p2)
115 return c; 115 return c;
116} 116}
117 117
118static int id_equal(uint8_t *a, uint8_t *b)
119{
120 return memcmp(a, b, CLIENT_ID_SIZE) == 0;
121}
122
123static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout)
124{
125 return timestamp + timeout <= time_now;
126}
127
128static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id) 118static 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 123
135 /* Dead nodes are considered dead (not in the list)*/ 124 /* Dead nodes are considered dead (not in the list)*/
136 if (!is_timeout(temp_time, list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) || 125 if (!is_timeout(list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) ||
137 !is_timeout(temp_time, list[i].assoc6.timestamp, KILL_NODE_TIMEOUT)) 126 !is_timeout(list[i].assoc6.timestamp, KILL_NODE_TIMEOUT))
138 if (id_equal(list[i].client_id, client_id)) 127 if (id_equal(list[i].client_id, client_id))
139 return 1; 128 return 1;
140 129
@@ -273,7 +262,7 @@ static int friend_number(DHT *dht, uint8_t *client_id)
273 */ 262 */
274static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list, 263static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list,
275 sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, 264 sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length,
276 time_t timestamp, int *num_nodes_ptr, uint8_t is_LAN) 265 int *num_nodes_ptr, uint8_t is_LAN)
277{ 266{
278 if ((sa_family != AF_INET) && (sa_family != AF_INET6)) 267 if ((sa_family != AF_INET) && (sa_family != AF_INET6))
279 return; 268 return;
@@ -297,7 +286,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
297 ipptp = &client->assoc6; 286 ipptp = &client->assoc6;
298 287
299 /* node not in a good condition? */ 288 /* node not in a good condition? */
300 if (is_timeout(timestamp, ipptp->timestamp, BAD_NODE_TIMEOUT)) 289 if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT))
301 continue; 290 continue;
302 291
303 IP *client_ip = &ipptp->ip_port.ip; 292 IP *client_ip = &ipptp->ip_port.ip;
@@ -369,15 +358,14 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
369 */ 358 */
370static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN) 359static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN)
371{ 360{
372 time_t timestamp = unix_time();
373 int num_nodes = 0, i; 361 int num_nodes = 0, i;
374 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 362 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
375 dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes, is_LAN); 363 dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN);
376 364
377 for (i = 0; i < dht->num_friends; ++i) 365 for (i = 0; i < dht->num_friends; ++i)
378 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 366 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
379 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, 367 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
380 timestamp, &num_nodes, is_LAN); 368 &num_nodes, is_LAN);
381 369
382 return num_nodes; 370 return num_nodes;
383} 371}
@@ -396,7 +384,6 @@ static int replace_bad( Client_data *list,
396 return 1; 384 return 1;
397 385
398 uint32_t i; 386 uint32_t i;
399 uint64_t temp_time = unix_time();
400 387
401 for (i = 0; i < length; ++i) { 388 for (i = 0; i < length; ++i) {
402 /* If node is bad */ 389 /* If node is bad */
@@ -408,10 +395,10 @@ static int replace_bad( Client_data *list,
408 else 395 else
409 ipptp = &client->assoc6; 396 ipptp = &client->assoc6;
410 397
411 if (is_timeout(temp_time, ipptp->timestamp, BAD_NODE_TIMEOUT)) { 398 if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT)) {
412 memcpy(client->client_id, client_id, CLIENT_ID_SIZE); 399 memcpy(client->client_id, client_id, CLIENT_ID_SIZE);
413 ipptp->ip_port = ip_port; 400 ipptp->ip_port = ip_port;
414 ipptp->timestamp = temp_time; 401 ipptp->timestamp = unix_time();
415 402
416 ip_reset(&ipptp->ret_ip_port.ip); 403 ip_reset(&ipptp->ret_ip_port.ip);
417 ipptp->ret_ip_port.port = 0; 404 ipptp->ret_ip_port.port = 0;
@@ -943,7 +930,6 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
943 */ 930 */
944static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id) 931static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id)
945{ 932{
946 uint64_t temp_time = unix_time();
947 uint32_t i, num = 0; 933 uint32_t i, num = 0;
948 934
949 for (i = 0; i < length; ++i) { 935 for (i = 0; i < length; ++i) {
@@ -952,7 +938,7 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_
952 938
953 for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4) 939 for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4)
954 if (ipport_isset(&(assoc->ip_port)) && 940 if (ipport_isset(&(assoc->ip_port)) &&
955 !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 941 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
956 getnodes(dht, assoc->ip_port, list[i].client_id, client_id, NULL); 942 getnodes(dht, assoc->ip_port, list[i].client_id, client_id, NULL);
957 ++num; 943 ++num;
958 944
@@ -1022,7 +1008,6 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id)
1022int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port) 1008int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port)
1023{ 1009{
1024 uint32_t i, j; 1010 uint32_t i, j;
1025 uint64_t temp_time = unix_time();
1026 1011
1027 ip_reset(&ip_port->ip); 1012 ip_reset(&ip_port->ip);
1028 ip_port->port = 0; 1013 ip_port->port = 0;
@@ -1038,7 +1023,7 @@ int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port)
1038 uint32_t a; 1023 uint32_t a;
1039 1024
1040 for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) 1025 for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4)
1041 if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { 1026 if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) {
1042 *ip_port = assoc->ip_port; 1027 *ip_port = assoc->ip_port;
1043 return 1; 1028 return 1;
1044 } 1029 }
@@ -1069,14 +1054,14 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8
1069 uint32_t a; 1054 uint32_t a;
1070 1055
1071 for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) 1056 for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4)
1072 if (!is_timeout(temp_time, assoc->timestamp, KILL_NODE_TIMEOUT)) { 1057 if (!is_timeout(assoc->timestamp, KILL_NODE_TIMEOUT)) {
1073 if (is_timeout(temp_time, assoc->last_pinged, PING_INTERVAL)) { 1058 if (is_timeout(assoc->last_pinged, PING_INTERVAL)) {
1074 send_ping_request(dht->ping, assoc->ip_port, client->client_id ); 1059 send_ping_request(dht->ping, assoc->ip_port, client->client_id );
1075 assoc->last_pinged = temp_time; 1060 assoc->last_pinged = temp_time;
1076 } 1061 }
1077 1062
1078 /* If node is good. */ 1063 /* If node is good. */
1079 if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { 1064 if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) {
1080 client_list[num_nodes] = client; 1065 client_list[num_nodes] = client;
1081 assoc_list[num_nodes] = assoc; 1066 assoc_list[num_nodes] = assoc;
1082 ++num_nodes; 1067 ++num_nodes;
@@ -1084,8 +1069,7 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8
1084 } 1069 }
1085 } 1070 }
1086 1071
1087 if ((num_nodes != 0) && 1072 if ((num_nodes != 0) && is_timeout(*lastgetnode, GET_NODE_INTERVAL)) {
1088 is_timeout(temp_time, *lastgetnode, GET_NODE_INTERVAL)) {
1089 uint32_t rand_node = rand() % num_nodes; 1073 uint32_t rand_node = rand() % num_nodes;
1090 getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id, 1074 getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id,
1091 client_id, NULL); 1075 client_id, NULL);
@@ -1180,9 +1164,6 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
1180 */ 1164 */
1181static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) 1165static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
1182{ 1166{
1183 int i;
1184 uint64_t temp_time = unix_time();
1185
1186 if (friend_num >= dht->num_friends) 1167 if (friend_num >= dht->num_friends)
1187 return -1; 1168 return -1;
1188 1169
@@ -1193,22 +1174,21 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
1193 IP_Port ipv6s[MAX_FRIEND_CLIENTS]; 1174 IP_Port ipv6s[MAX_FRIEND_CLIENTS];
1194 int num_ipv6s = 0; 1175 int num_ipv6s = 0;
1195 uint8_t connected; 1176 uint8_t connected;
1177 int i;
1196 1178
1197 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 1179 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
1198 client = &(friend->client_list[i]); 1180 client = &(friend->client_list[i]);
1199 connected = 0; 1181 connected = 0;
1200 1182
1201 /* If ip is not zero and node is good. */ 1183 /* If ip is not zero and node is good. */
1202 if (ip_isset(&client->assoc4.ret_ip_port.ip) 1184 if (ip_isset(&client->assoc4.ret_ip_port.ip) && !is_timeout(client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) {
1203 && !is_timeout(temp_time, client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) {
1204 ipv4s[num_ipv4s] = client->assoc4.ret_ip_port; 1185 ipv4s[num_ipv4s] = client->assoc4.ret_ip_port;
1205 ++num_ipv4s; 1186 ++num_ipv4s;
1206 1187
1207 connected = 1; 1188 connected = 1;
1208 } 1189 }
1209 1190
1210 if (ip_isset(&client->assoc6.ret_ip_port.ip) 1191 if (ip_isset(&client->assoc6.ret_ip_port.ip) && !is_timeout(client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) {
1211 && !is_timeout(temp_time, client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) {
1212 ipv6s[num_ipv6s] = client->assoc6.ret_ip_port; 1192 ipv6s[num_ipv6s] = client->assoc6.ret_ip_port;
1213 ++num_ipv6s; 1193 ++num_ipv6s;
1214 1194
@@ -1271,7 +1251,6 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
1271 if (ip_num < (MAX_FRIEND_CLIENTS / 2)) 1251 if (ip_num < (MAX_FRIEND_CLIENTS / 2))
1272 return 0; /* Reason for that? */ 1252 return 0; /* Reason for that? */
1273 1253
1274 uint64_t temp_time = unix_time();
1275 DHT_Friend *friend = &dht->friends_list[num]; 1254 DHT_Friend *friend = &dht->friends_list[num];
1276 Client_data *client; 1255 Client_data *client;
1277 1256
@@ -1294,7 +1273,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
1294 1273
1295 /* If ip is not zero and node is good. */ 1274 /* If ip is not zero and node is good. */
1296 if (ip_isset(&assoc->ret_ip_port.ip) && 1275 if (ip_isset(&assoc->ret_ip_port.ip) &&
1297 !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 1276 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
1298 int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length); 1277 int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length);
1299 1278
1300 if ((unsigned int)retval == length) { 1279 if ((unsigned int)retval == length) {
@@ -1324,7 +1303,6 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
1324 IP_Port ip_list[MAX_FRIEND_CLIENTS * 2]; 1303 IP_Port ip_list[MAX_FRIEND_CLIENTS * 2];
1325 int n = 0; 1304 int n = 0;
1326 uint32_t i; 1305 uint32_t i;
1327 uint64_t temp_time = unix_time();
1328 1306
1329 /* extra legwork, because having the outside allocating the space for us 1307 /* extra legwork, because having the outside allocating the space for us
1330 * is *usually* good(tm) (bites us in the behind in this case though) */ 1308 * is *usually* good(tm) (bites us in the behind in this case though) */
@@ -1341,7 +1319,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
1341 assoc = &client->assoc6; 1319 assoc = &client->assoc6;
1342 1320
1343 /* If ip is not zero and node is good. */ 1321 /* If ip is not zero and node is good. */
1344 if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 1322 if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
1345 ip_list[n] = assoc->ip_port; 1323 ip_list[n] = assoc->ip_port;
1346 ++n; 1324 ++n;
1347 } 1325 }
@@ -1665,6 +1643,9 @@ static int handle_hardening(void *object, IP_Port source, uint8_t *source_pubkey
1665 1643
1666DHT *new_DHT(Net_Crypto *c) 1644DHT *new_DHT(Net_Crypto *c)
1667{ 1645{
1646 /* init time */
1647 unix_time_update();
1648
1668 if (c == NULL) 1649 if (c == NULL)
1669 return NULL; 1650 return NULL;
1670 1651
@@ -1694,6 +1675,8 @@ DHT *new_DHT(Net_Crypto *c)
1694 1675
1695void do_DHT(DHT *dht) 1676void do_DHT(DHT *dht)
1696{ 1677{
1678 unix_time_update();
1679
1697 do_Close(dht); 1680 do_Close(dht);
1698 do_DHT_friends(dht); 1681 do_DHT_friends(dht);
1699 do_NAT(dht); 1682 do_NAT(dht);
@@ -1711,8 +1694,6 @@ void kill_DHT(DHT *dht)
1711#define DHT_STATE_COOKIE_GLOBAL 0x159000d 1694#define DHT_STATE_COOKIE_GLOBAL 0x159000d
1712 1695
1713#define DHT_STATE_COOKIE_TYPE 0x11ce 1696#define DHT_STATE_COOKIE_TYPE 0x11ce
1714#define DHT_STATE_TYPE_FRIENDS 1
1715#define DHT_STATE_TYPE_CLIENTS 2
1716#define DHT_STATE_TYPE_FRIENDS_ASSOC46 3 1697#define DHT_STATE_TYPE_FRIENDS_ASSOC46 3
1717#define DHT_STATE_TYPE_CLIENTS_ASSOC46 4 1698#define DHT_STATE_TYPE_CLIENTS_ASSOC46 4
1718 1699
@@ -1784,43 +1765,6 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length,
1784 uint32_t num, i, j; 1765 uint32_t num, i, j;
1785 1766
1786 switch (type) { 1767 switch (type) {
1787 case DHT_STATE_TYPE_FRIENDS:
1788 if (length % sizeof(DHT_Friend_old) != 0)
1789 break;
1790
1791 { /* localize declarations */
1792 DHT_Friend_old *friend_list = (DHT_Friend_old *)data;
1793 num = length / sizeof(DHT_Friend_old);
1794
1795 for (i = 0; i < num; ++i) {
1796 DHT_addfriend(dht, friend_list[i].client_id);
1797
1798 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1799 Client_data_old *client = &friend_list[i].client_list[j];
1800
1801 if (client->assoc.timestamp != 0)
1802 getnodes(dht, client->assoc.ip_port, client->client_id, friend_list[i].client_id, NULL);
1803 }
1804 }
1805 } /* localize declarations */
1806
1807 break;
1808
1809 case DHT_STATE_TYPE_CLIENTS:
1810 if ((length % sizeof(Client_data_old)) != 0)
1811 break;
1812
1813 { /* localize declarations */
1814 num = length / sizeof(Client_data_old);
1815 Client_data_old *client_list = (Client_data_old *)data;
1816
1817 for (i = 0; i < num; ++i)
1818 if (client_list[i].assoc.timestamp != 0)
1819 DHT_bootstrap(dht, client_list[i].assoc.ip_port, client_list[i].client_id);
1820 } /* localize declarations */
1821
1822 break;
1823
1824 case DHT_STATE_TYPE_FRIENDS_ASSOC46: 1768 case DHT_STATE_TYPE_FRIENDS_ASSOC46:
1825 if (length % sizeof(DHT_Friend) != 0) 1769 if (length % sizeof(DHT_Friend) != 0)
1826 break; 1770 break;
@@ -1894,7 +1838,7 @@ int DHT_load_new(DHT *dht, uint8_t *data, uint32_t length)
1894 length - cookie_len, DHT_STATE_COOKIE_TYPE); 1838 length - cookie_len, DHT_STATE_COOKIE_TYPE);
1895 } 1839 }
1896 1840
1897 return DHT_load_old(dht, data, length); 1841 return -1;
1898} 1842}
1899/* return 0 if we are not connected to the DHT. 1843/* return 0 if we are not connected to the DHT.
1900 * return 1 if we are. 1844 * return 1 if we are.
@@ -1902,13 +1846,13 @@ int DHT_load_new(DHT *dht, uint8_t *data, uint32_t length)
1902int DHT_isconnected(DHT *dht) 1846int DHT_isconnected(DHT *dht)
1903{ 1847{
1904 uint32_t i; 1848 uint32_t i;
1905 uint64_t temp_time = unix_time(); 1849 unix_time_update();
1906 1850
1907 for (i = 0; i < LCLIENT_LIST; ++i) { 1851 for (i = 0; i < LCLIENT_LIST; ++i) {
1908 Client_data *client = &dht->close_clientlist[i]; 1852 Client_data *client = &dht->close_clientlist[i];
1909 1853
1910 if (!is_timeout(temp_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) || 1854 if (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) ||
1911 !is_timeout(temp_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)) 1855 !is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT))
1912 return 1; 1856 return 1;
1913 } 1857 }
1914 1858