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