From a128e3ff8f09250757ed4ed73fcc088cb5fd15ee Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 13:56:03 +0200 Subject: network.h: - global: added sock_t - Networking_Core: added family (currently always AF_INET) and port - sendpacket(): changed signature to require (Networking_Core *) instead of sock_t *.c: - sendpacket()-calls: replaced *->net->sock with *->net --- toxcore/DHT.c | 10 +++++----- toxcore/LAN_discovery.c | 2 +- toxcore/Lossless_UDP.c | 6 +++--- toxcore/friend_requests.c | 2 +- toxcore/network.c | 17 ++++++++--------- toxcore/network.h | 21 +++++++++------------ toxcore/ping.c | 4 ++-- 7 files changed, 29 insertions(+), 33 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index e2d91256..e664c21c 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -518,7 +518,7 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); - return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, sizeof(data)); + return sendpacket(dht->c->lossless_udp->net, ip_port, data, sizeof(data)); } /* Send a send nodes response. */ @@ -563,7 +563,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); - return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); + return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); } static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) @@ -819,7 +819,7 @@ 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)) - return sendpacket(dht->c->lossless_udp->net->sock, dht->close_clientlist[i].ip_port, packet, length); + return sendpacket(dht->c->lossless_udp->net, dht->close_clientlist[i].ip_port, packet, length); } return -1; @@ -891,7 +891,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt /* If ip is not zero and node is good. */ if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { - int retval = sendpacket(dht->c->lossless_udp->net->sock, client->ip_port, packet, length); + int retval = sendpacket(dht->c->lossless_udp->net, client->ip_port, packet, length); if ((unsigned int)retval == length) ++sent; @@ -933,7 +933,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint if (n < 1) return 0; - int retval = sendpacket(dht->c->lossless_udp->net->sock, ip_list[rand() % n], packet, length); + int retval = sendpacket(dht->c->lossless_udp->net, ip_list[rand() % n], packet, length); if ((unsigned int)retval == length) return 1; diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index 1980cd93..fe9f748b 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -136,7 +136,7 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c) send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES); #endif IP_Port ip_port = {{broadcast_ip(), port, 0}}; - return sendpacket(c->lossless_udp->net->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); + return 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 fbb473e7..f66d5b62 100644 --- a/toxcore/Lossless_UDP.c +++ b/toxcore/Lossless_UDP.c @@ -429,7 +429,7 @@ static int send_handshake(Lossless_UDP *ludp, IP_Port ip_port, uint32_t handshak temp = htonl(handshake_id2); memcpy(packet + 5, &temp, 4); - return sendpacket(ludp->net->sock, ip_port, packet, sizeof(packet)); + return sendpacket(ludp->net, ip_port, packet, sizeof(packet)); } static int send_SYNC(Lossless_UDP *ludp, int connection_id) @@ -456,7 +456,7 @@ static int send_SYNC(Lossless_UDP *ludp, int connection_id) index += 4; memcpy(packet + index, requested, 4 * number); - return sendpacket(ludp->net->sock, ip_port, packet, (number * 4 + 4 + 4 + 2)); + return sendpacket(ludp->net, ip_port, packet, (number * 4 + 4 + 4 + 2)); } @@ -471,7 +471,7 @@ static int send_data_packet(Lossless_UDP *ludp, int connection_id, uint32_t pack temp = htonl(packet_num); memcpy(packet + 1, &temp, 4); memcpy(packet + 5, connection->sendbuffer[index].data, connection->sendbuffer[index].size); - return sendpacket(ludp->net->sock, connection->ip_port, packet, 1 + 4 + connection->sendbuffer[index].size); + return sendpacket(ludp->net, connection->ip_port, packet, 1 + 4 + connection->sendbuffer[index].size); } /* Sends 1 data packet. */ diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c index b01015c4..51a8112f 100644 --- a/toxcore/friend_requests.c +++ b/toxcore/friend_requests.c @@ -56,7 +56,7 @@ int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8 return -1; if (ip_port.ip.uint32 != 0) { - if (sendpacket(dht->c->lossless_udp->net->sock, ip_port, packet, len) != -1) + if (sendpacket(dht->c->lossless_udp->net, ip_port, packet, len) != -1) return 0; return -1; diff --git a/toxcore/network.c b/toxcore/network.c index ed3dff8a..53b7e3b5 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -64,14 +64,10 @@ uint32_t random_int(void) /* Basic network functions: * Function to send packet(data) of length length to ip_port. */ -#ifdef WIN32 -int sendpacket(unsigned int sock, IP_Port ip_port, uint8_t *data, uint32_t length) -#else -int sendpacket(int sock, IP_Port ip_port, uint8_t *data, uint32_t length) -#endif +int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t length) { ADDR addr = {AF_INET, ip_port.port, ip_port.ip, {0}}; - return sendto(sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); + return sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); } /* Function to receive data @@ -171,7 +167,8 @@ Networking_Core *new_networking(IP ip, uint16_t port) if (temp == NULL) return NULL; - temp->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + temp->family = AF_INET; + temp->sock = socket(temp->family, SOCK_DGRAM, IPPROTO_UDP); /* Check for socket error. */ #ifdef WIN32 @@ -219,8 +216,10 @@ Networking_Core *new_networking(IP ip, uint16_t port) #endif /* Bind our socket to port PORT and address 0.0.0.0 */ - ADDR addr = {AF_INET, htons(port), ip, {0}}; - bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr)); + ADDR addr = {temp->family, htons(port), ip, {0}}; + if (!bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr))) + temp->port = port; + return temp; } diff --git a/toxcore/network.h b/toxcore/network.h index 2d08e88d..8d494957 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -39,6 +39,8 @@ #include #include +typedef unsigned int sock_t; + #else // Linux includes #include @@ -50,6 +52,8 @@ #include #include +typedef int sock_t; + #endif #ifndef VANILLA_NACL @@ -117,13 +121,11 @@ typedef struct { typedef struct { Packet_Handles packethandlers[256]; - /* Our UDP socket. */ -#ifdef WIN32 - unsigned int sock; -#else - int sock; -#endif + /* Our UDP socket. */ + sa_family_t family; + uint16_t port; + sock_t sock; } Networking_Core; /* return current time in milleseconds since the epoch. */ @@ -137,12 +139,7 @@ uint32_t random_int(void); /* Basic network functions: */ /* Function to send packet(data) of length length to ip_port. */ -#ifdef WIN32 -int sendpacket(unsigned int sock, IP_Port ip_port, uint8_t *data, uint32_t length); -#else -int sendpacket(int sock, IP_Port ip_port, uint8_t *data, uint32_t length); -#endif - +int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t length); /* Function to call when packet beginning with byte is received. */ void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_callback cb, void *object); diff --git a/toxcore/ping.c b/toxcore/ping.c index 3b39d911..5f405b52 100644 --- a/toxcore/ping.c +++ b/toxcore/ping.c @@ -147,7 +147,7 @@ int send_ping_request(void *ping, Net_Crypto *c, IP_Port ipp, uint8_t *client_id if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) return 1; - return sendpacket(c->lossless_udp->net->sock, ipp, pk, sizeof(pk)); + return sendpacket(c->lossless_udp->net, ipp, pk, sizeof(pk)); } int send_ping_response(Net_Crypto *c, IP_Port ipp, uint8_t *client_id, uint64_t ping_id) @@ -172,7 +172,7 @@ int send_ping_response(Net_Crypto *c, IP_Port ipp, uint8_t *client_id, uint64_t if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) return 1; - return sendpacket(c->lossless_udp->net->sock, ipp, pk, sizeof(pk)); + return sendpacket(c->lossless_udp->net, ipp, pk, sizeof(pk)); } int handle_ping_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) -- cgit v1.2.3 From 29d777ef67bc964229722db073a2abdd1eb737b6 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 14:16:40 +0200 Subject: network.h: - IP: add in_addr_t as part of the union - IP: rename IP to IP4 --- other/DHT_bootstrap.c | 2 +- testing/DHT_test.c | 2 +- testing/Lossless_UDP_testclient.c | 2 +- testing/Lossless_UDP_testserver.c | 2 +- toxcore/DHT.c | 10 +++++----- toxcore/LAN_discovery.c | 6 +++--- toxcore/Messenger.c | 2 +- toxcore/network.c | 2 +- toxcore/network.h | 9 +++++---- 9 files changed, 19 insertions(+), 18 deletions(-) diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index a42545b1..bc0c592a 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -83,7 +83,7 @@ int main(int argc, char *argv[]) { /* Initialize networking - Bind to ip 0.0.0.0:PORT */ - IP ip; + IP4 ip; ip.uint32 = 0; DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); manage_keys(dht); diff --git a/testing/DHT_test.c b/testing/DHT_test.c index fce9c257..a7349a65 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c @@ -141,7 +141,7 @@ int main(int argc, char *argv[]) //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); /* initialize networking */ /* bind to ip 0.0.0.0:PORT */ - IP ip; + IP4 ip; ip.uint32 = 0; DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c index d5fb1544..4ac94b4b 100644 --- a/testing/Lossless_UDP_testclient.c +++ b/testing/Lossless_UDP_testclient.c @@ -168,7 +168,7 @@ int main(int argc, char *argv[]) /* initialize networking */ /* bind to ip 0.0.0.0:PORT */ - IP ip; + IP4 ip; ip.uint32 = 0; Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT)); perror("Initialization"); diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c index eb506b3d..e0ea92bc 100644 --- a/testing/Lossless_UDP_testserver.c +++ b/testing/Lossless_UDP_testserver.c @@ -163,7 +163,7 @@ int main(int argc, char *argv[]) //initialize networking //bind to ip 0.0.0.0:PORT - IP ip; + IP4 ip; ip.uint32 = 0; Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT)); perror("Initialization"); diff --git a/toxcore/DHT.c b/toxcore/DHT.c index e664c21c..3f3aef05 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -1030,9 +1030,9 @@ static int handle_NATping(void *object, IP_Port source, uint8_t *source_pubkey, * * return ip of 0 if failure. */ -static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) +static IP4 NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) { - IP zero = {{0}}; + IP4 zero = {{0}}; if (len > MAX_FRIEND_CLIENTS) return zero; @@ -1059,7 +1059,7 @@ static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) * * return number of ports and puts the list of ports in portlist. */ -static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip) +static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP4 ip) { uint32_t i; uint16_t num = 0; @@ -1074,7 +1074,7 @@ static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t return num; } -static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) +static void punch_holes(DHT *dht, IP4 ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) { if (numports > MAX_FRIEND_CLIENTS || numports == 0) return; @@ -1114,7 +1114,7 @@ static void do_NAT(DHT *dht) dht->friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { - IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); + IP4 ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); if (ip.uint32 == 0) continue; diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index fe9f748b..73337539 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -81,9 +81,9 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t * d #endif /* Return the broadcast ip. */ -static IP broadcast_ip(void) +static IP4 broadcast_ip(void) { - IP ip; + IP4 ip; ip.uint32 = ~0; return ip; } @@ -91,7 +91,7 @@ static IP broadcast_ip(void) /* return 0 if ip is a LAN ip. * return -1 if it is not. */ -static int LAN_ip(IP ip) +static int LAN_ip(IP4 ip) { if (ip.uint8[0] == 127) /* Loopback. */ return 0; diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 07893e02..e18e9efc 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -657,7 +657,7 @@ Messenger *initMessenger(void) if ( ! m ) return NULL; - IP ip; + IP4 ip; ip.uint32 = 0; m->net = new_networking(ip, PORT); diff --git a/toxcore/network.c b/toxcore/network.c index 53b7e3b5..622a4b17 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -156,7 +156,7 @@ static void at_shutdown(void) * return Networking_Core object if no problems * return NULL if there are problems. */ -Networking_Core *new_networking(IP ip, uint16_t port) +Networking_Core *new_networking(IP4 ip, uint16_t port) { if (at_startup() != 0) return NULL; diff --git a/toxcore/network.h b/toxcore/network.h index 8d494957..9991c4a4 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -86,11 +86,12 @@ typedef union { uint8_t uint8[4]; uint16_t uint16[2]; uint32_t uint32; -} IP; + in_addr_t in_addr; +} IP4; typedef union { struct { - IP ip; + IP4 ip; uint16_t port; /* Not used for anything right now. */ uint16_t padding; @@ -101,7 +102,7 @@ typedef union { typedef struct { int16_t family; uint16_t port; - IP ip; + IP4 ip; uint8_t zeroes[8]; #ifdef ENABLE_IPV6 uint8_t zeroes2[12]; @@ -155,7 +156,7 @@ void networking_poll(Networking_Core *net); * return 0 if no problems. * return -1 if there were problems. */ -Networking_Core *new_networking(IP ip, uint16_t port); +Networking_Core *new_networking(IP4 ip, uint16_t port); /* Function to cleanup networking stuff (doesn't do much right now). */ void kill_networking(Networking_Core *net); -- cgit v1.2.3 From 55214aa041f2cc0305d290ff7dfd9e3e2f5e0bde Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 14:53:27 +0200 Subject: network.*: - IP4: changed in_addr_t to struct in_addr for compatibility reasons - IP6: added - IPAny: added - addr_resolve_or_parse_ip(): converts a string into an IPAny --- toxcore/network.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ toxcore/network.h | 22 ++++++- 2 files changed, 198 insertions(+), 2 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index 622a4b17..f504401e 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -234,3 +234,181 @@ void kill_networking(Networking_Core *net) free(net); return; } + +/* + * addr_parse_ip + * directly parses the input into an IP structure + * tries IPv4 first, then IPv6 + * + * input + * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6) + * + * output + * IP: family and the value is set on success + * + * returns 1 on success, 0 on failure + */ + +int addr_parse_ip(const char *address, IPAny *to) +{ + struct in_addr addr4; + if (1 == inet_pton(AF_INET, address, &addr4)) + { + to->family = AF_INET; + to->ip4.in_addr = addr4; + return 1; + }; + + struct in6_addr addr6; + if (1 == inet_pton(AF_INET6, address, &addr6)) + { + to->family = AF_INET6; + to->ip6 = addr6; + return 1; + }; + + return 0; +}; + +/* + * addr_resolve(): + * uses getaddrinfo to resolve an address into an IP address + * uses the first IPv4/IPv6 addresses returned by getaddrinfo + * + * input + * address: a hostname (or something parseable to an IP address) + * ip: ip.family MUST be initialized, either set to a specific IP version + * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both + * IP versions are acceptable + * + * returns in ip a valid IPAny (v4/v6), + * prefers v6 if ip.family was AF_UNSPEC and both available + * returns 0 on failure + */ + +int addr_resolve(const char *address, IPAny *ip) +{ + struct addrinfo *server = NULL; + struct addrinfo *walker = NULL; + struct addrinfo hints; + int rc; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = ip->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) { + return 0; + } + +#endif + + rc = getaddrinfo(address, NULL, &hints, &server); + // Lookup failed. + if (rc != 0) { +#ifdef __WIN32__ + WSACleanup(); +#endif + return 0; + } + + IP4 ip4; + memset(&ip4, 0, sizeof(ip4)); + IP6 ip6; + memset(&ip6, 0, sizeof(ip6)); + + walker = server; + while (walker && (rc != 3)) + { + if (ip->family != AF_UNSPEC) + { + if (walker->ai_family == ip->family) { + if (ip->family == AF_INET) + { + if (walker->ai_addrlen == sizeof(struct sockaddr_in)) + { + struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; + ip->ip4.in_addr = addr->sin_addr; + rc = 3; + } + } + else if (ip->family == AF_INET6) + { + if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) + { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; + ip->ip6 = addr->sin6_addr; + rc = 3; + } + } + } + } + else + { + if (walker->ai_family == AF_INET) + { + if (walker->ai_addrlen == sizeof(struct sockaddr_in)) + { + struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; + ip4.in_addr = addr->sin_addr; + rc |= 1; + } + } + else if (walker->ai_family == AF_INET6) + { + if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) + { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; + ip6 = addr->sin6_addr; + rc |= 2; + } + } + } + + walker = walker->ai_next; + } + + if (ip->family == AF_UNSPEC) + { + if (rc & 2) + { + ip->family = AF_INET6; + ip->ip6 = ip6; + } else if (rc & 1) + { + ip->family = AF_INET; + ip->ip4 = ip4; + } + else + rc = 0; + } + + + freeaddrinfo(server); +#ifdef __WIN32__ + WSACleanup(); +#endif + return rc; +} + +/* + * addr_resolve_or_parse_ip + * resolves string into an IP address + * + * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6) + * returns 1 on success, 0 on failure + */ +int addr_resolve_or_parse_ip(const char *address, IPAny *to) +{ + if (!addr_resolve(address, to)) + if (!addr_parse_ip(address, to)) + return 0; + + return 1; +}; diff --git a/toxcore/network.h b/toxcore/network.h index 9991c4a4..2a0b5560 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -86,9 +86,19 @@ typedef union { uint8_t uint8[4]; uint16_t uint16[2]; uint32_t uint32; - in_addr_t in_addr; + struct in_addr in_addr; } IP4; +typedef struct in6_addr IP6; + +typedef struct { + sa_family_t family; + union { + IP4 ip4; + IP6 ip6; + }; +} IPAny; + typedef union { struct { IP4 ip; @@ -109,6 +119,15 @@ typedef struct { #endif } ADDR; +/* + * addr_resolve_or_parse_ip + * resolves string into an IP address + * + * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6) + * returns 1 on success, 0 on failure + */ +int addr_resolve_or_parse_ip(const char *address, IPAny *to); + /* Function to receive data, ip and port of sender is put into ip_port. * Packet data is put into data. * Packet length is put into length. @@ -161,5 +180,4 @@ Networking_Core *new_networking(IP4 ip, uint16_t port); /* Function to cleanup networking stuff (doesn't do much right now). */ void kill_networking(Networking_Core *net); - #endif -- cgit v1.2.3 From 180322293c245a853612b5f58913a29997e11267 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 15:32:05 +0200 Subject: network.h: - added ipany_ntoa() network.c: - added ipany_ntoa() - fixed formatting --- toxcore/network.c | 81 +++++++++++++++++++++++++++++++++---------------------- toxcore/network.h | 6 +++++ 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index f504401e..31da833c 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -235,6 +235,38 @@ void kill_networking(Networking_Core *net) return; } +/* ipany_ntoa + * converts ip into a string + * uses a static buffer, so mustn't used multiple times in the same output + */ +/* there would be INET6_ADDRSTRLEN, but it might be too short for the error message */ +static char addresstext[96]; +const char *ipany_ntoa(IPAny *ip) +{ + if (ip) { + 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) { + 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 + snprintf(addresstext, sizeof(addresstext), "(IP invalid, family %u)", ip->family); + } + else + snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)"); + + addresstext[INET6_ADDRSTRLEN + 2] = 0; + return addresstext; +}; + /* * addr_parse_ip * directly parses the input into an IP structure @@ -252,16 +284,14 @@ void kill_networking(Networking_Core *net) int addr_parse_ip(const char *address, IPAny *to) { struct in_addr addr4; - if (1 == inet_pton(AF_INET, address, &addr4)) - { + if (1 == inet_pton(AF_INET, address, &addr4)) { to->family = AF_INET; to->ip4.in_addr = addr4; return 1; }; struct in6_addr addr6; - if (1 == inet_pton(AF_INET6, address, &addr6)) - { + if (1 == inet_pton(AF_INET6, address, &addr6)) { to->family = AF_INET6; to->ip6 = addr6; return 1; @@ -324,24 +354,18 @@ int addr_resolve(const char *address, IPAny *ip) memset(&ip6, 0, sizeof(ip6)); walker = server; - while (walker && (rc != 3)) - { - if (ip->family != AF_UNSPEC) - { + while (walker && (rc != 3)) { + if (ip->family != AF_UNSPEC) { if (walker->ai_family == ip->family) { - if (ip->family == AF_INET) - { - if (walker->ai_addrlen == sizeof(struct sockaddr_in)) - { + if (ip->family == AF_INET) { + if (walker->ai_addrlen == sizeof(struct sockaddr_in)) { struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; ip->ip4.in_addr = addr->sin_addr; rc = 3; } } - else if (ip->family == AF_INET6) - { - if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) - { + else if (ip->family == AF_INET6) { + if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; ip->ip6 = addr->sin6_addr; rc = 3; @@ -349,21 +373,16 @@ int addr_resolve(const char *address, IPAny *ip) } } } - else - { - if (walker->ai_family == AF_INET) - { - if (walker->ai_addrlen == sizeof(struct sockaddr_in)) - { + else { + if (walker->ai_family == AF_INET) { + if (walker->ai_addrlen == sizeof(struct sockaddr_in)) { struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; ip4.in_addr = addr->sin_addr; rc |= 1; } } - else if (walker->ai_family == AF_INET6) - { - if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) - { + else if (walker->ai_family == AF_INET6) { + if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; ip6 = addr->sin6_addr; rc |= 2; @@ -374,14 +393,12 @@ int addr_resolve(const char *address, IPAny *ip) walker = walker->ai_next; } - if (ip->family == AF_UNSPEC) - { - if (rc & 2) - { + if (ip->family == AF_UNSPEC) { + if (rc & 2) { ip->family = AF_INET6; ip->ip6 = ip6; - } else if (rc & 1) - { + } + else if (rc & 1) { ip->family = AF_INET; ip->ip4 = ip4; } diff --git a/toxcore/network.h b/toxcore/network.h index 2a0b5560..15ca68e3 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -99,6 +99,12 @@ typedef struct { }; } IPAny; +/* ipany_ntoa + * converts ip into a string + * uses a static buffer, so mustn't used multiple times in the same output + */ +const char *ipany_ntoa(IPAny *ip); + typedef union { struct { IP4 ip; -- cgit v1.2.3 From 291fa8d5c53a819602bd84ef21f4ace9f310ed85 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 16:11:33 +0200 Subject: fix autobuild (not built locally) --- other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c index 4e90e345..58af2751 100644 --- a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c +++ b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c @@ -339,7 +339,7 @@ int main(int argc, char *argv[]) /* Initialize networking bind to ip 0.0.0.0:PORT */ - IP ip; + IP4 ip; ip.uint32 = 0; DHT *dht = new_DHT(new_net_crypto(new_networking(ip, server_conf.port))); /* Read the config file */ -- cgit v1.2.3 From dbd75e903e7931a3f673df6121a0dedab15c0423 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 16:12:50 +0200 Subject: network.*: - IPAny_Port: analogous to IP_Port - ipport_equal: moved from DHT.c and adapted DHTc.: - ipport_equal renamed to ip4port_equal --- toxcore/DHT.c | 6 +++--- toxcore/network.c | 37 +++++++++++++++++++++++++++++++++++++ toxcore/network.h | 16 ++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 3f3aef05..151f59d3 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -115,7 +115,7 @@ static int client_id_cmp(ClientPair p1, ClientPair p2) return c; } -static int ipport_equal(IP_Port a, IP_Port b) +static int ip4port_equal(IP_Port a, IP_Port b) { return (a.ip.uint32 == b.ip.uint32) && (a.port == b.port); } @@ -144,7 +144,7 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id for (i = 0; i < length; ++i) { /* If ip_port is assigned to a different client_id replace it */ - if (ipport_equal(list[i].ip_port, ip_port)) { + if (ip4port_equal(list[i].ip_port, ip_port)) { memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); } @@ -447,7 +447,7 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { pinging = 0; - if (ip_port.ip.uint32 != 0 && ipport_equal(dht->send_nodes[i].ip_port, ip_port)) + if (ip_port.ip.uint32 != 0 && ip4port_equal(dht->send_nodes[i].ip_port, ip_port)) ++pinging; if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id) diff --git a/toxcore/network.c b/toxcore/network.c index 31da833c..1fb5b77a 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -235,6 +235,43 @@ void kill_networking(Networking_Core *net) return; } +/* ip_equal + * compares two IPAny structures + * unset means unequal + * + * returns 0 when not equal or when uninitialized + */ +int ip_equal(IPAny *a, IPAny *b) +{ + if (!a || !b) + return 0; + + if (a->family == AF_INET) + return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr); + + if (a->family == AF_INET6) + return IN6_ARE_ADDR_EQUAL(&a->ip6, &b->ip6); + + return 0; +}; + +/* ipport_equal + * compares two IPAny_Port structures + * unset means unequal + * + * returns 0 when not equal or when uninitialized + */ +int ipport_equal(IPAny_Port *a, IPAny_Port *b) +{ + if (!a || !b) + return 0; + + if (!a->port || (a->port != b->port)) + return 0; + + return ip_equal(&a->ip, &b->ip); +}; + /* ipany_ntoa * converts ip into a string * uses a static buffer, so mustn't used multiple times in the same output diff --git a/toxcore/network.h b/toxcore/network.h index 15ca68e3..d52a02ae 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -115,6 +115,22 @@ typedef union { uint8_t uint8[8]; } IP_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; + uint16_t port; +} IPAny_Port; + +/* ipport_equal + * compares two IPAny_Port structures + * unset means unequal + * + * returns 0 when not equal or when uninitialized + */ +int ipport_equal(IPAny_Port *a, IPAny_Port *b); + typedef struct { int16_t family; uint16_t port; -- cgit v1.2.3 From 9439d296f1c7b331ec0a579b4840b8b103ad55d6 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 16:27:24 +0200 Subject: caught by autobuild, missing net->sock to net change --- toxcore/LAN_discovery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index 73337539..bc73a6a1 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -71,7 +71,7 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t * d 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->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); + sendpacket(net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); } } -- cgit v1.2.3 From 9a8dc575b7a2004fbe6e8237a8565df390d76529 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 16:35:39 +0200 Subject: - added missing include (autobuild warning) --- toxcore/network.h | 1 + 1 file changed, 1 insertion(+) diff --git a/toxcore/network.h b/toxcore/network.h index d52a02ae..1d2d1a4f 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -46,6 +46,7 @@ typedef unsigned int sock_t; #include #include #include +#include #include #include #include -- cgit v1.2.3 From a77253c79b9c2acaa73164dcbd0694cb7b19db91 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 19:17:21 +0200 Subject: tox.*, DHT.*; - second set of *_bootstrap_ex() functions to allow addresses instead of IPs network.h: - new message ID for sending/receiving IPv6 nodes DHT.*: - get_close_nodes(): - additional parameter to select which kind of nodes: IPv4 or IPv6 - sendnodes()/handle_sendnodes(): - the IPv4 message must remain intact even when the Node_format structure (which embeds IP_Port) is expanded - added Node4_format to keep the structure "alive" - copying in/out of wider to smaller format required in sendnodes()/handle_sendnodes() - switch of Node_format from Node4_format to Node46_format by define --- toxcore/DHT.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++-------- toxcore/DHT.h | 24 ++++++++--- toxcore/network.h | 12 ++++-- toxcore/tox.c | 5 +++ toxcore/tox.h | 2 + 5 files changed, 137 insertions(+), 27 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 151f59d3..4c15c1eb 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -197,18 +197,37 @@ static int friend_number(DHT *dht, uint8_t *client_id) * * TODO: For the love of based Allah make this function cleaner and much more efficient. */ -static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list) +static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family) { uint32_t i, j, k; uint64_t temp_time = unix_time(); - int num_nodes = 0, closest, tout, inlist; + int num_nodes = 0, closest, tout, inlist, ipv46x; for (i = 0; i < LCLIENT_LIST; ++i) { tout = is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, dht->close_clientlist[i].client_id); + /* + * NET_PACKET_SEND_NODES sends ONLY AF_INET + * NET_PACKET_SEND_NODES_EX sends ALL BUT AF_INET (i.e. AF_INET6), + * it could send both, but then a) packet size is an issue and + * b) duplicates the traffic (NET_PACKET_SEND_NODES has to be + * sent anyways for backwards compatibility) + * we COULD send ALL as NET_PACKET_SEND_NODES_EX if we KNEW that the + * partner node understands - that's true if *they* are on IPv6 + */ +#ifdef NETWORK_IP_PORT_IS_IPV6 + ipv46x = 0; + if (sa_family == AF_INET) + ipv46x = dht->close_clientlist[i].ip_port.ip.family != AF_INET; + else + ipv46x = dht->close_clientlist[i].ip_port.ip.family == AF_INET; +#else + ipv46x = sa_family != AF_INET; +#endif + /* If node isn't good or is already in list. */ - if (tout || inlist) + if (tout || inlist || ipv46x) continue; if (num_nodes < MAX_SENT_NODES) { @@ -247,8 +266,18 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list MAX_SENT_NODES, dht->friends_list[i].client_list[j].client_id); +#ifdef NETWORK_IP_PORT_IS_IPV6 + ipv46x = 0; + if (sa_family == AF_INET) + ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family != AF_INET; + else + ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family == AF_INET; +#else + ipv46x = sa_family != AF_INET; +#endif + /* If node isn't good or is already in list. */ - if (tout || inlist) + if (tout || inlist || ipv46x) continue; if (num_nodes < MAX_SENT_NODES) { @@ -522,40 +551,61 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli } /* Send a send nodes response. */ +/* because of BINARY compatibility, the Node_format MUST BE Node4_format, + * IPv6 nodes are sent in a different message */ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) { /* Check if packet is going to be sent to ourself. */ if (id_equal(public_key, dht->c->self_public_key)) return -1; + size_t Node4_format_size = sizeof(Node4_format); uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) - + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; + + Node4_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; Node_format nodes_list[MAX_SENT_NODES]; - int num_nodes = get_close_nodes(dht, client_id, nodes_list); + int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET); if (num_nodes == 0) return 0; - uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; - uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; + uint8_t plain[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES]; + uint8_t encrypt[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; uint8_t nonce[crypto_box_NONCEBYTES]; random_nonce(nonce); memcpy(plain, &ping_id, sizeof(ping_id)); - memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); +#if DHT_NODEFORMAT == 46 + Node4_format *nodes4_list = &(plain + sizeof(ping_id)); + int i, num_nodes_ok = 0; + for(i = 0; i < num_nodes, i++) + if (nodes_list[i].ip.family == AF_INET) { + memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); + nodes4_list[num_nodes_ok].ip_port.ip.uint32 = nodes_list[i].ip_port.ip.ip4.uint32; + nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; + + num_nodes_ok++; + } + + if (num_nodes_ok < num_nodes) { + /* shouldn't happen */ + 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, plain, - sizeof(ping_id) + num_nodes * sizeof(Node_format), + sizeof(ping_id) + num_nodes * Node4_format_size, encrypt ); if (len == -1) return -1; - if ((unsigned int)len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) + if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node4_format_size + ENCRYPTION_PADDING) return -1; data[0] = NET_PACKET_SEND_NODES; @@ -606,22 +656,23 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 uint32_t cid_size = 1 + CLIENT_ID_SIZE; cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; - if (length > (cid_size + sizeof(Node_format) * MAX_SENT_NODES) || - ((length - cid_size) % sizeof(Node_format)) != 0 || - (length < cid_size + sizeof(Node_format))) + 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)) return 1; - uint32_t num_nodes = (length - cid_size) / sizeof(Node_format); - uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; + uint32_t num_nodes = (length - cid_size) / Node4_format_size; + uint8_t plain[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES]; int len = decrypt_data( packet + 1, dht->c->self_secret_key, packet + 1 + CLIENT_ID_SIZE, packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, - sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain ); + sizeof(ping_id) + num_nodes * Node4_format_size + ENCRYPTION_PADDING, plain ); - if ((unsigned int)len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) + if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node4_format_size) return 1; memcpy(&ping_id, plain, sizeof(ping_id)); @@ -630,7 +681,28 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 return 1; Node_format nodes_list[MAX_SENT_NODES]; + +#if DHT_NODEFORMAT == 46 + Node4_format *nodes4_list = &(plain + sizeof(ping_id)); + + int i, num_nodes_ok = 0; + for(i = 0; i < num_nodes, i++) + if ((nodes_list[i].ip != 0) && (nodes_list[i].ip != ~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; + nodes_list[num_nodes_ok].ip_port.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32; + nodes_list[num_nodes_ok].ip_port.port = nodes4_list[i].ip_port.port; + + num_nodes_ok++; + } + + if (num_nodes_ok < num_nodes) { + /* shouldn't happen */ + 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); @@ -808,6 +880,19 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) getnodes(dht, ip_port, public_key, dht->c->self_public_key); send_ping_request(dht->ping, dht->c, ip_port, public_key); } +void DHT_bootstrap_ex(DHT *dht, const char *address, uint16_t port, uint8_t *public_key) +{ + IPAny_Port ipany_port; + ipany_port.ip.family = AF_INET; + if (addr_resolve_or_parse_ip(address, &ipany_port.ip)) { + /* IPAny temporary: copy down */ + IP_Port ip_port; + ip_port.ip.uint32 = ipany_port.ip.ip4.uint32; + ip_port.port = port; + + DHT_bootstrap(dht, ip_port, public_key); + } +} /* Send the given packet to node with client_id * diff --git a/toxcore/DHT.h b/toxcore/DHT.h index e5122b5e..5963d297 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -75,10 +75,21 @@ typedef struct { uint64_t NATping_timestamp; } DHT_Friend; +/* this must be kept even if IP_Port is expanded: wire compatibility */ typedef struct { uint8_t client_id[CLIENT_ID_SIZE]; - IP_Port ip_port; -} Node_format; + IP4_Port ip_port; +} Node4_format; + +typedef struct { + uint8_t client_id[CLIENT_ID_SIZE]; + IPAny_Port ip_port; +} Node46_format; +/* IPAny temporary: change to 46 */ +#define DHT_NODEFORMAT 4 +typedef Node4_format Node_format; +/* #define DHT_NODEFORMAT 46 */ +/* typedef Node46_format Node_format; */ typedef struct { IP_Port ip_port; @@ -88,15 +99,15 @@ typedef struct { /*----------------------------------------------------------------------------------*/ typedef struct { - Net_Crypto *c; + Net_Crypto *c; Client_data close_clientlist[LCLIENT_LIST]; - DHT_Friend *friends_list; + DHT_Friend *friends_list; uint16_t num_friends; Pinged send_nodes[LSEND_NODES_ARRAY]; Node_format toping[MAX_TOPING]; uint64_t last_toping; - uint64_t close_lastgetnodes; - void *ping; + uint64_t close_lastgetnodes; + void *ping; } DHT; /*----------------------------------------------------------------------------------*/ @@ -137,6 +148,7 @@ void do_DHT(DHT *dht); * Sends a get nodes request to the given node with ip port and public_key. */ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key); +void DHT_bootstrap_ex(DHT *dht, const char *address, 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/network.h b/toxcore/network.h index 1d2d1a4f..913763ee 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -71,7 +71,8 @@ typedef int sock_t; #define NET_PACKET_PING_REQUEST 0 /* Ping request packet ID. */ #define NET_PACKET_PING_RESPONSE 1 /* Ping response packet ID. */ #define NET_PACKET_GET_NODES 2 /* Get nodes request packet ID. */ -#define NET_PACKET_SEND_NODES 3 /* Send nodes response packet ID. */ +#define NET_PACKET_SEND_NODES 3 /* Send nodes response packet ID for IPv4 addresses. */ +#define NET_PACKET_SEND_NODES_EX 4 /* Send nodes response packet ID for other addresses. */ #define NET_PACKET_HANDSHAKE 16 /* Handshake packet ID. */ #define NET_PACKET_SYNC 17 /* SYNC packet ID. */ #define NET_PACKET_DATA 18 /* Data packet ID. */ @@ -114,8 +115,7 @@ typedef union { uint16_t padding; }; uint8_t uint8[8]; -} IP_Port; - +} IP4_Port; /* will replace IP_Port as soon as the complete infrastructure is in place * removed the unused union and padding also */ @@ -124,6 +124,12 @@ typedef struct { uint16_t port; } IPAny_Port; +#ifdef NETWORK_IP_PORT_IS_IPV6 +typedef IPAny_Port IP_Port; +#else +typedef IP4_Port IP_Port; +#endif + /* ipport_equal * compares two IPAny_Port structures * unset means unequal diff --git a/toxcore/tox.c b/toxcore/tox.c index 83b19e9b..1507b2c5 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -374,6 +374,11 @@ void tox_bootstrap(void *tox, IP_Port ip_port, uint8_t *public_key) Messenger *m = tox; DHT_bootstrap(m->dht, ip_port, public_key); } +void tox_bootstrap_ex(void *tox, const char *address, uint16_t port, uint8_t *public_key) +{ + Messenger *m = tox; + DHT_bootstrap_ex(m->dht, address, port, public_key); +}; /* return 0 if we are not connected to the DHT. * return 1 if we are. diff --git a/toxcore/tox.h b/toxcore/tox.h index 811e798b..77f0be7f 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -291,8 +291,10 @@ void tox_callback_connectionstatus(Tox *tox, void (*function)(Tox *tox, int, uin /* Use this function to bootstrap the client. * Sends a get nodes request to the given node with ip port and public_key. + * tox_bootstrap_ex converts the address into an IP_Port structure internally */ void tox_bootstrap(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key); +void tox_bootstrap_ex(Tox *tox, const char *address, uint16_t port, uint8_t *public_key); /* return 0 if we are not connected to the DHT. * return 1 if we are. -- cgit v1.2.3 From f932fd400c12271edeec6abf06fd00a554848419 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 20:14:24 +0200 Subject: tox.*, Messenger.*: - initialisation: argument added to enable/disable ipv6 as socket Messenger_test.c: - initialisation: ipv4 hardcoded for now - delegating IP resolution to DHT_bootstrap_ex() --- testing/Messenger_test.c | 9 ++++----- toxcore/Messenger.c | 8 +++++++- toxcore/Messenger.h | 2 +- toxcore/tox.c | 6 +++++- toxcore/tox.h | 3 +++ 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index e85a85a2..04d3bc14 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -100,7 +100,8 @@ int main(int argc, char *argv[]) exit(0); } - m = initMessenger(); + /* IPv6: maybe allow from cmdline --ipv6? sticking to IPv4 for now */ + m = initMessenger(0); if ( !m ) { fputs("Failed to allocate messenger datastructure\n", stderr); @@ -108,10 +109,8 @@ int main(int argc, char *argv[]) } if (argc > 3) { - IP_Port bootstrap_ip_port; - bootstrap_ip_port.port = htons(atoi(argv[2])); - bootstrap_ip_port.ip.uint32 = inet_addr(argv[1]); - DHT_bootstrap(m->dht, bootstrap_ip_port, hex_string_to_bin(argv[3])); + uint16_t port = htons(atoi(argv[2])); + DHT_bootstrap_ex(m->dht, argv[1], port, hex_string_to_bin(argv[3])); } else { FILE *file = fopen(argv[1], "rb"); diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index e18e9efc..48d40f43 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -650,15 +650,21 @@ static void LANdiscovery(Messenger *m) } /* Run this at startup. */ -Messenger *initMessenger(void) +Messenger *initMessenger(uint8_t ipv6enabled) { Messenger *m = calloc(1, sizeof(Messenger)); if ( ! m ) return NULL; +#ifdef NETWORK_IP_PORT_IS_IPV6 + IPAny ip; + memset(&ip, 0, sizeof(ip)); + ip.family = ipv6enabled ? AF_INET6 : AF_INET; +#else IP4 ip; ip.uint32 = 0; +#endif m->net = new_networking(ip, PORT); if (m->net == NULL) { diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index c512245c..34131a20 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -367,7 +367,7 @@ void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, in * return allocated instance of Messenger on success. * return 0 if there are problems. */ -Messenger *initMessenger(void); +Messenger *initMessenger(uint8_t ipv6enabled); /* Run this before closing shop * Free all datastructures. diff --git a/toxcore/tox.c b/toxcore/tox.c index 1507b2c5..d48de0d8 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -394,9 +394,13 @@ int tox_isconnected(void *tox) * return allocated instance of tox on success. * return 0 if there are problems. */ +void *tox_new_ex(uint8_t ipv6enabled) +{ + return initMessenger(ipv6enabled); +} void *tox_new(void) { - return initMessenger(); + return tox_new_ex(0); } /* Run this before closing shop. diff --git a/toxcore/tox.h b/toxcore/tox.h index 77f0be7f..f8d7975f 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -50,6 +50,8 @@ typedef struct { uint16_t padding; } tox_IP_Port; +#define TOX_IP_IS_IPV6 0 + /* Errors for m_addfriend * FAERR - Friend Add Error */ @@ -307,6 +309,7 @@ int tox_isconnected(Tox *tox); * return 0 if there are problems. */ Tox *tox_new(void); +Tox *tox_new_ex(uint8_t ipv6enabled); /* Run this before closing shop. * Free all datastructures. */ -- cgit v1.2.3 From 05d7b157c6560d4545f815b60b8c43aca6981227 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 20:14:24 +0200 Subject: tox.*, Messenger.*: - initialisation: argument added to enable/disable ipv6 as socket Messenger_test.c: - initialisation: ipv4 hardcoded for now - delegating IP resolution to DHT_bootstrap_ex() --- auto_tests/messenger_test.c | 3 ++- testing/Messenger_test.c | 9 ++++----- toxcore/Messenger.c | 8 +++++++- toxcore/Messenger.h | 2 +- toxcore/tox.c | 6 +++++- toxcore/tox.h | 3 +++ 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/auto_tests/messenger_test.c b/auto_tests/messenger_test.c index d067a014..cba509ba 100644 --- a/auto_tests/messenger_test.c +++ b/auto_tests/messenger_test.c @@ -274,7 +274,8 @@ int main(int argc, char *argv[]) good_id_b = hex_string_to_bin(good_id_b_str); bad_id = hex_string_to_bin(bad_id_str); - m = initMessenger(); + /* no IPv6 enabled yet */ + m = initMessenger(0); /* setup a default friend and friendnum */ if (m_addfriend_norequest(m, (uint8_t *)friend_id) < 0) diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index e85a85a2..04d3bc14 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -100,7 +100,8 @@ int main(int argc, char *argv[]) exit(0); } - m = initMessenger(); + /* IPv6: maybe allow from cmdline --ipv6? sticking to IPv4 for now */ + m = initMessenger(0); if ( !m ) { fputs("Failed to allocate messenger datastructure\n", stderr); @@ -108,10 +109,8 @@ int main(int argc, char *argv[]) } if (argc > 3) { - IP_Port bootstrap_ip_port; - bootstrap_ip_port.port = htons(atoi(argv[2])); - bootstrap_ip_port.ip.uint32 = inet_addr(argv[1]); - DHT_bootstrap(m->dht, bootstrap_ip_port, hex_string_to_bin(argv[3])); + uint16_t port = htons(atoi(argv[2])); + DHT_bootstrap_ex(m->dht, argv[1], port, hex_string_to_bin(argv[3])); } else { FILE *file = fopen(argv[1], "rb"); diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index e18e9efc..48d40f43 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -650,15 +650,21 @@ static void LANdiscovery(Messenger *m) } /* Run this at startup. */ -Messenger *initMessenger(void) +Messenger *initMessenger(uint8_t ipv6enabled) { Messenger *m = calloc(1, sizeof(Messenger)); if ( ! m ) return NULL; +#ifdef NETWORK_IP_PORT_IS_IPV6 + IPAny ip; + memset(&ip, 0, sizeof(ip)); + ip.family = ipv6enabled ? AF_INET6 : AF_INET; +#else IP4 ip; ip.uint32 = 0; +#endif m->net = new_networking(ip, PORT); if (m->net == NULL) { diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index c512245c..34131a20 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -367,7 +367,7 @@ void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, in * return allocated instance of Messenger on success. * return 0 if there are problems. */ -Messenger *initMessenger(void); +Messenger *initMessenger(uint8_t ipv6enabled); /* Run this before closing shop * Free all datastructures. diff --git a/toxcore/tox.c b/toxcore/tox.c index 1507b2c5..d48de0d8 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -394,9 +394,13 @@ int tox_isconnected(void *tox) * return allocated instance of tox on success. * return 0 if there are problems. */ +void *tox_new_ex(uint8_t ipv6enabled) +{ + return initMessenger(ipv6enabled); +} void *tox_new(void) { - return initMessenger(); + return tox_new_ex(0); } /* Run this before closing shop. diff --git a/toxcore/tox.h b/toxcore/tox.h index 77f0be7f..f8d7975f 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -50,6 +50,8 @@ typedef struct { uint16_t padding; } tox_IP_Port; +#define TOX_IP_IS_IPV6 0 + /* Errors for m_addfriend * FAERR - Friend Add Error */ @@ -307,6 +309,7 @@ int tox_isconnected(Tox *tox); * return 0 if there are problems. */ Tox *tox_new(void); +Tox *tox_new_ex(uint8_t ipv6enabled); /* Run this before closing shop. * Free all datastructures. */ -- cgit v1.2.3 From bcf251ac3190db4230d42be97b539e4df3af736f Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Mon, 9 Sep 2013 21:37:07 +0200 Subject: group_chats.c: - *->net->sock to *->net (like everywhere else :)) --- toxcore/group_chats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 3c134348..1b021e20 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -185,7 +185,7 @@ static int send_groupchatpacket(Group_Chat *chat, IP_Port ip_port, uint8_t *publ if (len == -1) return -1; - if (sendpacket(chat->net->sock, ip_port, packet, len) == len) + if (sendpacket(chat->net, ip_port, packet, len) == len) return 0; return -1; -- cgit v1.2.3 From bcb283cf4512f36b189ce2d49eb040c205cbc778 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Tue, 10 Sep 2013 16:36:20 +0200 Subject: big push, putting all the infrastructure in place behind TOX_ENABLE_IPV6 --- other/DHT_bootstrap.c | 13 +- .../bootstrap_serverdaemon/DHT_bootstrap_daemon.c | 9 +- testing/DHT_test.c | 33 +- testing/Lossless_UDP_testclient.c | 16 +- testing/Lossless_UDP_testserver.c | 8 +- testing/Messenger_test.c | 5 +- testing/nTox.c | 19 +- toxcore/DHT.c | 116 ++++--- toxcore/DHT.h | 25 +- toxcore/LAN_discovery.c | 85 ++++-- toxcore/Lossless_UDP.c | 52 +++- toxcore/Lossless_UDP.h | 6 + toxcore/Messenger.c | 15 +- toxcore/friend_requests.c | 10 +- toxcore/group_chats.c | 2 +- toxcore/net_crypto.c | 2 +- toxcore/network.c | 332 +++++++++++++++++++-- toxcore/network.h | 48 +-- toxcore/ping.c | 6 +- toxcore/tox.c | 5 +- toxcore/tox.h | 47 ++- toxcore/util.c | 5 - toxcore/util.h | 1 - 23 files changed, 625 insertions(+), 235 deletions(-) diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index bc0c592a..7355ca10 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -81,10 +81,14 @@ void manage_keys(DHT *dht) int main(int argc, char *argv[]) { + /* let use decide by cmdline: TODO */ + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; + /* Initialize networking - Bind to ip 0.0.0.0:PORT */ - IP4 ip; - ip.uint32 = 0; + IP ip; + ip_init(&ip, ipv6enabled); + DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); manage_keys(dht); printf("Public key: "); @@ -110,11 +114,8 @@ int main(int argc, char *argv[]) if (argc > 3) { printf("Trying to bootstrap into the network...\n"); - IP_Port bootstrap_info; - bootstrap_info.ip.uint32 = inet_addr(argv[1]); - bootstrap_info.port = htons(atoi(argv[2])); uint8_t *bootstrap_key = hex_string_to_bin(argv[3]); - DHT_bootstrap(dht, bootstrap_info, bootstrap_key); + DHT_bootstrap_ex(dht, argv[1], ipv6enabled, htons(atoi(argv[2])), bootstrap_key); free(bootstrap_key); } diff --git a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c index 58af2751..cf19435d 100644 --- a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c +++ b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c @@ -301,7 +301,12 @@ struct server_conf_s configure_server(char *cfg_file) printf("bootstrap_server %d: Invalid port.\n", i); } +#ifdef TOX_ENABLE_IPV6 + server_conf.info[i].conn.ip.family = AF_INET; + server_conf.info[i].conn.ip.ip4.uint32 = resolve_addr(strcpy(tmp_ip, bs_ip)); +#else server_conf.info[i].conn.ip.uint32 = resolve_addr(strcpy(tmp_ip, bs_ip)); +#endif server_conf.info[i].conn.port = htons(bs_port); b16_to_key(strcpy(tmp_pk, bs_pk), bs_pk_p); } @@ -339,8 +344,8 @@ int main(int argc, char *argv[]) /* Initialize networking bind to ip 0.0.0.0:PORT */ - IP4 ip; - ip.uint32 = 0; + IP ip; + ip_init(&ip, 0); DHT *dht = new_DHT(new_net_crypto(new_networking(ip, server_conf.port))); /* Read the config file */ printf("PID file: %s\n", server_conf.pid_file); diff --git a/testing/DHT_test.c b/testing/DHT_test.c index a7349a65..caa0cde2 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c @@ -66,13 +66,11 @@ void print_clientlist(DHT *dht) } p_ip = dht->close_clientlist[i].ip_port; - printf("\nIP: %u.%u.%u.%u Port: %u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3], - ntohs(p_ip.port)); + printf("\nIP: %s Port: %u", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); printf("\nTimestamp: %llu", (long long unsigned int) dht->close_clientlist[i].timestamp); printf("\nLast pinged: %llu\n", (long long unsigned int) dht->close_clientlist[i].last_pinged); p_ip = dht->close_clientlist[i].ret_ip_port; - printf("OUR IP: %u.%u.%u.%u Port: %u\n", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3], - ntohs(p_ip.port)); + printf("OUR IP: %s Port: %u\n", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); printf("Timestamp: %llu\n", (long long unsigned int) dht->close_clientlist[i].ret_timestamp); } } @@ -91,9 +89,8 @@ void print_friendlist(DHT *dht) printf("%c", dht->friends_list[k].client_id[j]); } - p_ip = DHT_getfriendip(dht, dht->friends_list[k].client_id); - printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3], - ntohs(p_ip.port)); + int friendok = DHT_getfriendip(dht, dht->friends_list[k].client_id, &p_ip); + printf("\nIP: %s:%u", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); printf("\nCLIENTS IN LIST:\n\n"); @@ -108,13 +105,11 @@ void print_friendlist(DHT *dht) } p_ip = dht->friends_list[k].client_list[i].ip_port; - printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3], - ntohs(p_ip.port)); + printf("\nIP: %s:%u", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); printf("\nTimestamp: %llu", (long long unsigned int) dht->friends_list[k].client_list[i].timestamp); printf("\nLast pinged: %llu\n", (long long unsigned int) dht->friends_list[k].client_list[i].last_pinged); p_ip = dht->friends_list[k].client_list[i].ret_ip_port; - printf("ret IP: %u.%u.%u.%u:%u\n", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3], - ntohs(p_ip.port)); + printf("ret IP: %s:%u\n", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); printf("Timestamp: %llu\n", (long long unsigned int)dht->friends_list[k].client_list[i].ret_timestamp); } } @@ -138,11 +133,14 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port) int main(int argc, char *argv[]) { + /* let use decide by cmdline: TODO */ + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; + //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); /* initialize networking */ /* bind to ip 0.0.0.0:PORT */ - IP4 ip; - ip.uint32 = 0; + IP ip; + ip_init(&ip, ipv6enabled); DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); @@ -172,14 +170,7 @@ int main(int argc, char *argv[]) perror("Initialization"); - IP_Port bootstrap_ip_port; - bootstrap_ip_port.port = htons(atoi(argv[2])); - /* bootstrap_ip_port.ip.c[0] = 127; - * bootstrap_ip_port.ip.c[1] = 0; - * bootstrap_ip_port.ip.c[2] = 0; - * bootstrap_ip_port.ip.c[3] = 1; */ - bootstrap_ip_port.ip.uint32 = inet_addr(argv[1]); - DHT_bootstrap(dht, bootstrap_ip_port, hex_string_to_bin(argv[3])); + DHT_bootstrap_ex(dht, argv[1], ipv6enabled, htons(atoi(argv[2])), hex_string_to_bin(argv[3])); /* IP_Port ip_port; diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c index 4ac94b4b..564b2ecf 100644 --- a/testing/Lossless_UDP_testclient.c +++ b/testing/Lossless_UDP_testclient.c @@ -66,8 +66,7 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port) void printip(IP_Port ip_port) { - printf("\nIP: %u.%u.%u.%u Port: %u", ip_port.ip.uint8[0], ip_port.ip.uint8[1], ip_port.ip.uint8[2], ip_port.ip.uint8[3], - ntohs(ip_port.port)); + printf("\nIP: %s Port: %u", ip_ntoa(&ip_port.ip), ntohs(ip_port.port)); } /* void printpackets(Data test) @@ -152,6 +151,9 @@ void printconnection(int connection_id) int main(int argc, char *argv[]) { + /* let use decide by cmdline: TODO */ + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; + if (argc < 4) { printf("usage: %s ip port filename\n", argv[0]); exit(0); @@ -168,14 +170,18 @@ int main(int argc, char *argv[]) /* initialize networking */ /* bind to ip 0.0.0.0:PORT */ - IP4 ip; - ip.uint32 = 0; + IP ip; + ip_init(&ip, ipv6enabled); + Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT)); perror("Initialization"); + IP_Port serverip; - serverip.ip.uint32 = inet_addr(argv[1]); + ip_init(&serverip.ip, ipv6enabled); + addr_resolve(argv[1], &serverip.ip); serverip.port = htons(atoi(argv[2])); printip(serverip); + int connection = new_connection(ludp, serverip); uint64_t timer = current_time(); diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c index e0ea92bc..3e54e9be 100644 --- a/testing/Lossless_UDP_testserver.c +++ b/testing/Lossless_UDP_testserver.c @@ -147,6 +147,9 @@ void printconnection(int connection_id) int main(int argc, char *argv[]) { + /* let use decide by cmdline: TODO */ + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; + if (argc < 2) { printf("usage: %s filename\n", argv[0]); exit(0); @@ -163,8 +166,9 @@ int main(int argc, char *argv[]) //initialize networking //bind to ip 0.0.0.0:PORT - IP4 ip; - ip.uint32 = 0; + IP ip; + ip_init(&ip, ipv6enabled); + Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT)); perror("Initialization"); diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index 04d3bc14..73d44efb 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -101,7 +101,8 @@ int main(int argc, char *argv[]) } /* IPv6: maybe allow from cmdline --ipv6? sticking to IPv4 for now */ - m = initMessenger(0); + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; + m = initMessenger(ipv6enabled); if ( !m ) { fputs("Failed to allocate messenger datastructure\n", stderr); @@ -110,7 +111,7 @@ int main(int argc, char *argv[]) if (argc > 3) { uint16_t port = htons(atoi(argv[2])); - DHT_bootstrap_ex(m->dht, argv[1], port, hex_string_to_bin(argv[3])); + DHT_bootstrap_ex(m->dht, argv[1], ipv6enabled, port, hex_string_to_bin(argv[3])); } else { FILE *file = fopen(argv[1], "rb"); diff --git a/testing/nTox.c b/testing/nTox.c index 438468bd..6084aeda 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -537,6 +537,9 @@ void print_help(void) int main(int argc, char *argv[]) { + /* let use decide by cmdline: TODO */ + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; + int on = 0; int c = 0; int i = 0; @@ -566,7 +569,7 @@ int main(int argc, char *argv[]) } } - m = tox_new(); + m = tox_new_ex(ipv6enabled); if ( !m ) { fputs("Failed to allocate Messenger datastructure", stderr); @@ -590,20 +593,12 @@ int main(int argc, char *argv[]) new_lines(idstring); strcpy(line, ""); - tox_IP_Port bootstrap_ip_port; - bootstrap_ip_port.port = htons(atoi(argv[2])); - int resolved_address = resolve_addr(argv[1]); - - if (resolved_address != 0) - bootstrap_ip_port.ip.i = resolved_address; - else - exit(1); - + uint16_t port = htons(atoi(argv[2])); unsigned char *binary_string = hex_string_to_bin(argv[3]); - tox_bootstrap(m, bootstrap_ip_port, binary_string); + tox_bootstrap_ex(m, argv[1], ipv6enabled, port, binary_string); free(binary_string); - nodelay(stdscr, TRUE); + 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 4c15c1eb..a4734747 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -115,11 +115,6 @@ static int client_id_cmp(ClientPair p1, ClientPair p2) return c; } -static int ip4port_equal(IP_Port a, IP_Port b) -{ - return (a.ip.uint32 == b.ip.uint32) && (a.port == b.port); -} - static int id_equal(uint8_t *a, uint8_t *b) { return memcmp(a, b, CLIENT_ID_SIZE) == 0; @@ -144,15 +139,14 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id for (i = 0; i < length; ++i) { /* If ip_port is assigned to a different client_id replace it */ - if (ip4port_equal(list[i].ip_port, ip_port)) { + if (ipport_equal(&list[i].ip_port, &ip_port)) { memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); } if (id_equal(list[i].client_id, client_id)) { /* Refresh the client timestamp. */ list[i].timestamp = temp_time; - list[i].ip_port.ip.uint32 = ip_port.ip.uint32; - list[i].ip_port.port = ip_port.port; + ipport_copy(&list[i].ip_port, &ip_port); return 1; } } @@ -216,7 +210,7 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list * we COULD send ALL as NET_PACKET_SEND_NODES_EX if we KNEW that the * partner node understands - that's true if *they* are on IPv6 */ -#ifdef NETWORK_IP_PORT_IS_IPV6 +#ifdef TOX_ENABLE_IPV6 ipv46x = 0; if (sa_family == AF_INET) ipv46x = dht->close_clientlist[i].ip_port.ip.family != AF_INET; @@ -266,7 +260,7 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list MAX_SENT_NODES, dht->friends_list[i].client_list[j].client_id); -#ifdef NETWORK_IP_PORT_IS_IPV6 +#ifdef TOX_ENABLE_IPV6 ipv46x = 0; if (sa_family == AF_INET) ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family != AF_INET; @@ -330,7 +324,7 @@ static int replace_bad( Client_data *list, memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); list[i].ip_port = ip_port; list[i].timestamp = temp_time; - list[i].ret_ip_port.ip.uint32 = 0; + ip_reset(&list[i].ret_ip_port.ip); list[i].ret_ip_port.port = 0; list[i].ret_timestamp = 0; return 0; @@ -378,7 +372,7 @@ static int replace_good( Client_data *list, memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); list[i].ip_port = ip_port; list[i].timestamp = temp_time; - list[i].ret_ip_port.ip.uint32 = 0; + ip_reset(&list[i].ret_ip_port.ip); list[i].ret_ip_port.port = 0; list[i].ret_timestamp = 0; return 0; @@ -476,13 +470,13 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { pinging = 0; - if (ip_port.ip.uint32 != 0 && ip4port_equal(dht->send_nodes[i].ip_port, ip_port)) + if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id) ++pinging; - if (ping_id != 0 && dht->send_nodes[i].ping_id == 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_port.ip.uint32 != 0)) + if (pinging == (ping_id != 0) + (ip_isset(&ip_port.ip) != 0)) return 1; } } @@ -575,11 +569,11 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl random_nonce(nonce); memcpy(plain, &ping_id, sizeof(ping_id)); -#if DHT_NODEFORMAT == 46 - Node4_format *nodes4_list = &(plain + sizeof(ping_id)); +#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++) - if (nodes_list[i].ip.family == AF_INET) { + for(i = 0; i < num_nodes; i++) + if (nodes_list[i].ip_port.ip.family == AF_INET) { memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); nodes4_list[num_nodes_ok].ip_port.ip.uint32 = nodes_list[i].ip_port.ip.ip4.uint32; nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; @@ -680,14 +674,15 @@ 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]; -#if DHT_NODEFORMAT == 46 - Node4_format *nodes4_list = &(plain + sizeof(ping_id)); +#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++) - if ((nodes_list[i].ip != 0) && (nodes_list[i].ip != ~0)) { + int num_nodes_ok = 0; + 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; nodes_list[num_nodes_ok].ip_port.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32; @@ -706,8 +701,6 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 addto_lists(dht, source, packet + 1); - uint32_t i; - for (i = 0; i < num_nodes; ++i) { send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id); returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); @@ -775,27 +768,30 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id) } /* TODO: Optimize this. */ -IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id) +int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port) { uint32_t i, j; uint64_t temp_time = unix_time(); - IP_Port empty = {{{{0}}, 0, 0}}; + + ip_reset(&ip_port->ip); + ip_port->port = 0; for (i = 0; i < dht->num_friends; ++i) { /* Equal */ if (id_equal(dht->friends_list[i].client_id, client_id)) { for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id) - && !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) - return dht->friends_list[i].client_list[j].ip_port; + && !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { + *ip_port = dht->friends_list[i].client_list[j].ip_port; + return 1; + } } - return empty; + return 0; } } - empty.ip.uint32 = 1; - return empty; + return -1; } /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request @@ -880,16 +876,12 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) getnodes(dht, ip_port, public_key, dht->c->self_public_key); send_ping_request(dht->ping, dht->c, ip_port, public_key); } -void DHT_bootstrap_ex(DHT *dht, const char *address, uint16_t port, uint8_t *public_key) +void DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) { - IPAny_Port ipany_port; - ipany_port.ip.family = AF_INET; - if (addr_resolve_or_parse_ip(address, &ipany_port.ip)) { - /* IPAny temporary: copy down */ - IP_Port ip_port; - ip_port.ip.uint32 = ipany_port.ip.ip4.uint32; + IP_Port ip_port; + ip_init(&ip_port.ip, ipv6enabled); + if (addr_resolve_or_parse_ip(address, &ip_port.ip)) { ip_port.port = port; - DHT_bootstrap(dht, ip_port, public_key); } } @@ -933,7 +925,7 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) client = &friend->client_list[i]; /* If ip is not zero and node is good. */ - if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { + if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { if (id_equal(client->client_id, friend->client_id)) return 0; @@ -975,7 +967,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt client = &friend->client_list[i]; /* If ip is not zero and node is good. */ - if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { + if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { int retval = sendpacket(dht->c->lossless_udp->net, client->ip_port, packet, length); if ((unsigned int)retval == length) @@ -1009,7 +1001,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint client = &friend->client_list[i]; /* If ip is not zero and node is good. */ - if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { + if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { ip_list[n] = client->ip_port; ++n; } @@ -1115,9 +1107,10 @@ static int handle_NATping(void *object, IP_Port source, uint8_t *source_pubkey, * * return ip of 0 if failure. */ -static IP4 NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) +static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) { - IP4 zero = {{0}}; + IP zero; + ip_reset(&zero); if (len > MAX_FRIEND_CLIENTS) return zero; @@ -1127,7 +1120,7 @@ static IP4 NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) for (i = 0; i < len; ++i) { for (j = 0; j < len; ++j) { - if (ip_portlist[i].ip.uint32 == ip_portlist[j].ip.uint32) + if (ip_equal(&ip_portlist[i].ip, &ip_portlist[j].ip)) ++numbers[i]; } @@ -1144,13 +1137,13 @@ static IP4 NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) * * return number of ports and puts the list of ports in portlist. */ -static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP4 ip) +static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip) { uint32_t i; uint16_t num = 0; for (i = 0; i < len; ++i) { - if (ip_portlist[i].ip.uint32 == ip.uint32) { + if (ip_equal(&ip_portlist[i].ip, &ip)) { portlist[num] = ntohs(ip_portlist[i].port); ++num; } @@ -1159,7 +1152,7 @@ static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t return num; } -static void punch_holes(DHT *dht, IP4 ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) +static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) { if (numports > MAX_FRIEND_CLIENTS || numports == 0) return; @@ -1170,7 +1163,9 @@ static void punch_holes(DHT *dht, IP4 ip, uint16_t *port_list, uint16_t numports for (i = dht->friends_list[friend_num].punching_index; i != top; i++) { /* TODO: Improve port guessing algorithm. */ uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); - IP_Port pinging = {{ip, htons(port), 0}}; + IP_Port pinging; + ip_copy(&pinging.ip, &ip); + pinging.port = htons(port); send_ping_request(dht->ping, dht->c, pinging, dht->friends_list[friend_num].client_id); } @@ -1199,9 +1194,8 @@ static void do_NAT(DHT *dht) dht->friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { - IP4 ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); - - if (ip.uint32 == 0) + IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); + if (!ip_isset(&ip)) continue; uint16_t port_list[MAX_FRIEND_CLIENTS]; @@ -1230,16 +1224,15 @@ static void do_NAT(DHT *dht) */ int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) { - if (ip_port.ip.uint32 == 0) + if (!ip_isset(&ip_port.ip)) return -1; uint32_t i; for (i = 0; i < MAX_TOPING; ++i) { - if (dht->toping[i].ip_port.ip.uint32 == 0) { + if (!ip_isset(&dht->toping[i].ip_port.ip)) { memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); - dht->toping[i].ip_port.ip.uint32 = ip_port.ip.uint32; - dht->toping[i].ip_port.port = ip_port.port; + ipport_copy(&dht->toping[i].ip_port, &ip_port); return 0; } } @@ -1247,8 +1240,7 @@ int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) for (i = 0; i < MAX_TOPING; ++i) { if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) { memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); - dht->toping[i].ip_port.ip.uint32 = ip_port.ip.uint32; - dht->toping[i].ip_port.port = ip_port.port; + ipport_copy(&dht->toping[i].ip_port, &ip_port); return 0; } } @@ -1270,11 +1262,11 @@ static void do_toping(DHT *dht) uint32_t i; for (i = 0; i < MAX_TOPING; ++i) { - if (dht->toping[i].ip_port.ip.uint32 == 0) + if (!ip_isset(&dht->toping[i].ip_port.ip)) return; send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, dht->toping[i].client_id); - dht->toping[i].ip_port.ip.uint32 = 0; + ip_reset(&dht->toping[i].ip_port.ip); } } diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 5963d297..d980f269 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -83,13 +83,14 @@ typedef struct { typedef struct { uint8_t client_id[CLIENT_ID_SIZE]; - IPAny_Port ip_port; + IP_Port ip_port; } Node46_format; -/* IPAny temporary: change to 46 */ -#define DHT_NODEFORMAT 4 + +#ifdef TOX_ENABLE_IPV6 +typedef Node46_format Node_format; +#else typedef Node4_format Node_format; -/* #define DHT_NODEFORMAT 46 */ -/* typedef Node46_format Node_format; */ +#endif typedef struct { IP_Port ip_port; @@ -135,11 +136,21 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id); * ip must be 4 bytes long. * port must be 2 bytes long. * + * !!! Signature changed!!! + * + * OLD: IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id); + * * return ip if success. * return ip of 0 if failure (This means the friend is either offline or we have not found him yet). * return ip of 1 if friend is not in list. + * + * NEW: int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port); + * + * return -1, -- if client_id does NOT refer to a friend + * return 0, -- if client_id refers to a friend and we failed to find the friend (yet) + * return 1, ip if client_id refers to a friend and we found him */ -IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id); +int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port); /* Run this function at least a couple times per second (It's the main loop). */ void do_DHT(DHT *dht); @@ -148,7 +159,7 @@ void do_DHT(DHT *dht); * Sends a get nodes request to the given node with ip port and public_key. */ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key); -void DHT_bootstrap_ex(DHT *dht, const char *address, uint16_t port, uint8_t *public_key); +void DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, 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 bc73a6a1..4cbe3177 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -81,33 +81,76 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t * d #endif /* Return the broadcast ip. */ -static IP4 broadcast_ip(void) +static IP broadcast_ip(sa_family_t sa_family) { - IP4 ip; - ip.uint32 = ~0; + IP ip; + ip_reset(&ip); + +#ifdef TOX_ENABLE_IPV6 + if (sa_family == AF_INET) + { + ip.family = AF_INET; + ip.ip4.uint32 = INADDR_BROADCAST; + } + + if (sa_family == AF_INET6) + { + ip.family = AF_INET6; + /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ + /* FE80::*: MUST be exact, for that we would need to look over all + * interfaces and check in which status they are */ + ip.ip6.s6_addr[ 0] = 0xFF; + ip.ip6.s6_addr[ 1] = 0x02; + ip.ip6.s6_addr[15] = 0x01; + } +#else + ip.uint32 = INADDR_BROADCAST; +#endif + return ip; } /* return 0 if ip is a LAN ip. * return -1 if it is not. */ -static int LAN_ip(IP4 ip) +static int LAN_ip(IP ip) { - if (ip.uint8[0] == 127) /* Loopback. */ - return 0; - - if (ip.uint8[0] == 10) /* 10.0.0.0 to 10.255.255.255 range. */ - return 0; - - if (ip.uint8[0] == 172 && ip.uint8[1] >= 16 && ip.uint8[1] <= 31) /* 172.16.0.0 to 172.31.255.255 range. */ - return 0; - - if (ip.uint8[0] == 192 && ip.uint8[1] == 168) /* 192.168.0.0 to 192.168.255.255 range. */ - return 0; - - if (ip.uint8[0] == 169 && ip.uint8[1] == 254 && ip.uint8[2] != 0 - && ip.uint8[2] != 255)/* 169.254.1.0 to 169.254.254.255 range. */ - return 0; +#ifdef TOX_ENABLE_IPV6 + if (ip.family == AF_INET) { + IP4 ip4 = ip.ip4; +#else + IP4 ip4 = ip; +#endif + /* Loopback. */ + if (ip4.uint8[0] == 127) + return 0; + + /* 10.0.0.0 to 10.255.255.255 range. */ + if (ip4.uint8[0] == 10) + return 0; + + /* 172.16.0.0 to 172.31.255.255 range. */ + if (ip4.uint8[0] == 172 && ip4.uint8[1] >= 16 && ip4.uint8[1] <= 31) + return 0; + + /* 192.168.0.0 to 192.168.255.255 range. */ + if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168) + return 0; + + /* 169.254.1.0 to 169.254.254.255 range. */ + 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) { + /* autogenerated for each interface: FE80::* (up to FEBF::*) + /* 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))) + return 0; + } +#endif return -1; } @@ -135,7 +178,9 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c) #ifdef __linux send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES); #endif - IP_Port ip_port = {{broadcast_ip(), port, 0}}; + IP_Port ip_port; + ip_port.ip = broadcast_ip(c->lossless_udp->net->family); + ip_port.port = port; return 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 f66d5b62..ca874562 100644 --- a/toxcore/Lossless_UDP.c +++ b/toxcore/Lossless_UDP.c @@ -44,9 +44,7 @@ int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port) { tox_array_for_each(&ludp->connections, Connection, tmp) { - if (tmp->ip_port.ip.uint32 == ip_port.ip.uint32 && - tmp->ip_port.port == ip_port.port && - tmp->status > 0) { + if (tmp-> status > 0 && ipport_equal(&tmp->ip_port, &ip_port)) { return tmp_i; } } @@ -61,17 +59,49 @@ int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port) * * TODO: make this better */ -static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) + +static uint8_t randtable_initget(Lossless_UDP *ludp, uint32_t index, uint8_t value) { - uint32_t id = 0, i; + if (ludp->randtable[index][value] == 0) + ludp->randtable[index][value] = random_int(); - for (i = 0; i < 6; ++i) { - if (ludp->randtable[i][source.uint8[i]] == 0) - ludp->randtable[i][source.uint8[i]] = random_int(); + return ludp->randtable[index][value]; +} - id ^= ludp->randtable[i][source.uint8[i]]; +static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) +{ + uint32_t id = 0, i = 0; + + uint8_t *uint8; + uint8 = (uint8_t *)&source.port; + id ^= randtable_initget(ludp, i, *uint8); + i++, uint8++; + 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]); + } +#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. */ if (id == 0) id = 1; @@ -290,7 +320,9 @@ IP_Port connection_ip(Lossless_UDP *ludp, int connection_id) if ((unsigned int)connection_id < ludp->connections.len) return tox_array_get(&ludp->connections, connection_id, Connection).ip_port; - IP_Port zero = {{{{0}}, 0, 0}}; + IP_Port zero; + ip_reset(&zero.ip); + zero.port = 0; return zero; } diff --git a/toxcore/Lossless_UDP.h b/toxcore/Lossless_UDP.h index 20471b0a..f0ce0e87 100644 --- a/toxcore/Lossless_UDP.h +++ b/toxcore/Lossless_UDP.h @@ -123,7 +123,13 @@ 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 61a76a76..cf744e23 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -658,14 +658,8 @@ Messenger *initMessenger(uint8_t ipv6enabled) if ( ! m ) return NULL; -#ifdef NETWORK_IP_PORT_IS_IPV6 - IPAny ip; - memset(&ip, 0, sizeof(ip)); - ip.family = ipv6enabled ? AF_INET6 : AF_INET; -#else - IP4 ip; - ip.uint32 = 0; -#endif + IP ip; + ip_init(&ip, ipv6enabled); m->net = new_networking(ip, PORT); if (m->net == NULL) { @@ -749,11 +743,12 @@ void doFriends(Messenger *m) } } - IP_Port friendip = DHT_getfriendip(m->dht, m->friendlist[i].client_id); + IP_Port friendip; + int friendok = DHT_getfriendip(m->dht, m->friendlist[i].client_id, &friendip); switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { case 0: - if (friendip.ip.uint32 > 1) + if (friendok == 1) m->friendlist[i].crypt_connection_id = crypto_connect(m->net_crypto, m->friendlist[i].client_id, friendip); break; diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c index 51a8112f..c821d998 100644 --- a/toxcore/friend_requests.c +++ b/toxcore/friend_requests.c @@ -50,18 +50,22 @@ int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8 if (len == -1) return -1; - IP_Port ip_port = DHT_getfriendip(dht, public_key); + IP_Port ip_port; + int friendok = DHT_getfriendip(dht, public_key, &ip_port); - if (ip_port.ip.uint32 == 1) + // not a friend + if (friendok == -1) return -1; - if (ip_port.ip.uint32 != 0) { + // is a friend and we know how to reach him + if (friendok == 1) { if (sendpacket(dht->c->lossless_udp->net, ip_port, packet, len) != -1) return 0; return -1; } + // is a friend, we DON'T know how to reach him int num = route_tofriend(dht, public_key, packet, len); if (num == 0) diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 1b021e20..59266b7a 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -204,7 +204,7 @@ static uint8_t sendto_allpeers(Group_Chat *chat, uint8_t *data, uint16_t length, uint64_t temp_time = unix_time(); for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { - if (chat->close[i].ip_port.ip.uint32 != 0 && chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) { + if (ip_isset(&chat->close[i].ip_port.ip) && chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) { if (send_groupchatpacket(chat, chat->close[i].ip_port, chat->close[i].client_id, data, length, request_id) == 0) ++sent; } diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index a182bb53..b6f08fe4 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -439,7 +439,7 @@ int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port) if (id != -1) { IP_Port c_ip = connection_ip(c->lossless_udp, c->crypto_connections[id].number); - if (c_ip.ip.uint32 == ip_port.ip.uint32 && c_ip.port == ip_port.port) + if (ipport_equal(&c_ip, &ip_port)) return -1; } diff --git a/toxcore/network.c b/toxcore/network.c index 1fb5b77a..d65e2077 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -66,8 +66,63 @@ uint32_t random_int(void) */ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t length) { - ADDR addr = {AF_INET, ip_port.port, ip_port.ip, {0}}; - return sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); +#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; +#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; + addr6->sin6_family = AF_INET6; + addr6->sin6_port = ip_port.port; + + /* there should be a macro for this in a standards compliant + * environment, not found */ + addr6->sin6_addr.s6_addr32[0] = 0; + addr6->sin6_addr.s6_addr32[1] = 0; + addr6->sin6_addr.s6_addr32[2] = htonl(0xFFFF); + addr6->sin6_addr.s6_addr32[3] = ip_port.ip.ip4.uint32; + + 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; + addr4->sin_family = AF_INET; + addr4->sin_addr = 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); + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; + addr6->sin6_family = AF_INET6; + addr6->sin6_port = ip_port.port; + addr6->sin6_addr = ip_port.ip.ip6; + + addr6->sin6_flowinfo = 0; + addr6->sin6_scope_id = 0; + } else { + /* unknown address type*/ + return 0; + } +#endif + + return sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize); } /* Function to receive data @@ -82,7 +137,7 @@ static int receivepacket(unsigned int sock, IP_Port *ip_port, uint8_t *data, uin static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) #endif { - ADDR addr; + struct sockaddr_storage addr; #ifdef WIN32 int addrlen = sizeof(addr); #else @@ -93,8 +148,31 @@ static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *le if (*(int32_t *)length <= 0) return -1; /* Nothing received or empty packet. */ - ip_port->ip = addr.ip; - ip_port->port = addr.port; +#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 = 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 + return 0; } @@ -156,18 +234,32 @@ static void at_shutdown(void) * return Networking_Core object if no problems * return NULL if there are problems. */ -Networking_Core *new_networking(IP4 ip, uint16_t port) +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) + return NULL; +#endif + if (at_startup() != 0) return NULL; - /* Initialize our socket. */ Networking_Core *temp = calloc(1, sizeof(Networking_Core)); - if (temp == NULL) return NULL; - temp->family = AF_INET; + sa_family_t family = 0; +#ifdef TOX_ENABLE_IPV6 + family = ip.family; +#else + family = AF_INET; +#endif + temp->family = family; + temp->port = 0; + + /* Initialize our socket. */ + /* add log message what we're creating */ temp->sock = socket(temp->family, SOCK_DGRAM, IPPROTO_UDP); /* Check for socket error. */ @@ -201,7 +293,7 @@ Networking_Core *new_networking(IP4 ip, uint16_t port) return -1; */ - /* Enable broadcast on socket. */ + /* Enable broadcast on socket? */ int broadcast = 1; setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); @@ -216,11 +308,72 @@ Networking_Core *new_networking(IP4 ip, uint16_t port) #endif /* Bind our socket to port PORT and address 0.0.0.0 */ - ADDR addr = {temp->family, htons(port), ip, {0}}; - if (!bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr))) - temp->port = port; + 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; + addr4->sin_family = AF_INET; + addr4->sin_port = htons(port); + addr4->sin_addr = ip4.in_addr; + + portptr = &addr4->sin_port; +#ifdef TOX_ENABLE_IPV6 + } + else if (temp->family == AF_INET6) + { + addrsize = sizeof(struct sockaddr_in6); + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; + addr6->sin6_family = AF_INET6; + addr6->sin6_port = htons(port); + addr6->sin6_addr = ip.ip6; + + addr6->sin6_flowinfo = 0; + addr6->sin6_scope_id = 0; + + portptr = &addr6->sin6_port; + } + else + return NULL; - return temp; + if (ip.family == AF_INET6) { + char ipv6only = 0; + int res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only)); + if (res < 0) { + /* add log message*/ + } + } +#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 + */ + int tries, res; + for(tries = 0; tries < 9; tries++) + { + res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); + if (!res) + { + temp->port = *portptr; + return temp; + } + + uint16_t port = ntohs(*portptr); + port++; + *portptr = htons(port); + } + + printf("Failed to bind socket: %s (IP/Port: %s:%u\n", strerror(errno), ip_ntoa(&ip), port); + free(temp); + return NULL; } /* Function to cleanup networking stuff. */ @@ -241,11 +394,12 @@ void kill_networking(Networking_Core *net) * * returns 0 when not equal or when uninitialized */ -int ip_equal(IPAny *a, IPAny *b) +int ip_equal(IP *a, IP *b) { if (!a || !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); @@ -253,6 +407,9 @@ int ip_equal(IPAny *a, IPAny *b) return IN6_ARE_ADDR_EQUAL(&a->ip6, &b->ip6); return 0; +#else + return (a->uint32 == b->uint32); +#endif }; /* ipport_equal @@ -261,7 +418,7 @@ int ip_equal(IPAny *a, IPAny *b) * * returns 0 when not equal or when uninitialized */ -int ipport_equal(IPAny_Port *a, IPAny_Port *b) +int ipport_equal(IP_Port *a, IP_Port *b) { if (!a || !b) return 0; @@ -272,15 +429,86 @@ int ipport_equal(IPAny_Port *a, IPAny_Port *b) return ip_equal(&a->ip, &b->ip); }; -/* ipany_ntoa +/* nulls out ip */ +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 */ +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 */ +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 */ +int ipport_isset(IP_Port *ipport) +{ + if (!ipport) + return 0; + + if (!ipport->port) + return 0; + + return ip_isset(&ipport->ip); +}; + +/* copies an ip structure (careful about direction!) */ +void ip_copy(IP *target, IP *source) +{ + if (!source || !target) + return; + + memcpy(target, source, sizeof(IP)); +}; + +/* copies an ip_port structure (careful about direction!) */ +void ipport_copy(IP_Port *target, IP_Port *source) +{ + if (!source || !target) + return; + + memcpy(target, source, sizeof(IP_Port)); +}; + +/* ip_ntoa * converts ip into a string * uses a static buffer, so mustn't used multiple times in the same output */ /* there would be INET6_ADDRSTRLEN, but it might be too short for the error message */ static char addresstext[96]; -const char *ipany_ntoa(IPAny *ip) +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; @@ -296,6 +524,11 @@ const char *ipany_ntoa(IPAny *ip) } 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)"); @@ -318,8 +551,12 @@ const char *ipany_ntoa(IPAny *ip) * returns 1 on success, 0 on failure */ -int addr_parse_ip(const char *address, IPAny *to) +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)) { to->family = AF_INET; @@ -333,6 +570,13 @@ int addr_parse_ip(const char *address, IPAny *to) 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; }; @@ -353,15 +597,25 @@ int addr_parse_ip(const char *address, IPAny *to) * returns 0 on failure */ -int addr_resolve(const char *address, IPAny *ip) +int addr_resolve(const char *address, IP *to) { + if (!address || !to) + return 0; + + sa_family_t family; +#ifdef TOX_ENABLE_IPV6 + family = to->family; +#else + family = AF_INET; +#endif + struct addrinfo *server = NULL; struct addrinfo *walker = NULL; struct addrinfo hints; int rc; memset(&hints, 0, sizeof(hints)); - hints.ai_family = ip->family; + hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses. #ifdef __WIN32__ @@ -385,31 +639,40 @@ int addr_resolve(const char *address, IPAny *ip) return 0; } +#ifdef TOX_ENABLE_IPV6 IP4 ip4; memset(&ip4, 0, sizeof(ip4)); IP6 ip6; memset(&ip6, 0, sizeof(ip6)); +#endif walker = server; while (walker && (rc != 3)) { - if (ip->family != AF_UNSPEC) { - if (walker->ai_family == ip->family) { - if (ip->family == AF_INET) { + if (family != AF_UNSPEC) { + if (walker->ai_family == family) { + if (family == AF_INET) { if (walker->ai_addrlen == sizeof(struct sockaddr_in)) { struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; - ip->ip4.in_addr = addr->sin_addr; +#ifdef TOX_ENABLE_IPV6 + to->ip4.in_addr = addr->sin_addr; +#else + to->in_addr = addr->sin_addr; +#endif rc = 3; } } - else if (ip->family == AF_INET6) { +#ifdef TOX_ENABLE_IPV6 + else if (family == AF_INET6) { if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; - ip->ip6 = addr->sin6_addr; + to->ip6 = addr->sin6_addr; rc = 3; } } +#endif } } +#ifdef TOX_ENABLE_IPV6 else { if (walker->ai_family == AF_INET) { if (walker->ai_addrlen == sizeof(struct sockaddr_in)) { @@ -426,22 +689,25 @@ int addr_resolve(const char *address, IPAny *ip) } } } +#endif walker = walker->ai_next; } - if (ip->family == AF_UNSPEC) { +#ifdef TOX_ENABLE_IPV6 + if (to->family == AF_UNSPEC) { if (rc & 2) { - ip->family = AF_INET6; - ip->ip6 = ip6; + to->family = AF_INET6; + to->ip6 = ip6; } else if (rc & 1) { - ip->family = AF_INET; - ip->ip4 = ip4; + to->family = AF_INET; + to->ip4 = ip4; } else rc = 0; } +#endif freeaddrinfo(server); @@ -458,7 +724,7 @@ int addr_resolve(const char *address, IPAny *ip) * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6) * returns 1 on success, 0 on failure */ -int addr_resolve_or_parse_ip(const char *address, IPAny *to) +int addr_resolve_or_parse_ip(const char *address, IP *to) { if (!addr_resolve(address, to)) if (!addr_parse_ip(address, to)) diff --git a/toxcore/network.h b/toxcore/network.h index 913763ee..0d31ffac 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -101,12 +101,6 @@ typedef struct { }; } IPAny; -/* ipany_ntoa - * converts ip into a string - * uses a static buffer, so mustn't used multiple times in the same output - */ -const char *ipany_ntoa(IPAny *ip); - typedef union { struct { IP4 ip; @@ -124,29 +118,43 @@ typedef struct { uint16_t port; } IPAny_Port; -#ifdef NETWORK_IP_PORT_IS_IPV6 +#undef 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 + * uses a static buffer, so mustn't used multiple times in the same output + */ +const char *ip_ntoa(IP *ip); + /* ipport_equal * compares two IPAny_Port structures * unset means unequal * * returns 0 when not equal or when uninitialized */ -int ipport_equal(IPAny_Port *a, IPAny_Port *b); - -typedef struct { - int16_t family; - uint16_t port; - IP4 ip; - uint8_t zeroes[8]; -#ifdef ENABLE_IPV6 - uint8_t zeroes2[12]; -#endif -} ADDR; +int ipport_equal(IP_Port *a, IP_Port *b); + +/* nulls out ip */ +void ip_reset(IP *ip); +/* nulls out ip, sets family according to flag */ +void ip_init(IP *ip, uint8_t ipv6enabled); +/* checks if ip is valid */ +int ip_isset(IP *ip); +/* checks if ip is valid */ +int ipport_isset(IP_Port *ipport); +/* copies an ip structure */ +void ip_copy(IP *target, IP *source); +/* copies an ip_port structure */ +void ipport_copy(IP_Port *target, IP_Port *source); /* * addr_resolve_or_parse_ip @@ -155,7 +163,7 @@ typedef struct { * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6) * returns 1 on success, 0 on failure */ -int addr_resolve_or_parse_ip(const char *address, IPAny *to); +int addr_resolve_or_parse_ip(const char *address, IP *to); /* Function to receive data, ip and port of sender is put into ip_port. * Packet data is put into data. @@ -204,7 +212,7 @@ void networking_poll(Networking_Core *net); * return 0 if no problems. * return -1 if there were problems. */ -Networking_Core *new_networking(IP4 ip, uint16_t port); +Networking_Core *new_networking(IP ip, uint16_t port); /* Function to cleanup networking stuff (doesn't do much right now). */ void kill_networking(Networking_Core *net); diff --git a/toxcore/ping.c b/toxcore/ping.c index 5f405b52..49e0dba9 100644 --- a/toxcore/ping.c +++ b/toxcore/ping.c @@ -100,7 +100,8 @@ bool is_pinging(void *ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: Repl { PING *png = ping; - if (ipp.ip.uint32 == 0 && ping_id == 0) + /* shouldn't that be an OR ? */ + if (!ip_isset(&ipp.ip) && ping_id == 0) return false; size_t i, id; @@ -111,7 +112,8 @@ bool is_pinging(void *ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: Repl id = (png->pos_pings + i) % PING_NUM_MAX; /* ping_id = 0 means match any id. */ - if ((ipp_eq(png->pings[id].ipp, ipp) || ipp.ip.uint32 == 0) && (png->pings[id].id == ping_id || ping_id == 0)) { + if ((!ip_isset(&ipp.ip) || ipport_equal(&png->pings[id].ipp, &ipp)) && + (png->pings[id].id == ping_id || ping_id == 0)) { return true; } } diff --git a/toxcore/tox.c b/toxcore/tox.c index e37eac3e..6417b16a 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -374,10 +374,11 @@ void tox_bootstrap(void *tox, IP_Port ip_port, uint8_t *public_key) Messenger *m = tox; DHT_bootstrap(m->dht, ip_port, public_key); } -void tox_bootstrap_ex(void *tox, const char *address, uint16_t port, uint8_t *public_key) +void tox_bootstrap_ex(void *tox, const char *address, uint8_t ipv6enabled, + uint16_t port, uint8_t *public_key) { Messenger *m = tox; - DHT_bootstrap_ex(m->dht, address, port, public_key); + DHT_bootstrap_ex(m->dht, address, ipv6enabled, port, public_key); }; /* return 0 if we are not connected to the DHT. diff --git a/toxcore/tox.h b/toxcore/tox.h index f8d7975f..44eba081 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -36,21 +36,51 @@ extern "C" { #define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) - typedef union { uint8_t c[4]; uint16_t s[2]; uint32_t i; -} tox_IP; +} tox_IP4; + + +typedef struct in6_addr tox_IP6; typedef struct { - tox_IP ip; + sa_family_t family; + union { + 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; + +/* 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; uint16_t port; - /* Not used for anything right now. */ - uint16_t padding; -} tox_IP_Port; +} tox_IPAny_Port; + +#undef 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 -#define TOX_IP_IS_IPV6 0 /* Errors for m_addfriend * FAERR - Friend Add Error @@ -296,7 +326,8 @@ void tox_callback_connectionstatus(Tox *tox, void (*function)(Tox *tox, int, uin * tox_bootstrap_ex converts the address into an IP_Port structure internally */ void tox_bootstrap(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key); -void tox_bootstrap_ex(Tox *tox, const char *address, uint16_t port, uint8_t *public_key); +void tox_bootstrap_ex(Tox *tox, const char *address, uint8_t ipv6enabled, + uint16_t port, uint8_t *public_key); /* return 0 if we are not connected to the DHT. * return 1 if we are. diff --git a/toxcore/util.c b/toxcore/util.c index 1728ea21..ff366a07 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -32,11 +32,6 @@ uint64_t random_64b() return r; } -bool ipp_eq(IP_Port a, IP_Port b) -{ - return (a.ip.uint32 == b.ip.uint32) && (a.port == b.port); -} - bool id_eq(uint8_t *dest, uint8_t *src) { return memcmp(dest, src, CLIENT_ID_SIZE) == 0; diff --git a/toxcore/util.h b/toxcore/util.h index 90a3c8e4..7dea3eac 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -7,6 +7,5 @@ uint64_t now(); uint64_t random_64b(); -bool ipp_eq(IP_Port a, IP_Port b); bool id_eq(uint8_t *dest, uint8_t *src); void id_cpy(uint8_t *dest, uint8_t *src); -- cgit v1.2.3 From f267266bf611570c6e79dfb800e97396151ff870 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Tue, 10 Sep 2013 17:38:53 +0200 Subject: fix: bad memset length in ip_init() --- toxcore/network.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index d65e2077..2969f3ac 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -307,7 +307,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) fcntl(temp->sock, F_SETFL, O_NONBLOCK, 1); #endif - /* Bind our socket to port PORT and address 0.0.0.0 */ + /* 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; @@ -371,7 +371,8 @@ Networking_Core *new_networking(IP ip, uint16_t port) *portptr = htons(port); } - printf("Failed to bind socket: %s (IP/Port: %s:%u\n", strerror(errno), ip_ntoa(&ip), port); + fprintf(stderr, "Failed to bind socket: %u, %s (IP/Port: %s:%u\n", errno, + strerror(errno), ip_ntoa(&ip), port); free(temp); return NULL; } @@ -436,7 +437,7 @@ void ip_reset(IP *ip) return; #ifdef TOX_ENABLE_IPV6 - memset(ip, 0, sizeof(*ip)); + memset(ip, 0, sizeof(IP)); #else ip->uint32 = 0; #endif @@ -449,7 +450,7 @@ void ip_init(IP *ip, uint8_t ipv6enabled) return; #ifdef TOX_ENABLE_IPV6 - memset(ip, 0, sizeof(ip)); + memset(ip, 0, sizeof(IP)); ip->family = ipv6enabled ? AF_INET6 : AF_INET; #else ip->uint32 = 0; -- cgit v1.2.3 From 3ae7460853b6777e18f213b316d43cef6c5a603e Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Tue, 10 Sep 2013 20:55:05 +0200 Subject: util.*: - added logging functions, default off tox.h: - added includes for sockaddr_in/6 network.c: - added logging functions, default off (#define in util.h) - IPv6: activating site-local all-nodes multicast address (i.e. IPv6 equivalent of broadcast) --- toxcore/Messenger.c | 65 +++++++++++++++++++++++++-------------------- toxcore/network.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++------ toxcore/network.h | 1 + toxcore/tox.h | 17 ++++++++++++ toxcore/util.c | 32 ++++++++++++++++++++-- toxcore/util.h | 17 ++++++++++++ 6 files changed, 170 insertions(+), 38 deletions(-) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index cf744e23..b955ad5a 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -965,19 +965,23 @@ void Messenger_save(Messenger *m, uint8_t *data) { save_keys(m->net_crypto, data); data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; + uint32_t nospam = get_nospam(&(m->fr)); memcpy(data, &nospam, sizeof(nospam)); data += sizeof(nospam); + uint32_t size = DHT_size(m->dht); memcpy(data, &size, sizeof(size)); data += sizeof(size); DHT_save(m->dht, data); data += size; + size = sizeof(Friend) * m->numfriends; memcpy(data, &size, sizeof(size)); data += sizeof(size); memcpy(data, m->friendlist, sizeof(Friend) * m->numfriends); data += size; + uint16_t small_size = m->name_length; memcpy(data, &small_size, sizeof(small_size)); data += sizeof(small_size); @@ -990,59 +994,64 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) if (length == ~((uint32_t)0)) return -1; - if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3) + /* BLOCK1: PUBKEY, SECKEY, NOSPAM, SIZE */ + if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2) return -1; - length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3; load_keys(m->net_crypto, data); data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; + length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; + uint32_t nospam; memcpy(&nospam, data, sizeof(nospam)); set_nospam(&(m->fr), nospam); data += sizeof(nospam); + length -= sizeof(nospam); + uint32_t size; memcpy(&size, data, sizeof(size)); data += sizeof(size); + length -= sizeof(size); if (length < size) return -1; - length -= size; - if (DHT_load(m->dht, data, size) == -1) - return -1; + fprintf(stderr, "Data file: Something wicked happened to the stored connections.\n"); + + /* go on, friends still might be intact */ data += size; + length -= size; + memcpy(&size, data, sizeof(size)); data += sizeof(size); - - if (length < size || size % sizeof(Friend) != 0) + if (length < size) return -1; - Friend *temp = malloc(size); - memcpy(temp, data, size); - - uint16_t num = size / sizeof(Friend); - - uint32_t i; - - for (i = 0; i < num; ++i) { - if (temp[i].status >= 3) { - int fnum = m_addfriend_norequest(m, temp[i].client_id); - setfriendname(m, fnum, temp[i].name, temp[i].name_length); - /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ - } else if (temp[i].status != 0) { - /* TODO: This is not a good way to do this. */ - uint8_t address[FRIEND_ADDRESS_SIZE]; - memcpy(address, temp[i].client_id, crypto_box_PUBLICKEYBYTES); - memcpy(address + crypto_box_PUBLICKEYBYTES, &(temp[i].friendrequest_nospam), sizeof(uint32_t)); - uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); - memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum)); - m_addfriend(m, address, temp[i].info, temp[i].info_size); + if (!(size % sizeof(Friend))) { + uint16_t num = size / sizeof(Friend); + Friend temp[num]; + 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); + setfriendname(m, fnum, temp[i].name, temp[i].name_length); + /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ + } else if (temp[i].status != 0) { + /* TODO: This is not a good way to do this. */ + uint8_t address[FRIEND_ADDRESS_SIZE]; + memcpy(address, temp[i].client_id, crypto_box_PUBLICKEYBYTES); + memcpy(address + crypto_box_PUBLICKEYBYTES, &(temp[i].friendrequest_nospam), sizeof(uint32_t)); + uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); + memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum)); + m_addfriend(m, address, temp[i].info, temp[i].info_size); + } } } - free(temp); data += size; length -= size; diff --git a/toxcore/network.c b/toxcore/network.c index 2969f3ac..0b5eba61 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -26,6 +26,7 @@ #endif #include "network.h" +#include "util.h" /* return current UNIX time in microseconds (us). */ uint64_t current_time(void) @@ -61,6 +62,10 @@ uint32_t random_int(void) #endif } +#ifdef LOGGING +static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res); +#endif + /* Basic network functions: * Function to send packet(data) of length length to ip_port. */ @@ -122,7 +127,11 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le } #endif - return sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize); + int res = sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize); +#ifdef LOGGING + loglogdata("O=>", data, length, &ip_port, res); +#endif + return res; } /* Function to receive data @@ -131,11 +140,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le * Packet length is put into length. * Dump all empty packets. */ -#ifdef WIN32 -static int receivepacket(unsigned int sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) -#else -static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) -#endif +static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) { struct sockaddr_storage addr; #ifdef WIN32 @@ -145,8 +150,13 @@ static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *le #endif (*(int32_t *)length) = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); - if (*(int32_t *)length <= 0) + 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)); +#endif return -1; /* Nothing received or empty packet. */ + } #ifdef TOX_ENABLE_IPV6 if (addr.ss_family == AF_INET) { @@ -173,6 +183,10 @@ static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *le return -1; #endif +#ifdef LOGGING + loglogdata("=>O", data, *length, ip_port, 0); +#endif + return 0; } @@ -307,6 +321,10 @@ Networking_Core *new_networking(IP ip, uint16_t port) fcntl(temp->sock, F_SETFL, O_NONBLOCK, 1); #endif +#ifdef LOGGING + loginit(ntohs(port)); +#endif + /* 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; @@ -346,9 +364,33 @@ Networking_Core *new_networking(IP ip, uint16_t port) 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", + errno, strerror(errno)); + loglog(logbuffer); + } + else + loglog("Embedded IPv4 addresses enabled successfully.\n"); +#endif + + /* multicast local nodes */ + struct ipv6_mreq mreq; + memset(&mreq, 0, sizeof(mreq)); + mreq.ipv6mr_multiaddr.s6_addr[ 0] = 0xFF; + 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 if (res < 0) { - /* add log message*/ + sprintf(logbuffer, "Failed to activate local multicast membership. (%u, %s)\n", + errno, strerror(errno)); + loglog(logbuffer); } + else + loglog("Local multicast group FF02::1 joined successfully.\n"); +#endif } #endif @@ -363,6 +405,10 @@ Networking_Core *new_networking(IP ip, uint16_t port) if (!res) { temp->port = *portptr; +#ifdef LOGGING + sprintf(logbuffer, "Bound successfully to %s:%u.\n", ip_ntoa(&ip), ntohs(temp->port)); + loglog(logbuffer); +#endif return temp; } @@ -733,3 +779,17 @@ int addr_resolve_or_parse_ip(const char *address, IP *to) return 1; }; + +#ifdef LOGGING +static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res) +{ + snprintf(logbuffer, sizeof(logbuffer), "[%2u] %3u%c %s %s:%u (%u: %s) | %04x%04x\n", + buffer[0], res < 0 ? (buflen & 0xFF) : res, + res < 0 ? '-' : (res == buflen ? '=' : '+'), + message, ip_ntoa(&ip_port->ip), ntohs(ip_port->port), res < 0 ? errno : 0, + res < 0 ? strerror(errno) : "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, + buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); + logbuffer[sizeof(logbuffer) - 1] = 0; + loglog(logbuffer); +} +#endif diff --git a/toxcore/network.h b/toxcore/network.h index 0d31ffac..e804379d 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -119,6 +119,7 @@ typedef struct { } IPAny_Port; #undef TOX_ENABLE_IPV6 +/* #define TOX_ENABLE_IPV6 */ #ifdef TOX_ENABLE_IPV6 #define TOX_ENABLE_IPV6_DEFAULT 1 typedef IPAny IP; diff --git a/toxcore/tox.h b/toxcore/tox.h index 44eba081..15bef94c 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -26,6 +26,22 @@ #include +#ifdef WIN32 +#ifndef WINVER +//Windows XP +#define WINVER 0x0501 +#endif + +#include +#include +#include + +#else + +#include + +#endif + #ifdef __cplusplus extern "C" { #endif @@ -71,6 +87,7 @@ typedef struct { } tox_IPAny_Port; #undef TOX_ENABLE_IPV6 +/* #define TOX_ENABLE_IPV6 */ #ifdef TOX_ENABLE_IPV6 #define TOX_ENABLE_IPV6_DEFAULT 1 typedef tox_IPAny tox_IP; diff --git a/toxcore/util.c b/toxcore/util.c index ff366a07..19d464d4 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -10,11 +10,12 @@ #endif #include -#include -#include +/* for CLIENT_ID_SIZE */ #include "DHT.h" +#include "util.h" + uint64_t now() { return time(NULL); @@ -41,3 +42,30 @@ void id_cpy(uint8_t *dest, uint8_t *src) { memcpy(dest, src, CLIENT_ID_SIZE); } + +#ifdef LOGGING +char logbuffer[512]; +static FILE *logfile = NULL; +void loginit(uint16_t port) +{ + if (logfile) + fclose(logfile); + + sprintf(logbuffer, "%u-%u.log", ntohs(port), now); + logfile = fopen(logbuffer, "w"); +}; +void loglog(char *text) +{ + if (logfile) { + fprintf(logfile, text); + fflush(logfile); + } +}; +void logexit() +{ + if (logfile) { + fclose(logfile); + logfile = NULL; + } +}; +#endif diff --git a/toxcore/util.h b/toxcore/util.h index 7dea3eac..20731a05 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -5,7 +5,24 @@ * Copyright 2013 plutooo */ +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include +#include + uint64_t now(); uint64_t random_64b(); bool id_eq(uint8_t *dest, uint8_t *src); void id_cpy(uint8_t *dest, uint8_t *src); + +#undef LOGGING +// #define LOGGING +#ifdef LOGGING +extern char logbuffer[512]; +void loginit(uint16_t port); +void loglog(char *text); +void logexit(); +#endif + +#endif /* __UTIL_H__ */ -- cgit v1.2.3 From e89dda5cea04f217d7981d567de963cc8f2e76c7 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Tue, 10 Sep 2013 21:36:58 +0200 Subject: DHT.c: - client_in_list: split loop in two to avoid inserting a client_id duplicate - final pieces for IPv6 expansion: (handle_)sendnodes_ex(), called from hande_getnodes() resp. handler callback --- toxcore/DHT.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 7 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index a4734747..7663b1cc 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -137,19 +137,23 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id uint32_t i; uint64_t temp_time = unix_time(); - for (i = 0; i < length; ++i) { - /* If ip_port is assigned to a different client_id replace it */ - if (ipport_equal(&list[i].ip_port, &ip_port)) { - memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); + /* 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. */ + list[i].timestamp = temp_time; + list[i].ip_port = ip_port; + return 1; } - if (id_equal(list[i].client_id, client_id)) { + /* client_id not in list yet: find ip_port to overwrite */ + for (i = 0; i < length; ++i) + if (ipport_equal(&list[i].ip_port, &ip_port)) { /* Refresh the client timestamp. */ list[i].timestamp = temp_time; - ipport_copy(&list[i].ip_port, &ip_port); + memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); return 1; } - } return 0; } @@ -610,6 +614,54 @@ 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_ex(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) +{ + /* Check if packet is going to be sent to ourself. */ + if (id_equal(public_key, dht->c->self_public_key)) + return -1; + + size_t Node_format_size = sizeof(Node_format); + uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; + + Node_format nodes_list[MAX_SENT_NODES]; + int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET6); + + if (num_nodes == 0) + return 0; + + 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); + + memcpy(plain, &ping_id, sizeof(ping_id)); + memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node_format_size); + + int len = encrypt_data( public_key, + dht->c->self_secret_key, + nonce, + plain, + sizeof(ping_id) + num_nodes * Node_format_size, + encrypt ); + + if (len == -1) + return -1; + + if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node_format_size + ENCRYPTION_PADDING) + return -1; + + data[0] = NET_PACKET_SEND_NODES_EX; + memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); + memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); + memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); + + 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) { DHT *dht = object; @@ -637,6 +689,9 @@ 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_ex(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); +#endif //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ @@ -709,6 +764,53 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 return 0; } +#ifdef TOX_ENABLE_IPV6 +static int handle_sendnodes_ex(void *object, IP_Port source, uint8_t *packet, uint32_t length) +{ + DHT *dht = object; + uint64_t ping_id; + 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); + if (length > (cid_size + Node_format_size * MAX_SENT_NODES) || + ((length - cid_size) % Node_format_size) != 0 || + (length < cid_size + Node_format_size)) + return 1; + + uint32_t num_nodes = (length - cid_size) / Node_format_size; + uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; + + int len = decrypt_data( + packet + 1, + dht->c->self_secret_key, + packet + 1 + CLIENT_ID_SIZE, + packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, + sizeof(ping_id) + num_nodes * Node_format_size + ENCRYPTION_PADDING, plain ); + + if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node_format_size) + return 1; + + memcpy(&ping_id, plain, sizeof(ping_id)); + + if (!is_gettingnodes(dht, source, ping_id)) + return 1; + + uint32_t i; + Node_format nodes_list[MAX_SENT_NODES]; + memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); + + addto_lists(dht, source, packet + 1); + + for (i = 0; i < num_nodes; ++i) { + send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id); + returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); + } + + return 0; +} +#endif + /*----------------------------------------------------------------------------------*/ /*------------------------END of packet handling functions--------------------------*/ @@ -1293,6 +1395,9 @@ DHT *new_DHT(Net_Crypto *c) networking_registerhandler(c->lossless_udp->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, temp); networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, temp); networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, temp); +#ifdef TOX_ENABLE_IPV6 + networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_EX, &handle_sendnodes_ex, temp); +#endif init_cryptopackets(temp); cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, temp); return temp; -- cgit v1.2.3 From 64ca4b5db23dbb68d1b01e307837c9fb89283256 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Tue, 10 Sep 2013 22:59:33 +0200 Subject: tox.*, DHT.*: - return to the caller if the string could be resolved into an IP other/DHT_bootstrap.c, testing/*_test.c, testing/nTox.c: - parse cmdline for --ipv4/--ipv6 switch to allow user a choice util.h: - proper old-style C-comment --- other/DHT_bootstrap.c | 51 +++++++++++++++++++++++---- testing/DHT_test.c | 52 +++++++++++++++++++++++----- testing/Lossless_UDP_testclient.c | 48 ++++++++++++++++++++----- testing/Lossless_UDP_testserver.c | 41 ++++++++++++++++++---- testing/Messenger_test.c | 55 ++++++++++++++++++++++++----- testing/nTox.c | 73 +++++++++++++++++++++++++++------------ toxcore/DHT.c | 5 ++- toxcore/DHT.h | 3 +- toxcore/tox.c | 4 +-- toxcore/tox.h | 4 +-- toxcore/util.h | 2 +- 11 files changed, 270 insertions(+), 68 deletions(-) diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 7355ca10..795e24ac 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -81,11 +81,44 @@ void manage_keys(DHT *dht) int main(int argc, char *argv[]) { - /* let use decide by cmdline: TODO */ - uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; + if (argc == 2 && !strncasecmp(argv[1], "-h", 3)) { + printf("Usage (connected) : %s [--ipv4|--ipv6] IP PORT KEY\n", argv[0]); + printf("Usage (unconnected): %s [--ipv4|--ipv6]\n", argv[0]); + exit(0); + } + + /* let user override default by cmdline */ + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ + + int argvoffset = 0, 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') + ipv6enabled = 1; + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + } + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + + if (argvoffset != argi - 1) { + printf("Argument must come first: %s.\n", argv[argi]); + exit(1); + } + + argvoffset++; + } /* Initialize networking - - Bind to ip 0.0.0.0:PORT */ + Bind to ip 0.0.0.0 / [::] : PORT */ IP ip; ip_init(&ip, ipv6enabled); @@ -112,11 +145,17 @@ int main(int argc, char *argv[]) perror("Initialization."); - if (argc > 3) { + if (argc > argvoffset + 3) { printf("Trying to bootstrap into the network...\n"); - uint8_t *bootstrap_key = hex_string_to_bin(argv[3]); - DHT_bootstrap_ex(dht, argv[1], ipv6enabled, htons(atoi(argv[2])), bootstrap_key); + uint16_t port = htons(atoi(argv[argvoffset + 2])); + uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); + int res = DHT_bootstrap_ex(dht, argv[argvoffset + 1], 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); + } } int is_waiting_for_dht_connection = 1; diff --git a/testing/DHT_test.c b/testing/DHT_test.c index caa0cde2..61762162 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c @@ -133,8 +133,40 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port) int main(int argc, char *argv[]) { - /* let use decide by cmdline: TODO */ - uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; + if (argc < 4) { + printf("Usage: %s [--ipv4|--ipv6] ip port public_key\n", argv[0]); + exit(0); + } + + /* let user override default by cmdline */ + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ + + int argvoffset = 0, 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') + ipv6enabled = 1; + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + } + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + + if (argvoffset != argi - 1) { + printf("Argument must come first: %s.\n", argv[argi]); + exit(1); + } + + argvoffset++; + } //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); /* initialize networking */ @@ -144,11 +176,6 @@ int main(int argc, char *argv[]) DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); - if (argc < 4) { - printf("usage %s ip port public_key\n", argv[0]); - exit(0); - } - new_keys(dht->c); printf("OUR ID: "); uint32_t i; @@ -168,9 +195,16 @@ int main(int argc, char *argv[]) DHT_addfriend(dht, hex_string_to_bin(temp_id)); - perror("Initialization"); - DHT_bootstrap_ex(dht, argv[1], ipv6enabled, htons(atoi(argv[2])), hex_string_to_bin(argv[3])); + + uint16_t port = htons(atoi(argv[argvoffset + 2])); + unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]); + int res = DHT_bootstrap_ex(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; + } /* IP_Port ip_port; diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c index 564b2ecf..5d4c8547 100644 --- a/testing/Lossless_UDP_testclient.c +++ b/testing/Lossless_UDP_testclient.c @@ -151,21 +151,50 @@ void printconnection(int connection_id) int main(int argc, char *argv[]) { - /* let use decide by cmdline: TODO */ - uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; + /* let user override default by cmdline */ + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ + + int argvoffset = 0, 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') + ipv6enabled = 1; + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + } + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + + if (argvoffset != argi - 1) { + printf("Argument must come first: %s.\n", argv[argi]); + exit(1); + } - if (argc < 4) { - printf("usage: %s ip port filename\n", argv[0]); + argvoffset++; + } + + if (argc < argvoffset + 4) { + printf("Usage: %s [--ipv4|--ipv6] ip port filename\n", argv[0]); exit(0); } uint8_t buffer[512]; int read; - FILE *file = fopen(argv[3], "rb"); + FILE *file = fopen(argv[argvoffset + 3], "rb"); - if (file == NULL) + if (file == NULL) { + printf("Failed to open file \"%s\".\n", argv[argvoffset + 3]); return 1; + } /* initialize networking */ @@ -178,8 +207,11 @@ int main(int argc, char *argv[]) IP_Port serverip; ip_init(&serverip.ip, ipv6enabled); - addr_resolve(argv[1], &serverip.ip); - serverip.port = htons(atoi(argv[2])); + if (!addr_resolve(argv[argvoffset + 1], &serverip.ip)) { + printf("Failed to convert \"%s\" into an IP address.\n", argv[argvoffset + 1]); + return 1; + } + serverip.port = htons(atoi(argv[argvoffset + 2])); printip(serverip); int connection = new_connection(ludp, serverip); diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c index 3e54e9be..52dbcc80 100644 --- a/testing/Lossless_UDP_testserver.c +++ b/testing/Lossless_UDP_testserver.c @@ -147,21 +147,50 @@ void printconnection(int connection_id) int main(int argc, char *argv[]) { - /* let use decide by cmdline: TODO */ - uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; + /* let user override default by cmdline */ + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ + + int argvoffset = 0, 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') + ipv6enabled = 1; + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + } + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + + if (argvoffset != argi - 1) { + printf("Argument must come first: %s.\n", argv[argi]); + exit(1); + } - if (argc < 2) { - printf("usage: %s filename\n", argv[0]); + argvoffset++; + } + + if (argc < argvoffset + 2) { + printf("Usage: %s [--ipv4|--ipv6] filename\n", argv[0]); exit(0); } uint8_t buffer[512]; int read; - FILE *file = fopen(argv[1], "wb"); + FILE *file = fopen(argv[argvoffset + 1], "wb"); - if (file == NULL) + if (file == NULL) { + printf("Failed to open file \"%s\".\n", argv[argvoffset + 1]); return 1; + } //initialize networking diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index 73d44efb..e7a75c8c 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -95,13 +95,44 @@ void print_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t len int main(int argc, char *argv[]) { - if (argc < 4 && argc != 2) { - printf("usage %s ip port public_key (of the DHT bootstrap node)\n or\n %s Save.bak\n", argv[0], argv[0]); + /* let user override default by cmdline */ + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ + + int argvoffset = 0, 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') + ipv6enabled = 1; + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + } + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + + if (argvoffset != argi - 1) { + printf("Argument must come first: %s.\n", argv[argi]); + exit(1); + } + + argvoffset++; + } + + /* with optional --ipvx, now it can be 1-4 arguments... */ + if ((argc != argvoffset + 2) && (argc != argvoffset + 4)) { + printf("Usage: %s [--ipv4|--ipv6] ip port public_key (of the DHT bootstrap node)\n", argv[0]); + printf("or\n"); + printf(" %s [--ipv4|--ipv6] Save.bak (to read Save.bak as state file)\n", argv[0], argv[0]); exit(0); } - /* IPv6: maybe allow from cmdline --ipv6? sticking to IPv4 for now */ - uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; m = initMessenger(ipv6enabled); if ( !m ) { @@ -109,13 +140,19 @@ int main(int argc, char *argv[]) exit(0); } - if (argc > 3) { - uint16_t port = htons(atoi(argv[2])); - DHT_bootstrap_ex(m->dht, argv[1], ipv6enabled, port, hex_string_to_bin(argv[3])); + if (argc == argvoffset + 4) { + uint16_t port = htons(atoi(argv[argvoffset + 2])); + uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); + int res = DHT_bootstrap_ex(m->dht, argv[argvoffset + 1], 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[1], "rb"); - + 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/nTox.c b/testing/nTox.c index 6084aeda..6eeec5d3 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -537,8 +537,40 @@ void print_help(void) int main(int argc, char *argv[]) { - /* let use decide by cmdline: TODO */ - uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; + if (argc < 4) { + printf("Usage: %s [--ipv4|--ipv6] IP PORT KEY [-f keyfile]\n", argv[0]); + exit(0); + } + + /* let user override default by cmdline */ + uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ + + int argvoffset = 0, 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') + ipv6enabled = 1; + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + } + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + exit(1); + } + + if (argvoffset != argi - 1) { + printf("Argument must come first: %s.\n", argv[argi]); + exit(1); + } + + argvoffset++; + } int on = 0; int c = 0; @@ -547,27 +579,16 @@ int main(int argc, char *argv[]) char idstring[200] = {0}; Tox *m; - if (argc < 4) { - printf("[!] Usage: %s [IP] [port] [public_key] \n", argv[0]); + if ((argc == 2) && !strcmp(argv[1], "-h")) { + print_help(); exit(0); } - for (i = 0; i < argc; i++) { - if (argv[i] == NULL) { - break; - } else if (argv[i][0] == '-') { - if (argv[i][1] == 'h') { - print_help(); - exit(0); - } else if (argv[i][1] == 'f') { - if (argv[i + 1] != NULL) - filename = argv[i + 1]; - else { - fputs("[!] you passed '-f' without giving an argument!\n", stderr); - } - } - } - } + /* [-f keyfile] MUST be last two arguments, no point in walking over the list + * especially not a good idea to accept it anywhere in the middle */ + if (argc > argvoffset + 3) + if (!strcmp(argv[argc - 2], "-f")) + filename = argv[argc - 1]; m = tox_new_ex(ipv6enabled); @@ -593,11 +614,17 @@ int main(int argc, char *argv[]) new_lines(idstring); strcpy(line, ""); - uint16_t port = htons(atoi(argv[2])); - unsigned char *binary_string = hex_string_to_bin(argv[3]); - tox_bootstrap_ex(m, argv[1], ipv6enabled, port, binary_string); + uint16_t port = htons(atoi(argv[argvoffset + 2])); + unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]); + int res = tox_bootstrap_ex(m, 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]); + endwin(); + exit(1); + } + nodelay(stdscr, TRUE); while (1) { if (on == 0 && tox_isconnected(m)) { diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 7663b1cc..1798ea1a 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -978,14 +978,17 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) getnodes(dht, ip_port, public_key, dht->c->self_public_key); send_ping_request(dht->ping, dht->c, ip_port, public_key); } -void DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) +int DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) { IP_Port ip_port; ip_init(&ip_port.ip, ipv6enabled); if (addr_resolve_or_parse_ip(address, &ip_port.ip)) { ip_port.port = port; DHT_bootstrap(dht, ip_port, public_key); + return 1; } + else + return 0; } /* Send the given packet to node with client_id diff --git a/toxcore/DHT.h b/toxcore/DHT.h index d980f269..90b76a2f 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -157,9 +157,10 @@ void do_DHT(DHT *dht); /* Use this function to bootstrap the client. * Sends a get nodes request to the given node with ip port and public_key. + * DHT_bootstrap_ex() returns 1 if the address could be converted, 0 otherwise */ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key); -void DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key); +int DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, 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/tox.c b/toxcore/tox.c index 6417b16a..5e3893ec 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -374,11 +374,11 @@ void tox_bootstrap(void *tox, IP_Port ip_port, uint8_t *public_key) Messenger *m = tox; DHT_bootstrap(m->dht, ip_port, public_key); } -void tox_bootstrap_ex(void *tox, const char *address, uint8_t ipv6enabled, +int tox_bootstrap_ex(void *tox, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) { Messenger *m = tox; - DHT_bootstrap_ex(m->dht, address, ipv6enabled, port, public_key); + return DHT_bootstrap_ex(m->dht, address, ipv6enabled, port, public_key); }; /* return 0 if we are not connected to the DHT. diff --git a/toxcore/tox.h b/toxcore/tox.h index 15bef94c..cf5d6b2a 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -340,10 +340,10 @@ void tox_callback_connectionstatus(Tox *tox, void (*function)(Tox *tox, int, uin /* Use this function to bootstrap the client. * Sends a get nodes request to the given node with ip port and public_key. - * tox_bootstrap_ex converts the address into an IP_Port structure internally + * tox_bootstrap_ex() returns 1 if the address could be converted, 0 otherwise */ void tox_bootstrap(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key); -void tox_bootstrap_ex(Tox *tox, const char *address, uint8_t ipv6enabled, +int tox_bootstrap_ex(Tox *tox, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key); /* return 0 if we are not connected to the DHT. diff --git a/toxcore/util.h b/toxcore/util.h index 20731a05..71be84ca 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -17,7 +17,7 @@ bool id_eq(uint8_t *dest, uint8_t *src); void id_cpy(uint8_t *dest, uint8_t *src); #undef LOGGING -// #define LOGGING +/* #define LOGGING */ #ifdef LOGGING extern char logbuffer[512]; void loginit(uint16_t port); -- cgit v1.2.3 From 4cf0d857bcf87ba271178e7b1734958fb93b018a Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Wed, 11 Sep 2013 00:14:20 +0200 Subject: cmdline parsing of --ipv4/6 plucked into util --- other/DHT_bootstrap.c | 30 +++--------------------------- testing/DHT_test.c | 30 +++--------------------------- testing/Lossless_UDP_testclient.c | 30 +++--------------------------- testing/Lossless_UDP_testserver.c | 30 +++--------------------------- testing/Messenger_test.c | 30 +++--------------------------- testing/nTox.c | 30 +++--------------------------- toxcore/util.c | 32 ++++++++++++++++++++++++++++++++ toxcore/util.h | 2 ++ 8 files changed, 52 insertions(+), 162 deletions(-) diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 795e24ac..099aad80 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -89,33 +89,9 @@ int main(int argc, char *argv[]) /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ - - int argvoffset = 0, 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') - ipv6enabled = 1; - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - } - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - - if (argvoffset != argi - 1) { - printf("Argument must come first: %s.\n", argv[argi]); - exit(1); - } - - argvoffset++; - } + int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) + exit(1); /* Initialize networking - Bind to ip 0.0.0.0 / [::] : PORT */ diff --git a/testing/DHT_test.c b/testing/DHT_test.c index 61762162..ba8c2f23 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c @@ -140,33 +140,9 @@ int main(int argc, char *argv[]) /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ - - int argvoffset = 0, 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') - ipv6enabled = 1; - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - } - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - - if (argvoffset != argi - 1) { - printf("Argument must come first: %s.\n", argv[argi]); - exit(1); - } - - argvoffset++; - } + int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) + exit(1); //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); /* initialize networking */ diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c index 5d4c8547..70349204 100644 --- a/testing/Lossless_UDP_testclient.c +++ b/testing/Lossless_UDP_testclient.c @@ -153,33 +153,9 @@ int main(int argc, char *argv[]) { /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ - - int argvoffset = 0, 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') - ipv6enabled = 1; - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - } - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - - if (argvoffset != argi - 1) { - printf("Argument must come first: %s.\n", argv[argi]); - exit(1); - } - - argvoffset++; - } + int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) + exit(1); if (argc < argvoffset + 4) { printf("Usage: %s [--ipv4|--ipv6] ip port filename\n", argv[0]); diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c index 52dbcc80..343a662a 100644 --- a/testing/Lossless_UDP_testserver.c +++ b/testing/Lossless_UDP_testserver.c @@ -149,33 +149,9 @@ int main(int argc, char *argv[]) { /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ - - int argvoffset = 0, 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') - ipv6enabled = 1; - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - } - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - - if (argvoffset != argi - 1) { - printf("Argument must come first: %s.\n", argv[argi]); - exit(1); - } - - argvoffset++; - } + int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) + exit(1); if (argc < argvoffset + 2) { printf("Usage: %s [--ipv4|--ipv6] filename\n", argv[0]); diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index e7a75c8c..14d9ca20 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -97,33 +97,9 @@ int main(int argc, char *argv[]) { /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ - - int argvoffset = 0, 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') - ipv6enabled = 1; - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - } - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - - if (argvoffset != argi - 1) { - printf("Argument must come first: %s.\n", argv[argi]); - exit(1); - } - - argvoffset++; - } + int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) + exit(1); /* with optional --ipvx, now it can be 1-4 arguments... */ if ((argc != argvoffset + 2) && (argc != argvoffset + 4)) { diff --git a/testing/nTox.c b/testing/nTox.c index 6eeec5d3..750970f9 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -544,33 +544,9 @@ int main(int argc, char *argv[]) /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ - - int argvoffset = 0, 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') - ipv6enabled = 1; - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - } - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - exit(1); - } - - if (argvoffset != argi - 1) { - printf("Argument must come first: %s.\n", argv[argi]); - exit(1); - } - - argvoffset++; - } + int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + if (argvoffset < 0) + exit(1); int on = 0; int c = 0; diff --git a/toxcore/util.c b/toxcore/util.c index 19d464d4..7b5ddc49 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -43,6 +43,38 @@ void id_cpy(uint8_t *dest, uint8_t *src) memcpy(dest, src, CLIENT_ID_SIZE); } +int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled) +{ + int argvoffset = 0, 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') + *ipv6enabled = 1; + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + return -1; + } + } + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + return -1; + } + + if (argvoffset != argi - 1) { + printf("Argument must come first: %s.\n", argv[argi]); + return -1; + } + + argvoffset++; + } + + return argvoffset; +}; + #ifdef LOGGING char logbuffer[512]; static FILE *logfile = NULL; diff --git a/toxcore/util.h b/toxcore/util.h index 71be84ca..e7be2d51 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -16,6 +16,8 @@ uint64_t random_64b(); bool id_eq(uint8_t *dest, uint8_t *src); void id_cpy(uint8_t *dest, uint8_t *src); +int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled); + #undef LOGGING /* #define LOGGING */ #ifdef LOGGING -- cgit v1.2.3 From 5869057aba3226bf6d1f996fbd3ba80c97ef359e Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Wed, 11 Sep 2013 00:44:05 +0200 Subject: network.c: - reset errno from failed bind() calls if the last one succeeds DHT_bootstrap.c: - move the perror() output next to where it belongs to --- other/DHT_bootstrap.c | 4 ++-- toxcore/network.c | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 63cb1b75..f5fa9818 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -102,6 +102,8 @@ int main(int argc, char *argv[]) ip_init(&ip, ipv6enabled); DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); + perror("Initialization"); + manage_keys(dht); printf("Public key: "); uint32_t i; @@ -122,8 +124,6 @@ int main(int argc, char *argv[]) printf("\n"); printf("Port: %u\n", PORT); - perror("Initialization."); - if (argc > argvoffset + 3) { printf("Trying to bootstrap into the network...\n"); uint16_t port = htons(atoi(argv[argvoffset + 2])); diff --git a/toxcore/network.c b/toxcore/network.c index 0b5eba61..7eacd0ca 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -211,7 +211,7 @@ void networking_poll(Networking_Core *net) } } -uint8_t at_startup_ran; +uint8_t at_startup_ran = 0; static int at_startup(void) { if (at_startup_ran != 0) @@ -252,8 +252,10 @@ 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) + 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) @@ -287,6 +289,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)); free(temp); return NULL; } @@ -409,6 +412,12 @@ Networking_Core *new_networking(IP ip, uint16_t port) 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 */ + if (tries > 0) + errno = 0; + return temp; } -- cgit v1.2.3 From 85912418db41d692b78b6bfe7a567ee2ca24e742 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Wed, 11 Sep 2013 10:54:47 +0200 Subject: cmdline parsing: - add missing includes (autobuild warnings) --- other/DHT_bootstrap.c | 1 + testing/DHT_test.c | 1 + testing/Lossless_UDP_testclient.c | 1 + testing/Lossless_UDP_testserver.c | 1 + testing/Messenger_test.c | 1 + toxcore/DHT.c | 1 + 6 files changed, 6 insertions(+) diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index f5fa9818..f2e792ac 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -33,6 +33,7 @@ #include "../toxcore/DHT.h" #include "../toxcore/friend_requests.h" #include "../testing/misc_tools.c" +#include "../toxcore/util.h" /* Sleep function (x = milliseconds) */ #ifdef WIN32 diff --git a/testing/DHT_test.c b/testing/DHT_test.c index ba8c2f23..5451c467 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c @@ -34,6 +34,7 @@ //#include "../core/network.h" #include "../toxcore/DHT.h" #include "../toxcore/friend_requests.h" +#include "../toxcore/util.h" #include "misc_tools.c" #include diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c index 70349204..e36ac6eb 100644 --- a/testing/Lossless_UDP_testclient.c +++ b/testing/Lossless_UDP_testclient.c @@ -34,6 +34,7 @@ #include "../toxcore/network.h" #include "../toxcore/Lossless_UDP.h" +#include "../toxcore/util.h" #ifdef WIN32 diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c index 343a662a..97c3eb46 100644 --- a/testing/Lossless_UDP_testserver.c +++ b/testing/Lossless_UDP_testserver.c @@ -34,6 +34,7 @@ #include "../toxcore/network.h" #include "../toxcore/Lossless_UDP.h" +#include "../toxcore/util.h" //Sleep function (x = milliseconds) #ifdef WIN32 diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index 14d9ca20..93069226 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -43,6 +43,7 @@ #include "../toxcore/Messenger.h" #include "misc_tools.c" +#include "../toxcore/util.h" #ifdef WIN32 diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 1798ea1a..44f7f101 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -28,6 +28,7 @@ #endif #include "DHT.h" +#include "network.h" #include "ping.h" #include "misc_tools.h" -- cgit v1.2.3 From 5e076e35d92f8dc6d28060afee5160339cad11a3 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Wed, 11 Sep 2013 11:44:05 +0200 Subject: network.c: logging more details, fixing poll LAN_discovery.c: IPv6: send both v6 multicast and v4 broadcast if socket allows --- toxcore/LAN_discovery.c | 64 ++++++++++++++++++++++++++++++++++++------------- toxcore/network.c | 40 ++++++++++++++++++++++--------- 2 files changed, 76 insertions(+), 28 deletions(-) diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index 4cbe3177..933c2402 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -81,27 +81,35 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t * d #endif /* Return the broadcast ip. */ -static IP broadcast_ip(sa_family_t sa_family) +static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) { IP ip; ip_reset(&ip); #ifdef TOX_ENABLE_IPV6 - if (sa_family == AF_INET) - { - ip.family = AF_INET; - ip.ip4.uint32 = INADDR_BROADCAST; + if (family_socket == AF_INET6) { + if (family_broadcast == AF_INET6) { + ip.family = AF_INET6; + /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ + /* FE80::*: MUST be exact, for that we would need to look over all + * interfaces and check in which status they are */ + ip.ip6.s6_addr[ 0] = 0xFF; + ip.ip6.s6_addr[ 1] = 0x02; + ip.ip6.s6_addr[15] = 0x01; + } + 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; + } } - - if (sa_family == AF_INET6) - { - ip.family = AF_INET6; - /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ - /* FE80::*: MUST be exact, for that we would need to look over all - * interfaces and check in which status they are */ - ip.ip6.s6_addr[ 0] = 0xFF; - ip.ip6.s6_addr[ 1] = 0x02; - ip.ip6.s6_addr[15] = 0x01; + else if (family_socket == AF_INET) { + if (family_broadcast == AF_INET) { + ip.family = AF_INET; + ip.ip4.uint32 = INADDR_BROADCAST; + } } #else ip.uint32 = INADDR_BROADCAST; @@ -175,13 +183,35 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c) uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; data[0] = NET_PACKET_LAN_DISCOVERY; memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES); + #ifdef __linux send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES); #endif + + int res = -1; IP_Port ip_port; - ip_port.ip = broadcast_ip(c->lossless_udp->net->family); ip_port.port = port; - return sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); + +#ifdef TOX_ENABLE_IPV6 + if (c->lossless_udp->net->family == AF_INET6) { + ip_port.ip = broadcast_ip(c->lossless_udp->net->family, AF_INET6); + if (ip_isset(&ip_port.ip)) + if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES) > 0) + res = 1; + } + + ip_port.ip = broadcast_ip(c->lossless_udp->net->family, AF_INET); + if (ip_isset(&ip_port.ip)) + if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES)) + res = 1; +#else + ip_port.ip = broadcast_ip(c->lossless_udp->net->family, AF_INET); + if (ip_isset(&ip_port.ip)) + if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES)) + res = 1; +#endif + + return res; } diff --git a/toxcore/network.c b/toxcore/network.c index 7eacd0ca..8d5b25b4 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -148,12 +148,15 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t #else uint32_t addrlen = sizeof(addr); #endif + uint32_t bufflen = *length; (*(int32_t *)length) = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); if (*(int32_t *)length <= 0) { #ifdef LOGGING - if ((length < 0) && (errno != EWOULDBLOCK)) + 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. */ } @@ -184,7 +187,7 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t #endif #ifdef LOGGING - loglogdata("=>O", data, *length, ip_port, 0); + loglogdata("=>O", data, bufflen, ip_port, *length); #endif return 0; @@ -202,10 +205,12 @@ void networking_poll(Networking_Core *net) uint8_t data[MAX_UDP_PACKET_SIZE]; uint32_t length; - while (receivepacket(net->sock, &ip_port, data, &length) != -1) { - if (length < 1) continue; + while (length = sizeof(data), receivepacket(net->sock, &ip_port, data, &length) != -1) { + if (length < 1) + continue; - if (!(net->packethandlers[data[0]].function)) continue; + if (!(net->packethandlers[data[0]].function)) + continue; net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, ip_port, data, length); } @@ -792,12 +797,25 @@ int addr_resolve_or_parse_ip(const char *address, IP *to) #ifdef LOGGING static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res) { - snprintf(logbuffer, sizeof(logbuffer), "[%2u] %3u%c %s %s:%u (%u: %s) | %04x%04x\n", - buffer[0], res < 0 ? (buflen & 0xFF) : res, - res < 0 ? '-' : (res == buflen ? '=' : '+'), - message, ip_ntoa(&ip_port->ip), ntohs(ip_port->port), res < 0 ? errno : 0, - res < 0 ? strerror(errno) : "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, - buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); + 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); + 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); + 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); + logbuffer[sizeof(logbuffer) - 1] = 0; loglog(logbuffer); } -- cgit v1.2.3 From a326e851ba532756fefd9b83555be66f3c9de764 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Wed, 11 Sep 2013 12:40:54 +0200 Subject: Prettier fix to missing length initialization --- toxcore/network.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index 8d5b25b4..725ce604 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -204,16 +204,18 @@ void networking_poll(Networking_Core *net) IP_Port ip_port; uint8_t data[MAX_UDP_PACKET_SIZE]; uint32_t length; - - while (length = sizeof(data), receivepacket(net->sock, &ip_port, data, &length) != -1) { - if (length < 1) - continue; - - if (!(net->packethandlers[data[0]].function)) - continue; - - net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, ip_port, data, length); - } + int recverr; + do { + length = sizeof(data); + recverr = receivepacket(net->sock, &ip_port, data, &length); + if (!recverr && (length > 0)) { + if (!(net->packethandlers[data[0]].function)) + continue; + + net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, + ip_port, data, length); + } + } while (recverr != -1); } uint8_t at_startup_ran = 0; -- cgit v1.2.3 From d35fee43ba7fe131e9c3dcda5167a46eacbf315a Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Wed, 11 Sep 2013 15:19:39 +0200 Subject: toxcore/util.h: - moved cmdline_parsefor_ipv46() to testing/misc_tools.c --- other/DHT_bootstrap.c | 1 - testing/DHT_test.c | 1 - testing/Lossless_UDP_testclient.c | 2 +- testing/Lossless_UDP_testserver.c | 2 +- testing/Messenger_test.c | 1 - testing/misc_tools.c | 33 +++++++++++++++++++++++++++++++++ toxcore/util.c | 32 -------------------------------- toxcore/util.h | 2 -- 8 files changed, 35 insertions(+), 39 deletions(-) diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index f2e792ac..f5fa9818 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -33,7 +33,6 @@ #include "../toxcore/DHT.h" #include "../toxcore/friend_requests.h" #include "../testing/misc_tools.c" -#include "../toxcore/util.h" /* Sleep function (x = milliseconds) */ #ifdef WIN32 diff --git a/testing/DHT_test.c b/testing/DHT_test.c index 5451c467..ba8c2f23 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c @@ -34,7 +34,6 @@ //#include "../core/network.h" #include "../toxcore/DHT.h" #include "../toxcore/friend_requests.h" -#include "../toxcore/util.h" #include "misc_tools.c" #include diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c index e36ac6eb..7891ce64 100644 --- a/testing/Lossless_UDP_testclient.c +++ b/testing/Lossless_UDP_testclient.c @@ -34,7 +34,7 @@ #include "../toxcore/network.h" #include "../toxcore/Lossless_UDP.h" -#include "../toxcore/util.h" +#include "misc_tools.c" #ifdef WIN32 diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c index 97c3eb46..0fd4edd9 100644 --- a/testing/Lossless_UDP_testserver.c +++ b/testing/Lossless_UDP_testserver.c @@ -34,7 +34,7 @@ #include "../toxcore/network.h" #include "../toxcore/Lossless_UDP.h" -#include "../toxcore/util.h" +#include "misc_tools.c" //Sleep function (x = milliseconds) #ifdef WIN32 diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index 93069226..14d9ca20 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -43,7 +43,6 @@ #include "../toxcore/Messenger.h" #include "misc_tools.c" -#include "../toxcore/util.h" #ifdef WIN32 diff --git a/testing/misc_tools.c b/testing/misc_tools.c index c4dce1bb..824200d8 100644 --- a/testing/misc_tools.c +++ b/testing/misc_tools.c @@ -46,3 +46,36 @@ unsigned char *hex_string_to_bin(char hex_string[]) return val; } + + +int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled) +{ + int argvoffset = 0, 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') + *ipv6enabled = 1; + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + return -1; + } + } + else { + printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); + return -1; + } + + if (argvoffset != argi - 1) { + printf("Argument must come first: %s.\n", argv[argi]); + return -1; + } + + argvoffset++; + } + + return argvoffset; +}; diff --git a/toxcore/util.c b/toxcore/util.c index 7b5ddc49..19d464d4 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -43,38 +43,6 @@ void id_cpy(uint8_t *dest, uint8_t *src) memcpy(dest, src, CLIENT_ID_SIZE); } -int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled) -{ - int argvoffset = 0, 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') - *ipv6enabled = 1; - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - return -1; - } - } - else { - printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); - return -1; - } - - if (argvoffset != argi - 1) { - printf("Argument must come first: %s.\n", argv[argi]); - return -1; - } - - argvoffset++; - } - - return argvoffset; -}; - #ifdef LOGGING char logbuffer[512]; static FILE *logfile = NULL; diff --git a/toxcore/util.h b/toxcore/util.h index e7be2d51..71be84ca 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -16,8 +16,6 @@ uint64_t random_64b(); bool id_eq(uint8_t *dest, uint8_t *src); void id_cpy(uint8_t *dest, uint8_t *src); -int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled); - #undef LOGGING /* #define LOGGING */ #ifdef LOGGING -- cgit v1.2.3 From be716af15df6ad8459d91c5779e2598c6b85c9ca Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Wed, 11 Sep 2013 15:47:29 +0200 Subject: network.c: - undo "fixing" the wrong variable - fix the logging in receivepacket() --- toxcore/network.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index 725ce604..de69bb3a 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -148,7 +148,6 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t #else uint32_t addrlen = sizeof(addr); #endif - uint32_t bufflen = *length; (*(int32_t *)length) = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); if (*(int32_t *)length <= 0) { @@ -187,7 +186,7 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t #endif #ifdef LOGGING - loglogdata("=>O", data, bufflen, ip_port, *length); + loglogdata("=>O", data, MAX_UDP_PACKET_SIZE, ip_port, *length); #endif return 0; @@ -204,18 +203,14 @@ void networking_poll(Networking_Core *net) IP_Port ip_port; uint8_t data[MAX_UDP_PACKET_SIZE]; uint32_t length; - int recverr; - do { - length = sizeof(data); - recverr = receivepacket(net->sock, &ip_port, data, &length); - if (!recverr && (length > 0)) { - if (!(net->packethandlers[data[0]].function)) - continue; - - net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, - ip_port, data, length); - } - } while (recverr != -1); + + while (receivepacket(net->sock, &ip_port, data, &length) != -1) { + if (length < 1) continue; + + if (!(net->packethandlers[data[0]].function)) continue; + + net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, ip_port, data, length); + } } uint8_t at_startup_ran = 0; -- cgit v1.2.3 From d0f5ad34ae2cb88e921cf6f6d829d611b5ea2152 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Wed, 11 Sep 2013 16:57:26 +0200 Subject: cleanup TravisCI warnings (missing exports/extraneous args to printf) --- testing/Messenger_test.c | 2 +- toxcore/network.h | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index 14d9ca20..fdcd3061 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) if ((argc != argvoffset + 2) && (argc != argvoffset + 4)) { printf("Usage: %s [--ipv4|--ipv6] ip port public_key (of the DHT bootstrap node)\n", argv[0]); printf("or\n"); - printf(" %s [--ipv4|--ipv6] Save.bak (to read Save.bak as state file)\n", argv[0], argv[0]); + printf(" %s [--ipv4|--ipv6] Save.bak (to read Save.bak as state file)\n", argv[0]); exit(0); } diff --git a/toxcore/network.h b/toxcore/network.h index e804379d..aa0c4661 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -136,6 +136,14 @@ typedef IP4_Port IP_Port; */ const char *ip_ntoa(IP *ip); +/* ip_equal + * compares two IPAny structures + * unset means unequal + * + * returns 0 when not equal or when uninitialized + */ +int ip_equal(IP *a, IP *b); + /* ipport_equal * compares two IPAny_Port structures * unset means unequal @@ -157,6 +165,24 @@ void ip_copy(IP *target, IP *source); /* copies an ip_port structure */ void ipport_copy(IP_Port *target, IP_Port *source); +/* + * addr_resolve(): + * uses getaddrinfo to resolve an address into an IP address + * uses the first IPv4/IPv6 addresses returned by getaddrinfo + * + * input + * address: a hostname (or something parseable to an IP address) + * ip: ip.family MUST be initialized, either set to a specific IP version + * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both + * IP versions are acceptable + * + * returns in ip a valid IPAny (v4/v6), + * prefers v6 if ip.family was AF_UNSPEC and both available + * returns 0 on failure + */ + +int addr_resolve(const char *address, IP *to); + /* * addr_resolve_or_parse_ip * resolves string into an IP address -- cgit v1.2.3 From 513e37815db8319dd015bf03b588380a4e3c61d3 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Wed, 11 Sep 2013 20:50:15 +0200 Subject: tox.h, DHT.h: - tox_bootstrap_ex(), DHT_bootstrap_ex() renamed to tox_bootstrap_from_address(), DHT_bootstrap_from_address() - (handle_)sendnodes_ex() renamed to (handle_)sendnodes_ipv6() - only sending sendnodes_ipv6() if we're actually IPv6 enabled - changed comments to conform better nTox.c, Messenger_text.c, DHT_test.c, DHT_bootstrap.c: - fallout from *_ex() to *_from_address() DHT_bootstrap.c: - corrected a potentially wrong info message util.c: - fixed logfile name: now (funcptr) => now() (number) network.c: - addead comment about the necessity of bind() to succeed auto_test/messenger_test.c: - defaulting ipv6enabled to TOX_ENABLE_IPV6_DEFAULT LAN_discovery.c: - slight cleanup and comments for clarity --- auto_tests/messenger_test.c | 4 ++-- other/DHT_bootstrap.c | 5 +++-- testing/DHT_test.c | 2 +- testing/Messenger_test.c | 3 ++- testing/nTox.c | 2 +- toxcore/DHT.c | 13 ++++++++----- toxcore/DHT.h | 24 +++++++++++++++++++----- toxcore/LAN_discovery.c | 15 ++++++++------- toxcore/network.c | 14 +++++++++++++- toxcore/tox.c | 6 +++--- toxcore/tox.h | 38 +++++++++++++++++++++++++++++++++----- toxcore/util.c | 2 +- 12 files changed, 94 insertions(+), 34 deletions(-) diff --git a/auto_tests/messenger_test.c b/auto_tests/messenger_test.c index 6677c345..1b72a92f 100644 --- a/auto_tests/messenger_test.c +++ b/auto_tests/messenger_test.c @@ -278,8 +278,8 @@ int main(int argc, char *argv[]) good_id_b = hex_string_to_bin(good_id_b_str); bad_id = hex_string_to_bin(bad_id_str); - /* no IPv6 enabled yet */ - m = initMessenger(0); + /* IPv6 status from global define */ + m = initMessenger(TOX_ENABLE_IPV6_DEFAULT); /* setup a default friend and friendnum */ if (m_addfriend_norequest(m, (uint8_t *)friend_id) < 0) diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index f5fa9818..e6e8d59f 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -122,13 +122,14 @@ int main(int argc, char *argv[]) fclose(file); printf("\n"); - printf("Port: %u\n", PORT); + printf("Port: %u\n", ntohs(dht->c->lossless_udp->net->port)); if (argc > argvoffset + 3) { printf("Trying to bootstrap into the network...\n"); uint16_t port = htons(atoi(argv[argvoffset + 2])); uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); - int res = DHT_bootstrap_ex(dht, argv[argvoffset + 1], ipv6enabled, port, bootstrap_key); + int res = DHT_bootstrap_from_address(dht, argv[argvoffset + 1], + ipv6enabled, port, bootstrap_key); free(bootstrap_key); if (!res) { diff --git a/testing/DHT_test.c b/testing/DHT_test.c index ba8c2f23..9eab60de 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c @@ -175,7 +175,7 @@ int main(int argc, char *argv[]) uint16_t port = htons(atoi(argv[argvoffset + 2])); unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]); - int res = DHT_bootstrap_ex(dht, argv[argvoffset + 1], ipv6enabled, port, binary_string); + 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]); diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index fdcd3061..06f8bdbf 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -119,7 +119,8 @@ int main(int argc, char *argv[]) if (argc == argvoffset + 4) { uint16_t port = htons(atoi(argv[argvoffset + 2])); uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); - int res = DHT_bootstrap_ex(m->dht, argv[argvoffset + 1], ipv6enabled, port, bootstrap_key); + int res = DHT_bootstrap_from_address(m->dht, argv[argvoffset + 1], + ipv6enabled, port, bootstrap_key); free(bootstrap_key); if (!res) { printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]); diff --git a/testing/nTox.c b/testing/nTox.c index 750970f9..9cfa3687 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -592,7 +592,7 @@ int main(int argc, char *argv[]) uint16_t port = htons(atoi(argv[argvoffset + 2])); unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]); - int res = tox_bootstrap_ex(m, argv[argvoffset + 1], ipv6enabled, port, binary_string); + int res = tox_bootstrap_from_address(m, argv[argvoffset + 1], ipv6enabled, port, binary_string); free(binary_string); if (!res) { diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 44f7f101..96bfd663 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -617,7 +617,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl #ifdef TOX_ENABLE_IPV6 /* Send a send nodes response: message for IPv6 nodes */ -static int sendnodes_ex(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) +static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) { /* Check if packet is going to be sent to ourself. */ if (id_equal(public_key, dht->c->self_public_key)) @@ -691,7 +691,9 @@ 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_ex(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); + /* only try to send IPv6 nodes if the ipv6enabled flag was given */ + if (dht->c->lossless_udp->net->family == AF_INET6) + sendnodes_ipv6(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); #endif //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ @@ -766,7 +768,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 } #ifdef TOX_ENABLE_IPV6 -static int handle_sendnodes_ex(void *object, IP_Port source, uint8_t *packet, uint32_t length) +static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length) { DHT *dht = object; uint64_t ping_id; @@ -979,7 +981,8 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) getnodes(dht, ip_port, public_key, dht->c->self_public_key); send_ping_request(dht->ping, dht->c, ip_port, public_key); } -int DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) +int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, + uint16_t port, uint8_t *public_key) { IP_Port ip_port; ip_init(&ip_port.ip, ipv6enabled); @@ -1400,7 +1403,7 @@ DHT *new_DHT(Net_Crypto *c) networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, temp); networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, temp); #ifdef TOX_ENABLE_IPV6 - networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_EX, &handle_sendnodes_ex, temp); + networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_EX, &handle_sendnodes_ipv6, temp); #endif init_cryptopackets(temp); cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, temp); diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 90b76a2f..255074b0 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -136,7 +136,7 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id); * ip must be 4 bytes long. * port must be 2 bytes long. * - * !!! Signature changed!!! + * !!! Signature changed !!! * * OLD: IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id); * @@ -155,12 +155,26 @@ int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port); /* Run this function at least a couple times per second (It's the main loop). */ void do_DHT(DHT *dht); -/* Use this function to bootstrap the client. - * Sends a get nodes request to the given node with ip port and public_key. - * DHT_bootstrap_ex() returns 1 if the address could be converted, 0 otherwise +/* + * Use these two functions to bootstrap the client. + */ +/* Sends a "get nodes" request to the given node with ip, port and public_key + * to setup connections */ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key); -int DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key); +/* Resolves address into an IP address. If successful, sends a "get nodes" + * request to the given node with ip, port and public_key to setup connections + * + * address can be a hostname or an IP address (IPv4 or IPv6). + * 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); /* 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 933c2402..b429ea6e 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -112,7 +112,9 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) } } #else - ip.uint32 = INADDR_BROADCAST; + if (family_socket == AF_INET) + if (family_broadcast == AF_INET) + ip.uint32 = INADDR_BROADCAST; #endif return ip; @@ -193,23 +195,22 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c) ip_port.port = port; #ifdef TOX_ENABLE_IPV6 + /* IPv6 multicast */ if (c->lossless_udp->net->family == AF_INET6) { - ip_port.ip = broadcast_ip(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; } + /* 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); - if (ip_isset(&ip_port.ip)) - if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES)) - res = 1; #else - ip_port.ip = broadcast_ip(c->lossless_udp->net->family, AF_INET); + 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; -#endif return res; } diff --git a/toxcore/network.c b/toxcore/network.c index de69bb3a..b40f7d56 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -312,7 +312,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) return -1; */ - /* Enable broadcast on socket? */ + /* Enable broadcast on socket */ int broadcast = 1; setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); @@ -402,6 +402,18 @@ Networking_Core *new_networking(IP ip, uint16_t port) /* 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 + * + * if we go on without binding, the first sendto() automatically binds to + * a free port chosen by the system (i.e. anything from 1024 to 65535) + * + * returning NULL after bind fails has both advantages and disadvantages: + * advantage: + * we can rely on getting the port in the range 33445..33450, which + * enables us to tell joe user to open their firewall to a small range + * + * disadvantage: + * some clients might not test return of tox_new(), blindly assuming that + * it worked ok (which it did previously without a successful bind) */ int tries, res; for(tries = 0; tries < 9; tries++) diff --git a/toxcore/tox.c b/toxcore/tox.c index 5e3893ec..31ae9c0f 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -374,11 +374,11 @@ void tox_bootstrap(void *tox, IP_Port ip_port, uint8_t *public_key) Messenger *m = tox; DHT_bootstrap(m->dht, ip_port, public_key); } -int tox_bootstrap_ex(void *tox, const char *address, uint8_t ipv6enabled, - uint16_t port, uint8_t *public_key) +int tox_bootstrap_from_address(void *tox, const char *address, + uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) { Messenger *m = tox; - return DHT_bootstrap_ex(m->dht, address, ipv6enabled, port, public_key); + return DHT_bootstrap_from_address(m->dht, address, ipv6enabled, port, public_key); }; /* return 0 if we are not connected to the DHT. diff --git a/toxcore/tox.h b/toxcore/tox.h index cf5d6b2a..b331479e 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -338,12 +338,25 @@ void tox_callback_read_receipt(Tox *tox, void (*function)(Tox *tox, int, uint32_ */ void tox_callback_connectionstatus(Tox *tox, void (*function)(Tox *tox, int, uint8_t, void *), void *userdata); -/* Use this function to bootstrap the client. - * Sends a get nodes request to the given node with ip port and public_key. - * tox_bootstrap_ex() returns 1 if the address could be converted, 0 otherwise +/* + * Use these two functions to bootstrap the client. + */ +/* Sends a "get nodes" request to the given node with ip, port and public_key + * to setup connections */ void tox_bootstrap(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key); -int tox_bootstrap_ex(Tox *tox, const char *address, uint8_t ipv6enabled, +/* Resolves address into an IP address. If successful, sends a "get nodes" + * request to the given node with ip, port and public_key to setup connections + * + * address can be a hostname or an IP address (IPv4 or IPv6). + * 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); /* return 0 if we are not connected to the DHT. @@ -351,12 +364,27 @@ int tox_bootstrap_ex(Tox *tox, const char *address, uint8_t ipv6enabled, */ int tox_isconnected(Tox *tox); -/* Run this at startup. +/* + * Run one of the following two functions at startup. + */ +/* Initializes a tox structure + * Defaults to using ipv4 connections only. * * return allocated instance of tox on success. * return 0 if there are problems. */ Tox *tox_new(void); + +/* Initializes a tox structure + * The type of communication socket depends on ipv6enabled: + * If set to 0 (zero), creates an IPv4 socket which subsequently only allows + * IPv4 communication + * If set to anything else, creates an IPv6 socket which allows both IPv4 AND + * IPv6 communication + * + * return allocated instance of tox on success. + * return 0 if there are problems. + */ Tox *tox_new_ex(uint8_t ipv6enabled); /* Run this before closing shop. diff --git a/toxcore/util.c b/toxcore/util.c index 19d464d4..e751e9e4 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -51,7 +51,7 @@ void loginit(uint16_t port) if (logfile) fclose(logfile); - sprintf(logbuffer, "%u-%u.log", ntohs(port), now); + sprintf(logbuffer, "%u-%u.log", ntohs(port), now()); logfile = fopen(logbuffer, "w"); }; void loglog(char *text) -- cgit v1.2.3 From ef86109460bae7b92607587218131754f32be30f Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Wed, 11 Sep 2013 21:22:43 +0200 Subject: Messenger.c: - unbroke Messenger_load(): lost a length adjustment - addeditional check for enough data available --- toxcore/Messenger.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index b955ad5a..166f9779 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -1024,8 +1024,13 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) data += size; length -= size; + if (length < sizeof(size)) + return -1; + memcpy(&size, data, sizeof(size)); data += sizeof(size); + length -= sizeof(size); + if (length < size) return -1; -- cgit v1.2.3 From 5e1523e61d5f5718d98e7b5eb41f9574ac386928 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Wed, 11 Sep 2013 22:21:31 +0200 Subject: network.c: - removed almost unused variable without further use --- toxcore/network.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index b40f7d56..b00204a2 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -267,13 +267,11 @@ Networking_Core *new_networking(IP ip, uint16_t port) if (temp == NULL) return NULL; - sa_family_t family = 0; #ifdef TOX_ENABLE_IPV6 - family = ip.family; + temp->family = ip.family; #else - family = AF_INET; + temp->family = AF_INET; #endif - temp->family = family; temp->port = 0; /* Initialize our socket. */ -- cgit v1.2.3 From d017189bb6b0ed69b27d5a62879a29408180310a Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Thu, 12 Sep 2013 00:01:46 +0200 Subject: nTox.c: - don't claim "Added friend" per default, check for returned ID first - on '/q' SAVE... else everything but the keys is lost on each restart - for that, split load_key() into load_data() and save_data() - announce own nickname on startup --- testing/nTox.c | 90 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/testing/nTox.c b/testing/nTox.c index 438468bd..74702697 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -208,6 +208,9 @@ char *format_message(Tox *m, char *message, int friendnum) return msg; } +/* forward declaration */ +int save_data(Tox *m); + void line_eval(Tox *m, char *line) { if (line[0] == '/') { @@ -251,7 +254,10 @@ void line_eval(Tox *m, char *line) break; default: - sprintf(numstring, "[i] Added friend as %d.", num); + if (num >= 0) + sprintf(numstring, "[i] Added friend as %d.", num); + else + sprintf(numstring, "[i] Unknown error %i.", num); break; } @@ -355,6 +361,7 @@ void line_eval(Tox *m, char *line) } else if (inpt_command == 'q') { //exit + save_data(m); endwin(); exit(EXIT_SUCCESS); } else { @@ -476,55 +483,69 @@ void print_statuschange(Tox *m, int friendnumber, uint8_t *string, uint16_t leng } } -void load_key(Tox *m, char *path) +static char *data_file_name = NULL; + +int load_data(Tox *m) { - FILE *data_file = fopen(path, "r"); + FILE *data_file = fopen(data_file_name, "r"); int size = 0; - if (data_file) { - //load keys fseek(data_file, 0, SEEK_END); size = ftell(data_file); rewind(data_file); uint8_t data[size]; - if (fread(data, sizeof(uint8_t), size, data_file) != size) { fputs("[!] could not read data file! exiting...\n", stderr); - goto FILE_ERROR; + return 0; } tox_load(m, data, size); - } else { - //else save new keys - int size = tox_size(m); - uint8_t data[size]; - tox_save(m, data); - data_file = fopen(path, "w"); - - if (!data_file) { - perror("[!] load_key"); - exit(1); + if (fclose(data_file) < 0) { + perror("[!] fclose failed"); + return 0; } - if (fwrite(data, sizeof(uint8_t), size, data_file) != size) { - fputs("[!] could not write data file! exiting...", stderr); - goto FILE_ERROR; - } + return 1; + } + + return 0; +} + +int save_data(Tox *m) +{ + FILE *data_file = fopen(data_file_name, "w"); + if (!data_file) { + perror("[!] load_key"); + return 0; } - if (fclose(data_file) < 0) - perror("[!] fclose failed"); + int size = tox_size(m); + uint8_t data[size]; + tox_save(m, data); - return; + if (fwrite(data, sizeof(uint8_t), size, data_file) != size) { + fputs("[!] could not write data file (1)!", stderr); + return 0; + } -FILE_ERROR: + if (fclose(data_file) < 0) { + perror("[!] could not write data file (2)"); + return 0; + } +} - if (fclose(data_file) < 0) - perror("[!] fclose failed"); +int load_old_key_or_save_new_one(Tox *m, char *path) +{ + data_file_name = path; + if (load_data(m)) + return 1; + + if (save_data(m)) + return 1; - exit(1); + return 0; } void print_help(void) @@ -573,7 +594,7 @@ int main(int argc, char *argv[]) exit(0); } - load_key(m, filename); + load_old_key_or_save_new_one(m, filename); tox_callback_friendrequest(m, print_request, NULL); tox_callback_friendmessage(m, print_message, NULL); @@ -604,9 +625,18 @@ int main(int argc, char *argv[]) free(binary_string); nodelay(stdscr, TRUE); + new_lines("[i] change username with /n"); + char name[TOX_MAX_NAME_LENGTH]; + uint16_t namelen = tox_getselfname(m, name, sizeof(name)); + if (namelen > 0) { + char whoami[128 + TOX_MAX_NAME_LENGTH]; + snprintf(whoami, sizeof(whoami), "[i] your current username is: %s", name); + new_lines(whoami); + } + while (1) { if (on == 0 && tox_isconnected(m)) { - new_lines("[i] connected to DHT\n[i] define username with /n"); + new_lines("[i] connected to DHT"); on = 1; } -- cgit v1.2.3 From 20f865521a6c3dafae85533a490c483621440e73 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Thu, 12 Sep 2013 14:19:22 +0200 Subject: nTox.c: - correct a message who claims we're going to exit when we actually aren't - don't treat a failed close on reading the data file as failure of the reading --- testing/nTox.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testing/nTox.c b/testing/nTox.c index 74702697..9f6d8233 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -496,7 +496,7 @@ int load_data(Tox *m) uint8_t data[size]; if (fread(data, sizeof(uint8_t), size, data_file) != size) { - fputs("[!] could not read data file! exiting...\n", stderr); + fputs("[!] could not read data file!\n", stderr); return 0; } @@ -504,7 +504,8 @@ int load_data(Tox *m) if (fclose(data_file) < 0) { perror("[!] fclose failed"); - return 0; + /* we got it open and the expected data read... let it be ok */ + /* return 0; */ } return 1; -- cgit v1.2.3 From a74cfaea81fecb11a6f56e069d59b8ea68dd98a8 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Thu, 12 Sep 2013 15:42:03 +0200 Subject: tox.h: - #define'd tox's network port (as range) - finally killed tox_new_ex() in favor of changing tox_new()'s signature - renamed tox_bootstrap() to tox_bootstrap_from_ip() network.h: - #define'd tox's network port (as range) - renamed SEND_NODES_EX to SEND_NODES_IPV6 - bind() loop uses #define'd port range DHT.c: - renamed SEND_NODES_EX to SEND_NODES_IPV6 - sending ipv6 node addresses even if can't use them ourselves nTox.c: - adapted to changed tox_new() --- testing/nTox.c | 2 +- toxcore/DHT.c | 8 +++----- toxcore/network.c | 17 +++++++++++------ toxcore/network.h | 5 ++++- toxcore/tox.c | 4 ++-- toxcore/tox.h | 26 +++++++++++--------------- 6 files changed, 32 insertions(+), 30 deletions(-) diff --git a/testing/nTox.c b/testing/nTox.c index 9cfa3687..1e83f507 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -566,7 +566,7 @@ int main(int argc, char *argv[]) if (!strcmp(argv[argc - 2], "-f")) filename = argv[argc - 1]; - m = tox_new_ex(ipv6enabled); + m = tox_new(ipv6enabled); if ( !m ) { fputs("Failed to allocate Messenger datastructure", stderr); diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 96bfd663..3de7b6ae 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -654,7 +654,7 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_ if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node_format_size + ENCRYPTION_PADDING) return -1; - data[0] = NET_PACKET_SEND_NODES_EX; + data[0] = NET_PACKET_SEND_NODES_IPV6; memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); @@ -691,9 +691,7 @@ 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 - /* only try to send IPv6 nodes if the ipv6enabled flag was given */ - if (dht->c->lossless_udp->net->family == AF_INET6) - sendnodes_ipv6(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); + sendnodes_ipv6(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); #endif //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ @@ -1403,7 +1401,7 @@ DHT *new_DHT(Net_Crypto *c) networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, temp); networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, temp); #ifdef TOX_ENABLE_IPV6 - networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_EX, &handle_sendnodes_ipv6, temp); + networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, temp); #endif init_cryptopackets(temp); cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, temp); diff --git a/toxcore/network.c b/toxcore/network.c index b00204a2..c0bd366d 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -213,6 +213,7 @@ void networking_poll(Networking_Core *net) } } + uint8_t at_startup_ran = 0; static int at_startup(void) { @@ -342,7 +343,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) addrsize = sizeof(struct sockaddr_in); struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; addr4->sin_family = AF_INET; - addr4->sin_port = htons(port); + addr4->sin_port = 0; addr4->sin_addr = ip4.in_addr; portptr = &addr4->sin_port; @@ -353,7 +354,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) addrsize = sizeof(struct sockaddr_in6); struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; addr6->sin6_family = AF_INET6; - addr6->sin6_port = htons(port); + addr6->sin6_port = 0; addr6->sin6_addr = ip.ip6; addr6->sin6_flowinfo = 0; @@ -413,8 +414,10 @@ Networking_Core *new_networking(IP ip, uint16_t port) * some clients might not test return of tox_new(), blindly assuming that * it worked ok (which it did previously without a successful bind) */ + uint16_t port_to_try = port; + *portptr = htons(port_to_try); int tries, res; - for(tries = 0; tries < 9; tries++) + for(tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++) { res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); if (!res) @@ -433,9 +436,11 @@ Networking_Core *new_networking(IP ip, uint16_t port) return temp; } - uint16_t port = ntohs(*portptr); - port++; - *portptr = htons(port); + port_to_try++; + if (port_to_try > TOX_PORTRANGE_TO) + port_to_try = TOX_PORTRANGE_FROM; + + *portptr = htons(port_to_try); } fprintf(stderr, "Failed to bind socket: %u, %s (IP/Port: %s:%u\n", errno, diff --git a/toxcore/network.h b/toxcore/network.h index aa0c4661..5bc04632 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -72,13 +72,16 @@ typedef int sock_t; #define NET_PACKET_PING_RESPONSE 1 /* Ping response packet ID. */ #define NET_PACKET_GET_NODES 2 /* Get nodes request packet ID. */ #define NET_PACKET_SEND_NODES 3 /* Send nodes response packet ID for IPv4 addresses. */ -#define NET_PACKET_SEND_NODES_EX 4 /* Send nodes response packet ID for other addresses. */ +#define NET_PACKET_SEND_NODES_IPV6 4 /* Send nodes response packet ID for other addresses. */ #define NET_PACKET_HANDSHAKE 16 /* Handshake packet ID. */ #define NET_PACKET_SYNC 17 /* SYNC packet ID. */ #define NET_PACKET_DATA 18 /* Data packet ID. */ #define NET_PACKET_CRYPTO 32 /* Encrypted data packet ID. */ #define NET_PACKET_LAN_DISCOVERY 33 /* LAN discovery packet ID. */ +#define TOX_PORTRANGE_FROM 33445 +#define TOX_PORTRANGE_TO 33455 +#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM /* Current time, unix format */ #define unix_time() ((uint64_t)time(NULL)) diff --git a/toxcore/tox.c b/toxcore/tox.c index 31ae9c0f..f5c6c8ba 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -366,10 +366,10 @@ void tox_callback_connectionstatus(void *tox, void (*function)(Messenger *tox, i m_callback_connectionstatus(m, function, userdata); } -/* Use this function to bootstrap the client. +/* Use these functions to bootstrap the client. * Sends a get nodes request to the given node with ip port and public_key. */ -void tox_bootstrap(void *tox, IP_Port ip_port, uint8_t *public_key) +void tox_bootstrap_from_ip(void *tox, IP_Port ip_port, uint8_t *public_key) { Messenger *m = tox; DHT_bootstrap(m->dht, ip_port, public_key); diff --git a/toxcore/tox.h b/toxcore/tox.h index b331479e..2fddfab4 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -52,8 +52,12 @@ extern "C" { #define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) +#define TOX_PORTRANGE_FROM 33445 +#define TOX_PORTRANGE_TO 33455 +#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM + typedef union { - uint8_t c[4]; + uint8_t c[4]; uint16_t s[2]; uint32_t i; } tox_IP4; @@ -71,7 +75,7 @@ typedef struct { typedef union { struct { - tox_IP4 ip; + tox_IP4 ip; uint16_t port; /* Not used for anything right now. */ uint16_t padding; @@ -83,7 +87,7 @@ typedef union { * removed the unused union and padding also */ typedef struct { tox_IPAny ip; - uint16_t port; + uint16_t port; } tox_IPAny_Port; #undef TOX_ENABLE_IPV6 @@ -344,7 +348,7 @@ void tox_callback_connectionstatus(Tox *tox, void (*function)(Tox *tox, int, uin /* Sends a "get nodes" request to the given node with ip, port and public_key * to setup connections */ -void tox_bootstrap(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key); +void tox_bootstrap_from_ip(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key); /* Resolves address into an IP address. If successful, sends a "get nodes" * request to the given node with ip, port and public_key to setup connections * @@ -365,17 +369,9 @@ int tox_bootstrap_from_address(Tox *tox, const char *address, uint8_t ipv6enable int tox_isconnected(Tox *tox); /* - * Run one of the following two functions at startup. - */ -/* Initializes a tox structure - * Defaults to using ipv4 connections only. + * Run this function at startup. * - * return allocated instance of tox on success. - * return 0 if there are problems. - */ -Tox *tox_new(void); - -/* Initializes a tox structure + * Initializes a tox structure * The type of communication socket depends on ipv6enabled: * If set to 0 (zero), creates an IPv4 socket which subsequently only allows * IPv4 communication @@ -385,7 +381,7 @@ Tox *tox_new(void); * return allocated instance of tox on success. * return 0 if there are problems. */ -Tox *tox_new_ex(uint8_t ipv6enabled); +Tox *tox_new(uint8_t ipv6enabled); /* Run this before closing shop. * Free all datastructures. */ -- cgit v1.2.3 From 0cfbe004ef30e5a601f965e625ab42a490e13e15 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Thu, 12 Sep 2013 16:07:51 +0200 Subject: Messenger.c: - remove local PORT definition in favor of TOX_PORT_DEFAULT --- toxcore/Messenger.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 166f9779..1b276602 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -639,13 +639,12 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint /* Interval in seconds between LAN discovery packet sending. */ #define LAN_DISCOVERY_INTERVAL 60 -#define PORT 33445 /* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */ static void LANdiscovery(Messenger *m) { if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) { - send_LANdiscovery(htons(PORT), m->net_crypto); + send_LANdiscovery(TOX_PORT_DEFAULT, m->net_crypto); m->last_LANdiscovery = unix_time(); } } @@ -660,7 +659,7 @@ Messenger *initMessenger(uint8_t ipv6enabled) IP ip; ip_init(&ip, ipv6enabled); - m->net = new_networking(ip, PORT); + m->net = new_networking(ip, TOX_PORT_DEFAULT); if (m->net == NULL) { free(m); -- cgit v1.2.3 From 591d6c70c635406830486deb561343e4dc06af2a Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Thu, 12 Sep 2013 18:39:21 +0200 Subject: network.*: - addr_resolv(_or_parse_ip)(): added an optional parameter to return both an IPv6 and an IPv4 address if requested address family was AF_UNSPEC - logging of unhandled packets DHT.c: - bootstrap_from_address(): use the additional return from addr_resolv_or_parse_ip() to bootstrap in both network types at once Lossless_UDP_testclient.c: - main(): adapt to signature change of addr_resolve() Messenger.c. LAN_discovery.h: - lost a htons(), readded - moved LAN_DISCOVERY_INTERVAL #define into LAN_discovery.h LAN_discovery.c: - added IPv4-in-IPv6 local address test --- testing/Lossless_UDP_testclient.c | 2 +- toxcore/DHT.c | 27 ++++++++++++++++++++++----- toxcore/LAN_discovery.c | 8 ++++++++ toxcore/LAN_discovery.h | 2 ++ toxcore/Messenger.c | 7 ++----- toxcore/network.c | 36 ++++++++++++++++++++++++++++-------- toxcore/network.h | 23 ++++++++++++++++------- toxcore/tox.c | 6 +----- 8 files changed, 80 insertions(+), 31 deletions(-) diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c index 7891ce64..155a412a 100644 --- a/testing/Lossless_UDP_testclient.c +++ b/testing/Lossless_UDP_testclient.c @@ -184,7 +184,7 @@ int main(int argc, char *argv[]) IP_Port serverip; ip_init(&serverip.ip, ipv6enabled); - if (!addr_resolve(argv[argvoffset + 1], &serverip.ip)) { + if (!addr_resolve(argv[argvoffset + 1], &serverip.ip, NULL)) { printf("Failed to convert \"%s\" into an IP address.\n", argv[argvoffset + 1]); return 1; } diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 3de7b6ae..a5f0c1ab 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -982,11 +982,28 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) { - IP_Port ip_port; - ip_init(&ip_port.ip, ipv6enabled); - if (addr_resolve_or_parse_ip(address, &ip_port.ip)) { - ip_port.port = port; - DHT_bootstrap(dht, ip_port, 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 + + 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 diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index b429ea6e..c50fe65d 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -159,6 +159,14 @@ static int LAN_ip(IP ip) 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))) return 0; + + /* embedded IPv4-in-IPv6 */ + if (!ip.ip6.s6_addr32[0] && !ip.ip6.s6_addr32[1] && ip.ip6.s6_addr32[2] == htonl(0xFFFF)) { + IP ip4; + ip4.family = AF_INET; + ip4.ip4.uint32 = ip.ip6.s6_addr32[3]; + return LAN_ip(ip4); + } } #endif diff --git a/toxcore/LAN_discovery.h b/toxcore/LAN_discovery.h index 78990936..a0789956 100644 --- a/toxcore/LAN_discovery.h +++ b/toxcore/LAN_discovery.h @@ -35,6 +35,8 @@ #include #endif +/* standard interval in seconds between LAN discovery packet sending. */ +#define LAN_DISCOVERY_INTERVAL 60 /* Send a LAN discovery pcaket to the broadcast address with port port. */ int send_LANdiscovery(uint16_t port, Net_Crypto *c); diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 1b276602..ae13e9d6 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -637,14 +637,11 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); } -/* Interval in seconds between LAN discovery packet sending. */ -#define LAN_DISCOVERY_INTERVAL 60 - /* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */ static void LANdiscovery(Messenger *m) { if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) { - send_LANdiscovery(TOX_PORT_DEFAULT, m->net_crypto); + send_LANdiscovery(htons(TOX_PORT_DEFAULT), m->net_crypto); m->last_LANdiscovery = unix_time(); } } @@ -1016,7 +1013,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) return -1; if (DHT_load(m->dht, data, size) == -1) - fprintf(stderr, "Data file: Something wicked happened to the stored connections.\n"); + fprintf(stderr, "Data file: Something wicked happened to the stored connections...\n"); /* go on, friends still might be intact */ diff --git a/toxcore/network.c b/toxcore/network.c index c0bd366d..39483b42 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -207,7 +207,13 @@ void networking_poll(Networking_Core *net) while (receivepacket(net->sock, &ip_port, data, &length) != -1) { if (length < 1) continue; - if (!(net->packethandlers[data[0]].function)) continue; + if (!(net->packethandlers[data[0]].function)) { +#ifdef LOGGING + sprintf(logbuffer, "[%02u] -- Packet has no handler.\n", data[0]); + loglog(logbuffer); +#endif + continue; + } net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, ip_port, data, length); } @@ -661,16 +667,18 @@ int addr_parse_ip(const char *address, IP *to) * * input * address: a hostname (or something parseable to an IP address) - * ip: ip.family MUST be initialized, either set to a specific IP version + * to: to.family MUST be initialized, either set to a specific IP version * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both * IP versions are acceptable + * extra can be NULL and is only set in special circumstances, see returns * - * returns in ip a valid IPAny (v4/v6), + * returns in *to a valid IPAny (v4/v6), * prefers v6 if ip.family was AF_UNSPEC and both available + * returns in *extra an IPv4 address, if family was AF_UNSPEC and *to is AF_INET6 * returns 0 on failure */ -int addr_resolve(const char *address, IP *to) +int addr_resolve(const char *address, IP *to, IP *extra) { if (!address || !to) return 0; @@ -772,6 +780,10 @@ int addr_resolve(const char *address, IP *to) 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) { to->family = AF_INET; @@ -794,12 +806,20 @@ int addr_resolve(const char *address, IP *to) * addr_resolve_or_parse_ip * resolves string into an IP address * - * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6) - * returns 1 on success, 0 on failure + * address: a hostname (or something parseable to an IP address) + * to: to.family MUST be initialized, either set to a specific IP version + * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both + * IP versions are acceptable + * extra can be NULL and is only set in special circumstances, see returns + * + * returns in *tro a matching address (IPv6 or IPv4) + * returns in *extra, if not NULL, an IPv4 address, if to->family was AF_UNSPEC + * returns 1 on success + * returns 0 on failure */ -int addr_resolve_or_parse_ip(const char *address, IP *to) +int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra) { - if (!addr_resolve(address, to)) + if (!addr_resolve(address, to, extra)) if (!addr_parse_ip(address, to)) return 0; diff --git a/toxcore/network.h b/toxcore/network.h index 5bc04632..6cdf300d 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -175,25 +175,34 @@ void ipport_copy(IP_Port *target, IP_Port *source); * * input * address: a hostname (or something parseable to an IP address) - * ip: ip.family MUST be initialized, either set to a specific IP version + * to: to.family MUST be initialized, either set to a specific IP version * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both * IP versions are acceptable + * extra can be NULL and is only set in special circumstances, see returns * - * returns in ip a valid IPAny (v4/v6), + * returns in *to a valid IPAny (v4/v6), * prefers v6 if ip.family was AF_UNSPEC and both available + * returns in *extra an IPv4 address, if family was AF_UNSPEC and *to is AF_INET6 * returns 0 on failure */ - -int addr_resolve(const char *address, IP *to); +int addr_resolve(const char *address, IP *to, IP *extra); /* * addr_resolve_or_parse_ip * resolves string into an IP address * - * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6) - * returns 1 on success, 0 on failure + * address: a hostname (or something parseable to an IP address) + * to: to.family MUST be initialized, either set to a specific IP version + * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both + * IP versions are acceptable + * extra can be NULL and is only set in special circumstances, see returns + * + * returns in *tro a matching address (IPv6 or IPv4) + * returns in *extra, if not NULL, an IPv4 address, if to->family was AF_UNSPEC + * returns 1 on success + * returns 0 on failure */ -int addr_resolve_or_parse_ip(const char *address, IP *to); +int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra); /* Function to receive data, ip and port of sender is put into ip_port. * Packet data is put into data. diff --git a/toxcore/tox.c b/toxcore/tox.c index f5c6c8ba..3eb80d22 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -395,14 +395,10 @@ int tox_isconnected(void *tox) * return allocated instance of tox on success. * return 0 if there are problems. */ -void *tox_new_ex(uint8_t ipv6enabled) +void *tox_new(uint8_t ipv6enabled) { return initMessenger(ipv6enabled); } -void *tox_new(void) -{ - return tox_new_ex(0); -} /* Run this before closing shop. * Free all datastructures. -- cgit v1.2.3 From ec3734fc5d0f0d81a5220cf16ad6ef8eb5f06c7c Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Fri, 13 Sep 2013 08:50:46 +0200 Subject: TOX_ENABLE_IPV6 is now #define'd per default. Added some logging and error messages. --- toxcore/DHT.c | 22 +++++++------- toxcore/Messenger.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ toxcore/network.h | 4 +-- toxcore/tox.h | 4 +-- toxcore/util.c | 3 ++ 5 files changed, 101 insertions(+), 15 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index a5f0c1ab..0b212d5b 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -31,6 +31,7 @@ #include "network.h" #include "ping.h" #include "misc_tools.h" +#include "Messenger.h" /* The number of seconds for a non responsive node to become bad. */ #define BAD_NODE_TIMEOUT 70 @@ -1459,24 +1460,24 @@ 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; + } - if ((size - sizeof(dht->close_clientlist)) % sizeof(DHT_Friend) != 0) + 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; + } uint32_t i, j; - uint16_t temp; - /* uint64_t temp_time = unix_time(); */ - Client_data *client; - - temp = (size - sizeof(dht->close_clientlist)) / sizeof(DHT_Friend); - - if (temp != 0) { + uint16_t friends_num = friendlistsize / sizeof(DHT_Friend); + if (friends_num != 0) { DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist)); - for (i = 0; i < temp; ++i) { + for (i = 0; i < friends_num; ++i) { DHT_addfriend(dht, tempfriends_list[i].client_id); for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { @@ -1489,7 +1490,6 @@ 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/Messenger.c b/toxcore/Messenger.c index 656b384b..d228fcc2 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -26,6 +26,7 @@ #endif #include "Messenger.h" +#include "util.h" #define MIN(a,b) (((a)<(b))?(a):(b)) @@ -1106,6 +1107,19 @@ void doInbound(Messenger *m) } } +#ifdef LOGGING +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; +} +#endif + /* The main loop that needs to be run at least 20 times per second. */ void doMessenger(Messenger *m) { @@ -1117,6 +1131,75 @@ void doMessenger(Messenger *m) doFriends(m); do_allgroupchats(m); LANdiscovery(m); + +#ifdef LOGGING + if (now() > lastdump + 60) { + 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); + } + } + + 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, 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, + cptr->client_id); + loglog(logbuffer); + } + } + + loglog(" = = = = = = = = \n"); + } +#endif } /* return size of the messenger data (for saving) */ diff --git a/toxcore/network.h b/toxcore/network.h index 12a48868..6d9bbfc0 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -122,8 +122,8 @@ typedef struct { uint16_t port; } IPAny_Port; -#undef TOX_ENABLE_IPV6 -/* #define TOX_ENABLE_IPV6 */ +/* #undef TOX_ENABLE_IPV6 */ +#define TOX_ENABLE_IPV6 #ifdef TOX_ENABLE_IPV6 #define TOX_ENABLE_IPV6_DEFAULT 1 typedef IPAny IP; diff --git a/toxcore/tox.h b/toxcore/tox.h index 2fddfab4..4c597250 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -90,8 +90,8 @@ typedef struct { uint16_t port; } tox_IPAny_Port; -#undef TOX_ENABLE_IPV6 -/* #define TOX_ENABLE_IPV6 */ +/* #undef TOX_ENABLE_IPV6 */ +#define TOX_ENABLE_IPV6 #ifdef TOX_ENABLE_IPV6 #define TOX_ENABLE_IPV6_DEFAULT 1 typedef tox_IPAny tox_IP; diff --git a/toxcore/util.c b/toxcore/util.c index e751e9e4..8960fe36 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -44,6 +44,7 @@ void id_cpy(uint8_t *dest, uint8_t *src) } #ifdef LOGGING +time_t starttime = 0; char logbuffer[512]; static FILE *logfile = NULL; void loginit(uint16_t port) @@ -53,10 +54,12 @@ void loginit(uint16_t port) sprintf(logbuffer, "%u-%u.log", ntohs(port), now()); logfile = fopen(logbuffer, "w"); + starttime = now(); }; void loglog(char *text) { if (logfile) { + fprintf(logfile, "%4u ", now() - starttime); fprintf(logfile, text); fflush(logfile); } -- cgit v1.2.3 From 484615e67d5f40255244546782bb94508f61cb66 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Fri, 13 Sep 2013 09:16:48 +0200 Subject: Made (load_/save_)data() functions static. --- testing/nTox.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testing/nTox.c b/testing/nTox.c index 178bce2f..9830e95f 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -209,7 +209,7 @@ char *format_message(Tox *m, char *message, int friendnum) } /* forward declaration */ -int save_data(Tox *m); +static int save_data(Tox *m); void line_eval(Tox *m, char *line) { @@ -505,7 +505,7 @@ void print_statuschange(Tox *m, int friendnumber, uint8_t *string, uint16_t leng static char *data_file_name = NULL; -int load_data(Tox *m) +static int load_data(Tox *m) { FILE *data_file = fopen(data_file_name, "r"); int size = 0; @@ -534,7 +534,7 @@ int load_data(Tox *m) return 0; } -int save_data(Tox *m) +static int save_data(Tox *m) { FILE *data_file = fopen(data_file_name, "w"); if (!data_file) { @@ -557,7 +557,7 @@ int save_data(Tox *m) } } -int load_old_key_or_save_new_one(Tox *m, char *path) +static int load_old_key_or_save_new_one(Tox *m, char *path) { data_file_name = path; if (load_data(m)) -- cgit v1.2.3 From f2ad7fd4ea8a68d8c6ef8c25bdc486086ed758fa Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Fri, 13 Sep 2013 09:20:03 +0200 Subject: Rename load_old_key_or_save_new_one() to load_data_or_init(). --- testing/nTox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/nTox.c b/testing/nTox.c index 9830e95f..35659726 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -557,7 +557,7 @@ static int save_data(Tox *m) } } -static int load_old_key_or_save_new_one(Tox *m, char *path) +static int load_data_or_init(Tox *m, char *path) { data_file_name = path; if (load_data(m)) @@ -631,7 +631,7 @@ int main(int argc, char *argv[]) exit(0); } - load_old_key_or_save_new_one(m, filename); + load_data_or_init(m, filename); tox_callback_friendrequest(m, print_request, NULL); tox_callback_friendmessage(m, print_message, NULL); -- cgit v1.2.3 From 09cdd813c5338fe1c809ee451d1aae35c14f05a8 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Sat, 14 Sep 2013 12:55:56 +0200 Subject: DHT.c: - get_close_nodes()/sendnodes()/sendnodes_ipv6(): when selecting for SEND_NODES/SEND_NODES_IPV6, treat embedded IPv4-in-IPv6 addresses as being IPv4 Messenger.c: - added a named constant for sixty seconds friend/client dump - fix logging to convert client_id to printable before printing --- toxcore/DHT.c | 66 ++++++++++++++++++++++++++++++++++++----------------- toxcore/Messenger.c | 10 ++++---- 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 085f93ed..2a5b03a4 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -32,6 +32,7 @@ #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. */ #define BAD_NODE_TIMEOUT 70 @@ -215,15 +216,25 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list * sent anyways for backwards compatibility) * we COULD send ALL as NET_PACKET_SEND_NODES_EX if we KNEW that the * partner node understands - that's true if *they* are on IPv6 + * + * 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(). */ #ifdef TOX_ENABLE_IPV6 - ipv46x = 0; - if (sa_family == AF_INET) - ipv46x = dht->close_clientlist[i].ip_port.ip.family != AF_INET; - else - ipv46x = dht->close_clientlist[i].ip_port.ip.family == AF_INET; + IP *client_ip = &dht->close_clientlist[i].ip_port.ip; + 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; + } + + 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. */ @@ -267,11 +278,17 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list dht->friends_list[i].client_list[j].client_id); #ifdef TOX_ENABLE_IPV6 - ipv46x = 0; - if (sa_family == AF_INET) - ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family != AF_INET; - else - ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family == AF_INET; + IP *client_ip = &dht->friends_list[i].client_list[j].ip_port.ip; + 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; + } + + ipv46x = !(sa_family == ip_treat_as_family); #else ipv46x = sa_family != AF_INET; #endif @@ -578,14 +595,21 @@ 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++) - if (nodes_list[i].ip_port.ip.family == AF_INET) { - memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); - nodes4_list[num_nodes_ok].ip_port.ip.uint32 = nodes_list[i].ip_port.ip.ip4.uint32; - nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; + 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]; + else if (node_ip->family == AF_INET) + nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip4.uint32; + else /* shouldn't happen */ + continue; - num_nodes_ok++; - } + num_nodes_ok++; + } if (num_nodes_ok < num_nodes) { /* shouldn't happen */ @@ -1461,13 +1485,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)) { - fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size); + 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); + 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 %u, got %u.\n", sizeof(DHT_Friend), friendlistsize); return -1; } diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 8d0b149f..55b27353 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -1220,6 +1220,7 @@ void doInbound(Messenger *m) } #ifdef LOGGING +#define DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS 60 static time_t lastdump = 0; static char IDString[CLIENT_ID_SIZE * 2 + 1]; static char *ID2String(uint8_t *client_id) @@ -1245,7 +1246,7 @@ void doMessenger(Messenger *m) LANdiscovery(m); #ifdef LOGGING - if (now() > lastdump + 60) { + if (now() > lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) { loglog(" = = = = = = = = \n"); lastdump = now(); @@ -1292,8 +1293,9 @@ void doMessenger(Messenger *m) 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, msgfptr->client_id); + 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++) { @@ -1304,7 +1306,7 @@ void doMessenger(Messenger *m) 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, - cptr->client_id); + ID2String(cptr->client_id)); loglog(logbuffer); } } -- cgit v1.2.3 From d9965df3823bd3df30f511ae29e8cee694026d88 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Sat, 14 Sep 2013 13:32:07 +0200 Subject: LAN_discovery.c: - LAN_ip(): use standard macro from IPv4-in-IPv6 test --- toxcore/LAN_discovery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index c50fe65d..92e42e0f 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -161,7 +161,7 @@ static int LAN_ip(IP ip) return 0; /* embedded IPv4-in-IPv6 */ - if (!ip.ip6.s6_addr32[0] && !ip.ip6.s6_addr32[1] && ip.ip6.s6_addr32[2] == htonl(0xFFFF)) { + if (IN6_IS_ADDR_V4MAPPED(&ip.ip6)) { IP ip4; ip4.family = AF_INET; ip4.ip4.uint32 = ip.ip6.s6_addr32[3]; -- cgit v1.2.3 From a7d059a13008bff51422aac97768f44a693c4f47 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Sat, 14 Sep 2013 17:09:03 +0200 Subject: network.c: - addr_resolve(): for() instead of while(), flip conditions for a much neater function (suggested by Andreas Schneider) - ip_ntoa(): enforced termination: terminate at the maximum position, that's the one snprintf() may forget - networking_poll(): forgot tabs2spaces --- toxcore/network.c | 66 +++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index 0baa6242..6ae13160 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -210,11 +210,11 @@ void networking_poll(Networking_Core *net) if (!(net->packethandlers[data[0]].function)) { #ifdef LOGGING - sprintf(logbuffer, "[%02u] -- Packet has no handler.\n", data[0]); - loglog(logbuffer); + sprintf(logbuffer, "[%02u] -- Packet has no handler.\n", data[0]); + loglog(logbuffer); #endif - continue; - } + continue; + } net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, ip_port, data, length); } @@ -613,7 +613,8 @@ const char *ip_ntoa(IP *ip) else snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)"); - addresstext[INET6_ADDRSTRLEN + 2] = 0; + /* brute force protection against lacking termination */ + addresstext[sizeof(addresstext) - 1] = 0; return addresstext; }; @@ -728,52 +729,45 @@ int addr_resolve(const char *address, IP *to, IP *extra) memset(&ip6, 0, sizeof(ip6)); #endif - walker = server; - while (walker && (rc != 3)) { - if (family != AF_UNSPEC) { + for(walker = server; (walker != NULL) && (rc != 3); walker = walker->ai_next) { + switch(walker->ai_family) { + case AF_INET: if (walker->ai_family == family) { - if (family == AF_INET) { - if (walker->ai_addrlen == sizeof(struct sockaddr_in)) { - struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; + 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; - } - } + rc = 3; + } #ifdef TOX_ENABLE_IPV6 - else if (family == AF_INET6) { - 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; - } - } -#endif + 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 - else { - if (walker->ai_family == AF_INET) { - if (walker->ai_addrlen == sizeof(struct sockaddr_in)) { - struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; - ip4.in_addr = addr->sin_addr; - rc |= 1; + 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 (walker->ai_family == AF_INET6) { + } 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 - - walker = walker->ai_next; + } } #ifdef TOX_ENABLE_IPV6 -- cgit v1.2.3 From 36e5636406c019390f96c2a02c17c850143d21b9 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Sat, 14 Sep 2013 17:10:10 +0200 Subject: DHT.c: - get_close_nodes(): refactored the inner loop out into get_close_nodes_inner() --- toxcore/DHT.c | 205 +++++++++++++++++++++++----------------------------------- 1 file changed, 82 insertions(+), 123 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 2a5b03a4..8557a5e0 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -193,137 +193,96 @@ static int friend_number(DHT *dht, uint8_t *client_id) return -1; } -/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: - * put them in the nodes_list and return how many were found. - * - * TODO: For the love of based Allah make this function cleaner and much more efficient. +/* + * helper for get_close_nodes(). argument list is a monster :D */ -static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family) +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) { - uint32_t i, j, k; - uint64_t temp_time = unix_time(); - int num_nodes = 0, closest, tout, inlist, ipv46x; - - for (i = 0; i < LCLIENT_LIST; ++i) { - tout = is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); - inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, dht->close_clientlist[i].client_id); - - /* - * NET_PACKET_SEND_NODES sends ONLY AF_INET - * NET_PACKET_SEND_NODES_EX sends ALL BUT AF_INET (i.e. AF_INET6), - * it could send both, but then a) packet size is an issue and - * b) duplicates the traffic (NET_PACKET_SEND_NODES has to be - * sent anyways for backwards compatibility) - * we COULD send ALL as NET_PACKET_SEND_NODES_EX if we KNEW that the - * partner node understands - that's true if *they* are on IPv6 - * - * 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(). - */ -#ifdef TOX_ENABLE_IPV6 - IP *client_ip = &dht->close_clientlist[i].ip_port.ip; - 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; - } - - ipv46x = !(sa_family == ip_treat_as_family); -#else - ipv46x = !(sa_family == AF_INET); -#endif - - /* 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, - dht->close_clientlist[i].client_id, - CLIENT_ID_SIZE ); - - nodes_list[num_nodes].ip_port = dht->close_clientlist[i].ip_port; - num_nodes++; - - } else { - - for (j = 0; j < MAX_SENT_NODES; ++j) { - closest = id_closest( client_id, - nodes_list[j].client_id, - dht->close_clientlist[i].client_id ); - - if (closest == 2) { - memcpy( nodes_list[j].client_id, - dht->close_clientlist[i].client_id, - CLIENT_ID_SIZE); - - nodes_list[j].ip_port = dht->close_clientlist[i].ip_port; - break; - } - } - } - } - - for (i = 0; i < dht->num_friends; ++i) { - for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { - - tout = is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT); - inlist = client_in_nodelist( nodes_list, - MAX_SENT_NODES, - dht->friends_list[i].client_list[j].client_id); + 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); #ifdef TOX_ENABLE_IPV6 - IP *client_ip = &dht->friends_list[i].client_list[j].ip_port.ip; - 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; - } - - ipv46x = !(sa_family == ip_treat_as_family); + 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; + } + + 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 (num_nodes < MAX_SENT_NODES) { - - memcpy( nodes_list[num_nodes].client_id, - dht->friends_list[i].client_list[j].client_id, - CLIENT_ID_SIZE); - - nodes_list[num_nodes].ip_port = dht->friends_list[i].client_list[j].ip_port; - num_nodes++; - } else { - for (k = 0; k < MAX_SENT_NODES; ++k) { - - closest = id_closest( client_id, - nodes_list[k].client_id, - dht->friends_list[i].client_list[j].client_id ); - - if (closest == 2) { - memcpy( nodes_list[k].client_id, - dht->friends_list[i].client_list[j].client_id, - CLIENT_ID_SIZE ); + /* 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 ); + + 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); + + nodes_list[j].ip_port = client->ip_port; + break; + } + } + } + } + + *num_nodes_ptr = num_nodes; +} - nodes_list[k].ip_port = dht->friends_list[i].client_list[j].ip_port; - break; - } - } - } - } - } +/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: + * put them in the nodes_list and return how many were found. + * + * TODO: For the love of based make + * this function cleaner and much more efficient. + */ +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); + + 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); return num_nodes; } -- cgit v1.2.3 From 0db05eca4951b06b478d2890ce512dc9d01c5775 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Sat, 14 Sep 2013 18:39:59 +0200 Subject: Save datafile when adding a friend/accepting a friend request. (Note to self: make clean is your friend. Those extra seconds are well spent.) --- testing/nTox.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testing/nTox.c b/testing/nTox.c index 35659726..8c87c20d 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -254,8 +254,10 @@ void line_eval(Tox *m, char *line) break; default: - if (num >= 0) + if (num >= 0) { sprintf(numstring, "[i] Added friend as %d.", num); + save_data(m); + } else sprintf(numstring, "[i] Unknown error %i.", num); break; @@ -345,6 +347,7 @@ void line_eval(Tox *m, char *line) new_lines(numchar); sprintf(numchar, "[i] added friendnumber %d", num); new_lines(numchar); + save_data(m); } else { sprintf(numchar, "[i] failed to add friend"); new_lines(numchar); -- cgit v1.2.3 From 64d000cdfaed710d3e22fa5444b8c2883b9f09d6 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Fri, 13 Sep 2013 17:08:54 -0400 Subject: Some fixes. --- toxcore/DHT.c | 165 ++++++++++++++++++++++------------------- toxcore/Lossless_UDP.c | 27 +++++-- toxcore/network.c | 198 ++++++++++++++++++++++++++++--------------------- 3 files changed, 224 insertions(+), 166 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; - - /* - * 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; - } - - ipv46x = !(sa_family == ip_treat_as_family); + 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; + } + + 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 (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 ); - - /* 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; - } - } - } - } - - *num_nodes_ptr = num_nodes; + /* 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 ); + + 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); + + nodes_list[j].ip_port = client->ip_port; + break; + } + } + } + } + + *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; -#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; - } + to->in_addr = addr->sin_addr; #endif - break; /* switch */ + rc = 3; + } #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 & 1)) { + struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; + to->ip4.in_addr = addr->sin_addr; + rc |= 1; } - } 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; + +#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 */ + + 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); -- cgit v1.2.3 From 12d1c5199bd2feecd93424ff57f44fab4bbb02ad Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 14 Sep 2013 12:42:17 -0400 Subject: astyled everything. --- other/DHT_bootstrap.c | 4 +- testing/DHT_test.c | 2 + testing/Lossless_UDP_testclient.c | 3 + testing/Lossless_UDP_testserver.c | 1 + testing/Messenger_test.c | 5 +- testing/misc_tools.c | 7 +- testing/nTox.c | 2 + toxcore/DHT.h | 4 +- toxcore/LAN_discovery.c | 48 +++++++----- toxcore/Messenger.c | 159 +++++++++++++++++++++----------------- toxcore/ping.c | 2 +- toxcore/tox.c | 2 +- toxcore/tox.h | 4 +- 13 files changed, 141 insertions(+), 102 deletions(-) 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..93130307 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -582,6 +582,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); @@ -641,6 +642,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.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..ed8dd229 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -35,7 +35,7 @@ * return higher than 0 on success. * return 0 on error. */ -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,16 +63,17 @@ 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; - } - - /* 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); - } + 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); + } } close(sock); @@ -87,6 +88,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 +98,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 +129,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 +156,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 */ 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 +174,7 @@ static int LAN_ip(IP ip) return LAN_ip(ip4); } } + #endif return -1; @@ -203,9 +210,11 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c) 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 +225,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/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); - } - } - - 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"); - } + + 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); + } + } + + 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"); + } + #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/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. -- cgit v1.2.3 From 46a99a87746fd071948bdbe47019e70f6d99e1c8 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 14 Sep 2013 12:57:41 -0400 Subject: Fixed some warnings. --- toxcore/DHT.c | 13 +++++++------ toxcore/network.c | 10 ++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index df3b2f76..a2d0b5d8 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -195,9 +195,9 @@ 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; @@ -974,9 +974,10 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, 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) { @@ -1456,14 +1457,14 @@ 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); + 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; } diff --git a/toxcore/network.c b/toxcore/network.c index 5aa17cd0..a244b400 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -383,7 +383,10 @@ Networking_Core *new_networking(IP ip, uint16_t port) 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) { @@ -403,7 +406,10 @@ 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) { -- cgit v1.2.3 From 18cfda2dc7da6cd19a8da9e23ee2a08ab459784d Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 14 Sep 2013 15:12:54 -0400 Subject: Small fixes. --- toxcore/network.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index a244b400..75d968be 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -307,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; } @@ -474,7 +474,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); - free(temp); + kill_networking(temp); return NULL; } @@ -728,25 +728,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; } @@ -823,9 +811,6 @@ int addr_resolve(const char *address, IP *to, IP *extra) freeaddrinfo(server); -#ifdef __WIN32__ - WSACleanup(); -#endif return rc; } -- cgit v1.2.3 From 04e7b0eb6c31f6650bcef83b4915af259b087227 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 14 Sep 2013 18:59:04 -0400 Subject: Fixed small problems, updated TODO. --- docs/TODO | 4 ++++ toxcore/DHT.c | 9 +++++---- 2 files changed, 9 insertions(+), 4 deletions(-) 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/toxcore/DHT.c b/toxcore/DHT.c index a2d0b5d8..51dd60f2 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -199,7 +199,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod 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 num_nodes = *num_nodes_ptr; int i, tout, inlist, ipv46x, j, closest; for (i = 0; i < client_list_length; i++) { @@ -459,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; } } @@ -679,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? */ @@ -764,7 +765,7 @@ 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 || -- cgit v1.2.3 From 20a8fb8a231d158368b8f2db2aab01e443f81b98 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 14 Sep 2013 19:15:26 -0400 Subject: Fixed warnings. --- testing/nTox.c | 1 - toxcore/LAN_discovery.c | 9 +++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/testing/nTox.c b/testing/nTox.c index 93130307..453c7489 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -588,7 +588,6 @@ int main(int argc, char *argv[]) int on = 0; int c = 0; - int i = 0; char *filename = "data"; char idstring[200] = {0}; Tox *m; diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index ed8dd229..c7afb991 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -30,10 +30,13 @@ #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) { @@ -80,6 +83,7 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t *da return 0; } #endif +#endif /* Return the broadcast ip. */ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) @@ -161,7 +165,7 @@ static int LAN_ip(IP ip) } 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))) return 0; @@ -202,9 +206,10 @@ 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; -- cgit v1.2.3 From dde98eb34567a274d444893f8c98868ba9d1fa4b Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 14 Sep 2013 20:38:48 -0400 Subject: DHT peer finding for new friends should now be slightly faster. Also fixed the "[i] could not send message" bug in nTox. --- testing/nTox.c | 2 +- toxcore/DHT.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/testing/nTox.c b/testing/nTox.c index 453c7489..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)); diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 51dd60f2..11f25880 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -808,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? */ @@ -825,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; } -- cgit v1.2.3 From 2092b5d936acd1b69269ace0d22e862790ad57b3 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Sun, 15 Sep 2013 08:20:37 +0200 Subject: addr_resolve() rewrite broke { (ipv6enabled == true) name => IPv4 address } network.c: - addr_resolve(): save AF_UNSPEC ip4 address into ip4, not into to->ip4 --- toxcore/network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxcore/network.c b/toxcore/network.c index 6ae13160..83081a49 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -744,7 +744,7 @@ int addr_resolve(const char *address, IP *to, IP *extra) #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; + ip4.in_addr = addr->sin_addr; rc |= 1; } #endif -- cgit v1.2.3 From 1e1782a952d1476d49c63fd1a3966e85eb3a09d4 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Sun, 15 Sep 2013 08:33:09 +0200 Subject: ip_equal(): handle embedded v4 vs. native v4 as equal network.c: - ip_equal(): on IPv4 vs. IPv6, check if the IPv6 is an embedded IPv4 and if true, compare that --- toxcore/network.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index 83081a49..44448f38 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -480,11 +480,24 @@ 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); - - if (a->family == AF_INET6) - return IN6_ARE_ADDR_EQUAL(&a->ip6, &b->ip6); + /* 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 */ + 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); + } return 0; #else -- cgit v1.2.3 From 8c41244627528ba35dc122ed166cc664fee8c4de Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sun, 15 Sep 2013 09:31:27 -0400 Subject: Fixed portablity problems. struct in6_addr member names can differ per platform. --- toxcore/DHT.c | 2 +- toxcore/LAN_discovery.c | 20 ++++++++++---------- toxcore/Lossless_UDP.c | 2 +- toxcore/network.c | 12 ++++++------ toxcore/network.h | 7 ++++++- toxcore/tox.h | 7 ++++++- 6 files changed, 30 insertions(+), 20 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 11f25880..32a1d96d 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -564,7 +564,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl 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]; + nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip6.uint32[3]; else if (node_ip->family == AF_INET) nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip4.uint32; else /* shouldn't happen */ diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index c7afb991..db07755d 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -99,15 +99,15 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ /* FE80::*: MUST be exact, for that we would need to look over all * interfaces and check in which status they are */ - ip.ip6.s6_addr[ 0] = 0xFF; - ip.ip6.s6_addr[ 1] = 0x02; - ip.ip6.s6_addr[15] = 0x01; + ip.ip6.uint8[ 0] = 0xFF; + ip.ip6.uint8[ 1] = 0x02; + ip.ip6.uint8[15] = 0x01; } 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; + ip.ip6.uint32[0] = 0; + ip.ip6.uint32[1] = 0; + ip.ip6.uint32[2] = htonl(0xFFFF); + ip.ip6.uint32[3] = INADDR_BROADCAST; } } else if (family_socket == AF_INET) { if (family_broadcast == AF_INET) { @@ -166,15 +166,15 @@ static int LAN_ip(IP ip) { /* autogenerated for each interface: FE80::* (up to FEBF::*) 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))) + if (((ip.ip6.uint8[0] == 0xFF) && (ip.ip6.uint8[1] < 3) && (ip.ip6.uint8[15] == 1)) || + ((ip.ip6.uint8[0] == 0xFE) && ((ip.ip6.uint8[1] & 0xC0) == 0x80))) return 0; /* embedded IPv4-in-IPv6 */ if (IN6_IS_ADDR_V4MAPPED(&ip.ip6)) { IP ip4; ip4.family = AF_INET; - ip4.ip4.uint32 = ip.ip6.s6_addr32[3]; + ip4.ip4.uint32 = ip.ip6.uint32[3]; return LAN_ip(ip4); } } diff --git a/toxcore/Lossless_UDP.c b/toxcore/Lossless_UDP.c index f942d8e5..46b0bed1 100644 --- a/toxcore/Lossless_UDP.c +++ b/toxcore/Lossless_UDP.c @@ -100,7 +100,7 @@ static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) int k; for (k = 0; k < 16; k++) { - id ^= randtable_initget(ludp, i++, source.ip.ip6.s6_addr[k]); + id ^= randtable_initget(ludp, i++, source.ip.ip6.uint8[k]); } } diff --git a/toxcore/network.c b/toxcore/network.c index 75d968be..e32e9a4c 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -120,7 +120,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; addr6->sin6_family = AF_INET6; addr6->sin6_port = ip_port.port; - addr6->sin6_addr = ip_port.ip.ip6; + addr6->sin6_addr = ip_port.ip.ip6.in6_addr; addr6->sin6_flowinfo = 0; addr6->sin6_scope_id = 0; @@ -177,7 +177,7 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t } 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->ip.ip6.in6_addr = addr_in6->sin6_addr; ip_port->port = addr_in6->sin6_port; } else return -1; @@ -371,7 +371,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; addr6->sin6_family = AF_INET6; addr6->sin6_port = 0; - addr6->sin6_addr = ip.ip6; + addr6->sin6_addr = ip.ip6.in6_addr; addr6->sin6_flowinfo = 0; addr6->sin6_scope_id = 0; @@ -672,7 +672,7 @@ int addr_parse_ip(const char *address, IP *to) if (1 == inet_pton(AF_INET6, address, &addr6)) { to->family = AF_INET6; - to->ip6 = addr6; + to->ip6.in6_addr = addr6; return 1; }; @@ -773,13 +773,13 @@ int addr_resolve(const char *address, IP *to, IP *extra) 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; + to->ip6.in6_addr = 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; + ip6.in6_addr = addr->sin6_addr; rc |= 2; } } diff --git a/toxcore/network.h b/toxcore/network.h index 7dea8c16..416d794d 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -96,7 +96,12 @@ typedef union { struct in_addr in_addr; } IP4; -typedef struct in6_addr IP6; +typedef union { + uint8_t uint8[16]; + uint16_t uint16[8]; + uint32_t uint32[4]; + struct in6_addr in6_addr; +} IP6; typedef struct { sa_family_t family; diff --git a/toxcore/tox.h b/toxcore/tox.h index a15d7ea0..89242f1f 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -63,7 +63,12 @@ typedef union { } tox_IP4; -typedef struct in6_addr tox_IP6; +typedef union { + uint8_t uint8[16]; + uint16_t uint16[8]; + uint32_t uint32[4]; + struct in6_addr in6_addr; +} tox_IP6; typedef struct { sa_family_t family; -- cgit v1.2.3 From 43b609d41cd24435eccf6ead89f12fff888915f4 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sun, 15 Sep 2013 09:35:46 -0400 Subject: Fixed merge problems. --- toxcore/network.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index da826a7f..1abe4784 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -502,6 +502,7 @@ 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) @@ -515,10 +516,10 @@ int ip_equal(IP *a, IP *b) /* 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]); + return (a->ip4.in_addr.s_addr == b->ip6.uint32[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 (a->ip6.uint32[3] == b->ip4.in_addr.s_addr); } return 0; @@ -776,6 +777,7 @@ int addr_resolve(const char *address, IP *to, IP *extra) ip4.in_addr = addr->sin_addr; rc |= 1; } + #endif break; /* switch */ #ifdef TOX_ENABLE_IPV6 -- cgit v1.2.3 From bbeb6e15cdd4135f1922146741d8c9d709f808eb Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sun, 15 Sep 2013 09:47:17 -0400 Subject: Fixed portability problems. --- toxcore/DHT.c | 4 ++-- toxcore/LAN_discovery.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 32a1d96d..2f7b2263 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -221,7 +221,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod (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)) + if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6.in6_addr)) ip_treat_as_family = AF_INET; } @@ -562,7 +562,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl IP *node_ip = &nodes_list[i].ip_port.ip; - if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6)) + if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6.in6_addr)) /* embedded IPv4-in-IPv6 address: return it in regular sendnodes packet */ nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip6.uint32[3]; else if (node_ip->family == AF_INET) diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index db07755d..cf4196d2 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -171,7 +171,7 @@ static int LAN_ip(IP ip) return 0; /* embedded IPv4-in-IPv6 */ - if (IN6_IS_ADDR_V4MAPPED(&ip.ip6)) { + if (IN6_IS_ADDR_V4MAPPED(&ip.ip6.in6_addr)) { IP ip4; ip4.family = AF_INET; ip4.ip4.uint32 = ip.ip6.uint32[3]; -- cgit v1.2.3 From decdb7aa8c827787240bac66526a81bf2b8f7ebb Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sun, 15 Sep 2013 10:17:09 -0400 Subject: more portability fixes. --- toxcore/network.c | 17 ++++++++++------- toxcore/network.h | 6 ++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index 1abe4784..fe2ef238 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -95,10 +95,13 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le /* there should be a macro for this in a standards compliant * environment, not found */ - addr6->sin6_addr.s6_addr32[0] = 0; - addr6->sin6_addr.s6_addr32[1] = 0; - addr6->sin6_addr.s6_addr32[2] = htonl(0xFFFF); - addr6->sin6_addr.s6_addr32[3] = ip_port.ip.ip4.uint32; + IP6 ip6; + + ip6.uint32[0] = 0; + ip6.uint32[1] = 0; + ip6.uint32[2] = htonl(0xFFFF); + ip6.uint32[3] = ip_port.ip.ip4.uint32; + addr6->sin6_addr = ip6.in6_addr; addr6->sin6_flowinfo = 0; addr6->sin6_scope_id = 0; @@ -508,17 +511,17 @@ int ip_equal(IP *a, IP *b) 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); + return IN6_ARE_ADDR_EQUAL(&a->ip6.in6_addr, &b->ip6.in6_addr); else return 0; } /* 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)) + if (IN6_IS_ADDR_V4COMPAT(&b->ip6.in6_addr)) return (a->ip4.in_addr.s_addr == b->ip6.uint32[3]); } else if ((a->family == AF_INET6) && (b->family == AF_INET)) { - if (IN6_IS_ADDR_V4COMPAT(&a->ip6)) + if (IN6_IS_ADDR_V4COMPAT(&a->ip6.in6_addr)) return (a->ip6.uint32[3] == b->ip4.in_addr.s_addr); } diff --git a/toxcore/network.h b/toxcore/network.h index 416d794d..4432baed 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -66,6 +66,12 @@ typedef int sock_t; #define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) #endif +#ifndef IPV6_ADD_MEMBERSHIP +#ifdef IPV6_JOIN_GROUP +#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP +#endif +#endif #define MAX_UDP_PACKET_SIZE 65507 -- cgit v1.2.3 From 96d39de2231fcd884afd80ce59dec1abc80c23ab Mon Sep 17 00:00:00 2001 From: Sebastian Stal Date: Sun, 15 Sep 2013 10:48:16 -0700 Subject: Fix leaks and null dereferences in net_crypto --- toxcore/net_crypto.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 3f866f74..1de32cb0 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -455,7 +455,8 @@ int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port) return -1; } - if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1) + if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1 + || c->crypto_connections == NULL) return -1; memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection)); @@ -578,7 +579,8 @@ int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, * return -1; * } */ - if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1) + if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1 + || c->crypto_connections == NULL) return -1; memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection)); @@ -778,8 +780,10 @@ Net_Crypto *new_net_crypto(Networking_Core *net) temp->lossless_udp = new_lossless_udp(net); - if (temp->lossless_udp == NULL) + if (temp->lossless_udp == NULL) { + free(temp); return NULL; + } memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING); return temp; -- cgit v1.2.3 From ee1cc34d551f978c63402e7ad6a33e410636a277 Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Sun, 15 Sep 2013 23:39:09 +0200 Subject: Fix in ip_equal, plus testing code which led to that fix... network.c: - use the correct macro for IPv4-in-IPv6 test network_test.c: - bunch of tests for addr_resolve() and ip_equal() --- auto_tests/Makefile.inc | 20 +++++- auto_tests/network_test.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++ toxcore/network.c | 4 +- 3 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 auto_tests/network_test.c diff --git a/auto_tests/Makefile.inc b/auto_tests/Makefile.inc index 4930a798..6c59eebb 100644 --- a/auto_tests/Makefile.inc +++ b/auto_tests/Makefile.inc @@ -1,8 +1,8 @@ if BUILD_TESTS -TESTS = messenger_autotest crypto_test +TESTS = messenger_autotest crypto_test network_test -check_PROGRAMS = messenger_autotest crypto_test +check_PROGRAMS = messenger_autotest crypto_test network_test messenger_autotest_SOURCES = \ ../auto_tests/messenger_test.c @@ -34,6 +34,22 @@ crypto_test_LDADD = $(LIBSODIUM_LDFLAGS) \ $(NACL_LIBS) \ $(CHECK_LIBS) +network_test_SOURCES = \ + ../auto_tests/network_test.c + +network_test_CFLAGS = \ + $(LIBSODIUM_CFLAGS) \ + $(NACL_CFLAGS) \ + $(CHECK_CFLAGS) + +network_test_LDADD = \ + $(LIBSODIUM_LDFLAGS) \ + $(NACL_LDFLAGS) \ + libtoxcore.la \ + $(LIBSODIUM_LIBS) \ + $(NACL_LIBS) \ + $(CHECK_LIBS) + endif EXTRA_DIST += $(top_srcdir)/auto_tests/friends_test.c diff --git a/auto_tests/network_test.c b/auto_tests/network_test.c new file mode 100644 index 00000000..593b1f40 --- /dev/null +++ b/auto_tests/network_test.c @@ -0,0 +1,154 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "../toxcore/network.h" + +START_TEST(test_addr_resolv_localhost) +{ +#ifdef __CYGWIN__ + /* force initialization of network stack + * normally this should happen automatically + * cygwin doesn't do it for every network related function though + * e.g. not for getaddrinfo... */ + socket(0, 0, 0); + errno = 0; +#endif + + const char localhost[] = "localhost"; + + IP ip; + ip_init(&ip, 0); + + int res = addr_resolve(localhost, &ip, NULL); + + ck_assert_msg(res > 0, "Resolver failed: %u, %s (%x, %x)", errno, strerror(errno)); + + if (res > 0) { + ck_assert_msg(ip.family == AF_INET, "Expected family AF_INET, got %u.", ip.family); + ck_assert_msg(ip.ip4.uint32 == htonl(0x7F000001), "Expected 127.0.0.1, got %s.", inet_ntoa(ip.ip4.in_addr)); + } + + ip_init(&ip, 1); + res = addr_resolve(localhost, &ip, NULL); + + ck_assert_msg(res > 0, "Resolver failed: %u, %s (%x, %x)", errno, strerror(errno)); + + if (res > 0) { + ck_assert_msg(ip.family == AF_INET6, "Expected family AF_INET6, got %u.", ip.family); + ck_assert_msg(!memcmp(&ip.ip6, &in6addr_loopback, sizeof(IP6)), "Expected ::1, got %s.", ip_ntoa(&ip)); + } + + ip_init(&ip, 1); + ip.family = AF_UNSPEC; + IP extra; + ip_reset(&extra); + res = addr_resolve(localhost, &ip, &extra); + + ck_assert_msg(res > 0, "Resolver failed: %u, %s (%x, %x)", errno, strerror(errno)); + + if (res > 0) { + ck_assert_msg(ip.family == AF_INET6, "Expected family AF_INET6, got %u.", ip.family); + ck_assert_msg(!memcmp(&ip.ip6, &in6addr_loopback, sizeof(IP6)), "Expected ::1, got %s.", ip_ntoa(&ip)); + + ck_assert_msg(extra.family == AF_INET, "Expected family AF_INET, got %u.", extra.family); + ck_assert_msg(extra.ip4.uint32 == htonl(0x7F000001), "Expected 127.0.0.1, got %s.", inet_ntoa(extra.ip4.in_addr)); + } +} +END_TEST + +START_TEST(test_ip_equal) +{ + int res; + IP ip1, ip2; + ip_reset(&ip1); + ip_reset(&ip2); + + res = ip_equal(NULL, NULL); + ck_assert_msg(res == 0, "ip_equal(NULL, NULL): expected result 0, got %u.", res); + + res = ip_equal(&ip1, NULL); + ck_assert_msg(res == 0, "ip_equal(PTR, NULL): expected result 0, got %u.", res); + + res = ip_equal(NULL, &ip1); + ck_assert_msg(res == 0, "ip_equal(NULL, PTR): expected result 0, got %u.", res); + + ip1.family = AF_INET; + ip1.ip4.uint32 = htonl(0x7F000001); + + res = ip_equal(&ip1, &ip2); + ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_UNSPEC, 0} ): expected result 0, got %u.", res); + + ip2.family = AF_INET; + ip2.ip4.uint32 = htonl(0x7F000001); + + res = ip_equal(&ip1, &ip2); + ck_assert_msg(res != 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET, 127.0.0.1} ): expected result != 0, got 0."); + + ip2.ip4.uint32 = htonl(0x7F000002); + + res = ip_equal(&ip1, &ip2); + ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET, 127.0.0.2} ): expected result 0, got %u.", res); + + ip2.family = AF_INET6; + ip2.ip6.uint32[0] = 0; + ip2.ip6.uint32[1] = 0; + ip2.ip6.uint32[2] = htonl(0xFFFF); + ip2.ip6.uint32[3] = htonl(0x7F000001); + + ck_assert_msg(IN6_IS_ADDR_V4MAPPED(&ip2.ip6) != 0, "IN6_IS_ADDR_V4MAPPED(::ffff:127.0.0.1): expected != 0, got 0."); + + res = ip_equal(&ip1, &ip2); + ck_assert_msg(res != 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET6, ::ffff:127.0.0.1} ): expected result != 0, got 0."); + + memcpy(&ip2.ip6, &in6addr_loopback, sizeof(IP6)); + res = ip_equal(&ip1, &ip2); + ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET6, ::1} ): expected result 0, got %u.", res); + + memcpy(&ip1, &ip2, sizeof(IP)); + res = ip_equal(&ip1, &ip2); + ck_assert_msg(res != 0, "ip_equal( {AF_INET6, ::1}, {AF_INET6, ::1} ): expected result != 0, got 0."); + + ip2.ip6.uint8[15]++; + res = ip_equal(&ip1, &ip2); + ck_assert_msg(res == 0, "ip_equal( {AF_INET6, ::1}, {AF_INET6, ::2} ): expected result 0, got %res.", res); +} +END_TEST + +#define DEFTESTCASE(NAME) \ + TCase *NAME = tcase_create(#NAME); \ + tcase_add_test(NAME, test_##NAME); \ + suite_add_tcase(s, NAME); + +Suite *network_suite(void) +{ + Suite *s = suite_create("Network"); + + DEFTESTCASE(addr_resolv_localhost); + DEFTESTCASE(ip_equal); + + return s; +} + +int main(int argc, char *argv[]) +{ + srand((unsigned int) time(NULL)); + + Suite *network = network_suite(); + SRunner *test_runner = srunner_create(network); + int number_failed = 0; + + srunner_run_all(test_runner, CK_NORMAL); + number_failed = srunner_ntests_failed(test_runner); + + srunner_free(test_runner); + + return number_failed; +} diff --git a/toxcore/network.c b/toxcore/network.c index fe2ef238..4b6dc3be 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -518,10 +518,10 @@ int ip_equal(IP *a, IP *b) /* 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.in6_addr)) + if (IN6_IS_ADDR_V4MAPPED(&b->ip6.in6_addr)) return (a->ip4.in_addr.s_addr == b->ip6.uint32[3]); } else if ((a->family == AF_INET6) && (b->family == AF_INET)) { - if (IN6_IS_ADDR_V4COMPAT(&a->ip6.in6_addr)) + if (IN6_IS_ADDR_V4MAPPED(&a->ip6.in6_addr)) return (a->ip6.uint32[3] == b->ip4.in_addr.s_addr); } -- cgit v1.2.3