From 64d000cdfaed710d3e22fa5444b8c2883b9f09d6 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Fri, 13 Sep 2013 17:08:54 -0400 Subject: [PATCH] Some fixes. --- toxcore/DHT.c | 151 +++++++++++++++++-------------- toxcore/Lossless_UDP.c | 27 ++++-- toxcore/network.c | 200 +++++++++++++++++++++++------------------ 3 files changed, 218 insertions(+), 160 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 8557a5e0..df3b2f76 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. */ @@ -197,73 +196,75 @@ 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) + 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 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; } @@ -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); @@ -691,6 +695,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 +726,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 +741,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 @@ -758,6 +765,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; size_t Node_format_size = sizeof(Node4_format); + if (length > (cid_size + Node_format_size * MAX_SENT_NODES) || ((length - cid_size) % Node_format_size) != 0 || (length < cid_size + Node_format_size)) @@ -964,17 +972,19 @@ 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 *ip_extra = NULL; #ifdef TOX_ENABLE_IPV6 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 +993,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 +1314,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,12 +1455,13 @@ 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)) { + if (size < sizeof(dht->close_clientlist)) { fprintf(stderr, "DHT_load: Expected at least %u 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); return -1; @@ -1457,6 +1470,7 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size) 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 +1487,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/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/network.c b/toxcore/network.c index 6ae13160..5aa17cd0 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; @@ -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,23 @@ 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 + 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 */ @@ -394,15 +405,17 @@ Networking_Core *new_networking(IP ip, uint16_t port) mreq.ipv6mr_interface = 0; res = 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 +437,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 +459,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,7 +467,7 @@ 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); + strerror(errno), ip_ntoa(&ip), port); free(temp); return NULL; } @@ -480,6 +496,7 @@ int ip_equal(IP *a, IP *b) return 0; #ifdef TOX_ENABLE_IPV6 + if (a->family == AF_INET) return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr); @@ -589,28 +606,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 */ @@ -639,6 +655,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; @@ -646,17 +663,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,6 +735,7 @@ int addr_resolve(const char *address, IP *to, IP *extra) #endif rc = getaddrinfo(address, NULL, &hints, &server); + // Lookup failed. if (rc != 0) { #ifdef __WIN32__ @@ -729,67 +751,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) { + 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; - to->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)) { + struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; + to->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) { + 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; + } + } + + 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(); @@ -826,22 +852,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);