diff --git a/docs/TODO b/docs/TODO index 49b06690..c905f96b 100644 --- a/docs/TODO +++ b/docs/TODO @@ -22,5 +22,9 @@ Lossless UDP: [NOT STARTED] Offline messaging [NOT STARTED] Friends list syncing [IN PROGRESS] IPV6 support + [DONE] Networking + [DONE] DHT + Messenger + [NOT STARTED] Group chats + [IN PROGRESS] GUI (https://github.com/nurupo/ProjectTox-Qt-GUI) [NOT STARTED] Security audit from professionals diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 246ae818..484a511c 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -94,6 +94,7 @@ int main(int argc, char *argv[]) /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) exit(1); @@ -130,7 +131,7 @@ int main(int argc, char *argv[]) uint16_t port = htons(atoi(argv[argvoffset + 2])); uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); int res = DHT_bootstrap_from_address(dht, argv[argvoffset + 1], - ipv6enabled, port, bootstrap_key); + ipv6enabled, port, bootstrap_key); free(bootstrap_key); if (!res) { @@ -151,6 +152,7 @@ int main(int argc, char *argv[]) } do_DHT(dht); + if (last_LANdiscovery + (is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL) < unix_time()) { send_LANdiscovery(htons(PORT), dht->c); last_LANdiscovery = unix_time(); diff --git a/testing/DHT_test.c b/testing/DHT_test.c index 9eab60de..d76057c1 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c @@ -141,6 +141,7 @@ int main(int argc, char *argv[]) /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) exit(1); @@ -177,6 +178,7 @@ int main(int argc, char *argv[]) unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]); int res = DHT_bootstrap_from_address(dht, argv[argvoffset + 1], ipv6enabled, port, binary_string); free(binary_string); + if (!res) { printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]); return 1; diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c index 155a412a..3c52c6d6 100644 --- a/testing/Lossless_UDP_testclient.c +++ b/testing/Lossless_UDP_testclient.c @@ -155,6 +155,7 @@ int main(int argc, char *argv[]) /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) exit(1); @@ -184,10 +185,12 @@ int main(int argc, char *argv[]) IP_Port serverip; ip_init(&serverip.ip, ipv6enabled); + if (!addr_resolve(argv[argvoffset + 1], &serverip.ip, NULL)) { printf("Failed to convert \"%s\" into an IP address.\n", argv[argvoffset + 1]); return 1; } + serverip.port = htons(atoi(argv[argvoffset + 2])); printip(serverip); diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c index 0fd4edd9..9d061c0c 100644 --- a/testing/Lossless_UDP_testserver.c +++ b/testing/Lossless_UDP_testserver.c @@ -151,6 +151,7 @@ int main(int argc, char *argv[]) /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) exit(1); diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index 06f8bdbf..7b94364a 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -98,6 +98,7 @@ int main(int argc, char *argv[]) /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) exit(1); @@ -120,14 +121,16 @@ int main(int argc, char *argv[]) uint16_t port = htons(atoi(argv[argvoffset + 2])); uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); int res = DHT_bootstrap_from_address(m->dht, argv[argvoffset + 1], - ipv6enabled, port, bootstrap_key); + ipv6enabled, port, bootstrap_key); free(bootstrap_key); + if (!res) { printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]); exit(1); } } else { FILE *file = fopen(argv[argvoffset + 1], "rb"); + if ( file == NULL ) { printf("Failed to open \"%s\" - does it exist?\n", argv[argvoffset + 1]); return 1; diff --git a/testing/misc_tools.c b/testing/misc_tools.c index 824200d8..81f5ed8a 100644 --- a/testing/misc_tools.c +++ b/testing/misc_tools.c @@ -51,10 +51,12 @@ unsigned char *hex_string_to_bin(char hex_string[]) int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled) { int argvoffset = 0, argi; - for(argi = 1; argi < argc; argi++) + + for (argi = 1; argi < argc; argi++) if (!strncasecmp(argv[argi], "--ipv", 5)) { if (argv[argi][5] && !argv[argi][6]) { char c = argv[argi][5]; + if (c == '4') *ipv6enabled = 0; else if (c == '6') @@ -63,8 +65,7 @@ int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled) printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); return -1; } - } - else { + } else { printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); return -1; } diff --git a/testing/nTox.c b/testing/nTox.c index 70dc5c77..73b55427 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -284,7 +284,7 @@ void line_eval(Tox *m, char *line) int num = atoi(numstring); - if (tox_sendmessage(m, num, (uint8_t *) message, strlen(message) + 1) != 1) { + if (tox_sendmessage(m, num, (uint8_t *) message, strlen(message) + 1) < 1) { new_lines("[i] could not send message"); } else { new_lines(format_message(m, message, -1)); @@ -582,12 +582,12 @@ int main(int argc, char *argv[]) /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) exit(1); int on = 0; int c = 0; - int i = 0; char *filename = "data"; char idstring[200] = {0}; Tox *m; @@ -641,6 +641,7 @@ int main(int argc, char *argv[]) } nodelay(stdscr, TRUE); + while (1) { if (on == 0 && tox_isconnected(m)) { new_lines("[i] connected to DHT\n[i] define username with /n"); diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 8557a5e0..11f25880 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -31,7 +31,6 @@ #include "network.h" #include "ping.h" #include "misc_tools.h" -#include "Messenger.h" #include "util.h" /* The number of seconds for a non responsive node to become bad. */ @@ -196,74 +195,76 @@ static int friend_number(DHT *dht, uint8_t *client_id) /* * helper for get_close_nodes(). argument list is a monster :D */ -static int get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list, - sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, - time_t timestamp, int *num_nodes_ptr) +static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list, + sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, + time_t timestamp, int *num_nodes_ptr) { - int num_nodes = 0; - int i, tout, inlist, ipv46x, j, closest; - for(i = 0; i < client_list_length; i++) { - Client_data *client = &client_list[i]; - tout = is_timeout(timestamp, client->timestamp, BAD_NODE_TIMEOUT); - inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, client->client_id); + int num_nodes = *num_nodes_ptr; + int i, tout, inlist, ipv46x, j, closest; + + for (i = 0; i < client_list_length; i++) { + Client_data *client = &client_list[i]; + tout = is_timeout(timestamp, client->timestamp, BAD_NODE_TIMEOUT); + inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, client->client_id); #ifdef TOX_ENABLE_IPV6 - IP *client_ip = &client->ip_port.ip; + IP *client_ip = &client->ip_port.ip; - /* - * Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for - * our connections, instead we have to look if it is an embedded - * IPv4-in-IPv6 here and convert it down in sendnodes(). - */ - sa_family_t ip_treat_as_family = client_ip->family; - if ((dht->c->lossless_udp->net->family == AF_INET6) && - (client_ip->family == AF_INET6)) { - /* socket is AF_INET6, address claims AF_INET6: - * check for embedded IPv4-in-IPv6 */ - if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6)) - ip_treat_as_family = AF_INET; - } + /* + * Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for + * our connections, instead we have to look if it is an embedded + * IPv4-in-IPv6 here and convert it down in sendnodes(). + */ + sa_family_t ip_treat_as_family = client_ip->family; - ipv46x = !(sa_family == ip_treat_as_family); + if ((dht->c->lossless_udp->net->family == AF_INET6) && + (client_ip->family == AF_INET6)) { + /* socket is AF_INET6, address claims AF_INET6: + * check for embedded IPv4-in-IPv6 */ + if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6)) + ip_treat_as_family = AF_INET; + } + + ipv46x = !(sa_family == ip_treat_as_family); #else - ipv46x = !(sa_family == AF_INET); + ipv46x = !(sa_family == AF_INET); #endif - /* If node isn't good or is already in list. */ - if (tout || inlist || ipv46x) - continue; + /* If node isn't good or is already in list. */ + if (tout || inlist || ipv46x) + continue; - if (num_nodes < MAX_SENT_NODES) { - memcpy(nodes_list[num_nodes].client_id, - client->client_id, - CLIENT_ID_SIZE ); + if (num_nodes < MAX_SENT_NODES) { + memcpy(nodes_list[num_nodes].client_id, + client->client_id, + CLIENT_ID_SIZE ); - nodes_list[num_nodes].ip_port = client->ip_port; - num_nodes++; - } else { - /* see if node_list contains a client_id that's "further away" - * compared to the one we're looking at at the moment, if there - * is, replace it - */ - for (j = 0; j < MAX_SENT_NODES; ++j) { - closest = id_closest( client_id, - nodes_list[j].client_id, - client->client_id ); + nodes_list[num_nodes].ip_port = client->ip_port; + num_nodes++; + } else { + /* see if node_list contains a client_id that's "further away" + * compared to the one we're looking at at the moment, if there + * is, replace it + */ + for (j = 0; j < MAX_SENT_NODES; ++j) { + closest = id_closest( client_id, + nodes_list[j].client_id, + client->client_id ); - /* second client_id is closer than current: change to it */ - if (closest == 2) { - memcpy( nodes_list[j].client_id, - client->client_id, - CLIENT_ID_SIZE); + /* second client_id is closer than current: change to it */ + if (closest == 2) { + memcpy( nodes_list[j].client_id, + client->client_id, + CLIENT_ID_SIZE); - nodes_list[j].ip_port = client->ip_port; - break; - } - } - } - } + nodes_list[j].ip_port = client->ip_port; + break; + } + } + } + } - *num_nodes_ptr = num_nodes; + *num_nodes_ptr = num_nodes; } /* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: @@ -274,15 +275,15 @@ static int get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *node */ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family) { - time_t timestamp = unix_time(); - int num_nodes = 0, i; - get_close_nodes_inner(dht, client_id, nodes_list, sa_family, - dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes); + time_t timestamp = unix_time(); + int num_nodes = 0, i; + get_close_nodes_inner(dht, client_id, nodes_list, sa_family, + dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes); for (i = 0; i < dht->num_friends; ++i) - get_close_nodes_inner(dht, client_id, nodes_list, sa_family, - dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, - timestamp, &num_nodes); + get_close_nodes_inner(dht, client_id, nodes_list, sa_family, + dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, + timestamp, &num_nodes); return num_nodes; } @@ -458,7 +459,7 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) if (ip_isset(&ip_port.ip) && ipport_equal(&dht->send_nodes[i].ip_port, &ip_port)) ++pinging; - if (pinging == (ping_id != 0) + (ip_isset(&ip_port.ip) != 0)) + if (pinging == (ping_id != 0) + ip_isset(&ip_port.ip)) return 1; } } @@ -554,11 +555,13 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl #ifdef TOX_ENABLE_IPV6 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); int i, num_nodes_ok = 0; - for(i = 0; i < num_nodes; i++) { + + for (i = 0; i < num_nodes; i++) { memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; IP *node_ip = &nodes_list[i].ip_port.ip; + if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6)) /* embedded IPv4-in-IPv6 address: return it in regular sendnodes packet */ nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip6.s6_addr32[3]; @@ -574,6 +577,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl /* shouldn't happen */ num_nodes = num_nodes_ok; } + #else memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node4_format_size); #endif @@ -620,7 +624,7 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_ uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; uint8_t encrypt[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; uint8_t nonce[crypto_box_NONCEBYTES]; - random_nonce(nonce); + new_nonce(nonce); memcpy(plain, &ping_id, sizeof(ping_id)); memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node_format_size); @@ -675,7 +679,8 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32 memcpy(&ping_id, plain, sizeof(ping_id)); sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); #ifdef TOX_ENABLE_IPV6 - sendnodes_ipv6(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); + sendnodes_ipv6(dht, source, packet + 1, plain + sizeof(ping_id), + ping_id); /* TODO: prevent possible amplification attacks */ #endif //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ @@ -691,6 +696,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; size_t Node4_format_size = sizeof(Node4_format); + if (length > (cid_size + Node4_format_size * MAX_SENT_NODES) || ((length - cid_size) % Node4_format_size) != 0 || (length < cid_size + Node4_format_size)) @@ -721,7 +727,8 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); int num_nodes_ok = 0; - for(i = 0; i < num_nodes; i++) + + for (i = 0; i < num_nodes; i++) if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != ~0)) { memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); nodes_list[num_nodes_ok].ip_port.ip.family = AF_INET; @@ -735,6 +742,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 /* shouldn't happen */ num_nodes = num_nodes_ok; } + #else memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); #endif @@ -757,7 +765,8 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t cid_size = 1 + CLIENT_ID_SIZE; cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; - size_t Node_format_size = sizeof(Node4_format); + size_t Node_format_size = sizeof(Node_format); + if (length > (cid_size + Node_format_size * MAX_SENT_NODES) || ((length - cid_size) % Node_format_size) != 0 || (length < cid_size + Node_format_size)) @@ -799,6 +808,24 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, /*----------------------------------------------------------------------------------*/ /*------------------------END of packet handling functions--------------------------*/ +/* + * Send get nodes requests with client_id to max_num peers in list of length length + */ +static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id) +{ + uint64_t temp_time = unix_time(); + uint32_t i, num = 0; + + for (i = 0; i < length; ++i) + if (ipport_isset(&(list[i].ip_port)) && !is_timeout(temp_time, list[i].ret_timestamp, BAD_NODE_TIMEOUT)) { + getnodes(dht, list[i].ip_port, list[i].client_id, client_id); + ++num; + + if (num >= max_num) + return; + } +} + int DHT_addfriend(DHT *dht, uint8_t *client_id) { if (friend_number(dht, client_id) != -1) /* Is friend already in DHT? */ @@ -816,6 +843,7 @@ int DHT_addfriend(DHT *dht, uint8_t *client_id) dht->friends_list[dht->num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int(); ++dht->num_friends; + get_bunchnodes(dht, dht->close_clientlist, LCLIENT_LIST, MAX_FRIEND_CLIENTS, client_id);/*TODO: make this better?*/ return 0; } @@ -964,17 +992,20 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) send_ping_request(dht->ping, dht->c, ip_port, public_key); } int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, - uint16_t port, uint8_t *public_key) + uint16_t port, uint8_t *public_key) { - IP_Port ip_port_v64, ip_port_v4; + IP_Port ip_port_v64; IP *ip_extra = NULL; #ifdef TOX_ENABLE_IPV6 + IP_Port ip_port_v4; ip_init(&ip_port_v64.ip, ipv6enabled); + if (ipv6enabled) { ip_port_v64.ip.family = AF_UNSPEC; ip_reset(&ip_port_v4.ip); ip_extra = &ip_port_v4.ip; } + #else ip_init(&ip_port_v64.ip, 0); #endif @@ -983,14 +1014,15 @@ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable ip_port_v64.port = port; DHT_bootstrap(dht, ip_port_v64, public_key); #ifdef TOX_ENABLE_IPV6 + if ((ip_extra != NULL) && ip_isset(ip_extra)) { ip_port_v4.port = port; DHT_bootstrap(dht, ip_port_v4, public_key); } + #endif return 1; - } - else + } else return 0; } @@ -1303,6 +1335,7 @@ static void do_NAT(DHT *dht) dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); + if (!ip_isset(&ip)) continue; @@ -1443,20 +1476,22 @@ void DHT_save(DHT *dht, uint8_t *data) */ int DHT_load(DHT *dht, uint8_t *data, uint32_t size) { - if (size < sizeof(dht->close_clientlist)) { - fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size); + if (size < sizeof(dht->close_clientlist)) { + fprintf(stderr, "DHT_load: Expected at least %lu bytes, got %u.\n", sizeof(dht->close_clientlist), size); return -1; } uint32_t friendlistsize = size - sizeof(dht->close_clientlist); + if (friendlistsize % sizeof(DHT_Friend) != 0) { - fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize); + fprintf(stderr, "DHT_load: Expected a multiple of %lu, got %u.\n", sizeof(DHT_Friend), friendlistsize); return -1; } uint32_t i, j; Client_data *client; uint16_t friends_num = friendlistsize / sizeof(DHT_Friend); + if (friends_num != 0) { DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist)); @@ -1473,6 +1508,7 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size) } Client_data *tempclose_clientlist = (Client_data *)data; + for (i = 0; i < LCLIENT_LIST; ++i) { if (tempclose_clientlist[i].timestamp != 0) DHT_bootstrap(dht, tempclose_clientlist[i].ip_port, diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 255074b0..ff20c892 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -169,12 +169,12 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key); * if ipv6enabled is 0 (zero), the resolving sticks STRICTLY to IPv4 addresses * if ipv6enabled is not 0 (zero), the resolving looks for IPv6 addresses first, * then IPv4 addresses. - * + * * returns 1 if the address could be converted into an IP address * returns 0 otherwise */ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, - uint16_t port, uint8_t *public_key); + uint16_t port, uint8_t *public_key); /* Add nodes to the toping list. * All nodes in this list are pinged every TIME_TOPING seconds diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index 92e42e0f..c7afb991 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -30,12 +30,15 @@ #define MAX_INTERFACES 16 #ifdef __linux +#ifndef TOX_ENABLE_IPV6 /* Send packet to all broadcast addresses * * return higher than 0 on success. * return 0 on error. + * + * TODO: Make this work with IPv6 and remove the #ifndef TOX_ENABLE_IPV6. */ -static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t * data, uint16_t length) +static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t *data, uint16_t length) { /* Not sure how many platforms this will run on, * so it's wrapped in __linux for now. @@ -63,22 +66,24 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t * d } for (i = 0; i < count; i++) { - if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) { - return 1; - } + if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) { + return 1; + } - /* Just to clarify where we're getting the values from. */ - sock_holder = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr; - if (sock_holder != NULL) { - IP_Port ip_port = {{{{sock_holder->sin_addr.s_addr}}, port, 0}}; - sendpacket(net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); - } + /* Just to clarify where we're getting the values from. */ + sock_holder = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr; + + if (sock_holder != NULL) { + IP_Port ip_port = {{{{sock_holder->sin_addr.s_addr}}, port, 0}}; + sendpacket(net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); + } } close(sock); return 0; } #endif +#endif /* Return the broadcast ip. */ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) @@ -87,6 +92,7 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) ip_reset(&ip); #ifdef TOX_ENABLE_IPV6 + if (family_socket == AF_INET6) { if (family_broadcast == AF_INET6) { ip.family = AF_INET6; @@ -96,25 +102,26 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) ip.ip6.s6_addr[ 0] = 0xFF; ip.ip6.s6_addr[ 1] = 0x02; ip.ip6.s6_addr[15] = 0x01; - } - else if (family_broadcast == AF_INET) { + } else if (family_broadcast == AF_INET) { ip.family = AF_INET6; ip.ip6.s6_addr32[0] = 0; ip.ip6.s6_addr32[1] = 0; ip.ip6.s6_addr32[2] = htonl(0xFFFF); ip.ip6.s6_addr32[3] = INADDR_BROADCAST; } - } - else if (family_socket == AF_INET) { + } else if (family_socket == AF_INET) { if (family_broadcast == AF_INET) { ip.family = AF_INET; ip.ip4.uint32 = INADDR_BROADCAST; } } + #else + if (family_socket == AF_INET) if (family_broadcast == AF_INET) ip.uint32 = INADDR_BROADCAST; + #endif return ip; @@ -126,11 +133,13 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) static int LAN_ip(IP ip) { #ifdef TOX_ENABLE_IPV6 + if (ip.family == AF_INET) { IP4 ip4 = ip.ip4; #else - IP4 ip4 = ip; + IP4 ip4 = ip; #endif + /* Loopback. */ if (ip4.uint8[0] == 127) return 0; @@ -151,13 +160,14 @@ static int LAN_ip(IP ip) if (ip4.uint8[0] == 169 && ip4.uint8[1] == 254 && ip4.uint8[2] != 0 && ip4.uint8[2] != 255) return 0; + #ifdef TOX_ENABLE_IPV6 - } - else if (ip.family == AF_INET6) { + } else if (ip.family == AF_INET6) + { /* autogenerated for each interface: FE80::* (up to FEBF::*) - /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ + FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ if (((ip.ip6.s6_addr[0] == 0xFF) && (ip.ip6.s6_addr[1] < 3) && (ip.ip6.s6_addr[15] == 1)) || - ((ip.ip6.s6_addr[0] == 0xFE) && ((ip.ip6.s6_addr[1] & 0xC0) == 0x80))) + ((ip.ip6.s6_addr[0] == 0xFE) && ((ip.ip6.s6_addr[1] & 0xC0) == 0x80))) return 0; /* embedded IPv4-in-IPv6 */ @@ -168,6 +178,7 @@ static int LAN_ip(IP ip) return LAN_ip(ip4); } } + #endif return -1; @@ -195,17 +206,20 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c) memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES); #ifdef __linux +#ifndef TOX_ENABLE_IPV6 send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES); #endif - +#endif int res = -1; IP_Port ip_port; ip_port.port = port; #ifdef TOX_ENABLE_IPV6 + /* IPv6 multicast */ if (c->lossless_udp->net->family == AF_INET6) { ip_port.ip = broadcast_ip(AF_INET6, AF_INET6); + if (ip_isset(&ip_port.ip)) if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES) > 0) res = 1; @@ -216,6 +230,7 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c) #else ip_port.ip = broadcast_ip(AF_INET, AF_INET); #endif + if (ip_isset(&ip_port.ip)) if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES)) res = 1; diff --git a/toxcore/Lossless_UDP.c b/toxcore/Lossless_UDP.c index ca874562..f942d8e5 100644 --- a/toxcore/Lossless_UDP.c +++ b/toxcore/Lossless_UDP.c @@ -80,26 +80,30 @@ static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) i++; #ifdef TOX_ENABLE_IPV6 - if (source.ip.family == AF_INET) - { + + if (source.ip.family == AF_INET) { IP4 ip4 = source.ip.ip4; #else - IP4 ip4 = source.ip; + IP4 ip4 = source.ip; #endif int k; + for (k = 0; k < 4; k++) { id ^= randtable_initget(ludp, i++, ip4.uint8[k]); } + #ifdef TOX_ENABLE_IPV6 } if (source.ip.family == AF_INET6) { int k; + for (k = 0; k < 16; k++) { id ^= randtable_initget(ludp, i++, source.ip.ip6.s6_addr[k]); } } + #endif /* id can't be zero. */ @@ -116,8 +120,21 @@ static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) */ static void change_handshake(Lossless_UDP *ludp, IP_Port source) { - uint8_t rand = random_int() % 4; - ludp->randtable[rand][((uint8_t *)&source)[rand]] = random_int(); +#ifdef TOX_ENABLE_IPV6 + uint8_t rand; + + if (source.ip.family == AF_INET) { + rand = 2 + random_int() % 4; + } else if (source.ip.family == AF_INET6) { + rand = 2 + random_int() % 16; + } else { + return; + } + +#else + uint8_t rand = 2 + random_int() % 4; +#endif + ludp->randtable[rand][((uint8_t *)&source.ip)[rand]] = random_int(); } /* diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 55b27353..eb18e3a3 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -1225,11 +1225,13 @@ static time_t lastdump = 0; static char IDString[CLIENT_ID_SIZE * 2 + 1]; static char *ID2String(uint8_t *client_id) { - uint32_t i; - for(i = 0; i < CLIENT_ID_SIZE; i++) - sprintf(&IDString[i], "%02X", client_id[i]); - IDString[CLIENT_ID_SIZE * 2] = 0; - return IDString; + uint32_t i; + + for (i = 0; i < CLIENT_ID_SIZE; i++) + sprintf(&IDString[i], "%02X", client_id[i]); + + IDString[CLIENT_ID_SIZE * 2] = 0; + return IDString; } #endif @@ -1246,73 +1248,85 @@ void doMessenger(Messenger *m) LANdiscovery(m); #ifdef LOGGING - if (now() > lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) { - loglog(" = = = = = = = = \n"); - lastdump = now(); - uint32_t client, last_pinged; - for(client = 0; client < LCLIENT_LIST; client++) { - Client_data *cptr = &m->dht->close_clientlist[client]; - if (ip_isset(&cptr->ip_port.ip)) { - last_pinged = lastdump - cptr->last_pinged; - if (last_pinged > 999) - last_pinged = 999; - snprintf(logbuffer, sizeof(logbuffer), "C[%2u] %s:%u [%3u] %s\n", - client, ip_ntoa(&cptr->ip_port.ip), ntohs(cptr->ip_port.port), - last_pinged, ID2String(cptr->client_id)); - loglog(logbuffer); - } - } + if (now() > lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) { + loglog(" = = = = = = = = \n"); - loglog(" = = = = = = = = \n"); + lastdump = now(); + uint32_t client, last_pinged; - uint32_t num_friends = MIN(m->numfriends, m->dht->num_friends); - if (m->numfriends != m->dht->num_friends) { - sprintf(logbuffer, "Friend num in DHT %u != friend num in msger %u\n", - m->dht->num_friends, m->numfriends); - loglog(logbuffer); - } + for (client = 0; client < LCLIENT_LIST; client++) { + Client_data *cptr = &m->dht->close_clientlist[client]; - uint32_t friend, ping_lastrecv; - for(friend = 0; friend < num_friends; friend++) { - Friend *msgfptr = &m->friendlist[friend]; - DHT_Friend *dhtfptr = &m->dht->friends_list[friend]; - if (memcmp(msgfptr->client_id, dhtfptr->client_id, CLIENT_ID_SIZE)) { - if (sizeof(logbuffer) > 2 * CLIENT_ID_SIZE + 64) { - sprintf(logbuffer, "F[%2u] ID(m) %s != ID(d) ", friend, - ID2String(msgfptr->client_id)); - strcat(logbuffer + strlen(logbuffer), ID2String(dhtfptr->client_id)); - strcat(logbuffer + strlen(logbuffer), "\n"); - } - else - sprintf(logbuffer, "F[%2u] ID(m) != ID(d) ", friend); + if (ip_isset(&cptr->ip_port.ip)) { + last_pinged = lastdump - cptr->last_pinged; - loglog(logbuffer); - } + if (last_pinged > 999) + last_pinged = 999; - ping_lastrecv = lastdump - msgfptr->ping_lastrecv; - if (ping_lastrecv > 999) - ping_lastrecv = 999; - snprintf(logbuffer, sizeof(logbuffer), "F[%2u] <%s> %02u [%03u] %s\n", - friend, msgfptr->name, msgfptr->crypt_connection_id, - ping_lastrecv, ID2String(msgfptr->client_id)); - loglog(logbuffer); + snprintf(logbuffer, sizeof(logbuffer), "C[%2u] %s:%u [%3u] %s\n", + client, ip_ntoa(&cptr->ip_port.ip), ntohs(cptr->ip_port.port), + last_pinged, ID2String(cptr->client_id)); + loglog(logbuffer); + } + } - for(client = 0; client < MAX_FRIEND_CLIENTS; client++) { - Client_data *cptr = &dhtfptr->client_list[client]; - last_pinged = lastdump - cptr->last_pinged; - if (last_pinged > 999) - last_pinged = 999; - snprintf(logbuffer, sizeof(logbuffer), "F[%2u] => C[%2u] %s:%u [%3u] %s\n", - friend, client, ip_ntoa(&cptr->ip_port.ip), - ntohs(cptr->ip_port.port), last_pinged, - ID2String(cptr->client_id)); - loglog(logbuffer); - } - } + loglog(" = = = = = = = = \n"); + + uint32_t num_friends = MIN(m->numfriends, m->dht->num_friends); + + if (m->numfriends != m->dht->num_friends) { + sprintf(logbuffer, "Friend num in DHT %u != friend num in msger %u\n", + m->dht->num_friends, m->numfriends); + loglog(logbuffer); + } + + uint32_t friend, ping_lastrecv; + + for (friend = 0; friend < num_friends; friend++) { + Friend *msgfptr = &m->friendlist[friend]; + DHT_Friend *dhtfptr = &m->dht->friends_list[friend]; + + if (memcmp(msgfptr->client_id, dhtfptr->client_id, CLIENT_ID_SIZE)) { + if (sizeof(logbuffer) > 2 * CLIENT_ID_SIZE + 64) { + sprintf(logbuffer, "F[%2u] ID(m) %s != ID(d) ", friend, + ID2String(msgfptr->client_id)); + strcat(logbuffer + strlen(logbuffer), ID2String(dhtfptr->client_id)); + strcat(logbuffer + strlen(logbuffer), "\n"); + } else + sprintf(logbuffer, "F[%2u] ID(m) != ID(d) ", friend); + + loglog(logbuffer); + } + + ping_lastrecv = lastdump - msgfptr->ping_lastrecv; + + if (ping_lastrecv > 999) + ping_lastrecv = 999; + + snprintf(logbuffer, sizeof(logbuffer), "F[%2u] <%s> %02u [%03u] %s\n", + friend, msgfptr->name, msgfptr->crypt_connection_id, + ping_lastrecv, ID2String(msgfptr->client_id)); + loglog(logbuffer); + + for (client = 0; client < MAX_FRIEND_CLIENTS; client++) { + Client_data *cptr = &dhtfptr->client_list[client]; + last_pinged = lastdump - cptr->last_pinged; + + if (last_pinged > 999) + last_pinged = 999; + + snprintf(logbuffer, sizeof(logbuffer), "F[%2u] => C[%2u] %s:%u [%3u] %s\n", + friend, client, ip_ntoa(&cptr->ip_port.ip), + ntohs(cptr->ip_port.port), last_pinged, + ID2String(cptr->client_id)); + loglog(logbuffer); + } + } + + loglog(" = = = = = = = = \n"); + } - loglog(" = = = = = = = = \n"); - } #endif } @@ -1410,6 +1424,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) memcpy(temp, data, size); uint32_t i; + for (i = 0; i < num; ++i) { if (temp[i].status >= 3) { int fnum = m_addfriend_norequest(m, temp[i].client_id); diff --git a/toxcore/network.c b/toxcore/network.c index 44448f38..4818b438 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -73,15 +73,18 @@ static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *i int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t length) { #ifdef TOX_ENABLE_IPV6 + /* socket AF_INET, but target IP NOT: can't send */ - if ((net->family == AF_INET) && (ip_port.ip.family != AF_INET)) - return 0; + if ((net->family == AF_INET) && (ip_port.ip.family != AF_INET)) + return -1; + #endif - + struct sockaddr_storage addr; size_t addrsize = 0; #ifdef TOX_ENABLE_IPV6 + if (ip_port.ip.family == AF_INET) { if (net->family == AF_INET6) { /* must convert to IPV4-in-IPV6 address */ @@ -99,11 +102,10 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le addr6->sin6_flowinfo = 0; addr6->sin6_scope_id = 0; - } - else { + } else { IP4 ip4 = ip_port.ip.ip4; #else - IP4 ip4 = ip_port.ip; + IP4 ip4 = ip_port.ip; #endif addrsize = sizeof(struct sockaddr_in); struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; @@ -112,8 +114,8 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le addr4->sin_port = ip_port.port; #ifdef TOX_ENABLE_IPV6 } - } - else if (ip_port.ip.family == AF_INET6) { + } else if (ip_port.ip.family == AF_INET6) + { addrsize = sizeof(struct sockaddr_in6); struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; addr6->sin6_family = AF_INET6; @@ -122,10 +124,12 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le addr6->sin6_flowinfo = 0; addr6->sin6_scope_id = 0; - } else { + } else + { /* unknown address type*/ - return 0; + return -1; } + #endif int res = sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize); @@ -153,37 +157,40 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t if (*(int32_t *)length <= 0) { #ifdef LOGGING + if ((length < 0) && (errno != EWOULDBLOCK)) { sprintf(logbuffer, "Unexpected error reading from socket: %u, %s\n", errno, strerror(errno)); loglog(logbuffer); } + #endif return -1; /* Nothing received or empty packet. */ } #ifdef TOX_ENABLE_IPV6 + if (addr.ss_family == AF_INET) { struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; ip_port->ip.family = addr_in->sin_family; ip_port->ip.ip4.in_addr = addr_in->sin_addr; ip_port->port = addr_in->sin_port; - } - else if (addr.ss_family == AF_INET6) { + } else if (addr.ss_family == AF_INET6) { struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr; ip_port->ip.family = addr_in6->sin6_family; ip_port->ip.ip6 = addr_in6->sin6_addr; ip_port->port = addr_in6->sin6_port; - } - else + } else return -1; + #else + if (addr.ss_family == AF_INET) { struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; ip_port->ip.in_addr = addr_in->sin_addr; ip_port->port = addr_in->sin_port; - } - else + } else return -1; + #endif #ifdef LOGGING @@ -261,17 +268,20 @@ static void at_shutdown(void) Networking_Core *new_networking(IP ip, uint16_t port) { #ifdef TOX_ENABLE_IPV6 + /* maybe check for invalid IPs like 224+.x.y.z? if there is any IP set ever */ if (ip.family != AF_INET && ip.family != AF_INET6) { fprintf(stderr, "Invalid address family: %u\n", ip.family); return NULL; } + #endif if (at_startup() != 0) return NULL; Networking_Core *temp = calloc(1, sizeof(Networking_Core)); + if (temp == NULL) return NULL; @@ -297,7 +307,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) #else if (temp->sock < 0) { - fprintf(stderr, "Failed to get a scoket?! %u, %s\n", errno, strerror(errno)); + fprintf(stderr, "Failed to get a socket?! %u, %s\n", errno, strerror(errno)); free(temp); return NULL; } @@ -341,11 +351,11 @@ Networking_Core *new_networking(IP ip, uint16_t port) struct sockaddr_storage addr; size_t addrsize; #ifdef TOX_ENABLE_IPV6 - if (temp->family == AF_INET) - { + + if (temp->family == AF_INET) { IP4 ip4 = ip.ip4; #else - IP4 ip4 = ip; + IP4 ip4 = ip; #endif addrsize = sizeof(struct sockaddr_in); struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; @@ -355,8 +365,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) portptr = &addr4->sin_port; #ifdef TOX_ENABLE_IPV6 - } - else if (temp->family == AF_INET6) + } else if (temp->family == AF_INET6) { addrsize = sizeof(struct sockaddr_in6); struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; @@ -368,21 +377,26 @@ Networking_Core *new_networking(IP ip, uint16_t port) addr6->sin6_scope_id = 0; portptr = &addr6->sin6_port; - } - else + } else return NULL; - if (ip.family == AF_INET6) { + if (ip.family == AF_INET6) + { char ipv6only = 0; - int res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only)); #ifdef LOGGING + int res = +#endif + setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only)); +#ifdef LOGGING + if (res < 0) { - sprintf(logbuffer, "Failed to enable dual-stack on IPv6 socket, won't be able to receive from/send to IPv4 addresses. (%u, %s)\n", + sprintf(logbuffer, + "Failed to enable dual-stack on IPv6 socket, won't be able to receive from/send to IPv4 addresses. (%u, %s)\n", errno, strerror(errno)); loglog(logbuffer); - } - else + } else loglog("Embedded IPv4 addresses enabled successfully.\n"); + #endif /* multicast local nodes */ @@ -392,17 +406,22 @@ Networking_Core *new_networking(IP ip, uint16_t port) mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02; mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01; mreq.ipv6mr_interface = 0; - res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); #ifdef LOGGING + res = +#endif + setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); +#ifdef LOGGING + if (res < 0) { sprintf(logbuffer, "Failed to activate local multicast membership. (%u, %s)\n", errno, strerror(errno)); loglog(logbuffer); - } - else + } else loglog("Local multicast group FF02::1 joined successfully.\n"); + #endif } + #endif /* a hanging program or a different user might block the standard port; @@ -424,16 +443,18 @@ Networking_Core *new_networking(IP ip, uint16_t port) uint16_t port_to_try = port; *portptr = htons(port_to_try); int tries, res; - for(tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++) + + for (tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++) { res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); - if (!res) - { + + if (!res) { temp->port = *portptr; #ifdef LOGGING sprintf(logbuffer, "Bound successfully to %s:%u.\n", ip_ntoa(&ip), ntohs(temp->port)); loglog(logbuffer); #endif + /* errno isn't reset on success, only set on failure, the failed * binds with parallel clients yield a -EPERM to the outside if * errno isn't cleared here */ @@ -444,6 +465,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) } port_to_try++; + if (port_to_try > TOX_PORTRANGE_TO) port_to_try = TOX_PORTRANGE_FROM; @@ -451,8 +473,8 @@ Networking_Core *new_networking(IP ip, uint16_t port) } fprintf(stderr, "Failed to bind socket: %u, %s (IP/Port: %s:%u\n", errno, - strerror(errno), ip_ntoa(&ip), port); - free(temp); + strerror(errno), ip_ntoa(&ip), port); + kill_networking(temp); return NULL; } @@ -480,24 +502,24 @@ int ip_equal(IP *a, IP *b) return 0; #ifdef TOX_ENABLE_IPV6 - /* same family */ - if (a->family == b->family) { - if (a->family == AF_INET) - return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr); - else if (a->family == AF_INET6) - return IN6_ARE_ADDR_EQUAL(&a->ip6, &b->ip6); - else - return 0; - } + /* same family */ + if (a->family == b->family) { + if (a->family == AF_INET) + return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr); + else if (a->family == AF_INET6) + return IN6_ARE_ADDR_EQUAL(&a->ip6, &b->ip6); + else + return 0; + } - /* different family: check on the IPv6 one if it is the IPv4 one embedded */ + /* different family: check on the IPv6 one if it is the IPv4 one embedded */ if ((a->family == AF_INET) && (b->family == AF_INET6)) { - if (IN6_IS_ADDR_V4COMPAT(&b->ip6)) - return (a->ip4.in_addr.s_addr == b->ip6.s6_addr32[3]); - } else if ((a->family == AF_INET6) && (b->family == AF_INET)) { - if (IN6_IS_ADDR_V4COMPAT(&a->ip6)) - return (a->ip6.s6_addr32[3] == b->ip4.in_addr.s_addr); - } + if (IN6_IS_ADDR_V4COMPAT(&b->ip6)) + return (a->ip4.in_addr.s_addr == b->ip6.s6_addr32[3]); + } else if ((a->family == AF_INET6) && (b->family == AF_INET)) { + if (IN6_IS_ADDR_V4COMPAT(&a->ip6)) + return (a->ip6.s6_addr32[3] == b->ip4.in_addr.s_addr); + } return 0; #else @@ -602,28 +624,27 @@ const char *ip_ntoa(IP *ip) { if (ip) { #ifdef TOX_ENABLE_IPV6 + if (ip->family == AF_INET) { addresstext[0] = 0; struct in_addr *addr = (struct in_addr *)&ip->ip4; inet_ntop(ip->family, addr, addresstext, sizeof(addresstext)); - } - else if (ip->family == AF_INET6) { + } else if (ip->family == AF_INET6) { addresstext[0] = '['; struct in6_addr *addr = (struct in6_addr *)&ip->ip6; inet_ntop(ip->family, addr, &addresstext[1], sizeof(addresstext) - 3); size_t len = strlen(addresstext); addresstext[len] = ']'; addresstext[len + 1] = 0; - } - else + } else snprintf(addresstext, sizeof(addresstext), "(IP invalid, family %u)", ip->family); + #else addresstext[0] = 0; struct in_addr *addr = (struct in_addr *)&ip; inet_ntop(AF_INET, addr, addresstext, sizeof(addresstext)); #endif - } - else + } else snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)"); /* brute force protection against lacking termination */ @@ -652,6 +673,7 @@ int addr_parse_ip(const char *address, IP *to) #ifdef TOX_ENABLE_IPV6 struct in_addr addr4; + if (1 == inet_pton(AF_INET, address, &addr4)) { to->family = AF_INET; to->ip4.in_addr = addr4; @@ -659,17 +681,21 @@ int addr_parse_ip(const char *address, IP *to) }; struct in6_addr addr6; + if (1 == inet_pton(AF_INET6, address, &addr6)) { to->family = AF_INET6; to->ip6 = addr6; return 1; }; + #else struct in_addr addr4; + if (1 == inet_pton(AF_INET, address, &addr4)) { to->in_addr = addr4; return 1; }; + #endif return 0; @@ -714,24 +740,13 @@ int addr_resolve(const char *address, IP *to, IP *extra) hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses. -#ifdef __WIN32__ - WSADATA wsa_data; - - /* CLEANUP: really not the best place to put this */ - rc = WSAStartup(MAKEWORD(2, 2), &wsa_data); - - if (rc != 0) { + if (at_startup() != 0) return 0; - } - -#endif rc = getaddrinfo(address, NULL, &hints, &server); + // Lookup failed. if (rc != 0) { -#ifdef __WIN32__ - WSACleanup(); -#endif return 0; } @@ -742,71 +757,71 @@ int addr_resolve(const char *address, IP *to, IP *extra) memset(&ip6, 0, sizeof(ip6)); #endif - for(walker = server; (walker != NULL) && (rc != 3); walker = walker->ai_next) { - switch(walker->ai_family) { - case AF_INET: - if (walker->ai_family == family) { - struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; + for (walker = server; (walker != NULL) && (rc != 3); walker = walker->ai_next) { + switch (walker->ai_family) { + case AF_INET: + if (walker->ai_family == family) { /* AF_INET requested, done */ + struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; #ifdef TOX_ENABLE_IPV6 - to->ip4.in_addr = addr->sin_addr; + to->ip4.in_addr = addr->sin_addr; #else - to->in_addr = addr->sin_addr; + to->in_addr = addr->sin_addr; #endif - rc = 3; - } -#ifdef TOX_ENABLE_IPV6 - else if (!(rc & 1)) { - struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; - ip4.in_addr = addr->sin_addr; - rc |= 1; - } -#endif - break; /* switch */ - -#ifdef TOX_ENABLE_IPV6 - case AF_INET6: - if (walker->ai_family == family) { - if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { - struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; - to->ip6 = addr->sin6_addr; rc = 3; } - } else if (!(rc & 2)) { - if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { - struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; - ip6 = addr->sin6_addr; - rc |= 2; + +#ifdef TOX_ENABLE_IPV6 + else if (!(rc & 1)) { /* AF_UNSPEC requested, store away */ + struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; + ip4.in_addr = addr->sin_addr; + rc |= 1; } - } - break; /* switch */ +#endif + break; /* switch */ +#ifdef TOX_ENABLE_IPV6 + + case AF_INET6: + if (walker->ai_family == family) { /* AF_INET6 requested, done */ + if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; + to->ip6 = addr->sin6_addr; + rc = 3; + } + } else if (!(rc & 2)) { /* AF_UNSPEC requested, store away */ + if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; + ip6 = addr->sin6_addr; + rc |= 2; + } + } + + break; /* switch */ #endif } } #ifdef TOX_ENABLE_IPV6 + if (to->family == AF_UNSPEC) { if (rc & 2) { to->family = AF_INET6; to->ip6 = ip6; + if ((rc & 1) && (extra != NULL)) { extra->family = AF_INET; extra->ip4 = ip4; } - } - else if (rc & 1) { + } else if (rc & 1) { to->family = AF_INET; to->ip4 = ip4; - } - else + } else rc = 0; } + #endif - + freeaddrinfo(server); -#ifdef __WIN32__ - WSACleanup(); -#endif return rc; } @@ -839,22 +854,22 @@ static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *i { if (res < 0) snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x\n", - buffer[0], message, buflen < 999 ? buflen : 999, 'E', - ip_ntoa(&ip_port->ip), ntohs(ip_port->port), errno, - strerror(errno), buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, - buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); + buffer[0], message, buflen < 999 ? buflen : 999, 'E', + ip_ntoa(&ip_port->ip), ntohs(ip_port->port), errno, + strerror(errno), buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, + buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); else if ((res > 0) && (res <= buflen)) snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x\n", - buffer[0], message, res < 999 ? res : 999, res < buflen ? '<' : '=', - ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0, - "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, - buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); + buffer[0], message, res < 999 ? res : 999, res < buflen ? '<' : '=', + ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0, + "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, + buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); else /* empty or overwrite */ snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %u%c%u %s:%u (%u: %s) | %04x%04x\n", - buffer[0], message, res, !res ? '0' : '>', buflen, - ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0, - "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, - buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); + buffer[0], message, res, !res ? '0' : '>', buflen, + ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0, + "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, + buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); logbuffer[sizeof(logbuffer) - 1] = 0; loglog(logbuffer); diff --git a/toxcore/ping.c b/toxcore/ping.c index 113702bf..56ce2f59 100644 --- a/toxcore/ping.c +++ b/toxcore/ping.c @@ -113,7 +113,7 @@ bool is_pinging(void *ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: Repl /* ping_id = 0 means match any id. */ if ((!ip_isset(&ipp.ip) || ipport_equal(&png->pings[id].ipp, &ipp)) && - (png->pings[id].id == ping_id || ping_id == 0)) { + (png->pings[id].id == ping_id || ping_id == 0)) { return true; } } diff --git a/toxcore/tox.c b/toxcore/tox.c index 68b1e6e9..80d64626 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -450,7 +450,7 @@ void tox_bootstrap_from_ip(void *tox, IP_Port ip_port, uint8_t *public_key) DHT_bootstrap(m->dht, ip_port, public_key); } int tox_bootstrap_from_address(void *tox, const char *address, - uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) + uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) { Messenger *m = tox; return DHT_bootstrap_from_address(m->dht, address, ipv6enabled, port, public_key); diff --git a/toxcore/tox.h b/toxcore/tox.h index c52a644f..a15d7ea0 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -409,12 +409,12 @@ void tox_bootstrap_from_ip(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key); * if ipv6enabled is 0 (zero), the resolving sticks STRICTLY to IPv4 addresses * if ipv6enabled is not 0 (zero), the resolving looks for IPv6 addresses first, * then IPv4 addresses. - * + * * returns 1 if the address could be converted into an IP address * returns 0 otherwise */ int tox_bootstrap_from_address(Tox *tox, const char *address, uint8_t ipv6enabled, - uint16_t port, uint8_t *public_key); + uint16_t port, uint8_t *public_key); /* return 0 if we are not connected to the DHT. * return 1 if we are.