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"
40 int contradicting_add_edge = 0;
41 int contradicting_del_edge = 0;
42 static int sleeptime = 10;
43 time_t last_config_check = 0;
44 static timeout_t pingtimer;
45 static timeout_t periodictimer;
46 static struct timeval last_periodic_run_time;
48 /* Purge edges and subnets of unreachable nodes. Use carefully. */
51 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Purging unreachable nodes");
53 /* Remove all edges and subnets owned by unreachable nodes. */
55 for splay_each(node_t, n, &node_tree) {
56 if(!n->status.reachable) {
57 logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Purging node %s (%s)", n->name, n->hostname);
59 for splay_each(subnet_t, s, &n->subnet_tree) {
60 send_del_subnet(everyone, s);
67 for splay_each(edge_t, e, &n->edge_tree) {
69 send_del_edge(everyone, e);
77 /* Check if anyone else claims to have an edge to an unreachable node. If not, delete node. */
79 for splay_each(node_t, n, &node_tree) {
80 if(!n->status.reachable) {
81 for splay_each(edge_t, e, &edge_weight_tree)
86 if(!autoconnect && (!strictsubnets || !n->subnet_tree.head))
87 /* in strictsubnets mode do not delete nodes with subnets */
95 /* Put a misbehaving connection in the tarpit */
97 static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
98 static unsigned int next_pit = 0;
100 if(pits[next_pit] != -1) {
101 closesocket(pits[next_pit]);
104 pits[next_pit++] = fd;
106 if(next_pit >= sizeof pits / sizeof pits[0]) {
112 Terminate a connection:
113 - Mark it as inactive
114 - Remove the edge representing this connection
116 - Check if we need to retry making an outgoing connection
118 void terminate_connection(connection_t *c, bool report) {
119 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname);
122 if(c->node->connection == c) {
123 c->node->connection = NULL;
127 if(report && !tunnelserver) {
128 send_del_edge(everyone, c->edge);
134 /* Run MST and SSSP algorithms */
138 /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */
140 if(report && !c->node->status.reachable) {
142 e = lookup_edge(c->node, myself);
146 send_del_edge(everyone, e);
155 outgoing_t *outgoing = c->outgoing;
158 /* Check if this was our outgoing connection */
161 do_outgoing_connection(outgoing);
165 /* Clean up dead proxy processes */
167 while(waitpid(-1, NULL, WNOHANG) > 0);
173 Check if the other end is active.
174 If we have sent packets, but didn't receive any,
175 then possibly the other end is dead. We send a
176 PING request over the meta connection. If the other
177 end does not reply in time, we consider them dead
178 and close the connection.
180 static void timeout_handler(void *data) {
182 bool close_all_connections = false;
185 timeout_handler will start after 30 seconds from start of tincd
186 hold information about the elapsed time since last time the handler
189 long sleep_time = now.tv_sec - last_periodic_run_time.tv_sec;
192 It seems that finding sane default value is harder than expected
193 Since we send every second a UDP packet to make holepunching work
194 And default UDP state expire on firewalls is between 15-30 seconds
195 we drop all connections after 60 Seconds - UDPDiscoveryTimeout=30
198 if(sleep_time > 2 * udp_discovery_timeout) {
202 logger(DEBUG_ALWAYS, LOG_ERR, "Awaking from dead after %ld seconds of sleep", sleep_time);
204 Do not send any packets to tinc after we wake up.
205 The other node probably closed our connection but we still
206 are holding context information to them. This may happen on
207 laptops or any other hardware which can be suspended for some time.
208 Sending any data to node that wasn't expecting it will produce
209 annoying and misleading errors on the other side about failed signature
210 verification and or about missing sptps context
212 close_all_connections = true;
215 last_periodic_run_time = now;
217 for list_each(connection_t, c, &connection_list) {
218 // control connections (eg. tinc ctl) do not have any timeout
219 if(c->status.control) {
223 if(close_all_connections) {
224 logger(DEBUG_ALWAYS, LOG_ERR, "Forcing connection close after sleep time %s (%s)", c->name, c->hostname);
225 terminate_connection(c, c->edge);
229 // Bail out early if we haven't reached the ping timeout for this node yet
230 if(c->last_ping_time + pingtimeout > now.tv_sec) {
234 // timeout during connection establishing
236 if(c->status.connecting) {
237 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname);
239 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname);
240 c->status.tarpit = true;
243 terminate_connection(c, c->edge);
247 // helps in UDP holepunching
248 try_tx(c->node, false);
250 // timeout during ping
251 if(c->status.pinged) {
252 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));
253 terminate_connection(c, c->edge);
257 // check whether we need to send a new ping
258 if(c->last_ping_time + pinginterval <= now.tv_sec) {
263 timeout_set(data, &(struct timeval) {
268 static void periodic_handler(void *data) {
269 /* Check if there are too many contradicting ADD_EDGE and DEL_EDGE messages.
270 This usually only happens when another node has the same Name as this node.
271 If so, sleep for a short while to prevent a storm of contradicting messages.
274 if(contradicting_del_edge > 100 && contradicting_add_edge > 100) {
275 logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime);
276 sleep_millis(sleeptime * 1000);
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 splay_empty_tree(&config_tree);
343 if(!read_server_config(&config_tree)) {
344 logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file.");
348 read_config_options(&config_tree, NULL);
350 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, myself->name);
351 read_config_file(&config_tree, fname, true);
353 /* Parse some options that are allowed to be changed while tinc is running */
355 setup_myself_reloadable();
357 /* If StrictSubnet is set, expire deleted Subnets and read new ones in */
360 for splay_each(subnet_t, subnet, &subnet_tree)
366 for splay_each(node_t, n, &node_tree) {
367 n->status.has_address = false;
373 for splay_each(subnet_t, subnet, &subnet_tree) {
378 if(subnet->expires == 1) {
379 send_del_subnet(everyone, subnet);
381 if(subnet->owner->status.reachable) {
382 subnet_update(subnet->owner, subnet, false);
385 subnet_del(subnet->owner, subnet);
386 } else if(subnet->expires == -1) {
389 send_add_subnet(everyone, subnet);
391 if(subnet->owner->status.reachable) {
392 subnet_update(subnet->owner, subnet, true);
396 } else { /* Only read our own subnets back in */
397 for splay_each(subnet_t, subnet, &myself->subnet_tree)
398 if(!subnet->expires) {
402 config_t *cfg = lookup_config(&config_tree, "Subnet");
405 subnet_t *subnet, *s2;
407 if(get_config_subnet(cfg, &subnet)) {
408 if((s2 = lookup_subnet(myself, subnet))) {
409 if(s2->expires == 1) {
415 subnet_add(myself, subnet);
416 send_add_subnet(everyone, subnet);
417 subnet_update(myself, subnet, true);
421 cfg = lookup_config_next(&config_tree, cfg);
424 for splay_each(subnet_t, subnet, &myself->subnet_tree) {
425 if(subnet->expires == 1) {
426 send_del_subnet(everyone, subnet);
427 subnet_update(myself, subnet, false);
428 subnet_del(myself, subnet);
433 /* Try to make outgoing connections */
435 try_outgoing_connections();
437 /* Close connections to hosts that have a changed or deleted host config file */
439 for list_each(connection_t, c, &connection_list) {
440 if(c->status.control) {
444 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
447 if(stat(fname, &s) || s.st_mtime > last_config_check) {
448 logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name);
449 terminate_connection(c, c->edge);
453 last_config_check = now.tv_sec;
459 /* Reset the reconnection timers for all outgoing connections */
460 for list_each(outgoing_t, outgoing, &outgoing_list) {
461 outgoing->timeout = 0;
464 timeout_set(&outgoing->ev, &(struct timeval) {
469 /* Check for outgoing connections that are in progress, and reset their ping timers */
470 for list_each(connection_t, c, &connection_list) {
471 if(c->outgoing && !c->node) {
472 c->last_ping_time = 0;
476 /* Kick the ping timeout handler */
477 timeout_set(&pingtimer, &(struct timeval) {
483 this is where it all happens...
485 int main_loop(void) {
486 last_periodic_run_time = now;
487 timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval) {
488 pingtimeout, jitter()
490 timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval) {
495 signal_t sighup = {0};
496 signal_t sigterm = {0};
497 signal_t sigquit = {0};
498 signal_t sigint = {0};
499 signal_t sigalrm = {0};
501 signal_add(&sighup, sighup_handler, &sighup, SIGHUP);
502 signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM);
503 signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT);
504 signal_add(&sigint, sigterm_handler, &sigint, SIGINT);
505 signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM);
509 logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", sockstrerror(sockerrno));
515 signal_del(&sigterm);
516 signal_del(&sigquit);
518 signal_del(&sigalrm);
521 timeout_del(&periodictimer);
522 timeout_del(&pingtimer);