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 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 int setup_vpn_in_socket(const sockaddr_t *sa) {
250 nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
253 logger(DEBUG_ALWAYS, LOG_ERR, "Creating UDP socket failed: %s", sockstrerror(sockerrno));
258 fcntl(nfd, F_SETFD, FD_CLOEXEC);
263 int flags = fcntl(nfd, F_GETFL);
265 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
267 logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl",
274 unsigned long arg = 1;
276 if(ioctlsocket(nfd, FIONBIO, &arg) != 0) {
278 logger(DEBUG_ALWAYS, LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno));
285 setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option));
286 setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof(option));
288 if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) {
289 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, sockstrerror(sockerrno));
293 // The system may cap the requested buffer size.
294 // Read back the value and check if it is now as requested.
295 int udp_rcvbuf_actual = -1;
296 socklen_t optlen = sizeof(udp_rcvbuf_actual);
298 if(getsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf_actual, &optlen)) {
299 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP SO_RCVBUF: %s", sockstrerror(sockerrno));
300 } else if(optlen != sizeof(udp_rcvbuf_actual)) {
301 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP SO_RCVBUF: Unexpected returned optlen %jd", (intmax_t) optlen);
303 if(udp_rcvbuf_actual != udp_rcvbuf) {
304 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_RCVBUF to %i, the system set it to %i instead", udp_rcvbuf, udp_rcvbuf_actual);
309 if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) {
310 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, sockstrerror(sockerrno));
314 // The system may cap the requested buffer size.
315 // Read back the value and check if it is now as requested.
316 int udp_sndbuf_actual = -1;
317 socklen_t optlen = sizeof(udp_sndbuf_actual);
319 if(getsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf_actual, &optlen)) {
320 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP SO_SNDBUF: %s", sockstrerror(sockerrno));
321 } else if(optlen != sizeof(udp_sndbuf_actual)) {
322 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP SO_SNDBUF: Unexpected returned optlen %jd", (intmax_t) optlen);
324 if(udp_sndbuf_actual != udp_sndbuf) {
325 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_SNDBUF to %i, the system set it to %i instead", udp_sndbuf, udp_sndbuf_actual);
330 #if defined(IPV6_V6ONLY)
332 if(sa->sa.sa_family == AF_INET6) {
333 setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option));
338 #if defined(IP_DONTFRAG) && !defined(IP_DONTFRAGMENT)
339 #define IP_DONTFRAGMENT IP_DONTFRAG
342 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
344 if(myself->options & OPTION_PMTU_DISCOVERY) {
345 option = IP_PMTUDISC_DO;
346 setsockopt(nfd, IPPROTO_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option));
349 #elif defined(IP_DONTFRAGMENT)
351 if(myself->options & OPTION_PMTU_DISCOVERY) {
353 setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, (void *)&option, sizeof(option));
358 #if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
360 if(myself->options & OPTION_PMTU_DISCOVERY) {
361 option = IPV6_PMTUDISC_DO;
362 setsockopt(nfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option));
365 #elif defined(IPV6_DONTFRAG)
367 if(myself->options & OPTION_PMTU_DISCOVERY) {
369 setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, (void *)&option, sizeof(option));
377 setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark));
382 if(!bind_to_interface(nfd)) {
387 if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
389 addrstr = sockaddr2hostname(sa);
390 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/udp: %s", addrstr, sockstrerror(sockerrno));
396 } /* int setup_vpn_in_socket */
398 static void retry_outgoing_handler(void *data) {
399 setup_outgoing_connection(data, true);
402 void retry_outgoing(outgoing_t *outgoing) {
403 outgoing->timeout += 5;
405 if(outgoing->timeout > maxtimeout) {
406 outgoing->timeout = maxtimeout;
409 timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval) {
410 outgoing->timeout, rand() % 100000
413 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout);
416 void finish_connecting(connection_t *c) {
417 logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname);
419 c->last_ping_time = now.tv_sec;
420 c->status.connecting = false;
425 static void do_outgoing_pipe(connection_t *c, const char *command) {
429 if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
430 logger(DEBUG_ALWAYS, LOG_ERR, "Could not create socketpair: %s", sockstrerror(sockerrno));
437 logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Using proxy %s", command);
448 // Other filedescriptors should be closed automatically by CLOEXEC
453 sockaddr2str(&c->address, &host, &port);
454 setenv("REMOTEADDRESS", host, true);
455 setenv("REMOTEPORT", port, true);
456 setenv("NODE", c->name, true);
457 setenv("NAME", myself->name, true);
460 setenv("NETNAME", netname, true);
463 int result = system(command);
466 logger(DEBUG_ALWAYS, LOG_ERR, "Could not execute %s: %s", command, strerror(errno));
468 logger(DEBUG_ALWAYS, LOG_ERR, "%s exited with non-zero status %d", command, result);
475 logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type exec not supported on this platform!");
480 static void handle_meta_write(connection_t *c) {
481 if(c->outbuf.len <= c->outbuf.offset) {
485 ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0);
488 if(!sockerrno || sockerrno == EPIPE) {
489 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname);
490 } else if(sockwouldblock(sockerrno)) {
491 logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname);
494 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));
497 terminate_connection(c, c->edge);
501 buffer_read(&c->outbuf, outlen);
504 io_set(&c->io, IO_READ);
508 static void handle_meta_io(void *data, int flags) {
509 connection_t *c = data;
511 if(c->status.connecting) {
513 The event loop does not protect against spurious events. Verify that we are actually connected
514 by issuing an empty send() call.
516 Note that the behavior of send() on potentially unconnected sockets differ between platforms:
517 +------------+-----------+-------------+-----------+
518 | Event | POSIX | Linux | Windows |
519 +------------+-----------+-------------+-----------+
520 | Spurious | ENOTCONN | EWOULDBLOCK | ENOTCONN |
521 | Failed | ENOTCONN | (cause) | ENOTCONN |
522 | Successful | (success) | (success) | (success) |
523 +------------+-----------+-------------+-----------+
525 if(send(c->socket, NULL, 0, 0) != 0) {
526 if(sockwouldblock(sockerrno)) {
532 if(!socknotconn(sockerrno)) {
533 socket_error = sockerrno;
535 socklen_t len = sizeof(socket_error);
536 getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&socket_error, &len);
540 logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(socket_error));
541 terminate_connection(c, false);
547 c->status.connecting = false;
548 finish_connecting(c);
551 if(flags & IO_WRITE) {
552 handle_meta_write(c);
554 handle_meta_connection_data(c);
558 bool do_outgoing_connection(outgoing_t *outgoing) {
559 const sockaddr_t *sa;
560 struct addrinfo *proxyai = NULL;
564 sa = get_recent_address(outgoing->node->address_cache);
567 logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->node->name);
568 retry_outgoing(outgoing);
572 connection_t *c = new_connection();
573 c->outgoing = outgoing;
574 memcpy(&c->address, sa, SALEN(sa->sa));
575 c->hostname = sockaddr2hostname(&c->address);
577 logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->node->name, c->hostname);
580 c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
582 } else if(proxytype == PROXY_EXEC) {
583 do_outgoing_pipe(c, proxyhost);
585 proxyai = str2addrinfo(proxyhost, proxyport, SOCK_STREAM);
592 logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport);
593 c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP);
597 if(c->socket == -1) {
598 logger(DEBUG_CONNECTIONS, LOG_ERR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno));
604 fcntl(c->socket, F_SETFD, FD_CLOEXEC);
607 if(proxytype != PROXY_EXEC) {
608 #if defined(IPV6_V6ONLY)
611 if(c->address.sa.sa_family == AF_INET6) {
612 setsockopt(c->socket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option));
617 bind_to_interface(c->socket);
624 result = connect(c->socket, &c->address.sa, SALEN(c->address.sa));
625 } else if(proxytype == PROXY_EXEC) {
632 result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen);
633 freeaddrinfo(proxyai);
636 if(result == -1 && !sockinprogress(sockerrno)) {
637 logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not connect to %s (%s): %s", outgoing->node->name, c->hostname, sockstrerror(sockerrno));
643 /* Now that there is a working socket, fill in the rest and register this connection. */
645 c->last_ping_time = time(NULL);
646 c->status.connecting = true;
647 c->name = xstrdup(outgoing->node->name);
648 #ifndef DISABLE_LEGACY
649 c->outcipher = myself->connection->outcipher;
650 c->outdigest = myself->connection->outdigest;
652 c->outmaclength = myself->connection->outmaclength;
653 c->outcompression = myself->connection->outcompression;
654 c->last_ping_time = now.tv_sec;
658 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ | IO_WRITE);
663 void setup_outgoing_connection(outgoing_t *outgoing, bool verbose) {
665 timeout_del(&outgoing->ev);
667 node_t *n = outgoing->node;
669 if(!n->address_cache) {
670 n->address_cache = open_address_cache(n);
674 logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", n->name);
676 if(!n->connection->outgoing) {
677 n->connection->outgoing = outgoing;
684 do_outgoing_connection(outgoing);
688 list_delete(outgoing_list, outgoing);
692 accept a new tcp connect and create a
695 void handle_new_meta_connection(void *data, int flags) {
697 listen_socket_t *l = data;
701 socklen_t len = sizeof(sa);
703 fd = accept(l->tcp.fd, &sa.sa, &len);
706 logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
712 // Check if we get many connections from the same host
714 static sockaddr_t prev_sa;
716 if(!sockaddrcmp_noport(&sa, &prev_sa)) {
717 static int samehost_burst;
718 static int samehost_burst_time;
720 if(now.tv_sec - samehost_burst_time > samehost_burst) {
723 samehost_burst -= now.tv_sec - samehost_burst_time;
726 samehost_burst_time = now.tv_sec;
729 if(samehost_burst > max_connection_burst) {
735 memcpy(&prev_sa, &sa, sizeof(sa));
737 // Check if we get many connections from different hosts
739 static int connection_burst;
740 static int connection_burst_time;
742 if(now.tv_sec - connection_burst_time > connection_burst) {
743 connection_burst = 0;
745 connection_burst -= now.tv_sec - connection_burst_time;
748 connection_burst_time = now.tv_sec;
751 if(connection_burst >= max_connection_burst) {
752 connection_burst = max_connection_burst;
757 // Accept the new connection
759 c = new_connection();
760 c->name = xstrdup("<unknown>");
761 #ifndef DISABLE_LEGACY
762 c->outcipher = myself->connection->outcipher;
763 c->outdigest = myself->connection->outdigest;
765 c->outmaclength = myself->connection->outmaclength;
766 c->outcompression = myself->connection->outcompression;
769 c->hostname = sockaddr2hostname(&sa);
771 c->last_ping_time = now.tv_sec;
773 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
775 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
781 c->allow_request = ID;
786 accept a new UNIX socket connection
788 void handle_new_unix_connection(void *data, int flags) {
794 socklen_t len = sizeof(sa);
796 fd = accept(io->fd, &sa.sa, &len);
799 logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
805 c = new_connection();
806 c->name = xstrdup("<control>");
808 c->hostname = xstrdup("localhost port unix");
810 c->last_ping_time = now.tv_sec;
812 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
814 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
818 c->allow_request = ID;
822 static void free_outgoing(outgoing_t *outgoing) {
823 timeout_del(&outgoing->ev);
827 void try_outgoing_connections(void) {
828 /* If there is no outgoing list yet, create one. Otherwise, mark all outgoings as deleted. */
831 outgoing_list = list_alloc((list_action_t)free_outgoing);
833 for list_each(outgoing_t, outgoing, outgoing_list) {
834 outgoing->timeout = -1;
838 /* Make sure there is one outgoing_t in the list for each ConnectTo. */
840 for(config_t *cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
842 get_config_string(cfg, &name);
844 if(!check_id(name)) {
845 logger(DEBUG_ALWAYS, LOG_ERR,
846 "Invalid name for outgoing connection in %s line %d",
847 cfg->file, cfg->line);
852 if(!strcmp(name, myself->name)) {
859 for list_each(outgoing_t, outgoing, outgoing_list) {
860 if(!strcmp(outgoing->node->name, name)) {
862 outgoing->timeout = 0;
868 outgoing_t *outgoing = xzalloc(sizeof(*outgoing));
869 node_t *n = lookup_node(name);
873 n->name = xstrdup(name);
878 list_insert_tail(outgoing_list, outgoing);
879 setup_outgoing_connection(outgoing, true);
883 /* Terminate any connections whose outgoing_t is to be deleted. */
885 for list_each(connection_t, c, connection_list) {
886 if(c->outgoing && c->outgoing->timeout == -1) {
888 logger(DEBUG_CONNECTIONS, LOG_INFO, "No more outgoing connection to %s", c->name);
889 terminate_connection(c, c->edge);
893 /* Delete outgoing_ts for which there is no ConnectTo. */
895 for list_each(outgoing_t, outgoing, outgoing_list)
896 if(outgoing->timeout == -1) {
897 list_delete_node(outgoing_list, node);