You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

netsukuku.c 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /* This file is part of Netsukuku
  2. * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
  3. *
  4. * This source code is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * This source code is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * Please refer to the GNU Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Public License along with
  15. * this source code; if not, write to:
  16. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. *
  18. * --
  19. * netsukuku.c:
  20. * Where main() resides.
  21. */
  22. #include "includes.h"
  23. #include "common.h"
  24. #include "conf.h"
  25. #include "libnetlink.h"
  26. #include "ll_map.h"
  27. #include "request.h"
  28. #include "pkts.h"
  29. #include "if.h"
  30. #include "bmap.h"
  31. #include "netsukuku.h"
  32. #include "qspn.h"
  33. #include "accept.h"
  34. #include "daemon.h"
  35. #include "crypto.h"
  36. #include "andna_cache.h"
  37. #include "andna.h"
  38. #include "radar.h"
  39. #include "hook.h"
  40. #include "rehook.h"
  41. #include "ntk-console-server.h"
  42. #include <pthread.h>
  43. extern int errno;
  44. extern char *optarg;
  45. extern int optind, opterr, optopt;
  46. int destroy_netsukuku_mutex;
  47. int pid_saved;
  48. int options_parsed = 0; /* How many times parse_options() has been called */
  49. void
  50. save_pid(void)
  51. {
  52. FILE *fd;
  53. if (!(fd = fopen(server_opt.pid_file, "w")))
  54. error("Couldn't create pid file \"%s\": %s",
  55. server_opt.pid_file, strerror(errno));
  56. fprintf(fd, "ntkd %ld\n", (long) getpid());
  57. fclose(fd);
  58. pid_saved = 1;
  59. }
  60. /*
  61. * is_ntkd_already_running
  62. *
  63. * Returns 1 if there's already a ntkd running
  64. */
  65. int
  66. is_ntkd_already_running(void)
  67. {
  68. pid_t oldpid;
  69. FILE *fd;
  70. if (!(fd = fopen(server_opt.pid_file, "r"))) {
  71. if (errno != ENOENT)
  72. error("Cannot read pid file \"%s\": %s",
  73. server_opt.pid_file, strerror(errno));
  74. return 0;
  75. }
  76. fscanf(fd, "ntkd %d\n", &oldpid);
  77. if (ferror(fd)) {
  78. error("error reading pid file \"%s\": %s\n",
  79. server_opt.pid_file, strerror(errno));
  80. fclose(fd);
  81. return 0;
  82. }
  83. fclose(fd);
  84. return !kill(oldpid, 0);
  85. }
  86. int
  87. ntk_load_maps(void)
  88. {
  89. if (file_exist(server_opt.int_map_file) &&
  90. (me.int_map = load_map(server_opt.int_map_file, &me.cur_node)))
  91. debug(DBG_NORMAL, "Internal map loaded");
  92. else
  93. me.int_map = init_map(0);
  94. #if 0
  95. /* Don't load the bnode map, it's useless */
  96. if ((me.bnode_map = load_bmap(server_opt.bnode_map_file, me.ext_map,
  97. FAMILY_LVLS, &me.bmap_nodes))) {
  98. debug(DBG_NORMAL, "Bnode map loaded");
  99. } else
  100. #endif
  101. bmap_levels_init(BMAP_LEVELS(FAMILY_LVLS), &me.bnode_map,
  102. &me.bmap_nodes);
  103. bmap_counter_init(BMAP_LEVELS(FAMILY_LVLS), &me.bmap_nodes_closed,
  104. &me.bmap_nodes_opened);
  105. if (file_exist(server_opt.ext_map_file) &&
  106. (me.ext_map = load_extmap(server_opt.ext_map_file, &me.cur_quadg)))
  107. debug(DBG_NORMAL, "External map loaded from '%s'", server_opt.ext_map_file);
  108. else
  109. me.ext_map = init_extmap(FAMILY_LVLS, 0);
  110. return 0;
  111. }
  112. int
  113. ntk_save_maps(void)
  114. {
  115. debug(DBG_NORMAL, "Saving the internal map");
  116. save_map(me.int_map, me.cur_node, server_opt.int_map_file);
  117. #ifdef DEBUG
  118. debug(DBG_NORMAL, "Saving the border nodes map");
  119. save_bmap(me.bnode_map, me.bmap_nodes, me.ext_map, me.cur_quadg,
  120. server_opt.bnode_map_file);
  121. #endif
  122. debug(DBG_NORMAL, "Saving the external map");
  123. save_extmap(me.ext_map, MAXGROUPNODE, &me.cur_quadg,
  124. server_opt.ext_map_file);
  125. return 0;
  126. }
  127. int
  128. ntk_free_maps(void)
  129. {
  130. bmap_levels_free(me.bnode_map, me.bmap_nodes);
  131. bmap_counter_free(me.bmap_nodes_closed, me.bmap_nodes_opened);
  132. free_extmap(me.ext_map, FAMILY_LVLS, 0);
  133. free_map(me.int_map, 0);
  134. return 0;
  135. }
  136. void
  137. usage(void)
  138. {
  139. printf("Usage:\n"
  140. " ntkd [-hvaldrRD46] [-i net_interface] [-c conf_file] [-l logfile]\n\n"
  141. " -4 ipv4\n"
  142. " -6 ipv6\n"
  143. " -i Specify the interface after this\n\n"
  144. " -a Prevents running the ANDNA daemon\n"
  145. " -R Prevents editting /etc/resolv.conf\n"
  146. " -D Prevents running as daemon (Does not fork to the background)\n"
  147. "\n"
  148. " -r Runs in restricted mode\n"
  149. " -I Share your internet connection with other nodes\n"
  150. "\n"
  151. " -c Configuration file\n"
  152. " -l Enables logging to file\n"
  153. "\n"
  154. " -d Debug (Add more ds to get more info)\n"
  155. " -h Shows this help\n"
  156. " -v Shows the version you are using\n"
  157. " -k Kills the running instance of ntkd\n"
  158. " -C Runs the console server for Ntk-Console to connect to\n"
  159. " -e Excludes an interface from usage I.E all interfaces except this one\n"
  160. " -n Experimental argument to implement ntk netsplit inet/INET or ntk/NTK\n http://netsukuku.freaknet.org/docs/main_doc/ntk_rfc/Ntk_net_split\n");
  161. }
  162. /*
  163. * fill_default_options: fills the default values in the server_opt struct
  164. */
  165. void
  166. fill_default_options(void)
  167. {
  168. setzero(&server_opt, sizeof(server_opt));
  169. server_opt.family = AF_INET;
  170. set_option_literal(&(server_opt.config_file), NTK_CONFIG_FILE);
  171. set_option_literal(&(server_opt.pid_file), NTK_PID_FILE);
  172. set_option_literal(&(server_opt.int_map_file), INT_MAP_FILE);
  173. set_option_literal(&(server_opt.ext_map_file), EXT_MAP_FILE);
  174. set_option_literal(&(server_opt.bnode_map_file), BNODE_MAP_FILE);
  175. set_option_literal(&(server_opt.andna_hnames_file), ANDNA_HNAMES_FILE);
  176. set_option_literal(&(server_opt.snsd_nodes_file), SNSD_NODES_FILE);
  177. set_option_literal(&(server_opt.andna_cache_file), ANDNA_CACHE_FILE);
  178. set_option_literal(&(server_opt.lclkey_file), LCLKEY_FILE);
  179. set_option_literal(&(server_opt.lcl_file), LCL_FILE);
  180. set_option_literal(&(server_opt.rhc_file), RHC_FILE);
  181. set_option_literal(&(server_opt.counter_c_file), COUNTER_C_FILE);
  182. server_opt.daemon = 1;
  183. server_opt.dbg_lvl = 0;
  184. server_opt.disable_andna = 0;
  185. server_opt.disable_resolvconf = 0;
  186. server_opt.restricted = 0;
  187. server_opt.restricted_class = 0;
  188. server_opt.use_shared_inet = 1;
  189. set_option_literal(&(server_opt.ip_masq_script), IPMASQ_SCRIPT_FILE);
  190. set_option_literal(&(server_opt.tc_shaper_script), TCSHAPER_SCRIPT_FILE);
  191. server_opt.max_connections = MAX_CONNECTIONS;
  192. server_opt.max_accepts_per_host = MAX_ACCEPTS;
  193. server_opt.max_accepts_per_host_time = FREE_ACCEPT_TIME;
  194. }
  195. /*
  196. * fill_loaded_cfg_options
  197. *
  198. * stores in server_opt the options loaded from the configuration file
  199. */
  200. void
  201. fill_loaded_cfg_options(void)
  202. {
  203. char *value;
  204. CONF_SET_STRN_OPT(&(server_opt.int_map_file), CONF_NTK_INT_MAP_FILE,
  205. NAME_MAX - 1);
  206. CONF_SET_STRN_OPT(&(server_opt.bnode_map_file), CONF_NTK_BNODE_MAP_FILE,
  207. NAME_MAX - 1);
  208. CONF_SET_STRN_OPT(&(server_opt.ext_map_file), CONF_NTK_EXT_MAP_FILE,
  209. NAME_MAX - 1);
  210. CONF_SET_STRN_OPT(&(server_opt.andna_hnames_file), CONF_ANDNA_HNAMES_FILE,
  211. NAME_MAX - 1);
  212. CONF_SET_STRN_OPT(&(server_opt.snsd_nodes_file), CONF_SNSD_NODES_FILE,
  213. NAME_MAX - 1);
  214. CONF_SET_STRN_OPT(&(server_opt.andna_cache_file), CONF_ANDNA_CACHE_FILE,
  215. NAME_MAX - 1);
  216. CONF_SET_STRN_OPT(&(server_opt.lclkey_file), CONF_ANDNA_LCLKEY_FILE,
  217. NAME_MAX - 1);
  218. CONF_SET_STRN_OPT(&(server_opt.lcl_file), CONF_ANDNA_LCL_FILE,
  219. NAME_MAX - 1);
  220. CONF_SET_STRN_OPT(&(server_opt.rhc_file), CONF_ANDNA_RHC_FILE,
  221. NAME_MAX - 1);
  222. CONF_SET_STRN_OPT(&(server_opt.counter_c_file), CONF_ANDNA_COUNTER_C_FILE,
  223. NAME_MAX - 1);
  224. CONF_SET_STRN_OPT(&(server_opt.pid_file), CONF_NTK_PID_FILE,
  225. NAME_MAX - 1);
  226. CONF_GET_INT_VALUE(CONF_NTK_MAX_CONNECTIONS,
  227. server_opt.max_connections);
  228. CONF_GET_INT_VALUE(CONF_NTK_MAX_ACCEPTS_PER_HOST,
  229. server_opt.max_accepts_per_host);
  230. CONF_GET_INT_VALUE(CONF_NTK_MAX_ACCEPTS_PER_HOST_TIME,
  231. server_opt.max_accepts_per_host_time);
  232. CONF_GET_INT_VALUE(CONF_DISABLE_ANDNA, server_opt.disable_andna);
  233. CONF_GET_INT_VALUE(CONF_DISABLE_RESOLVCONF,
  234. server_opt.disable_resolvconf);
  235. CONF_GET_INT_VALUE(CONF_NTK_RESTRICTED_MODE, server_opt.restricted);
  236. CONF_GET_INT_VALUE(CONF_NTK_RESTRICTED_CLASS,
  237. server_opt.restricted_class);
  238. CONF_GET_INT_VALUE(CONF_NTK_INTERNET_CONNECTION,
  239. server_opt.inet_connection);
  240. if ((value = CONF_GET_VALUE(CONF_NTK_INTERNET_GW))) {
  241. if (str_to_inet_gw(value, &server_opt.inet_gw,
  242. &server_opt.inet_gw_dev))
  243. fatal
  244. ("Malformed `%s' option: \"%s\". Its syntax is \"IP:dev\"",
  245. config_str[CONF_NTK_INTERNET_GW], value);
  246. }
  247. CONF_GET_INT_VALUE(CONF_NTK_INTERNET_UPLOAD, server_opt.my_upload_bw);
  248. CONF_GET_INT_VALUE(CONF_NTK_INTERNET_DOWNLOAD,
  249. server_opt.my_dnload_bw);
  250. if (server_opt.my_upload_bw && server_opt.my_dnload_bw)
  251. me.my_bandwidth =
  252. bandwidth_in_8bit((server_opt.my_upload_bw +
  253. server_opt.my_dnload_bw) / 2);
  254. if ((value = CONF_GET_VALUE(CONF_NTK_INTERNET_PING_HOSTS))) {
  255. server_opt.inet_hosts = parse_internet_hosts(value,
  256. &server_opt.
  257. inet_hosts_counter);
  258. if (!server_opt.inet_hosts)
  259. fatal("Malformed `%s' option: \"%s\". "
  260. "Its syntax is host1:host2:...",
  261. config_str[CONF_NTK_INTERNET_PING_HOSTS], value);
  262. }
  263. CONF_GET_INT_VALUE(CONF_SHARE_INTERNET, server_opt.share_internet);
  264. CONF_GET_INT_VALUE(CONF_SHAPE_INTERNET, server_opt.shape_internet);
  265. CONF_GET_INT_VALUE(CONF_USE_SHARED_INET, server_opt.use_shared_inet);
  266. CONF_GET_STRN_VALUE(CONF_NTK_IP_MASQ_SCRIPT,
  267. &server_opt.ip_masq_script, NAME_MAX - 1);
  268. CONF_GET_STRN_VALUE(CONF_NTK_TC_SHAPER_SCRIPT,
  269. &server_opt.tc_shaper_script, NAME_MAX - 1);
  270. /* Clean the enviroment */
  271. clear_config_env();
  272. }
  273. void
  274. free_server_opt(void)
  275. {
  276. int i;
  277. xfree(server_opt.config_file);
  278. xfree(server_opt.pid_file);
  279. xfree(server_opt.int_map_file);
  280. xfree(server_opt.ext_map_file);
  281. xfree(server_opt.bnode_map_file);
  282. xfree(server_opt.andna_hnames_file);
  283. xfree(server_opt.snsd_nodes_file);
  284. xfree(server_opt.andna_cache_file);
  285. xfree(server_opt.lclkey_file);
  286. xfree(server_opt.lcl_file);
  287. xfree(server_opt.rhc_file);
  288. xfree(server_opt.counter_c_file);
  289. xfree(server_opt.ip_masq_script);
  290. xfree(server_opt.tc_shaper_script);
  291. xfree(server_opt.inet_gw_dev);
  292. for (i = 0; i < MAX_INTERFACES && server_opt.ifs[i]; i++)
  293. xfree(server_opt.ifs[i]);
  294. }
  295. /* Removes specified existing interface, Ntkd should populate the device list
  296. * prior to this.
  297. * returns 0 on success, return -1 and closes ntkd on error.
  298. */
  299. int
  300. exclude_interface(void)
  301. {
  302. int i;
  303. printf("Number of Interfaces in Use: %d\n", me.cur_ifs_n);
  304. for (i = 0; i < me.cur_ifs_n; i++)
  305. printf("Interface names in Use: %s", me.cur_ifs[i].dev_name);
  306. for (i = 0; i < me.cur_ifs_n; i++) {
  307. if (strcmp(me.cur_ifs[i].dev_name, optarg) == 0) {
  308. printf("Interface %s removed, And replaced with %s",
  309. me.cur_ifs[i].dev_name, me.cur_ifs[me.cur_ifs_n].dev_name);
  310. ifs_del(me.cur_ifs, &me.cur_ifs_n, i);
  311. return 0;
  312. }
  313. else
  314. fatal("Interface %s not found!", optarg);
  315. }
  316. return -1;
  317. }
  318. void
  319. ntk_thread_creatation(void)
  320. {
  321. int x;
  322. pthread_t console_recv_send_thread;
  323. if (pthread_create
  324. (&console_recv_send_thread, NULL, &console_recv_send, &x)) {
  325. fprintf(stderr, "Error creating thread\n");
  326. exit(-1);
  327. }
  328. }
  329. void
  330. parse_options(int argc, char **argv)
  331. {
  332. int c, saved_argc = argc;
  333. int if_n, if_dup;
  334. optind = 0;
  335. while (1) {
  336. int option_index = 0;
  337. static struct option long_options[] = {
  338. {"help", 0, 0, 'h'},
  339. {"iface", 1, 0, 'i'},
  340. {"ipv6", 0, 0, '6'},
  341. {"ipv4", 0, 0, '4'},
  342. {"conf", 1, 0, 'c'},
  343. {"logfile", 1, 0, 'l'},
  344. {"no_andna", 0, 0, 'a'},
  345. {"no_daemon", 0, 0, 'D'},
  346. {"no_resolv", 0, 0, 'R'},
  347. {"restricted", 0, 0, 'r'},
  348. {"share-inet", 0, 0, 'I'},
  349. {"debug", 0, 0, 'd'},
  350. {"version", 0, 0, 'v'},
  351. {"kill", 0, 0, 'k'},
  352. {"exclude", 1, 0, 'e'},
  353. {"console", 0, 0, 'C'},
  354. {"netsplit", 1, 0, 'n'},
  355. {0, 0, 0, 0}
  356. };
  357. c = getopt_long(argc, argv, "i:c:l:e:n:hvd64DRrIakC", long_options,
  358. &option_index);
  359. if (c == -1)
  360. break;
  361. switch (c) {
  362. case 'n':
  363. printf("netsplit argument: %s\n", optarg);
  364. if(strcmp("inet", optarg) == 0 || strcmp("INET", optarg) == 0)
  365. netsplit.netsplit_inet_mode = 1;
  366. if(strcmp("ntk", optarg) == 0 || strcmp("NTK", optarg) == 0)
  367. netsplit.netsplit_ntk_mode = 1;
  368. break;
  369. case 'C':
  370. ntk_thread_creatation();
  371. break;
  372. case 'v':
  373. printf("%s\n", VERSION_STR);
  374. exit(0);
  375. break;
  376. case 'e':
  377. exclude_interface();
  378. break;
  379. case 'k':
  380. if (is_ntkd_already_running() == 1) {
  381. char process_name[256] = { 0 };
  382. pid_t pid;
  383. printf("...Closing ntkd...\n");
  384. FILE *fd = fopen(server_opt.pid_file, "r");
  385. while (fscanf(fd, "%s %d", process_name, &pid) != EOF) {
  386. if (strcmp(process_name, "ntkd") == 0) {
  387. kill(pid, SIGINT);
  388. }
  389. }
  390. fclose(fd);
  391. exit(0);
  392. } else if (is_ntkd_already_running() == 0) {
  393. printf("ntkd is not running\n ...Exiting...\n");
  394. exit(0);
  395. }
  396. break;
  397. case 'h':
  398. usage();
  399. exit(0);
  400. break;
  401. case '4':
  402. server_opt.family = AF_INET;
  403. break;
  404. case '6':
  405. #ifdef IPV6_DISABLED
  406. fatal("The ipv6 is still not supported");
  407. #endif
  408. loginfo
  409. ("WARNING: The ipv6 support is still experimental and under "
  410. "development, nothing is assured to work.");
  411. server_opt.family = AF_INET6;
  412. break;
  413. case 'c':
  414. if(strlen(optarg) > NAME_MAX - 1)
  415. {
  416. optarg[NAME_MAX] = '\0';
  417. }
  418. set_option_str(&(server_opt.config_file), optarg);
  419. break;
  420. case 'l':
  421. if (log_to_file(optarg) < 0)
  422. fatal(0);
  423. break;
  424. case 'i':
  425. if(server_opt.ifs_n+1 >= MAX_INTERFACES)
  426. fatal("The maximum number of interfaces is %d",
  427. MAX_INTERFACES);
  428. if_dup = 0;
  429. for(if_n = 0; if_n < server_opt.ifs_n; if_n++) {
  430. if(strncmp(server_opt.ifs[if_n], optarg, IFNAMSIZ-1) == 0) {
  431. if_dup = 1;
  432. break;
  433. }
  434. }
  435. if(if_dup) { break; }
  436. server_opt.ifs[server_opt.ifs_n++]=xstrndup(optarg, IFNAMSIZ-1);
  437. break;
  438. case 'D':
  439. server_opt.daemon = 0;
  440. break;
  441. case 'a':
  442. server_opt.disable_andna = 1;
  443. break;
  444. case 'R':
  445. server_opt.disable_resolvconf = 1;
  446. break;
  447. case 'r':
  448. server_opt.restricted = 1;
  449. /***
  450. * This is a very dirty hack, but it handles
  451. * the optional argument better than getopt.
  452. *
  453. * This is the problem:
  454. * ntkd -abcrdefg
  455. * If 'r' is an element that specifies an
  456. * optional argument, then the "defg" string
  457. * is taken as its arg, but this is not what
  458. * we want because in this case '-r' is
  459. * specified without its argument.
  460. *
  461. * So, what we do is checking if the argv
  462. * next to the arg of 'r' begins with a '-'
  463. * or not. If not, it is the option of '-r'
  464. *
  465. * The only thing that won't work is:
  466. * ntkd -rOPTION
  467. * it has to be specified in this way:
  468. * ntkd -r OPTION
  469. */
  470. if (argc > optind && argv[optind][0] != '-') {
  471. server_opt.restricted_class = atoi(argv[optind]);
  472. saved_argc--;
  473. }
  474. /**/ break;
  475. case 'I':
  476. server_opt.share_internet = 1;
  477. if (!server_opt.restricted) {
  478. loginfo("Share_internet=1. Assuming restricted=1");
  479. server_opt.restricted = 1;
  480. }
  481. if (!server_opt.inet_connection) {
  482. loginfo("Share_internet=1. Assuming inet_connection=1");
  483. server_opt.inet_connection = 1;
  484. }
  485. break;
  486. case 'd':
  487. server_opt.dbg_lvl++;
  488. break;
  489. default:
  490. usage();
  491. exit(1);
  492. break;
  493. }
  494. }
  495. if (optind < saved_argc && !options_parsed) {
  496. usage();
  497. exit(1);
  498. }
  499. options_parsed++;
  500. }
  501. void
  502. check_conflicting_options(void)
  503. {
  504. #define FATAL_NOT_SPECIFIED(str) fatal("You didn't specified the `%s' " \
  505. "option in netsukuku.conf", \
  506. (str)); \
  507. if (!server_opt.pid_file)
  508. FATAL_NOT_SPECIFIED("pid_file");
  509. if (!server_opt.inet_hosts && server_opt.restricted)
  510. FATAL_NOT_SPECIFIED("internet_ping_hosts");
  511. if (server_opt.restricted && server_opt.share_internet &&
  512. !file_exist(server_opt.ip_masq_script))
  513. fatal("ip_masquerade_script \"%s\" is inexistent",
  514. server_opt.ip_masq_script);
  515. if (server_opt.shape_internet &&
  516. !file_exist(server_opt.tc_shaper_script))
  517. fatal("tc_shaper_script \"%s\" is inexistent",
  518. server_opt.ip_masq_script);
  519. if (!server_opt.restricted && server_opt.inet_connection)
  520. fatal("inet_connection=1 but ntk_restricted_mode=0. If you "
  521. "want to be compatible with the Internet, "
  522. "set the restricted mode in the options");
  523. if (!server_opt.restricted && (server_opt.share_internet))
  524. fatal("You want to share your Internet connection,"
  525. "but I am not running in restricted mode (-r), "
  526. "'cause I'm not sure of what you want... " "I'm aborting.");
  527. if (server_opt.share_internet && me.my_bandwidth < MIN_CONN_BANDWIDTH)
  528. fatal("You want to share your Internet connection but "
  529. "your bandwidth is just TOO small. Do not share "
  530. "it, or your connection will be saturated");
  531. if (!server_opt.inet_connection && server_opt.share_internet) {
  532. loginfo("You want to share your Internet connection,"
  533. "but `internet_connection' is set to 0."
  534. "We are assuming it is 1");
  535. server_opt.inet_connection = 1;
  536. }
  537. if (server_opt.shape_internet && !server_opt.inet_connection)
  538. fatal("The Internet traffic shaping option is set, but "
  539. "the `internet_connection' is set to 0, please check "
  540. "your options.");
  541. #ifdef IPV6_DISABLED
  542. if (server_opt.inet_gw.family == AF_INET6)
  543. fatal("Ipv6 is not supported");
  544. #endif
  545. }
  546. void
  547. init_netsukuku(char **argv)
  548. {
  549. xsrand();
  550. if (geteuid())
  551. fatal("Need root privileges");
  552. destroy_netsukuku_mutex = pid_saved = 0;
  553. sigterm_timestamp = sighup_timestamp = sigalrm_timestamp = 0;
  554. setzero(&me, sizeof(struct current_globals));
  555. if (is_ntkd_already_running())
  556. fatal("ntkd is already running. If it is not, remove \"%s\"",
  557. server_opt.pid_file);
  558. else
  559. save_pid();
  560. my_family = server_opt.family;
  561. restricted_mode = server_opt.restricted;
  562. restricted_class =
  563. server_opt.restricted_class ? RESTRICTED_172 : RESTRICTED_10;
  564. /* Check if the DATA_DIR exists, if not create it */
  565. if (check_and_create_dir(DATA_DIR))
  566. fatal("Cannot access to the %s directory. Exiting.", DATA_DIR);
  567. /*
  568. * Device initialization
  569. */
  570. if (if_init_all(server_opt.ifs, server_opt.ifs_n,
  571. me.cur_ifs, &me.cur_ifs_n) < 0)
  572. fatal("Cannot initialize any network interfaces");
  573. /*
  574. * ANDNA init
  575. */
  576. if (!server_opt.disable_andna)
  577. andna_init();
  578. /*
  579. * Initialize the Internet gateway stuff
  580. */
  581. if (server_opt.my_upload_bw && server_opt.my_dnload_bw)
  582. me.my_bandwidth = bandwidth_in_8bit((server_opt.my_upload_bw +
  583. server_opt.my_dnload_bw) / 2);
  584. init_internet_gateway_search();
  585. pkts_init(me.cur_ifs, me.cur_ifs_n, 0);
  586. qspn_init(FAMILY_LVLS);
  587. me.cur_erc = e_rnode_init(&me.cur_erc_counter);
  588. /* Radar init */
  589. rq_wait_idx_init(rq_wait_idx);
  590. first_init_radar();
  591. total_radars = 0;
  592. ntk_load_maps();
  593. #if 0
  594. /* TODO: activate and test it !! */
  595. debug(DBG_NORMAL, "ACPT: Initializing the accept_tbl: \n"
  596. " max_connections: %d,\n"
  597. " max_accepts_per_host: %d,\n"
  598. " max_accept_per_host_time: %d",
  599. server_opt.max_connections,
  600. server_opt.max_accepts_per_host,
  601. server_opt.max_accepts_per_host_time);
  602. init_accept_tbl(server_opt.max_connections,
  603. server_opt.max_accepts_per_host,
  604. server_opt.max_accepts_per_host_time);
  605. #endif
  606. if (restricted_mode)
  607. loginfo("NetsukukuD is in restricted mode. "
  608. "Restricted class: %s",
  609. server_opt.
  610. restricted_class ? RESTRICTED_172_STR : RESTRICTED_10_STR);
  611. hook_init();
  612. rehook_init();
  613. me.uptime = time(0);
  614. }
  615. int
  616. destroy_netsukuku(void)
  617. {
  618. if (destroy_netsukuku_mutex)
  619. return -1;
  620. destroy_netsukuku_mutex = 1;
  621. unlink(server_opt.pid_file);
  622. ntk_save_maps();
  623. ntk_free_maps();
  624. if (!server_opt.disable_andna)
  625. andna_close();
  626. close_internet_gateway_search();
  627. last_close_radar();
  628. e_rnode_free(&me.cur_erc, &me.cur_erc_counter);
  629. destroy_accept_tbl();
  630. if_close_all();
  631. qspn_free();
  632. free_server_opt();
  633. return 0;
  634. }
  635. void
  636. sigterm_handler(int sig)
  637. {
  638. time_t cur_t;
  639. if (sigterm_timestamp == (cur_t = time(0)))
  640. return;
  641. sigterm_timestamp = time(0);
  642. if (!destroy_netsukuku())
  643. fatal("Termination signal caught. Dying, bye, bye");
  644. }
  645. void *
  646. reload_hostname_thread(void *null)
  647. {
  648. /*
  649. * Reload the file where the hostnames to be registered are and
  650. * register the new ones
  651. */
  652. loginfo("Reloading the andna hostnames file");
  653. load_hostnames(server_opt.andna_hnames_file, &andna_lcl, &lcl_counter);
  654. load_snsd(server_opt.snsd_nodes_file, andna_lcl);
  655. andna_update_hnames(1);
  656. return 0;
  657. }
  658. void
  659. sighup_handler(int sig)
  660. {
  661. pthread_t thread;
  662. pthread_attr_t t_attr;
  663. time_t cur_t;
  664. if (sighup_timestamp == (cur_t = time(0)))
  665. return;
  666. sighup_timestamp = time(0);
  667. pthread_attr_init(&t_attr);
  668. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  669. pthread_create(&thread, &t_attr, reload_hostname_thread, 0);
  670. }
  671. void *
  672. rh_cache_flush_thread(void *null)
  673. {
  674. /*
  675. * Flush the resolved hostnames cache.
  676. */
  677. loginfo("Flush the resolved hostnames cache");
  678. rh_cache_flush();
  679. return 0;
  680. }
  681. void
  682. sigalrm_handler(int sig)
  683. {
  684. pthread_t thread;
  685. pthread_attr_t t_attr;
  686. time_t cur_t;
  687. if (sigalrm_timestamp == (cur_t = time(0)))
  688. return;
  689. sigalrm_timestamp = time(0);
  690. pthread_attr_init(&t_attr);
  691. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  692. pthread_create(&thread, &t_attr, rh_cache_flush_thread, 0);
  693. }
  694. /*
  695. * The main flow shall never be stopped, and the sand of time will be
  696. * revealed.
  697. */
  698. int
  699. main(int argc, char **argv)
  700. {
  701. struct udp_daemon_argv ud_argv;
  702. u_short *port;
  703. pthread_t daemon_tcp_thread, daemon_udp_thread, andna_thread;
  704. pthread_t ping_igw_thread;
  705. pthread_attr_t t_attr;
  706. log_init(argv[0], 0, 1);
  707. /* Options loading... */
  708. fill_default_options();
  709. parse_options(argc, argv);
  710. /* reinit the logs using the new `dbg_lvl' value */
  711. log_init(argv[0], server_opt.dbg_lvl, 1);
  712. log_to_file(0);
  713. /* Load the option from the config file */
  714. load_config_file(server_opt.config_file);
  715. fill_loaded_cfg_options();
  716. /* If a same option was specified in the config file and in the
  717. * command line, give priority to the latter */
  718. parse_options(argc, argv);
  719. check_conflicting_options();
  720. /* Initialize the whole netsukuku source code */
  721. init_netsukuku(argv);
  722. signal(SIGALRM, sigalrm_handler);
  723. signal(SIGHUP, sighup_handler);
  724. signal(SIGINT, sigterm_handler);
  725. signal(SIGTERM, sigterm_handler);
  726. signal(SIGQUIT, sigterm_handler);
  727. /* Angelic foreground or Daemonic background ? */
  728. if (server_opt.daemon) {
  729. loginfo("Forking to background");
  730. log_init(argv[0], server_opt.dbg_lvl, 0);
  731. if (daemon(0, 0) == -1)
  732. error("Impossible to daemonize: %s.", strerror(errno));
  733. }
  734. pthread_attr_init(&t_attr);
  735. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  736. setzero(&ud_argv, sizeof(struct udp_daemon_argv));
  737. port = xmalloc(sizeof(u_short));
  738. /*
  739. * These are the daemons, the main threads that keeps NetsukukuD
  740. * up & running.
  741. */
  742. debug(DBG_NORMAL, "Activating all daemons");
  743. pthread_mutex_init(&udp_daemon_lock, 0);
  744. pthread_mutex_init(&tcp_daemon_lock, 0);
  745. debug(DBG_SOFT, "Evoking the netsukuku udp radar daemon.");
  746. ud_argv.port = ntk_udp_radar_port;
  747. pthread_mutex_lock(&udp_daemon_lock);
  748. pthread_create(&daemon_udp_thread, &t_attr, udp_daemon,
  749. (void *) &ud_argv);
  750. pthread_mutex_lock(&udp_daemon_lock);
  751. pthread_mutex_unlock(&udp_daemon_lock);
  752. debug(DBG_SOFT, "Evoking the netsukuku tcp daemon.");
  753. *port = ntk_tcp_port;
  754. pthread_mutex_lock(&tcp_daemon_lock);
  755. pthread_create(&daemon_tcp_thread, &t_attr, tcp_daemon, (void *) port);
  756. pthread_mutex_lock(&tcp_daemon_lock);
  757. pthread_mutex_unlock(&tcp_daemon_lock);
  758. /* Now we hook in Netsukuku */
  759. netsukuku_hook(0, 0);
  760. /*
  761. * If not disabled, start the ANDNA daemon
  762. */
  763. if (!server_opt.disable_andna)
  764. pthread_create(&andna_thread, &t_attr, andna_main, 0);
  765. xfree(port);
  766. if (restricted_mode && (server_opt.share_internet ||
  767. server_opt.use_shared_inet)) {
  768. debug(DBG_SOFT, "Evoking the Internet Gateway Pinger daemon");
  769. pthread_create(&ping_igw_thread, &t_attr, igw_monitor_igws_t, 0);
  770. }
  771. /* We use this same process for the radar_daemon. */
  772. debug(DBG_SOFT, "Evoking radar daemon.");
  773. radar_daemon(0);
  774. /* Not reached, hahaha */
  775. loginfo("Cya m8");
  776. pthread_attr_destroy(&t_attr);
  777. destroy_netsukuku();
  778. exit(0);
  779. }