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