tinc: update to 1.1pre11
[tomato.git] / release / src / router / tinc / src / net_socket.c
blob1bf9d16afe03588c079af6aad0c9a1946f202369
1 /*
2 net_socket.c -- Handle various kinds of sockets.
3 Copyright (C) 1998-2005 Ivo Timmermans,
4 2000-2014 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.
23 #include "system.h"
25 #include "conf.h"
26 #include "connection.h"
27 #include "control_common.h"
28 #include "list.h"
29 #include "logger.h"
30 #include "meta.h"
31 #include "names.h"
32 #include "net.h"
33 #include "netutl.h"
34 #include "protocol.h"
35 #include "utils.h"
36 #include "xalloc.h"
38 /* Needed on Mac OS/X */
39 #ifndef SOL_TCP
40 #define SOL_TCP IPPROTO_TCP
41 #endif
43 int addressfamily = AF_UNSPEC;
44 int maxtimeout = 900;
45 int seconds_till_retry = 5;
46 int udp_rcvbuf = 0;
47 int udp_sndbuf = 0;
48 int max_connection_burst = 100;
50 listen_socket_t listen_socket[MAXSOCKETS];
51 int listen_sockets;
52 #ifndef HAVE_MINGW
53 io_t unix_socket;
54 #endif
55 list_t *outgoing_list = NULL;
57 /* Setup sockets */
59 static void configure_tcp(connection_t *c) {
60 int option;
62 #ifdef O_NONBLOCK
63 int flags = fcntl(c->socket, F_GETFL);
65 if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) {
66 logger(DEBUG_ALWAYS, LOG_ERR, "fcntl for %s: %s", c->hostname, strerror(errno));
68 #elif defined(WIN32)
69 unsigned long arg = 1;
71 if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) {
72 logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno));
74 #endif
76 #if defined(SOL_TCP) && defined(TCP_NODELAY)
77 option = 1;
78 setsockopt(c->socket, SOL_TCP, TCP_NODELAY, (void *)&option, sizeof option);
79 #endif
81 #if defined(SOL_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY)
82 option = IPTOS_LOWDELAY;
83 setsockopt(c->socket, SOL_IP, IP_TOS, (void *)&option, sizeof option);
84 #endif
87 static bool bind_to_interface(int sd) {
88 char *iface;
90 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
91 struct ifreq ifr;
92 int status;
93 #endif /* defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) */
95 if(!get_config_string (lookup_config (config_tree, "BindToInterface"), &iface))
96 return true;
98 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
99 memset(&ifr, 0, sizeof(ifr));
100 strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
101 ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0;
103 status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
104 if(status) {
105 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface,
106 sockstrerror(sockerrno));
107 return false;
109 #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */
110 logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface");
111 #endif
113 return true;
116 static bool bind_to_address(connection_t *c) {
117 int s = -1;
119 for(int i = 0; i < listen_sockets && listen_socket[i].bindto; i++) {
120 if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family)
121 continue;
122 if(s >= 0)
123 return false;
124 s = i;
127 if(s < 0)
128 return false;
130 sockaddr_t sa = listen_socket[s].sa;
131 if(sa.sa.sa_family == AF_INET)
132 sa.in.sin_port = 0;
133 else if(sa.sa.sa_family == AF_INET6)
134 sa.in6.sin6_port = 0;
136 if(bind(c->socket, &sa.sa, SALEN(sa.sa))) {
137 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", sockstrerror(sockerrno));
138 return false;
141 return true;
144 int setup_listen_socket(const sockaddr_t *sa) {
145 int nfd;
146 char *addrstr;
147 int option;
148 char *iface;
150 nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
152 if(nfd < 0) {
153 logger(DEBUG_STATUS, LOG_ERR, "Creating metasocket failed: %s", sockstrerror(sockerrno));
154 return -1;
157 #ifdef FD_CLOEXEC
158 fcntl(nfd, F_SETFD, FD_CLOEXEC);
159 #endif
161 /* Optimize TCP settings */
163 option = 1;
164 setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option);
166 #if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
167 if(sa->sa.sa_family == AF_INET6)
168 setsockopt(nfd, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
169 #endif
171 if(get_config_string
172 (lookup_config(config_tree, "BindToInterface"), &iface)) {
173 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
174 struct ifreq ifr;
176 memset(&ifr, 0, sizeof ifr);
177 strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
179 if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof ifr)) {
180 closesocket(nfd);
181 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface,
182 sockstrerror(sockerrno));
183 return -1;
185 #else
186 logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface");
187 #endif
190 if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
191 closesocket(nfd);
192 addrstr = sockaddr2hostname(sa);
193 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno));
194 free(addrstr);
195 return -1;
198 if(listen(nfd, 3)) {
199 closesocket(nfd);
200 logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "listen", sockstrerror(sockerrno));
201 return -1;
204 return nfd;
207 int setup_vpn_in_socket(const sockaddr_t *sa) {
208 int nfd;
209 char *addrstr;
210 int option;
212 nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
214 if(nfd < 0) {
215 logger(DEBUG_ALWAYS, LOG_ERR, "Creating UDP socket failed: %s", sockstrerror(sockerrno));
216 return -1;
219 #ifdef FD_CLOEXEC
220 fcntl(nfd, F_SETFD, FD_CLOEXEC);
221 #endif
223 #ifdef O_NONBLOCK
225 int flags = fcntl(nfd, F_GETFL);
227 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
228 closesocket(nfd);
229 logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl",
230 strerror(errno));
231 return -1;
234 #elif defined(WIN32)
236 unsigned long arg = 1;
237 if(ioctlsocket(nfd, FIONBIO, &arg) != 0) {
238 closesocket(nfd);
239 logger(DEBUG_ALWAYS, LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno));
240 return -1;
243 #endif
245 option = 1;
246 setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option);
247 setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof option);
249 if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf)))
250 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, sockstrerror(sockerrno));
252 if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf)))
253 logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, sockstrerror(sockerrno));
255 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
256 if(sa->sa.sa_family == AF_INET6)
257 setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
258 #endif
260 #if defined(IP_DONTFRAG) && !defined(IP_DONTFRAGMENT)
261 #define IP_DONTFRAGMENT IP_DONTFRAG
262 #endif
264 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
265 if(myself->options & OPTION_PMTU_DISCOVERY) {
266 option = IP_PMTUDISC_DO;
267 setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option));
269 #elif defined(IPPROTO_IP) && defined(IP_DONTFRAGMENT)
270 if(myself->options & OPTION_PMTU_DISCOVERY) {
271 option = 1;
272 setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, (void *)&option, sizeof(option));
274 #endif
276 #if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
277 if(myself->options & OPTION_PMTU_DISCOVERY) {
278 option = IPV6_PMTUDISC_DO;
279 setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option));
281 #elif defined(IPPROTO_IPV6) && defined(IPV6_DONTFRAG)
282 if(myself->options & OPTION_PMTU_DISCOVERY) {
283 option = 1;
284 setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, (void *)&option, sizeof(option));
286 #endif
288 if (!bind_to_interface(nfd)) {
289 closesocket(nfd);
290 return -1;
293 if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
294 closesocket(nfd);
295 addrstr = sockaddr2hostname(sa);
296 logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/udp: %s", addrstr, sockstrerror(sockerrno));
297 free(addrstr);
298 return -1;
301 return nfd;
302 } /* int setup_vpn_in_socket */
304 static void retry_outgoing_handler(void *data) {
305 setup_outgoing_connection(data);
308 void retry_outgoing(outgoing_t *outgoing) {
309 outgoing->timeout += 5;
311 if(outgoing->timeout > maxtimeout)
312 outgoing->timeout = maxtimeout;
314 timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval){outgoing->timeout, rand() % 100000});
316 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout);
319 void finish_connecting(connection_t *c) {
320 logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname);
322 c->last_ping_time = now.tv_sec;
323 c->status.connecting = false;
325 send_id(c);
328 static void do_outgoing_pipe(connection_t *c, char *command) {
329 #ifndef HAVE_MINGW
330 int fd[2];
332 if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
333 logger(DEBUG_ALWAYS, LOG_ERR, "Could not create socketpair: %s", sockstrerror(sockerrno));
334 return;
337 if(fork()) {
338 c->socket = fd[0];
339 close(fd[1]);
340 logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Using proxy %s", command);
341 return;
344 close(0);
345 close(1);
346 close(fd[0]);
347 dup2(fd[1], 0);
348 dup2(fd[1], 1);
349 close(fd[1]);
351 // Other filedescriptors should be closed automatically by CLOEXEC
353 char *host = NULL;
354 char *port = NULL;
356 sockaddr2str(&c->address, &host, &port);
357 setenv("REMOTEADDRESS", host, true);
358 setenv("REMOTEPORT", port, true);
359 setenv("NODE", c->name, true);
360 setenv("NAME", myself->name, true);
361 if(netname)
362 setenv("NETNAME", netname, true);
364 int result = system(command);
365 if(result < 0)
366 logger(DEBUG_ALWAYS, LOG_ERR, "Could not execute %s: %s", command, strerror(errno));
367 else if(result)
368 logger(DEBUG_ALWAYS, LOG_ERR, "%s exited with non-zero status %d", command, result);
369 exit(result);
370 #else
371 logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type exec not supported on this platform!");
372 return;
373 #endif
376 static void handle_meta_write(connection_t *c) {
377 if(c->outbuf.len <= c->outbuf.offset)
378 return;
380 ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0);
381 if(outlen <= 0) {
382 if(!sockerrno || sockerrno == EPIPE) {
383 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname);
384 } else if(sockwouldblock(sockerrno)) {
385 logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname);
386 return;
387 } else {
388 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));
391 terminate_connection(c, c->edge);
392 return;
395 buffer_read(&c->outbuf, outlen);
396 if(!c->outbuf.len)
397 io_set(&c->io, IO_READ);
400 static void handle_meta_io(void *data, int flags) {
401 connection_t *c = data;
403 if(c->status.connecting) {
405 The event loop does not protect against spurious events. Verify that we are actually connected
406 by issuing an empty send() call.
408 Note that the behavior of send() on potentially unconnected sockets differ between platforms:
409 +------------+-----------+-------------+-----------+
410 | Event | POSIX | Linux | Windows |
411 +------------+-----------+-------------+-----------+
412 | Spurious | ENOTCONN | EWOULDBLOCK | ENOTCONN |
413 | Failed | ENOTCONN | (cause) | ENOTCONN |
414 | Successful | (success) | (success) | (success) |
415 +------------+-----------+-------------+-----------+
417 if (send(c->socket, NULL, 0, 0) != 0) {
418 if (sockwouldblock(sockerrno))
419 return;
420 int socket_error;
421 if (!socknotconn(sockerrno))
422 socket_error = sockerrno;
423 else {
424 socklen_t len = sizeof socket_error;
425 getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&socket_error, &len);
427 if (socket_error) {
428 logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(socket_error));
429 terminate_connection(c, false);
431 return;
434 c->status.connecting = false;
435 finish_connecting(c);
438 if(flags & IO_WRITE)
439 handle_meta_write(c);
440 else
441 handle_meta_connection_data(c);
444 bool do_outgoing_connection(outgoing_t *outgoing) {
445 char *address, *port, *space;
446 struct addrinfo *proxyai = NULL;
447 int result;
449 begin:
450 if(!outgoing->ai) {
451 if(!outgoing->cfg) {
452 logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->name);
453 retry_outgoing(outgoing);
454 return false;
457 get_config_string(outgoing->cfg, &address);
459 space = strchr(address, ' ');
460 if(space) {
461 port = xstrdup(space + 1);
462 *space = 0;
463 } else {
464 if(!get_config_string(lookup_config(outgoing->config_tree, "Port"), &port))
465 port = xstrdup("655");
468 outgoing->ai = str2addrinfo(address, port, SOCK_STREAM);
469 free(address);
470 free(port);
472 outgoing->aip = outgoing->ai;
473 outgoing->cfg = lookup_config_next(outgoing->config_tree, outgoing->cfg);
476 if(!outgoing->aip) {
477 if(outgoing->ai)
478 freeaddrinfo(outgoing->ai);
479 outgoing->ai = NULL;
480 goto begin;
483 connection_t *c = new_connection();
484 c->outgoing = outgoing;
486 memcpy(&c->address, outgoing->aip->ai_addr, outgoing->aip->ai_addrlen);
487 outgoing->aip = outgoing->aip->ai_next;
489 c->hostname = sockaddr2hostname(&c->address);
491 logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->name, c->hostname);
493 if(!proxytype) {
494 c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
495 configure_tcp(c);
496 } else if(proxytype == PROXY_EXEC) {
497 do_outgoing_pipe(c, proxyhost);
498 } else {
499 proxyai = str2addrinfo(proxyhost, proxyport, SOCK_STREAM);
500 if(!proxyai) {
501 free_connection(c);
502 goto begin;
504 logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport);
505 c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP);
506 configure_tcp(c);
509 if(c->socket == -1) {
510 logger(DEBUG_CONNECTIONS, LOG_ERR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno));
511 free_connection(c);
512 goto begin;
515 #ifdef FD_CLOEXEC
516 fcntl(c->socket, F_SETFD, FD_CLOEXEC);
517 #endif
519 if(proxytype != PROXY_EXEC) {
520 #if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
521 int option = 1;
522 if(c->address.sa.sa_family == AF_INET6)
523 setsockopt(c->socket, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
524 #endif
526 bind_to_interface(c->socket);
527 bind_to_address(c);
530 /* Connect */
532 if(!proxytype) {
533 result = connect(c->socket, &c->address.sa, SALEN(c->address.sa));
534 } else if(proxytype == PROXY_EXEC) {
535 result = 0;
536 } else {
537 result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen);
538 freeaddrinfo(proxyai);
541 if(result == -1 && !sockinprogress(sockerrno)) {
542 logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not connect to %s (%s): %s", outgoing->name, c->hostname, sockstrerror(sockerrno));
543 free_connection(c);
545 goto begin;
548 /* Now that there is a working socket, fill in the rest and register this connection. */
550 c->status.connecting = true;
551 c->name = xstrdup(outgoing->name);
552 c->outcipher = myself->connection->outcipher;
553 c->outdigest = myself->connection->outdigest;
554 c->outmaclength = myself->connection->outmaclength;
555 c->outcompression = myself->connection->outcompression;
556 c->last_ping_time = now.tv_sec;
558 connection_add(c);
560 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ|IO_WRITE);
562 return true;
565 // Find edges pointing to this node, and use them to build a list of unique, known addresses.
566 static struct addrinfo *get_known_addresses(node_t *n) {
567 struct addrinfo *ai = NULL;
569 for splay_each(edge_t, e, n->edge_tree) {
570 if(!e->reverse)
571 continue;
573 bool found = false;
574 for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
575 if(!sockaddrcmp(&e->reverse->address, (sockaddr_t *)aip->ai_addr)) {
576 found = true;
577 break;
580 if(found)
581 continue;
583 struct addrinfo *nai = xzalloc(sizeof *nai);
584 if(ai)
585 ai->ai_next = nai;
586 ai = nai;
587 ai->ai_family = e->reverse->address.sa.sa_family;
588 ai->ai_socktype = SOCK_STREAM;
589 ai->ai_protocol = IPPROTO_TCP;
590 ai->ai_addrlen = SALEN(e->reverse->address.sa);
591 ai->ai_addr = xmalloc(ai->ai_addrlen);
592 memcpy(ai->ai_addr, &e->reverse->address, ai->ai_addrlen);
595 return ai;
598 void setup_outgoing_connection(outgoing_t *outgoing) {
599 timeout_del(&outgoing->ev);
601 node_t *n = lookup_node(outgoing->name);
603 if(n && n->connection) {
604 logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", outgoing->name);
606 n->connection->outgoing = outgoing;
607 return;
610 init_configuration(&outgoing->config_tree);
611 read_host_config(outgoing->config_tree, outgoing->name);
612 outgoing->cfg = lookup_config(outgoing->config_tree, "Address");
614 if(!outgoing->cfg) {
615 if(n)
616 outgoing->aip = outgoing->ai = get_known_addresses(n);
617 if(!outgoing->ai) {
618 logger(DEBUG_ALWAYS, LOG_ERR, "No address known for %s", outgoing->name);
619 return;
623 do_outgoing_connection(outgoing);
627 accept a new tcp connect and create a
628 new connection
630 void handle_new_meta_connection(void *data, int flags) {
631 listen_socket_t *l = data;
632 connection_t *c;
633 sockaddr_t sa;
634 int fd;
635 socklen_t len = sizeof sa;
637 fd = accept(l->tcp.fd, &sa.sa, &len);
639 if(fd < 0) {
640 logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
641 return;
644 sockaddrunmap(&sa);
646 // Check if we get many connections from the same host
648 static sockaddr_t prev_sa;
649 static int tarpit = -1;
651 if(tarpit >= 0) {
652 closesocket(tarpit);
653 tarpit = -1;
656 if(!sockaddrcmp_noport(&sa, &prev_sa)) {
657 static int samehost_burst;
658 static int samehost_burst_time;
660 if(now.tv_sec - samehost_burst_time > samehost_burst)
661 samehost_burst = 0;
662 else
663 samehost_burst -= now.tv_sec - samehost_burst_time;
665 samehost_burst_time = now.tv_sec;
666 samehost_burst++;
668 if(samehost_burst > max_connection_burst) {
669 tarpit = fd;
670 return;
674 memcpy(&prev_sa, &sa, sizeof sa);
676 // Check if we get many connections from different hosts
678 static int connection_burst;
679 static int connection_burst_time;
681 if(now.tv_sec - connection_burst_time > connection_burst)
682 connection_burst = 0;
683 else
684 connection_burst -= now.tv_sec - connection_burst_time;
686 connection_burst_time = now.tv_sec;
687 connection_burst++;
689 if(connection_burst >= max_connection_burst) {
690 connection_burst = max_connection_burst;
691 tarpit = fd;
692 return;
695 // Accept the new connection
697 c = new_connection();
698 c->name = xstrdup("<unknown>");
699 c->outcipher = myself->connection->outcipher;
700 c->outdigest = myself->connection->outdigest;
701 c->outmaclength = myself->connection->outmaclength;
702 c->outcompression = myself->connection->outcompression;
704 c->address = sa;
705 c->hostname = sockaddr2hostname(&sa);
706 c->socket = fd;
707 c->last_ping_time = now.tv_sec;
709 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
711 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
713 configure_tcp(c);
715 connection_add(c);
717 c->allow_request = ID;
718 send_id(c);
721 #ifndef HAVE_MINGW
723 accept a new UNIX socket connection
725 void handle_new_unix_connection(void *data, int flags) {
726 io_t *io = data;
727 connection_t *c;
728 sockaddr_t sa;
729 int fd;
730 socklen_t len = sizeof sa;
732 fd = accept(io->fd, &sa.sa, &len);
734 if(fd < 0) {
735 logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
736 return;
739 sockaddrunmap(&sa);
741 c = new_connection();
742 c->name = xstrdup("<control>");
743 c->address = sa;
744 c->hostname = xstrdup("localhost port unix");
745 c->socket = fd;
746 c->last_ping_time = now.tv_sec;
748 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
750 io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
752 connection_add(c);
754 c->allow_request = ID;
756 send_id(c);
758 #endif
760 static void free_outgoing(outgoing_t *outgoing) {
761 timeout_del(&outgoing->ev);
763 if(outgoing->ai)
764 freeaddrinfo(outgoing->ai);
766 if(outgoing->config_tree)
767 exit_configuration(&outgoing->config_tree);
769 if(outgoing->name)
770 free(outgoing->name);
772 free(outgoing);
775 void try_outgoing_connections(void) {
776 /* If there is no outgoing list yet, create one. Otherwise, mark all outgoings as deleted. */
778 if(!outgoing_list) {
779 outgoing_list = list_alloc((list_action_t)free_outgoing);
780 } else {
781 for list_each(outgoing_t, outgoing, outgoing_list)
782 outgoing->timeout = -1;
785 /* Make sure there is one outgoing_t in the list for each ConnectTo. */
787 for(config_t *cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
788 char *name;
789 get_config_string(cfg, &name);
791 if(!check_id(name)) {
792 logger(DEBUG_ALWAYS, LOG_ERR,
793 "Invalid name for outgoing connection in %s line %d",
794 cfg->file, cfg->line);
795 free(name);
796 continue;
799 bool found = false;
801 for list_each(outgoing_t, outgoing, outgoing_list) {
802 if(!strcmp(outgoing->name, name)) {
803 found = true;
804 outgoing->timeout = 0;
805 break;
809 if(!found) {
810 outgoing_t *outgoing = xzalloc(sizeof *outgoing);
811 outgoing->name = name;
812 list_insert_tail(outgoing_list, outgoing);
813 setup_outgoing_connection(outgoing);
817 /* Terminate any connections whose outgoing_t is to be deleted. */
819 for list_each(connection_t, c, connection_list) {
820 if(c->outgoing && c->outgoing->timeout == -1) {
821 c->outgoing = NULL;
822 logger(DEBUG_CONNECTIONS, LOG_INFO, "No more outgoing connection to %s", c->name);
823 terminate_connection(c, c->edge);
827 /* Delete outgoing_ts for which there is no ConnectTo. */
829 for list_each(outgoing_t, outgoing, outgoing_list)
830 if(outgoing->timeout == -1)
831 list_delete_node(outgoing_list, node);