diff options
Diffstat (limited to 'toxcore/network.c')
-rw-r--r-- | toxcore/network.c | 198 |
1 files changed, 112 insertions, 86 deletions
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); |