2 net.c -- most of the network code
3 Copyright (C) 1998-2005 Ivo Timmermans,
4 2000-2017 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"
27 #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) {
199 logger(DEBUG_ALWAYS, LOG_ERR, "Awaking from dead after %ld seconds of sleep", sleep_time);
201 Do not send any packets to tinc after we wake up.
202 The other node probably closed our connection but we still
203 are holding context information to them. This may happen on
204 laptops or any other hardware which can be suspended for some time.
205 Sending any data to node that wasn't expecting it will produce
206 annoying and misleading errors on the other side about failed signature
207 verification and or about missing sptps context
209 close_all_connections = true;
212 last_periodic_run_time = now;
214 for list_each(connection_t, c, connection_list) {
215 // control connections (eg. tinc ctl) do not have any timeout
216 if(c->status.control) {
220 if(close_all_connections) {
221 logger(DEBUG_ALWAYS, LOG_ERR, "Forcing connection close after sleep time %s (%s)", c->name, c->hostname);
222 terminate_connection(c, c->edge);
226 // Bail out early if we haven't reached the ping timeout for this node yet
227 if(c->last_ping_time + pingtimeout > now.tv_sec) {
231 // timeout during connection establishing
233 if(c->status.connecting) {
234 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname);
236 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname);
237 c->status.tarpit = true;
240 terminate_connection(c, c->edge);
244 // helps in UDP holepunching
245 try_tx(c->node, false);
247 // timeout during ping
248 if(c->status.pinged) {
249 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));
250 terminate_connection(c, c->edge);
254 // check whether we need to send a new ping
255 if(c->last_ping_time + pinginterval <= now.tv_sec) {
260 timeout_set(data, &(struct timeval) {
265 static void periodic_handler(void *data) {
266 /* Check if there are too many contradicting ADD_EDGE and DEL_EDGE messages.
267 This usually only happens when another node has the same Name as this node.
268 If so, sleep for a short while to prevent a storm of contradicting messages.
271 if(contradicting_del_edge > 100 && contradicting_add_edge > 100) {
272 logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime);
273 nanosleep(&(struct timespec) {
289 contradicting_add_edge = 0;
290 contradicting_del_edge = 0;
292 /* If AutoConnect is set, check if we need to make or break connections. */
294 if(autoconnect && node_tree->count > 1) {
298 timeout_set(data, &(struct timeval) {
303 void handle_meta_connection_data(connection_t *c) {
304 if(!receive_meta(c)) {
305 if(!c->status.control) {
306 c->status.tarpit = true;
309 terminate_connection(c, c->edge);
315 static void sigterm_handler(void *data) {
316 logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
320 static void sighup_handler(void *data) {
321 logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
324 if(reload_configuration()) {
329 static void sigalrm_handler(void *data) {
330 logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
335 int reload_configuration(void) {
336 char fname[PATH_MAX];
338 /* Reread our own configuration file */
340 exit_configuration(&config_tree);
341 init_configuration(&config_tree);
343 if(!read_server_config()) {
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, rand() % 100000
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);