Use splay trees inside node_t directly.
[tinc] / src / net.c
1 /*
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>
7
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.
12
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.
17
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.
21 */
22
23 #include "system.h"
24
25 #include "autoconnect.h"
26 #include "conf_net.h"
27 #include "conf.h"
28 #include "connection.h"
29 #include "graph.h"
30 #include "logger.h"
31 #include "meta.h"
32 #include "names.h"
33 #include "net.h"
34 #include "protocol.h"
35 #include "subnet.h"
36 #include "utils.h"
37
38 int contradicting_add_edge = 0;
39 int contradicting_del_edge = 0;
40 static int sleeptime = 10;
41 time_t last_config_check = 0;
42 static timeout_t pingtimer;
43 static timeout_t periodictimer;
44 static struct timeval last_periodic_run_time;
45
46 /* Purge edges and subnets of unreachable nodes. Use carefully. */
47
48 void purge(void) {
49         logger(DEBUG_PROTOCOL, LOG_DEBUG, "Purging unreachable nodes");
50
51         /* Remove all edges and subnets owned by unreachable nodes. */
52
53         for splay_each(node_t, n, &node_tree) {
54                 if(!n->status.reachable) {
55                         logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Purging node %s (%s)", n->name, n->hostname);
56
57                         for splay_each(subnet_t, s, &n->subnet_tree) {
58                                 send_del_subnet(everyone, s);
59
60                                 if(!strictsubnets) {
61                                         subnet_del(n, s);
62                                 }
63                         }
64
65                         for splay_each(edge_t, e, &n->edge_tree) {
66                                 if(!tunnelserver) {
67                                         send_del_edge(everyone, e);
68                                 }
69
70                                 edge_del(e);
71                         }
72                 }
73         }
74
75         /* Check if anyone else claims to have an edge to an unreachable node. If not, delete node. */
76
77         for splay_each(node_t, n, &node_tree) {
78                 if(!n->status.reachable) {
79                         for splay_each(edge_t, e, &edge_weight_tree)
80                                 if(e->to == n) {
81                                         return;
82                                 }
83
84                         if(!autoconnect && (!strictsubnets || !n->subnet_tree.head))
85                                 /* in strictsubnets mode do not delete nodes with subnets */
86                         {
87                                 node_del(n);
88                         }
89                 }
90         }
91 }
92
93 /* Put a misbehaving connection in the tarpit */
94 void tarpit(int fd) {
95         static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
96         static unsigned int next_pit = 0;
97
98         if(pits[next_pit] != -1) {
99                 closesocket(pits[next_pit]);
100         }
101
102         pits[next_pit++] = fd;
103
104         if(next_pit >= sizeof pits / sizeof pits[0]) {
105                 next_pit = 0;
106         }
107 }
108
109 /*
110   Terminate a connection:
111   - Mark it as inactive
112   - Remove the edge representing this connection
113   - Kill it with fire
114   - Check if we need to retry making an outgoing connection
115 */
116 void terminate_connection(connection_t *c, bool report) {
117         logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname);
118
119         if(c->node) {
120                 if(c->node->connection == c) {
121                         c->node->connection = NULL;
122                 }
123
124                 if(c->edge) {
125                         if(report && !tunnelserver) {
126                                 send_del_edge(everyone, c->edge);
127                         }
128
129                         edge_del(c->edge);
130                         c->edge = NULL;
131
132                         /* Run MST and SSSP algorithms */
133
134                         graph();
135
136                         /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */
137
138                         if(report && !c->node->status.reachable) {
139                                 edge_t *e;
140                                 e = lookup_edge(c->node, myself);
141
142                                 if(e) {
143                                         if(!tunnelserver) {
144                                                 send_del_edge(everyone, e);
145                                         }
146
147                                         edge_del(e);
148                                 }
149                         }
150                 }
151         }
152
153         outgoing_t *outgoing = c->outgoing;
154         connection_del(c);
155
156         /* Check if this was our outgoing connection */
157
158         if(outgoing) {
159                 do_outgoing_connection(outgoing);
160         }
161
162 #ifndef HAVE_MINGW
163         /* Clean up dead proxy processes */
164
165         while(waitpid(-1, NULL, WNOHANG) > 0);
166
167 #endif
168 }
169
170 /*
171   Check if the other end is active.
172   If we have sent packets, but didn't receive any,
173   then possibly the other end is dead. We send a
174   PING request over the meta connection. If the other
175   end does not reply in time, we consider them dead
176   and close the connection.
177 */
178 static void timeout_handler(void *data) {
179
180         bool close_all_connections = false;
181
182         /*
183                  timeout_handler will start after 30 seconds from start of tincd
184                  hold information about the elapsed time since last time the handler
185                  has been run
186         */
187         long sleep_time = now.tv_sec - last_periodic_run_time.tv_sec;
188
189         /*
190                  It seems that finding sane default value is harder than expected
191                  Since we send every second a UDP packet to make holepunching work
192                  And default UDP state expire on firewalls is between 15-30 seconds
193                  we drop all connections after 60 Seconds - UDPDiscoveryTimeout=30
194                  by default
195         */
196         if(sleep_time > 2 * udp_discovery_timeout) {
197                 logger(DEBUG_ALWAYS, LOG_ERR, "Awaking from dead after %ld seconds of sleep", sleep_time);
198                 /*
199                         Do not send any packets to tinc after we wake up.
200                         The other node probably closed our connection but we still
201                         are holding context information to them. This may happen on
202                         laptops or any other hardware which can be suspended for some time.
203                         Sending any data to node that wasn't expecting it will produce
204                         annoying and misleading errors on the other side about failed signature
205                         verification and or about missing sptps context
206                 */
207                 close_all_connections = true;
208         }
209
210         last_periodic_run_time = now;
211
212         for list_each(connection_t, c, &connection_list) {
213                 // control connections (eg. tinc ctl) do not have any timeout
214                 if(c->status.control) {
215                         continue;
216                 }
217
218                 if(close_all_connections) {
219                         logger(DEBUG_ALWAYS, LOG_ERR, "Forcing connection close after sleep time %s (%s)", c->name, c->hostname);
220                         terminate_connection(c, c->edge);
221                         continue;
222                 }
223
224                 // Bail out early if we haven't reached the ping timeout for this node yet
225                 if(c->last_ping_time + pingtimeout > now.tv_sec) {
226                         continue;
227                 }
228
229                 // timeout during connection establishing
230                 if(!c->edge) {
231                         if(c->status.connecting) {
232                                 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname);
233                         } else {
234                                 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname);
235                                 c->status.tarpit = true;
236                         }
237
238                         terminate_connection(c, c->edge);
239                         continue;
240                 }
241
242                 // helps in UDP holepunching
243                 try_tx(c->node, false);
244
245                 // timeout during ping
246                 if(c->status.pinged) {
247                         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));
248                         terminate_connection(c, c->edge);
249                         continue;
250                 }
251
252                 // check whether we need to send a new ping
253                 if(c->last_ping_time + pinginterval <= now.tv_sec) {
254                         send_ping(c);
255                 }
256         }
257
258         timeout_set(data, &(struct timeval) {
259                 1, rand() % 100000
260         });
261 }
262
263 static void periodic_handler(void *data) {
264         /* Check if there are too many contradicting ADD_EDGE and DEL_EDGE messages.
265            This usually only happens when another node has the same Name as this node.
266            If so, sleep for a short while to prevent a storm of contradicting messages.
267         */
268
269         if(contradicting_del_edge > 100 && contradicting_add_edge > 100) {
270                 logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime);
271                 nanosleep(&(struct timespec) {
272                         sleeptime, 0
273                 }, NULL);
274                 sleeptime *= 2;
275
276                 if(sleeptime < 0) {
277                         sleeptime = 3600;
278                 }
279         } else {
280                 sleeptime /= 2;
281
282                 if(sleeptime < 10) {
283                         sleeptime = 10;
284                 }
285         }
286
287         contradicting_add_edge = 0;
288         contradicting_del_edge = 0;
289
290         /* If AutoConnect is set, check if we need to make or break connections. */
291
292         if(autoconnect && node_tree.count > 1) {
293                 do_autoconnect();
294         }
295
296         timeout_set(data, &(struct timeval) {
297                 5, rand() % 100000
298         });
299 }
300
301 void handle_meta_connection_data(connection_t *c) {
302         if(!receive_meta(c)) {
303                 if(!c->status.control) {
304                         c->status.tarpit = true;
305                 }
306
307                 terminate_connection(c, c->edge);
308                 return;
309         }
310 }
311
312 #ifndef HAVE_MINGW
313 static void sigterm_handler(void *data) {
314         logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
315         event_exit();
316 }
317
318 static void sighup_handler(void *data) {
319         logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
320         reopenlogger();
321
322         if(reload_configuration()) {
323                 exit(1);
324         }
325 }
326
327 static void sigalrm_handler(void *data) {
328         logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
329         retry();
330 }
331 #endif
332
333 int reload_configuration(void) {
334         char fname[PATH_MAX];
335
336         /* Reread our own configuration file */
337
338         splay_empty_tree(&config_tree);
339
340         if(!read_server_config(&config_tree)) {
341                 logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file.");
342                 return EINVAL;
343         }
344
345         read_config_options(&config_tree, NULL);
346
347         snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, myself->name);
348         read_config_file(&config_tree, fname, true);
349
350         /* Parse some options that are allowed to be changed while tinc is running */
351
352         setup_myself_reloadable();
353
354         /* If StrictSubnet is set, expire deleted Subnets and read new ones in */
355
356         if(strictsubnets) {
357                 for splay_each(subnet_t, subnet, &subnet_tree)
358                         if(subnet->owner) {
359                                 subnet->expires = 1;
360                         }
361         }
362
363         for splay_each(node_t, n, &node_tree) {
364                 n->status.has_address = false;
365         }
366
367         load_all_nodes();
368
369         if(strictsubnets) {
370                 for splay_each(subnet_t, subnet, &subnet_tree) {
371                         if(!subnet->owner) {
372                                 continue;
373                         }
374
375                         if(subnet->expires == 1) {
376                                 send_del_subnet(everyone, subnet);
377
378                                 if(subnet->owner->status.reachable) {
379                                         subnet_update(subnet->owner, subnet, false);
380                                 }
381
382                                 subnet_del(subnet->owner, subnet);
383                         } else if(subnet->expires == -1) {
384                                 subnet->expires = 0;
385                         } else {
386                                 send_add_subnet(everyone, subnet);
387
388                                 if(subnet->owner->status.reachable) {
389                                         subnet_update(subnet->owner, subnet, true);
390                                 }
391                         }
392                 }
393         } else { /* Only read our own subnets back in */
394                 for splay_each(subnet_t, subnet, &myself->subnet_tree)
395                         if(!subnet->expires) {
396                                 subnet->expires = 1;
397                         }
398
399                 config_t *cfg = lookup_config(&config_tree, "Subnet");
400
401                 while(cfg) {
402                         subnet_t *subnet, *s2;
403
404                         if(get_config_subnet(cfg, &subnet)) {
405                                 if((s2 = lookup_subnet(myself, subnet))) {
406                                         if(s2->expires == 1) {
407                                                 s2->expires = 0;
408                                         }
409
410                                         free_subnet(subnet);
411                                 } else {
412                                         subnet_add(myself, subnet);
413                                         send_add_subnet(everyone, subnet);
414                                         subnet_update(myself, subnet, true);
415                                 }
416                         }
417
418                         cfg = lookup_config_next(&config_tree, cfg);
419                 }
420
421                 for splay_each(subnet_t, subnet, &myself->subnet_tree) {
422                         if(subnet->expires == 1) {
423                                 send_del_subnet(everyone, subnet);
424                                 subnet_update(myself, subnet, false);
425                                 subnet_del(myself, subnet);
426                         }
427                 }
428         }
429
430         /* Try to make outgoing connections */
431
432         try_outgoing_connections();
433
434         /* Close connections to hosts that have a changed or deleted host config file */
435
436         for list_each(connection_t, c, &connection_list) {
437                 if(c->status.control) {
438                         continue;
439                 }
440
441                 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
442                 struct stat s;
443
444                 if(stat(fname, &s) || s.st_mtime > last_config_check) {
445                         logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name);
446                         terminate_connection(c, c->edge);
447                 }
448         }
449
450         last_config_check = now.tv_sec;
451
452         return 0;
453 }
454
455 void retry(void) {
456         /* Reset the reconnection timers for all outgoing connections */
457         for list_each(outgoing_t, outgoing, &outgoing_list) {
458                 outgoing->timeout = 0;
459
460                 if(outgoing->ev.cb)
461                         timeout_set(&outgoing->ev, &(struct timeval) {
462                         0, 0
463                 });
464         }
465
466         /* Check for outgoing connections that are in progress, and reset their ping timers */
467         for list_each(connection_t, c, &connection_list) {
468                 if(c->outgoing && !c->node) {
469                         c->last_ping_time = 0;
470                 }
471         }
472
473         /* Kick the ping timeout handler */
474         timeout_set(&pingtimer, &(struct timeval) {
475                 0, 0
476         });
477 }
478
479 /*
480   this is where it all happens...
481 */
482 int main_loop(void) {
483         last_periodic_run_time = now;
484         timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval) {
485                 pingtimeout, rand() % 100000
486         });
487         timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval) {
488                 0, 0
489         });
490
491 #ifndef HAVE_MINGW
492         signal_t sighup = {0};
493         signal_t sigterm = {0};
494         signal_t sigquit = {0};
495         signal_t sigint = {0};
496         signal_t sigalrm = {0};
497
498         signal_add(&sighup, sighup_handler, &sighup, SIGHUP);
499         signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM);
500         signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT);
501         signal_add(&sigint, sigterm_handler, &sigint, SIGINT);
502         signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM);
503 #endif
504
505         if(!event_loop()) {
506                 logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", sockstrerror(sockerrno));
507                 return 1;
508         }
509
510 #ifndef HAVE_MINGW
511         signal_del(&sighup);
512         signal_del(&sigterm);
513         signal_del(&sigquit);
514         signal_del(&sigint);
515         signal_del(&sigalrm);
516 #endif
517
518         timeout_del(&periodictimer);
519         timeout_del(&pingtimer);
520
521         return 0;
522 }