main: musl does not support execinfo.h (the backtrace functions)
[olsrd.git] / src / main.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in
14  *   the documentation and/or other materials provided with the
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its
17  *   contributors may be used to endorse or promote products derived
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  */
40
41 #include <arpa/inet.h>
42 #include <unistd.h>
43 #include <signal.h>
44 #include <sys/stat.h>
45 #include <assert.h>
46 #include <fcntl.h>
47 #if defined(__linux__) && !defined(__ANDROID__)
48   #ifdef __GLIBC__
49     #include <execinfo.h>
50   #endif
51 #include <syslog.h>
52 #endif /* defined(__linux__) && !defined(__ANDROID__) */
53
54 #include "cfgparser/olsrd_conf.h"
55 #include "ipcalc.h"
56 #include "defs.h"
57 #include "builddata.h"
58 #include "olsr.h"
59 #include "log.h"
60 #include "scheduler.h"
61 #include "parser.h"
62 #include "generate_msg.h"
63 #include "plugin_loader.h"
64 #include "apm.h"
65 #include "net_os.h"
66 #include "build_msg.h"
67 #include "net_olsr.h"
68 #include "mid_set.h"
69 #include "mpr_selector_set.h"
70 #include "gateway.h"
71 #include "olsr_niit.h"
72 #include "olsr_random.h"
73 #include "pid_file.h"
74 #include "lock_file.h"
75 #include "cli.h"
76
77 #ifdef __linux__
78 #include <linux/types.h>
79 #include <linux/rtnetlink.h>
80 #include "kernel_routes.h"
81
82 #endif /* __linux__ */
83
84 #ifdef _WIN32
85 #include <process.h>
86 #include <winbase.h>
87 #define olsr_shutdown(x) SignalHandler(x)
88 #define close(x) closesocket(x)
89 int __stdcall SignalHandler(unsigned long signo) __attribute__ ((noreturn));
90 void DisableIcmpRedirects(void);
91 #endif /* _WIN32 */
92
93 struct timer_entry * heartBeatTimer = NULL;
94
95 static char **olsr_argv = NULL;
96
97 struct olsr_cookie_info *def_timer_ci = NULL;
98
99 #ifndef _WIN32
100 /**
101  * Reconfigure olsrd. Currently kind of a hack...
102  *
103  *@param signo the signal that triggered this callback
104  */
105 __attribute__ ((noreturn))
106 static void olsr_reconfigure(int signo __attribute__ ((unused))) {
107 #ifndef _WIN32
108   int errNr = errno;
109 #endif
110   /* if we are started with -nofork, we do not want to go into the
111    * background here. So we can simply stop on -HUP
112    */
113   olsr_syslog(OLSR_LOG_INFO, "sot: olsr_reconfigure()\n");
114   if (!olsr_cnf->no_fork) {
115     if (!fork()) {
116       int i;
117       sigset_t sigs;
118
119       /* New process, wait a bit to let the old process exit */
120       sleep(3);
121       sigemptyset(&sigs);
122       sigaddset(&sigs, SIGHUP);
123       sigprocmask(SIG_UNBLOCK, &sigs, NULL);
124       for (i = sysconf(_SC_OPEN_MAX); --i > STDERR_FILENO;) {
125         close(i);
126       }
127       printf("Restarting %s", olsr_argv[0]);
128       olsr_syslog(OLSR_LOG_INFO, "Restarting %s", olsr_argv[0]);
129       execv(olsr_argv[0], olsr_argv);
130       olsr_syslog(OLSR_LOG_ERR, "execv(%s) failed: %s", olsr_argv[0], strerror(errno));
131     } else {
132       olsr_syslog(OLSR_LOG_INFO, "RECONFIGURING");
133     }
134   }
135 #ifndef _WIN32
136   errno = errNr;
137 #endif
138   olsr_exit(NULL, EXIT_SUCCESS);
139 }
140 #endif /* _WIN32 */
141
142 static void olsr_shutdown_messages(void) {
143   struct interface_olsr *ifn;
144
145   /* send TC reset */
146   for (ifn = ifnet; ifn; ifn = ifn->int_next) {
147     /* clean output buffer */
148     net_output(ifn);
149
150     /* send 'I'm gone' messages */
151     if (olsr_cnf->lq_level > 0) {
152       olsr_output_lq_tc(ifn);
153       olsr_output_lq_hello(ifn);
154     } else {
155       generate_tc(ifn);
156       generate_hello(ifn);
157     }
158     net_output(ifn);
159   }
160 }
161
162 /**
163  *Function called at shutdown. Signal handler
164  *
165  * @param signo the signal that triggered this call
166  */
167 __attribute__ ((noreturn))
168 #ifdef _WIN32
169 int __stdcall
170 SignalHandler(unsigned long signo)
171 #else /* _WIN32 */
172 static void olsr_shutdown(int signo __attribute__ ((unused)))
173 #endif /* _WIN32 */
174 {
175 #ifndef _WIN32
176   int errNr = errno;
177 #endif
178   struct interface_olsr *ifn;
179   int exit_value;
180
181   OLSR_PRINTF(1, "Received signal %d - shutting down\n", (int)signo);
182
183   /* instruct the scheduler to stop */
184   olsr_scheduler_stop();
185
186   /* clear all links and send empty hellos/tcs */
187   olsr_reset_all_links();
188
189   /* deactivate fisheye and immediate TCs */
190   olsr_cnf->lq_fish = 0;
191   for (ifn = ifnet; ifn; ifn = ifn->int_next) {
192     ifn->immediate_send_tc = false;
193   }
194   increase_local_ansn();
195
196   /* send first shutdown message burst */
197   olsr_shutdown_messages();
198
199   /* delete all routes */
200   olsr_delete_all_kernel_routes();
201
202   /* send second shutdown message burst */
203   olsr_shutdown_messages();
204
205   /* now try to cleanup the rest of the mess */
206   olsr_delete_all_tc_entries();
207
208   olsr_delete_all_mid_entries();
209
210 #ifdef __linux__
211   /* trigger gateway selection */
212   if (olsr_cnf->smart_gw_active) {
213     olsr_shutdown_gateways();
214     olsr_cleanup_gateways();
215   }
216
217   /* trigger niit static route cleanup */
218   if (olsr_cnf->use_niit) {
219     olsr_cleanup_niit_routes();
220   }
221
222   /* cleanup lo:olsr interface */
223   if (olsr_cnf->use_src_ip_routes) {
224     olsr_os_localhost_if(&olsr_cnf->main_addr, false);
225   }
226 #endif /* __linux__ */
227
228   olsr_destroy_parser();
229
230   OLSR_PRINTF(1, "Closing sockets...\n");
231
232   /* front-end IPC socket */
233   if (olsr_cnf->ipc_connections > 0) {
234     shutdown_ipc();
235   }
236
237   /* OLSR sockets */
238   for (ifn = ifnet; ifn; ifn = ifn->int_next) {
239     close(ifn->olsr_socket);
240     close(ifn->send_socket);
241
242 #ifdef __linux__
243     if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) {
244       olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default,
245           olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, false);
246     }
247 #endif /* __linux__ */
248   }
249
250   /* Closing plug-ins */
251   olsr_close_plugins();
252
253   /* Reset network settings */
254   net_os_restore_ifoptions();
255
256   /* ioctl socket */
257   close(olsr_cnf->ioctl_s);
258
259 #ifdef __linux__
260   if (DEF_RT_NONE != olsr_cnf->rt_table_pri) {
261     olsr_os_policy_rule(olsr_cnf->ip_version,
262         olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, false);
263   }
264   if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) {
265     olsr_os_policy_rule(olsr_cnf->ip_version,
266         olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, false);
267   }
268   if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) {
269     olsr_os_policy_rule(olsr_cnf->ip_version,
270         olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, false);
271   }
272   close(olsr_cnf->rtnl_s);
273   close (olsr_cnf->rt_monitor_socket);
274 #endif /* __linux__ */
275
276 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
277   /* routing socket */
278   close(olsr_cnf->rts);
279 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
280
281   /* remove the lock file */
282   olsr_remove_lock_file();
283
284   /* stop heartbeat that is showing on stdout */
285 #if !defined WINCE
286   if (heartBeatTimer) {
287     olsr_stop_timer(heartBeatTimer);
288     heartBeatTimer = NULL;
289   }
290 #endif /* !defined WINCE */
291
292   /* Free cookies and memory pools attached. */
293   OLSR_PRINTF(0, "Free all memory...\n");
294   olsr_delete_all_cookies();
295
296   olsr_syslog(OLSR_LOG_INFO, "%s stopped", olsrd_version);
297
298   OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n           http://www.olsr.org\n", olsrd_version);
299
300   exit_value = olsr_cnf->exit_value;
301   olsrd_free_cnf(&olsr_cnf);
302
303   /* close the log */
304   olsr_closelog();
305
306 #ifndef _WIN32
307   errno = errNr;
308 #endif
309   exit(exit_value);
310 }
311
312 #if defined(__linux__) && !defined(__ANDROID__)
313 static void olsr_segv_handler(int sig) {
314   static bool in_segv = false;
315
316 #ifdef __GLIBC__
317   void *bt_array[64];
318   size_t bt_size;
319   size_t bt_index=0;
320   char ** bt_syms;
321
322   bt_size = backtrace(bt_array, 64);
323   bt_syms = backtrace_symbols(bt_array, bt_size);
324
325   syslog(LOG_ERR, "olsrd crashed, stack trace follows");
326   while (bt_index < bt_size) {
327     syslog(LOG_ERR, "%s", bt_syms[bt_index++]);
328   }
329 #else
330   syslog(LOG_ERR, "olsrd crashed (logging a stack trace is not supported on this platform)");
331 #endif
332
333   if (!in_segv) {
334     in_segv = true;
335     olsr_shutdown(sig);
336   }
337
338   /* safety net */
339   exit(123);
340 }
341 #endif /* defined(__linux__) && !defined(__ANDROID__) */
342
343 /**
344  * Sets the provided configuration on all unconfigured
345  * interfaces
346  *
347  * @param ifs a linked list of interfaces to check and possible update
348  * @param cnf the default configuration to set on unconfigured interfaces
349  */
350 static int set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf) {
351   int changes = 0;
352
353   while (ifs) {
354     if (ifs->cnf == NULL) {
355       ifs->cnf = olsr_malloc(sizeof(struct if_config_options),
356           "Set default config");
357       *ifs->cnf = *cnf;
358       changes++;
359     }
360     ifs = ifs->next;
361   }
362   return changes;
363 }
364
365 /**
366  * Main entrypoint
367  */
368
369 int main(int argc, char *argv[]) {
370   int argcLocal = argc;
371
372   /* Open syslog */
373   olsr_openlog("olsrd");
374
375   /*
376    * Initialisation
377    */
378
379   /* setup debug printf destination */
380   debug_handle = stdout;
381
382   /* set stdout and stderr to unbuffered output */
383   setbuf(stdout, NULL);
384   setbuf(stderr, NULL);
385
386   /* setup random seed */
387   srandom(time(NULL));
388
389   /* Init widely used statics */
390   memset(&all_zero, 0, sizeof(union olsr_ip_addr));
391
392   /* store the arguments for restart */
393   olsr_argv = argv;
394
395   /*
396    * Start
397    */
398
399   print_version();
400
401   if (argcLocal == 2) {
402     if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "/?")) {
403       /* help */
404       print_usage(false);
405       olsr_exit(NULL, EXIT_SUCCESS);
406     }
407     if (!strcmp(argv[1], "-v")) {
408       /* version */
409       olsr_exit(NULL, EXIT_SUCCESS);
410     }
411   }
412
413   /* Check root Privileges */
414 #ifndef _WIN32
415   if (geteuid()) {
416     olsr_exit("You must be root (uid = 0) to run olsrd", EXIT_FAILURE);
417   }
418 #else /* _WIN32 */
419   DisableIcmpRedirects();
420
421   {
422     WSADATA WsaData;
423     if (WSAStartup(0x0202, &WsaData)) {
424       char buf2[1024];
425       snprintf(buf2, sizeof(buf2), "%s: Could not initialise WinSock", __func__);
426       olsr_exit(buf2, EXIT_FAILURE);
427     }
428   }
429 #endif /* _WIN32 */
430
431   /* load the configuration */
432   if (!loadConfig(&argcLocal, argv)) {
433     olsr_exit(NULL, EXIT_FAILURE);
434   }
435
436   /* Process CLI Arguments */
437   {
438     char * error = NULL;
439     int exitCode = EXIT_FAILURE;
440
441     /* get the default interface config */
442     struct if_config_options *default_ifcnf = get_default_if_config();
443     if (!default_ifcnf) {
444       olsr_exit("No default ifconfig found", EXIT_FAILURE);
445     }
446
447     /* Process olsrd options */
448     exitCode = olsr_process_arguments(argcLocal, argv, olsr_cnf, default_ifcnf, &error);
449     if (exitCode != 0) {
450       free(default_ifcnf);
451       olsr_exit(error, EXIT_FAILURE);
452     }
453
454     /* Set configuration for command-line specified interfaces */
455     set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
456
457     /* free the default ifcnf */
458     free(default_ifcnf);
459   }
460
461   /* Sanity check configuration */
462   if (olsrd_sanity_check_cnf(olsr_cnf) < 0) {
463     char buf2[1024];
464     snprintf(buf2, sizeof(buf2), "%s: Bad configuration", __func__);
465     olsr_exit(buf2, EXIT_FAILURE);
466   }
467
468   /* Setup derived configuration */
469   set_derived_cnf(olsr_cnf);
470
471   /* Print configuration */
472   if (olsr_cnf->debug_level > 1) {
473     olsrd_print_cnf(olsr_cnf);
474   }
475
476   /* configuration loaded and sane */
477
478   /* initialise timers */
479   olsr_init_timers();
480
481   def_timer_ci = olsr_alloc_cookie("Default Timer Cookie", OLSR_COOKIE_TYPE_TIMER);
482
483   /* create a socket for ioctl calls */
484   olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
485   if (olsr_cnf->ioctl_s < 0) {
486     char buf2[1024];
487     snprintf(buf2, sizeof(buf2), "ioctl socket: %s", strerror(errno));
488     olsr_exit(buf2, EXIT_FAILURE);
489   }
490
491   /* create a socket for netlink calls */
492 #ifdef __linux__
493   olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
494   if (olsr_cnf->rtnl_s < 0) {
495     char buf2[1024];
496     snprintf(buf2, sizeof(buf2), "rtnetlink socket: %s", strerror(errno));
497     olsr_exit(buf2, EXIT_FAILURE);
498   }
499
500   if (fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK)) {
501     olsr_syslog(OLSR_LOG_INFO, "rtnetlink could not be set to nonblocking");
502   }
503
504   if ((olsr_cnf->rt_monitor_socket = rtnetlink_register_socket(RTMGRP_LINK)) < 0) {
505     char buf2[1024];
506     snprintf(buf2, sizeof(buf2), "rtmonitor socket: %s", strerror(errno));
507     olsr_exit(buf2, EXIT_FAILURE);
508   }
509 #endif /* __linux__ */
510
511   /* create routing socket */
512 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
513   olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0);
514   if (olsr_cnf->rts < 0) {
515     char buf2[1024];
516     snprintf(buf2, sizeof(buf2), "routing socket: %s", strerror(errno));
517     olsr_exit(buf2, EXIT_FAILURE);
518   }
519 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
520
521   /* initialise gateway system */
522 #ifdef __linux__
523   if (olsr_cnf->smart_gw_active && olsr_init_gateways()) {
524     olsr_exit("Cannot initialise gateway tunnels", EXIT_FAILURE);
525   }
526 #endif /* __linux__ */
527
528   /* initialise niit if index */
529 #ifdef __linux__
530   if (olsr_cnf->use_niit) {
531     olsr_init_niit();
532   }
533 #endif /* __linux__ */
534
535   /* initialise empty TC timer */
536   set_empty_tc_timer(GET_TIMESTAMP(0));
537
538   /* enable ip forwarding on host and disable redirects globally (not for WIN32) */
539   net_os_set_global_ifoptions();
540
541   /* initialise parser */
542   olsr_init_parser();
543
544   /* initialise route exporter */
545   olsr_init_export_route();
546
547   /* initialise message sequence number */
548   init_msg_seqno();
549
550   /* initialise dynamic willingness calculation */
551   olsr_init_willingness();
552
553   /* Set up willingness/APM */
554   if (olsr_cnf->willingness_auto) {
555     if (apm_init() < 0) {
556       OLSR_PRINTF(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
557
558       olsr_syslog(OLSR_LOG_ERR, "Could not read APM info - setting default willingness(%d)\n",
559       WILL_DEFAULT);
560
561       olsr_cnf->willingness_auto = 0;
562       olsr_cnf->willingness = WILL_DEFAULT;
563     } else {
564       olsr_cnf->willingness = olsr_calculate_willingness();
565
566       OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, (double )olsr_cnf->will_int);
567     }
568   }
569
570   /* initialise net */
571   init_net();
572
573   /* initialise network interfaces */
574   if (!olsr_init_interfacedb()) {
575     if (olsr_cnf->allow_no_interfaces) {
576       fprintf( stderr, "No interfaces detected! This might be intentional, but it also might mean"
577           " that your configuration is fubar.\nI will continue after 5 seconds...\n");
578       olsr_startup_sleep(5);
579     } else {
580       char buf2[1024];
581       snprintf(buf2, sizeof(buf2), "%s: No interfaces detected", __func__);
582       olsr_exit(buf2, EXIT_FAILURE);
583     }
584   }
585
586 #ifdef __linux__
587   /* startup gateway system */
588   if (olsr_cnf->smart_gw_active && olsr_startup_gateways()) {
589     olsr_exit("Cannot startup gateway tunnels", EXIT_FAILURE);
590   }
591 #endif /* __linux__ */
592
593   /* initialise the IPC socket */
594   if ((olsr_cnf->ipc_connections > 0) && ipc_init()) {
595     olsr_exit("ipc_init failure", EXIT_FAILURE);
596   }
597
598   /* Initialisation of different tables to be used. */
599   olsr_init_tables();
600
601   olsr_do_startup_sleep();
602
603   /* start heartbeat that is showing on stdout */
604 #if !defined WINCE
605   if ((olsr_cnf->debug_level > 0) && isatty(STDOUT_FILENO)) {
606     heartBeatTimer = olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC, &generate_stdout_pulse, NULL, 0);
607   }
608 #endif /* !defined WINCE */
609
610   /* daemon mode */
611 #ifndef _WIN32
612   if ((olsr_cnf->debug_level == 0) && !olsr_cnf->no_fork) {
613     printf("%s detaching from the current process...\n", olsrd_version);
614     if (daemon(0, 0) < 0) {
615       char buf2[1024];
616       snprintf(buf2, sizeof(buf2), "daemon(3) failed: %s", strerror(errno));
617       olsr_exit(buf2, EXIT_FAILURE);
618     }
619   }
620 #endif /* _WIN32 */
621
622   if (!writePidFile()) {
623     olsr_exit(NULL, EXIT_FAILURE);
624   }
625
626   /* Create locking file for olsrd, will be cleared after olsrd exits */
627   if (!olsr_create_lock_file()) {
628     char buf2[1024];
629     snprintf(buf2, sizeof(buf2), "Error, cannot create OLSR lock file '%s'", olsr_cnf->lock_file);
630     olsr_exit(buf2, EXIT_FAILURE);
631   }
632
633   /* Load plugins */
634   olsr_load_plugins();
635
636   /* print the main address */
637   {
638     struct ipaddr_str buf;
639     OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
640   }
641
642   /* create policy routing rules with priorities if necessary */
643 #ifdef __linux__
644   if (DEF_RT_NONE != olsr_cnf->rt_table_pri) {
645     olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, true);
646   }
647
648   if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) {
649     olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, true);
650   }
651
652   if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) {
653     olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, true);
654   }
655
656   /* rule to default table on all olsrd interfaces */
657   if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) {
658     struct interface_olsr *ifn;
659     for (ifn = ifnet; ifn; ifn = ifn->int_next) {
660       olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, true);
661     }
662   }
663
664   /* trigger gateway selection */
665   if (olsr_cnf->smart_gw_active) {
666     olsr_trigger_inetgw_startup();
667   }
668
669   /* trigger niit static route setup */
670   if (olsr_cnf->use_niit) {
671     olsr_setup_niit_routes();
672   }
673
674   /* create lo:olsr interface */
675   if (olsr_cnf->use_src_ip_routes) {
676     olsr_os_localhost_if(&olsr_cnf->main_addr, true);
677   }
678 #endif /* __linux__ */
679
680   /* Start syslog entry */
681   olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version);
682
683   /* setup signal-handlers */
684 #ifdef _WIN32
685 #ifndef WINCE
686   SetConsoleCtrlHandler(SignalHandler, true);
687 #endif /* WINCE */
688 #else /* _WIN32 */
689   signal(SIGHUP, olsr_reconfigure);
690   signal(SIGINT, olsr_shutdown);
691   signal(SIGQUIT, olsr_shutdown);
692   signal(SIGILL, olsr_shutdown);
693   signal(SIGABRT, olsr_shutdown);
694 #if defined(__linux__) && !defined(__ANDROID__)
695   signal(SIGSEGV, olsr_segv_handler);
696 #endif  /* defined(__linux__) && !defined(__ANDROID__) */
697   signal(SIGTERM, olsr_shutdown);
698   signal(SIGPIPE, SIG_IGN);
699   // Ignoring SIGUSR1 and SIGUSR1 by default to be able to use them in plugins
700   signal(SIGUSR1, SIG_IGN);
701   signal(SIGUSR2, SIG_IGN);
702 #endif /* _WIN32 */
703
704   /* Starting scheduler */
705   olsr_scheduler();
706
707   /* We'll only get here when olsr_shutdown has stopped the scheduler */
708   sleep(30);
709
710   exit(EXIT_FAILURE);
711 } /* main */
712
713 /*
714  * Local Variables:
715  * c-basic-offset: 2
716  * indent-tabs-mode: nil
717  * End:
718  */