2 net_socket.c -- Handle various kinds of sockets.
3 Copyright (C) 1998-2005 Ivo Timmermans,
4 2000-2018 Guus Sliepen <guus@tinc-vpn.org>
5 2006 Scott Lamb <slamb@slamb.org>
6 2009 Florian Forster <octo@verplant.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "address_cache.h"
27 #include "connection.h"
37 int addressfamily = AF_UNSPEC;
39 int seconds_till_retry = 5;
40 int udp_rcvbuf = 1024 * 1024;
41 int udp_sndbuf = 1024 * 1024;
42 bool udp_rcvbuf_warnings;
43 bool udp_sndbuf_warnings;
44 int max_connection_burst = 10;
47 listen_socket_t listen_socket[MAXSOCKETS];
52 list_t *outgoing_list = NULL;
56 static void configure_tcp(connection_t *c) {
60 int flags = fcntl(c->socket, F_GETFL);
62 if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) {
63 logger(DEBUG_ALWAYS, LOG_ERR, "fcntl for %s fd %d: %s", c->hostname, c->socket, strerror(errno));
67 unsigned long arg = 1;
69 if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) {
70 logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s fd %d: %s", c->hostname, c->socket, sockstrerror(sockerrno));
75 #if defined(TCP_NODELAY)
77 setsockopt(c->socket, IPPROTO_TCP, TCP_NODELAY, (void *)&option, sizeof(option));
80 #if defined(IP_TOS) && defined(IPTOS_LOWDELAY)
81 option = IPTOS_LOWDELAY;
82 setsockopt(c->socket, IPPROTO_IP, IP_TOS, (void *)&option, sizeof(option));
85 #if defined(IPV6_TCLASS) && defined(IPTOS_LOWDELAY)
86 option = IPTOS_LOWDELAY;
87 setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof(option));
93 setsockopt(c->socket, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark));
99 static bool bind_to_interface(int sd) {
102 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
105 #endif /* defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) */
107 if(!get_config_string(lookup_config(config_tree, "BindToInterface"), &iface)) {
111 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
112 memset(&ifr, 0, sizeof(ifr));
113 strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
114 ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0;
116 status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
119 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface,
120 sockstrerror(sockerrno));
124 #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */
126 logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface");
132 static bool bind_to_address(connection_t *c) {
135 for(int i = 0; i < listen_sockets && listen_socket[i].bindto; i++) {
136 if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) {
151 sockaddr_t sa = listen_socket[s].sa;
153 if(sa.sa.sa_family == AF_INET) {
155 } else if(sa.sa.sa_family == AF_INET6) {
156 sa.in6.sin6_port = 0;
159 if(bind(c->socket, &sa.sa, SALEN(sa.sa))) {
160 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", sockstrerror(sockerrno));
167 int setup_listen_socket(const sockaddr_t *sa) {
173 nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
176 logger(DEBUG_STATUS, LOG_ERR, "Creating metasocket failed: %s", sockstrerror(sockerrno));
181 fcntl(nfd, F_SETFD, FD_CLOEXEC);
184 /* Optimize TCP settings */
187 setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option));
189 #if defined(IPV6_V6ONLY)
191 if(sa->sa.sa_family == AF_INET6) {
192 setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option));
196 #warning IPV6_V6ONLY not defined
202 setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark));
208 (lookup_config(config_tree, "BindToInterface"), &iface)) {
209 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
212 memset(&ifr, 0, sizeof(ifr));
213 strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
214 ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0;
216 if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr))) {
218 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface,
219 sockstrerror(sockerrno));
224 logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface");
228 if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
230 addrstr = sockaddr2hostname(sa);
231 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno));
238 logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "listen", sockstrerror(sockerrno));
245 static void set_udp_buffer(int nfd, int type, const char *name, int size, bool warnings) {
250 if(setsockopt(nfd, SOL_SOCKET, type, (void *)&size, sizeof(size))) {
251 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP %s to %i: %s", name, size, sockstrerror(sockerrno));
259 // The system may cap the requested buffer size.
260 // Read back the value and check if it is now as requested.
262 socklen_t optlen = sizeof(actual);
264 if(getsockopt(nfd, SOL_SOCKET, type, (void *)&actual, &optlen)) {
265 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP %s: %s", name, sockstrerror(sockerrno));
266 } else if(optlen != sizeof(actual)) {
267 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP %s: unexpected returned optlen %d", name, (int)optlen);
268 } else if(actual < size) {
269 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP %s to %i, the system set it to %i instead", name, size, actual);
274 int setup_vpn_in_socket(const sockaddr_t *sa) {
279 nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
282 logger(DEBUG_ALWAYS, LOG_ERR, "Creating UDP socket failed: %s", sockstrerror(sockerrno));
287 fcntl(nfd, F_SETFD, FD_CLOEXEC);
292 int flags = fcntl(nfd, F_GETFL);
294 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
296 logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl",
303 unsigned long arg = 1;
305 if(ioctlsocket(nfd, FIONBIO, &arg) != 0) {
307 logger(DEBUG_ALWAYS, LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno));
314 setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option));
315 setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof(option));
317 set_udp_buffer(nfd, SO_RCVBUF, "SO_RCVBUF", udp_rcvbuf, udp_rcvbuf_warnings);
318 set_udp_buffer(nfd, SO_SNDBUF, "SO_SNDBUF", udp_sndbuf, udp_sndbuf_warnings);
320 #if defined(IPV6_V6ONLY)
322 if(sa->sa.sa_family == AF_INET6) {
323 setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option));
328 #if defined(IP_DONTFRAG) && !defined(IP_DONTFRAGMENT)
329 #define IP_DONTFRAGMENT IP_DONTFRAG
332 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
334 if(myself->options & OPTION_PMTU_DISCOVERY) {
335 option = IP_PMTUDISC_DO;
336 setsockopt(nfd, IPPROTO_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option));
339 #elif defined(IP_DONTFRAGMENT)
341 if(myself->options & OPTION_PMTU_DISCOVERY) {
343 setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, (void *)&option, sizeof(option));
348 #if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
350 if(myself->options & OPTION_PMTU_DISCOVERY) {
351 option = IPV6_PMTUDISC_DO;
352 setsockopt(nfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option));
355 #elif defined(IPV6_DONTFRAG)
357 if(myself->options & OPTION_PMTU_DISCOVERY) {
359 setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, (void *)&option, sizeof(option));
367 setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark));
372 if(!bind_to_interface(nfd)) {
377 if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
379 addrstr = sockaddr2hostname(sa);
380 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/udp: %s", addrstr, sockstrerror(sockerrno));
386 } /* int setup_vpn_in_socket */
388 static void retry_outgoing_handler(void *data) {
389 setup_outgoing_connection(data, true);
392 void retry_outgoing(outgoing_t *outgoing) {
393 outgoing->timeout += 5;
395 if(outgoing->timeout > maxtimeout) {
396 outgoing->timeout = maxtimeout;
399 timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval) {
400 outgoing->timeout, rand() % 100000
403 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout);
406 void finish_connecting(connection_t *c) {
407 logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname);
409 c->last_ping_time = now.tv_sec;
410 c->status.connecting = false;
415 static void do_outgoing_pipe(connection_t *c, const char *command) {
419 if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
420 logger(DEBUG_ALWAYS, LOG_ERR, "Could not create socketpair: %s", sockstrerror(sockerrno));
427 logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Using proxy %s", command);
438 // Other filedescriptors should be closed automatically by CLOEXEC
443 sockaddr2str(&c->address, &host, &port);
444 setenv("REMOTEADDRESS", host, true);
445 setenv("REMOTEPORT", port, true);
446 setenv("NODE", c->name, true);
447 setenv("NAME", myself->name, true);
450 setenv("NETNAME", netname, true);
453 int result = system(command);
456 logger(DEBUG_ALWAYS, LOG_ERR, "Could not execute %s: %s", command, strerror(errno));
458 logger(DEBUG_ALWAYS, LOG_ERR, "%s exited with non-zero status %d", command, result);
465 logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type exec not supported on this platform!");
470 static void handle_meta_write(connection_t *c) {
471 if(c->outbuf.len <= c->outbuf.offset) {
475 ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0);
478 if(!sockerrno || sockerrno == EPIPE) {
479 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname);
480 } else if(sockwouldblock(sockerrno)) {
481 logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname);
484 logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not send %d bytes of data to %s (%s): %s", c->outbuf.len - c->outbuf.offset, c->name, c->hostname, sockstrerror(sockerrno));
487 terminate_connection(c, c->edge);
491 buffer_read(&c->outbuf, outlen);
494 io_set(&c->io, IO_READ);
498 static void handle_meta_io(void *data, int flags) {
499 connection_t *c = data;
501 if(c->status.connecting) {
503 The event loop does not protect against spurious events. Verify that we are actually connected
504 by issuing an empty send() call.
506 Note that the behavior of send() on potentially unconnected sockets differ between platforms:
507 +------------+-----------+-------------+-----------+
508 | Event | POSIX | Linux | Windows |
509 +------------+-----------+-------------+-----------+
510 | Spurious | ENOTCONN | EWOULDBLOCK | ENOTCONN |
511 | Failed | ENOTCONN | (cause) | ENOTCONN |
512 | Successful | (success) | (success) | (success) |
513 +------------+-----------+-------------+-----------+
515 if(send(c->socket, NULL, 0, 0) != 0) {
516 if(sockwouldblock(sockerrno)) {
522 if(!socknotconn(sockerrno)) {
523 socket_error = sockerrno;
525 socklen_t len = sizeof(socket_error);
526 getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&socket_error, &len);
530 logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(socket_error));
531 terminate_connection(c, false);
537 c->status.connecting = false;
538 finish_connecting(c);
541 if(flags & IO_WRITE) {
542 handle_meta_write(c);
544 handle_meta_connection_data(c);
548 bool do_outgoing_connection(outgoing_t *outgoing) {
549 const sockaddr_t *sa;
550 struct addrinfo *proxyai = NULL;
554 sa = get_recent_address(outgoing->node->address_cache);
557 logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->node->name);
558 retry_outgoing(outgoing);
562 connection_t *c = new_connection();
563 c->outgoing = outgoing;
564 memcpy(&c->address, sa, SALEN(sa->sa));
565 c->hostname = sockaddr2hostname(&c->address);
567 logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->node->name, c->hostname);
570 c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
572 } else if(proxytype == PROXY_EXEC) {
573 do_outgoing_pipe(c, proxyhost);
575 proxyai = str2addrinfo(proxyhost, proxyport, SOCK_STREAM);
582 logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport);
583 c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP);
587 if(c->socket == -1) {
588 logger(DEBUG_CONNECTIONS, LOG_ERR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno));
594 fcntl(c->socket, F_SETFD, FD_CLOEXEC);
597 if(proxytype != PROXY_EXEC) {
598 #if defined(IPV6_V6ONLY)
601 if(c->address.sa.sa_family == AF_INET6) {
602 setsockopt(c->socket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option));
607 bind_to_interface(c->socket);
614 result = connect(c->socket, &c->address.sa, SALEN(c->address.sa));
615 } else if(proxytype == PROXY_EXEC) {
622 result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen);
623 freeaddrinfo(proxyai);
626 if(result == -1 && !sockinprogress(sockerrno)) {
627 logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not connect to %s (%s): %s", outgoing->node->name, c->hostname, sockstrerror(sockerrno));
633 /* Now that there is a working socket, fill in the rest and register this connection. */
635 c->last_ping_time = time(NULL);
636 c->status.connecting = true;
637 c->name = xstrdup(outgoing->node->name);
638 #ifndef DISABLE_LEGACY
639 c->outcipher = myself->connection->outcipher;
640 c->outdigest = myself->connection->outdigest;
642 c->outmaclength = myself->connection->outmaclength;
643 c->outcompression = myself->connection->outcompression;
644 c->last_ping_time = now.tv_sec;
648 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ | IO_WRITE);
653 void setup_outgoing_connection(outgoing_t *outgoing, bool verbose) {
655 timeout_del(&outgoing->ev);
657 node_t *n = outgoing->node;
659 if(!n->address_cache) {
660 n->address_cache = open_address_cache(n);
664 logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", n->name);
666 if(!n->connection->outgoing) {
667 n->connection->outgoing = outgoing;
674 do_outgoing_connection(outgoing);
678 list_delete(outgoing_list, outgoing);
682 accept a new tcp connect and create a
685 void handle_new_meta_connection(void *data, int flags) {
687 listen_socket_t *l = data;
691 socklen_t len = sizeof(sa);
693 fd = accept(l->tcp.fd, &sa.sa, &len);
696 logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
702 // Check if we get many connections from the same host
704 static sockaddr_t prev_sa;
706 if(!sockaddrcmp_noport(&sa, &prev_sa)) {
707 static int samehost_burst;
708 static int samehost_burst_time;
710 if(now.tv_sec - samehost_burst_time > samehost_burst) {
713 samehost_burst -= now.tv_sec - samehost_burst_time;
716 samehost_burst_time = now.tv_sec;
719 if(samehost_burst > max_connection_burst) {
725 memcpy(&prev_sa, &sa, sizeof(sa));
727 // Check if we get many connections from different hosts
729 static int connection_burst;
730 static int connection_burst_time;
732 if(now.tv_sec - connection_burst_time > connection_burst) {
733 connection_burst = 0;
735 connection_burst -= now.tv_sec - connection_burst_time;
738 connection_burst_time = now.tv_sec;
741 if(connection_burst >= max_connection_burst) {
742 connection_burst = max_connection_burst;
747 // Accept the new connection
749 c = new_connection();
750 c->name = xstrdup("<unknown>");
751 #ifndef DISABLE_LEGACY
752 c->outcipher = myself->connection->outcipher;
753 c->outdigest = myself->connection->outdigest;
755 c->outmaclength = myself->connection->outmaclength;
756 c->outcompression = myself->connection->outcompression;
759 c->hostname = sockaddr2hostname(&sa);
761 c->last_ping_time = now.tv_sec;
763 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
765 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
771 c->allow_request = ID;
776 accept a new UNIX socket connection
778 void handle_new_unix_connection(void *data, int flags) {
784 socklen_t len = sizeof(sa);
786 fd = accept(io->fd, &sa.sa, &len);
789 logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
795 c = new_connection();
796 c->name = xstrdup("<control>");
798 c->hostname = xstrdup("localhost port unix");
800 c->last_ping_time = now.tv_sec;
802 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
804 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
808 c->allow_request = ID;
812 static void free_outgoing(outgoing_t *outgoing) {
813 timeout_del(&outgoing->ev);
817 void try_outgoing_connections(void) {
818 /* If there is no outgoing list yet, create one. Otherwise, mark all outgoings as deleted. */
821 outgoing_list = list_alloc((list_action_t)free_outgoing);
823 for list_each(outgoing_t, outgoing, outgoing_list) {
824 outgoing->timeout = -1;
828 /* Make sure there is one outgoing_t in the list for each ConnectTo. */
830 for(config_t *cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
832 get_config_string(cfg, &name);
834 if(!check_id(name)) {
835 logger(DEBUG_ALWAYS, LOG_ERR,
836 "Invalid name for outgoing connection in %s line %d",
837 cfg->file, cfg->line);
842 if(!strcmp(name, myself->name)) {
849 for list_each(outgoing_t, outgoing, outgoing_list) {
850 if(!strcmp(outgoing->node->name, name)) {
852 outgoing->timeout = 0;
858 outgoing_t *outgoing = xzalloc(sizeof(*outgoing));
859 node_t *n = lookup_node(name);
863 n->name = xstrdup(name);
870 list_insert_tail(outgoing_list, outgoing);
871 setup_outgoing_connection(outgoing, true);
875 /* Terminate any connections whose outgoing_t is to be deleted. */
877 for list_each(connection_t, c, connection_list) {
878 if(c->outgoing && c->outgoing->timeout == -1) {
880 logger(DEBUG_CONNECTIONS, LOG_INFO, "No more outgoing connection to %s", c->name);
881 terminate_connection(c, c->edge);
885 /* Delete outgoing_ts for which there is no ConnectTo. */
887 for list_each(outgoing_t, outgoing, outgoing_list)
888 if(outgoing->timeout == -1) {
889 list_delete_node(outgoing_list, node);