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"
28 #include "control_common.h"
39 int addressfamily = AF_UNSPEC;
41 int seconds_till_retry = 5;
42 int udp_rcvbuf = 1024 * 1024;
43 int udp_sndbuf = 1024 * 1024;
44 bool udp_rcvbuf_warnings;
45 bool udp_sndbuf_warnings;
46 int max_connection_burst = 10;
49 listen_socket_t listen_socket[MAXSOCKETS];
54 list_t *outgoing_list = NULL;
58 static void configure_tcp(connection_t *c) {
62 int flags = fcntl(c->socket, F_GETFL);
64 if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) {
65 logger(DEBUG_ALWAYS, LOG_ERR, "fcntl for %s fd %d: %s", c->hostname, c->socket, strerror(errno));
69 unsigned long arg = 1;
71 if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) {
72 logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s fd %d: %s", c->hostname, c->socket, sockstrerror(sockerrno));
77 #if defined(TCP_NODELAY)
79 setsockopt(c->socket, IPPROTO_TCP, TCP_NODELAY, (void *)&option, sizeof(option));
82 #if defined(IP_TOS) && defined(IPTOS_LOWDELAY)
83 option = IPTOS_LOWDELAY;
84 setsockopt(c->socket, IPPROTO_IP, IP_TOS, (void *)&option, sizeof(option));
87 #if defined(IPV6_TCLASS) && defined(IPTOS_LOWDELAY)
88 option = IPTOS_LOWDELAY;
89 setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof(option));
95 setsockopt(c->socket, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark));
101 static bool bind_to_interface(int sd) {
104 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
107 #endif /* defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) */
109 if(!get_config_string(lookup_config(config_tree, "BindToInterface"), &iface)) {
113 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
114 memset(&ifr, 0, sizeof(ifr));
115 strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
116 ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0;
118 status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
121 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface,
122 sockstrerror(sockerrno));
126 #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */
128 logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface");
134 static bool bind_to_address(connection_t *c) {
137 for(int i = 0; i < listen_sockets && listen_socket[i].bindto; i++) {
138 if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) {
153 sockaddr_t sa = listen_socket[s].sa;
155 if(sa.sa.sa_family == AF_INET) {
157 } else if(sa.sa.sa_family == AF_INET6) {
158 sa.in6.sin6_port = 0;
161 if(bind(c->socket, &sa.sa, SALEN(sa.sa))) {
162 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", sockstrerror(sockerrno));
169 int setup_listen_socket(const sockaddr_t *sa) {
175 nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
178 logger(DEBUG_STATUS, LOG_ERR, "Creating metasocket failed: %s", sockstrerror(sockerrno));
183 fcntl(nfd, F_SETFD, FD_CLOEXEC);
186 /* Optimize TCP settings */
189 setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option));
191 #if defined(IPV6_V6ONLY)
193 if(sa->sa.sa_family == AF_INET6) {
194 setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option));
198 #warning IPV6_V6ONLY not defined
204 setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark));
210 (lookup_config(config_tree, "BindToInterface"), &iface)) {
211 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
214 memset(&ifr, 0, sizeof(ifr));
215 strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
216 ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0;
218 if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr))) {
220 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface,
221 sockstrerror(sockerrno));
226 logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface");
230 if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
232 addrstr = sockaddr2hostname(sa);
233 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno));
240 logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "listen", sockstrerror(sockerrno));
247 static void set_udp_buffer(int nfd, int type, const char *name, int size, bool warnings) {
252 if(setsockopt(nfd, SOL_SOCKET, type, (void *)&size, sizeof(size))) {
253 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP %s to %i: %s", name, size, sockstrerror(sockerrno));
261 // The system may cap the requested buffer size.
262 // Read back the value and check if it is now as requested.
264 socklen_t optlen = sizeof(actual);
266 if(getsockopt(nfd, SOL_SOCKET, type, (void *)&actual, &optlen)) {
267 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP %s: %s", name, sockstrerror(sockerrno));
268 } else if(optlen != sizeof(actual)) {
269 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP %s: unexpected returned optlen %d", name, (int)optlen);
270 } else if(actual < size) {
271 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP %s to %i, the system set it to %i instead", name, size, actual);
276 int setup_vpn_in_socket(const sockaddr_t *sa) {
281 nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
284 logger(DEBUG_ALWAYS, LOG_ERR, "Creating UDP socket failed: %s", sockstrerror(sockerrno));
289 fcntl(nfd, F_SETFD, FD_CLOEXEC);
294 int flags = fcntl(nfd, F_GETFL);
296 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
298 logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl",
305 unsigned long arg = 1;
307 if(ioctlsocket(nfd, FIONBIO, &arg) != 0) {
309 logger(DEBUG_ALWAYS, LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno));
316 setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option));
317 setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof(option));
319 set_udp_buffer(nfd, SO_RCVBUF, "SO_RCVBUF", udp_rcvbuf, udp_rcvbuf_warnings);
320 set_udp_buffer(nfd, SO_SNDBUF, "SO_SNDBUF", udp_sndbuf, udp_sndbuf_warnings);
322 #if defined(IPV6_V6ONLY)
324 if(sa->sa.sa_family == AF_INET6) {
325 setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option));
330 #if defined(IP_DONTFRAG) && !defined(IP_DONTFRAGMENT)
331 #define IP_DONTFRAGMENT IP_DONTFRAG
334 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
336 if(myself->options & OPTION_PMTU_DISCOVERY) {
337 option = IP_PMTUDISC_DO;
338 setsockopt(nfd, IPPROTO_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option));
341 #elif defined(IP_DONTFRAGMENT)
343 if(myself->options & OPTION_PMTU_DISCOVERY) {
345 setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, (void *)&option, sizeof(option));
350 #if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
352 if(myself->options & OPTION_PMTU_DISCOVERY) {
353 option = IPV6_PMTUDISC_DO;
354 setsockopt(nfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option));
357 #elif defined(IPV6_DONTFRAG)
359 if(myself->options & OPTION_PMTU_DISCOVERY) {
361 setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, (void *)&option, sizeof(option));
369 setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark));
374 if(!bind_to_interface(nfd)) {
379 if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
381 addrstr = sockaddr2hostname(sa);
382 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/udp: %s", addrstr, sockstrerror(sockerrno));
388 } /* int setup_vpn_in_socket */
390 static void retry_outgoing_handler(void *data) {
391 setup_outgoing_connection(data, true);
394 void retry_outgoing(outgoing_t *outgoing) {
395 outgoing->timeout += 5;
397 if(outgoing->timeout > maxtimeout) {
398 outgoing->timeout = maxtimeout;
401 timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval) {
402 outgoing->timeout, rand() % 100000
405 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout);
408 void finish_connecting(connection_t *c) {
409 logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname);
411 c->last_ping_time = now.tv_sec;
412 c->status.connecting = false;
417 static void do_outgoing_pipe(connection_t *c, const char *command) {
421 if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
422 logger(DEBUG_ALWAYS, LOG_ERR, "Could not create socketpair: %s", sockstrerror(sockerrno));
429 logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Using proxy %s", command);
440 // Other filedescriptors should be closed automatically by CLOEXEC
445 sockaddr2str(&c->address, &host, &port);
446 setenv("REMOTEADDRESS", host, true);
447 setenv("REMOTEPORT", port, true);
448 setenv("NODE", c->name, true);
449 setenv("NAME", myself->name, true);
452 setenv("NETNAME", netname, true);
455 int result = system(command);
458 logger(DEBUG_ALWAYS, LOG_ERR, "Could not execute %s: %s", command, strerror(errno));
460 logger(DEBUG_ALWAYS, LOG_ERR, "%s exited with non-zero status %d", command, result);
467 logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type exec not supported on this platform!");
472 static void handle_meta_write(connection_t *c) {
473 if(c->outbuf.len <= c->outbuf.offset) {
477 ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0);
480 if(!sockerrno || sockerrno == EPIPE) {
481 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname);
482 } else if(sockwouldblock(sockerrno)) {
483 logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname);
486 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));
489 terminate_connection(c, c->edge);
493 buffer_read(&c->outbuf, outlen);
496 io_set(&c->io, IO_READ);
500 static void handle_meta_io(void *data, int flags) {
501 connection_t *c = data;
503 if(c->status.connecting) {
505 The event loop does not protect against spurious events. Verify that we are actually connected
506 by issuing an empty send() call.
508 Note that the behavior of send() on potentially unconnected sockets differ between platforms:
509 +------------+-----------+-------------+-----------+
510 | Event | POSIX | Linux | Windows |
511 +------------+-----------+-------------+-----------+
512 | Spurious | ENOTCONN | EWOULDBLOCK | ENOTCONN |
513 | Failed | ENOTCONN | (cause) | ENOTCONN |
514 | Successful | (success) | (success) | (success) |
515 +------------+-----------+-------------+-----------+
517 if(send(c->socket, NULL, 0, 0) != 0) {
518 if(sockwouldblock(sockerrno)) {
524 if(!socknotconn(sockerrno)) {
525 socket_error = sockerrno;
527 socklen_t len = sizeof(socket_error);
528 getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&socket_error, &len);
532 logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(socket_error));
533 terminate_connection(c, false);
539 c->status.connecting = false;
540 finish_connecting(c);
543 if(flags & IO_WRITE) {
544 handle_meta_write(c);
546 handle_meta_connection_data(c);
550 bool do_outgoing_connection(outgoing_t *outgoing) {
551 const sockaddr_t *sa;
552 struct addrinfo *proxyai = NULL;
556 sa = get_recent_address(outgoing->node->address_cache);
559 logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->node->name);
560 retry_outgoing(outgoing);
564 connection_t *c = new_connection();
565 c->outgoing = outgoing;
566 memcpy(&c->address, sa, SALEN(sa->sa));
567 c->hostname = sockaddr2hostname(&c->address);
569 logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->node->name, c->hostname);
572 c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
574 } else if(proxytype == PROXY_EXEC) {
575 do_outgoing_pipe(c, proxyhost);
577 proxyai = str2addrinfo(proxyhost, proxyport, SOCK_STREAM);
584 logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport);
585 c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP);
589 if(c->socket == -1) {
590 logger(DEBUG_CONNECTIONS, LOG_ERR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno));
596 fcntl(c->socket, F_SETFD, FD_CLOEXEC);
599 if(proxytype != PROXY_EXEC) {
600 #if defined(IPV6_V6ONLY)
603 if(c->address.sa.sa_family == AF_INET6) {
604 setsockopt(c->socket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option));
609 bind_to_interface(c->socket);
616 result = connect(c->socket, &c->address.sa, SALEN(c->address.sa));
617 } else if(proxytype == PROXY_EXEC) {
624 result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen);
625 freeaddrinfo(proxyai);
628 if(result == -1 && !sockinprogress(sockerrno)) {
629 logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not connect to %s (%s): %s", outgoing->node->name, c->hostname, sockstrerror(sockerrno));
635 /* Now that there is a working socket, fill in the rest and register this connection. */
637 c->last_ping_time = time(NULL);
638 c->status.connecting = true;
639 c->name = xstrdup(outgoing->node->name);
640 #ifndef DISABLE_LEGACY
641 c->outcipher = myself->connection->outcipher;
642 c->outdigest = myself->connection->outdigest;
644 c->outmaclength = myself->connection->outmaclength;
645 c->outcompression = myself->connection->outcompression;
646 c->last_ping_time = now.tv_sec;
650 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ | IO_WRITE);
655 void setup_outgoing_connection(outgoing_t *outgoing, bool verbose) {
657 timeout_del(&outgoing->ev);
659 node_t *n = outgoing->node;
661 if(!n->address_cache) {
662 n->address_cache = open_address_cache(n);
666 logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", n->name);
668 if(!n->connection->outgoing) {
669 n->connection->outgoing = outgoing;
676 do_outgoing_connection(outgoing);
680 list_delete(outgoing_list, outgoing);
684 accept a new tcp connect and create a
687 void handle_new_meta_connection(void *data, int flags) {
689 listen_socket_t *l = data;
693 socklen_t len = sizeof(sa);
695 fd = accept(l->tcp.fd, &sa.sa, &len);
698 logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
704 // Check if we get many connections from the same host
706 static sockaddr_t prev_sa;
708 if(!sockaddrcmp_noport(&sa, &prev_sa)) {
709 static int samehost_burst;
710 static int samehost_burst_time;
712 if(now.tv_sec - samehost_burst_time > samehost_burst) {
715 samehost_burst -= now.tv_sec - samehost_burst_time;
718 samehost_burst_time = now.tv_sec;
721 if(samehost_burst > max_connection_burst) {
727 memcpy(&prev_sa, &sa, sizeof(sa));
729 // Check if we get many connections from different hosts
731 static int connection_burst;
732 static int connection_burst_time;
734 if(now.tv_sec - connection_burst_time > connection_burst) {
735 connection_burst = 0;
737 connection_burst -= now.tv_sec - connection_burst_time;
740 connection_burst_time = now.tv_sec;
743 if(connection_burst >= max_connection_burst) {
744 connection_burst = max_connection_burst;
749 // Accept the new connection
751 c = new_connection();
752 c->name = xstrdup("<unknown>");
753 #ifndef DISABLE_LEGACY
754 c->outcipher = myself->connection->outcipher;
755 c->outdigest = myself->connection->outdigest;
757 c->outmaclength = myself->connection->outmaclength;
758 c->outcompression = myself->connection->outcompression;
761 c->hostname = sockaddr2hostname(&sa);
763 c->last_ping_time = now.tv_sec;
765 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
767 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
773 c->allow_request = ID;
778 accept a new UNIX socket connection
780 void handle_new_unix_connection(void *data, int flags) {
786 socklen_t len = sizeof(sa);
788 fd = accept(io->fd, &sa.sa, &len);
791 logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
797 c = new_connection();
798 c->name = xstrdup("<control>");
800 c->hostname = xstrdup("localhost port unix");
802 c->last_ping_time = now.tv_sec;
804 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
806 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
810 c->allow_request = ID;
814 static void free_outgoing(outgoing_t *outgoing) {
815 timeout_del(&outgoing->ev);
819 void try_outgoing_connections(void) {
820 /* If there is no outgoing list yet, create one. Otherwise, mark all outgoings as deleted. */
823 outgoing_list = list_alloc((list_action_t)free_outgoing);
825 for list_each(outgoing_t, outgoing, outgoing_list) {
826 outgoing->timeout = -1;
830 /* Make sure there is one outgoing_t in the list for each ConnectTo. */
832 for(config_t *cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
834 get_config_string(cfg, &name);
836 if(!check_id(name)) {
837 logger(DEBUG_ALWAYS, LOG_ERR,
838 "Invalid name for outgoing connection in %s line %d",
839 cfg->file, cfg->line);
844 if(!strcmp(name, myself->name)) {
851 for list_each(outgoing_t, outgoing, outgoing_list) {
852 if(!strcmp(outgoing->node->name, name)) {
854 outgoing->timeout = 0;
860 outgoing_t *outgoing = xzalloc(sizeof(*outgoing));
861 node_t *n = lookup_node(name);
865 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);