summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoren[m] <Break@Ocean>2013-09-27 03:27:52 +0200
committerCoren[m] <Break@Ocean>2013-09-27 03:27:52 +0200
commit9de295374decd78fd676574bd38243479dfd6054 (patch)
treea614006e1919e1c16f67fe0c90b16114d0b47aab
parentbeff2b6de659a708ed366a9ae925eab8c4ca0ddd (diff)
expanded Client_data to hold two addresses (IPv4, IPv6) instead of one
Compilerflag: CLIENT_ONETOONE_IP (to define in DHT.h, default unset i.e. NEW case: two addresses) Every function in DHT{_test}.c working on Client_data has been rewritten to store IPv4 addresses in assoc4, IPv6 addresses in assoc6. Loading/Storing of states defined with other compiler switch is transparently adjusting to the differences. DHT.h, DHT.c: - introduction and handling of the structure changes DHT_test.c, Messenger.c: - logging adapted to new structures util.h: - LOGGING isn't undefined per default anymore
-rw-r--r--testing/DHT_test.c50
-rw-r--r--toxcore/DHT.c694
-rw-r--r--toxcore/DHT.h51
-rw-r--r--toxcore/Messenger.c49
-rw-r--r--toxcore/util.h2
5 files changed, 614 insertions, 232 deletions
diff --git a/testing/DHT_test.c b/testing/DHT_test.c
index 3cd1bce6..492586fc 100644
--- a/testing/DHT_test.c
+++ b/testing/DHT_test.c
@@ -52,26 +52,40 @@
52 52
53#define PORT 33445 53#define PORT 33445
54 54
55void print_assoc(IPPTsPng *assoc, uint8_t ours)
56{
57 IP_Port *ipp = &assoc->ip_port;
58 printf("\nIP: %s Port: %u", ip_ntoa(&ipp->ip), ntohs(ipp->port));
59 printf("\nTimestamp: %llu", (long long unsigned int) assoc->timestamp);
60 printf("\nLast pinged: %llu\n", (long long unsigned int) assoc->last_pinged);
61
62 ipp = &assoc->ret_ip_port;
63 if (ours)
64 printf("OUR IP: %s Port: %u\n", ip_ntoa(&ipp->ip), ntohs(ipp->port));
65 else
66 printf("RET IP: %s Port: %u\n", ip_ntoa(&ipp->ip), ntohs(ipp->port));
67 printf("Timestamp: %llu\n", (long long unsigned int) assoc->ret_timestamp);
68}
69
55void print_clientlist(DHT *dht) 70void print_clientlist(DHT *dht)
56{ 71{
57 uint32_t i, j; 72 uint32_t i, j;
58 IP_Port p_ip;
59 printf("___________________CLOSE________________________________\n"); 73 printf("___________________CLOSE________________________________\n");
60 74
61 for (i = 0; i < LCLIENT_LIST; i++) { 75 for (i = 0; i < LCLIENT_LIST; i++) {
76 Client_data *client = &dht->close_clientlist[i];
62 printf("ClientID: "); 77 printf("ClientID: ");
63 78
64 for (j = 0; j < CLIENT_ID_SIZE; j++) { 79 for (j = 0; j < CLIENT_ID_SIZE; j++) {
65 printf("%02hhX", dht->close_clientlist[i].client_id[j]); 80 printf("%02hhX", client->client_id[j]);
66 } 81 }
67 82
68 p_ip = dht->close_clientlist[i].ip_port; 83#ifdef CLIENT_ONETOONE_IP
69 printf("\nIP: %s Port: %u", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); 84 print_assoc(&client->assoc, 1);
70 printf("\nTimestamp: %llu", (long long unsigned int) dht->close_clientlist[i].timestamp); 85#else
71 printf("\nLast pinged: %llu\n", (long long unsigned int) dht->close_clientlist[i].last_pinged); 86 print_assoc(&client->assoc4, 1);
72 p_ip = dht->close_clientlist[i].ret_ip_port; 87 print_assoc(&client->assoc6, 1);
73 printf("OUR IP: %s Port: %u\n", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); 88#endif
74 printf("Timestamp: %llu\n", (long long unsigned int) dht->close_clientlist[i].ret_timestamp);
75 } 89 }
76} 90}
77 91
@@ -95,22 +109,22 @@ void print_friendlist(DHT *dht)
95 printf("\nCLIENTS IN LIST:\n\n"); 109 printf("\nCLIENTS IN LIST:\n\n");
96 110
97 for (i = 0; i < MAX_FRIEND_CLIENTS; i++) { 111 for (i = 0; i < MAX_FRIEND_CLIENTS; i++) {
112 Client_data *client = &dht->friends_list[k].client_list[i];
98 printf("ClientID: "); 113 printf("ClientID: ");
99 114
100 for (j = 0; j < CLIENT_ID_SIZE; j++) { 115 for (j = 0; j < CLIENT_ID_SIZE; j++) {
101 if (dht->friends_list[k].client_list[i].client_id[j] < 16) 116 if (client->client_id[j] < 16)
102 printf("0"); 117 printf("0");
103 118
104 printf("%hhX", dht->friends_list[k].client_list[i].client_id[j]); 119 printf("%hhX", client->client_id[j]);
105 } 120 }
106 121
107 p_ip = dht->friends_list[k].client_list[i].ip_port; 122#ifdef CLIENT_ONETOONE_IP
108 printf("\nIP: %s:%u", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); 123 print_assoc(&client->assoc, 0);
109 printf("\nTimestamp: %llu", (long long unsigned int) dht->friends_list[k].client_list[i].timestamp); 124#else
110 printf("\nLast pinged: %llu\n", (long long unsigned int) dht->friends_list[k].client_list[i].last_pinged); 125 print_assoc(&client->assoc4, 0);
111 p_ip = dht->friends_list[k].client_list[i].ret_ip_port; 126 print_assoc(&client->assoc6, 0);
112 printf("ret IP: %s:%u\n", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); 127#endif
113 printf("Timestamp: %llu\n", (long long unsigned int)dht->friends_list[k].client_list[i].ret_timestamp);
114 } 128 }
115 } 129 }
116} 130}
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index db3c5883..1c550628 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -43,7 +43,7 @@
43#define PING_TIMEOUT 5 43#define PING_TIMEOUT 5
44 44
45/* The timeout after which a node is discarded completely. */ 45/* The timeout after which a node is discarded completely. */
46#define Kill_NODE_TIMEOUT 300 46#define KILL_NODE_TIMEOUT 300
47 47
48/* Ping interval in seconds for each node in our lists. */ 48/* Ping interval in seconds for each node in our lists. */
49#define PING_INTERVAL 60 49#define PING_INTERVAL 60
@@ -136,6 +136,7 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t
136 uint32_t i; 136 uint32_t i;
137 uint64_t temp_time = unix_time(); 137 uint64_t temp_time = unix_time();
138 138
139#ifdef CLIENT_ONETOONE_IP
139 uint8_t candropipv4 = 1; 140 uint8_t candropipv4 = 1;
140 141
141 if (ip_port.ip.family == AF_INET6) { 142 if (ip_port.ip.family == AF_INET6) {
@@ -143,35 +144,71 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t
143 144
144 /* ipv6: count how many spots are used */ 145 /* ipv6: count how many spots are used */
145 for (i = 0; i < length; i++) 146 for (i = 0; i < length; i++)
146 if (list[i].ip_port.ip.family == AF_INET6) 147 if (list[i].assoc.ip_port.ip.family == AF_INET6)
147 ipv6cnt++; 148 ipv6cnt++;
148 149
149 /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */ 150 /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */
150 if (ipv6cnt > length / 2) 151 if (ipv6cnt > length / 2)
151 candropipv4 = 0; 152 candropipv4 = 0;
152 } 153 }
154#endif
153 155
154 /* if client_id is in list, find it and maybe overwrite ip_port */ 156 /* if client_id is in list, find it and maybe overwrite ip_port */
155 for (i = 0; i < length; ++i) 157 for (i = 0; i < length; ++i)
156 if (id_equal(list[i].client_id, client_id)) { 158 if (id_equal(list[i].client_id, client_id)) {
159 /* Refresh the client timestamp. */
160#ifdef CLIENT_ONETOONE_IP
157 /* if we got "too many" ipv6 addresses already, keep the ipv4 address */ 161 /* if we got "too many" ipv6 addresses already, keep the ipv4 address */
158 if (!candropipv4 && (list[i].ip_port.ip.family == AF_INET)) 162 if (!candropipv4 && (list[i].assoc.ip_port.ip.family == AF_INET))
159 return 1; 163 return 1;
160 164
161 /* Refresh the client timestamp. */ 165 list[i].assoc.ip_port = ip_port;
162 list[i].timestamp = temp_time; 166 list[i].assoc.timestamp = temp_time;
163 list[i].ip_port = ip_port; 167#else
168 if (ip_port.ip.family == AF_INET) {
169 list[i].assoc4.ip_port = ip_port;
170 list[i].assoc4.timestamp = temp_time;
171 } else if (ip_port.ip.family == AF_INET6) {
172 list[i].assoc6.ip_port = ip_port;
173 list[i].assoc6.timestamp = temp_time;
174 }
175#endif
164 return 1; 176 return 1;
165 } 177 }
166 178
167 /* client_id not in list yet: find ip_port to overwrite */ 179 /* client_id not in list yet: see if we can find an identical ip_port, in
168 for (i = 0; i < length; ++i) 180 * that case we kill the old client_id by overwriting it with the new one
169 if (ipport_equal(&list[i].ip_port, &ip_port)) { 181 * TODO: maybe we SHOULDN'T do that if that client_id is in a friend_list
170 /* Refresh the client timestamp. */ 182 * and the one who is the actual friend's client_id/address set? */
171 list[i].timestamp = temp_time; 183 for (i = 0; i < length; ++i) {
184#ifdef CLIENT_ONETOONE_IP
185 if (ipport_equal(&list[i].assoc.ip_port, &ip_port)) {
186 /* Initialize client timestamp. */
187 list[i].assoc.timestamp = temp_time;
172 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 188 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
173 return 1; 189 return 1;
174 } 190 }
191#else
192 /* MAYBE: check the other address, if valid, don't nuke? */
193 if ((ip_port.ip.family == AF_INET) && ipport_equal(&list[i].assoc4.ip_port, &ip_port)) {
194 /* Initialize client timestamp. */
195 list[i].assoc4.timestamp = temp_time;
196 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
197
198 /* kill the other address, if it was set */
199 memset(&list[i].assoc6, 0, sizeof(list[i].assoc6));
200 return 1;
201 } else if ((ip_port.ip.family == AF_INET6) && ipport_equal(&list[i].assoc6.ip_port, &ip_port)) {
202 /* Initialize client timestamp. */
203 list[i].assoc6.timestamp = temp_time;
204 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
205
206 /* kill the other address, if it was set */
207 memset(&list[i].assoc4, 0, sizeof(list[i].assoc4));
208 return 1;
209 }
210#endif
211 }
175 212
176 return 0; 213 return 0;
177} 214}
@@ -215,17 +252,30 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
215 sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, 252 sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length,
216 time_t timestamp, int *num_nodes_ptr) 253 time_t timestamp, int *num_nodes_ptr)
217{ 254{
255 if ((sa_family != AF_INET) && (sa_family != AF_INET6))
256 return;
257
218 int num_nodes = *num_nodes_ptr; 258 int num_nodes = *num_nodes_ptr;
219 int tout, inlist, ipv46x, j, closest; 259 int tout, inlist, ipv46x, j, closest;
220 uint32_t i; 260 uint32_t i;
221 261
222 for (i = 0; i < client_list_length; i++) { 262 for (i = 0; i < client_list_length; i++) {
223 Client_data *client = &client_list[i]; 263 Client_data *client = &client_list[i];
224 tout = is_timeout(timestamp, client->timestamp, BAD_NODE_TIMEOUT); 264 IPPTsPng *ipptp = NULL;
265#ifdef CLIENT_ONETOONE_IP
266 ipptp = &client->assoc;
267#else
268 if (sa_family == AF_INET)
269 ipptp = &client->assoc4;
270 else
271 ipptp = &client->assoc6;
272#endif
273
274 tout = is_timeout(timestamp, ipptp->timestamp, BAD_NODE_TIMEOUT);
225 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, client->client_id); 275 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, client->client_id);
226 276
227#ifdef TOX_ENABLE_IPV6 277#ifdef TOX_ENABLE_IPV6
228 IP *client_ip = &client->ip_port.ip; 278 IP *client_ip = &ipptp->ip_port.ip;
229 279
230 /* 280 /*
231 * Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for 281 * Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for
@@ -237,7 +287,8 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
237 if ((dht->c->lossless_udp->net->family == AF_INET6) && 287 if ((dht->c->lossless_udp->net->family == AF_INET6) &&
238 (client_ip->family == AF_INET6)) { 288 (client_ip->family == AF_INET6)) {
239 /* socket is AF_INET6, address claims AF_INET6: 289 /* socket is AF_INET6, address claims AF_INET6:
240 * check for embedded IPv4-in-IPv6 */ 290 * check for embedded IPv4-in-IPv6 (shouldn't happen anymore,
291 * all storing functions should already convert down to IPv4) */
241 if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6.in6_addr)) 292 if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6.in6_addr))
242 ip_treat_as_family = AF_INET; 293 ip_treat_as_family = AF_INET;
243 } 294 }
@@ -256,7 +307,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
256 client->client_id, 307 client->client_id,
257 CLIENT_ID_SIZE ); 308 CLIENT_ID_SIZE );
258 309
259 nodes_list[num_nodes].ip_port = client->ip_port; 310 nodes_list[num_nodes].ip_port = ipptp->ip_port;
260 num_nodes++; 311 num_nodes++;
261 } else { 312 } else {
262 /* see if node_list contains a client_id that's "further away" 313 /* see if node_list contains a client_id that's "further away"
@@ -274,7 +325,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
274 client->client_id, 325 client->client_id,
275 CLIENT_ID_SIZE); 326 CLIENT_ID_SIZE);
276 327
277 nodes_list[j].ip_port = client->ip_port; 328 nodes_list[j].ip_port = ipptp->ip_port;
278 break; 329 break;
279 } 330 }
280 } 331 }
@@ -315,9 +366,13 @@ static int replace_bad( Client_data *list,
315 uint8_t *client_id, 366 uint8_t *client_id,
316 IP_Port ip_port ) 367 IP_Port ip_port )
317{ 368{
369 if ((ip_port.ip.family != AF_INET) && (ip_port.ip.family != AF_INET6))
370 return 1;
371
318 uint32_t i; 372 uint32_t i;
319 uint64_t temp_time = unix_time(); 373 uint64_t temp_time = unix_time();
320 374
375#ifdef CLIENT_ONETOONE_IP
321 uint8_t candropipv4 = 1; 376 uint8_t candropipv4 = 1;
322 377
323 if (ip_port.ip.family == AF_INET6) { 378 if (ip_port.ip.family == AF_INET6) {
@@ -325,26 +380,39 @@ static int replace_bad( Client_data *list,
325 380
326 /* ipv6: count how many spots are used */ 381 /* ipv6: count how many spots are used */
327 for (i = 0; i < length; i++) 382 for (i = 0; i < length; i++)
328 if (list[i].ip_port.ip.family == AF_INET6) 383 if (list[i].assoc.ip_port.ip.family == AF_INET6)
329 ipv6cnt++; 384 ipv6cnt++;
330 385
331 /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */ 386 /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */
332 if (ipv6cnt > length / 2) 387 if (ipv6cnt > length / 2)
333 candropipv4 = 0; 388 candropipv4 = 0;
334 } 389 }
335 390#endif
336 for (i = 0; i < length; ++i) { 391 for (i = 0; i < length; ++i) {
337 /* If node is bad */ 392 /* If node is bad */
338 Client_data *client = &list[i]; 393 Client_data *client = &list[i];
394 IPPTsPng *ipptp = NULL;
395
396#ifdef CLIENT_ONETOONE_IP
397 ipptp = &client->assoc;
398 if ((candropipv4 || (ipptp->ip_port.ip.family == AF_INET6)) &&
399 is_timeout(temp_time, ipptp->timestamp, BAD_NODE_TIMEOUT)) {
400#else
401 if (ip_port.ip.family == AF_INET)
402 ipptp = &client->assoc4;
403 else
404 ipptp = &client->assoc6;
339 405
340 if ((candropipv4 || (client->ip_port.ip.family == AF_INET6)) && 406 if (is_timeout(temp_time, ipptp->timestamp, BAD_NODE_TIMEOUT)) {
341 is_timeout(temp_time, client->timestamp, BAD_NODE_TIMEOUT)) { 407#endif
342 memcpy(client->client_id, client_id, CLIENT_ID_SIZE); 408 memcpy(client->client_id, client_id, CLIENT_ID_SIZE);
343 client->ip_port = ip_port; 409 ipptp->ip_port = ip_port;
344 client->timestamp = temp_time; 410 ipptp->timestamp = temp_time;
345 ip_reset(&client->ret_ip_port.ip); 411
346 client->ret_ip_port.port = 0; 412 ip_reset(&ipptp->ret_ip_port.ip);
347 client->ret_timestamp = 0; 413 ipptp->ret_ip_port.port = 0;
414 ipptp->ret_timestamp = 0;
415
348 return 0; 416 return 0;
349 } 417 }
350 } 418 }
@@ -381,8 +449,14 @@ static int replace_good( Client_data *list,
381 IP_Port ip_port, 449 IP_Port ip_port,
382 uint8_t *comp_client_id ) 450 uint8_t *comp_client_id )
383{ 451{
452 if ((ip_port.ip.family != AF_INET) && (ip_port.ip.family != AF_INET6))
453 return 1;
454
384 sort_list(list, length, comp_client_id); 455 sort_list(list, length, comp_client_id);
385 456
457 int8_t replace = -1;
458
459#ifdef CLIENT_ONETOONE_IP
386 uint8_t candropipv4 = 1; 460 uint8_t candropipv4 = 1;
387 461
388 if (ip_port.ip.family == AF_INET6) { 462 if (ip_port.ip.family == AF_INET6) {
@@ -390,7 +464,7 @@ static int replace_good( Client_data *list,
390 464
391 /* ipv6: count how many spots are used */ 465 /* ipv6: count how many spots are used */
392 for (i = 0; i < length; i++) 466 for (i = 0; i < length; i++)
393 if (list[i].ip_port.ip.family == AF_INET6) 467 if (list[i].assoc.ip_port.ip.family == AF_INET6)
394 ipv6cnt++; 468 ipv6cnt++;
395 469
396 /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */ 470 /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */
@@ -398,7 +472,6 @@ static int replace_good( Client_data *list,
398 candropipv4 = 0; 472 candropipv4 = 0;
399 } 473 }
400 474
401 int8_t replace = -1;
402 uint32_t i; 475 uint32_t i;
403 476
404 if (candropipv4) { 477 if (candropipv4) {
@@ -414,8 +487,10 @@ static int replace_good( Client_data *list,
414 * so the furthest element is the first, NOT the last (at least that's 487 * so the furthest element is the first, NOT the last (at least that's
415 * what the comment above sort_list() claims) 488 * what the comment above sort_list() claims)
416 */ 489 */
490#endif
417 if (id_closest(comp_client_id, list[0].client_id, client_id) == 2) 491 if (id_closest(comp_client_id, list[0].client_id, client_id) == 2)
418 replace = 0; 492 replace = 0;
493#ifdef CLIENT_ONETOONE_IP
419 } else { 494 } else {
420 /* ipv6 case without a right to push out an ipv4: only look for ipv6 495 /* ipv6 case without a right to push out an ipv4: only look for ipv6
421 * addresses, the first one we find is either closer (then we can skip 496 * addresses, the first one we find is either closer (then we can skip
@@ -424,7 +499,7 @@ static int replace_good( Client_data *list,
424 for (i = 0; i < length; i++) { 499 for (i = 0; i < length; i++) {
425 Client_data *client = &list[i]; 500 Client_data *client = &list[i];
426 501
427 if (client->ip_port.ip.family == AF_INET6) { 502 if (client->assoc.ip_port.ip.family == AF_INET6) {
428 if (id_closest(comp_client_id, list[i].client_id, client_id) == 2) 503 if (id_closest(comp_client_id, list[i].client_id, client_id) == 2)
429 replace = i; 504 replace = i;
430 505
@@ -432,18 +507,29 @@ static int replace_good( Client_data *list,
432 } 507 }
433 } 508 }
434 } 509 }
510#endif
435 511
436 if (replace != -1) { 512 if (replace != -1) {
437#ifdef DEBUG 513#ifdef DEBUG
438 assert(replace >= 0 && replace < length); 514 assert(replace >= 0 && replace < length);
439#endif 515#endif
440 Client_data *client = &list[replace]; 516 Client_data *client = &list[replace];
517 IPPTsPng *ipptp = NULL;
518#ifdef CLIENT_ONETOONE_IP
519 ipptp = &client->assoc;
520#else
521 if (ip_port.ip.family == AF_INET)
522 ipptp = &client->assoc4;
523 else
524 ipptp = &client->assoc6;
525#endif
441 memcpy(client->client_id, client_id, CLIENT_ID_SIZE); 526 memcpy(client->client_id, client_id, CLIENT_ID_SIZE);
442 client->ip_port = ip_port; 527 ipptp->ip_port = ip_port;
443 client->timestamp = unix_time(); 528 ipptp->timestamp = unix_time();
444 ip_reset(&client->ret_ip_port.ip); 529
445 client->ret_ip_port.port = 0; 530 ip_reset(&ipptp->ret_ip_port.ip);
446 client->ret_timestamp = 0; 531 ipptp->ret_ip_port.port = 0;
532 ipptp->ret_timestamp = 0;
447 return 0; 533 return 0;
448 } 534 }
449 535
@@ -496,25 +582,48 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint
496 uint32_t i, j; 582 uint32_t i, j;
497 uint64_t temp_time = unix_time(); 583 uint64_t temp_time = unix_time();
498 584
499 if (id_equal(client_id, dht->c->self_public_key)) { 585 /* convert IPv4-in-IPv6 to IPv4 */
586 if ((ip_port.ip.family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&ip_port.ip.ip6.in6_addr)) {
587 ip_port.ip.family = AF_INET;
588 ip_port.ip.ip4.uint32 = ip_port.ip.ip6.uint32[3];
589 }
500 590
591 if (id_equal(client_id, dht->c->self_public_key)) {
501 for (i = 0; i < LCLIENT_LIST; ++i) { 592 for (i = 0; i < LCLIENT_LIST; ++i) {
502 if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) { 593 if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) {
503 dht->close_clientlist[i].ret_ip_port = ip_port; 594#ifdef CLIENT_ONETOONE_IP
504 dht->close_clientlist[i].ret_timestamp = temp_time; 595 dht->close_clientlist[i].assoc.ret_ip_port = ip_port;
596 dht->close_clientlist[i].assoc.ret_timestamp = temp_time;
597#else
598 if (ip_port.ip.family == AF_INET) {
599 dht->close_clientlist[i].assoc4.ret_ip_port = ip_port;
600 dht->close_clientlist[i].assoc4.ret_timestamp = temp_time;
601 } else if (ip_port.ip.family == AF_INET6) {
602 dht->close_clientlist[i].assoc6.ret_ip_port = ip_port;
603 dht->close_clientlist[i].assoc6.ret_timestamp = temp_time;
604 }
605#endif
505 return; 606 return;
506 } 607 }
507 } 608 }
508 609
509 } else { 610 } else {
510
511 for (i = 0; i < dht->num_friends; ++i) { 611 for (i = 0; i < dht->num_friends; ++i) {
512 if (id_equal(client_id, dht->friends_list[i].client_id)) { 612 if (id_equal(client_id, dht->friends_list[i].client_id)) {
513
514 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 613 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
515 if (id_equal(nodeclient_id, dht->friends_list[i].client_list[j].client_id)) { 614 if (id_equal(nodeclient_id, dht->friends_list[i].client_list[j].client_id)) {
516 dht->friends_list[i].client_list[j].ret_ip_port = ip_port; 615#ifdef CLIENT_ONETOONE_IP
517 dht->friends_list[i].client_list[j].ret_timestamp = temp_time; 616 dht->friends_list[i].client_list[j].assoc.ret_ip_port = ip_port;
617 dht->friends_list[i].client_list[j].assoc.ret_timestamp = temp_time;
618#else
619 if (ip_port.ip.family == AF_INET) {
620 dht->friends_list[i].client_list[j].assoc4.ret_ip_port = ip_port;
621 dht->friends_list[i].client_list[j].assoc4.ret_timestamp = temp_time;
622 } else if (ip_port.ip.family == AF_INET6) {
623 dht->friends_list[i].client_list[j].assoc6.ret_ip_port = ip_port;
624 dht->friends_list[i].client_list[j].assoc6.ret_timestamp = temp_time;
625 }
626#endif
518 return; 627 return;
519 } 628 }
520 } 629 }
@@ -897,14 +1006,29 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_
897 uint64_t temp_time = unix_time(); 1006 uint64_t temp_time = unix_time();
898 uint32_t i, num = 0; 1007 uint32_t i, num = 0;
899 1008
900 for (i = 0; i < length; ++i) 1009 for (i = 0; i < length; ++i) {
901 if (ipport_isset(&(list[i].ip_port)) && !is_timeout(temp_time, list[i].ret_timestamp, BAD_NODE_TIMEOUT)) { 1010 IPPTsPng *assoc;
902 getnodes(dht, list[i].ip_port, list[i].client_id, client_id); 1011#ifdef CLIENT_ONETOONE_IP
903 ++num; 1012 assoc = &list[i].assoc;
1013 if (1) {
1014#else
1015 uint32_t a;
1016 for (a = 0; a < 2; a++) {
1017 if (!a)
1018 assoc = &list[i].assoc6;
1019 else
1020 assoc = &list[i].assoc4;
1021#endif
1022 if (ipport_isset(&(assoc->ip_port)) &&
1023 !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
1024 getnodes(dht, assoc->ip_port, list[i].client_id, client_id);
1025 ++num;
904 1026
905 if (num >= max_num) 1027 if (num >= max_num)
906 return; 1028 return;
1029 }
907 } 1030 }
1031 }
908} 1032}
909 1033
910int DHT_addfriend(DHT *dht, uint8_t *client_id) 1034int DHT_addfriend(DHT *dht, uint8_t *client_id)
@@ -922,7 +1046,7 @@ int DHT_addfriend(DHT *dht, uint8_t *client_id)
922 memset(&dht->friends_list[dht->num_friends], 0, sizeof(DHT_Friend)); 1046 memset(&dht->friends_list[dht->num_friends], 0, sizeof(DHT_Friend));
923 memcpy(dht->friends_list[dht->num_friends].client_id, client_id, CLIENT_ID_SIZE); 1047 memcpy(dht->friends_list[dht->num_friends].client_id, client_id, CLIENT_ID_SIZE);
924 1048
925 dht->friends_list[dht->num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int(); 1049 dht->friends_list[dht->num_friends].nat.NATping_id = ((uint64_t)random_int() << 32) + random_int();
926 ++dht->num_friends; 1050 ++dht->num_friends;
927 get_bunchnodes(dht, dht->close_clientlist, LCLIENT_LIST, MAX_FRIEND_CLIENTS, client_id);/*TODO: make this better?*/ 1051 get_bunchnodes(dht, dht->close_clientlist, LCLIENT_LIST, MAX_FRIEND_CLIENTS, client_id);/*TODO: make this better?*/
928 return 0; 1052 return 0;
@@ -976,10 +1100,25 @@ int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port)
976 /* Equal */ 1100 /* Equal */
977 if (id_equal(dht->friends_list[i].client_id, client_id)) { 1101 if (id_equal(dht->friends_list[i].client_id, client_id)) {
978 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 1102 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
979 if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id) 1103 Client_data *client = &dht->friends_list[i].client_list[j];
980 && !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { 1104 if (id_equal(client->client_id, client_id)) {
981 *ip_port = dht->friends_list[i].client_list[j].ip_port; 1105 IPPTsPng *assoc = NULL;
982 return 1; 1106#ifdef CLIENT_ONETOONE_IP
1107 assoc = &client->assoc;
1108 if (1) {
1109#else
1110 uint32_t a;
1111 for (a = 0; a < 2; a++) {
1112 if (!a)
1113 assoc = &client->assoc6;
1114 else
1115 assoc = &client->assoc4;
1116#endif
1117 if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) {
1118 *ip_port = assoc->ip_port;
1119 return 1;
1120 }
1121 }
983 } 1122 }
984 } 1123 }
985 1124
@@ -990,81 +1129,75 @@ int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port)
990 return -1; 1129 return -1;
991} 1130}
992 1131
993/* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request 1132static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8_t *client_id,
994 * every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list. 1133 Client_data *list, uint32_t list_count)
995 */
996static void do_DHT_friends(DHT *dht)
997{ 1134{
998 uint32_t i, j; 1135 uint32_t i;
999 uint64_t temp_time = unix_time(); 1136 uint64_t temp_time = unix_time();
1000 uint32_t rand_node;
1001 uint32_t index[MAX_FRIEND_CLIENTS];
1002 1137
1003 for (i = 0; i < dht->num_friends; ++i) { 1138 uint32_t num_nodes = 0;
1004 uint32_t num_nodes = 0; 1139 Client_data *client_list[list_count];
1005 1140 IPPTsPng *assoc_list[list_count];
1006 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 1141
1007 /* If node is not dead. */ 1142 for (i = 0; i < list_count; i++) {
1008 if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { 1143 /* If node is not dead. */
1009 if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 1144 Client_data *client = &list[i];
1010 send_ping_request(dht->ping, dht->friends_list[i].client_list[j].ip_port, 1145 IPPTsPng *assoc;
1011 dht->friends_list[i].client_list[j].client_id ); 1146#ifdef CLIENT_ONETOONE_IP
1012 dht->friends_list[i].client_list[j].last_pinged = temp_time; 1147 assoc = &client->assoc;
1148 if (1) {
1149#else
1150 uint32_t a;
1151 for (a = 0; a < 2; a++) {
1152 if (!a)
1153 assoc = &client->assoc6;
1154 else
1155 assoc = &client->assoc4;
1156#endif
1157
1158 if (!is_timeout(temp_time, assoc->timestamp, KILL_NODE_TIMEOUT)) {
1159 if (is_timeout(temp_time, assoc->last_pinged, PING_INTERVAL)) {
1160 send_ping_request(dht->ping, assoc->ip_port, client->client_id );
1161 assoc->last_pinged = temp_time;
1013 } 1162 }
1014 1163
1015 /* If node is good. */ 1164 /* If node is good. */
1016 if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { 1165 if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) {
1017 index[num_nodes] = j; 1166 client_list[num_nodes] = client;
1167 assoc_list[num_nodes] = assoc;
1018 ++num_nodes; 1168 ++num_nodes;
1019 } 1169 }
1020 } 1170 }
1021 } 1171 }
1172 }
1022 1173
1023 if (dht->friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { 1174 if ((num_nodes != 0) &&
1024 rand_node = rand() % num_nodes; 1175 is_timeout(temp_time, *lastgetnode, GET_NODE_INTERVAL)) {
1025 getnodes(dht, dht->friends_list[i].client_list[index[rand_node]].ip_port, 1176 uint32_t rand_node = rand() % num_nodes;
1026 dht->friends_list[i].client_list[index[rand_node]].client_id, 1177 getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id,
1027 dht->friends_list[i].client_id ); 1178 client_id);
1028 dht->friends_list[i].lastgetnode = temp_time; 1179 *lastgetnode = temp_time;
1029 }
1030 } 1180 }
1031} 1181}
1032 1182
1183/* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request
1184 * every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list.
1185 */
1186static void do_DHT_friends(DHT *dht)
1187{
1188 uint32_t i;
1189 for (i = 0; i < dht->num_friends; ++i)
1190 do_ping_and_sendnode_requests(dht, &dht->friends_list[i].lastgetnode, dht->friends_list[i].client_id,
1191 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS);
1192}
1193
1033/* Ping each client in the close nodes list every PING_INTERVAL seconds. 1194/* Ping each client in the close nodes list every PING_INTERVAL seconds.
1034 * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list. 1195 * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list.
1035 */ 1196 */
1036static void do_Close(DHT *dht) 1197static void do_Close(DHT *dht)
1037{ 1198{
1038 uint32_t i; 1199 do_ping_and_sendnode_requests(dht, &dht->close_lastgetnodes, dht->c->self_public_key,
1039 uint64_t temp_time = unix_time(); 1200 dht->close_clientlist, LCLIENT_LIST);
1040 uint32_t num_nodes = 0;
1041 uint32_t rand_node;
1042 uint32_t index[LCLIENT_LIST];
1043
1044 for (i = 0; i < LCLIENT_LIST; ++i) {
1045 /* If node is not dead. */
1046 if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) {
1047 if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
1048 send_ping_request(dht->ping, dht->close_clientlist[i].ip_port,
1049 dht->close_clientlist[i].client_id );
1050 dht->close_clientlist[i].last_pinged = temp_time;
1051 }
1052
1053 /* If node is good. */
1054 if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) {
1055 index[num_nodes] = i;
1056 ++num_nodes;
1057 }
1058 }
1059 }
1060
1061 if (dht->close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
1062 rand_node = rand() % num_nodes;
1063 getnodes(dht, dht->close_clientlist[index[rand_node]].ip_port,
1064 dht->close_clientlist[index[rand_node]].client_id,
1065 dht->c->self_public_key );
1066 dht->close_lastgetnodes = temp_time;
1067 }
1068} 1201}
1069 1202
1070void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) 1203void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
@@ -1116,8 +1249,20 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
1116 uint32_t i; 1249 uint32_t i;
1117 1250
1118 for (i = 0; i < LCLIENT_LIST; ++i) { 1251 for (i = 0; i < LCLIENT_LIST; ++i) {
1119 if (id_equal(client_id, dht->close_clientlist[i].client_id)) 1252 if (id_equal(client_id, dht->close_clientlist[i].client_id)) {
1120 return sendpacket(dht->c->lossless_udp->net, dht->close_clientlist[i].ip_port, packet, length); 1253 Client_data *client = &dht->close_clientlist[i];
1254#ifdef CLIENT_ONETOONE_IP
1255 if (ip_isset(&client->assoc.ip_port.ip))
1256 return sendpacket(dht->c->lossless_udp->net, dht->close_clientlist[i].assoc.ip_port, packet, length);
1257#else
1258 if (ip_isset(&client->assoc6.ip_port.ip))
1259 return sendpacket(dht->c->lossless_udp->net, client->assoc6.ip_port, packet, length);
1260 else if (ip_isset(&client->assoc4.ip_port.ip))
1261 return sendpacket(dht->c->lossless_udp->net, client->assoc4.ip_port, packet, length);
1262 else
1263 break;
1264#endif
1265 }
1121 } 1266 }
1122 1267
1123 return -1; 1268 return -1;
@@ -1132,8 +1277,7 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
1132 */ 1277 */
1133static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) 1278static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
1134{ 1279{
1135 int num_ips = 0; 1280 int i, num_ips = 0;
1136 uint32_t i;
1137 uint64_t temp_time = unix_time(); 1281 uint64_t temp_time = unix_time();
1138 1282
1139 if (friend_num >= dht->num_friends) 1283 if (friend_num >= dht->num_friends)
@@ -1142,18 +1286,89 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
1142 DHT_Friend *friend = &dht->friends_list[friend_num]; 1286 DHT_Friend *friend = &dht->friends_list[friend_num];
1143 Client_data *client; 1287 Client_data *client;
1144 1288
1145 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 1289#ifndef CLIENT_ONETOONE_IP
1146 client = &(friend->client_list[i]); 1290 /* extra legwork, because having the outside allocating the space for us
1291 * is *usually* good(tm) (bites us in the behind in this case though) */
1292 int client_friend = -1;
1293 uint8_t client_friend_flags = 0;
1294 uint32_t a;
1147 1295
1148 if (id_equal(client->client_id, friend->client_id) && !is_timeout(temp_time, client->timestamp, BAD_NODE_TIMEOUT)) 1296 for(a = 0; a < 2; a++)
1149 return 0; 1297#endif
1298 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
1299 client = &(friend->client_list[i]);
1150 1300
1151 /* If ip is not zero and node is good. */ 1301 IPPTsPng *assoc = NULL;
1152 if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { 1302#ifdef CLIENT_ONETOONE_IP
1153 ip_portlist[num_ips] = client->ret_ip_port; 1303 assoc = &client->assoc;
1154 ++num_ips; 1304#else
1305 /* this is the one place where ipv4 is favored over ipv6, because
1306 * we can't be sure there's enough space to return both, and we do
1307 * need to return IPv4 (because of the majority of the people still
1308 * lacking IPv6 connectivity) */
1309 if (!a)
1310 assoc = &client->assoc4;
1311 else
1312 assoc = &client->assoc6;
1313#endif
1314 if (id_equal(client->client_id, friend->client_id) &&
1315 !is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT))
1316 return 0;
1317
1318 /* If ip is not zero and node is good. */
1319 if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
1320 ip_portlist[num_ips] = assoc->ret_ip_port;
1321 ++num_ips;
1322
1323#ifndef CLIENT_ONETOONE_IP
1324 if ((client_friend == -1) && id_equal(client->client_id, friend->client_id))
1325 client_friend = i;
1326
1327 if (client_friend == i)
1328 client_friend_flags |= 1 << a;
1329
1330 if (num_ips == MAX_FRIEND_CLIENTS) {
1331 /* if we got "real" IP addresses for the friend and we added
1332 * the ipv4 one, but (maybe) couldn't add the ipv6 one
1333 * due to space constraints... */
1334 if ((client_friend != -1) && (client_friend_flags == 1)) {
1335 assoc = &friend->client_list[client_friend].assoc6;
1336
1337 /* but the IPv6 address WOULD be valid... (which also
1338 * means there is DEFINITELY a functioning IPv6 stack
1339 * and connectivity!) */
1340 if (ip_isset(&assoc->ret_ip_port.ip) &&
1341 !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
1342 uint32_t r;
1343
1344 /* then kick another entry out:
1345 * first, try to find an IPv6 entry to kick
1346 * (don't need to look for friend's, because he
1347 * definitely hasn't been added yet) */
1348 for (r = 0; r < MAX_FRIEND_CLIENTS; r++)
1349 if (ip_portlist[r].ip.family == AF_INET6) {
1350 ip_portlist[r] = assoc->ip_port;
1351 return num_ips;
1352 }
1353
1354 /* no IPv6 found to kick:
1355 * kick the first IPv4 that is NOT the friend's one */
1356 for (r = 0; r < MAX_FRIEND_CLIENTS; r++)
1357 if ((ip_portlist[r].ip.family == AF_INET) &&
1358 !ipport_equal(&ip_portlist[r], &assoc->ip_port)) {
1359 ip_portlist[r] = assoc->ip_port;
1360 return num_ips;
1361 }
1362
1363 /* shouldn't be reached... */
1364 }
1365 }
1366
1367 return num_ips;
1368 }
1369#endif
1370 }
1155 } 1371 }
1156 }
1157 1372
1158 return num_ips; 1373 return num_ips;
1159} 1374}
@@ -1177,23 +1392,39 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
1177 int ip_num = friend_iplist(dht, ip_list, num); 1392 int ip_num = friend_iplist(dht, ip_list, num);
1178 1393
1179 if (ip_num < (MAX_FRIEND_CLIENTS / 2)) 1394 if (ip_num < (MAX_FRIEND_CLIENTS / 2))
1180 return 0; 1395 return 0; /* Reason for that? */
1181 1396
1182 uint64_t temp_time = unix_time(); 1397 uint64_t temp_time = unix_time();
1183 DHT_Friend *friend = &dht->friends_list[num]; 1398 DHT_Friend *friend = &dht->friends_list[num];
1184 Client_data *client; 1399 Client_data *client;
1185 1400
1186 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 1401#ifndef CLIENT_ONETOONE_IP
1187 client = &friend->client_list[i]; 1402 /* extra legwork, because having the outside allocating the space for us
1403 * is *usually* good(tm) (bites us in the behind in this case though) */
1404 uint32_t a;
1188 1405
1189 /* If ip is not zero and node is good. */ 1406 for(a = 0; a < 2; a++)
1190 if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { 1407#endif
1191 int retval = sendpacket(dht->c->lossless_udp->net, client->ip_port, packet, length); 1408 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
1409 client = &friend->client_list[i];
1410 IPPTsPng *assoc = NULL;
1411#ifdef CLIENT_ONETOONE_IP
1412 assoc = &client->assoc;
1413#else
1414 if (!a)
1415 assoc = &client->assoc4;
1416 else
1417 assoc = &client->assoc6;
1418#endif
1419 /* If ip is not zero and node is good. */
1420 if (ip_isset(&assoc->ret_ip_port.ip) &&
1421 !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
1422 int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length);
1192 1423
1193 if ((unsigned int)retval == length) 1424 if ((unsigned int)retval == length)
1194 ++sent; 1425 ++sent;
1426 }
1195 } 1427 }
1196 }
1197 1428
1198 return sent; 1429 return sent;
1199} 1430}
@@ -1212,20 +1443,35 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
1212 DHT_Friend *friend = &dht->friends_list[num]; 1443 DHT_Friend *friend = &dht->friends_list[num];
1213 Client_data *client; 1444 Client_data *client;
1214 1445
1215 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 1446 IP_Port ip_list[MAX_FRIEND_CLIENTS * 2];
1216 int n = 0; 1447 int n = 0;
1217 uint32_t i; 1448 uint32_t i;
1218 uint64_t temp_time = unix_time(); 1449 uint64_t temp_time = unix_time();
1219 1450
1220 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 1451#ifndef CLIENT_ONETOONE_IP
1221 client = &friend->client_list[i]; 1452 /* extra legwork, because having the outside allocating the space for us
1453 * is *usually* good(tm) (bites us in the behind in this case though) */
1454 uint32_t a;
1222 1455
1223 /* If ip is not zero and node is good. */ 1456 for(a = 0; a < 2; a++)
1224 if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { 1457#endif
1225 ip_list[n] = client->ip_port; 1458 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
1226 ++n; 1459 client = &friend->client_list[i];
1460 IPPTsPng *assoc = NULL;
1461#ifdef CLIENT_ONETOONE_IP
1462 assoc = &client->assoc;
1463#else
1464 if (!a)
1465 assoc = &client->assoc4;
1466 else
1467 assoc = &client->assoc6;
1468#endif
1469 /* If ip is not zero and node is good. */
1470 if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
1471 ip_list[n] = assoc->ip_port;
1472 ++n;
1473 }
1227 } 1474 }
1228 }
1229 1475
1230 if (n < 1) 1476 if (n < 1)
1231 return 0; 1477 return 0;
@@ -1308,12 +1554,12 @@ static int handle_NATping(void *object, IP_Port source, uint8_t *source_pubkey,
1308 if (packet[0] == NAT_PING_REQUEST) { 1554 if (packet[0] == NAT_PING_REQUEST) {
1309 /* 1 is reply */ 1555 /* 1 is reply */
1310 send_NATping(dht, source_pubkey, ping_id, NAT_PING_RESPONSE); 1556 send_NATping(dht, source_pubkey, ping_id, NAT_PING_RESPONSE);
1311 friend->recvNATping_timestamp = unix_time(); 1557 friend->nat.recvNATping_timestamp = unix_time();
1312 return 0; 1558 return 0;
1313 } else if (packet[0] == NAT_PING_RESPONSE) { 1559 } else if (packet[0] == NAT_PING_RESPONSE) {
1314 if (friend->NATping_id == ping_id) { 1560 if (friend->nat.NATping_id == ping_id) {
1315 friend->NATping_id = ((uint64_t)random_int() << 32) + random_int(); 1561 friend->nat.NATping_id = ((uint64_t)random_int() << 32) + random_int();
1316 friend->hole_punching = 1; 1562 friend->nat.hole_punching = 1;
1317 return 0; 1563 return 0;
1318 } 1564 }
1319 } 1565 }
@@ -1378,9 +1624,9 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports,
1378 return; 1624 return;
1379 1625
1380 uint32_t i; 1626 uint32_t i;
1381 uint32_t top = dht->friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; 1627 uint32_t top = dht->friends_list[friend_num].nat.punching_index + MAX_PUNCHING_PORTS;
1382 1628
1383 for (i = dht->friends_list[friend_num].punching_index; i != top; i++) { 1629 for (i = dht->friends_list[friend_num].nat.punching_index; i != top; i++) {
1384 /* TODO: Improve port guessing algorithm. */ 1630 /* TODO: Improve port guessing algorithm. */
1385 uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); 1631 uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1);
1386 IP_Port pinging; 1632 IP_Port pinging;
@@ -1389,7 +1635,7 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports,
1389 send_ping_request(dht->ping, pinging, dht->friends_list[friend_num].client_id); 1635 send_ping_request(dht->ping, pinging, dht->friends_list[friend_num].client_id);
1390 } 1636 }
1391 1637
1392 dht->friends_list[friend_num].punching_index = i; 1638 dht->friends_list[friend_num].nat.punching_index = i;
1393} 1639}
1394 1640
1395static void do_NAT(DHT *dht) 1641static void do_NAT(DHT *dht)
@@ -1405,14 +1651,14 @@ static void do_NAT(DHT *dht)
1405 if (num < MAX_FRIEND_CLIENTS / 2) 1651 if (num < MAX_FRIEND_CLIENTS / 2)
1406 continue; 1652 continue;
1407 1653
1408 if (dht->friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { 1654 if (dht->friends_list[i].nat.NATping_timestamp + PUNCH_INTERVAL < temp_time) {
1409 send_NATping(dht, dht->friends_list[i].client_id, dht->friends_list[i].NATping_id, NAT_PING_REQUEST); 1655 send_NATping(dht, dht->friends_list[i].client_id, dht->friends_list[i].nat.NATping_id, NAT_PING_REQUEST);
1410 dht->friends_list[i].NATping_timestamp = temp_time; 1656 dht->friends_list[i].nat.NATping_timestamp = temp_time;
1411 } 1657 }
1412 1658
1413 if (dht->friends_list[i].hole_punching == 1 && 1659 if (dht->friends_list[i].nat.hole_punching == 1 &&
1414 dht->friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && 1660 dht->friends_list[i].nat.punching_timestamp + PUNCH_INTERVAL < temp_time &&
1415 dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { 1661 dht->friends_list[i].nat.recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) {
1416 1662
1417 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); 1663 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2);
1418 1664
@@ -1423,8 +1669,8 @@ static void do_NAT(DHT *dht)
1423 uint16_t numports = NAT_getports(port_list, ip_list, num, ip); 1669 uint16_t numports = NAT_getports(port_list, ip_list, num, ip);
1424 punch_holes(dht, ip, port_list, numports, i); 1670 punch_holes(dht, ip, port_list, numports, i);
1425 1671
1426 dht->friends_list[i].punching_timestamp = temp_time; 1672 dht->friends_list[i].nat.punching_timestamp = temp_time;
1427 dht->friends_list[i].hole_punching = 0; 1673 dht->friends_list[i].nat.hole_punching = 0;
1428 } 1674 }
1429 } 1675 }
1430} 1676}
@@ -1496,16 +1742,17 @@ void DHT_save_old(DHT *dht, uint8_t *data)
1496 */ 1742 */
1497int DHT_load_old(DHT *dht, uint8_t *data, uint32_t size) 1743int DHT_load_old(DHT *dht, uint8_t *data, uint32_t size)
1498{ 1744{
1499 if (size < sizeof(dht->close_clientlist)) { 1745 size_t clientlist_oldsize = sizeof(Client_data_old) * LCLIENT_LIST;
1746 if (size < clientlist_oldsize) {
1500#ifdef DEBUG 1747#ifdef DEBUG
1501 fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size); 1748 fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size);
1502#endif 1749#endif
1503 return -1; 1750 return -1;
1504 } 1751 }
1505 1752
1506 uint32_t friendlistsize = size - sizeof(dht->close_clientlist); 1753 uint32_t friendlistsize = size - clientlist_oldsize;
1507 1754
1508 if (friendlistsize % sizeof(DHT_Friend) != 0) { 1755 if (friendlistsize % sizeof(DHT_Friend_old) != 0) {
1509#ifdef DEBUG 1756#ifdef DEBUG
1510 fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize); 1757 fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize);
1511#endif 1758#endif
@@ -1513,11 +1760,11 @@ int DHT_load_old(DHT *dht, uint8_t *data, uint32_t size)
1513 } 1760 }
1514 1761
1515 uint32_t i, j; 1762 uint32_t i, j;
1516 Client_data *client; 1763 Client_data_old *client;
1517 uint16_t friends_num = friendlistsize / sizeof(DHT_Friend); 1764 uint16_t friends_num = friendlistsize / sizeof(DHT_Friend_old);
1518 1765
1519 if (friends_num != 0) { 1766 if (friends_num != 0) {
1520 DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist)); 1767 DHT_Friend_old *tempfriends_list = (DHT_Friend_old *)(data + sizeof(dht->close_clientlist));
1521 1768
1522 for (i = 0; i < friends_num; ++i) { 1769 for (i = 0; i < friends_num; ++i) {
1523 DHT_addfriend(dht, tempfriends_list[i].client_id); 1770 DHT_addfriend(dht, tempfriends_list[i].client_id);
@@ -1525,17 +1772,17 @@ int DHT_load_old(DHT *dht, uint8_t *data, uint32_t size)
1525 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 1772 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1526 client = &tempfriends_list[i].client_list[j]; 1773 client = &tempfriends_list[i].client_list[j];
1527 1774
1528 if (client->timestamp != 0) 1775 if (client->assoc.timestamp != 0)
1529 getnodes(dht, client->ip_port, client->client_id, tempfriends_list[i].client_id); 1776 getnodes(dht, client->assoc.ip_port, client->client_id, tempfriends_list[i].client_id);
1530 } 1777 }
1531 } 1778 }
1532 } 1779 }
1533 1780
1534 Client_data *tempclose_clientlist = (Client_data *)data; 1781 Client_data_old *tempclose_clientlist = (Client_data_old *)data;
1535 1782
1536 for (i = 0; i < LCLIENT_LIST; ++i) { 1783 for (i = 0; i < LCLIENT_LIST; ++i) {
1537 if (tempclose_clientlist[i].timestamp != 0) 1784 if (tempclose_clientlist[i].assoc.timestamp != 0)
1538 DHT_bootstrap(dht, tempclose_clientlist[i].ip_port, 1785 DHT_bootstrap(dht, tempclose_clientlist[i].assoc.ip_port,
1539 tempclose_clientlist[i].client_id ); 1786 tempclose_clientlist[i].client_id );
1540 } 1787 }
1541 1788
@@ -1548,8 +1795,10 @@ int DHT_load_old(DHT *dht, uint8_t *data, uint32_t size)
1548#define DHT_STATE_COOKIE_GLOBAL 0x159000d 1795#define DHT_STATE_COOKIE_GLOBAL 0x159000d
1549 1796
1550#define DHT_STATE_COOKIE_TYPE 0x11ce 1797#define DHT_STATE_COOKIE_TYPE 0x11ce
1551#define DHT_STATE_TYPE_FRIENDS 1 1798#define DHT_STATE_TYPE_FRIENDS 1
1552#define DHT_STATE_TYPE_CLIENTS 2 1799#define DHT_STATE_TYPE_CLIENTS 2
1800#define DHT_STATE_TYPE_FRIENDS_ASSOC46 3
1801#define DHT_STATE_TYPE_CLIENTS_ASSOC46 4
1553 1802
1554/* Get the size of the DHT (for saving). */ 1803/* Get the size of the DHT (for saving). */
1555uint32_t DHT_size(DHT *dht) 1804uint32_t DHT_size(DHT *dht)
@@ -1557,7 +1806,12 @@ uint32_t DHT_size(DHT *dht)
1557 uint32_t num = 0, i; 1806 uint32_t num = 0, i;
1558 1807
1559 for (i = 0; i < LCLIENT_LIST; ++i) 1808 for (i = 0; i < LCLIENT_LIST; ++i)
1560 if (dht->close_clientlist[i].timestamp != 0) 1809#ifdef CLIENT_ONETOONE_IP
1810 if (dht->close_clientlist[i].assoc.timestamp != 0)
1811#else
1812 if ((dht->close_clientlist[i].assoc4.timestamp != 0) ||
1813 (dht->close_clientlist[i].assoc6.timestamp != 0))
1814#endif
1561 num++; 1815 num++;
1562 1816
1563 uint32_t size32 = sizeof(uint32_t), sizesubhead = size32 * 2; 1817 uint32_t size32 = sizeof(uint32_t), sizesubhead = size32 * 2;
@@ -1584,7 +1838,11 @@ void DHT_save(DHT *dht, uint8_t *data)
1584 data += sizeof(uint32_t); 1838 data += sizeof(uint32_t);
1585 1839
1586 len = sizeof(DHT_Friend) * dht->num_friends; 1840 len = sizeof(DHT_Friend) * dht->num_friends;
1841#ifdef CLIENT_ONETOONE_IP
1587 type = DHT_STATE_TYPE_FRIENDS; 1842 type = DHT_STATE_TYPE_FRIENDS;
1843#else
1844 type = DHT_STATE_TYPE_FRIENDS_ASSOC46;
1845#endif
1588 data = z_state_save_subheader(data, len, type); 1846 data = z_state_save_subheader(data, len, type);
1589 memcpy(data, dht->friends_list, len); 1847 memcpy(data, dht->friends_list, len);
1590 data += len; 1848 data += len;
@@ -1592,18 +1850,32 @@ void DHT_save(DHT *dht, uint8_t *data)
1592 uint32_t num = 0, i; 1850 uint32_t num = 0, i;
1593 1851
1594 for (i = 0; i < LCLIENT_LIST; ++i) 1852 for (i = 0; i < LCLIENT_LIST; ++i)
1595 if (dht->close_clientlist[i].timestamp != 0) 1853#ifdef CLIENT_ONETOONE_IP
1854 if (dht->close_clientlist[i].assoc.timestamp != 0)
1855#else
1856 if ((dht->close_clientlist[i].assoc4.timestamp != 0) ||
1857 (dht->close_clientlist[i].assoc6.timestamp != 0))
1858#endif
1596 num++; 1859 num++;
1597 1860
1598 len = num * sizeof(Client_data); 1861 len = num * sizeof(Client_data);
1862#ifdef CLIENT_ONETOONE_IP
1599 type = DHT_STATE_TYPE_CLIENTS; 1863 type = DHT_STATE_TYPE_CLIENTS;
1864#else
1865 type = DHT_STATE_TYPE_CLIENTS_ASSOC46;
1866#endif
1600 data = z_state_save_subheader(data, len, type); 1867 data = z_state_save_subheader(data, len, type);
1601 1868
1602 if (num) { 1869 if (num) {
1603 Client_data *clients = (Client_data *)data; 1870 Client_data *clients = (Client_data *)data;
1604 1871
1605 for (num = 0, i = 0; i < LCLIENT_LIST; ++i) 1872 for (num = 0, i = 0; i < LCLIENT_LIST; ++i)
1606 if (dht->close_clientlist[i].timestamp != 0) 1873#ifdef CLIENT_ONETOONE_IP
1874 if (dht->close_clientlist[i].assoc.timestamp != 0)
1875#else
1876 if ((dht->close_clientlist[i].assoc4.timestamp != 0) ||
1877 (dht->close_clientlist[i].assoc6.timestamp != 0))
1878#endif
1607 memcpy(&clients[num++], &dht->close_clientlist[i], sizeof(Client_data)); 1879 memcpy(&clients[num++], &dht->close_clientlist[i], sizeof(Client_data));
1608 } 1880 }
1609 1881
@@ -1617,35 +1889,81 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length,
1617 1889
1618 switch (type) { 1890 switch (type) {
1619 case DHT_STATE_TYPE_FRIENDS: 1891 case DHT_STATE_TYPE_FRIENDS:
1620 if (length % sizeof(DHT_Friend) != 0) 1892 if (length % sizeof(DHT_Friend_old) != 0)
1621 break; 1893 break;
1622 1894
1623 DHT_Friend *friend_list = (DHT_Friend *)data; 1895 { /* localize declarations */
1624 num = length / sizeof(DHT_Friend); 1896 DHT_Friend_old *friend_list = (DHT_Friend_old *)data;
1897 num = length / sizeof(DHT_Friend_old);
1625 1898
1626 for (i = 0; i < num; ++i) { 1899 for (i = 0; i < num; ++i) {
1627 DHT_addfriend(dht, friend_list[i].client_id); 1900 DHT_addfriend(dht, friend_list[i].client_id);
1628 1901
1629 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 1902 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1630 Client_data *client = &friend_list[i].client_list[j]; 1903 Client_data_old *client = &friend_list[i].client_list[j];
1631 1904
1632 if (client->timestamp != 0) 1905 if (client->assoc.timestamp != 0)
1633 getnodes(dht, client->ip_port, client->client_id, friend_list[i].client_id); 1906 getnodes(dht, client->assoc.ip_port, client->client_id, friend_list[i].client_id);
1907 }
1634 } 1908 }
1635 } 1909 } /* localize declarations */
1636 1910
1637 break; 1911 break;
1638 1912
1639 case DHT_STATE_TYPE_CLIENTS: 1913 case DHT_STATE_TYPE_CLIENTS:
1640 if ((length % sizeof(Client_data)) != 0) 1914 if ((length % sizeof(Client_data_old)) != 0)
1641 break; 1915 break;
1642 1916
1643 num = length / sizeof(Client_data); 1917 { /* localize declarations */
1644 Client_data *client_list = (Client_data *)data; 1918 num = length / sizeof(Client_data_old);
1919 Client_data_old *client_list = (Client_data_old *)data;
1645 1920
1646 for (i = 0; i < num; ++i) 1921 for (i = 0; i < num; ++i)
1647 if (client_list[i].timestamp != 0) 1922 if (client_list[i].assoc.timestamp != 0)
1648 DHT_bootstrap(dht, client_list[i].ip_port, client_list[i].client_id); 1923 DHT_bootstrap(dht, client_list[i].assoc.ip_port, client_list[i].client_id);
1924 } /* localize declarations */
1925
1926 break;
1927
1928 case DHT_STATE_TYPE_FRIENDS_ASSOC46:
1929 if (length % sizeof(DHT_Friend_new) != 0)
1930 break;
1931
1932 { /* localize declarations */
1933 DHT_Friend_new *friend_list = (DHT_Friend_new *)data;
1934 num = length / sizeof(DHT_Friend_new);
1935
1936 for (i = 0; i < num; ++i) {
1937 DHT_addfriend(dht, friend_list[i].client_id);
1938
1939 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1940 Client_data_new *client = &friend_list[i].client_list[j];
1941
1942 if (client->assoc4.timestamp != 0)
1943 getnodes(dht, client->assoc4.ip_port, client->client_id, friend_list[i].client_id);
1944 if (client->assoc6.timestamp != 0)
1945 getnodes(dht, client->assoc6.ip_port, client->client_id, friend_list[i].client_id);
1946 }
1947 }
1948 } /* localize declarations */
1949
1950 break;
1951
1952 case DHT_STATE_TYPE_CLIENTS_ASSOC46:
1953 if ((length % sizeof(Client_data_new)) != 0)
1954 break;
1955
1956 { /* localize declarations */
1957 num = length / sizeof(Client_data_new);
1958 Client_data_new *client_list = (Client_data_new *)data;
1959
1960 for (i = 0; i < num; ++i) {
1961 if (client_list[i].assoc4.timestamp != 0)
1962 DHT_bootstrap(dht, client_list[i].assoc4.ip_port, client_list[i].client_id);
1963 if (client_list[i].assoc6.timestamp != 0)
1964 DHT_bootstrap(dht, client_list[i].assoc6.ip_port, client_list[i].client_id);
1965 }
1966 } /* localize declarations */
1649 1967
1650 break; 1968 break;
1651 1969
@@ -1685,7 +2003,13 @@ int DHT_isconnected(DHT *dht)
1685 uint64_t temp_time = unix_time(); 2003 uint64_t temp_time = unix_time();
1686 2004
1687 for (i = 0; i < LCLIENT_LIST; ++i) { 2005 for (i = 0; i < LCLIENT_LIST; ++i) {
1688 if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) 2006 Client_data *client = &dht->close_clientlist[i];
2007#ifdef CLIENT_ONETOONE_IP
2008 if (!is_timeout(temp_time, client->assoc.timestamp, BAD_NODE_TIMEOUT))
2009#else
2010 if (!is_timeout(temp_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) ||
2011 !is_timeout(temp_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT))
2012#endif
1689 return 1; 2013 return 1;
1690 } 2014 }
1691 2015
diff --git a/toxcore/DHT.h b/toxcore/DHT.h
index 7cb3198d..46193b56 100644
--- a/toxcore/DHT.h
+++ b/toxcore/DHT.h
@@ -44,7 +44,6 @@
44#define MAX_TOPING 16 44#define MAX_TOPING 16
45 45
46typedef struct { 46typedef struct {
47 uint8_t client_id[CLIENT_ID_SIZE];
48 IP_Port ip_port; 47 IP_Port ip_port;
49 uint64_t timestamp; 48 uint64_t timestamp;
50 uint64_t last_pinged; 49 uint64_t last_pinged;
@@ -52,19 +51,22 @@ typedef struct {
52 /* Returned by this node. Either our friend or us. */ 51 /* Returned by this node. Either our friend or us. */
53 IP_Port ret_ip_port; 52 IP_Port ret_ip_port;
54 uint64_t ret_timestamp; 53 uint64_t ret_timestamp;
55} Client_data; 54} IPPTsPng;
56
57/*----------------------------------------------------------------------------------*/
58 55
59typedef struct { 56typedef struct {
60 uint8_t client_id[CLIENT_ID_SIZE]; 57 uint8_t client_id[CLIENT_ID_SIZE];
61 Client_data client_list[MAX_FRIEND_CLIENTS]; 58 IPPTsPng assoc;
59} Client_data_old;
62 60
63 /* Time at which the last get_nodes request was sent. */ 61typedef struct {
64 uint64_t lastgetnode; 62 uint8_t client_id[CLIENT_ID_SIZE];
63 IPPTsPng assoc4;
64 IPPTsPng assoc6;
65} Client_data_new;
65 66
66 /* Symetric NAT hole punching stuff. */ 67/*----------------------------------------------------------------------------------*/
67 68
69typedef struct {
68 /* 1 if currently hole punching, otherwise 0 */ 70 /* 1 if currently hole punching, otherwise 0 */
69 uint8_t hole_punching; 71 uint8_t hole_punching;
70 uint32_t punching_index; 72 uint32_t punching_index;
@@ -72,7 +74,38 @@ typedef struct {
72 uint64_t recvNATping_timestamp; 74 uint64_t recvNATping_timestamp;
73 uint64_t NATping_id; 75 uint64_t NATping_id;
74 uint64_t NATping_timestamp; 76 uint64_t NATping_timestamp;
75} DHT_Friend; 77} NAT;
78
79typedef struct {
80 uint8_t client_id[CLIENT_ID_SIZE];
81 Client_data_old client_list[MAX_FRIEND_CLIENTS];
82
83 /* Time at which the last get_nodes request was sent. */
84 uint64_t lastgetnode;
85
86 /* Symetric NAT hole punching stuff. */
87 NAT nat;
88} DHT_Friend_old;
89
90typedef struct {
91 uint8_t client_id[CLIENT_ID_SIZE];
92 Client_data_new client_list[MAX_FRIEND_CLIENTS];
93
94 /* Time at which the last get_nodes request was sent. */
95 uint64_t lastgetnode;
96
97 /* Symetric NAT hole punching stuff. */
98 NAT nat;
99} DHT_Friend_new;
100
101/* #define CLIENT_ONETOONE_IP */
102#ifdef CLIENT_ONETOONE_IP
103typedef Client_data_old Client_data;
104typedef DHT_Friend_old DHT_Friend;
105#else
106typedef Client_data_new Client_data;
107typedef DHT_Friend_new DHT_Friend;
108#endif
76 109
77/* this must be kept even if IP_Port is expanded: wire compatibility */ 110/* this must be kept even if IP_Port is expanded: wire compatibility */
78typedef struct { 111typedef struct {
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index f22a8d57..8ad15bc1 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -1296,18 +1296,23 @@ void doMessenger(Messenger *m)
1296 1296
1297 for (client = 0; client < LCLIENT_LIST; client++) { 1297 for (client = 0; client < LCLIENT_LIST; client++) {
1298 Client_data *cptr = &m->dht->close_clientlist[client]; 1298 Client_data *cptr = &m->dht->close_clientlist[client];
1299 IPPTsPng *assoc = NULL;
1300#ifdef CLIENT_ONETOONE_IP
1301 assoc = &cptr->assoc;
1302#else
1303 for (assoc = &cptr->assoc4; assoc != &cptr->assoc6; assoc = &cptr->assoc6)
1304#endif
1305 if (ip_isset(&assoc->ip_port.ip)) {
1306 last_pinged = lastdump - assoc->last_pinged;
1299 1307
1300 if (ip_isset(&cptr->ip_port.ip)) { 1308 if (last_pinged > 999)
1301 last_pinged = lastdump - cptr->last_pinged; 1309 last_pinged = 999;
1302
1303 if (last_pinged > 999)
1304 last_pinged = 999;
1305 1310
1306 snprintf(logbuffer, sizeof(logbuffer), "C[%2u] %s:%u [%3u] %s\n", 1311 snprintf(logbuffer, sizeof(logbuffer), "C[%2u] %s:%u [%3u] %s\n",
1307 client, ip_ntoa(&cptr->ip_port.ip), ntohs(cptr->ip_port.port), 1312 client, ip_ntoa(&assoc->ip_port.ip), ntohs(assoc->ip_port.port),
1308 last_pinged, ID2String(cptr->client_id)); 1313 last_pinged, ID2String(cptr->client_id));
1309 loglog(logbuffer); 1314 loglog(logbuffer);
1310 } 1315 }
1311 } 1316 }
1312 1317
1313 loglog(" = = = = = = = = \n"); 1318 loglog(" = = = = = = = = \n");
@@ -1350,16 +1355,24 @@ void doMessenger(Messenger *m)
1350 1355
1351 for (client = 0; client < MAX_FRIEND_CLIENTS; client++) { 1356 for (client = 0; client < MAX_FRIEND_CLIENTS; client++) {
1352 Client_data *cptr = &dhtfptr->client_list[client]; 1357 Client_data *cptr = &dhtfptr->client_list[client];
1353 last_pinged = lastdump - cptr->last_pinged; 1358 IPPTsPng *assoc = NULL;
1359#ifdef CLIENT_ONETOONE_IP
1360 assoc = &cptr->assoc;
1361#else
1362 for (assoc = &cptr->assoc4; assoc != &cptr->assoc6; assoc = &cptr->assoc6)
1363#endif
1364 if (ip_isset(&assoc->ip_port.ip)) {
1365 last_pinged = lastdump - assoc->last_pinged;
1354 1366
1355 if (last_pinged > 999) 1367 if (last_pinged > 999)
1356 last_pinged = 999; 1368 last_pinged = 999;
1357 1369
1358 snprintf(logbuffer, sizeof(logbuffer), "F[%2u] => C[%2u] %s:%u [%3u] %s\n", 1370 snprintf(logbuffer, sizeof(logbuffer), "F[%2u] => C[%2u] %s:%u [%3u] %s\n",
1359 friend, client, ip_ntoa(&cptr->ip_port.ip), 1371 friend, client, ip_ntoa(&assoc->ip_port.ip),
1360 ntohs(cptr->ip_port.port), last_pinged, 1372 ntohs(assoc->ip_port.port), last_pinged,
1361 ID2String(cptr->client_id)); 1373 ID2String(cptr->client_id));
1362 loglog(logbuffer); 1374 loglog(logbuffer);
1375 }
1363 } 1376 }
1364 } 1377 }
1365 1378
diff --git a/toxcore/util.h b/toxcore/util.h
index 9e4ac79a..13ab4792 100644
--- a/toxcore/util.h
+++ b/toxcore/util.h
@@ -20,8 +20,6 @@ typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len
20int load_state(load_state_callback_func load_state_callback, void *outer, 20int load_state(load_state_callback_func load_state_callback, void *outer,
21 uint8_t *data, uint32_t length, uint16_t cookie_inner); 21 uint8_t *data, uint32_t length, uint16_t cookie_inner);
22 22
23#undef LOGGING
24/* #define LOGGING */
25#ifdef LOGGING 23#ifdef LOGGING
26extern char logbuffer[512]; 24extern char logbuffer[512];
27void loginit(uint16_t port); 25void loginit(uint16_t port);