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"
39 int contradicting_add_edge = 0;
40 int contradicting_del_edge = 0;
41 static int sleeptime = 10;
42 time_t last_config_check = 0;
43 static timeout_t pingtimer;
44 static timeout_t periodictimer;
45 static struct timeval last_periodic_run_time;
47 /* Purge edges and subnets of unreachable nodes. Use carefully. */
50 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Purging unreachable nodes");
52 /* Remove all edges and subnets owned by unreachable nodes. */
54 for splay_each(node_t, n, &node_tree) {
55 if(!n->status.reachable) {
56 logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Purging node %s (%s)", n->name, n->hostname);
58 for splay_each(subnet_t, s, &n->subnet_tree) {
59 send_del_subnet(everyone, s);
66 for splay_each(edge_t, e, &n->edge_tree) {
68 send_del_edge(everyone, e);
76 /* Check if anyone else claims to have an edge to an unreachable node. If not, delete node. */
78 for splay_each(node_t, n, &node_tree) {
79 if(!n->status.reachable) {
80 for splay_each(edge_t, e, &edge_weight_tree)
85 if(!autoconnect && (!strictsubnets || !n->subnet_tree.head))
86 /* in strictsubnets mode do not delete nodes with subnets */
94 /* Put a misbehaving connection in the tarpit */
96 static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
97 static unsigned int next_pit = 0;
99 if(pits[next_pit] != -1) {
100 closesocket(pits[next_pit]);
103 pits[next_pit++] = fd;
105 if(next_pit >= sizeof pits / sizeof pits[0]) {
111 Terminate a connection:
112 - Mark it as inactive
113 - Remove the edge representing this connection
115 - Check if we need to retry making an outgoing connection
117 void terminate_connection(connection_t *c, bool report) {
118 logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname);
121 if(c->node->connection == c) {
122 c->node->connection = NULL;
126 if(report && !tunnelserver) {
127 send_del_edge(everyone, c->edge);
133 /* Run MST and SSSP algorithms */
137 /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */
139 if(report && !c->node->status.reachable) {
141 e = lookup_edge(c->node, myself);
145 send_del_edge(everyone, e);
154 outgoing_t *outgoing = c->outgoing;
157 /* Check if this was our outgoing connection */
160 do_outgoing_connection(outgoing);
164 /* Clean up dead proxy processes */
166 while(waitpid(-1, NULL, WNOHANG) > 0);
172 Check if the other end is active.
173 If we have sent packets, but didn't receive any,
174 then possibly the other end is dead. We send a
175 PING request over the meta connection. If the other
176 end does not reply in time, we consider them dead
177 and close the connection.
179 static void timeout_handler(void *data) {
181 bool close_all_connections = false;
184 timeout_handler will start after 30 seconds from start of tincd
185 hold information about the elapsed time since last time the handler
188 long sleep_time = now.tv_sec - last_periodic_run_time.tv_sec;
191 It seems that finding sane default value is harder than expected
192 Since we send every second a UDP packet to make holepunching work
193 And default UDP state expire on firewalls is between 15-30 seconds
194 we drop all connections after 60 Seconds - UDPDiscoveryTimeout=30
197 if(sleep_time > 2 * udp_discovery_timeout) {
198 logger(DEBUG_ALWAYS, LOG_ERR, "Awaking from dead after %ld seconds of sleep", sleep_time);
200 Do not send any packets to tinc after we wake up.
201 The other node probably closed our connection but we still
202 are holding context information to them. This may happen on
203 laptops or any other hardware which can be suspended for some time.
204 Sending any data to node that wasn't expecting it will produce
205 annoying and misleading errors on the other side about failed signature
206 verification and or about missing sptps context
208 close_all_connections = true;
211 last_periodic_run_time = now;
213 for list_each(connection_t, c, &connection_list) {
214 // control connections (eg. tinc ctl) do not have any timeout
215 if(c->status.control) {
219 if(close_all_connections) {
220 logger(DEBUG_ALWAYS, LOG_ERR, "Forcing connection close after sleep time %s (%s)", c->name, c->hostname);
221 terminate_connection(c, c->edge);
225 // Bail out early if we haven't reached the ping timeout for this node yet
226 if(c->last_ping_time + pingtimeout > now.tv_sec) {
230 // timeout during connection establishing
232 if(c->status.connecting) {
233 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname);
235 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname);
236 c->status.tarpit = true;
239 terminate_connection(c, c->edge);
243 // helps in UDP holepunching
244 try_tx(c->node, false);
246 // timeout during ping
247 if(c->status.pinged) {
248 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));
249 terminate_connection(c, c->edge);
253 // check whether we need to send a new ping
254 if(c->last_ping_time + pinginterval <= now.tv_sec) {
259 timeout_set(data, &(struct timeval) {
264 static void periodic_handler(void *data) {
265 /* Check if there are too many contradicting ADD_EDGE and DEL_EDGE messages.
266 This usually only happens when another node has the same Name as this node.
267 If so, sleep for a short while to prevent a storm of contradicting messages.
270 if(contradicting_del_edge > 100 && contradicting_add_edge > 100) {
271 logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime);
272 sleep_millis(sleeptime * 1000);
286 contradicting_add_edge = 0;
287 contradicting_del_edge = 0;
289 /* If AutoConnect is set, check if we need to make or break connections. */
291 if(autoconnect && node_tree.count > 1) {
295 timeout_set(data, &(struct timeval) {
300 void handle_meta_connection_data(connection_t *c) {
301 if(!receive_meta(c)) {
302 if(!c->status.control) {
303 c->status.tarpit = true;
306 terminate_connection(c, c->edge);
312 static void sigterm_handler(void *data) {
313 logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
317 static void sighup_handler(void *data) {
318 logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
321 if(reload_configuration()) {
326 static void sigalrm_handler(void *data) {
327 logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
332 int reload_configuration(void) {
333 char fname[PATH_MAX];
335 /* Reread our own configuration file */
337 splay_empty_tree(&config_tree);
339 if(!read_server_config(&config_tree)) {
340 logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file.");
344 read_config_options(&config_tree, NULL);
346 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, myself->name);
347 read_config_file(&config_tree, fname, true);
349 /* Parse some options that are allowed to be changed while tinc is running */
351 setup_myself_reloadable();
353 /* If StrictSubnet is set, expire deleted Subnets and read new ones in */
356 for splay_each(subnet_t, subnet, &subnet_tree)
362 for splay_each(node_t, n, &node_tree) {
363 n->status.has_address = false;
369 for splay_each(subnet_t, subnet, &subnet_tree) {
374 if(subnet->expires == 1) {
375 send_del_subnet(everyone, subnet);
377 if(subnet->owner->status.reachable) {
378 subnet_update(subnet->owner, subnet, false);
381 subnet_del(subnet->owner, subnet);
382 } else if(subnet->expires == -1) {
385 send_add_subnet(everyone, subnet);
387 if(subnet->owner->status.reachable) {
388 subnet_update(subnet->owner, subnet, true);
392 } else { /* Only read our own subnets back in */
393 for splay_each(subnet_t, subnet, &myself->subnet_tree)
394 if(!subnet->expires) {
398 config_t *cfg = lookup_config(&config_tree, "Subnet");
401 subnet_t *subnet, *s2;
403 if(get_config_subnet(cfg, &subnet)) {
404 if((s2 = lookup_subnet(myself, subnet))) {
405 if(s2->expires == 1) {
411 subnet_add(myself, subnet);
412 send_add_subnet(everyone, subnet);
413 subnet_update(myself, subnet, true);
417 cfg = lookup_config_next(&config_tree, cfg);
420 for splay_each(subnet_t, subnet, &myself->subnet_tree) {
421 if(subnet->expires == 1) {
422 send_del_subnet(everyone, subnet);
423 subnet_update(myself, subnet, false);
424 subnet_del(myself, subnet);
429 /* Try to make outgoing connections */
431 try_outgoing_connections();
433 /* Close connections to hosts that have a changed or deleted host config file */
435 for list_each(connection_t, c, &connection_list) {
436 if(c->status.control) {
440 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
443 if(stat(fname, &s) || s.st_mtime > last_config_check) {
444 logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name);
445 terminate_connection(c, c->edge);
449 last_config_check = now.tv_sec;
455 /* Reset the reconnection timers for all outgoing connections */
456 for list_each(outgoing_t, outgoing, &outgoing_list) {
457 outgoing->timeout = 0;
460 timeout_set(&outgoing->ev, &(struct timeval) {
465 /* Check for outgoing connections that are in progress, and reset their ping timers */
466 for list_each(connection_t, c, &connection_list) {
467 if(c->outgoing && !c->node) {
468 c->last_ping_time = 0;
472 /* Kick the ping timeout handler */
473 timeout_set(&pingtimer, &(struct timeval) {
479 this is where it all happens...
481 int main_loop(void) {
482 last_periodic_run_time = now;
483 timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval) {
484 pingtimeout, jitter()
486 timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval) {
491 signal_t sighup = {0};
492 signal_t sigterm = {0};
493 signal_t sigquit = {0};
494 signal_t sigint = {0};
495 signal_t sigalrm = {0};
497 signal_add(&sighup, sighup_handler, &sighup, SIGHUP);
498 signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM);
499 signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT);
500 signal_add(&sigint, sigterm_handler, &sigint, SIGINT);
501 signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM);
505 logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", sockstrerror(sockerrno));
511 signal_del(&sigterm);
512 signal_del(&sigquit);
514 signal_del(&sigalrm);
517 timeout_del(&periodictimer);
518 timeout_del(&pingtimer);