info: java: update workspace
[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 static int argc_saved = 0;
408 char ** argv_saved = NULL;
409
410 void get_argc_argv(int *argc, char ***argv) {
411   if (argc) {
412     *argc = argc_saved;
413   }
414   if (argv) {
415     *argv = argv_saved;
416   }
417 }
418
419 int main(int argc, char *argv[]) {
420   int argcLocal = argc;
421
422   /* save argc and argv */
423   {
424     size_t i;
425
426     argc_saved = argc;
427     argv_saved = malloc(sizeof(char*) * (argc + 1));
428     for (i = 0; i <= (size_t) argc; i++) {
429       argv_saved[i] = argv[i];
430     }
431   }
432
433   /* Open syslog */
434   olsr_openlog("olsrd");
435
436   olsrd_config_checksum_init();
437   olsrd_config_checksum_add_cli(argc, argv);
438   olsrd_config_checksum_add(OLSRD_CONFIG_START, OLSRD_CONFIG_START_LEN);
439
440   /*
441    * Initialisation
442    */
443
444   /* setup debug printf destination */
445   debug_handle = stdout;
446
447   /* set stdout and stderr to unbuffered output */
448   setbuf(stdout, NULL);
449   setbuf(stderr, NULL);
450
451   /* setup random seed */
452   srandom(time(NULL));
453
454   /* Init widely used statics */
455   memset(&all_zero, 0, sizeof(union olsr_ip_addr));
456
457   /* store the arguments for restart */
458   olsr_argv = argv;
459
460   /*
461    * Start
462    */
463
464   print_version();
465
466   if (argcLocal == 2) {
467     if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "/?")) {
468       /* help */
469       print_usage(false);
470       olsr_exit(NULL, EXIT_SUCCESS);
471     }
472     if (!strcmp(argv[1], "-v")) {
473       /* version */
474       olsr_exit(NULL, EXIT_SUCCESS);
475     }
476   }
477
478   /* Check root Privileges */
479 #ifndef _WIN32
480   if (geteuid()) {
481     olsr_exit("You must be root (uid = 0) to run olsrd", EXIT_FAILURE);
482   }
483 #else /* _WIN32 */
484   DisableIcmpRedirects();
485
486   {
487     WSADATA WsaData;
488     if (WSAStartup(0x0202, &WsaData)) {
489       char buf2[1024];
490       snprintf(buf2, sizeof(buf2), "%s: Could not initialise WinSock", __func__);
491       olsr_exit(buf2, EXIT_FAILURE);
492     }
493   }
494 #endif /* _WIN32 */
495
496   /* load the configuration */
497   if (!loadConfig(&argcLocal, argv)) {
498     olsr_exit(NULL, EXIT_FAILURE);
499   }
500
501   /* Process CLI Arguments */
502   {
503     char * error = NULL;
504     int exitCode = EXIT_FAILURE;
505
506     /* get the default interface config */
507     struct if_config_options *default_ifcnf = get_default_if_config();
508     if (!default_ifcnf) {
509       olsr_exit("No default ifconfig found", EXIT_FAILURE);
510     }
511
512     /* Process olsrd options */
513     exitCode = olsr_process_arguments(argcLocal, argv, olsr_cnf, default_ifcnf, &error);
514     if (exitCode != 0) {
515       free(default_ifcnf);
516       olsr_exit(error, EXIT_FAILURE);
517     }
518
519     /* Set configuration for command-line specified interfaces */
520     set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
521
522     /* free the default ifcnf */
523     free(default_ifcnf);
524   }
525
526   olsrd_config_checksum_add(OLSRD_CONFIG_END, OLSRD_CONFIG_END_LEN);
527   olsrd_config_checksum_final();
528
529   /* Sanity check configuration */
530   if (olsrd_sanity_check_cnf(olsr_cnf) < 0) {
531     char buf2[1024];
532     snprintf(buf2, sizeof(buf2), "%s: Bad configuration", __func__);
533     olsr_exit(buf2, EXIT_FAILURE);
534   }
535
536   /* Setup derived configuration */
537   set_derived_cnf(olsr_cnf);
538
539   olsrd_cfgfile_init();
540
541   /* Print configuration */
542   if (olsr_cnf->debug_level > 1) {
543     olsrd_print_cnf(olsr_cnf);
544   }
545
546   /* configuration loaded and sane */
547
548   /* initialise timers */
549   olsr_init_timers();
550
551   def_timer_ci = olsr_alloc_cookie("Default Timer Cookie", OLSR_COOKIE_TYPE_TIMER);
552
553   /* create a socket for ioctl calls */
554   olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
555   if (olsr_cnf->ioctl_s < 0) {
556     char buf2[1024];
557     snprintf(buf2, sizeof(buf2), "ioctl socket: %s", strerror(errno));
558     olsr_exit(buf2, EXIT_FAILURE);
559   }
560
561   /* create a socket for netlink calls */
562 #ifdef __linux__
563   olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
564   if (olsr_cnf->rtnl_s < 0) {
565     char buf2[1024];
566     snprintf(buf2, sizeof(buf2), "rtnetlink socket: %s", strerror(errno));
567     olsr_exit(buf2, EXIT_FAILURE);
568   }
569
570   if (fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK)) {
571     olsr_syslog(OLSR_LOG_INFO, "rtnetlink could not be set to nonblocking");
572   }
573
574   if ((olsr_cnf->rt_monitor_socket = rtnetlink_register_socket(RTMGRP_LINK)) < 0) {
575     char buf2[1024];
576     snprintf(buf2, sizeof(buf2), "rtmonitor socket: %s", strerror(errno));
577     olsr_exit(buf2, EXIT_FAILURE);
578   }
579 #endif /* __linux__ */
580
581   /* create routing socket */
582 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
583   olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0);
584   if (olsr_cnf->rts < 0) {
585     char buf2[1024];
586     snprintf(buf2, sizeof(buf2), "routing socket: %s", strerror(errno));
587     olsr_exit(buf2, EXIT_FAILURE);
588   }
589 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
590
591   /* initialise gateway system */
592 #ifdef __linux__
593   if (olsr_cnf->smart_gw_active && olsr_init_gateways()) {
594     olsr_exit("Cannot initialise gateway tunnels", EXIT_FAILURE);
595   }
596 #endif /* __linux__ */
597
598   /* initialise niit if index */
599 #ifdef __linux__
600   if (olsr_cnf->use_niit) {
601     olsr_init_niit();
602   }
603 #endif /* __linux__ */
604
605   /* initialise empty TC timer */
606   set_empty_tc_timer(GET_TIMESTAMP(0));
607
608   /* enable ip forwarding on host and disable redirects globally (not for WIN32) */
609   net_os_set_global_ifoptions();
610
611   /* initialise parser */
612   olsr_init_parser();
613
614   /* initialise route exporter */
615   olsr_init_export_route();
616
617   /* initialise message sequence number */
618   init_msg_seqno();
619
620   /* initialise dynamic willingness calculation */
621   olsr_init_willingness();
622
623   /* Set up willingness/APM */
624   if (olsr_cnf->willingness_auto) {
625     if (apm_init() < 0) {
626       OLSR_PRINTF(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
627
628       olsr_syslog(OLSR_LOG_ERR, "Could not read APM info - setting default willingness(%d)\n",
629       WILL_DEFAULT);
630
631       olsr_cnf->willingness_auto = 0;
632       olsr_cnf->willingness = WILL_DEFAULT;
633     } else {
634       olsr_cnf->willingness = olsr_calculate_willingness();
635
636       OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, (double )olsr_cnf->will_int);
637     }
638   }
639
640   /* initialise net */
641   init_net();
642
643   /* initialise network interfaces */
644   if (!olsr_init_interfacedb()) {
645     if (olsr_cnf->allow_no_interfaces) {
646       fprintf( stderr, "No interfaces detected! This might be intentional, but it also might mean"
647           " that your configuration is fubar.\nI will continue after 5 seconds...\n");
648       olsr_startup_sleep(5);
649     } else {
650       char buf2[1024];
651       snprintf(buf2, sizeof(buf2), "%s: No interfaces detected", __func__);
652       olsr_exit(buf2, EXIT_FAILURE);
653     }
654   }
655
656   /* initialise the IPC socket */
657   if ((olsr_cnf->ipc_connections > 0) && ipc_init()) {
658     olsr_exit("ipc_init failure", EXIT_FAILURE);
659   }
660
661   /* Initialisation of different tables to be used. */
662   olsr_init_tables();
663
664 #ifdef __linux__
665   /* startup gateway system */
666   if (olsr_cnf->smart_gw_active && olsr_startup_gateways()) {
667     olsr_exit("Cannot startup gateway tunnels", EXIT_FAILURE);
668   }
669 #endif /* __linux__ */
670
671   olsr_do_startup_sleep();
672
673   /* start heartbeat that is showing on stdout */
674 #if !defined WINCE
675   if ((olsr_cnf->debug_level > 0) && isatty(STDOUT_FILENO)) {
676     heartBeatTimer = olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC, &generate_stdout_pulse, NULL, 0);
677   }
678 #endif /* !defined WINCE */
679
680   /* daemon mode */
681 #ifndef _WIN32
682   if ((olsr_cnf->debug_level == 0) && !olsr_cnf->no_fork) {
683     printf("%s detaching from the current process...\n", olsrd_version);
684     if (daemon(0, 0) < 0) {
685       char buf2[1024];
686       snprintf(buf2, sizeof(buf2), "daemon(3) failed: %s", strerror(errno));
687       olsr_exit(buf2, EXIT_FAILURE);
688     }
689   }
690 #endif /* _WIN32 */
691
692   if (!writePidFile()) {
693     olsr_exit(NULL, EXIT_FAILURE);
694   }
695
696   /* Create locking file for olsrd, will be cleared after olsrd exits */
697   if (!olsr_create_lock_file()) {
698     char buf2[1024];
699     snprintf(buf2, sizeof(buf2), "Error, cannot create OLSR lock file '%s'", olsr_cnf->lock_file);
700     olsr_exit(buf2, EXIT_FAILURE);
701   }
702
703   /* Load plugins */
704   olsr_load_plugins();
705
706   /* print the main address */
707   {
708     struct ipaddr_str buf;
709     OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
710   }
711
712   /* create policy routing rules with priorities if necessary */
713 #ifdef __linux__
714   if (DEF_RT_NONE != olsr_cnf->rt_table_pri) {
715     olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, true);
716   }
717
718   if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) {
719     olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, true);
720   }
721
722   if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) {
723     olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, true);
724   }
725
726   /* rule to default table on all olsrd interfaces */
727   if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) {
728     struct interface_olsr *ifn;
729     for (ifn = ifnet; ifn; ifn = ifn->int_next) {
730       olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, true);
731     }
732   }
733
734   /* trigger gateway selection */
735   if (olsr_cnf->smart_gw_active) {
736     olsr_trigger_inetgw_startup();
737   }
738
739   /* trigger niit static route setup */
740   if (olsr_cnf->use_niit) {
741     olsr_setup_niit_routes();
742   }
743
744   /* create lo:olsr interface */
745   if (olsr_cnf->use_src_ip_routes) {
746     olsr_os_localhost_if(&olsr_cnf->main_addr, true);
747   }
748 #endif /* __linux__ */
749
750   /* Start syslog entry */
751   olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version);
752
753   /* setup signal-handlers */
754 #ifdef _WIN32
755 #ifndef WINCE
756   SetConsoleCtrlHandler(SignalHandler, true);
757 #endif /* WINCE */
758 #else /* _WIN32 */
759   signal(SIGHUP, olsr_reconfigure);
760   signal(SIGINT, olsr_shutdown);
761   signal(SIGQUIT, olsr_shutdown);
762   signal(SIGILL, olsr_shutdown);
763   signal(SIGABRT, olsr_shutdown);
764 #if defined(__linux__) && !defined(__ANDROID__)
765   signal(SIGSEGV, olsr_segv_handler);
766 #endif  /* defined(__linux__) && !defined(__ANDROID__) */
767   signal(SIGTERM, olsr_shutdown);
768   signal(SIGPIPE, SIG_IGN);
769   // Ignoring SIGUSR1 and SIGUSR1 by default to be able to use them in plugins
770   signal(SIGUSR1, SIG_IGN);
771   signal(SIGUSR2, SIG_IGN);
772 #endif /* _WIN32 */
773
774   /* Starting scheduler */
775   olsr_scheduler();
776
777   /* We'll only get here when olsr_shutdown has stopped the scheduler */
778   sleep(30);
779
780   exit(EXIT_FAILURE);
781 } /* main */
782
783 /*
784  * Local Variables:
785  * c-basic-offset: 2
786  * indent-tabs-mode: nil
787  * End:
788  */