diff options
Diffstat (limited to 'toxcore/network.c')
-rw-r--r-- | toxcore/network.c | 111 |
1 files changed, 82 insertions, 29 deletions
diff --git a/toxcore/network.c b/toxcore/network.c index d267a216..6df13fb8 100644 --- a/toxcore/network.c +++ b/toxcore/network.c | |||
@@ -37,16 +37,38 @@ | |||
37 | #include "logger.h" | 37 | #include "logger.h" |
38 | #include "util.h" | 38 | #include "util.h" |
39 | 39 | ||
40 | #if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32) | 40 | #include <assert.h> |
41 | #include <errno.h> | ||
42 | #endif | ||
43 | |||
44 | #ifdef __APPLE__ | 41 | #ifdef __APPLE__ |
45 | #include <mach/clock.h> | 42 | #include <mach/clock.h> |
46 | #include <mach/mach.h> | 43 | #include <mach/mach.h> |
47 | #endif | 44 | #endif |
48 | 45 | ||
49 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) | 46 | #ifndef IPV6_ADD_MEMBERSHIP |
47 | #ifdef IPV6_JOIN_GROUP | ||
48 | #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP | ||
49 | #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP | ||
50 | #endif | ||
51 | #endif | ||
52 | |||
53 | #if !(defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) | ||
54 | |||
55 | #include <arpa/inet.h> | ||
56 | #include <errno.h> | ||
57 | #include <fcntl.h> | ||
58 | #include <netinet/in.h> | ||
59 | #include <sys/time.h> | ||
60 | #include <sys/types.h> | ||
61 | #include <sys/socket.h> | ||
62 | |||
63 | #else | ||
64 | |||
65 | #ifndef IPV6_V6ONLY | ||
66 | #define IPV6_V6ONLY 27 | ||
67 | #endif | ||
68 | |||
69 | #ifndef EWOULDBLOCK | ||
70 | #define EWOULDBLOCK WSAEWOULDBLOCK | ||
71 | #endif | ||
50 | 72 | ||
51 | static const char *inet_ntop(sa_family_t family, const void *addr, char *buf, size_t bufsize) | 73 | static const char *inet_ntop(sa_family_t family, const void *addr, char *buf, size_t bufsize) |
52 | { | 74 | { |
@@ -123,7 +145,7 @@ static int inet_pton(sa_family_t family, const char *addrString, void *addrbuf) | |||
123 | * return 1 if valid | 145 | * return 1 if valid |
124 | * return 0 if not valid | 146 | * return 0 if not valid |
125 | */ | 147 | */ |
126 | int sock_valid(sock_t sock) | 148 | int sock_valid(Socket sock) |
127 | { | 149 | { |
128 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) | 150 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) |
129 | 151 | ||
@@ -140,7 +162,7 @@ int sock_valid(sock_t sock) | |||
140 | 162 | ||
141 | /* Close the socket. | 163 | /* Close the socket. |
142 | */ | 164 | */ |
143 | void kill_sock(sock_t sock) | 165 | void kill_sock(Socket sock) |
144 | { | 166 | { |
145 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) | 167 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) |
146 | closesocket(sock); | 168 | closesocket(sock); |
@@ -154,7 +176,7 @@ void kill_sock(sock_t sock) | |||
154 | * return 1 on success | 176 | * return 1 on success |
155 | * return 0 on failure | 177 | * return 0 on failure |
156 | */ | 178 | */ |
157 | int set_socket_nonblock(sock_t sock) | 179 | int set_socket_nonblock(Socket sock) |
158 | { | 180 | { |
159 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) | 181 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) |
160 | u_long mode = 1; | 182 | u_long mode = 1; |
@@ -169,7 +191,7 @@ int set_socket_nonblock(sock_t sock) | |||
169 | * return 1 on success | 191 | * return 1 on success |
170 | * return 0 on failure | 192 | * return 0 on failure |
171 | */ | 193 | */ |
172 | int set_socket_nosigpipe(sock_t sock) | 194 | int set_socket_nosigpipe(Socket sock) |
173 | { | 195 | { |
174 | #if defined(__MACH__) | 196 | #if defined(__MACH__) |
175 | int set = 1; | 197 | int set = 1; |
@@ -184,7 +206,7 @@ int set_socket_nosigpipe(sock_t sock) | |||
184 | * return 1 on success | 206 | * return 1 on success |
185 | * return 0 on failure | 207 | * return 0 on failure |
186 | */ | 208 | */ |
187 | int set_socket_reuseaddr(sock_t sock) | 209 | int set_socket_reuseaddr(Socket sock) |
188 | { | 210 | { |
189 | int set = 1; | 211 | int set = 1; |
190 | return (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&set, sizeof(set)) == 0); | 212 | return (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&set, sizeof(set)) == 0); |
@@ -195,7 +217,7 @@ int set_socket_reuseaddr(sock_t sock) | |||
195 | * return 1 on success | 217 | * return 1 on success |
196 | * return 0 on failure | 218 | * return 0 on failure |
197 | */ | 219 | */ |
198 | int set_socket_dualstack(sock_t sock) | 220 | int set_socket_dualstack(Socket sock) |
199 | { | 221 | { |
200 | int ipv6only = 0; | 222 | int ipv6only = 0; |
201 | socklen_t optsize = sizeof(ipv6only); | 223 | socklen_t optsize = sizeof(ipv6only); |
@@ -310,6 +332,28 @@ static void loglogdata(Logger *log, const char *message, const uint8_t *buffer, | |||
310 | } | 332 | } |
311 | } | 333 | } |
312 | 334 | ||
335 | void get_ip4(IP4 *result, const struct in_addr *addr) | ||
336 | { | ||
337 | result->uint32 = addr->s_addr; | ||
338 | } | ||
339 | |||
340 | void get_ip6(IP6 *result, const struct in6_addr *addr) | ||
341 | { | ||
342 | assert(sizeof(result->uint8) == sizeof(addr->s6_addr)); | ||
343 | memcpy(result->uint8, addr->s6_addr, sizeof(result->uint8)); | ||
344 | } | ||
345 | |||
346 | |||
347 | void fill_addr4(IP4 ip, struct in_addr *addr) | ||
348 | { | ||
349 | addr->s_addr = ip.uint32; | ||
350 | } | ||
351 | |||
352 | void fill_addr6(IP6 ip, struct in6_addr *addr) | ||
353 | { | ||
354 | assert(sizeof(ip.uint8) == sizeof(addr->s6_addr)); | ||
355 | memcpy(addr->s6_addr, ip.uint8, sizeof(ip.uint8)); | ||
356 | } | ||
313 | 357 | ||
314 | /* Basic network functions: | 358 | /* Basic network functions: |
315 | * Function to send packet(data) of length length to ip_port. | 359 | * Function to send packet(data) of length length to ip_port. |
@@ -346,7 +390,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1 | |||
346 | ip6.uint32[1] = 0; | 390 | ip6.uint32[1] = 0; |
347 | ip6.uint32[2] = htonl(0xFFFF); | 391 | ip6.uint32[2] = htonl(0xFFFF); |
348 | ip6.uint32[3] = ip_port.ip.ip4.uint32; | 392 | ip6.uint32[3] = ip_port.ip.ip4.uint32; |
349 | addr6->sin6_addr = ip6.in6_addr; | 393 | fill_addr6(ip6, &addr6->sin6_addr); |
350 | 394 | ||
351 | addr6->sin6_flowinfo = 0; | 395 | addr6->sin6_flowinfo = 0; |
352 | addr6->sin6_scope_id = 0; | 396 | addr6->sin6_scope_id = 0; |
@@ -355,7 +399,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1 | |||
355 | 399 | ||
356 | addrsize = sizeof(struct sockaddr_in); | 400 | addrsize = sizeof(struct sockaddr_in); |
357 | addr4->sin_family = AF_INET; | 401 | addr4->sin_family = AF_INET; |
358 | addr4->sin_addr = ip_port.ip.ip4.in_addr; | 402 | fill_addr4(ip_port.ip.ip4, &addr4->sin_addr); |
359 | addr4->sin_port = ip_port.port; | 403 | addr4->sin_port = ip_port.port; |
360 | } | 404 | } |
361 | } else if (ip_port.ip.family == AF_INET6) { | 405 | } else if (ip_port.ip.family == AF_INET6) { |
@@ -364,7 +408,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1 | |||
364 | addrsize = sizeof(struct sockaddr_in6); | 408 | addrsize = sizeof(struct sockaddr_in6); |
365 | addr6->sin6_family = AF_INET6; | 409 | addr6->sin6_family = AF_INET6; |
366 | addr6->sin6_port = ip_port.port; | 410 | addr6->sin6_port = ip_port.port; |
367 | addr6->sin6_addr = ip_port.ip.ip6.in6_addr; | 411 | fill_addr6(ip_port.ip.ip6, &addr6->sin6_addr); |
368 | 412 | ||
369 | addr6->sin6_flowinfo = 0; | 413 | addr6->sin6_flowinfo = 0; |
370 | addr6->sin6_scope_id = 0; | 414 | addr6->sin6_scope_id = 0; |
@@ -385,7 +429,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1 | |||
385 | * Packet data is put into data. | 429 | * Packet data is put into data. |
386 | * Packet length is put into length. | 430 | * Packet length is put into length. |
387 | */ | 431 | */ |
388 | static int receivepacket(Logger *log, sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) | 432 | static int receivepacket(Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) |
389 | { | 433 | { |
390 | memset(ip_port, 0, sizeof(IP_Port)); | 434 | memset(ip_port, 0, sizeof(IP_Port)); |
391 | struct sockaddr_storage addr; | 435 | struct sockaddr_storage addr; |
@@ -412,12 +456,12 @@ static int receivepacket(Logger *log, sock_t sock, IP_Port *ip_port, uint8_t *da | |||
412 | struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; | 456 | struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; |
413 | 457 | ||
414 | ip_port->ip.family = addr_in->sin_family; | 458 | ip_port->ip.family = addr_in->sin_family; |
415 | ip_port->ip.ip4.in_addr = addr_in->sin_addr; | 459 | get_ip4(&ip_port->ip.ip4, &addr_in->sin_addr); |
416 | ip_port->port = addr_in->sin_port; | 460 | ip_port->port = addr_in->sin_port; |
417 | } else if (addr.ss_family == AF_INET6) { | 461 | } else if (addr.ss_family == AF_INET6) { |
418 | struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr; | 462 | struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr; |
419 | ip_port->ip.family = addr_in6->sin6_family; | 463 | ip_port->ip.family = addr_in6->sin6_family; |
420 | ip_port->ip.ip6.in6_addr = addr_in6->sin6_addr; | 464 | get_ip6(&ip_port->ip.ip6, &addr_in6->sin6_addr); |
421 | ip_port->port = addr_in6->sin6_port; | 465 | ip_port->port = addr_in6->sin6_port; |
422 | 466 | ||
423 | if (IPV6_IPV4_IN_V6(ip_port->ip.ip6)) { | 467 | if (IPV6_IPV4_IN_V6(ip_port->ip.ip6)) { |
@@ -634,7 +678,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 | |||
634 | addrsize = sizeof(struct sockaddr_in); | 678 | addrsize = sizeof(struct sockaddr_in); |
635 | addr4->sin_family = AF_INET; | 679 | addr4->sin_family = AF_INET; |
636 | addr4->sin_port = 0; | 680 | addr4->sin_port = 0; |
637 | addr4->sin_addr = ip.ip4.in_addr; | 681 | fill_addr4(ip.ip4, &addr4->sin_addr); |
638 | 682 | ||
639 | portptr = &addr4->sin_port; | 683 | portptr = &addr4->sin_port; |
640 | } else if (temp->family == AF_INET6) { | 684 | } else if (temp->family == AF_INET6) { |
@@ -643,7 +687,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 | |||
643 | addrsize = sizeof(struct sockaddr_in6); | 687 | addrsize = sizeof(struct sockaddr_in6); |
644 | addr6->sin6_family = AF_INET6; | 688 | addr6->sin6_family = AF_INET6; |
645 | addr6->sin6_port = 0; | 689 | addr6->sin6_port = 0; |
646 | addr6->sin6_addr = ip.ip6.in6_addr; | 690 | fill_addr6(ip.ip6, &addr6->sin6_addr); |
647 | 691 | ||
648 | addr6->sin6_flowinfo = 0; | 692 | addr6->sin6_flowinfo = 0; |
649 | addr6->sin6_scope_id = 0; | 693 | addr6->sin6_scope_id = 0; |
@@ -767,11 +811,16 @@ int ip_equal(const IP *a, const IP *b) | |||
767 | /* same family */ | 811 | /* same family */ |
768 | if (a->family == b->family) { | 812 | if (a->family == b->family) { |
769 | if (a->family == AF_INET) { | 813 | if (a->family == AF_INET) { |
770 | return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr); | 814 | struct in_addr addr_a; |
815 | struct in_addr addr_b; | ||
816 | fill_addr4(a->ip4, &addr_a); | ||
817 | fill_addr4(b->ip4, &addr_b); | ||
818 | return addr_a.s_addr == addr_b.s_addr; | ||
771 | } | 819 | } |
772 | 820 | ||
773 | if (a->family == AF_INET6) { | 821 | if (a->family == AF_INET6) { |
774 | return a->ip6.uint64[0] == b->ip6.uint64[0] && a->ip6.uint64[1] == b->ip6.uint64[1]; | 822 | return a->ip6.uint64[0] == b->ip6.uint64[0] && |
823 | a->ip6.uint64[1] == b->ip6.uint64[1]; | ||
775 | } | 824 | } |
776 | 825 | ||
777 | return 0; | 826 | return 0; |
@@ -780,11 +829,15 @@ int ip_equal(const IP *a, const IP *b) | |||
780 | /* different family: check on the IPv6 one if it is the IPv4 one embedded */ | 829 | /* different family: check on the IPv6 one if it is the IPv4 one embedded */ |
781 | if ((a->family == AF_INET) && (b->family == AF_INET6)) { | 830 | if ((a->family == AF_INET) && (b->family == AF_INET6)) { |
782 | if (IPV6_IPV4_IN_V6(b->ip6)) { | 831 | if (IPV6_IPV4_IN_V6(b->ip6)) { |
783 | return (a->ip4.in_addr.s_addr == b->ip6.uint32[3]); | 832 | struct in_addr addr_a; |
833 | fill_addr4(a->ip4, &addr_a); | ||
834 | return addr_a.s_addr == b->ip6.uint32[3]; | ||
784 | } | 835 | } |
785 | } else if ((a->family == AF_INET6) && (b->family == AF_INET)) { | 836 | } else if ((a->family == AF_INET6) && (b->family == AF_INET)) { |
786 | if (IPV6_IPV4_IN_V6(a->ip6)) { | 837 | if (IPV6_IPV4_IN_V6(a->ip6)) { |
787 | return (a->ip6.uint32[3] == b->ip4.in_addr.s_addr); | 838 | struct in_addr addr_b; |
839 | fill_addr4(b->ip4, &addr_b); | ||
840 | return a->ip6.uint32[3] == addr_b.s_addr; | ||
788 | } | 841 | } |
789 | } | 842 | } |
790 | 843 | ||
@@ -976,7 +1029,7 @@ int addr_parse_ip(const char *address, IP *to) | |||
976 | 1029 | ||
977 | if (1 == inet_pton(AF_INET, address, &addr4)) { | 1030 | if (1 == inet_pton(AF_INET, address, &addr4)) { |
978 | to->family = AF_INET; | 1031 | to->family = AF_INET; |
979 | to->ip4.in_addr = addr4; | 1032 | get_ip4(&to->ip4, &addr4); |
980 | return 1; | 1033 | return 1; |
981 | } | 1034 | } |
982 | 1035 | ||
@@ -984,7 +1037,7 @@ int addr_parse_ip(const char *address, IP *to) | |||
984 | 1037 | ||
985 | if (1 == inet_pton(AF_INET6, address, &addr6)) { | 1038 | if (1 == inet_pton(AF_INET6, address, &addr6)) { |
986 | to->family = AF_INET6; | 1039 | to->family = AF_INET6; |
987 | to->ip6.in6_addr = addr6; | 1040 | get_ip6(&to->ip6, &addr6); |
988 | return 1; | 1041 | return 1; |
989 | } | 1042 | } |
990 | 1043 | ||
@@ -1048,12 +1101,12 @@ int addr_resolve(const char *address, IP *to, IP *extra) | |||
1048 | case AF_INET: | 1101 | case AF_INET: |
1049 | if (walker->ai_family == family) { /* AF_INET requested, done */ | 1102 | if (walker->ai_family == family) { /* AF_INET requested, done */ |
1050 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; | 1103 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; |
1051 | to->ip4.in_addr = addr->sin_addr; | 1104 | get_ip4(&to->ip4, &addr->sin_addr); |
1052 | result = TOX_ADDR_RESOLVE_INET; | 1105 | result = TOX_ADDR_RESOLVE_INET; |
1053 | done = 1; | 1106 | done = 1; |
1054 | } else if (!(result & TOX_ADDR_RESOLVE_INET)) { /* AF_UNSPEC requested, store away */ | 1107 | } else if (!(result & TOX_ADDR_RESOLVE_INET)) { /* AF_UNSPEC requested, store away */ |
1055 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; | 1108 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; |
1056 | ip4.ip4.in_addr = addr->sin_addr; | 1109 | get_ip4(&ip4.ip4, &addr->sin_addr); |
1057 | result |= TOX_ADDR_RESOLVE_INET; | 1110 | result |= TOX_ADDR_RESOLVE_INET; |
1058 | } | 1111 | } |
1059 | 1112 | ||
@@ -1063,14 +1116,14 @@ int addr_resolve(const char *address, IP *to, IP *extra) | |||
1063 | if (walker->ai_family == family) { /* AF_INET6 requested, done */ | 1116 | if (walker->ai_family == family) { /* AF_INET6 requested, done */ |
1064 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { | 1117 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { |
1065 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; | 1118 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; |
1066 | to->ip6.in6_addr = addr->sin6_addr; | 1119 | get_ip6(&to->ip6, &addr->sin6_addr); |
1067 | result = TOX_ADDR_RESOLVE_INET6; | 1120 | result = TOX_ADDR_RESOLVE_INET6; |
1068 | done = 1; | 1121 | done = 1; |
1069 | } | 1122 | } |
1070 | } else if (!(result & TOX_ADDR_RESOLVE_INET6)) { /* AF_UNSPEC requested, store away */ | 1123 | } else if (!(result & TOX_ADDR_RESOLVE_INET6)) { /* AF_UNSPEC requested, store away */ |
1071 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { | 1124 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { |
1072 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; | 1125 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; |
1073 | ip6.ip6.in6_addr = addr->sin6_addr; | 1126 | get_ip6(&ip6.ip6, &addr->sin6_addr); |
1074 | result |= TOX_ADDR_RESOLVE_INET6; | 1127 | result |= TOX_ADDR_RESOLVE_INET6; |
1075 | } | 1128 | } |
1076 | } | 1129 | } |