00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <sys/stat.h>
00043 #include <assert.h>
00044 #include <errno.h>
00045 #include <stdio.h>
00046 #include <signal.h>
00047 #include <unistd.h>
00048
00049 #include "defs.h"
00050 #include "common/avl.h"
00051 #include "builddata/data.h"
00052 #include "avl_olsr_comp.h"
00053 #include "olsr.h"
00054 #include "ipcalc.h"
00055 #include "olsr_timer.h"
00056 #include "olsr_socket.h"
00057 #include "parser.h"
00058 #include "plugin_loader.h"
00059 #include "os_apm.h"
00060 #include "net_olsr.h"
00061 #include "olsr_cfg_gen.h"
00062 #include "common/string.h"
00063 #include "mid_set.h"
00064 #include "duplicate_set.h"
00065 #include "olsr_comport.h"
00066 #include "neighbor_table.h"
00067 #include "olsr_logging.h"
00068 #include "olsr_callbacks.h"
00069 #include "os_apm.h"
00070 #include "os_net.h"
00071 #include "os_kernel_routes.h"
00072 #include "os_time.h"
00073 #include "os_system.h"
00074
00075 #if defined linux
00076 #include <linux/types.h>
00077 #include <linux/rtnetlink.h>
00078 #include <fcntl.h>
00079 #endif
00080
00081 #define STDOUT_PULSE_INT 600
00082
00083 #ifdef WIN32
00084 int __stdcall SignalHandler(unsigned long signo);
00085 #else
00086 static void signal_shutdown(int);
00087 #endif
00088 static void olsr_shutdown(void);
00089
00090
00091
00092
00093 #ifndef WIN32
00094 static void signal_reconfigure(int);
00095 #endif
00096
00097
00098 struct olsr_config *olsr_cnf;
00099
00100 enum app_state app_state = STATE_INIT;
00101
00102 static char copyright_string[] __attribute__ ((unused)) =
00103 "The olsr.org Optimized Link-State Routing daemon(olsrd) Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org) All rights reserved.";
00104
00105 static char pulsedata[] = "\\|/-";
00106 static uint8_t pulse_state = 0;
00107
00108 static struct olsr_timer_entry *hna_gen_timer;
00109 static struct olsr_timer_entry *mid_gen_timer;
00110 static struct olsr_timer_entry *tc_gen_timer;
00111
00112 static void
00113 generate_stdout_pulse(void *foo __attribute__ ((unused)))
00114 {
00115 if (pulsedata[++pulse_state] == '\0') {
00116 pulse_state = 0;
00117 }
00118 fprintf(stderr, "%c\r", pulsedata[pulse_state]);
00119 }
00120
00125 int
00126 main(int argc, char *argv[])
00127 {
00128
00129 static struct olsr_timer_info *pulse_timer_info = NULL;
00130 static struct olsr_timer_info *tc_gen_timer_info = NULL;
00131 static struct olsr_timer_info *mid_gen_timer_info = NULL;
00132 static struct olsr_timer_info *hna_gen_timer_info = NULL;
00133
00134 char conf_file_name[FILENAME_MAX];
00135 int exitcode = 0;
00136 #if !defined(REMOVE_LOG_INFO) || !defined(REMOVE_LOG_ERROR)
00137 struct ipaddr_str buf;
00138 #endif
00139 #ifdef WIN32
00140 WSADATA WsaData;
00141 size_t len;
00142 #endif
00143
00144
00145 assert(sizeof(uint8_t) == 1);
00146 assert(sizeof(uint16_t) == 2);
00147 assert(sizeof(uint32_t) == 4);
00148 assert(sizeof(int8_t) == 1);
00149 assert(sizeof(int16_t) == 2);
00150 assert(sizeof(int32_t) == 4);
00151
00152 setbuf(stdout, NULL);
00153 setbuf(stderr, NULL);
00154
00155
00156 srandom(getpid());
00157
00158
00159 os_arg(&argc, argv);
00160
00161
00162
00163
00164 #ifdef WIN32
00165 #ifndef WINCE
00166 GetWindowsDirectory(conf_file_name, sizeof(conf_file_name) - 1 - strlen(OLSRD_GLOBAL_CONF_FILE));
00167 #else
00168 conf_file_name[0] = 0;
00169 #endif
00170
00171 len = strlen(conf_file_name);
00172
00173 if (len == 0 || conf_file_name[len - 1] != '\\') {
00174 conf_file_name[len++] = '\\';
00175 }
00176
00177 strscpy(conf_file_name + len, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name) - len);
00178 #else
00179 strscpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name));
00180 #endif
00181
00182
00183 olsr_log_init();
00184
00185
00186
00187
00188 olsr_parse_cfg(argc, argv, conf_file_name, &olsr_cnf);
00189
00190
00191 if (olsr_cnf->ipsize == 4) {
00192 avl_comp_default = avl_comp_ipv4;
00193 avl_comp_addr_origin_default = avl_comp_ipv4_addr_origin;
00194 avl_comp_prefix_default = avl_comp_ipv4_prefix;
00195 avl_comp_prefix_origin_default = avl_comp_ipv4_prefix_origin;
00196 } else {
00197 avl_comp_default = avl_comp_ipv6;
00198 avl_comp_addr_origin_default = avl_comp_ipv6_addr_origin;
00199 avl_comp_prefix_default = avl_comp_ipv6_prefix;
00200 avl_comp_prefix_origin_default = avl_comp_ipv6_prefix_origin;
00201 }
00202
00203
00204 olsr_log_applyconfig();
00205
00206 OLSR_INFO(LOG_MAIN, "\n *** %s ***\n Build date: %s\n http://www.olsr.org\n\n",
00207 get_olsrd_version(), get_olsrd_builddate());
00208
00209
00210 if (olsr_sanity_check_cfg(olsr_cnf) < 0) {
00211 olsr_exit(EXIT_FAILURE);
00212 }
00213
00214
00215 os_init();
00216
00217 #ifndef WIN32
00218
00219 if (geteuid()) {
00220 OLSR_ERROR(LOG_MAIN, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
00221 olsr_exit(EXIT_FAILURE);
00222 }
00223 #else
00224 if (WSAStartup(0x0202, &WsaData)) {
00225 OLSR_ERROR(LOG_MAIN, "Could not initialize WinSock.\n");
00226 olsr_exit(EXIT_FAILURE);
00227 }
00228 #endif
00229
00230
00231 olsr_clock_init();
00232
00233
00234 olsr_memcookie_init();
00235
00236
00237 olsr_timer_init();
00238 olsr_socket_init();
00239
00240
00241 olsr_callback_init();
00242
00243
00244 pulse_timer_info = olsr_timer_add("Stdout pulse", &generate_stdout_pulse, true);
00245 tc_gen_timer_info = olsr_timer_add("TC generation", &olsr_output_lq_tc, true);
00246 mid_gen_timer_info = olsr_timer_add("MID generation", &generate_mid, true);
00247 hna_gen_timer_info = olsr_timer_add("HNA generation", &generate_hna, true);
00248
00249
00250 olsr_init_pluginsystem();
00251 olsr_plugins_init(true);
00252
00253
00254 olsr_init_link_set();
00255
00256
00257 olsr_init_duplicate_set();
00258
00259
00260 olsr_init_neighbor_table();
00261
00262
00263 olsr_init_routing_table();
00264
00265
00266 olsr_init_tc();
00267
00268
00269 olsr_init_mid_set();
00270
00271
00272 olsr_init_hna_set();
00273
00274
00275 olsr_plugins_enable(PLUGIN_TYPE_LQ, true);
00276
00277
00278 olsr_com_init();
00279
00280
00281 init_net();
00282
00283
00284 olsr_init_spf();
00285
00286
00287
00288
00289 olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
00290 if (olsr_cnf->ioctl_s < 0) {
00291 OLSR_ERROR(LOG_MAIN, "ioctl socket: %s\n", strerror(errno));
00292 olsr_exit(EXIT_FAILURE);
00293 }
00294 #if defined linux
00295 olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
00296 if (olsr_cnf->rtnl_s < 0) {
00297 OLSR_ERROR(LOG_MAIN, "rtnetlink socket: %s\n", strerror(errno));
00298 olsr_exit(EXIT_FAILURE);
00299 }
00300 os_socket_set_nonblocking(olsr_cnf->rtnl_s);
00301
00302
00303 if ( ( olsr_cnf->rt_table < 253) & ( olsr_cnf->rt_table > 0 ) ) {
00304 OLSR_WARN(LOG_NETWORKING,"make sure to have correct policy routing rules (destination based rules are required, or a dummy rule with prio like 65535)");
00305
00306 }
00307 #endif
00308
00309
00310
00311
00312 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
00313 olsr_cnf->rts_bsd = socket(PF_ROUTE, SOCK_RAW, 0);
00314 if (olsr_cnf->rts_bsd < 0) {
00315 OLSR_ERROR(LOG_MAIN, "routing socket: %s\n", strerror(errno));
00316 olsr_exit(EXIT_FAILURE);
00317 }
00318 #endif
00319
00320
00321 olsr_init_parser();
00322
00323
00324 olsr_init_export_route();
00325
00326
00327 init_msg_seqno();
00328
00329
00330 olsr_init_willingness();
00331
00332
00333
00334
00335 if (olsr_cnf->willingness_auto) {
00336 olsr_calculate_willingness();
00337 }
00338
00339 #if defined linux
00340
00341 if (olsr_cnf->source_ip_mode) {
00342 OLSR_INFO(LOG_NETWORKING, "Initializing lo:olsr interface for source ip mode...\n");
00343 if (olsr_os_localhost_if(&olsr_cnf->router_id, true) <= 0) {
00344 OLSR_ERROR(LOG_NETWORKING, "Cannot create lo:olsr interface for ip '%s'\n", olsr_ip_to_string(&buf, &olsr_cnf->router_id));
00345 olsr_exit(EXIT_FAILURE);
00346 }
00347 }
00348 #endif
00349
00350
00351 if (!init_interfaces()) {
00352 if (olsr_cnf->allow_no_interfaces) {
00353 OLSR_INFO(LOG_MAIN,
00354 "No interfaces detected! This might be intentional, but it also might mean that your configuration is fubar.\nI will continue after 5 seconds...\n");
00355 os_sleep(5);
00356 } else {
00357 OLSR_ERROR(LOG_MAIN, "No interfaces detected!\nBailing out!\n");
00358 olsr_exit(EXIT_FAILURE);
00359 }
00360 }
00361
00362
00363
00364 #if !defined WINCE
00365 if (olsr_cnf->log_target_stderr > 0 && isatty(STDOUT_FILENO)) {
00366 olsr_timer_start(STDOUT_PULSE_INT, 0, NULL, pulse_timer_info);
00367 }
00368 #endif
00369
00370
00371 #ifndef WIN32
00372 if (!olsr_cnf->no_fork) {
00373 OLSR_INFO(LOG_MAIN, "%s detaching from the current process...\n",
00374 get_olsrd_version());
00375 if (daemon(0, 0) < 0) {
00376 OLSR_ERROR(LOG_MAIN, "daemon(3) failed: %s\n", strerror(errno));
00377 olsr_exit(EXIT_FAILURE);
00378 }
00379 }
00380 #endif
00381
00382
00383 init_lq_handler();
00384
00385 OLSR_INFO(LOG_MAIN, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->router_id));
00386
00387
00388 OLSR_INFO(LOG_MAIN, "%s successfully started", get_olsrd_version());
00389
00390
00391
00392
00393
00394
00395 #ifdef WIN32
00396 #ifndef WINCE
00397 SetConsoleCtrlHandler(SignalHandler, true);
00398 #endif
00399 #else
00400 {
00401 struct sigaction act;
00402 sigemptyset(&act.sa_mask);
00403 act.sa_flags = 0;
00404 act.sa_handler = signal_reconfigure;
00405 sigaction(SIGHUP, &act, NULL);
00406 act.sa_handler = signal_shutdown;
00407 sigaction(SIGINT, &act, NULL);
00408 sigaction(SIGQUIT, &act, NULL);
00409 sigaction(SIGILL, &act, NULL);
00410 sigaction(SIGABRT, &act, NULL);
00411
00412 sigaction(SIGTERM, &act, NULL);
00413 act.sa_handler = SIG_IGN;
00414 sigaction(SIGPIPE, &act, NULL);
00415
00416 sigaction(SIGUSR1, &act, NULL);
00417 sigaction(SIGUSR2, &act, NULL);
00418 }
00419 #endif
00420
00421 link_changes = false;
00422
00423 tc_gen_timer =
00424 olsr_timer_start(olsr_cnf->tc_params.emission_interval, TC_JITTER, NULL, tc_gen_timer_info);
00425 mid_gen_timer =
00426 olsr_timer_start(olsr_cnf->mid_params.emission_interval, MID_JITTER, NULL, mid_gen_timer_info);
00427 hna_gen_timer =
00428 olsr_timer_start(olsr_cnf->hna_params.emission_interval, HNA_JITTER, NULL, hna_gen_timer_info);
00429
00430
00431 olsr_plugins_enable(PLUGIN_TYPE_DEFAULT, true);
00432
00433
00434 app_state = STATE_RUNNING;
00435 while (app_state == STATE_RUNNING) {
00436 uint32_t next_interval;
00437
00438
00439
00440
00441
00442 olsr_clock_update();
00443 next_interval = olsr_clock_getAbsolute(olsr_cnf->pollrate);
00444
00445
00446 olsr_timer_walk();
00447
00448
00449 olsr_process_changes();
00450
00451
00452 olsr_socket_handle(next_interval);
00453 }
00454
00455 olsr_timer_stop(tc_gen_timer);
00456 tc_gen_timer = NULL;
00457
00458 olsr_timer_stop(mid_gen_timer);
00459 mid_gen_timer = NULL;
00460
00461 olsr_timer_stop(hna_gen_timer);
00462 hna_gen_timer = NULL;
00463
00464 exitcode = olsr_cnf->exit_value;
00465 switch (app_state) {
00466 case STATE_INIT:
00467 OLSR_ERROR(LOG_MAIN, "terminating and got \"init\"?");
00468 exitcode = EXIT_FAILURE;
00469 break;
00470 case STATE_RUNNING:
00471 OLSR_ERROR(LOG_MAIN, "terminating and got \"running\"?");
00472 exitcode = EXIT_FAILURE;
00473 break;
00474 #ifndef WIN32
00475 case STATE_RECONFIGURE:
00476
00477
00478
00479 switch (olsr_cnf->no_fork ? 0 : fork()) {
00480 int i;
00481 case 0:
00482
00483 for (i = sysconf(_SC_OPEN_MAX); --i > STDERR_FILENO;) {
00484 close(i);
00485 }
00486 os_sleep(1);
00487 OLSR_INFO(LOG_MAIN, "Restarting %s\n", argv[0]);
00488 execv(argv[0], argv);
00489
00490 OLSR_ERROR(LOG_MAIN, "execv() failed: %s", strerror(errno));
00491
00492 exitcode = EXIT_FAILURE;
00493 break;
00494 case -1:
00495
00496 OLSR_ERROR(LOG_MAIN, "fork() failed: %s", strerror(errno));
00497
00498 exitcode = EXIT_FAILURE;
00499 break;
00500 default:
00501
00502 OLSR_INFO(LOG_MAIN, "Reconfiguring OLSR\n");
00503 break;
00504 }
00505
00506 #endif
00507 case STATE_SHUTDOWN:
00508 olsr_shutdown();
00509 break;
00510 };
00511
00512 return exitcode;
00513 }
00514
00515 #ifndef WIN32
00516
00522 static void
00523 signal_reconfigure(int signo __attribute__ ((unused)))
00524 {
00525 const int save_errno = errno;
00526 OLSR_INFO(LOG_MAIN, "Received signal %d - requesting reconfiguration", signo);
00527 app_state = STATE_RECONFIGURE;
00528 errno = save_errno;
00529 }
00530
00531 #endif
00532
00538 #ifdef WIN32
00539 int __stdcall
00540 SignalHandler(unsigned long signo)
00541 #else
00542 static void
00543 signal_shutdown(int signo __attribute__ ((unused)))
00544 #endif
00545 {
00546 const int save_errno = errno;
00547 OLSR_INFO(LOG_MAIN, "Received signal %d - requesting shutdown", (int)signo);
00548 app_state = STATE_SHUTDOWN;
00549 errno = save_errno;
00550 #ifdef WIN32
00551 return 0;
00552 #endif
00553 }
00554
00555 static void
00556 olsr_shutdown(void)
00557 {
00558 struct mid_entry *mid, *iterator;
00559
00560 olsr_delete_all_kernel_routes();
00561
00562
00563 OLSR_FOR_ALL_MID_ENTRIES(mid, iterator) {
00564 olsr_delete_mid_entry(mid);
00565 }
00566
00567
00568 olsr_delete_all_tc_entries();
00569
00570 OLSR_INFO(LOG_MAIN, "Closing sockets...\n");
00571
00572
00573 olsr_com_destroy();
00574
00575
00576 olsr_flush_duplicate_entries();
00577
00578
00579 deinit_lq_handler();
00580
00581
00582 olsr_destroy_pluginsystem();
00583
00584
00585 destroy_interfaces();
00586
00587 #if defined linux
00588
00589 if (olsr_cnf->source_ip_mode) {
00590 olsr_os_localhost_if(&olsr_cnf->router_id, false);
00591 }
00592 #endif
00593
00594
00595 os_close(olsr_cnf->ioctl_s);
00596
00597 #if defined linux
00598
00599
00600
00601
00602 os_close(olsr_cnf->rtnl_s);
00603 #endif
00604
00605 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
00606
00607 os_close(olsr_cnf->rts_bsd);
00608 #endif
00609
00610
00611 olsr_socket_cleanup();
00612
00613
00614 olsr_timer_cleanup();
00615
00616
00617 olsr_deinit_parser();
00618
00619
00620 deinit_netfilters();
00621
00622
00623 olsr_callback_cleanup();
00624
00625
00626 olsr_memcookie_cleanup();
00627
00628
00629 os_cleanup();
00630
00631 OLSR_INFO(LOG_MAIN, "\n <<<< %s - terminating >>>>\n http://www.olsr.org\n",
00632 get_olsrd_version());
00633
00634
00635 olsr_log_cleanup();
00636
00637
00638 olsr_free_cfg(olsr_cnf);
00639 }
00640
00641
00642
00643
00644
00645
00646