Allow using key & configuration parser from tincd in tinc.
[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 "device.h"
30 #include "graph.h"
31 #include "logger.h"
32 #include "meta.h"
33 #include "names.h"
34 #include "net.h"
35 #include "netutl.h"
36 #include "protocol.h"
37 #include "subnet.h"
38 #include "utils.h"
39 #include "xalloc.h"
40
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;
48
49 /* Purge edges and subnets of unreachable nodes. Use carefully. */
50
51 void purge(void) {
52         logger(DEBUG_PROTOCOL, LOG_DEBUG, "Purging unreachable nodes");
53
54         /* Remove all edges and subnets owned by unreachable nodes. */
55
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);
59
60                         for splay_each(subnet_t, s, n->subnet_tree) {
61                                 send_del_subnet(everyone, s);
62
63                                 if(!strictsubnets) {
64                                         subnet_del(n, s);
65                                 }
66                         }
67
68                         for splay_each(edge_t, e, n->edge_tree) {
69                                 if(!tunnelserver) {
70                                         send_del_edge(everyone, e);
71                                 }
72
73                                 edge_del(e);
74                         }
75                 }
76         }
77
78         /* Check if anyone else claims to have an edge to an unreachable node. If not, delete node. */
79
80         for splay_each(node_t, n, node_tree) {
81                 if(!n->status.reachable) {
82                         for splay_each(edge_t, e, edge_weight_tree)
83                                 if(e->to == n) {
84                                         return;
85                                 }
86
87                         if(!autoconnect && (!strictsubnets || !n->subnet_tree->head))
88                                 /* in strictsubnets mode do not delete nodes with subnets */
89                         {
90                                 node_del(n);
91                         }
92                 }
93         }
94 }
95
96 /* Put a misbehaving connection in the tarpit */
97 void tarpit(int fd) {
98         static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
99         static unsigned int next_pit = 0;
100
101         if(pits[next_pit] != -1) {
102                 closesocket(pits[next_pit]);
103         }
104
105         pits[next_pit++] = fd;
106
107         if(next_pit >= sizeof pits / sizeof pits[0]) {
108                 next_pit = 0;
109         }
110 }
111
112 /*
113   Terminate a connection:
114   - Mark it as inactive
115   - Remove the edge representing this connection
116   - Kill it with fire
117   - Check if we need to retry making an outgoing connection
118 */
119 void terminate_connection(connection_t *c, bool report) {
120         logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname);
121
122         if(c->node) {
123                 if(c->node->connection == c) {
124                         c->node->connection = NULL;
125                 }
126
127                 if(c->edge) {
128                         if(report && !tunnelserver) {
129                                 send_del_edge(everyone, c->edge);
130                         }
131
132                         edge_del(c->edge);
133                         c->edge = NULL;
134
135                         /* Run MST and SSSP algorithms */
136
137                         graph();
138
139                         /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */
140
141                         if(report && !c->node->status.reachable) {
142                                 edge_t *e;
143                                 e = lookup_edge(c->node, myself);
144
145                                 if(e) {
146                                         if(!tunnelserver) {
147                                                 send_del_edge(everyone, e);
148                                         }
149
150                                         edge_del(e);
151                                 }
152                         }
153                 }
154         }
155
156         outgoing_t *outgoing = c->outgoing;
157         connection_del(c);
158
159         /* Check if this was our outgoing connection */
160
161         if(outgoing) {
162                 do_outgoing_connection(outgoing);
163         }
164
165 #ifndef HAVE_MINGW
166         /* Clean up dead proxy processes */
167
168         while(waitpid(-1, NULL, WNOHANG) > 0);
169
170 #endif
171 }
172
173 /*
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.
180 */
181 static void timeout_handler(void *data) {
182
183         bool close_all_connections = false;
184
185         /*
186                  timeout_handler will start after 30 seconds from start of tincd
187                  hold information about the elapsed time since last time the handler
188                  has been run
189         */
190         long sleep_time = now.tv_sec - last_periodic_run_time.tv_sec;
191
192         /*
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
197                  by default
198         */
199         if(sleep_time > 2 * udp_discovery_timeout) {
200                 logger(DEBUG_ALWAYS, LOG_ERR, "Awaking from dead after %ld seconds of sleep", sleep_time);
201                 /*
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
209                 */
210                 close_all_connections = true;
211         }
212
213         last_periodic_run_time = now;
214
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) {
218                         continue;
219                 }
220
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);
224                         continue;
225                 }
226
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) {
229                         continue;
230                 }
231
232                 // timeout during connection establishing
233                 if(!c->edge) {
234                         if(c->status.connecting) {
235                                 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname);
236                         } else {
237                                 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname);
238                                 c->status.tarpit = true;
239                         }
240
241                         terminate_connection(c, c->edge);
242                         continue;
243                 }
244
245                 // helps in UDP holepunching
246                 try_tx(c->node, false);
247
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);
252                         continue;
253                 }
254
255                 // check whether we need to send a new ping
256                 if(c->last_ping_time + pinginterval <= now.tv_sec) {
257                         send_ping(c);
258                 }
259         }
260
261         timeout_set(data, &(struct timeval) {
262                 1, rand() % 100000
263         });
264 }
265
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.
270         */
271
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) {
275                         sleeptime, 0
276                 }, NULL);
277                 sleeptime *= 2;
278
279                 if(sleeptime < 0) {
280                         sleeptime = 3600;
281                 }
282         } else {
283                 sleeptime /= 2;
284
285                 if(sleeptime < 10) {
286                         sleeptime = 10;
287                 }
288         }
289
290         contradicting_add_edge = 0;
291         contradicting_del_edge = 0;
292
293         /* If AutoConnect is set, check if we need to make or break connections. */
294
295         if(autoconnect && node_tree->count > 1) {
296                 do_autoconnect();
297         }
298
299         timeout_set(data, &(struct timeval) {
300                 5, rand() % 100000
301         });
302 }
303
304 void handle_meta_connection_data(connection_t *c) {
305         if(!receive_meta(c)) {
306                 if(!c->status.control) {
307                         c->status.tarpit = true;
308                 }
309
310                 terminate_connection(c, c->edge);
311                 return;
312         }
313 }
314
315 #ifndef HAVE_MINGW
316 static void sigterm_handler(void *data) {
317         logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
318         event_exit();
319 }
320
321 static void sighup_handler(void *data) {
322         logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
323         reopenlogger();
324
325         if(reload_configuration()) {
326                 exit(1);
327         }
328 }
329
330 static void sigalrm_handler(void *data) {
331         logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
332         retry();
333 }
334 #endif
335
336 int reload_configuration(void) {
337         char fname[PATH_MAX];
338
339         /* Reread our own configuration file */
340
341         exit_configuration(&config_tree);
342         init_configuration(&config_tree);
343
344         if(!read_server_config(config_tree)) {
345                 logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file.");
346                 return EINVAL;
347         }
348
349         read_config_options(config_tree, NULL);
350
351         snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, myself->name);
352         read_config_file(config_tree, fname, true);
353
354         /* Parse some options that are allowed to be changed while tinc is running */
355
356         setup_myself_reloadable();
357
358         /* If StrictSubnet is set, expire deleted Subnets and read new ones in */
359
360         if(strictsubnets) {
361                 for splay_each(subnet_t, subnet, subnet_tree)
362                         if(subnet->owner) {
363                                 subnet->expires = 1;
364                         }
365         }
366
367         for splay_each(node_t, n, node_tree) {
368                 n->status.has_address = false;
369         }
370
371         load_all_nodes();
372
373         if(strictsubnets) {
374                 for splay_each(subnet_t, subnet, subnet_tree) {
375                         if(!subnet->owner) {
376                                 continue;
377                         }
378
379                         if(subnet->expires == 1) {
380                                 send_del_subnet(everyone, subnet);
381
382                                 if(subnet->owner->status.reachable) {
383                                         subnet_update(subnet->owner, subnet, false);
384                                 }
385
386                                 subnet_del(subnet->owner, subnet);
387                         } else if(subnet->expires == -1) {
388                                 subnet->expires = 0;
389                         } else {
390                                 send_add_subnet(everyone, subnet);
391
392                                 if(subnet->owner->status.reachable) {
393                                         subnet_update(subnet->owner, subnet, true);
394                                 }
395                         }
396                 }
397         } else { /* Only read our own subnets back in */
398                 for splay_each(subnet_t, subnet, myself->subnet_tree)
399                         if(!subnet->expires) {
400                                 subnet->expires = 1;
401                         }
402
403                 config_t *cfg = lookup_config(config_tree, "Subnet");
404
405                 while(cfg) {
406                         subnet_t *subnet, *s2;
407
408                         if(get_config_subnet(cfg, &subnet)) {
409                                 if((s2 = lookup_subnet(myself, subnet))) {
410                                         if(s2->expires == 1) {
411                                                 s2->expires = 0;
412                                         }
413
414                                         free_subnet(subnet);
415                                 } else {
416                                         subnet_add(myself, subnet);
417                                         send_add_subnet(everyone, subnet);
418                                         subnet_update(myself, subnet, true);
419                                 }
420                         }
421
422                         cfg = lookup_config_next(config_tree, cfg);
423                 }
424
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);
430                         }
431                 }
432         }
433
434         /* Try to make outgoing connections */
435
436         try_outgoing_connections();
437
438         /* Close connections to hosts that have a changed or deleted host config file */
439
440         for list_each(connection_t, c, connection_list) {
441                 if(c->status.control) {
442                         continue;
443                 }
444
445                 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
446                 struct stat s;
447
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);
451                 }
452         }
453
454         last_config_check = now.tv_sec;
455
456         return 0;
457 }
458
459 void retry(void) {
460         /* Reset the reconnection timers for all outgoing connections */
461         for list_each(outgoing_t, outgoing, outgoing_list) {
462                 outgoing->timeout = 0;
463
464                 if(outgoing->ev.cb)
465                         timeout_set(&outgoing->ev, &(struct timeval) {
466                         0, 0
467                 });
468         }
469
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;
474                 }
475         }
476
477         /* Kick the ping timeout handler */
478         timeout_set(&pingtimer, &(struct timeval) {
479                 0, 0
480         });
481 }
482
483 /*
484   this is where it all happens...
485 */
486 int main_loop(void) {
487         last_periodic_run_time = now;
488         timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval) {
489                 pingtimeout, rand() % 100000
490         });
491         timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval) {
492                 0, 0
493         });
494
495 #ifndef HAVE_MINGW
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};
501
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);
507 #endif
508
509         if(!event_loop()) {
510                 logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", sockstrerror(sockerrno));
511                 return 1;
512         }
513
514 #ifndef HAVE_MINGW
515         signal_del(&sighup);
516         signal_del(&sigterm);
517         signal_del(&sigquit);
518         signal_del(&sigint);
519         signal_del(&sigalrm);
520 #endif
521
522         timeout_del(&periodictimer);
523         timeout_del(&pingtimer);
524
525         return 0;
526 }