diff options
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/DHT.c | 107 | ||||
-rw-r--r-- | toxcore/Messenger.c | 3 | ||||
-rw-r--r-- | toxcore/group_chats.c | 8 | ||||
-rw-r--r-- | toxcore/network.c | 24 | ||||
-rw-r--r-- | toxcore/network.h | 12 |
5 files changed, 101 insertions, 53 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index f5d93fc4..f49858bc 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -108,21 +108,6 @@ static int client_id_cmp(ClientPair p1, ClientPair p2) | |||
108 | return c; | 108 | return c; |
109 | } | 109 | } |
110 | 110 | ||
111 | static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id) | ||
112 | { | ||
113 | uint32_t i; | ||
114 | |||
115 | for (i = 0; i < length; i++) | ||
116 | |||
117 | /* Dead nodes are considered dead (not in the list)*/ | ||
118 | if (!is_timeout(list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) || | ||
119 | !is_timeout(list[i].assoc6.timestamp, KILL_NODE_TIMEOUT)) | ||
120 | if (id_equal(list[i].client_id, client_id)) | ||
121 | return 1; | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | /* Check if client with client_id is already in list of length length. | 111 | /* Check if client with client_id is already in list of length length. |
127 | * If it is then set its corresponding timestamp to current time. | 112 | * If it is then set its corresponding timestamp to current time. |
128 | * If the id is already in the list with a different ip_port, update it. | 113 | * If the id is already in the list with a different ip_port, update it. |
@@ -380,21 +365,31 @@ static int replace_bad( Client_data *list, | |||
380 | for (i = 0; i < length; ++i) { | 365 | for (i = 0; i < length; ++i) { |
381 | /* If node is bad */ | 366 | /* If node is bad */ |
382 | Client_data *client = &list[i]; | 367 | Client_data *client = &list[i]; |
383 | IPPTsPng *ipptp = NULL; | ||
384 | 368 | ||
385 | if (ip_port.ip.family == AF_INET) | 369 | if (is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && |
386 | ipptp = &client->assoc4; | 370 | is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) { |
387 | else | 371 | |
388 | ipptp = &client->assoc6; | 372 | IPPTsPng *ipptp_write = NULL; |
373 | IPPTsPng *ipptp_clear = NULL; | ||
374 | |||
375 | if (ip_port.ip.family == AF_INET) { | ||
376 | ipptp_write = &client->assoc4; | ||
377 | ipptp_clear = &client->assoc6; | ||
378 | } else { | ||
379 | ipptp_write = &client->assoc6; | ||
380 | ipptp_clear = &client->assoc4; | ||
381 | } | ||
389 | 382 | ||
390 | if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT)) { | ||
391 | memcpy(client->client_id, client_id, CLIENT_ID_SIZE); | 383 | memcpy(client->client_id, client_id, CLIENT_ID_SIZE); |
392 | ipptp->ip_port = ip_port; | 384 | ipptp_write->ip_port = ip_port; |
393 | ipptp->timestamp = unix_time(); | 385 | ipptp_write->timestamp = unix_time(); |
386 | |||
387 | ip_reset(&ipptp_write->ret_ip_port.ip); | ||
388 | ipptp_write->ret_ip_port.port = 0; | ||
389 | ipptp_write->ret_timestamp = 0; | ||
394 | 390 | ||
395 | ip_reset(&ipptp->ret_ip_port.ip); | 391 | /* zero out other address */ |
396 | ipptp->ret_ip_port.port = 0; | 392 | memset(ipptp_clear, 0, sizeof(*ipptp_clear)); |
397 | ipptp->ret_timestamp = 0; | ||
398 | 393 | ||
399 | return 0; | 394 | return 0; |
400 | } | 395 | } |
@@ -458,20 +453,28 @@ static int replace_good( Client_data *list, | |||
458 | assert(replace >= 0 && replace < length); | 453 | assert(replace >= 0 && replace < length); |
459 | #endif | 454 | #endif |
460 | Client_data *client = &list[replace]; | 455 | Client_data *client = &list[replace]; |
461 | IPPTsPng *ipptp = NULL; | 456 | IPPTsPng *ipptp_write = NULL; |
457 | IPPTsPng *ipptp_clear = NULL; | ||
462 | 458 | ||
463 | if (ip_port.ip.family == AF_INET) | 459 | if (ip_port.ip.family == AF_INET) { |
464 | ipptp = &client->assoc4; | 460 | ipptp_write = &client->assoc4; |
465 | else | 461 | ipptp_clear = &client->assoc6; |
466 | ipptp = &client->assoc6; | 462 | } else { |
463 | ipptp_write = &client->assoc6; | ||
464 | ipptp_clear = &client->assoc4; | ||
465 | } | ||
467 | 466 | ||
468 | memcpy(client->client_id, client_id, CLIENT_ID_SIZE); | 467 | memcpy(client->client_id, client_id, CLIENT_ID_SIZE); |
469 | ipptp->ip_port = ip_port; | 468 | ipptp_write->ip_port = ip_port; |
470 | ipptp->timestamp = unix_time(); | 469 | ipptp_write->timestamp = unix_time(); |
470 | |||
471 | ip_reset(&ipptp_write->ret_ip_port.ip); | ||
472 | ipptp_write->ret_ip_port.port = 0; | ||
473 | ipptp_write->ret_timestamp = 0; | ||
474 | |||
475 | /* zero out other address */ | ||
476 | memset(ipptp_clear, 0, sizeof(*ipptp_clear)); | ||
471 | 477 | ||
472 | ip_reset(&ipptp->ret_ip_port.ip); | ||
473 | ipptp->ret_ip_port.port = 0; | ||
474 | ipptp->ret_timestamp = 0; | ||
475 | return 0; | 478 | return 0; |
476 | } | 479 | } |
477 | 480 | ||
@@ -1083,10 +1086,12 @@ int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port) | |||
1083 | return -1; | 1086 | return -1; |
1084 | } | 1087 | } |
1085 | 1088 | ||
1086 | static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8_t *client_id, | 1089 | /* returns number of nodes not in kill-timeout */ |
1090 | static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8_t *client_id, | ||
1087 | Client_data *list, uint32_t list_count) | 1091 | Client_data *list, uint32_t list_count) |
1088 | { | 1092 | { |
1089 | uint32_t i; | 1093 | uint32_t i; |
1094 | uint8_t not_kill = 0; | ||
1090 | uint64_t temp_time = unix_time(); | 1095 | uint64_t temp_time = unix_time(); |
1091 | 1096 | ||
1092 | uint32_t num_nodes = 0; | 1097 | uint32_t num_nodes = 0; |
@@ -1101,6 +1106,8 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8 | |||
1101 | 1106 | ||
1102 | for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) | 1107 | for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) |
1103 | if (!is_timeout(assoc->timestamp, KILL_NODE_TIMEOUT)) { | 1108 | if (!is_timeout(assoc->timestamp, KILL_NODE_TIMEOUT)) { |
1109 | not_kill++; | ||
1110 | |||
1104 | if (is_timeout(assoc->last_pinged, PING_INTERVAL)) { | 1111 | if (is_timeout(assoc->last_pinged, PING_INTERVAL)) { |
1105 | send_ping_request(dht->ping, assoc->ip_port, client->client_id ); | 1112 | send_ping_request(dht->ping, assoc->ip_port, client->client_id ); |
1106 | assoc->last_pinged = temp_time; | 1113 | assoc->last_pinged = temp_time; |
@@ -1121,6 +1128,8 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8 | |||
1121 | client_id); | 1128 | client_id); |
1122 | *lastgetnode = temp_time; | 1129 | *lastgetnode = temp_time; |
1123 | } | 1130 | } |
1131 | |||
1132 | return not_kill; | ||
1124 | } | 1133 | } |
1125 | 1134 | ||
1126 | /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request | 1135 | /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request |
@@ -1140,8 +1149,28 @@ static void do_DHT_friends(DHT *dht) | |||
1140 | */ | 1149 | */ |
1141 | static void do_Close(DHT *dht) | 1150 | static void do_Close(DHT *dht) |
1142 | { | 1151 | { |
1143 | do_ping_and_sendnode_requests(dht, &dht->close_lastgetnodes, dht->c->self_public_key, | 1152 | uint8_t not_killed = do_ping_and_sendnode_requests(dht, &dht->close_lastgetnodes, dht->c->self_public_key, |
1144 | dht->close_clientlist, LCLIENT_LIST); | 1153 | dht->close_clientlist, LCLIENT_LIST); |
1154 | |||
1155 | if (!not_killed) { | ||
1156 | /* all existing nodes are at least KILL_NODE_TIMEOUT, | ||
1157 | * which means we are mute, as we only send packets to | ||
1158 | * nodes NOT in KILL_NODE_TIMEOUT | ||
1159 | * | ||
1160 | * so: reset all nodes to be BAD_NODE_TIMEOUT, but not | ||
1161 | * KILL_NODE_TIMEOUT, so we at least keep trying pings */ | ||
1162 | uint64_t badonly = unix_time() - BAD_NODE_TIMEOUT; | ||
1163 | size_t i, a; | ||
1164 | |||
1165 | for (i = 0; i < LCLIENT_LIST; i++) { | ||
1166 | Client_data *client = &dht->close_clientlist[i]; | ||
1167 | IPPTsPng *assoc; | ||
1168 | |||
1169 | for (a = 0, assoc = &client->assoc4; a < 2; a++, assoc = &client->assoc6) | ||
1170 | if (assoc->timestamp) | ||
1171 | assoc->timestamp = badonly; | ||
1172 | } | ||
1173 | } | ||
1145 | } | 1174 | } |
1146 | 1175 | ||
1147 | void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) | 1176 | void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) |
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 904c3ecc..19bd7edf 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -734,7 +734,8 @@ static int group_num(Messenger *m, uint8_t *group_public_key) | |||
734 | uint32_t i; | 734 | uint32_t i; |
735 | 735 | ||
736 | for (i = 0; i < m->numchats; ++i) { | 736 | for (i = 0; i < m->numchats; ++i) { |
737 | if (id_equal(m->chats[i]->self_public_key, group_public_key)) | 737 | if (m->chats[i] != NULL) |
738 | if (id_equal(m->chats[i]->self_public_key, group_public_key)) | ||
738 | return i; | 739 | return i; |
739 | } | 740 | } |
740 | 741 | ||
diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 3fa90c42..b5e421a6 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c | |||
@@ -423,6 +423,7 @@ static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, uint8 | |||
423 | } | 423 | } |
424 | 424 | ||
425 | #define GROUP_DATA_MIN_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + 1) | 425 | #define GROUP_DATA_MIN_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + 1) |
426 | static void send_names_new_peer(Group_Chat *chat); | ||
426 | 427 | ||
427 | static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len) | 428 | static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len) |
428 | { | 429 | { |
@@ -475,6 +476,7 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len) | |||
475 | return 1; | 476 | return 1; |
476 | 477 | ||
477 | addpeer(chat, contents); | 478 | addpeer(chat, contents); |
479 | send_names_new_peer(chat); | ||
478 | break; | 480 | break; |
479 | 481 | ||
480 | case GROUP_CHAT_PEER_NICK: | 482 | case GROUP_CHAT_PEER_NICK: |
@@ -673,7 +675,11 @@ static void del_dead_peers(Group_Chat *chat) | |||
673 | } | 675 | } |
674 | 676 | ||
675 | #define NICK_SEND_INTERVAL 180 | 677 | #define NICK_SEND_INTERVAL 180 |
676 | 678 | static void send_names_new_peer(Group_Chat *chat) | |
679 | { | ||
680 | group_send_nick(chat, chat->nick, chat->nick_len); | ||
681 | chat->last_sent_nick = (unix_time() - NICK_SEND_INTERVAL) + 10; | ||
682 | } | ||
677 | static void send_names(Group_Chat *chat) | 683 | static void send_names(Group_Chat *chat) |
678 | { | 684 | { |
679 | /* send own nick from time to time, to let newly added peers be informed | 685 | /* send own nick from time to time, to let newly added peers be informed |
diff --git a/toxcore/network.c b/toxcore/network.c index 0f96083c..e5a80254 100644 --- a/toxcore/network.c +++ b/toxcore/network.c | |||
@@ -278,7 +278,7 @@ void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handl | |||
278 | void networking_poll(Networking_Core *net) | 278 | void networking_poll(Networking_Core *net) |
279 | { | 279 | { |
280 | unix_time_update(); | 280 | unix_time_update(); |
281 | 281 | ||
282 | IP_Port ip_port; | 282 | IP_Port ip_port; |
283 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 283 | uint8_t data[MAX_UDP_PACKET_SIZE]; |
284 | uint32_t length; | 284 | uint32_t length; |
@@ -373,13 +373,15 @@ int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds) | |||
373 | /* returns -1 on error, 0 on timeout, the socket on activity */ | 373 | /* returns -1 on error, 0 on timeout, the socket on activity */ |
374 | int res = select(nfds, &readfds, &writefds, &exceptfds, &timeout); | 374 | int res = select(nfds, &readfds, &writefds, &exceptfds, &timeout); |
375 | #ifdef LOGGING | 375 | #ifdef LOGGING |
376 | |||
376 | /* only dump if not timeout */ | 377 | /* only dump if not timeout */ |
377 | if (res) { | 378 | if (res) { |
378 | sprintf(logbuffer, "select(%d): %d (%d, %s) - %d %d %d\n", milliseconds, res, errno, | 379 | sprintf(logbuffer, "select(%d): %d (%d, %s) - %d %d %d\n", milliseconds, res, errno, |
379 | strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds), | 380 | strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds), |
380 | FD_ISSET(s->sock, &exceptfds)); | 381 | FD_ISSET(s->sock, &exceptfds)); |
381 | loglog(logbuffer); | 382 | loglog(logbuffer); |
382 | } | 383 | } |
384 | |||
383 | #endif | 385 | #endif |
384 | 386 | ||
385 | if (FD_ISSET(s->sock, &writefds)) | 387 | if (FD_ISSET(s->sock, &writefds)) |
@@ -527,14 +529,14 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
527 | } else | 529 | } else |
528 | return NULL; | 530 | return NULL; |
529 | 531 | ||
530 | if (ip.family == AF_INET6) | 532 | if (ip.family == AF_INET6) { |
531 | { | ||
532 | char ipv6only = 0; | 533 | char ipv6only = 0; |
533 | socklen_t optsize = sizeof(ipv6only); | 534 | socklen_t optsize = sizeof(ipv6only); |
534 | #ifdef LOGGING | 535 | #ifdef LOGGING |
535 | errno = 0; | 536 | errno = 0; |
536 | #endif | 537 | #endif |
537 | int res = getsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, &optsize); | 538 | int res = getsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, &optsize); |
539 | |||
538 | if ((res == 0) && (ipv6only == 0)) { | 540 | if ((res == 0) && (ipv6only == 0)) { |
539 | #ifdef LOGGING | 541 | #ifdef LOGGING |
540 | loglog("Dual-stack socket: enabled per default.\n"); | 542 | loglog("Dual-stack socket: enabled per default.\n"); |
@@ -542,6 +544,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
542 | } else { | 544 | } else { |
543 | ipv6only = 0; | 545 | ipv6only = 0; |
544 | #ifdef LOGGING | 546 | #ifdef LOGGING |
547 | |||
545 | if (res < 0) { | 548 | if (res < 0) { |
546 | sprintf(logbuffer, "Dual-stack socket: Failed to query default. (%d, %s)\n", | 549 | sprintf(logbuffer, "Dual-stack socket: Failed to query default. (%d, %s)\n", |
547 | errno, strerror(errno)); | 550 | errno, strerror(errno)); |
@@ -551,8 +554,9 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
551 | errno = 0; | 554 | errno = 0; |
552 | res = | 555 | res = |
553 | #endif | 556 | #endif |
554 | setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only)); | 557 | setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only)); |
555 | #ifdef LOGGING | 558 | #ifdef LOGGING |
559 | |||
556 | if (res < 0) { | 560 | if (res < 0) { |
557 | sprintf(logbuffer, | 561 | sprintf(logbuffer, |
558 | "Dual-stack socket: Failed to enable, won't be able to receive from/send to IPv4 addresses. (%u, %s)\n", | 562 | "Dual-stack socket: Failed to enable, won't be able to receive from/send to IPv4 addresses. (%u, %s)\n", |
@@ -560,6 +564,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
560 | loglog(logbuffer); | 564 | loglog(logbuffer); |
561 | } else | 565 | } else |
562 | loglog("Dual-stack socket: Enabled successfully.\n"); | 566 | loglog("Dual-stack socket: Enabled successfully.\n"); |
567 | |||
563 | #endif | 568 | #endif |
564 | } | 569 | } |
565 | 570 | ||
@@ -607,8 +612,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
607 | *portptr = htons(port_to_try); | 612 | *portptr = htons(port_to_try); |
608 | int tries, res; | 613 | int tries, res; |
609 | 614 | ||
610 | for (tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++) | 615 | for (tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++) { |
611 | { | ||
612 | res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); | 616 | res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); |
613 | 617 | ||
614 | if (!res) { | 618 | if (!res) { |
@@ -674,11 +678,7 @@ int ip_equal(IP *a, IP *b) | |||
674 | if (a->family == AF_INET) | 678 | if (a->family == AF_INET) |
675 | return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr); | 679 | return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr); |
676 | else if (a->family == AF_INET6) | 680 | else if (a->family == AF_INET6) |
677 | #ifdef WIN32 | ||
678 | return IN6_ADDR_EQUAL(&a->ip6.in6_addr, &b->ip6.in6_addr); | ||
679 | #else | ||
680 | return IN6_ARE_ADDR_EQUAL(&a->ip6.in6_addr, &b->ip6.in6_addr); | 681 | return IN6_ARE_ADDR_EQUAL(&a->ip6.in6_addr, &b->ip6.in6_addr); |
681 | #endif | ||
682 | else | 682 | else |
683 | return 0; | 683 | return 0; |
684 | } | 684 | } |
diff --git a/toxcore/network.h b/toxcore/network.h index 87cb4794..d9bc2bfe 100644 --- a/toxcore/network.h +++ b/toxcore/network.h | |||
@@ -43,6 +43,18 @@ typedef unsigned int sock_t; | |||
43 | /* sa_family_t is the sockaddr_in / sockaddr_in6 family field */ | 43 | /* sa_family_t is the sockaddr_in / sockaddr_in6 family field */ |
44 | typedef short sa_family_t; | 44 | typedef short sa_family_t; |
45 | 45 | ||
46 | #ifndef IN6_ARE_ADDR_EQUAL | ||
47 | #ifdef IN6_ADDR_EQUAL | ||
48 | #define IN6_ARE_ADDR_EQUAL(a,b) IN6_ADDR_EQUAL(a,b) | ||
49 | #else | ||
50 | #define IN6_ARE_ADDR_EQUAL(a,b) \ | ||
51 | ((((__const uint32_t *) (a))[0] == ((__const uint32_t *) (b))[0]) \ | ||
52 | && (((__const uint32_t *) (a))[1] == ((__const uint32_t *) (b))[1]) \ | ||
53 | && (((__const uint32_t *) (a))[2] == ((__const uint32_t *) (b))[2]) \ | ||
54 | && (((__const uint32_t *) (a))[3] == ((__const uint32_t *) (b))[3])) | ||
55 | #endif | ||
56 | #endif | ||
57 | |||
46 | #ifndef EWOULDBLOCK | 58 | #ifndef EWOULDBLOCK |
47 | #define EWOULDBLOCK WSAEWOULDBLOCK | 59 | #define EWOULDBLOCK WSAEWOULDBLOCK |
48 | #endif | 60 | #endif |