From a0f08839bd134f3f964a6cccf1243cd42f15d4e5 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Sun, 20 Oct 2013 16:56:12 +0200 Subject: Main: Eliminate TOX_ENABLE_IPV6 (then always on), CLIENT_ONETOONE_IP (then always off). Additionally (besides cleanups): network.h/tox.h: - WIN32: fix a strange sa_family_t definition - WIN32: define EWOULDBLOCK to WSAEWOULDBLOCK - WIN32: kill macro for an existing function (IN6_ADDR_EQUAL) network.c: - use EWOULDBLOCK instead of EAGAIN (same value, but EWOULDBLOCK is more "popular") - new_networking(): only try to enable IPv4-in-IPv6 if it's not already enabled per default - inet_ntop()/inet_pton(): WIN32: remove partial initializers in favor of a simple memset() - ip_equal(): WIN32: use an existing function - logging: networking_wait_execute(): only dump result if not timeout - logging: loglogdata(): kill an unused variable LAN_discovery.c: - send_broadcasts(): re-enabled, can only support IPv4 by principle, split into fetch_broadcast_info() (to fetch the addresses once) and send_broadcasts() (actual sending) DHT.c: - DHT_load_state_callback(): enclosed a fprintf(stderr, ...) into #ifdef DEBUG Lossless_UDP.c: - change_handshake(): harden against strange sa_family_t definitions Messenger.c: - logging: fix ID to string conversion util.c: - logging: eliminate a signed-warning --- toxcore/DHT.c | 387 ++++++++++-------------------------------------- toxcore/DHT.h | 27 +--- toxcore/LAN_discovery.c | 122 ++++++++------- toxcore/Lossless_UDP.c | 30 +--- toxcore/Lossless_UDP.h | 6 - toxcore/Messenger.c | 48 +++--- toxcore/network.c | 231 ++++++++++------------------- toxcore/network.h | 32 +--- toxcore/tox.h | 31 +--- toxcore/util.c | 3 +- 10 files changed, 273 insertions(+), 644 deletions(-) (limited to 'toxcore') diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 470826f0..ee51f16c 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -131,12 +131,9 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id uint64_t temp_time = unix_time(); for (i = 0; i < length; i++) -#ifdef CLIENT_ONETOONE_IP /* Dead nodes are considered dead (not in the list)*/ - if (!is_timeout(temp_time, list[i].assoc.timestamp, KILL_NODE_TIMEOUT)) -#else + /* Dead nodes are considered dead (not in the list)*/ if (!is_timeout(temp_time, list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) || !is_timeout(temp_time, list[i].assoc6.timestamp, KILL_NODE_TIMEOUT)) -#endif if (id_equal(list[i].client_id, client_id)) return 1; @@ -155,41 +152,12 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t uint32_t i; uint64_t temp_time = unix_time(); -#ifdef CLIENT_ONETOONE_IP - uint8_t candropipv4 = 1; - - if (ip_port.ip.family == AF_INET6) { - uint8_t ipv6cnt = 0; - - /* ipv6: count how many spots are used */ - for (i = 0; i < length; i++) - if (list[i].assoc.ip_port.ip.family == AF_INET6) - ipv6cnt++; - - /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */ - if (ipv6cnt > length / 2) - candropipv4 = 0; - } - -#endif - /* if client_id is in list, find it and maybe overwrite ip_port */ for (i = 0; i < length; ++i) if (id_equal(list[i].client_id, client_id)) { /* Refresh the client timestamp. */ -#ifdef CLIENT_ONETOONE_IP - /* if we got "too many" ipv6 addresses already, keep the ipv4 address */ - if (!candropipv4 && (list[i].assoc.ip_port.ip.family == AF_INET)) - return 1; - - if (LAN_ip(list[i].assoc.ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0) - return 1; - - list[i].assoc.ip_port = ip_port; - list[i].assoc.timestamp = temp_time; -#else - if (ip_port.ip.family == AF_INET) { + #ifdef LOGGING if (!ipport_equal(&list[i].assoc4.ip_port, &ip_port)) { @@ -209,6 +177,7 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t list[i].assoc4.ip_port = ip_port; list[i].assoc4.timestamp = temp_time; } else if (ip_port.ip.family == AF_INET6) { + #ifdef LOGGING if (!ipport_equal(&list[i].assoc6.ip_port, &ip_port)) { @@ -229,7 +198,6 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t list[i].assoc6.timestamp = temp_time; } -#endif return 1; } @@ -238,21 +206,6 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t * TODO: maybe we SHOULDN'T do that if that client_id is in a friend_list * and the one who is the actual friend's client_id/address set? */ for (i = 0; i < length; ++i) { -#ifdef CLIENT_ONETOONE_IP - - if (ipport_equal(&list[i].assoc.ip_port, &ip_port)) { - /* Initialize client timestamp. */ - list[i].assoc.timestamp = temp_time; - memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); -#ifdef LOGGING - sprintf(logbuffer, "coipil[%u]: switching client_id\n", i); - loglog(logbuffer); -#endif - return 1; - } - -#else - /* MAYBE: check the other address, if valid, don't nuke? */ if ((ip_port.ip.family == AF_INET) && ipport_equal(&list[i].assoc4.ip_port, &ip_port)) { /* Initialize client timestamp. */ @@ -277,8 +230,6 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t memset(&list[i].assoc4, 0, sizeof(list[i].assoc4)); return 1; } - -#endif } return 0; @@ -338,22 +289,15 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod continue; IPPTsPng *ipptp = NULL; -#ifdef CLIENT_ONETOONE_IP - ipptp = &client->assoc; -#else - if (sa_family == AF_INET) ipptp = &client->assoc4; else ipptp = &client->assoc6; -#endif - /* node not in a good condition? */ if (is_timeout(timestamp, ipptp->timestamp, BAD_NODE_TIMEOUT)) continue; -#ifdef TOX_ENABLE_IPV6 IP *client_ip = &ipptp->ip_port.ip; /* @@ -373,9 +317,6 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod } ipv46x = !(sa_family == ip_treat_as_family); -#else - ipv46x = !(sa_family == AF_INET); -#endif /* node address of the wrong family? */ if (ipv46x) @@ -454,43 +395,17 @@ static int replace_bad( Client_data *list, uint32_t i; uint64_t temp_time = unix_time(); -#ifdef CLIENT_ONETOONE_IP - uint8_t candropipv4 = 1; - - if (ip_port.ip.family == AF_INET6) { - uint32_t ipv6cnt = 0; - - /* ipv6: count how many spots are used */ - for (i = 0; i < length; i++) - if (list[i].assoc.ip_port.ip.family == AF_INET6) - ipv6cnt++; - - /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */ - if (ipv6cnt > length / 2) - candropipv4 = 0; - } - -#endif - for (i = 0; i < length; ++i) { /* If node is bad */ Client_data *client = &list[i]; IPPTsPng *ipptp = NULL; -#ifdef CLIENT_ONETOONE_IP - ipptp = &client->assoc; - - if ((candropipv4 || (ipptp->ip_port.ip.family == AF_INET6)) && - is_timeout(temp_time, ipptp->timestamp, BAD_NODE_TIMEOUT)) { -#else - if (ip_port.ip.family == AF_INET) ipptp = &client->assoc4; else ipptp = &client->assoc6; if (is_timeout(temp_time, ipptp->timestamp, BAD_NODE_TIMEOUT)) { -#endif memcpy(client->client_id, client_id, CLIENT_ID_SIZE); ipptp->ip_port = ip_port; ipptp->timestamp = temp_time; @@ -542,60 +457,17 @@ static int replace_good( Client_data *list, int8_t replace = -1; -#ifdef CLIENT_ONETOONE_IP - uint8_t candropipv4 = 1; - - if (ip_port.ip.family == AF_INET6) { - uint32_t i, ipv6cnt = 0; - - /* ipv6: count how many spots are used */ - for (i = 0; i < length; i++) - if (list[i].assoc.ip_port.ip.family == AF_INET6) - ipv6cnt++; - - /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */ - if (ipv6cnt > length / 2) - candropipv4 = 0; - } - - uint32_t i; - - if (candropipv4) { - /* either we got an ipv4 address, or we're "allowed" to push out an ipv4 - * address in favor of an ipv6 one - * - * because the list is sorted, we can simply check the client_id at the - * border, either it is closer, then every other one is as well, or it is - * further, then it gets pushed out in favor of the new address, which - * will with the next sort() move to its "rightful" position - * - * CAVEAT: weirdly enough, the list is sorted DESCENDING in distance - * so the furthest element is the first, NOT the last (at least that's - * what the comment above sort_list() claims) - */ -#endif - if (id_closest(comp_client_id, list[0].client_id, client_id) == 2) - replace = 0; - -#ifdef CLIENT_ONETOONE_IP - } else { - /* ipv6 case without a right to push out an ipv4: only look for ipv6 - * addresses, the first one we find is either closer (then we can skip - * out like above) or further (then we can replace it, like above) - */ - for (i = 0; i < length; i++) { - Client_data *client = &list[i]; - - if (client->assoc.ip_port.ip.family == AF_INET6) { - if (id_closest(comp_client_id, list[i].client_id, client_id) == 2) - replace = i; - - break; - } - } - } - -#endif + /* Because the list is sorted, we can simply check the client_id at the + * border, either it is closer, then every other one is as well, or it is + * further, then it gets pushed out in favor of the new address, which + * will with the next sort() move to its "rightful" position + * + * CAVEAT: weirdly enough, the list is sorted DESCENDING in distance + * so the furthest element is the first, NOT the last (at least that's + * what the comment above sort_list() claims) + */ + if (id_closest(comp_client_id, list[0].client_id, client_id) == 2) + replace = 0; if (replace != -1) { #ifdef DEBUG @@ -603,16 +475,12 @@ static int replace_good( Client_data *list, #endif Client_data *client = &list[replace]; IPPTsPng *ipptp = NULL; -#ifdef CLIENT_ONETOONE_IP - ipptp = &client->assoc; -#else if (ip_port.ip.family == AF_INET) ipptp = &client->assoc4; else ipptp = &client->assoc6; -#endif memcpy(client->client_id, client_id, CLIENT_ID_SIZE); ipptp->ip_port = ip_port; ipptp->timestamp = unix_time(); @@ -681,11 +549,6 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint if (id_equal(client_id, dht->c->self_public_key)) { for (i = 0; i < LCLIENT_LIST; ++i) { if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) { -#ifdef CLIENT_ONETOONE_IP - dht->close_clientlist[i].assoc.ret_ip_port = ip_port; - dht->close_clientlist[i].assoc.ret_timestamp = temp_time; -#else - if (ip_port.ip.family == AF_INET) { dht->close_clientlist[i].assoc4.ret_ip_port = ip_port; dht->close_clientlist[i].assoc4.ret_timestamp = temp_time; @@ -694,7 +557,6 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint dht->close_clientlist[i].assoc6.ret_timestamp = temp_time; } -#endif return; } } @@ -704,11 +566,6 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint if (id_equal(client_id, dht->friends_list[i].client_id)) { for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { if (id_equal(nodeclient_id, dht->friends_list[i].client_list[j].client_id)) { -#ifdef CLIENT_ONETOONE_IP - dht->friends_list[i].client_list[j].assoc.ret_ip_port = ip_port; - dht->friends_list[i].client_list[j].assoc.ret_timestamp = temp_time; -#else - if (ip_port.ip.family == AF_INET) { dht->friends_list[i].client_list[j].assoc4.ret_ip_port = ip_port; dht->friends_list[i].client_list[j].assoc4.ret_timestamp = temp_time; @@ -717,7 +574,6 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint dht->friends_list[i].client_list[j].assoc6.ret_timestamp = temp_time; } -#endif return; } } @@ -836,7 +692,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl new_nonce(nonce); memcpy(plain, &ping_id, sizeof(ping_id)); -#ifdef TOX_ENABLE_IPV6 + Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); int i, num_nodes_ok = 0; @@ -862,10 +718,6 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl num_nodes = num_nodes_ok; } -#else - memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node4_format_size); -#endif - int len = encrypt_data( public_key, dht->c->self_secret_key, nonce, @@ -887,7 +739,6 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); } -#ifdef TOX_ENABLE_IPV6 /* Send a send nodes response: message for IPv6 nodes */ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) { @@ -933,7 +784,6 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_ return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); } -#endif static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) { @@ -962,10 +812,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); /* TODO: prevent possible amplification attacks */ -#endif add_toping(dht->ping, packet + 1, source); //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ @@ -1005,14 +853,11 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 if (!is_gettingnodes(dht, source, ping_id)) return 1; - uint32_t i; - Node_format nodes_list[MAX_SENT_NODES]; - -#ifdef TOX_ENABLE_IPV6 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); + Node_format nodes_list[MAX_SENT_NODES]; + uint32_t i, num_nodes_ok = 0; - uint32_t num_nodes_ok = 0; - + /* blow up from Node4 (IPv4) wire format to Node (IPv4/IPv6) structure */ for (i = 0; i < num_nodes; i++) if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != (uint32_t)~0)) { memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); @@ -1028,10 +873,6 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 num_nodes = num_nodes_ok; } -#else - memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); -#endif - addto_lists(dht, source, packet + 1); for (i = 0; i < num_nodes; ++i) { @@ -1042,7 +883,6 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 return 0; } -#ifdef TOX_ENABLE_IPV6 static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length) { DHT *dht = object; @@ -1088,7 +928,6 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, return 0; } -#endif /*----------------------------------------------------------------------------------*/ /*------------------------END of packet handling functions--------------------------*/ @@ -1103,21 +942,17 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_ for (i = 0; i < length; ++i) { IPPTsPng *assoc; -#ifdef CLIENT_ONETOONE_IP - assoc = &list[i].assoc; -#else uint32_t a; for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4) -#endif - if (ipport_isset(&(assoc->ip_port)) && - !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { - getnodes(dht, assoc->ip_port, list[i].client_id, client_id); - ++num; + if (ipport_isset(&(assoc->ip_port)) && + !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { + getnodes(dht, assoc->ip_port, list[i].client_id, client_id); + ++num; - if (num >= max_num) - return; - } + if (num >= max_num) + return; + } } } @@ -1194,17 +1029,13 @@ int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port) if (id_equal(client->client_id, client_id)) { IPPTsPng *assoc = NULL; -#ifdef CLIENT_ONETOONE_IP - assoc = &client->assoc; -#else uint32_t a; for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) -#endif - if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { - *ip_port = assoc->ip_port; - return 1; - } + if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { + *ip_port = assoc->ip_port; + return 1; + } } } @@ -1229,27 +1060,22 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8 /* If node is not dead. */ Client_data *client = &list[i]; IPPTsPng *assoc; -#ifdef CLIENT_ONETOONE_IP - assoc = &client->assoc; -#else uint32_t a; for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) -#endif - - if (!is_timeout(temp_time, assoc->timestamp, KILL_NODE_TIMEOUT)) { - if (is_timeout(temp_time, assoc->last_pinged, PING_INTERVAL)) { - send_ping_request(dht->ping, assoc->ip_port, client->client_id ); - assoc->last_pinged = temp_time; - } + if (!is_timeout(temp_time, assoc->timestamp, KILL_NODE_TIMEOUT)) { + if (is_timeout(temp_time, assoc->last_pinged, PING_INTERVAL)) { + send_ping_request(dht->ping, assoc->ip_port, client->client_id ); + assoc->last_pinged = temp_time; + } - /* If node is good. */ - if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { - client_list[num_nodes] = client; - assoc_list[num_nodes] = assoc; - ++num_nodes; + /* If node is good. */ + if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { + client_list[num_nodes] = client; + assoc_list[num_nodes] = assoc; + ++num_nodes; + } } - } } if ((num_nodes != 0) && @@ -1291,31 +1117,25 @@ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable { 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) { + /* setup for getting BOTH: an IPv6 AND an IPv4 address */ 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 - if (addr_resolve_or_parse_ip(address, &ip_port_v64.ip, ip_extra)) { 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 return 0; @@ -1332,12 +1152,6 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length) for (i = 0; i < LCLIENT_LIST; ++i) { if (id_equal(client_id, dht->close_clientlist[i].client_id)) { Client_data *client = &dht->close_clientlist[i]; -#ifdef CLIENT_ONETOONE_IP - - if (ip_isset(&client->assoc.ip_port.ip)) - return sendpacket(dht->c->lossless_udp->net, dht->close_clientlist[i].assoc.ip_port, packet, length); - -#else if (ip_isset(&client->assoc6.ip_port.ip)) return sendpacket(dht->c->lossless_udp->net, client->assoc6.ip_port, packet, length); @@ -1345,8 +1159,6 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length) return sendpacket(dht->c->lossless_udp->net, client->assoc4.ip_port, packet, length); else break; - -#endif } } @@ -1355,7 +1167,6 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length) /* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist. * ip_portlist must be at least MAX_FRIEND_CLIENTS big. - * unless CLIENT_ONETOONE_IP is defined, returns an array with ips of the same family. * * return the number of ips returned. * return 0 if we are connected to friend or if no ips were found. @@ -1375,55 +1186,56 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) int num_ipv4s = 0; IP_Port ipv6s[MAX_FRIEND_CLIENTS]; int num_ipv6s = 0; + uint8_t connected; for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { client = &(friend->client_list[i]); - - IPPTsPng *assoc = NULL; -#ifdef CLIENT_ONETOONE_IP - assoc = &client->assoc; -#else - assoc = &client->assoc4; -#endif - - if (id_equal(client->client_id, friend->client_id) && - !is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) - return 0; + connected = 0; /* If ip is not zero and node is good. */ - if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { - ipv4s[num_ipv4s] = assoc->ret_ip_port; + if (ip_isset(&client->assoc4.ret_ip_port.ip) && !is_timeout(temp_time, client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) { + ipv4s[num_ipv4s] = client->assoc4.ret_ip_port; ++num_ipv4s; + + connected = 1; } - } -#ifndef CLIENT_ONETOONE_IP + if (ip_isset(&client->assoc6.ret_ip_port.ip) && !is_timeout(temp_time, client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) { + ipv6s[num_ipv6s] = client->assoc6.ret_ip_port; + ++num_ipv6s; - for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { - client = &(friend->client_list[i]); + connected = 1; + } - IPPTsPng *assoc = NULL; - assoc = &client->assoc6; + if (connected && id_equal(client->client_id, friend->client_id)) + return 0; /* direct connectivity */ + } - if (id_equal(client->client_id, friend->client_id) && - !is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) - return 0; +#ifdef FRIEND_IPLIST_PAD + memcpy(ip_portlist, ipv6s, num_ipv6s * sizeof(IP_Port)); + if (num_ipv6s == MAX_FRIEND_CLIENTS) + return MAX_FRIEND_CLIENTS; - /* If ip is not zero and node is good. */ - if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { - ipv6s[num_ipv6s] = assoc->ret_ip_port; - ++num_ipv6s; - } - } + int num_ipv4s_used = MAX_FRIEND_CLIENTS - num_ipv6s; + if (num_ipv4s_used > num_ipv4s) + num_ipv4s_used = num_ipv4s; + memcpy(&ip_portlist[num_ipv6s], ipv4s, num_ipv4s_used * sizeof(IP_Port)); + return num_ipv6s + num_ipv4s_used; + +#else /* !FRIEND_IPLIST_PAD */ + /* there must be some secret reason why we can't pad the longer list + * with the shorter one... + */ if (num_ipv6s >= num_ipv4s) { memcpy(ip_portlist, ipv6s, num_ipv6s * sizeof(IP_Port)); return num_ipv6s; } -#endif memcpy(ip_portlist, ipv4s, num_ipv4s * sizeof(IP_Port)); return num_ipv4s; + +#endif /* !FRIEND_IPLIST_PAD */ } @@ -1452,30 +1264,23 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt DHT_Friend *friend = &dht->friends_list[num]; Client_data *client; -#ifndef CLIENT_ONETOONE_IP /* extra legwork, because having the outside allocating the space for us * is *usually* good(tm) (bites us in the behind in this case though) */ uint32_t a; for (a = 0; a < 2; a++) -#endif for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { if (friend_sent[i])/* Send one packet per client.*/ continue; client = &friend->client_list[i]; IPPTsPng *assoc = NULL; -#ifdef CLIENT_ONETOONE_IP - assoc = &client->assoc; -#else if (!a) assoc = &client->assoc4; else assoc = &client->assoc6; -#endif - /* If ip is not zero and node is good. */ if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { @@ -1510,27 +1315,20 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint uint32_t i; uint64_t temp_time = unix_time(); -#ifndef CLIENT_ONETOONE_IP /* extra legwork, because having the outside allocating the space for us * is *usually* good(tm) (bites us in the behind in this case though) */ uint32_t a; for (a = 0; a < 2; a++) -#endif for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { client = &friend->client_list[i]; IPPTsPng *assoc = NULL; -#ifdef CLIENT_ONETOONE_IP - assoc = &client->assoc; -#else if (!a) assoc = &client->assoc4; else assoc = &client->assoc6; -#endif - /* If ip is not zero and node is good. */ if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { ip_list[n] = assoc->ip_port; @@ -1776,9 +1574,7 @@ DHT *new_DHT(Net_Crypto *c) dht->c = c; networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht); -#ifdef TOX_ENABLE_IPV6 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); -#endif init_cryptopackets(dht); cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); @@ -1885,12 +1681,8 @@ uint32_t DHT_size(DHT *dht) uint32_t num = 0, i; for (i = 0; i < LCLIENT_LIST; ++i) -#ifdef CLIENT_ONETOONE_IP - if (dht->close_clientlist[i].assoc.timestamp != 0) -#else if ((dht->close_clientlist[i].assoc4.timestamp != 0) || (dht->close_clientlist[i].assoc6.timestamp != 0)) -#endif num++; uint32_t size32 = sizeof(uint32_t), sizesubhead = size32 * 2; @@ -1917,11 +1709,7 @@ void DHT_save(DHT *dht, uint8_t *data) data += sizeof(uint32_t); len = sizeof(DHT_Friend) * dht->num_friends; -#ifdef CLIENT_ONETOONE_IP - type = DHT_STATE_TYPE_FRIENDS; -#else type = DHT_STATE_TYPE_FRIENDS_ASSOC46; -#endif data = z_state_save_subheader(data, len, type); memcpy(data, dht->friends_list, len); data += len; @@ -1929,32 +1717,20 @@ void DHT_save(DHT *dht, uint8_t *data) uint32_t num = 0, i; for (i = 0; i < LCLIENT_LIST; ++i) -#ifdef CLIENT_ONETOONE_IP - if (dht->close_clientlist[i].assoc.timestamp != 0) -#else if ((dht->close_clientlist[i].assoc4.timestamp != 0) || (dht->close_clientlist[i].assoc6.timestamp != 0)) -#endif num++; len = num * sizeof(Client_data); -#ifdef CLIENT_ONETOONE_IP - type = DHT_STATE_TYPE_CLIENTS; -#else type = DHT_STATE_TYPE_CLIENTS_ASSOC46; -#endif data = z_state_save_subheader(data, len, type); if (num) { Client_data *clients = (Client_data *)data; for (num = 0, i = 0; i < LCLIENT_LIST; ++i) -#ifdef CLIENT_ONETOONE_IP - if (dht->close_clientlist[i].assoc.timestamp != 0) -#else if ((dht->close_clientlist[i].assoc4.timestamp != 0) || (dht->close_clientlist[i].assoc6.timestamp != 0)) -#endif memcpy(&clients[num++], &dht->close_clientlist[i], sizeof(Client_data)); } @@ -2005,18 +1781,18 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length, break; case DHT_STATE_TYPE_FRIENDS_ASSOC46: - if (length % sizeof(DHT_Friend_new) != 0) + if (length % sizeof(DHT_Friend) != 0) break; { /* localize declarations */ - DHT_Friend_new *friend_list = (DHT_Friend_new *)data; - num = length / sizeof(DHT_Friend_new); + DHT_Friend *friend_list = (DHT_Friend *)data; + num = length / sizeof(DHT_Friend); for (i = 0; i < num; ++i) { DHT_addfriend(dht, friend_list[i].client_id); for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { - Client_data_new *client = &friend_list[i].client_list[j]; + Client_data *client = &friend_list[i].client_list[j]; if (client->assoc4.timestamp != 0) getnodes(dht, client->assoc4.ip_port, client->client_id, friend_list[i].client_id); @@ -2030,12 +1806,12 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length, break; case DHT_STATE_TYPE_CLIENTS_ASSOC46: - if ((length % sizeof(Client_data_new)) != 0) + if ((length % sizeof(Client_data)) != 0) break; { /* localize declarations */ - num = length / sizeof(Client_data_new); - Client_data_new *client_list = (Client_data_new *)data; + num = length / sizeof(Client_data); + Client_data *client_list = (Client_data *)data; for (i = 0; i < num; ++i) { if (client_list[i].assoc4.timestamp != 0) @@ -2048,9 +1824,12 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length, break; +#ifdef DEBUG default: fprintf(stderr, "Load state (DHT): contains unrecognized part (len %u, type %u)\n", length, type); + break; +#endif } return 0; @@ -2085,13 +1864,9 @@ int DHT_isconnected(DHT *dht) for (i = 0; i < LCLIENT_LIST; ++i) { Client_data *client = &dht->close_clientlist[i]; -#ifdef CLIENT_ONETOONE_IP - if (!is_timeout(temp_time, client->assoc.timestamp, BAD_NODE_TIMEOUT)) -#else if (!is_timeout(temp_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) || !is_timeout(temp_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)) -#endif return 1; } diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 46193b56..360773ff 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -56,13 +56,13 @@ typedef struct { typedef struct { uint8_t client_id[CLIENT_ID_SIZE]; IPPTsPng assoc; -} Client_data_old; +} Client_data_old; /* required to load old state files */ typedef struct { uint8_t client_id[CLIENT_ID_SIZE]; IPPTsPng assoc4; IPPTsPng assoc6; -} Client_data_new; +} Client_data; /*----------------------------------------------------------------------------------*/ @@ -85,27 +85,18 @@ typedef struct { /* Symetric NAT hole punching stuff. */ NAT nat; -} DHT_Friend_old; +} DHT_Friend_old; /* required to load old state files */ typedef struct { uint8_t client_id[CLIENT_ID_SIZE]; - Client_data_new client_list[MAX_FRIEND_CLIENTS]; + Client_data client_list[MAX_FRIEND_CLIENTS]; /* Time at which the last get_nodes request was sent. */ uint64_t lastgetnode; /* Symetric NAT hole punching stuff. */ NAT nat; -} DHT_Friend_new; - -/* #define CLIENT_ONETOONE_IP */ -#ifdef CLIENT_ONETOONE_IP -typedef Client_data_old Client_data; -typedef DHT_Friend_old DHT_Friend; -#else -typedef Client_data_new Client_data; -typedef DHT_Friend_new DHT_Friend; -#endif +} DHT_Friend; /* this must be kept even if IP_Port is expanded: wire compatibility */ typedef struct { @@ -116,13 +107,7 @@ typedef struct { typedef struct { uint8_t client_id[CLIENT_ID_SIZE]; IP_Port ip_port; -} Node46_format; - -#ifdef TOX_ENABLE_IPV6 -typedef Node46_format Node_format; -#else -typedef Node4_format Node_format; -#endif +} Node_format; /*----------------------------------------------------------------------------------*/ diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index 1e4fa125..26366d0f 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -30,60 +30,83 @@ #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 int broadcast_count = -1; +static IP_Port broadcast_ip_port[MAX_INTERFACES]; + +static void fetch_broadcast_info(uint16_t port) { /* Not sure how many platforms this will run on, * so it's wrapped in __linux for now. + * Definitely won't work like this on Windows... */ - struct sockaddr_in *sock_holder = NULL; - struct ifreq i_faces[MAX_INTERFACES]; - struct ifconf ifconf; - int count = 0; - int sock = 0; - int i = 0; + broadcast_count = 0; + sock_t sock = 0; + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + return; /* Configure ifconf for the ioctl call. */ - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - return 1; - } - + struct ifreq i_faces[MAX_INTERFACES]; memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES); + struct ifconf ifconf; ifconf.ifc_buf = (char *)i_faces; ifconf.ifc_len = sizeof(i_faces); - count = ifconf.ifc_len / sizeof(struct ifreq); if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0) { - return 1; + close(sock); + return; } + /* ifconf.ifc_len is set by the ioctl() to the actual length used; + * on usage of the complete array the call should be repeated with + * a larger array, not done (640kB and 16 interfaces shall be + * enough, for everybody!) + */ + int i, count = ifconf.ifc_len / sizeof(struct ifreq); for (i = 0; i < count; i++) { - 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); - } + /* there are interfaces with are incapable of broadcast */ + if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) + continue; + + /* moot check: only AF_INET returned (backwards compat.) */ + if (i_faces[i].ifr_broadaddr.sa_family != AF_INET) + continue; + + struct sockaddr_in *sock4 = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr; + IP_Port *ip_port = &broadcast_ip_port[broadcast_count]; + ip_port->ip.family = AF_INET; + ip_port->ip.ip4.in_addr = sock4->sin_addr; + ip_port->port = port; + broadcast_count++; } close(sock); - return 0; } -#endif -#endif + +/* Send packet to all IPv4 broadcast addresses + * + * return 1 if sent to at least one broadcast target. + * return 0 on failure to find any valid broadcast target. + */ +static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t *data, uint16_t length) +{ + /* fetch only once? on every packet? every X seconds? + * old: every packet, new: once */ + if (broadcast_count < 0) + fetch_broadcast_info(port); + + if (!broadcast_count) + return 0; + + int i; + + for(i = 0; i < broadcast_count; i++) + sendpacket(net, broadcast_ip_port[i], data, 1 + crypto_box_PUBLICKEYBYTES); + + return 1; +} +#endif /* __linux */ /* Return the broadcast ip. */ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) @@ -91,8 +114,6 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) IP ip; ip_reset(&ip); -#ifdef TOX_ENABLE_IPV6 - if (family_socket == AF_INET6) { if (family_broadcast == AF_INET6) { ip.family = AF_INET6; @@ -116,14 +137,6 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) } } -#else - - if (family_socket == AF_INET) - if (family_broadcast == AF_INET) - ip.uint32 = INADDR_BROADCAST; - -#endif - return ip; } @@ -132,13 +145,8 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) */ int LAN_ip(IP ip) { -#ifdef TOX_ENABLE_IPV6 - if (ip.family == AF_INET) { IP4 ip4 = ip.ip4; -#else - IP4 ip4 = ip; -#endif /* Loopback. */ if (ip4.uint8[0] == 127) @@ -161,9 +169,8 @@ int LAN_ip(IP ip) && 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 */ if (((ip.ip6.uint8[0] == 0xFF) && (ip.ip6.uint8[1] < 3) && (ip.ip6.uint8[15] == 1)) || @@ -179,8 +186,6 @@ int LAN_ip(IP ip) } } -#endif - return -1; } @@ -206,16 +211,12 @@ 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); @@ -227,9 +228,6 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c) /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is AF_INET6 */ ip_port.ip = broadcast_ip(c->lossless_udp->net->family, AF_INET); -#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)) diff --git a/toxcore/Lossless_UDP.c b/toxcore/Lossless_UDP.c index 02fc7251..6d82b768 100644 --- a/toxcore/Lossless_UDP.c +++ b/toxcore/Lossless_UDP.c @@ -119,24 +119,15 @@ static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) id ^= randtable_initget(ludp, i, *uint8); i++; -#ifdef TOX_ENABLE_IPV6 - if (source.ip.family == AF_INET) { - IP4 ip4 = source.ip.ip4; -#else - IP4 ip4 = source.ip; -#endif int k; for (k = 0; k < 4; k++) { - id ^= randtable_initget(ludp, i++, ip4.uint8[k]); + id ^= randtable_initget(ludp, i++, source.ip.ip4.uint8[k]); } - -#ifdef TOX_ENABLE_IPV6 } - if (source.ip.family == AF_INET6) - { + if (source.ip.family == AF_INET6) { int k; for (k = 0; k < 16; k++) { @@ -144,8 +135,6 @@ static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) } } -#endif - /* id can't be zero. */ if (id == 0) id = 1; @@ -160,21 +149,18 @@ static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) */ static void change_handshake(Lossless_UDP *ludp, IP_Port source) { -#ifdef TOX_ENABLE_IPV6 uint8_t rand; if (source.ip.family == AF_INET) { - rand = 2 + random_int() % 4; + rand = random_int() % 4; } else if (source.ip.family == AF_INET6) { - rand = 2 + random_int() % 16; + rand = random_int() % 16; } else { return; } -#else - uint8_t rand = 2 + random_int() % 4; -#endif - ludp->randtable[rand][((uint8_t *)&source.ip)[rand]] = random_int(); + /* Forced to be more robust against strange definitions of sa_family_t */ + ludp->randtable[2 + rand][((uint8_t *)&source.ip.ip6)[rand]] = random_int(); } /* @@ -467,8 +453,8 @@ uint32_t sendqueue(Lossless_UDP *ludp, int connection_id) /* return number of packets in all queues waiting to be successfully sent. */ uint32_t sendqueue_total(Lossless_UDP *ludp) { - uint32_t total = 0; - int i; + uint32_t i, total = 0; + for(i = 0; i < ludp->connections.len; i++) { Connection *connection = &tox_array_get(&ludp->connections, i, Connection); if (connection->status != 0) diff --git a/toxcore/Lossless_UDP.h b/toxcore/Lossless_UDP.h index 794381de..d2f1986f 100644 --- a/toxcore/Lossless_UDP.h +++ b/toxcore/Lossless_UDP.h @@ -134,14 +134,8 @@ typedef struct { tox_array connections; /* Table of random numbers used in handshake_id. */ -#ifdef TOX_ENABLE_IPV6 /* IPv6 (16) + port (2)*/ uint32_t randtable[18][256]; -#else - /* IPv4 (4) + port (2) */ - uint32_t randtable[6][256]; -#endif - } Lossless_UDP; /* diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 44570742..6764dfe3 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -1700,7 +1700,7 @@ 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]); + sprintf(&IDString[i * 2], "%02X", client_id[i]); IDString[CLIENT_ID_SIZE * 2] = 0; return IDString; @@ -1730,24 +1730,20 @@ void doMessenger(Messenger *m) for (client = 0; client < LCLIENT_LIST; client++) { Client_data *cptr = &m->dht->close_clientlist[client]; IPPTsPng *assoc = NULL; -#ifdef CLIENT_ONETOONE_IP - assoc = &cptr->assoc; -#else uint32_t a; for (a = 0, assoc = &cptr->assoc4; a < 2; a++, assoc = &cptr->assoc6) -#endif - if (ip_isset(&assoc->ip_port.ip)) { - last_pinged = lastdump - assoc->last_pinged; + if (ip_isset(&assoc->ip_port.ip)) { + last_pinged = lastdump - assoc->last_pinged; - if (last_pinged > 999) - last_pinged = 999; + if (last_pinged > 999) + last_pinged = 999; - snprintf(logbuffer, sizeof(logbuffer), "C[%2u] %s:%u [%3u] %s\n", - client, ip_ntoa(&assoc->ip_port.ip), ntohs(assoc->ip_port.port), - last_pinged, ID2String(cptr->client_id)); - loglog(logbuffer); - } + snprintf(logbuffer, sizeof(logbuffer), "C[%2u] %s:%u [%3u] %s\n", + client, ip_ntoa(&assoc->ip_port.ip), ntohs(assoc->ip_port.port), + last_pinged, ID2String(cptr->client_id)); + loglog(logbuffer); + } } loglog(" = = = = = = = = \n"); @@ -1791,25 +1787,21 @@ void doMessenger(Messenger *m) for (client = 0; client < MAX_FRIEND_CLIENTS; client++) { Client_data *cptr = &dhtfptr->client_list[client]; IPPTsPng *assoc = NULL; -#ifdef CLIENT_ONETOONE_IP - assoc = &cptr->assoc; -#else uint32_t a; for (a = 0, assoc = &cptr->assoc4; a < 2; a++, assoc = &cptr->assoc6) -#endif - if (ip_isset(&assoc->ip_port.ip)) { - last_pinged = lastdump - assoc->last_pinged; + if (ip_isset(&assoc->ip_port.ip)) { + last_pinged = lastdump - assoc->last_pinged; - if (last_pinged > 999) - last_pinged = 999; + if (last_pinged > 999) + last_pinged = 999; - snprintf(logbuffer, sizeof(logbuffer), "F[%2u] => C[%2u] %s:%u [%3u] %s\n", - friend, client, ip_ntoa(&assoc->ip_port.ip), - ntohs(assoc->ip_port.port), last_pinged, - ID2String(cptr->client_id)); - loglog(logbuffer); - } + snprintf(logbuffer, sizeof(logbuffer), "F[%2u] => C[%2u] %s:%u [%3u] %s\n", + friend, client, ip_ntoa(&assoc->ip_port.ip), + ntohs(assoc->ip_port.port), last_pinged, + ID2String(cptr->client_id)); + loglog(logbuffer); + } } } diff --git a/toxcore/network.c b/toxcore/network.c index 3abd71e0..ee950d97 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -41,7 +41,9 @@ static const char *inet_ntop(sa_family_t family, void *addr, char *buf, size_t bufsize) { if (family == AF_INET) { - struct sockaddr_in saddr = { 0 }; + struct sockaddr_in saddr; + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; saddr.sin_addr = *(struct in_addr *)addr; @@ -52,7 +54,9 @@ static const char *inet_ntop(sa_family_t family, void *addr, char *buf, size_t b return buf; } else if (family == AF_INET6) { - struct sockaddr_in6 saddr = { 0 }; + struct sockaddr_in6 saddr; + memset(&saddr, 0, sizeof(saddr)); + saddr.sin6_family = AF_INET6; saddr.sin6_addr = *(struct in6_addr *)addr; @@ -70,7 +74,8 @@ static const char *inet_ntop(sa_family_t family, void *addr, char *buf, size_t b static int inet_pton(sa_family_t family, const char *addrString, void *addrbuf) { if (family == AF_INET) { - struct sockaddr_in saddr = { 0 }; + struct sockaddr_in saddr; + memset(&saddr, 0, sizeof(saddr)); INT len = sizeof(saddr); @@ -81,7 +86,8 @@ static int inet_pton(sa_family_t family, const char *addrString, void *addrbuf) return 1; } else if (family == AF_INET6) { - struct sockaddr_in6 saddr = { 0 }; + struct sockaddr_in6 saddr; + memset(&saddr, 0, sizeof(saddr)); INT len = sizeof(saddr); @@ -142,24 +148,19 @@ 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 -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 */ - addrsize = sizeof(struct sockaddr_in6); struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; + + addrsize = sizeof(struct sockaddr_in6); addr6->sin6_family = AF_INET6; addr6->sin6_port = ip_port.port; @@ -176,48 +177,36 @@ 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 { - IP4 ip4 = ip_port.ip.ip4; -#else - IP4 ip4 = ip_port.ip; -#endif - addrsize = sizeof(struct sockaddr_in); struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; + + addrsize = sizeof(struct sockaddr_in); addr4->sin_family = AF_INET; - addr4->sin_addr = ip4.in_addr; + addr4->sin_addr = ip_port.ip.ip4.in_addr; addr4->sin_port = ip_port.port; -#ifdef TOX_ENABLE_IPV6 } - } else if (ip_port.ip.family == AF_INET6) - { - addrsize = sizeof(struct sockaddr_in6); + } else if (ip_port.ip.family == AF_INET6) { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; + + addrsize = sizeof(struct sockaddr_in6); addr6->sin6_family = AF_INET6; addr6->sin6_port = ip_port.port; addr6->sin6_addr = ip_port.ip.ip6.in6_addr; addr6->sin6_flowinfo = 0; addr6->sin6_scope_id = 0; - } else - { + } else { /* unknown address type*/ return -1; } -#endif - int res = sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize); #ifdef LOGGING loglogdata("O=>", data, length, &ip_port, res); #endif - if (res == length) + if ((res >= 0) && ((uint32_t)res == length)) net->send_fail_eagain = 0; - -#ifdef WIN32 - else if ((res < 0) && (errno == WSAEWOULDBLOCK)) -#else - else if ((res < 0) && (errno == EAGAIN)) -#endif + else if ((res < 0) && (errno == EWOULDBLOCK)) net->send_fail_eagain = current_time(); return res; @@ -254,32 +243,21 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t *length = (uint32_t)fail_or_len; -#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) { struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr; + ip_port->ip.family = addr_in6->sin6_family; ip_port->ip.ip6.in6_addr = addr_in6->sin6_addr; ip_port->port = addr_in6->sin6_port; } 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 - return -1; - -#endif - #ifdef LOGGING loglogdata("=>O", data, MAX_UDP_PACKET_SIZE, ip_port, *length); #endif @@ -389,10 +367,13 @@ int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds) /* returns -1 on error, 0 on timeout, the socket on activity */ int res = select(nfds, &readfds, &writefds, &exceptfds, &timeout); #ifdef LOGGING - sprintf(logbuffer, "select(%d): %d (%d, %s) - %d %d %d\n", milliseconds, res, errno, - strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds), - FD_ISSET(s->sock, &exceptfds)); - loglog(logbuffer); + /* only dump if not timeout */ + if (res) { + sprintf(logbuffer, "select(%d): %d (%d, %s) - %d %d %d\n", milliseconds, res, errno, + strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds), + FD_ISSET(s->sock, &exceptfds)); + loglog(logbuffer); + } #endif if (FD_ISSET(s->sock, &writefds)) @@ -448,8 +429,6 @@ 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) { #ifdef DEBUG @@ -458,8 +437,6 @@ Networking_Core *new_networking(IP ip, uint16_t port) return NULL; } -#endif - if (at_startup() != 0) return NULL; @@ -468,11 +445,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) if (temp == NULL) return NULL; -#ifdef TOX_ENABLE_IPV6 temp->family = ip.family; -#else - temp->family = AF_INET; -#endif temp->port = 0; /* Initialize our socket. */ @@ -487,7 +460,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) return NULL; } -#else +#else /* !WIN32 */ if (temp->sock < 0) { #ifdef DEBUG @@ -497,7 +470,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) return NULL; } -#endif +#endif /* !WIN32 */ /* Functions to increase the size of the send and receive UDP buffers. */ @@ -515,33 +488,28 @@ Networking_Core *new_networking(IP ip, uint16_t port) u_long mode = 1; /* ioctl(sock, FIONBIO, &mode); */ ioctlsocket(temp->sock, FIONBIO, &mode); -#else +#else /* !WIN32 */ fcntl(temp->sock, F_SETFL, O_NONBLOCK, 1); -#endif +#endif /* !WIN32 */ /* Bind our socket to port PORT and the given IP address (usually 0.0.0.0 or ::) */ uint16_t *portptr = NULL; struct sockaddr_storage addr; size_t addrsize; -#ifdef TOX_ENABLE_IPV6 if (temp->family == AF_INET) { - IP4 ip4 = ip.ip4; -#else - IP4 ip4 = ip; -#endif - addrsize = sizeof(struct sockaddr_in); struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; + + addrsize = sizeof(struct sockaddr_in); addr4->sin_family = AF_INET; addr4->sin_port = 0; - addr4->sin_addr = ip4.in_addr; + addr4->sin_addr = ip.ip4.in_addr; portptr = &addr4->sin_port; -#ifdef TOX_ENABLE_IPV6 - } else if (temp->family == AF_INET6) - { - addrsize = sizeof(struct sockaddr_in6); + } else if (temp->family == AF_INET6) { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; + + addrsize = sizeof(struct sockaddr_in6); addr6->sin6_family = AF_INET6; addr6->sin6_port = 0; addr6->sin6_addr = ip.ip6.in6_addr; @@ -556,22 +524,38 @@ Networking_Core *new_networking(IP ip, uint16_t port) if (ip.family == AF_INET6) { char ipv6only = 0; + socklen_t optsize = sizeof(ipv6only); #ifdef LOGGING errno = 0; - int res = #endif - setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only)); + int res = getsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, &optsize); + if ((res == 0) && (ipv6only == 0)) { #ifdef LOGGING + loglog("Dual-stack socket: enabled per default.\n"); +#endif + } else { + ipv6only = 0; +#ifdef LOGGING + if (res < 0) { + sprintf(logbuffer, "Dual-stack socket: Failed to query default. (%d, %s)\n", + errno, strerror(errno)); + loglog(logbuffer); + } - 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", - errno, strerror(errno)); - loglog(logbuffer); - } else - loglog("Embedded IPv4 addresses enabled successfully.\n"); - + errno = 0; + res = +#endif + setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only)); +#ifdef LOGGING + if (res < 0) { + sprintf(logbuffer, + "Dual-stack socket: Failed to enable, won't be able to receive from/send to IPv4 addresses. (%u, %s)\n", + errno, strerror(errno)); + loglog(logbuffer); + } else + loglog("Dual-stack socket: Enabled successfully.\n"); #endif + } /* multicast local nodes */ struct ipv6_mreq mreq; @@ -597,8 +581,6 @@ Networking_Core *new_networking(IP ip, uint16_t port) #endif } -#endif - /* a hanging program or a different user might block the standard port; * as long as it isn't a parameter coming from the commandline, * try a few ports after it, to see if we can find a "free" one @@ -681,14 +663,16 @@ int ip_equal(IP *a, IP *b) if (!a || !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) +#ifdef WIN32 + return IN6_ADDR_EQUAL(&a->ip6.in6_addr, &b->ip6.in6_addr); +#else return IN6_ARE_ADDR_EQUAL(&a->ip6.in6_addr, &b->ip6.in6_addr); +#endif else return 0; } @@ -703,9 +687,6 @@ int ip_equal(IP *a, IP *b) } return 0; -#else - return (a->uint32 == b->uint32); -#endif }; /* ipport_equal @@ -731,11 +712,7 @@ void ip_reset(IP *ip) if (!ip) return; -#ifdef TOX_ENABLE_IPV6 memset(ip, 0, sizeof(IP)); -#else - ip->uint32 = 0; -#endif }; /* nulls out ip, sets family according to flag */ @@ -744,12 +721,8 @@ void ip_init(IP *ip, uint8_t ipv6enabled) if (!ip) return; -#ifdef TOX_ENABLE_IPV6 memset(ip, 0, sizeof(IP)); ip->family = ipv6enabled ? AF_INET6 : AF_INET; -#else - ip->uint32 = 0; -#endif }; /* checks if ip is valid */ @@ -758,11 +731,7 @@ int ip_isset(IP *ip) if (!ip) return 0; -#ifdef TOX_ENABLE_IPV6 return (ip->family != 0); -#else - return (ip->uint32 != 0); -#endif }; /* checks if ip is valid */ @@ -804,27 +773,23 @@ static char addresstext[96]; const char *ip_ntoa(IP *ip) { if (ip) { -#ifdef TOX_ENABLE_IPV6 - if (ip->family == AF_INET) { - addresstext[0] = 0; + /* returns standard quad-dotted notation */ struct in_addr *addr = (struct in_addr *)&ip->ip4; + + addresstext[0] = 0; inet_ntop(ip->family, addr, addresstext, sizeof(addresstext)); } else if (ip->family == AF_INET6) { - addresstext[0] = '['; + /* returns hex-groups enclosed into square brackets */ struct in6_addr *addr = (struct in6_addr *)&ip->ip6; + + addresstext[0] = '['; inet_ntop(ip->family, addr, &addresstext[1], sizeof(addresstext) - 3); size_t len = strlen(addresstext); addresstext[len] = ']'; addresstext[len + 1] = 0; } 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 snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)"); @@ -852,7 +817,6 @@ int addr_parse_ip(const char *address, IP *to) if (!address || !to) return 0; -#ifdef TOX_ENABLE_IPV6 struct in_addr addr4; if (1 == inet_pton(AF_INET, address, &addr4)) { @@ -869,16 +833,6 @@ int addr_parse_ip(const char *address, IP *to) return 1; }; -#else - struct in_addr addr4; - - if (1 == inet_pton(AF_INET, address, &addr4)) { - to->in_addr = addr4; - return 1; - }; - -#endif - return 0; }; @@ -905,12 +859,7 @@ int addr_resolve(const char *address, IP *to, IP *extra) if (!address || !to) return 0; - sa_family_t family; -#ifdef TOX_ENABLE_IPV6 - family = to->family; -#else - family = AF_INET; -#endif + sa_family_t family = to->family; struct addrinfo *server = NULL; struct addrinfo *walker = NULL; @@ -931,36 +880,25 @@ int addr_resolve(const char *address, IP *to, IP *extra) return 0; } -#ifdef TOX_ENABLE_IPV6 IP4 ip4; memset(&ip4, 0, sizeof(ip4)); IP6 ip6; 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) { /* 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; -#else - to->in_addr = addr->sin_addr; -#endif rc = 3; - } - -#ifdef TOX_ENABLE_IPV6 - else if (!(rc & 1)) { /* AF_UNSPEC requested, store away */ + } 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; } -#endif break; /* switch */ -#ifdef TOX_ENABLE_IPV6 case AF_INET6: if (walker->ai_family == family) { /* AF_INET6 requested, done */ @@ -978,12 +916,9 @@ int addr_resolve(const char *address, IP *to, IP *extra) } break; /* switch */ -#endif } } -#ifdef TOX_ENABLE_IPV6 - if (to->family == AF_UNSPEC) { if (rc & 2) { to->family = AF_INET6; @@ -1000,9 +935,6 @@ int addr_resolve(const char *address, IP *to, IP *extra) rc = 0; } -#endif - - freeaddrinfo(server); return rc; } @@ -1040,10 +972,11 @@ static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *i data[0] = buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0; data[1] = buflen > 7 ? ntohl(*(uint32_t *)&buffer[5]) : 0; + /* Windows doesn't necessarily know %zu */ if (res < 0) { - int written = snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3hu%c %s:%hu (%u: %s) | %04x%04x\n", - buffer[0], message, (buflen < 999 ? (uint16_t)buflen : 999), 'E', - ip_ntoa(&ip_port->ip), port, errno, strerror(errno), data[0], data[1]); + snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3hu%c %s:%hu (%u: %s) | %04x%04x\n", + buffer[0], message, (buflen < 999 ? (uint16_t)buflen : 999), 'E', + ip_ntoa(&ip_port->ip), port, errno, strerror(errno), data[0], data[1]); } else if ((res > 0) && ((size_t)res <= buflen)) snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3zu%c %s:%hu (%u: %s) | %04x%04x\n", buffer[0], message, (res < 999 ? (size_t)res : 999), ((size_t)res < buflen ? '<' : '='), diff --git a/toxcore/network.h b/toxcore/network.h index 8a0e20dc..1253c07e 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -40,14 +40,11 @@ #include typedef unsigned int sock_t; -typedef INT sa_family_t; - -#ifndef IN6_ARE_ADDR_EQUAL -#define IN6_ARE_ADDR_EQUAL(a,b) \ - ((((__const uint32_t *) (a))[0] == ((__const uint32_t *) (b))[0]) \ - && (((__const uint32_t *) (a))[1] == ((__const uint32_t *) (b))[1]) \ - && (((__const uint32_t *) (a))[2] == ((__const uint32_t *) (b))[2]) \ - && (((__const uint32_t *) (a))[3] == ((__const uint32_t *) (b))[3])) +/* sa_family_t is the sockaddr_in / sockaddr_in6 family field */ +typedef short sa_family_t; + +#ifndef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK #endif #else // Linux includes @@ -103,7 +100,6 @@ typedef int sock_t; /* Current time, unix format */ #define unix_time() ((uint64_t)time(NULL)) - typedef union { uint8_t uint8[4]; uint16_t uint16[2]; @@ -124,7 +120,7 @@ typedef struct { IP4 ip4; IP6 ip6; }; -} IPAny; +} IP; typedef union { struct { @@ -136,24 +132,12 @@ typedef union { uint8_t uint8[8]; } IP4_Port; -/* will replace IP_Port as soon as the complete infrastructure is in place - * removed the unused union and padding also */ typedef struct { - IPAny ip; + IP ip; uint16_t port; -} IPAny_Port; +} IP_Port; -/* #undef TOX_ENABLE_IPV6 */ -#define TOX_ENABLE_IPV6 -#ifdef TOX_ENABLE_IPV6 #define TOX_ENABLE_IPV6_DEFAULT 1 -typedef IPAny IP; -typedef IPAny_Port IP_Port; -#else -#define TOX_ENABLE_IPV6_DEFAULT 0 -typedef IP4 IP; -typedef IP4_Port IP_Port; -#endif /* ip_ntoa * converts ip into a string diff --git a/toxcore/tox.h b/toxcore/tox.h index 39832073..bcc89ce1 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -36,7 +36,9 @@ #include #include -typedef INT sa_family_t; +/* sa_family_t is the sockaddr_in / sockaddr_in6 family field */ +typedef short sa_family_t; + #ifndef true #define true 1 #endif @@ -69,7 +71,6 @@ typedef union { uint32_t i; } tox_IP4; - typedef union { uint8_t uint8[16]; uint16_t uint16[8]; @@ -83,36 +84,16 @@ typedef struct { tox_IP4 ip4; tox_IP6 ip6; }; -} tox_IPAny; - -typedef union { - struct { - tox_IP4 ip; - uint16_t port; - /* Not used for anything right now. */ - uint16_t padding; - }; - uint8_t uint8[8]; -} tox_IP4_Port; +} tox_IP; /* will replace IP_Port as soon as the complete infrastructure is in place * removed the unused union and padding also */ typedef struct { - tox_IPAny ip; + tox_IP ip; uint16_t port; -} tox_IPAny_Port; +} tox_IP_Port; -/* #undef TOX_ENABLE_IPV6 */ -#define TOX_ENABLE_IPV6 -#ifdef TOX_ENABLE_IPV6 #define TOX_ENABLE_IPV6_DEFAULT 1 -typedef tox_IPAny tox_IP; -typedef tox_IPAny_Port tox_IP_Port; -#else -#define TOX_ENABLE_IPV6_DEFAULT 0 -typedef tox_IP4 tox_IP; -typedef tox_IP4_Port tox_IP_Port; -#endif /* Errors for m_addfriend diff --git a/toxcore/util.c b/toxcore/util.c index 8fc6806e..a1de6392 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -109,6 +109,7 @@ void loginit(uint16_t port) struct tm *tm = localtime(&starttime); + /* "%F %T" might not be Windows compatible */ if (strftime(logbuffer + 32, sizeof(logbuffer) - 32, "%F %T", tm)) sprintf(logbuffer, "%u-%s.log", ntohs(port), logbuffer + 32); else @@ -149,7 +150,7 @@ void loglog(char *text) if (!logbufferpredata) return; - if (len + logbufferprehead - logbufferpredata + 16U < logbufferprelen) { + if (len + (logbufferprehead - logbufferpredata) + 16U < logbufferprelen) { size_t logpos = logbufferprehead - logbufferpredata; size_t lennew = logbufferprelen * 1.4; logbufferpredata = realloc(logbufferpredata, lennew); -- cgit v1.2.3