summaryrefslogtreecommitdiff
path: root/toxcore/network.c
diff options
context:
space:
mode:
authoriphydf <iphydf@users.noreply.github.com>2018-02-27 02:07:59 +0000
committeriphydf <iphydf@users.noreply.github.com>2018-05-20 15:42:42 +0000
commitbe797d4b039b40d2c876f0a71cd1e48454a74065 (patch)
treec759c0f15a3ac0285e0bd941dc3edad06ade015d /toxcore/network.c
parent291a849a5a0afb4450bcd0d0c50b7aeccaac04f5 (diff)
Move system header includes from network.h to network.c
Diffstat (limited to 'toxcore/network.c')
-rw-r--r--toxcore/network.c263
1 files changed, 167 insertions, 96 deletions
diff --git a/toxcore/network.c b/toxcore/network.c
index 984071d4..f357d887 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -38,44 +38,65 @@
38#define _WIN32_WINNT 0x501 38#define _WIN32_WINNT 0x501
39#endif 39#endif
40 40
41#include "network.h" 41#if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
42#define OS_WIN32
43#endif
42 44
43#include "logger.h" 45#ifdef OS_WIN32
44#include "util.h" 46#ifndef WINVER
47//Windows XP
48#define WINVER 0x0501
49#endif
50#endif
45 51
46#include <assert.h> 52#ifdef PLAN9
47#ifdef __APPLE__ 53#include <u.h> // Plan 9 requires this is imported first
48#include <mach/clock.h> 54// Comment line here to avoid reordering by source code formatters.
49#include <mach/mach.h> 55#include <libc.h>
50#endif 56#endif
51 57
52#ifndef IPV6_ADD_MEMBERSHIP 58#ifdef OS_WIN32 /* Put win32 includes here */
53#ifdef IPV6_JOIN_GROUP 59// The mingw32/64 Windows library warns about including winsock2.h after
54#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP 60// windows.h even though with the above it's a valid thing to do. So, to make
61// mingw32 headers happy, we include winsock2.h first.
62#include <winsock2.h>
63// Comment line here to avoid reordering by source code formatters.
64#include <windows.h>
65#include <ws2tcpip.h>
55#endif 66#endif
67
68#include "network.h"
69
70#ifdef __APPLE__
71#include <mach/clock.h>
72#include <mach/mach.h>
56#endif 73#endif
57 74
58#if !(defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) 75#if !defined(OS_WIN32)
59 76
77#include <arpa/inet.h>
60#include <errno.h> 78#include <errno.h>
61#include <fcntl.h> 79#include <fcntl.h>
62#include <netdb.h> 80#include <netdb.h>
81#include <netinet/in.h>
82#include <sys/ioctl.h>
83#include <sys/socket.h>
63#include <sys/time.h> 84#include <sys/time.h>
64#include <sys/types.h> 85#include <sys/types.h>
86#include <unistd.h>
65 87
66#define TOX_EWOULDBLOCK EWOULDBLOCK 88#define TOX_EWOULDBLOCK EWOULDBLOCK
67 89
68#else 90#else
69
70#ifndef IPV6_V6ONLY 91#ifndef IPV6_V6ONLY
71#define IPV6_V6ONLY 27 92#define IPV6_V6ONLY 27
72#endif 93#endif
73 94
74#define TOX_EWOULDBLOCK WSAEWOULDBLOCK 95#define TOX_EWOULDBLOCK WSAEWOULDBLOCK
75 96
76static const char *inet_ntop(Family family, const void *addr, char *buf, size_t bufsize) 97static const char *inet_ntop(int family, const void *addr, char *buf, size_t bufsize)
77{ 98{
78 if (family == TOX_AF_INET) { 99 if (family == AF_INET) {
79 struct sockaddr_in saddr; 100 struct sockaddr_in saddr;
80 memset(&saddr, 0, sizeof(saddr)); 101 memset(&saddr, 0, sizeof(saddr));
81 102
@@ -89,7 +110,7 @@ static const char *inet_ntop(Family family, const void *addr, char *buf, size_t
89 } 110 }
90 111
91 return buf; 112 return buf;
92 } else if (family == TOX_AF_INET6) { 113 } else if (family == AF_INET6) {
93 struct sockaddr_in6 saddr; 114 struct sockaddr_in6 saddr;
94 memset(&saddr, 0, sizeof(saddr)); 115 memset(&saddr, 0, sizeof(saddr));
95 116
@@ -108,9 +129,9 @@ static const char *inet_ntop(Family family, const void *addr, char *buf, size_t
108 return nullptr; 129 return nullptr;
109} 130}
110 131
111static int inet_pton(Family family, const char *addrString, void *addrbuf) 132static int inet_pton(int family, const char *addrString, void *addrbuf)
112{ 133{
113 if (family == TOX_AF_INET) { 134 if (family == AF_INET) {
114 struct sockaddr_in saddr; 135 struct sockaddr_in saddr;
115 memset(&saddr, 0, sizeof(saddr)); 136 memset(&saddr, 0, sizeof(saddr));
116 137
@@ -123,7 +144,7 @@ static int inet_pton(Family family, const char *addrString, void *addrbuf)
123 *(struct in_addr *)addrbuf = saddr.sin_addr; 144 *(struct in_addr *)addrbuf = saddr.sin_addr;
124 145
125 return 1; 146 return 1;
126 } else if (family == TOX_AF_INET6) { 147 } else if (family == AF_INET6) {
127 struct sockaddr_in6 saddr; 148 struct sockaddr_in6 saddr;
128 memset(&saddr, 0, sizeof(saddr)); 149 memset(&saddr, 0, sizeof(saddr));
129 150
@@ -143,6 +164,25 @@ static int inet_pton(Family family, const char *addrString, void *addrbuf)
143 164
144#endif 165#endif
145 166
167#include <assert.h>
168#include <stdio.h>
169#include <stdlib.h>
170#include <string.h>
171
172#include "logger.h"
173#include "util.h"
174
175// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD
176#if !defined(MSG_NOSIGNAL)
177#define MSG_NOSIGNAL 0
178#endif
179
180#ifndef IPV6_ADD_MEMBERSHIP
181#ifdef IPV6_JOIN_GROUP
182#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
183#endif
184#endif
185
146#if TOX_INET6_ADDRSTRLEN < INET6_ADDRSTRLEN 186#if TOX_INET6_ADDRSTRLEN < INET6_ADDRSTRLEN
147#error TOX_INET6_ADDRSTRLEN should be greater or equal to INET6_ADDRSTRLEN (#INET6_ADDRSTRLEN) 187#error TOX_INET6_ADDRSTRLEN should be greater or equal to INET6_ADDRSTRLEN (#INET6_ADDRSTRLEN)
148#endif 188#endif
@@ -153,8 +193,40 @@ static int inet_pton(Family family, const char *addrString, void *addrbuf)
153 193
154static int make_proto(int proto); 194static int make_proto(int proto);
155static int make_socktype(int type); 195static int make_socktype(int type);
156static int make_family(int tox_family); 196
157static int make_tox_family(int family); 197static int make_family(Family tox_family)
198{
199 switch (tox_family) {
200 case TOX_AF_INET:
201 return AF_INET;
202
203 case TOX_AF_INET6:
204 return AF_INET6;
205
206 case TOX_AF_UNSPEC:
207 return AF_UNSPEC;
208
209 default:
210 return tox_family;
211 }
212}
213
214static Family make_tox_family(int family)
215{
216 switch (family) {
217 case AF_INET:
218 return TOX_AF_INET;
219
220 case AF_INET6:
221 return TOX_AF_INET6;
222
223 case AF_UNSPEC:
224 return TOX_AF_UNSPEC;
225
226 default:
227 return family;
228 }
229}
158 230
159static void get_ip4(IP4 *result, const struct in_addr *addr) 231static void get_ip4(IP4 *result, const struct in_addr *addr)
160{ 232{
@@ -201,6 +273,14 @@ IP6 get_ip6_loopback(void)
201 return loopback; 273 return loopback;
202} 274}
203 275
276const Socket net_invalid_socket = {
277#ifdef OS_WIN32
278 (int)INVALID_SOCKET,
279#else
280 -1,
281#endif
282};
283
204/* Check if socket is valid. 284/* Check if socket is valid.
205 * 285 *
206 * return 1 if valid 286 * return 1 if valid
@@ -208,27 +288,17 @@ IP6 get_ip6_loopback(void)
208 */ 288 */
209int sock_valid(Socket sock) 289int sock_valid(Socket sock)
210{ 290{
211#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 291 return sock.socket != net_invalid_socket.socket;
212
213 if (sock == INVALID_SOCKET) {
214#else
215
216 if (sock < 0) {
217#endif
218 return 0;
219 }
220
221 return 1;
222} 292}
223 293
224/* Close the socket. 294/* Close the socket.
225 */ 295 */
226void kill_sock(Socket sock) 296void kill_sock(Socket sock)
227{ 297{
228#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 298#ifdef OS_WIN32
229 closesocket(sock); 299 closesocket(sock.socket);
230#else 300#else
231 close(sock); 301 close(sock.socket);
232#endif 302#endif
233} 303}
234 304
@@ -239,11 +309,11 @@ void kill_sock(Socket sock)
239 */ 309 */
240int set_socket_nonblock(Socket sock) 310int set_socket_nonblock(Socket sock)
241{ 311{
242#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 312#ifdef OS_WIN32
243 u_long mode = 1; 313 u_long mode = 1;
244 return (ioctlsocket(sock, FIONBIO, &mode) == 0); 314 return (ioctlsocket(sock.socket, FIONBIO, &mode) == 0);
245#else 315#else
246 return (fcntl(sock, F_SETFL, O_NONBLOCK, 1) == 0); 316 return (fcntl(sock.socket, F_SETFL, O_NONBLOCK, 1) == 0);
247#endif 317#endif
248} 318}
249 319
@@ -256,7 +326,7 @@ int set_socket_nosigpipe(Socket sock)
256{ 326{
257#if defined(__MACH__) 327#if defined(__MACH__)
258 int set = 1; 328 int set = 1;
259 return (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (const char *)&set, sizeof(int)) == 0); 329 return setsockopt(sock.socket, SOL_SOCKET, SO_NOSIGPIPE, (const char *)&set, sizeof(int)) == 0;
260#else 330#else
261 return 1; 331 return 1;
262#endif 332#endif
@@ -270,7 +340,7 @@ int set_socket_nosigpipe(Socket sock)
270int set_socket_reuseaddr(Socket sock) 340int set_socket_reuseaddr(Socket sock)
271{ 341{
272 int set = 1; 342 int set = 1;
273 return (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&set, sizeof(set)) == 0); 343 return setsockopt(sock.socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&set, sizeof(set)) == 0;
274} 344}
275 345
276/* Set socket to dual (IPv4 + IPv6 socket) 346/* Set socket to dual (IPv4 + IPv6 socket)
@@ -282,14 +352,14 @@ int set_socket_dualstack(Socket sock)
282{ 352{
283 int ipv6only = 0; 353 int ipv6only = 0;
284 socklen_t optsize = sizeof(ipv6only); 354 socklen_t optsize = sizeof(ipv6only);
285 int res = getsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, &optsize); 355 int res = getsockopt(sock.socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, &optsize);
286 356
287 if ((res == 0) && (ipv6only == 0)) { 357 if ((res == 0) && (ipv6only == 0)) {
288 return 1; 358 return 1;
289 } 359 }
290 360
291 ipv6only = 0; 361 ipv6only = 0;
292 return (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&ipv6only, sizeof(ipv6only)) == 0); 362 return setsockopt(sock.socket, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&ipv6only, sizeof(ipv6only)) == 0;
293} 363}
294 364
295 365
@@ -297,7 +367,7 @@ int set_socket_dualstack(Socket sock)
297static uint64_t current_time_actual(void) 367static uint64_t current_time_actual(void)
298{ 368{
299 uint64_t time; 369 uint64_t time;
300#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 370#ifdef OS_WIN32
301 /* This probably works fine */ 371 /* This probably works fine */
302 FILETIME ft; 372 FILETIME ft;
303 GetSystemTimeAsFileTime(&ft); 373 GetSystemTimeAsFileTime(&ft);
@@ -315,7 +385,7 @@ static uint64_t current_time_actual(void)
315} 385}
316 386
317 387
318#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 388#ifdef OS_WIN32
319static uint64_t last_monotime; 389static uint64_t last_monotime;
320static uint64_t add_monotime; 390static uint64_t add_monotime;
321#endif 391#endif
@@ -324,7 +394,7 @@ static uint64_t add_monotime;
324uint64_t current_time_monotonic(void) 394uint64_t current_time_monotonic(void)
325{ 395{
326 uint64_t time; 396 uint64_t time;
327#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 397#ifdef OS_WIN32
328 uint64_t old_add_monotime = add_monotime; 398 uint64_t old_add_monotime = add_monotime;
329 time = (uint64_t)GetTickCount() + add_monotime; 399 time = (uint64_t)GetTickCount() + add_monotime;
330 400
@@ -472,11 +542,11 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1
472 addr6->sin6_flowinfo = 0; 542 addr6->sin6_flowinfo = 0;
473 addr6->sin6_scope_id = 0; 543 addr6->sin6_scope_id = 0;
474 } else { 544 } else {
475 /* unknown address type*/ 545 LOGGER_WARNING(net->log, "unknown address type: %d", ip_port.ip.family);
476 return -1; 546 return -1;
477 } 547 }
478 548
479 const int res = sendto(net->sock, (const char *) data, length, 0, (struct sockaddr *)&addr, addrsize); 549 const int res = sendto(net->sock.socket, (const char *) data, length, 0, (struct sockaddr *)&addr, addrsize);
480 550
481 loglogdata(net->log, "O=>", data, length, ip_port, res); 551 loglogdata(net->log, "O=>", data, length, ip_port, res);
482 552
@@ -492,13 +562,13 @@ static int receivepacket(Logger *log, Socket sock, IP_Port *ip_port, uint8_t *da
492{ 562{
493 memset(ip_port, 0, sizeof(IP_Port)); 563 memset(ip_port, 0, sizeof(IP_Port));
494 struct sockaddr_storage addr; 564 struct sockaddr_storage addr;
495#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 565#ifdef OS_WIN32
496 int addrlen = sizeof(addr); 566 int addrlen = sizeof(addr);
497#else 567#else
498 socklen_t addrlen = sizeof(addr); 568 socklen_t addrlen = sizeof(addr);
499#endif 569#endif
500 *length = 0; 570 *length = 0;
501 int fail_or_len = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); 571 int fail_or_len = recvfrom(sock.socket, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
502 572
503 if (fail_or_len < 0) { 573 if (fail_or_len < 0) {
504 int error = net_error(); 574 int error = net_error();
@@ -597,7 +667,7 @@ int networking_at_startup(void)
597 667
598#endif/*VANILLA_NACL*/ 668#endif/*VANILLA_NACL*/
599 669
600#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 670#ifdef OS_WIN32
601 WSADATA wsaData; 671 WSADATA wsaData;
602 672
603 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { 673 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) {
@@ -614,7 +684,7 @@ int networking_at_startup(void)
614#if 0 684#if 0
615static void at_shutdown(void) 685static void at_shutdown(void)
616{ 686{
617#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 687#ifdef OS_WIN32
618 WSACleanup(); 688 WSACleanup();
619#endif 689#endif
620} 690}
@@ -703,12 +773,12 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1
703 /* Functions to increase the size of the send and receive UDP buffers. 773 /* Functions to increase the size of the send and receive UDP buffers.
704 */ 774 */
705 int n = 1024 * 1024 * 2; 775 int n = 1024 * 1024 * 2;
706 setsockopt(temp->sock, SOL_SOCKET, SO_RCVBUF, (const char *)&n, sizeof(n)); 776 setsockopt(temp->sock.socket, SOL_SOCKET, SO_RCVBUF, (const char *)&n, sizeof(n));
707 setsockopt(temp->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof(n)); 777 setsockopt(temp->sock.socket, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof(n));
708 778
709 /* Enable broadcast on socket */ 779 /* Enable broadcast on socket */
710 int broadcast = 1; 780 int broadcast = 1;
711 setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (const char *)&broadcast, sizeof(broadcast)); 781 setsockopt(temp->sock.socket, SOL_SOCKET, SO_BROADCAST, (const char *)&broadcast, sizeof(broadcast));
712 782
713 /* iOS UDP sockets are weird and apparently can SIGPIPE */ 783 /* iOS UDP sockets are weird and apparently can SIGPIPE */
714 if (!set_socket_nosigpipe(temp->sock)) { 784 if (!set_socket_nosigpipe(temp->sock)) {
@@ -776,7 +846,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1
776 mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02; 846 mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02;
777 mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01; 847 mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01;
778 mreq.ipv6mr_interface = 0; 848 mreq.ipv6mr_interface = 0;
779 int res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char *)&mreq, sizeof(mreq)); 849 const int res = setsockopt(temp->sock.socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char *)&mreq, sizeof(mreq));
780 850
781 int neterror = net_error(); 851 int neterror = net_error();
782 const char *strerror = net_new_strerror(neterror); 852 const char *strerror = net_new_strerror(neterror);
@@ -806,7 +876,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1
806 int tries; 876 int tries;
807 877
808 for (tries = port_from; tries <= port_to; tries++) { 878 for (tries = port_from; tries <= port_to; tries++) {
809 int res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); 879 int res = bind(temp->sock.socket, (struct sockaddr *)&addr, addrsize);
810 880
811 if (!res) { 881 if (!res) {
812 temp->port = *portptr; 882 temp->port = *portptr;
@@ -1290,7 +1360,7 @@ int net_connect(Socket sock, IP_Port ip_port)
1290 return 0; 1360 return 0;
1291 } 1361 }
1292 1362
1293 return connect(sock, (struct sockaddr *)&addr, addrsize); 1363 return connect(sock.socket, (struct sockaddr *)&addr, addrsize);
1294} 1364}
1295 1365
1296int32_t net_getipport(const char *node, IP_Port **res, int tox_type) 1366int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
@@ -1391,41 +1461,7 @@ int bind_to_port(Socket sock, int family, uint16_t port)
1391 return 0; 1461 return 0;
1392 } 1462 }
1393 1463
1394 return (bind(sock, (struct sockaddr *)&addr, addrsize) == 0); 1464 return bind(sock.socket, (struct sockaddr *)&addr, addrsize) == 0;
1395}
1396
1397static int make_tox_family(int family)
1398{
1399 switch (family) {
1400 case AF_INET:
1401 return TOX_AF_INET;
1402
1403 case AF_INET6:
1404 return TOX_AF_INET6;
1405
1406 case AF_UNSPEC:
1407 return TOX_AF_UNSPEC;
1408
1409 default:
1410 return family;
1411 }
1412}
1413
1414static int make_family(int tox_family)
1415{
1416 switch (tox_family) {
1417 case TOX_AF_INET:
1418 return AF_INET;
1419
1420 case TOX_AF_INET6:
1421 return AF_INET6;
1422
1423 case TOX_AF_UNSPEC:
1424 return AF_UNSPEC;
1425
1426 default:
1427 return tox_family;
1428 }
1429} 1465}
1430 1466
1431static int make_socktype(int type) 1467static int make_socktype(int type)
@@ -1456,12 +1492,47 @@ static int make_proto(int proto)
1456 } 1492 }
1457} 1493}
1458 1494
1459Socket net_socket(int domain, int type, int protocol) 1495Socket net_socket(Family domain, int type, int protocol)
1496{
1497 const int platform_domain = make_family(domain);
1498 const int platform_type = make_socktype(type);
1499 const int platform_prot = make_proto(protocol);
1500 const Socket sock = {(int)socket(platform_domain, platform_type, platform_prot)};
1501 return sock;
1502}
1503
1504int net_send(Socket sock, const void *buf, size_t len)
1460{ 1505{
1461 int platform_domain = make_family(domain); 1506 return send(sock.socket, (const char *)buf, len, MSG_NOSIGNAL);
1462 int platform_type = make_socktype(type); 1507}
1463 int platform_prot = make_proto(protocol); 1508
1464 return socket(platform_domain, platform_type, platform_prot); 1509int net_recv(Socket sock, void *buf, size_t len)
1510{
1511 return recv(sock.socket, (char *)buf, len, MSG_NOSIGNAL);
1512}
1513
1514int net_listen(Socket sock, int backlog)
1515{
1516 return listen(sock.socket, backlog);
1517}
1518
1519Socket net_accept(Socket sock)
1520{
1521 const Socket newsock = {accept(sock.socket, nullptr, nullptr)};
1522 return newsock;
1523}
1524
1525size_t net_socket_data_recv_buffer(Socket sock)
1526{
1527#ifdef OS_WIN32
1528 unsigned long count = 0;
1529 ioctlsocket(sock.socket, FIONREAD, &count);
1530#else
1531 int count = 0;
1532 ioctl(sock.socket, FIONREAD, &count);
1533#endif
1534
1535 return count;
1465} 1536}
1466 1537
1467uint32_t net_htonl(uint32_t hostlong) 1538uint32_t net_htonl(uint32_t hostlong)