diff options
-rw-r--r-- | toxcore/DHT.c | 165 | ||||
-rw-r--r-- | toxcore/Lossless_UDP.c | 27 | ||||
-rw-r--r-- | 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 @@ | |||
31 | #include "network.h" | 31 | #include "network.h" |
32 | #include "ping.h" | 32 | #include "ping.h" |
33 | #include "misc_tools.h" | 33 | #include "misc_tools.h" |
34 | #include "Messenger.h" | ||
35 | #include "util.h" | 34 | #include "util.h" |
36 | 35 | ||
37 | /* The number of seconds for a non responsive node to become bad. */ | 36 | /* 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) | |||
197 | * helper for get_close_nodes(). argument list is a monster :D | 196 | * helper for get_close_nodes(). argument list is a monster :D |
198 | */ | 197 | */ |
199 | static int get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list, | 198 | static int get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list, |
200 | sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, | 199 | sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, |
201 | time_t timestamp, int *num_nodes_ptr) | 200 | time_t timestamp, int *num_nodes_ptr) |
202 | { | 201 | { |
203 | int num_nodes = 0; | 202 | int num_nodes = 0; |
204 | int i, tout, inlist, ipv46x, j, closest; | 203 | int i, tout, inlist, ipv46x, j, closest; |
205 | for(i = 0; i < client_list_length; i++) { | 204 | |
206 | Client_data *client = &client_list[i]; | 205 | for (i = 0; i < client_list_length; i++) { |
207 | tout = is_timeout(timestamp, client->timestamp, BAD_NODE_TIMEOUT); | 206 | Client_data *client = &client_list[i]; |
208 | inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, client->client_id); | 207 | tout = is_timeout(timestamp, client->timestamp, BAD_NODE_TIMEOUT); |
208 | inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, client->client_id); | ||
209 | 209 | ||
210 | #ifdef TOX_ENABLE_IPV6 | 210 | #ifdef TOX_ENABLE_IPV6 |
211 | IP *client_ip = &client->ip_port.ip; | 211 | IP *client_ip = &client->ip_port.ip; |
212 | 212 | ||
213 | /* | 213 | /* |
214 | * Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for | 214 | * Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for |
215 | * our connections, instead we have to look if it is an embedded | 215 | * our connections, instead we have to look if it is an embedded |
216 | * IPv4-in-IPv6 here and convert it down in sendnodes(). | 216 | * IPv4-in-IPv6 here and convert it down in sendnodes(). |
217 | */ | 217 | */ |
218 | sa_family_t ip_treat_as_family = client_ip->family; | 218 | sa_family_t ip_treat_as_family = client_ip->family; |
219 | if ((dht->c->lossless_udp->net->family == AF_INET6) && | 219 | |
220 | (client_ip->family == AF_INET6)) { | 220 | if ((dht->c->lossless_udp->net->family == AF_INET6) && |
221 | /* socket is AF_INET6, address claims AF_INET6: | 221 | (client_ip->family == AF_INET6)) { |
222 | * check for embedded IPv4-in-IPv6 */ | 222 | /* socket is AF_INET6, address claims AF_INET6: |
223 | if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6)) | 223 | * check for embedded IPv4-in-IPv6 */ |
224 | ip_treat_as_family = AF_INET; | 224 | if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6)) |
225 | } | 225 | ip_treat_as_family = AF_INET; |
226 | 226 | } | |
227 | ipv46x = !(sa_family == ip_treat_as_family); | 227 | |
228 | ipv46x = !(sa_family == ip_treat_as_family); | ||
228 | #else | 229 | #else |
229 | ipv46x = !(sa_family == AF_INET); | 230 | ipv46x = !(sa_family == AF_INET); |
230 | #endif | 231 | #endif |
231 | 232 | ||
232 | /* If node isn't good or is already in list. */ | 233 | /* If node isn't good or is already in list. */ |
233 | if (tout || inlist || ipv46x) | 234 | if (tout || inlist || ipv46x) |
234 | continue; | 235 | continue; |
235 | 236 | ||
236 | if (num_nodes < MAX_SENT_NODES) { | 237 | if (num_nodes < MAX_SENT_NODES) { |
237 | memcpy(nodes_list[num_nodes].client_id, | 238 | memcpy(nodes_list[num_nodes].client_id, |
238 | client->client_id, | 239 | client->client_id, |
239 | CLIENT_ID_SIZE ); | 240 | CLIENT_ID_SIZE ); |
240 | 241 | ||
241 | nodes_list[num_nodes].ip_port = client->ip_port; | 242 | nodes_list[num_nodes].ip_port = client->ip_port; |
242 | num_nodes++; | 243 | num_nodes++; |
243 | } else { | 244 | } else { |
244 | /* see if node_list contains a client_id that's "further away" | 245 | /* see if node_list contains a client_id that's "further away" |
245 | * compared to the one we're looking at at the moment, if there | 246 | * compared to the one we're looking at at the moment, if there |
246 | * is, replace it | 247 | * is, replace it |
247 | */ | 248 | */ |
248 | for (j = 0; j < MAX_SENT_NODES; ++j) { | 249 | for (j = 0; j < MAX_SENT_NODES; ++j) { |
249 | closest = id_closest( client_id, | 250 | closest = id_closest( client_id, |
250 | nodes_list[j].client_id, | 251 | nodes_list[j].client_id, |
251 | client->client_id ); | 252 | client->client_id ); |
252 | 253 | ||
253 | /* second client_id is closer than current: change to it */ | 254 | /* second client_id is closer than current: change to it */ |
254 | if (closest == 2) { | 255 | if (closest == 2) { |
255 | memcpy( nodes_list[j].client_id, | 256 | memcpy( nodes_list[j].client_id, |
256 | client->client_id, | 257 | client->client_id, |
257 | CLIENT_ID_SIZE); | 258 | CLIENT_ID_SIZE); |
258 | 259 | ||
259 | nodes_list[j].ip_port = client->ip_port; | 260 | nodes_list[j].ip_port = client->ip_port; |
260 | break; | 261 | break; |
261 | } | 262 | } |
262 | } | 263 | } |
263 | } | 264 | } |
264 | } | 265 | } |
265 | 266 | ||
266 | *num_nodes_ptr = num_nodes; | 267 | *num_nodes_ptr = num_nodes; |
267 | } | 268 | } |
268 | 269 | ||
269 | /* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: | 270 | /* 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 | |||
274 | */ | 275 | */ |
275 | static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family) | 276 | static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family) |
276 | { | 277 | { |
277 | time_t timestamp = unix_time(); | 278 | time_t timestamp = unix_time(); |
278 | int num_nodes = 0, i; | 279 | int num_nodes = 0, i; |
279 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, | 280 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, |
280 | dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes); | 281 | dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes); |
281 | 282 | ||
282 | for (i = 0; i < dht->num_friends; ++i) | 283 | for (i = 0; i < dht->num_friends; ++i) |
283 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, | 284 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, |
284 | dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, | 285 | dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, |
285 | timestamp, &num_nodes); | 286 | timestamp, &num_nodes); |
286 | 287 | ||
287 | return num_nodes; | 288 | return num_nodes; |
288 | } | 289 | } |
@@ -554,11 +555,13 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl | |||
554 | #ifdef TOX_ENABLE_IPV6 | 555 | #ifdef TOX_ENABLE_IPV6 |
555 | Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); | 556 | Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); |
556 | int i, num_nodes_ok = 0; | 557 | int i, num_nodes_ok = 0; |
557 | for(i = 0; i < num_nodes; i++) { | 558 | |
559 | for (i = 0; i < num_nodes; i++) { | ||
558 | memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); | 560 | memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); |
559 | nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; | 561 | nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; |
560 | 562 | ||
561 | IP *node_ip = &nodes_list[i].ip_port.ip; | 563 | IP *node_ip = &nodes_list[i].ip_port.ip; |
564 | |||
562 | if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6)) | 565 | if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6)) |
563 | /* embedded IPv4-in-IPv6 address: return it in regular sendnodes packet */ | 566 | /* embedded IPv4-in-IPv6 address: return it in regular sendnodes packet */ |
564 | nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip6.s6_addr32[3]; | 567 | 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 | |||
574 | /* shouldn't happen */ | 577 | /* shouldn't happen */ |
575 | num_nodes = num_nodes_ok; | 578 | num_nodes = num_nodes_ok; |
576 | } | 579 | } |
580 | |||
577 | #else | 581 | #else |
578 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node4_format_size); | 582 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node4_format_size); |
579 | #endif | 583 | #endif |
@@ -620,7 +624,7 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_ | |||
620 | uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; | 624 | uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; |
621 | uint8_t encrypt[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; | 625 | uint8_t encrypt[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; |
622 | uint8_t nonce[crypto_box_NONCEBYTES]; | 626 | uint8_t nonce[crypto_box_NONCEBYTES]; |
623 | random_nonce(nonce); | 627 | new_nonce(nonce); |
624 | 628 | ||
625 | memcpy(plain, &ping_id, sizeof(ping_id)); | 629 | memcpy(plain, &ping_id, sizeof(ping_id)); |
626 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node_format_size); | 630 | 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 | |||
691 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; | 695 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; |
692 | 696 | ||
693 | size_t Node4_format_size = sizeof(Node4_format); | 697 | size_t Node4_format_size = sizeof(Node4_format); |
698 | |||
694 | if (length > (cid_size + Node4_format_size * MAX_SENT_NODES) || | 699 | if (length > (cid_size + Node4_format_size * MAX_SENT_NODES) || |
695 | ((length - cid_size) % Node4_format_size) != 0 || | 700 | ((length - cid_size) % Node4_format_size) != 0 || |
696 | (length < cid_size + Node4_format_size)) | 701 | (length < cid_size + Node4_format_size)) |
@@ -721,7 +726,8 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 | |||
721 | Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); | 726 | Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); |
722 | 727 | ||
723 | int num_nodes_ok = 0; | 728 | int num_nodes_ok = 0; |
724 | for(i = 0; i < num_nodes; i++) | 729 | |
730 | for (i = 0; i < num_nodes; i++) | ||
725 | if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != ~0)) { | 731 | if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != ~0)) { |
726 | memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); | 732 | memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); |
727 | nodes_list[num_nodes_ok].ip_port.ip.family = AF_INET; | 733 | 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 | |||
735 | /* shouldn't happen */ | 741 | /* shouldn't happen */ |
736 | num_nodes = num_nodes_ok; | 742 | num_nodes = num_nodes_ok; |
737 | } | 743 | } |
744 | |||
738 | #else | 745 | #else |
739 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); | 746 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); |
740 | #endif | 747 | #endif |
@@ -758,6 +765,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, | |||
758 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; | 765 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; |
759 | 766 | ||
760 | size_t Node_format_size = sizeof(Node4_format); | 767 | size_t Node_format_size = sizeof(Node4_format); |
768 | |||
761 | if (length > (cid_size + Node_format_size * MAX_SENT_NODES) || | 769 | if (length > (cid_size + Node_format_size * MAX_SENT_NODES) || |
762 | ((length - cid_size) % Node_format_size) != 0 || | 770 | ((length - cid_size) % Node_format_size) != 0 || |
763 | (length < cid_size + Node_format_size)) | 771 | (length < cid_size + Node_format_size)) |
@@ -964,17 +972,19 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) | |||
964 | send_ping_request(dht->ping, dht->c, ip_port, public_key); | 972 | send_ping_request(dht->ping, dht->c, ip_port, public_key); |
965 | } | 973 | } |
966 | int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, | 974 | int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, |
967 | uint16_t port, uint8_t *public_key) | 975 | uint16_t port, uint8_t *public_key) |
968 | { | 976 | { |
969 | IP_Port ip_port_v64, ip_port_v4; | 977 | IP_Port ip_port_v64, ip_port_v4; |
970 | IP *ip_extra = NULL; | 978 | IP *ip_extra = NULL; |
971 | #ifdef TOX_ENABLE_IPV6 | 979 | #ifdef TOX_ENABLE_IPV6 |
972 | ip_init(&ip_port_v64.ip, ipv6enabled); | 980 | ip_init(&ip_port_v64.ip, ipv6enabled); |
981 | |||
973 | if (ipv6enabled) { | 982 | if (ipv6enabled) { |
974 | ip_port_v64.ip.family = AF_UNSPEC; | 983 | ip_port_v64.ip.family = AF_UNSPEC; |
975 | ip_reset(&ip_port_v4.ip); | 984 | ip_reset(&ip_port_v4.ip); |
976 | ip_extra = &ip_port_v4.ip; | 985 | ip_extra = &ip_port_v4.ip; |
977 | } | 986 | } |
987 | |||
978 | #else | 988 | #else |
979 | ip_init(&ip_port_v64.ip, 0); | 989 | ip_init(&ip_port_v64.ip, 0); |
980 | #endif | 990 | #endif |
@@ -983,14 +993,15 @@ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable | |||
983 | ip_port_v64.port = port; | 993 | ip_port_v64.port = port; |
984 | DHT_bootstrap(dht, ip_port_v64, public_key); | 994 | DHT_bootstrap(dht, ip_port_v64, public_key); |
985 | #ifdef TOX_ENABLE_IPV6 | 995 | #ifdef TOX_ENABLE_IPV6 |
996 | |||
986 | if ((ip_extra != NULL) && ip_isset(ip_extra)) { | 997 | if ((ip_extra != NULL) && ip_isset(ip_extra)) { |
987 | ip_port_v4.port = port; | 998 | ip_port_v4.port = port; |
988 | DHT_bootstrap(dht, ip_port_v4, public_key); | 999 | DHT_bootstrap(dht, ip_port_v4, public_key); |
989 | } | 1000 | } |
1001 | |||
990 | #endif | 1002 | #endif |
991 | return 1; | 1003 | return 1; |
992 | } | 1004 | } else |
993 | else | ||
994 | return 0; | 1005 | return 0; |
995 | } | 1006 | } |
996 | 1007 | ||
@@ -1303,6 +1314,7 @@ static void do_NAT(DHT *dht) | |||
1303 | dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { | 1314 | dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { |
1304 | 1315 | ||
1305 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); | 1316 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); |
1317 | |||
1306 | if (!ip_isset(&ip)) | 1318 | if (!ip_isset(&ip)) |
1307 | continue; | 1319 | continue; |
1308 | 1320 | ||
@@ -1443,12 +1455,13 @@ void DHT_save(DHT *dht, uint8_t *data) | |||
1443 | */ | 1455 | */ |
1444 | int DHT_load(DHT *dht, uint8_t *data, uint32_t size) | 1456 | int DHT_load(DHT *dht, uint8_t *data, uint32_t size) |
1445 | { | 1457 | { |
1446 | if (size < sizeof(dht->close_clientlist)) { | 1458 | if (size < sizeof(dht->close_clientlist)) { |
1447 | fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size); | 1459 | fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size); |
1448 | return -1; | 1460 | return -1; |
1449 | } | 1461 | } |
1450 | 1462 | ||
1451 | uint32_t friendlistsize = size - sizeof(dht->close_clientlist); | 1463 | uint32_t friendlistsize = size - sizeof(dht->close_clientlist); |
1464 | |||
1452 | if (friendlistsize % sizeof(DHT_Friend) != 0) { | 1465 | if (friendlistsize % sizeof(DHT_Friend) != 0) { |
1453 | fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize); | 1466 | fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize); |
1454 | return -1; | 1467 | return -1; |
@@ -1457,6 +1470,7 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size) | |||
1457 | uint32_t i, j; | 1470 | uint32_t i, j; |
1458 | Client_data *client; | 1471 | Client_data *client; |
1459 | uint16_t friends_num = friendlistsize / sizeof(DHT_Friend); | 1472 | uint16_t friends_num = friendlistsize / sizeof(DHT_Friend); |
1473 | |||
1460 | if (friends_num != 0) { | 1474 | if (friends_num != 0) { |
1461 | DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist)); | 1475 | DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist)); |
1462 | 1476 | ||
@@ -1473,6 +1487,7 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size) | |||
1473 | } | 1487 | } |
1474 | 1488 | ||
1475 | Client_data *tempclose_clientlist = (Client_data *)data; | 1489 | Client_data *tempclose_clientlist = (Client_data *)data; |
1490 | |||
1476 | for (i = 0; i < LCLIENT_LIST; ++i) { | 1491 | for (i = 0; i < LCLIENT_LIST; ++i) { |
1477 | if (tempclose_clientlist[i].timestamp != 0) | 1492 | if (tempclose_clientlist[i].timestamp != 0) |
1478 | DHT_bootstrap(dht, tempclose_clientlist[i].ip_port, | 1493 | 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) | |||
80 | i++; | 80 | i++; |
81 | 81 | ||
82 | #ifdef TOX_ENABLE_IPV6 | 82 | #ifdef TOX_ENABLE_IPV6 |
83 | if (source.ip.family == AF_INET) | 83 | |
84 | { | 84 | if (source.ip.family == AF_INET) { |
85 | IP4 ip4 = source.ip.ip4; | 85 | IP4 ip4 = source.ip.ip4; |
86 | #else | 86 | #else |
87 | IP4 ip4 = source.ip; | 87 | IP4 ip4 = source.ip; |
88 | #endif | 88 | #endif |
89 | int k; | 89 | int k; |
90 | |||
90 | for (k = 0; k < 4; k++) { | 91 | for (k = 0; k < 4; k++) { |
91 | id ^= randtable_initget(ludp, i++, ip4.uint8[k]); | 92 | id ^= randtable_initget(ludp, i++, ip4.uint8[k]); |
92 | } | 93 | } |
94 | |||
93 | #ifdef TOX_ENABLE_IPV6 | 95 | #ifdef TOX_ENABLE_IPV6 |
94 | } | 96 | } |
95 | 97 | ||
96 | if (source.ip.family == AF_INET6) | 98 | if (source.ip.family == AF_INET6) |
97 | { | 99 | { |
98 | int k; | 100 | int k; |
101 | |||
99 | for (k = 0; k < 16; k++) { | 102 | for (k = 0; k < 16; k++) { |
100 | id ^= randtable_initget(ludp, i++, source.ip.ip6.s6_addr[k]); | 103 | id ^= randtable_initget(ludp, i++, source.ip.ip6.s6_addr[k]); |
101 | } | 104 | } |
102 | } | 105 | } |
106 | |||
103 | #endif | 107 | #endif |
104 | 108 | ||
105 | /* id can't be zero. */ | 109 | /* id can't be zero. */ |
@@ -116,8 +120,21 @@ static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) | |||
116 | */ | 120 | */ |
117 | static void change_handshake(Lossless_UDP *ludp, IP_Port source) | 121 | static void change_handshake(Lossless_UDP *ludp, IP_Port source) |
118 | { | 122 | { |
119 | uint8_t rand = random_int() % 4; | 123 | #ifdef TOX_ENABLE_IPV6 |
120 | ludp->randtable[rand][((uint8_t *)&source)[rand]] = random_int(); | 124 | uint8_t rand; |
125 | |||
126 | if (source.ip.family == AF_INET) { | ||
127 | rand = 2 + random_int() % 4; | ||
128 | } else if (source.ip.family == AF_INET6) { | ||
129 | rand = 2 + random_int() % 16; | ||
130 | } else { | ||
131 | return; | ||
132 | } | ||
133 | |||
134 | #else | ||
135 | uint8_t rand = 2 + random_int() % 4; | ||
136 | #endif | ||
137 | ludp->randtable[rand][((uint8_t *)&source.ip)[rand]] = random_int(); | ||
121 | } | 138 | } |
122 | 139 | ||
123 | /* | 140 | /* |
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 | |||
73 | int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t length) | 73 | int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t length) |
74 | { | 74 | { |
75 | #ifdef TOX_ENABLE_IPV6 | 75 | #ifdef TOX_ENABLE_IPV6 |
76 | |||
76 | /* socket AF_INET, but target IP NOT: can't send */ | 77 | /* socket AF_INET, but target IP NOT: can't send */ |
77 | if ((net->family == AF_INET) && (ip_port.ip.family != AF_INET)) | 78 | if ((net->family == AF_INET) && (ip_port.ip.family != AF_INET)) |
78 | return 0; | 79 | return -1; |
80 | |||
79 | #endif | 81 | #endif |
80 | 82 | ||
81 | struct sockaddr_storage addr; | 83 | struct sockaddr_storage addr; |
82 | size_t addrsize = 0; | 84 | size_t addrsize = 0; |
83 | 85 | ||
84 | #ifdef TOX_ENABLE_IPV6 | 86 | #ifdef TOX_ENABLE_IPV6 |
87 | |||
85 | if (ip_port.ip.family == AF_INET) { | 88 | if (ip_port.ip.family == AF_INET) { |
86 | if (net->family == AF_INET6) { | 89 | if (net->family == AF_INET6) { |
87 | /* must convert to IPV4-in-IPV6 address */ | 90 | /* 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 | |||
99 | 102 | ||
100 | addr6->sin6_flowinfo = 0; | 103 | addr6->sin6_flowinfo = 0; |
101 | addr6->sin6_scope_id = 0; | 104 | addr6->sin6_scope_id = 0; |
102 | } | 105 | } else { |
103 | else { | ||
104 | IP4 ip4 = ip_port.ip.ip4; | 106 | IP4 ip4 = ip_port.ip.ip4; |
105 | #else | 107 | #else |
106 | IP4 ip4 = ip_port.ip; | 108 | IP4 ip4 = ip_port.ip; |
107 | #endif | 109 | #endif |
108 | addrsize = sizeof(struct sockaddr_in); | 110 | addrsize = sizeof(struct sockaddr_in); |
109 | struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; | 111 | 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 | |||
112 | addr4->sin_port = ip_port.port; | 114 | addr4->sin_port = ip_port.port; |
113 | #ifdef TOX_ENABLE_IPV6 | 115 | #ifdef TOX_ENABLE_IPV6 |
114 | } | 116 | } |
115 | } | 117 | } else if (ip_port.ip.family == AF_INET6) |
116 | else if (ip_port.ip.family == AF_INET6) { | 118 | { |
117 | addrsize = sizeof(struct sockaddr_in6); | 119 | addrsize = sizeof(struct sockaddr_in6); |
118 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; | 120 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; |
119 | addr6->sin6_family = AF_INET6; | 121 | addr6->sin6_family = AF_INET6; |
@@ -122,10 +124,12 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le | |||
122 | 124 | ||
123 | addr6->sin6_flowinfo = 0; | 125 | addr6->sin6_flowinfo = 0; |
124 | addr6->sin6_scope_id = 0; | 126 | addr6->sin6_scope_id = 0; |
125 | } else { | 127 | } else |
128 | { | ||
126 | /* unknown address type*/ | 129 | /* unknown address type*/ |
127 | return 0; | 130 | return -1; |
128 | } | 131 | } |
132 | |||
129 | #endif | 133 | #endif |
130 | 134 | ||
131 | int res = sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize); | 135 | 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 | |||
153 | 157 | ||
154 | if (*(int32_t *)length <= 0) { | 158 | if (*(int32_t *)length <= 0) { |
155 | #ifdef LOGGING | 159 | #ifdef LOGGING |
160 | |||
156 | if ((length < 0) && (errno != EWOULDBLOCK)) { | 161 | if ((length < 0) && (errno != EWOULDBLOCK)) { |
157 | sprintf(logbuffer, "Unexpected error reading from socket: %u, %s\n", errno, strerror(errno)); | 162 | sprintf(logbuffer, "Unexpected error reading from socket: %u, %s\n", errno, strerror(errno)); |
158 | loglog(logbuffer); | 163 | loglog(logbuffer); |
159 | } | 164 | } |
165 | |||
160 | #endif | 166 | #endif |
161 | return -1; /* Nothing received or empty packet. */ | 167 | return -1; /* Nothing received or empty packet. */ |
162 | } | 168 | } |
163 | 169 | ||
164 | #ifdef TOX_ENABLE_IPV6 | 170 | #ifdef TOX_ENABLE_IPV6 |
171 | |||
165 | if (addr.ss_family == AF_INET) { | 172 | if (addr.ss_family == AF_INET) { |
166 | struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; | 173 | struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; |
167 | ip_port->ip.family = addr_in->sin_family; | 174 | ip_port->ip.family = addr_in->sin_family; |
168 | ip_port->ip.ip4.in_addr = addr_in->sin_addr; | 175 | ip_port->ip.ip4.in_addr = addr_in->sin_addr; |
169 | ip_port->port = addr_in->sin_port; | 176 | ip_port->port = addr_in->sin_port; |
170 | } | 177 | } else if (addr.ss_family == AF_INET6) { |
171 | else if (addr.ss_family == AF_INET6) { | ||
172 | struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr; | 178 | struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr; |
173 | ip_port->ip.family = addr_in6->sin6_family; | 179 | ip_port->ip.family = addr_in6->sin6_family; |
174 | ip_port->ip.ip6 = addr_in6->sin6_addr; | 180 | ip_port->ip.ip6 = addr_in6->sin6_addr; |
175 | ip_port->port = addr_in6->sin6_port; | 181 | ip_port->port = addr_in6->sin6_port; |
176 | } | 182 | } else |
177 | else | ||
178 | return -1; | 183 | return -1; |
184 | |||
179 | #else | 185 | #else |
186 | |||
180 | if (addr.ss_family == AF_INET) { | 187 | if (addr.ss_family == AF_INET) { |
181 | struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; | 188 | struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; |
182 | ip_port->ip.in_addr = addr_in->sin_addr; | 189 | ip_port->ip.in_addr = addr_in->sin_addr; |
183 | ip_port->port = addr_in->sin_port; | 190 | ip_port->port = addr_in->sin_port; |
184 | } | 191 | } else |
185 | else | ||
186 | return -1; | 192 | return -1; |
193 | |||
187 | #endif | 194 | #endif |
188 | 195 | ||
189 | #ifdef LOGGING | 196 | #ifdef LOGGING |
@@ -261,17 +268,20 @@ static void at_shutdown(void) | |||
261 | Networking_Core *new_networking(IP ip, uint16_t port) | 268 | Networking_Core *new_networking(IP ip, uint16_t port) |
262 | { | 269 | { |
263 | #ifdef TOX_ENABLE_IPV6 | 270 | #ifdef TOX_ENABLE_IPV6 |
271 | |||
264 | /* maybe check for invalid IPs like 224+.x.y.z? if there is any IP set ever */ | 272 | /* maybe check for invalid IPs like 224+.x.y.z? if there is any IP set ever */ |
265 | if (ip.family != AF_INET && ip.family != AF_INET6) { | 273 | if (ip.family != AF_INET && ip.family != AF_INET6) { |
266 | fprintf(stderr, "Invalid address family: %u\n", ip.family); | 274 | fprintf(stderr, "Invalid address family: %u\n", ip.family); |
267 | return NULL; | 275 | return NULL; |
268 | } | 276 | } |
277 | |||
269 | #endif | 278 | #endif |
270 | 279 | ||
271 | if (at_startup() != 0) | 280 | if (at_startup() != 0) |
272 | return NULL; | 281 | return NULL; |
273 | 282 | ||
274 | Networking_Core *temp = calloc(1, sizeof(Networking_Core)); | 283 | Networking_Core *temp = calloc(1, sizeof(Networking_Core)); |
284 | |||
275 | if (temp == NULL) | 285 | if (temp == NULL) |
276 | return NULL; | 286 | return NULL; |
277 | 287 | ||
@@ -341,11 +351,11 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
341 | struct sockaddr_storage addr; | 351 | struct sockaddr_storage addr; |
342 | size_t addrsize; | 352 | size_t addrsize; |
343 | #ifdef TOX_ENABLE_IPV6 | 353 | #ifdef TOX_ENABLE_IPV6 |
344 | if (temp->family == AF_INET) | 354 | |
345 | { | 355 | if (temp->family == AF_INET) { |
346 | IP4 ip4 = ip.ip4; | 356 | IP4 ip4 = ip.ip4; |
347 | #else | 357 | #else |
348 | IP4 ip4 = ip; | 358 | IP4 ip4 = ip; |
349 | #endif | 359 | #endif |
350 | addrsize = sizeof(struct sockaddr_in); | 360 | addrsize = sizeof(struct sockaddr_in); |
351 | struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; | 361 | struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; |
@@ -355,8 +365,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
355 | 365 | ||
356 | portptr = &addr4->sin_port; | 366 | portptr = &addr4->sin_port; |
357 | #ifdef TOX_ENABLE_IPV6 | 367 | #ifdef TOX_ENABLE_IPV6 |
358 | } | 368 | } else if (temp->family == AF_INET6) |
359 | else if (temp->family == AF_INET6) | ||
360 | { | 369 | { |
361 | addrsize = sizeof(struct sockaddr_in6); | 370 | addrsize = sizeof(struct sockaddr_in6); |
362 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; | 371 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; |
@@ -368,21 +377,23 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
368 | addr6->sin6_scope_id = 0; | 377 | addr6->sin6_scope_id = 0; |
369 | 378 | ||
370 | portptr = &addr6->sin6_port; | 379 | portptr = &addr6->sin6_port; |
371 | } | 380 | } else |
372 | else | ||
373 | return NULL; | 381 | return NULL; |
374 | 382 | ||
375 | if (ip.family == AF_INET6) { | 383 | if (ip.family == AF_INET6) |
384 | { | ||
376 | char ipv6only = 0; | 385 | char ipv6only = 0; |
377 | int res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only)); | 386 | int res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only)); |
378 | #ifdef LOGGING | 387 | #ifdef LOGGING |
388 | |||
379 | if (res < 0) { | 389 | if (res < 0) { |
380 | sprintf(logbuffer, "Failed to enable dual-stack on IPv6 socket, won't be able to receive from/send to IPv4 addresses. (%u, %s)\n", | 390 | sprintf(logbuffer, |
391 | "Failed to enable dual-stack on IPv6 socket, won't be able to receive from/send to IPv4 addresses. (%u, %s)\n", | ||
381 | errno, strerror(errno)); | 392 | errno, strerror(errno)); |
382 | loglog(logbuffer); | 393 | loglog(logbuffer); |
383 | } | 394 | } else |
384 | else | ||
385 | loglog("Embedded IPv4 addresses enabled successfully.\n"); | 395 | loglog("Embedded IPv4 addresses enabled successfully.\n"); |
396 | |||
386 | #endif | 397 | #endif |
387 | 398 | ||
388 | /* multicast local nodes */ | 399 | /* multicast local nodes */ |
@@ -394,15 +405,17 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
394 | mreq.ipv6mr_interface = 0; | 405 | mreq.ipv6mr_interface = 0; |
395 | res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); | 406 | res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); |
396 | #ifdef LOGGING | 407 | #ifdef LOGGING |
408 | |||
397 | if (res < 0) { | 409 | if (res < 0) { |
398 | sprintf(logbuffer, "Failed to activate local multicast membership. (%u, %s)\n", | 410 | sprintf(logbuffer, "Failed to activate local multicast membership. (%u, %s)\n", |
399 | errno, strerror(errno)); | 411 | errno, strerror(errno)); |
400 | loglog(logbuffer); | 412 | loglog(logbuffer); |
401 | } | 413 | } else |
402 | else | ||
403 | loglog("Local multicast group FF02::1 joined successfully.\n"); | 414 | loglog("Local multicast group FF02::1 joined successfully.\n"); |
415 | |||
404 | #endif | 416 | #endif |
405 | } | 417 | } |
418 | |||
406 | #endif | 419 | #endif |
407 | 420 | ||
408 | /* a hanging program or a different user might block the standard port; | 421 | /* 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) | |||
424 | uint16_t port_to_try = port; | 437 | uint16_t port_to_try = port; |
425 | *portptr = htons(port_to_try); | 438 | *portptr = htons(port_to_try); |
426 | int tries, res; | 439 | int tries, res; |
427 | for(tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++) | 440 | |
441 | for (tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++) | ||
428 | { | 442 | { |
429 | res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); | 443 | res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); |
430 | if (!res) | 444 | |
431 | { | 445 | if (!res) { |
432 | temp->port = *portptr; | 446 | temp->port = *portptr; |
433 | #ifdef LOGGING | 447 | #ifdef LOGGING |
434 | sprintf(logbuffer, "Bound successfully to %s:%u.\n", ip_ntoa(&ip), ntohs(temp->port)); | 448 | sprintf(logbuffer, "Bound successfully to %s:%u.\n", ip_ntoa(&ip), ntohs(temp->port)); |
435 | loglog(logbuffer); | 449 | loglog(logbuffer); |
436 | #endif | 450 | #endif |
451 | |||
437 | /* errno isn't reset on success, only set on failure, the failed | 452 | /* errno isn't reset on success, only set on failure, the failed |
438 | * binds with parallel clients yield a -EPERM to the outside if | 453 | * binds with parallel clients yield a -EPERM to the outside if |
439 | * errno isn't cleared here */ | 454 | * errno isn't cleared here */ |
@@ -444,6 +459,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
444 | } | 459 | } |
445 | 460 | ||
446 | port_to_try++; | 461 | port_to_try++; |
462 | |||
447 | if (port_to_try > TOX_PORTRANGE_TO) | 463 | if (port_to_try > TOX_PORTRANGE_TO) |
448 | port_to_try = TOX_PORTRANGE_FROM; | 464 | port_to_try = TOX_PORTRANGE_FROM; |
449 | 465 | ||
@@ -451,7 +467,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
451 | } | 467 | } |
452 | 468 | ||
453 | fprintf(stderr, "Failed to bind socket: %u, %s (IP/Port: %s:%u\n", errno, | 469 | fprintf(stderr, "Failed to bind socket: %u, %s (IP/Port: %s:%u\n", errno, |
454 | strerror(errno), ip_ntoa(&ip), port); | 470 | strerror(errno), ip_ntoa(&ip), port); |
455 | free(temp); | 471 | free(temp); |
456 | return NULL; | 472 | return NULL; |
457 | } | 473 | } |
@@ -480,6 +496,7 @@ int ip_equal(IP *a, IP *b) | |||
480 | return 0; | 496 | return 0; |
481 | 497 | ||
482 | #ifdef TOX_ENABLE_IPV6 | 498 | #ifdef TOX_ENABLE_IPV6 |
499 | |||
483 | if (a->family == AF_INET) | 500 | if (a->family == AF_INET) |
484 | return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr); | 501 | return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr); |
485 | 502 | ||
@@ -589,28 +606,27 @@ const char *ip_ntoa(IP *ip) | |||
589 | { | 606 | { |
590 | if (ip) { | 607 | if (ip) { |
591 | #ifdef TOX_ENABLE_IPV6 | 608 | #ifdef TOX_ENABLE_IPV6 |
609 | |||
592 | if (ip->family == AF_INET) { | 610 | if (ip->family == AF_INET) { |
593 | addresstext[0] = 0; | 611 | addresstext[0] = 0; |
594 | struct in_addr *addr = (struct in_addr *)&ip->ip4; | 612 | struct in_addr *addr = (struct in_addr *)&ip->ip4; |
595 | inet_ntop(ip->family, addr, addresstext, sizeof(addresstext)); | 613 | inet_ntop(ip->family, addr, addresstext, sizeof(addresstext)); |
596 | } | 614 | } else if (ip->family == AF_INET6) { |
597 | else if (ip->family == AF_INET6) { | ||
598 | addresstext[0] = '['; | 615 | addresstext[0] = '['; |
599 | struct in6_addr *addr = (struct in6_addr *)&ip->ip6; | 616 | struct in6_addr *addr = (struct in6_addr *)&ip->ip6; |
600 | inet_ntop(ip->family, addr, &addresstext[1], sizeof(addresstext) - 3); | 617 | inet_ntop(ip->family, addr, &addresstext[1], sizeof(addresstext) - 3); |
601 | size_t len = strlen(addresstext); | 618 | size_t len = strlen(addresstext); |
602 | addresstext[len] = ']'; | 619 | addresstext[len] = ']'; |
603 | addresstext[len + 1] = 0; | 620 | addresstext[len + 1] = 0; |
604 | } | 621 | } else |
605 | else | ||
606 | snprintf(addresstext, sizeof(addresstext), "(IP invalid, family %u)", ip->family); | 622 | snprintf(addresstext, sizeof(addresstext), "(IP invalid, family %u)", ip->family); |
623 | |||
607 | #else | 624 | #else |
608 | addresstext[0] = 0; | 625 | addresstext[0] = 0; |
609 | struct in_addr *addr = (struct in_addr *)&ip; | 626 | struct in_addr *addr = (struct in_addr *)&ip; |
610 | inet_ntop(AF_INET, addr, addresstext, sizeof(addresstext)); | 627 | inet_ntop(AF_INET, addr, addresstext, sizeof(addresstext)); |
611 | #endif | 628 | #endif |
612 | } | 629 | } else |
613 | else | ||
614 | snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)"); | 630 | snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)"); |
615 | 631 | ||
616 | /* brute force protection against lacking termination */ | 632 | /* brute force protection against lacking termination */ |
@@ -639,6 +655,7 @@ int addr_parse_ip(const char *address, IP *to) | |||
639 | 655 | ||
640 | #ifdef TOX_ENABLE_IPV6 | 656 | #ifdef TOX_ENABLE_IPV6 |
641 | struct in_addr addr4; | 657 | struct in_addr addr4; |
658 | |||
642 | if (1 == inet_pton(AF_INET, address, &addr4)) { | 659 | if (1 == inet_pton(AF_INET, address, &addr4)) { |
643 | to->family = AF_INET; | 660 | to->family = AF_INET; |
644 | to->ip4.in_addr = addr4; | 661 | to->ip4.in_addr = addr4; |
@@ -646,17 +663,21 @@ int addr_parse_ip(const char *address, IP *to) | |||
646 | }; | 663 | }; |
647 | 664 | ||
648 | struct in6_addr addr6; | 665 | struct in6_addr addr6; |
666 | |||
649 | if (1 == inet_pton(AF_INET6, address, &addr6)) { | 667 | if (1 == inet_pton(AF_INET6, address, &addr6)) { |
650 | to->family = AF_INET6; | 668 | to->family = AF_INET6; |
651 | to->ip6 = addr6; | 669 | to->ip6 = addr6; |
652 | return 1; | 670 | return 1; |
653 | }; | 671 | }; |
672 | |||
654 | #else | 673 | #else |
655 | struct in_addr addr4; | 674 | struct in_addr addr4; |
675 | |||
656 | if (1 == inet_pton(AF_INET, address, &addr4)) { | 676 | if (1 == inet_pton(AF_INET, address, &addr4)) { |
657 | to->in_addr = addr4; | 677 | to->in_addr = addr4; |
658 | return 1; | 678 | return 1; |
659 | }; | 679 | }; |
680 | |||
660 | #endif | 681 | #endif |
661 | 682 | ||
662 | return 0; | 683 | return 0; |
@@ -714,6 +735,7 @@ int addr_resolve(const char *address, IP *to, IP *extra) | |||
714 | #endif | 735 | #endif |
715 | 736 | ||
716 | rc = getaddrinfo(address, NULL, &hints, &server); | 737 | rc = getaddrinfo(address, NULL, &hints, &server); |
738 | |||
717 | // Lookup failed. | 739 | // Lookup failed. |
718 | if (rc != 0) { | 740 | if (rc != 0) { |
719 | #ifdef __WIN32__ | 741 | #ifdef __WIN32__ |
@@ -729,67 +751,71 @@ int addr_resolve(const char *address, IP *to, IP *extra) | |||
729 | memset(&ip6, 0, sizeof(ip6)); | 751 | memset(&ip6, 0, sizeof(ip6)); |
730 | #endif | 752 | #endif |
731 | 753 | ||
732 | for(walker = server; (walker != NULL) && (rc != 3); walker = walker->ai_next) { | 754 | for (walker = server; (walker != NULL) && (rc != 3); walker = walker->ai_next) { |
733 | switch(walker->ai_family) { | 755 | switch (walker->ai_family) { |
734 | case AF_INET: | 756 | case AF_INET: |
735 | if (walker->ai_family == family) { | 757 | if (walker->ai_family == family) { |
736 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; | 758 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; |
737 | #ifdef TOX_ENABLE_IPV6 | 759 | #ifdef TOX_ENABLE_IPV6 |
738 | to->ip4.in_addr = addr->sin_addr; | 760 | to->ip4.in_addr = addr->sin_addr; |
739 | #else | 761 | #else |
740 | to->in_addr = addr->sin_addr; | 762 | to->in_addr = addr->sin_addr; |
741 | #endif | ||
742 | rc = 3; | ||
743 | } | ||
744 | #ifdef TOX_ENABLE_IPV6 | ||
745 | else if (!(rc & 1)) { | ||
746 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; | ||
747 | to->ip4.in_addr = addr->sin_addr; | ||
748 | rc |= 1; | ||
749 | } | ||
750 | #endif | 763 | #endif |
751 | break; /* switch */ | 764 | rc = 3; |
765 | } | ||
752 | 766 | ||
753 | #ifdef TOX_ENABLE_IPV6 | 767 | #ifdef TOX_ENABLE_IPV6 |
754 | case AF_INET6: | 768 | else if (!(rc & 1)) { |
755 | if (walker->ai_family == family) { | 769 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; |
756 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { | 770 | to->ip4.in_addr = addr->sin_addr; |
757 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; | 771 | rc |= 1; |
758 | to->ip6 = addr->sin6_addr; | ||
759 | rc = 3; | ||
760 | } | 772 | } |
761 | } else if (!(rc & 2)) { | 773 | |
762 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { | 774 | #endif |
763 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; | 775 | break; /* switch */ |
764 | ip6 = addr->sin6_addr; | 776 | #ifdef TOX_ENABLE_IPV6 |
765 | rc |= 2; | 777 | |
778 | case AF_INET6: | ||
779 | if (walker->ai_family == family) { | ||
780 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { | ||
781 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; | ||
782 | to->ip6 = addr->sin6_addr; | ||
783 | rc = 3; | ||
784 | } | ||
785 | } else if (!(rc & 2)) { | ||
786 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { | ||
787 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; | ||
788 | ip6 = addr->sin6_addr; | ||
789 | rc |= 2; | ||
790 | } | ||
766 | } | 791 | } |
767 | } | 792 | |
768 | break; /* switch */ | 793 | break; /* switch */ |
769 | #endif | 794 | #endif |
770 | } | 795 | } |
771 | } | 796 | } |
772 | 797 | ||
773 | #ifdef TOX_ENABLE_IPV6 | 798 | #ifdef TOX_ENABLE_IPV6 |
799 | |||
774 | if (to->family == AF_UNSPEC) { | 800 | if (to->family == AF_UNSPEC) { |
775 | if (rc & 2) { | 801 | if (rc & 2) { |
776 | to->family = AF_INET6; | 802 | to->family = AF_INET6; |
777 | to->ip6 = ip6; | 803 | to->ip6 = ip6; |
804 | |||
778 | if ((rc & 1) && (extra != NULL)) { | 805 | if ((rc & 1) && (extra != NULL)) { |
779 | extra->family = AF_INET; | 806 | extra->family = AF_INET; |
780 | extra->ip4 = ip4; | 807 | extra->ip4 = ip4; |
781 | } | 808 | } |
782 | } | 809 | } else if (rc & 1) { |
783 | else if (rc & 1) { | ||
784 | to->family = AF_INET; | 810 | to->family = AF_INET; |
785 | to->ip4 = ip4; | 811 | to->ip4 = ip4; |
786 | } | 812 | } else |
787 | else | ||
788 | rc = 0; | 813 | rc = 0; |
789 | } | 814 | } |
815 | |||
790 | #endif | 816 | #endif |
791 | 817 | ||
792 | 818 | ||
793 | freeaddrinfo(server); | 819 | freeaddrinfo(server); |
794 | #ifdef __WIN32__ | 820 | #ifdef __WIN32__ |
795 | WSACleanup(); | 821 | WSACleanup(); |
@@ -826,22 +852,22 @@ static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *i | |||
826 | { | 852 | { |
827 | if (res < 0) | 853 | if (res < 0) |
828 | snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x\n", | 854 | snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x\n", |
829 | buffer[0], message, buflen < 999 ? buflen : 999, 'E', | 855 | buffer[0], message, buflen < 999 ? buflen : 999, 'E', |
830 | ip_ntoa(&ip_port->ip), ntohs(ip_port->port), errno, | 856 | ip_ntoa(&ip_port->ip), ntohs(ip_port->port), errno, |
831 | strerror(errno), buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, | 857 | strerror(errno), buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, |
832 | buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); | 858 | buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); |
833 | else if ((res > 0) && (res <= buflen)) | 859 | else if ((res > 0) && (res <= buflen)) |
834 | snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x\n", | 860 | snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x\n", |
835 | buffer[0], message, res < 999 ? res : 999, res < buflen ? '<' : '=', | 861 | buffer[0], message, res < 999 ? res : 999, res < buflen ? '<' : '=', |
836 | ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0, | 862 | ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0, |
837 | "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, | 863 | "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, |
838 | buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); | 864 | buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); |
839 | else /* empty or overwrite */ | 865 | else /* empty or overwrite */ |
840 | snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %u%c%u %s:%u (%u: %s) | %04x%04x\n", | 866 | snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %u%c%u %s:%u (%u: %s) | %04x%04x\n", |
841 | buffer[0], message, res, !res ? '0' : '>', buflen, | 867 | buffer[0], message, res, !res ? '0' : '>', buflen, |
842 | ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0, | 868 | ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0, |
843 | "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, | 869 | "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, |
844 | buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); | 870 | buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0); |
845 | 871 | ||
846 | logbuffer[sizeof(logbuffer) - 1] = 0; | 872 | logbuffer[sizeof(logbuffer) - 1] = 0; |
847 | loglog(logbuffer); | 873 | loglog(logbuffer); |