2 net.c -- most of the network code
3 Copyright (C) 1998-2005 Ivo Timmermans,
4 2000-2021 Guus Sliepen <guus@tinc-vpn.org>
5 2006 Scott Lamb <slamb@slamb.org>
6 2011 Loïc Grenié <loic.grenie@gmail.com>
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 "autoconnect.h"
28 #include "connection.h"
41 int contradicting_add_edge = 0;
42 int contradicting_del_edge = 0;
43 static int sleeptime = 10;
44 time_t last_config_check = 0;
45 static timeout_t pingtimer;
46 static timeout_t periodictimer;
47 static struct timeval last_periodic_run_time;
49 /* Purge edges and subnets of unreachable nodes. Use carefully. */
52 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Purging unreachable nodes");
54 /* Remove all edges and subnets owned by unreachable nodes. */
56 for splay_each(node_t, n, node_tree) {
57 if(!n->status.reachable) {
58 logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Purging node %s (%s)", n->name, n->hostname);
60 for splay_each(subnet_t, s, n->subnet_tree) {
61 send_del_subnet(everyone, s);
68 for splay_each(edge_t, e, n->edge_tree) {
70 send_del_edge(everyone, e);
78 /* Check if anyone else claims to have an edge to an unreachable node. If not, delete node. */
80 for splay_each(node_t, n, node_tree) {
81 if(!n->status.reachable) {
82 for splay_each(edge_t, e, edge_weight_tree)
87 if(!autoconnect && (!strictsubnets || !n->subnet_tree->head))
88 /* in strictsubnets mode do not delete nodes with subnets */
96 /* Put a misbehaving connection in the tarpit */
98 static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
99 static unsigned int next_pit = 0;
101 if(pits[next_pit] != -1) {
102 closesocket(pits[next_pit]);
105 pits[next_pit++] = fd;
107 if(next_pit >= sizeof pits / sizeof pits[0]) {
113 Terminate a connection:
114 - Mark it as inactive
115 - Remove the edge representing this connection
117 - Check if we need to retry making an outgoing connection
119 void terminate_connection(connection_t *c, bool report) {
120 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname);
123 if(c->node->connection == c) {
124 c->node->connection = NULL;
128 if(report && !tunnelserver) {
129 send_del_edge(everyone, c->edge);
135 /* Run MST and SSSP algorithms */
139 /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */
141 if(report && !c->node->status.reachable) {
143 e = lookup_edge(c->node, myself);
147 send_del_edge(everyone, e);
156 outgoing_t *outgoing = c->outgoing;
159 /* Check if this was our outgoing connection */
162 do_outgoing_connection(outgoing);
166 /* Clean up dead proxy processes */
168 while(waitpid(-1, NULL, WNOHANG) > 0);
174 Check if the other end is active.
175 If we have sent packets, but didn't receive any,
176 then possibly the other end is dead. We send a
177 PING request over the meta connection. If the other
178 end does not reply in time, we consider them dead
179 and close the connection.
181 static void timeout_handler(void *data) {
183 bool close_all_connections = false;
186 timeout_handler will start after 30 seconds from start of tincd
187 hold information about the elapsed time since last time the handler
190 long sleep_time = now.tv_sec - last_periodic_run_time.tv_sec;
193 It seems that finding sane default value is harder than expected
194 Since we send every second a UDP packet to make holepunching work
195 And default UDP state expire on firewalls is between 15-30 seconds
196 we drop all connections after 60 Seconds - UDPDiscoveryTimeout=30
199 if(sleep_time > 2 * udp_discovery_timeout) {
200 logger(DEBUG_ALWAYS, LOG_ERR, "Awaking from dead after %ld seconds of sleep", sleep_time);
202 Do not send any packets to tinc after we wake up.
203 The other node probably closed our connection but we still
204 are holding context information to them. This may happen on
205 laptops or any other hardware which can be suspended for some time.
206 Sending any data to node that wasn't expecting it will produce
207 annoying and misleading errors on the other side about failed signature
208 verification and or about missing sptps context
210 close_all_connections = true;
213 last_periodic_run_time = now;
215 for list_each(connection_t, c, connection_list) {
216 // control connections (eg. tinc ctl) do not have any timeout
217 if(c->status.control) {
221 if(close_all_connections) {
222 logger(DEBUG_ALWAYS, LOG_ERR, "Forcing connection close after sleep time %s (%s)", c->name, c->hostname);
223 terminate_connection(c, c->edge);
227 // Bail out early if we haven't reached the ping timeout for this node yet
228 if(c->last_ping_time + pingtimeout > now.tv_sec) {
232 // timeout during connection establishing
234 if(c->status.connecting) {
235 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname);
237 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname);
238 c->status.tarpit = true;
241 terminate_connection(c, c->edge);
245 // helps in UDP holepunching
246 try_tx(c->node, false);
248 // timeout during ping
249 if(c->status.pinged) {
250 logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)(now.tv_sec - c->last_ping_time));
251 terminate_connection(c, c->edge);
255 // check whether we need to send a new ping
256 if(c->last_ping_time + pinginterval <= now.tv_sec) {
261 timeout_set(data, &(struct timeval) {
266 static void periodic_handler(void *data) {
267 /* Check if there are too many contradicting ADD_EDGE and DEL_EDGE messages.
268 This usually only happens when another node has the same Name as this node.
269 If so, sleep for a short while to prevent a storm of contradicting messages.
272 if(contradicting_del_edge > 100 && contradicting_add_edge > 100) {
273 logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime);
274 nanosleep(&(struct timespec) {
290 contradicting_add_edge = 0;
291 contradicting_del_edge = 0;
293 /* If AutoConnect is set, check if we need to make or break connections. */
295 if(autoconnect && node_tree->count > 1) {
299 timeout_set(data, &(struct timeval) {
304 void handle_meta_connection_data(connection_t *c) {
305 if(!receive_meta(c)) {
306 if(!c->status.control) {
307 c->status.tarpit = true;
310 terminate_connection(c, c->edge);
316 static void sigterm_handler(void *data) {
317 logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
321 static void sighup_handler(void *data) {
322 logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
325 if(reload_configuration()) {
330 static void sigalrm_handler(void *data) {
331 logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
336 int reload_configuration(void) {
337 char fname[PATH_MAX];
339 /* Reread our own configuration file */
341 exit_configuration(&config_tree);
342 init_configuration(&config_tree);
344 if(!read_server_config(config_tree)) {
345 logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file.");
349 read_config_options(config_tree, NULL);
351 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, myself->name);
352 read_config_file(config_tree, fname, true);
354 /* Parse some options that are allowed to be changed while tinc is running */
356 setup_myself_reloadable();
358 /* If StrictSubnet is set, expire deleted Subnets and read new ones in */
361 for splay_each(subnet_t, subnet, subnet_tree)
367 for splay_each(node_t, n, node_tree) {
368 n->status.has_address = false;
374 for splay_each(subnet_t, subnet, subnet_tree) {
379 if(subnet->expires == 1) {
380 send_del_subnet(everyone, subnet);
382 if(subnet->owner->status.reachable) {
383 subnet_update(subnet->owner, subnet, false);
386 subnet_del(subnet->owner, subnet);
387 } else if(subnet->expires == -1) {
390 send_add_subnet(everyone, subnet);
392 if(subnet->owner->status.reachable) {
393 subnet_update(subnet->owner, subnet, true);
397 } else { /* Only read our own subnets back in */
398 for splay_each(subnet_t, subnet, myself->subnet_tree)
399 if(!subnet->expires) {
403 config_t *cfg = lookup_config(config_tree, "Subnet");
406 subnet_t *subnet, *s2;
408 if(get_config_subnet(cfg, &subnet)) {
409 if((s2 = lookup_subnet(myself, subnet))) {
410 if(s2->expires == 1) {
416 subnet_add(myself, subnet);
417 send_add_subnet(everyone, subnet);
418 subnet_update(myself, subnet, true);
422 cfg = lookup_config_next(config_tree, cfg);
425 for splay_each(subnet_t, subnet, myself->subnet_tree) {
426 if(subnet->expires == 1) {
427 send_del_subnet(everyone, subnet);
428 subnet_update(myself, subnet, false);
429 subnet_del(myself, subnet);
434 /* Try to make outgoing connections */
436 try_outgoing_connections();
438 /* Close connections to hosts that have a changed or deleted host config file */
440 for list_each(connection_t, c, connection_list) {
441 if(c->status.control) {
445 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
448 if(stat(fname, &s) || s.st_mtime > last_config_check) {
449 logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name);
450 terminate_connection(c, c->edge);
454 last_config_check = now.tv_sec;
460 /* Reset the reconnection timers for all outgoing connections */
461 for list_each(outgoing_t, outgoing, outgoing_list) {
462 outgoing->timeout = 0;
465 timeout_set(&outgoing->ev, &(struct timeval) {
470 /* Check for outgoing connections that are in progress, and reset their ping timers */
471 for list_each(connection_t, c, connection_list) {
472 if(c->outgoing && !c->node) {
473 c->last_ping_time = 0;
477 /* Kick the ping timeout handler */
478 timeout_set(&pingtimer, &(struct timeval) {
484 this is where it all happens...
486 int main_loop(void) {
487 last_periodic_run_time = now;
488 timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval) {
489 pingtimeout, rand() % 100000
491 timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval) {
496 signal_t sighup = {0};
497 signal_t sigterm = {0};
498 signal_t sigquit = {0};
499 signal_t sigint = {0};
500 signal_t sigalrm = {0};
502 signal_add(&sighup, sighup_handler, &sighup, SIGHUP);
503 signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM);
504 signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT);
505 signal_add(&sigint, sigterm_handler, &sigint, SIGINT);
506 signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM);
510 logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", sockstrerror(sockerrno));
516 signal_del(&sigterm);
517 signal_del(&sigquit);
519 signal_del(&sigalrm);
522 timeout_del(&periodictimer);
523 timeout_del(&pingtimer);