2 * The olsr.org Optimized Link-State Routing daemon(olsrd)
3 * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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.
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.
33 * Visit http://www.olsr.org for more information.
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.
41 #include <arpa/inet.h>
48 #include "cfgparser/olsrd_conf.h"
51 #include "builddata.h"
54 #include "scheduler.h"
56 #include "generate_msg.h"
57 #include "plugin_loader.h"
60 #include "build_msg.h"
63 #include "mpr_selector_set.h"
65 #include "olsr_niit.h"
66 #include "olsr_random.h"
68 #include "lock_file.h"
72 #include <linux/types.h>
73 #include <linux/rtnetlink.h>
74 #include "kernel_routes.h"
76 #endif /* __linux__ */
81 #define olsr_shutdown(x) SignalHandler(x)
82 #define close(x) closesocket(x)
83 int __stdcall SignalHandler(unsigned long signo) __attribute__ ((noreturn));
84 void DisableIcmpRedirects(void);
87 struct timer_entry * heartBeatTimer = NULL;
89 static char **olsr_argv = NULL;
91 struct olsr_cookie_info *def_timer_ci = NULL;
95 * Reconfigure olsrd. Currently kind of a hack...
97 *@param signo the signal that triggered this callback
99 static void olsr_reconfigure(int signo __attribute__ ((unused))) {
103 /* if we are started with -nofork, we do not want to go into the
104 * background here. So we can simply stop on -HUP
106 olsr_syslog(OLSR_LOG_INFO, "sot: olsr_reconfigure()\n");
107 if (!olsr_cnf->no_fork) {
112 /* New process, wait a bit to let the old process exit */
115 sigaddset(&sigs, SIGHUP);
116 sigprocmask(SIG_UNBLOCK, &sigs, NULL);
117 for (i = sysconf(_SC_OPEN_MAX); --i > STDERR_FILENO;) {
120 printf("Restarting %s", olsr_argv[0]);
121 olsr_syslog(OLSR_LOG_INFO, "Restarting %s", olsr_argv[0]);
122 execv(olsr_argv[0], olsr_argv);
123 olsr_syslog(OLSR_LOG_ERR, "execv(%s) failed: %s", olsr_argv[0], strerror(errno));
125 olsr_syslog(OLSR_LOG_INFO, "RECONFIGURING");
131 olsr_exit(NULL, EXIT_SUCCESS);
135 static void olsr_shutdown_messages(void) {
136 struct interface_olsr *ifn;
139 for (ifn = ifnet; ifn; ifn = ifn->int_next) {
140 /* clean output buffer */
143 /* send 'I'm gone' messages */
144 if (olsr_cnf->lq_level > 0) {
145 olsr_output_lq_tc(ifn);
146 olsr_output_lq_hello(ifn);
156 *Function called at shutdown. Signal handler
158 * @param signo the signal that triggered this call
162 SignalHandler(unsigned long signo)
164 static void olsr_shutdown(int signo __attribute__ ((unused)))
170 struct interface_olsr *ifn;
173 OLSR_PRINTF(1, "Received signal %d - shutting down\n", (int)signo);
175 /* instruct the scheduler to stop */
176 olsr_scheduler_stop();
178 /* clear all links and send empty hellos/tcs */
179 olsr_reset_all_links();
181 /* deactivate fisheye and immediate TCs */
182 olsr_cnf->lq_fish = 0;
183 for (ifn = ifnet; ifn; ifn = ifn->int_next) {
184 ifn->immediate_send_tc = false;
186 increase_local_ansn();
188 /* send first shutdown message burst */
189 olsr_shutdown_messages();
191 /* delete all routes */
192 olsr_delete_all_kernel_routes();
194 /* send second shutdown message burst */
195 olsr_shutdown_messages();
197 /* now try to cleanup the rest of the mess */
198 olsr_delete_all_tc_entries();
200 olsr_delete_all_mid_entries();
203 /* trigger gateway selection */
204 if (olsr_cnf->smart_gw_active) {
205 olsr_shutdown_gateways();
206 olsr_cleanup_gateways();
209 /* trigger niit static route cleanup */
210 if (olsr_cnf->use_niit) {
211 olsr_cleanup_niit_routes();
214 /* cleanup lo:olsr interface */
215 if (olsr_cnf->use_src_ip_routes) {
216 olsr_os_localhost_if(&olsr_cnf->main_addr, false);
218 #endif /* __linux__ */
220 olsr_destroy_parser();
222 OLSR_PRINTF(1, "Closing sockets...\n");
224 /* front-end IPC socket */
225 if (olsr_cnf->ipc_connections > 0) {
230 for (ifn = ifnet; ifn; ifn = ifn->int_next) {
231 close(ifn->olsr_socket);
232 close(ifn->send_socket);
235 if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) {
236 olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default,
237 olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, false);
239 #endif /* __linux__ */
242 /* Closing plug-ins */
243 olsr_close_plugins();
245 /* Reset network settings */
246 net_os_restore_ifoptions();
249 close(olsr_cnf->ioctl_s);
252 if (DEF_RT_NONE != olsr_cnf->rt_table_pri) {
253 olsr_os_policy_rule(olsr_cnf->ip_version,
254 olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, false);
256 if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) {
257 olsr_os_policy_rule(olsr_cnf->ip_version,
258 olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, false);
260 if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) {
261 olsr_os_policy_rule(olsr_cnf->ip_version,
262 olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, false);
264 close(olsr_cnf->rtnl_s);
265 close (olsr_cnf->rt_monitor_socket);
266 #endif /* __linux__ */
268 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
270 close(olsr_cnf->rts);
271 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
273 /* remove the lock file */
274 olsr_remove_lock_file();
276 /* stop heartbeat that is showing on stdout */
278 if (heartBeatTimer) {
279 olsr_stop_timer(heartBeatTimer);
280 heartBeatTimer = NULL;
282 #endif /* !defined WINCE */
284 /* Free cookies and memory pools attached. */
285 OLSR_PRINTF(0, "Free all memory...\n");
286 olsr_delete_all_cookies();
288 olsr_syslog(OLSR_LOG_INFO, "%s stopped", olsrd_version);
290 OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n http://www.olsr.org\n", olsrd_version);
292 exit_value = olsr_cnf->exit_value;
293 olsrd_free_cnf(&olsr_cnf);
305 * Sets the provided configuration on all unconfigured
308 * @param ifs a linked list of interfaces to check and possible update
309 * @param cnf the default configuration to set on unconfigured interfaces
311 static int set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf) {
315 if (ifs->cnf == NULL) {
316 ifs->cnf = olsr_malloc(sizeof(struct if_config_options),
317 "Set default config");
330 int main(int argc, char *argv[]) {
331 int argcLocal = argc;
334 olsr_openlog("olsrd");
340 /* setup debug printf destination */
341 debug_handle = stdout;
343 /* set stdout and stderr to unbuffered output */
344 setbuf(stdout, NULL);
345 setbuf(stderr, NULL);
347 /* setup random seed */
350 /* Init widely used statics */
351 memset(&all_zero, 0, sizeof(union olsr_ip_addr));
353 /* store the arguments for restart */
362 if (argcLocal == 2) {
363 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "/?")) {
366 olsr_exit(NULL, EXIT_SUCCESS);
368 if (!strcmp(argv[1], "-v")) {
370 olsr_exit(NULL, EXIT_SUCCESS);
374 /* Check root Privileges */
377 olsr_exit("You must be root (uid = 0) to run olsrd", EXIT_FAILURE);
380 DisableIcmpRedirects();
384 if (WSAStartup(0x0202, &WsaData)) {
386 snprintf(buf2, sizeof(buf2), "%s: Could not initialise WinSock", __func__);
387 olsr_exit(buf2, EXIT_FAILURE);
392 /* load the configuration */
393 if (!loadConfig(&argcLocal, argv)) {
394 olsr_exit(NULL, EXIT_FAILURE);
397 /* Process CLI Arguments */
400 int exitCode = EXIT_FAILURE;
402 /* get the default interface config */
403 struct if_config_options *default_ifcnf = get_default_if_config();
404 if (!default_ifcnf) {
405 olsr_exit("No default ifconfig found", EXIT_FAILURE);
408 /* Process olsrd options */
409 exitCode = olsr_process_arguments(argcLocal, argv, olsr_cnf, default_ifcnf, &error);
412 olsr_exit(error, EXIT_FAILURE);
415 /* Set configuration for command-line specified interfaces */
416 set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
418 /* free the default ifcnf */
422 /* Sanity check configuration */
423 if (olsrd_sanity_check_cnf(olsr_cnf) < 0) {
425 snprintf(buf2, sizeof(buf2), "%s: Bad configuration", __func__);
426 olsr_exit(buf2, EXIT_FAILURE);
429 /* Setup derived configuration */
430 set_derived_cnf(olsr_cnf);
432 /* Print configuration */
433 if (olsr_cnf->debug_level > 1) {
434 olsrd_print_cnf(olsr_cnf);
437 /* configuration loaded and sane */
439 /* initialise timers */
442 def_timer_ci = olsr_alloc_cookie("Default Timer Cookie", OLSR_COOKIE_TYPE_TIMER);
444 /* create a socket for ioctl calls */
445 olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
446 if (olsr_cnf->ioctl_s < 0) {
448 snprintf(buf2, sizeof(buf2), "ioctl socket: %s", strerror(errno));
449 olsr_exit(buf2, EXIT_FAILURE);
452 /* create a socket for netlink calls */
454 olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
455 if (olsr_cnf->rtnl_s < 0) {
457 snprintf(buf2, sizeof(buf2), "rtnetlink socket: %s", strerror(errno));
458 olsr_exit(buf2, EXIT_FAILURE);
461 if (fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK)) {
462 olsr_syslog(OLSR_LOG_INFO, "rtnetlink could not be set to nonblocking");
465 if ((olsr_cnf->rt_monitor_socket = rtnetlink_register_socket(RTMGRP_LINK)) < 0) {
467 snprintf(buf2, sizeof(buf2), "rtmonitor socket: %s", strerror(errno));
468 olsr_exit(buf2, EXIT_FAILURE);
470 #endif /* __linux__ */
472 /* create routing socket */
473 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
474 olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0);
475 if (olsr_cnf->rts < 0) {
477 snprintf(buf2, sizeof(buf2), "routing socket: %s", strerror(errno));
478 olsr_exit(buf2, EXIT_FAILURE);
480 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
482 /* initialise gateway system */
484 if (olsr_cnf->smart_gw_active && olsr_init_gateways()) {
485 olsr_exit("Cannot initialise gateway tunnels", EXIT_FAILURE);
487 #endif /* __linux__ */
489 /* initialise niit if index */
491 if (olsr_cnf->use_niit) {
494 #endif /* __linux__ */
496 /* initialise empty TC timer */
497 set_empty_tc_timer(GET_TIMESTAMP(0));
499 /* enable ip forwarding on host and disable redirects globally (not for WIN32) */
500 net_os_set_global_ifoptions();
502 /* initialise parser */
505 /* initialise route exporter */
506 olsr_init_export_route();
508 /* initialise message sequence number */
511 /* initialise dynamic willingness calculation */
512 olsr_init_willingness();
514 /* Set up willingness/APM */
515 if (olsr_cnf->willingness_auto) {
516 if (apm_init() < 0) {
517 OLSR_PRINTF(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
519 olsr_syslog(OLSR_LOG_ERR, "Could not read APM info - setting default willingness(%d)\n",
522 olsr_cnf->willingness_auto = 0;
523 olsr_cnf->willingness = WILL_DEFAULT;
525 olsr_cnf->willingness = olsr_calculate_willingness();
527 OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, (double )olsr_cnf->will_int);
534 /* initialise network interfaces */
535 if (!olsr_init_interfacedb()) {
536 if (olsr_cnf->allow_no_interfaces) {
537 fprintf( stderr, "No interfaces detected! This might be intentional, but it also might mean"
538 " that your configuration is fubar.\nI will continue after 5 seconds...\n");
539 olsr_startup_sleep(5);
542 snprintf(buf2, sizeof(buf2), "%s: No interfaces detected", __func__);
543 olsr_exit(buf2, EXIT_FAILURE);
548 /* startup gateway system */
549 if (olsr_cnf->smart_gw_active && olsr_startup_gateways()) {
550 olsr_exit("Cannot startup gateway tunnels", EXIT_FAILURE);
552 #endif /* __linux__ */
554 /* initialise the IPC socket */
555 if ((olsr_cnf->ipc_connections > 0) && ipc_init()) {
556 olsr_exit("ipc_init failure", EXIT_FAILURE);
559 /* Initialisation of different tables to be used. */
562 olsr_do_startup_sleep();
564 /* start heartbeat that is showing on stdout */
566 if ((olsr_cnf->debug_level > 0) && isatty(STDOUT_FILENO)) {
567 heartBeatTimer = olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC, &generate_stdout_pulse, NULL, 0);
569 #endif /* !defined WINCE */
573 if ((olsr_cnf->debug_level == 0) && !olsr_cnf->no_fork) {
574 printf("%s detaching from the current process...\n", olsrd_version);
575 if (daemon(0, 0) < 0) {
577 snprintf(buf2, sizeof(buf2), "daemon(3) failed: %s", strerror(errno));
578 olsr_exit(buf2, EXIT_FAILURE);
583 if (!writePidFile()) {
584 olsr_exit(NULL, EXIT_FAILURE);
587 /* Create locking file for olsrd, will be cleared after olsrd exits */
588 if (!olsr_create_lock_file()) {
590 snprintf(buf2, sizeof(buf2), "Error, cannot create OLSR lock file '%s'", olsr_cnf->lock_file);
591 olsr_exit(buf2, EXIT_FAILURE);
597 /* print the main address */
599 struct ipaddr_str buf;
600 OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
603 /* create policy routing rules with priorities if necessary */
605 if (DEF_RT_NONE != olsr_cnf->rt_table_pri) {
606 olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, true);
609 if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) {
610 olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, true);
613 if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) {
614 olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, true);
617 /* rule to default table on all olsrd interfaces */
618 if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) {
619 struct interface_olsr *ifn;
620 for (ifn = ifnet; ifn; ifn = ifn->int_next) {
621 olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, true);
625 /* trigger gateway selection */
626 if (olsr_cnf->smart_gw_active) {
627 olsr_trigger_inetgw_startup();
630 /* trigger niit static route setup */
631 if (olsr_cnf->use_niit) {
632 olsr_setup_niit_routes();
635 /* create lo:olsr interface */
636 if (olsr_cnf->use_src_ip_routes) {
637 olsr_os_localhost_if(&olsr_cnf->main_addr, true);
639 #endif /* __linux__ */
641 /* Start syslog entry */
642 olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version);
644 /* setup signal-handlers */
647 SetConsoleCtrlHandler(SignalHandler, true);
650 signal(SIGHUP, olsr_reconfigure);
651 signal(SIGINT, olsr_shutdown);
652 signal(SIGQUIT, olsr_shutdown);
653 signal(SIGILL, olsr_shutdown);
654 signal(SIGABRT, olsr_shutdown);
655 // signal(SIGSEGV, olsr_shutdown);
656 signal(SIGTERM, olsr_shutdown);
657 signal(SIGPIPE, SIG_IGN);
658 // Ignoring SIGUSR1 and SIGUSR1 by default to be able to use them in plugins
659 signal(SIGUSR1, SIG_IGN);
660 signal(SIGUSR2, SIG_IGN);
663 /* Starting scheduler */
666 /* We'll only get here when olsr_shutdown has stopped the scheduler */
675 * indent-tabs-mode: nil