summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/DHT.c107
-rw-r--r--toxcore/Messenger.c3
-rw-r--r--toxcore/group_chats.c8
-rw-r--r--toxcore/network.c24
-rw-r--r--toxcore/network.h12
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
111static 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
1086static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8_t *client_id, 1089/* returns number of nodes not in kill-timeout */
1090static 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 */
1141static void do_Close(DHT *dht) 1150static 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
1147void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) 1176void 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)
426static void send_names_new_peer(Group_Chat *chat);
426 427
427static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len) 428static 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 678static 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}
677static void send_names(Group_Chat *chat) 683static 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
278void networking_poll(Networking_Core *net) 278void 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 */
44typedef short sa_family_t; 44typedef 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