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.

daemon.c 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  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. #include "includes.h"
  19. #include "common.h"
  20. #include "inet.h"
  21. #include "request.h"
  22. #include "if.h"
  23. #include "pkts.h"
  24. #include "bmap.h"
  25. #include "daemon.h"
  26. #include "netsukuku.h"
  27. #include "accept.h"
  28. extern int errno;
  29. /*
  30. * prepare_listen_socket:
  31. * It creates a new socket of the desired `family' and binds it to the
  32. * specified `port'. It sets also the reuseaddr and NONBLOCK
  33. * socket options, because this new socket shall be used to listen() and
  34. * accept().
  35. * If `dev' is not null, the socket will be binded to the device named
  36. * `dev'->dev_name with the SO_BINDTODEVICE socket option.
  37. * The created socket is returned.
  38. */
  39. int prepare_listen_socket(int family, int socktype, u_short port,
  40. interface *dev)
  41. {
  42. struct addrinfo hints, *ai, *aitop;
  43. char strport[NI_MAXSERV];
  44. int err, s;
  45. setzero(&hints, sizeof(struct addrinfo));
  46. hints.ai_family=family;
  47. hints.ai_socktype=socktype;
  48. hints.ai_flags=AI_PASSIVE;
  49. snprintf(strport, NI_MAXSERV, "%u", port);
  50. err=getaddrinfo(NULL, strport, &hints, &aitop);
  51. if(err) {
  52. error("Getaddrinfo error: %s", gai_strerror(err));
  53. return -1;
  54. }
  55. for (ai = aitop; ai; ai = ai->ai_next) {
  56. if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
  57. continue;
  58. s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
  59. if (s == -1)
  60. /* Maybe we can use another socket...*/
  61. continue;
  62. /* Bind the created socket to the device named dev->dev_name */
  63. if(dev && (set_bindtodevice_sk(s, dev->dev_name) < 0)) {
  64. inet_close(&s);
  65. continue;
  66. }
  67. if(set_reuseaddr_sk(s) < 0) {
  68. inet_close(&s);
  69. continue;
  70. }
  71. /* Let's bind it! */
  72. if(bind(s, ai->ai_addr, ai->ai_addrlen) < 0) {
  73. error("Cannot bind the port %d: %s. Trying another "
  74. "socket...", port, strerror(errno));
  75. inet_close(&s);
  76. continue;
  77. }
  78. freeaddrinfo(aitop);
  79. return s;
  80. }
  81. error("Cannot open inbound socket on port %d: %s", port, strerror(errno));
  82. freeaddrinfo(aitop);
  83. return -1;
  84. }
  85. /*
  86. * sockets_all_ifs
  87. *
  88. * creates a socket for each interface which is in the `ifs' array.
  89. * The array has `ifs_n' members.
  90. * Each created socket is stored in the `dev_sk' array, which has `ifs_n'#
  91. * members.
  92. * The created socket will be bound to the relative interface.
  93. * In `max_sk_idx' is stored the index of the `dev_sk' array, which has the
  94. * biggest dev_sk.
  95. *
  96. * On error 0 is returned, otherwise the number of utilised interfaces is
  97. * returned.
  98. * If the error is fatal, a negative value is returned.
  99. */
  100. int sockets_all_ifs(int family, int socktype, u_short port,
  101. interface *ifs, int ifs_n,
  102. int *dev_sk, int *max_sk_idx)
  103. {
  104. int i, n, e=0;
  105. *max_sk_idx=0;
  106. for(i=0, n=0; i<ifs_n; i++) {
  107. dev_sk[i] = prepare_listen_socket(family, socktype, port,
  108. &ifs[i]);
  109. if(dev_sk[i] < 0) {
  110. error("Cannot create a socket on the %s interface! "
  111. "Ignoring it", ifs[i].dev_name);
  112. dev_sk[i]=0;
  113. e++;
  114. continue;
  115. }
  116. if(dev_sk[i] >= dev_sk[*max_sk_idx])
  117. *max_sk_idx=i;
  118. n++;
  119. }
  120. if(e == ifs_n)
  121. return -1;
  122. return n;
  123. }
  124. /*
  125. * udp_exec_pkt: passes the received udp packet to pkt_exec().
  126. * `passed_argv' is a pointer to a udp_exec_pkt_argv struct
  127. */
  128. void *udp_exec_pkt(void *passed_argv)
  129. {
  130. struct udp_exec_pkt_argv argv;
  131. PACKET rpkt;
  132. const char *ntop;
  133. memcpy(&argv, passed_argv, sizeof(struct udp_exec_pkt_argv));
  134. memcpy(&rpkt, argv.recv_pkt, sizeof(PACKET));
  135. if(argv.flags & UDP_THREAD_FOR_EACH_PKT)
  136. pthread_mutex_unlock(&udp_exec_lock);
  137. /* Drop any packet we sent in broadcast */
  138. if(!memcmp(rpkt.from.data, me.cur_ip.data, MAX_IP_SZ)) {
  139. pkt_free(&rpkt, 0);
  140. return 0;
  141. }
  142. if(add_accept(rpkt.from, 1)) {
  143. ntop=inet_to_str(rpkt.from);
  144. debug(DBG_NORMAL, "ACPT: dropped UDP pkt from %s: "
  145. "Accept table full.", ntop);
  146. return 0;
  147. }
  148. pkt_exec(rpkt, argv.acpt_idx);
  149. pkt_free(&rpkt, 0);
  150. return 0;
  151. }
  152. /*
  153. * udp_daemon: Takes care of receiving udp packets.
  154. * `passed_argv' is a pointer to a udp_daemon_argv struct
  155. */
  156. void *udp_daemon(void *passed_argv)
  157. {
  158. struct udp_daemon_argv argv;
  159. struct udp_exec_pkt_argv exec_pkt_argv;
  160. interface *ifs;
  161. int max_sk_idx, dev_sk[me.cur_ifs_n];
  162. PACKET rpkt;
  163. fd_set fdset;
  164. int ret, i, err;
  165. u_short udp_port;
  166. pthread_t thread;
  167. pthread_attr_t t_attr;
  168. #ifdef DEBUG
  169. int select_errors=0;
  170. #endif
  171. memcpy(&argv, passed_argv, sizeof(struct udp_daemon_argv));
  172. udp_port=argv.port;
  173. setzero(&exec_pkt_argv, sizeof(struct udp_exec_pkt_argv));
  174. if(argv.flags & UDP_THREAD_FOR_EACH_PKT) {
  175. pthread_attr_init(&t_attr);
  176. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  177. exec_pkt_argv.flags|=UDP_THREAD_FOR_EACH_PKT;
  178. }
  179. debug(DBG_SOFT, "Preparing the udp listening socket on port %d", udp_port);
  180. err=sockets_all_ifs(my_family, SOCK_DGRAM, udp_port, me.cur_ifs,
  181. me.cur_ifs_n, dev_sk, &max_sk_idx);
  182. if(!err)
  183. return NULL;
  184. else if(err < 0)
  185. fatal("Creation of the %s daemon aborted. "
  186. "Is there another ntkd running?", "udp");
  187. debug(DBG_NORMAL, "Udp daemon on port %d up & running", udp_port);
  188. pthread_mutex_unlock(&udp_daemon_lock);
  189. pthread_mutex_init(&udp_exec_lock, 0);
  190. for(;;) {
  191. FD_ZERO(&fdset);
  192. if(!me.cur_ifs_n) {
  193. /* All the devices have been removed while ntkd was
  194. * running, sleep well */
  195. sleep(1);
  196. continue;
  197. }
  198. for(i=0; i < me.cur_ifs_n; i++)
  199. if(dev_sk[i])
  200. FD_SET(dev_sk[i], &fdset);
  201. ret=select(dev_sk[max_sk_idx]+1, &fdset, NULL, NULL, NULL);
  202. if(sigterm_timestamp)
  203. /* NetsukukuD has been closed */
  204. break;
  205. if (ret < 0) {
  206. #ifdef DEBUG
  207. if(select_errors > 20)
  208. break;
  209. select_errors++;
  210. #endif
  211. error("daemon_udp: select error: %s", strerror(errno));
  212. continue;
  213. }
  214. for(i=0; i < me.cur_ifs_n; i++) {
  215. ifs=&me.cur_ifs[i];
  216. if(!dev_sk[i])
  217. continue;
  218. if(!FD_ISSET(dev_sk[i], &fdset))
  219. continue;
  220. setzero(&rpkt, sizeof(PACKET));
  221. pkt_addsk(&rpkt, my_family, dev_sk[i], SKT_UDP);
  222. pkt_add_dev(&rpkt, ifs, 0);
  223. rpkt.flags=MSG_WAITALL;
  224. pkt_addport(&rpkt, udp_port);
  225. if(pkt_recv(&rpkt) < 0) {
  226. pkt_free(&rpkt, 0);
  227. continue;
  228. }
  229. exec_pkt_argv.acpt_idx=accept_idx;
  230. exec_pkt_argv.acpt_sidx=accept_sidx;
  231. if(argv.flags & UDP_THREAD_FOR_EACH_PKT) {
  232. exec_pkt_argv.recv_pkt=&rpkt;
  233. pthread_mutex_lock(&udp_exec_lock);
  234. pthread_create(&thread, &t_attr, udp_exec_pkt,
  235. &exec_pkt_argv);
  236. pthread_mutex_lock(&udp_exec_lock);
  237. pthread_mutex_unlock(&udp_exec_lock);
  238. } else {
  239. exec_pkt_argv.recv_pkt=&rpkt;
  240. udp_exec_pkt(&exec_pkt_argv);
  241. }
  242. }
  243. }
  244. destroy_accept_tbl();
  245. return NULL;
  246. }
  247. void *tcp_recv_loop(void *recv_pkt)
  248. {
  249. PACKET rpkt;
  250. int acpt_idx, acpt_sidx;
  251. acpt_idx=accept_idx;
  252. acpt_sidx=accept_sidx;
  253. memcpy(&rpkt, recv_pkt, sizeof(PACKET));
  254. pthread_mutex_unlock(&tcp_exec_lock);
  255. #if 0
  256. add_accept_pid(getpid(), acpt_idx, acpt_sidx);
  257. #endif
  258. while( pkt_recv(&rpkt) != -1 ) {
  259. if(pkt_exec(rpkt, acpt_idx) < 0) {
  260. goto close;
  261. break;
  262. } else
  263. pkt_free(&rpkt, 0);
  264. }
  265. close:
  266. pkt_free(&rpkt, 1);
  267. close_accept(acpt_idx, acpt_sidx);
  268. return NULL;
  269. }
  270. void *tcp_daemon(void *door)
  271. {
  272. pthread_t thread;
  273. pthread_attr_t t_attr;
  274. PACKET rpkt;
  275. struct sockaddr_storage addr;
  276. socklen_t addrlen = sizeof addr;
  277. inet_prefix ip;
  278. fd_set fdset;
  279. int fd, ret, err, i;
  280. interface *ifs;
  281. int max_sk_idx, dev_sk[me.cur_ifs_n];
  282. u_short tcp_port=*(u_short *)door;
  283. const char *ntop;
  284. pthread_attr_init(&t_attr);
  285. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  286. debug(DBG_SOFT, "Preparing the tcp listening socket on port %d", tcp_port);
  287. err=sockets_all_ifs(my_family, SOCK_STREAM, tcp_port, me.cur_ifs,
  288. me.cur_ifs_n, dev_sk, &max_sk_idx);
  289. if(!err)
  290. return NULL;
  291. else if(err < 0)
  292. fatal("Creation of the %s daemon aborted. "
  293. "Is there another ntkd running?", "tcp");
  294. pthread_mutex_init(&tcp_exec_lock, 0);
  295. for(i=0; i<me.cur_ifs_n; i++) {
  296. if(!dev_sk[i])
  297. continue;
  298. /*
  299. * While we are accepting the connections we keep the socket non
  300. * blocking.
  301. */
  302. if(set_nonblock_sk(dev_sk[i])) {
  303. pthread_mutex_unlock(&tcp_daemon_lock);
  304. return NULL;
  305. }
  306. /* Shhh, it's listening... */
  307. if(listen(dev_sk[i], 5) == -1) {
  308. inet_close(&dev_sk[i]);
  309. pthread_mutex_unlock(&tcp_daemon_lock);
  310. return NULL;
  311. }
  312. }
  313. debug(DBG_NORMAL, "Tcp daemon on port %d up & running", tcp_port);
  314. pthread_mutex_unlock(&tcp_daemon_lock);
  315. for(;;) {
  316. FD_ZERO(&fdset);
  317. if(!me.cur_ifs_n) {
  318. /* All the devices have been removed while ntkd was
  319. * running, sleep well */
  320. sleep(1);
  321. continue;
  322. }
  323. for(i=0; i < me.cur_ifs_n; i++)
  324. if(dev_sk[i])
  325. FD_SET(dev_sk[i], &fdset);
  326. ret=select(dev_sk[max_sk_idx]+1, &fdset, NULL, NULL, NULL);
  327. if(sigterm_timestamp)
  328. /* NetsukukuD has been closed */
  329. break;
  330. if(ret < 0 && errno != EINTR)
  331. error("daemon_tcp: select error: %s", strerror(errno));
  332. if(ret < 0)
  333. continue;
  334. for(i=0; i < me.cur_ifs_n; i++) {
  335. ifs=&me.cur_ifs[i];
  336. if(!dev_sk[i])
  337. continue;
  338. if(!FD_ISSET(dev_sk[i], &fdset))
  339. continue;
  340. fd=accept(dev_sk[i], (struct sockaddr *)&addr, &addrlen);
  341. if(fd == -1) {
  342. if (errno != EINTR && errno != EWOULDBLOCK)
  343. error("daemon_tcp: accept(): %s", strerror(errno));
  344. continue;
  345. }
  346. setzero(&rpkt, sizeof(PACKET));
  347. pkt_addsk(&rpkt, my_family, fd, SKT_TCP);
  348. pkt_add_dev(&rpkt, ifs, 0);
  349. rpkt.flags=MSG_WAITALL;
  350. pkt_addport(&rpkt, tcp_port);
  351. ntop=0;
  352. sockaddr_to_inet((struct sockaddr *)&addr, &ip, 0);
  353. pkt_addfrom(&rpkt, &ip);
  354. if(server_opt.dbg_lvl)
  355. ntop=inet_to_str(ip);
  356. if((ret=add_accept(ip, 0))) {
  357. debug(DBG_NORMAL, "ACPT: drop connection with %s: "
  358. "Accept table full.", ntop);
  359. /* Omg, we cannot take it anymore, go away: ACK_NEGATIVE */
  360. pkt_err(rpkt, ret, 1);
  361. inet_close(&fd);
  362. continue;
  363. } else {
  364. /*
  365. * Ok, the connection is good, send back the
  366. * ACK_AFFERMATIVE.
  367. */
  368. pkt_addto(&rpkt, &rpkt.from);
  369. send_rq(&rpkt, 0, ACK_AFFERMATIVE, 0, 0, 0, 0);
  370. }
  371. if(unset_nonblock_sk(fd))
  372. continue;
  373. pthread_mutex_lock(&tcp_exec_lock);
  374. err=pthread_create(&thread, &t_attr, tcp_recv_loop, (void *)&rpkt);
  375. pthread_detach(thread);
  376. pthread_mutex_lock(&tcp_exec_lock);
  377. pthread_mutex_unlock(&tcp_exec_lock);
  378. }
  379. }
  380. return NULL;
  381. }