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.

pkts.c 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
  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. * pkts.c:
  20. * General functions to forge, pack, send, receive, forward and unpack
  21. * packets.
  22. */
  23. #include "includes.h"
  24. #include <zlib.h>
  25. #include "inet.h"
  26. #include "request.h"
  27. #include "endianness.h"
  28. #include "pkts.h"
  29. #include "accept.h"
  30. #include "common.h"
  31. interface cur_ifs[MAX_INTERFACES];
  32. int cur_ifs_n;
  33. /*
  34. * pkts_init:
  35. * Initialize the vital organs of the pkts.c's functions.
  36. * `ifs' is the array which keeps all the the `ifs_n'# network
  37. * interface that will be used.
  38. * If `queue_init' is not 0, the pkt_queue is initialized too.
  39. */
  40. void pkts_init(interface *ifs, int ifs_n, int queue_init)
  41. {
  42. cur_ifs_n = ifs_n > MAX_INTERFACES ? ifs_n : MAX_INTERFACES;
  43. memcpy(cur_ifs, ifs, sizeof(interface)*cur_ifs_n);
  44. pkt_q_counter=0;
  45. if(queue_init)
  46. pkt_queue_init();
  47. op_filter_reset(OP_FILTER_ALLOW);
  48. }
  49. /*
  50. * * * Handy functions to build the PACKET * *
  51. */
  52. void pkt_addfrom(PACKET *pkt, inet_prefix *from)
  53. {
  54. if(!from)
  55. setzero(&pkt->from, sizeof(inet_prefix));
  56. else
  57. inet_copy(&pkt->from, from);
  58. }
  59. void pkt_addto(PACKET *pkt, inet_prefix *to)
  60. {
  61. if(!to)
  62. setzero(&pkt->to, sizeof(inet_prefix));
  63. else
  64. inet_copy(&pkt->to, to);
  65. }
  66. void pkt_add_dev(PACKET *pkt, interface *dev, int bind_the_socket)
  67. {
  68. pkt->dev=dev;
  69. if(dev && bind_the_socket)
  70. pkt->pkt_flags|=PKT_BIND_DEV;
  71. }
  72. void pkt_addsk(PACKET *pkt, int family, int sk, int sk_type)
  73. {
  74. pkt->family=family;
  75. pkt->sk=sk;
  76. pkt->sk_type=sk_type;
  77. }
  78. void pkt_addport(PACKET *pkt, u_short port)
  79. {
  80. pkt->port=port;
  81. }
  82. void pkt_addtimeout(PACKET *pkt, u_int timeout, int recv, int send)
  83. {
  84. if((pkt->timeout=timeout)) {
  85. if(recv)
  86. pkt->pkt_flags|=PKT_RECV_TIMEOUT;
  87. if(send)
  88. pkt->pkt_flags|=PKT_SEND_TIMEOUT;
  89. }
  90. }
  91. void pkt_addcompress(PACKET *pkt)
  92. {
  93. pkt->pkt_flags|=PKT_COMPRESSED;
  94. }
  95. void pkt_addlowdelay(PACKET *pkt)
  96. {
  97. pkt->pkt_flags|=PKT_SET_LOWDELAY;
  98. }
  99. void pkt_addnonblock(PACKET *pkt)
  100. {
  101. pkt->pkt_flags|=PKT_NONBLOCK;
  102. }
  103. void pkt_addhdr(PACKET *pkt, pkt_hdr *hdr)
  104. {
  105. if(!hdr)
  106. setzero(&pkt->hdr, sizeof(pkt_hdr));
  107. else
  108. memcpy(&pkt->hdr, hdr, sizeof(pkt_hdr));
  109. }
  110. void pkt_addmsg(PACKET *pkt, char *msg)
  111. {
  112. pkt->msg=msg;
  113. }
  114. /* * * End of handy stupid functions (^_+) * * */
  115. /*
  116. * pkt_clear: blanks the entire PACKET struct, leaving intact only `hdr'
  117. * and `msg'
  118. */
  119. void pkt_clear(PACKET *pkt)
  120. {
  121. pkt_addfrom(pkt, 0);
  122. pkt_addto(pkt, 0);
  123. pkt_addsk(pkt, 0,0,0);
  124. pkt_addport(pkt, 0);
  125. pkt->flags=pkt->pkt_flags=0;
  126. }
  127. /*
  128. * pkt_copy: Copy the `src' PACKET in `dst'. It xmallocs also a new msg block in
  129. * `dst->msg' of `src->hdr.sz' size and copies in it `src->msg'
  130. */
  131. void pkt_copy(PACKET *dst, PACKET *src)
  132. {
  133. memcpy(dst, src, sizeof(PACKET));
  134. if(src->hdr.sz && src->msg) {
  135. dst->msg=xmalloc(src->hdr.sz);
  136. memcpy(dst->msg, src->msg, src->hdr.sz);
  137. }
  138. }
  139. void pkt_free(PACKET *pkt, int close_socket)
  140. {
  141. if(close_socket && pkt->sk)
  142. inet_close(&pkt->sk);
  143. if(pkt->msg) {
  144. xfree(pkt->msg);
  145. pkt->msg=0;
  146. }
  147. }
  148. /*
  149. * pkt_compress
  150. *
  151. * It compresses `pkt'->msg and stores the result in `dst'.
  152. * `dst_msg' must have at least `newhdr'->sz bytes big.
  153. * It is also assumed that `pkt'->msg is not 0.
  154. *
  155. * The size of the compressed msg is stored in `newhdr'->sz, while
  156. * the size of the orignal one is written in `newhdr'->uncompress_sz.
  157. * If the compression doesn't fail, `newhdr'->sz will be always less than
  158. * `newhdr'->uncompress_sz.
  159. *
  160. * Nothing in `pkt' is modified.
  161. *
  162. * If the packet was compressed 0 is returned and the COMPRESSED_PKT flag is
  163. * set to `newhdr'->.flags.
  164. * On error a negative value is returned.
  165. */
  166. int pkt_compress(PACKET *pkt, pkt_hdr *newhdr, char *dst_msg)
  167. {
  168. uLongf bound_sz;
  169. int ret;
  170. bound_sz=compressBound(pkt->hdr.sz);
  171. unsigned char dst[bound_sz];
  172. ret=compress2(dst, &bound_sz, (u_char*)pkt->msg, pkt->hdr.sz,
  173. PKT_COMPRESS_LEVEL);
  174. if(ret != Z_OK) {
  175. error(RED(ERROR_MSG) "cannot compress the pkt. "
  176. "It will be sent uncompressed.", ERROR_FUNC);
  177. return -1;
  178. }
  179. if(bound_sz >= pkt->hdr.sz)
  180. /* Disgregard compression, it isn't useful in this case */
  181. return -pkt->hdr.sz;
  182. memcpy(dst_msg, dst, bound_sz);
  183. newhdr->uncompress_sz=pkt->hdr.sz;
  184. newhdr->sz=bound_sz;
  185. newhdr->flags|=COMPRESSED_PKT;
  186. return 0;
  187. }
  188. /*
  189. * pkt_pack
  190. *
  191. * It packs the packet with its `pkt'->header in a single buffer.
  192. * If PKT_COMPRESSED is set in `pkt'->pkt_flags, `pkt'->msg will be compressed
  193. * if its size is > PKT_COMPRESS_THRESHOLD.
  194. */
  195. char *pkt_pack(PACKET *pkt)
  196. {
  197. char *buf, *buf_hdr, *buf_body;
  198. buf=(char *)xmalloc(PACKET_SZ(pkt->hdr.sz));
  199. buf_hdr=buf;
  200. buf_body=buf+sizeof(pkt_hdr);
  201. /***
  202. * Copy the header
  203. */
  204. memcpy(buf_hdr, &pkt->hdr, sizeof(pkt_hdr));
  205. /* host -> network order */
  206. ints_host_to_network(buf_hdr, pkt_hdr_iinfo);
  207. /***/
  208. if(pkt->hdr.sz) {
  209. /*
  210. * compress the packet if necessary
  211. */
  212. if((pkt->pkt_flags & PKT_COMPRESSED &&
  213. pkt->hdr.sz >= PKT_COMPRESS_THRESHOLD)) {
  214. if(!pkt_compress(pkt, &pkt->hdr, buf_body)) {
  215. /*
  216. * Re-copy the header in `buf', because
  217. * it has been changed during compression. */
  218. memcpy(buf_hdr, &pkt->hdr, sizeof(pkt_hdr));
  219. ints_host_to_network(buf_hdr, pkt_hdr_iinfo);
  220. }
  221. } else
  222. /* Just copy the body of the packet */
  223. memcpy(buf_body, pkt->msg, pkt->hdr.sz);
  224. /**/
  225. }
  226. return buf;
  227. }
  228. /*
  229. * pkt_uncompress
  230. *
  231. * It uncompress the compressed `pkt' and stores the result in `pkt' itself
  232. * On error -1 is returned.
  233. */
  234. int pkt_uncompress(PACKET *pkt)
  235. {
  236. uLongf dstlen;
  237. int ret=0;
  238. unsigned char *dst=0;
  239. dstlen=pkt->hdr.uncompress_sz;
  240. dst=xmalloc(dstlen);
  241. ret=uncompress(dst, &dstlen, (u_char*) pkt->msg, pkt->hdr.sz);
  242. if(ret != Z_OK)
  243. ERROR_FINISH(ret, -1, finish);
  244. else
  245. ret=0;
  246. /**
  247. * Restore the uncompressed packet
  248. */
  249. xfree(pkt->msg);
  250. pkt->msg=(char*)dst;
  251. pkt->hdr.sz=pkt->hdr.uncompress_sz;
  252. pkt->hdr.uncompress_sz=0;
  253. pkt->hdr.flags&=~COMPRESSED_PKT;
  254. /**/
  255. finish:
  256. if(ret && dst)
  257. xfree(dst);
  258. return ret;
  259. }
  260. /*
  261. * pkt_unpack
  262. *
  263. * `pkt' must be already in host order
  264. */
  265. int pkt_unpack(PACKET *pkt)
  266. {
  267. if(pkt->hdr.sz && pkt->msg &&
  268. pkt->hdr.flags & COMPRESSED_PKT)
  269. if(pkt_uncompress(pkt))
  270. return -1;
  271. return 0;
  272. }
  273. int pkt_verify_hdr(PACKET pkt)
  274. {
  275. if(strncmp(pkt.hdr.ntk_id, NETSUKUKU_ID, 3) ||
  276. pkt.hdr.sz > MAXMSGSZ)
  277. return 1;
  278. if(pkt.hdr.flags & COMPRESSED_PKT &&
  279. (pkt.hdr.sz >= pkt.hdr.uncompress_sz ||
  280. pkt.hdr.uncompress_sz > PKT_MAX_MSG_SZ))
  281. /* Invalid compression */
  282. return 1;
  283. return 0;
  284. }
  285. ssize_t pkt_send(PACKET *pkt)
  286. {
  287. ssize_t ret=0;
  288. char *buf=0;
  289. buf=pkt_pack(pkt);
  290. if(pkt->sk_type==SKT_UDP || pkt->sk_type==SKT_BCAST) {
  291. struct sockaddr_storage saddr_sto;
  292. struct sockaddr *to = (struct sockaddr *)&saddr_sto;
  293. socklen_t tolen;
  294. if(inet_to_sockaddr(&pkt->to, pkt->port, to, &tolen) < 0) {
  295. debug(DBG_NOISE, "Cannot pkt_send(): %d "
  296. "Family not supported", pkt->to.family);
  297. ERROR_FINISH(ret, -1, finish);
  298. }
  299. if(pkt->pkt_flags & PKT_SEND_TIMEOUT)
  300. ret=inet_sendto_timeout(pkt->sk, buf,
  301. PACKET_SZ(pkt->hdr.sz), pkt->flags, to,
  302. tolen, pkt->timeout);
  303. else
  304. ret=inet_sendto(pkt->sk, buf, PACKET_SZ(pkt->hdr.sz),
  305. pkt->flags, to, tolen);
  306. } else if(pkt->sk_type==SKT_TCP) {
  307. if(pkt->pkt_flags & PKT_SEND_TIMEOUT)
  308. ret=inet_send_timeout(pkt->sk, buf, PACKET_SZ(pkt->hdr.sz),
  309. pkt->flags, pkt->timeout);
  310. else
  311. ret=inet_send(pkt->sk, buf, PACKET_SZ(pkt->hdr.sz),
  312. pkt->flags);
  313. } else
  314. fatal("Unkown socket_type. Something's very wrong!! Be aware");
  315. finish:
  316. if(buf)
  317. xfree(buf);
  318. return ret;
  319. }
  320. ssize_t pkt_recv_udp(PACKET *pkt)
  321. {
  322. ssize_t err=-1;
  323. struct sockaddr from;
  324. socklen_t fromlen;
  325. char buf[MAXMSGSZ];
  326. setzero(buf, MAXMSGSZ);
  327. setzero(&from, sizeof(struct sockaddr));
  328. if(pkt->family == AF_INET)
  329. fromlen=sizeof(struct sockaddr_in);
  330. else if(pkt->family == AF_INET6)
  331. fromlen=sizeof(struct sockaddr_in6);
  332. else {
  333. error("pkt_recv udp: family not set");
  334. return -1;
  335. }
  336. /* we get the whole pkt, */
  337. if(pkt->pkt_flags & PKT_RECV_TIMEOUT)
  338. err=inet_recvfrom_timeout(pkt->sk, buf, PACKET_SZ(MAXMSGSZ),
  339. pkt->flags, &from, &fromlen, pkt->timeout);
  340. else
  341. err=inet_recvfrom(pkt->sk, buf, PACKET_SZ(MAXMSGSZ),
  342. pkt->flags, &from, &fromlen);
  343. if(err < sizeof(pkt_hdr)) {
  344. debug(DBG_NOISE, "inet_recvfrom() of the hdr aborted!");
  345. return -1;
  346. }
  347. /* then we extract the hdr... and verify it */
  348. memcpy(&pkt->hdr, buf, sizeof(pkt_hdr));
  349. /* network -> host order */
  350. ints_network_to_host(&pkt->hdr, pkt_hdr_iinfo);
  351. if(pkt_verify_hdr(*pkt) || pkt->hdr.sz+sizeof(pkt_hdr) > err) {
  352. debug(DBG_NOISE, RED(ERROR_MSG) "Malformed header", ERROR_POS);
  353. return -1;
  354. }
  355. if(sockaddr_to_inet(&from, &pkt->from, 0) < 0) {
  356. debug(DBG_NOISE, "Cannot pkt_recv(): %d"
  357. " Family not supported", from.sa_family);
  358. return -1;
  359. }
  360. pkt->msg=0;
  361. if(pkt->hdr.sz) {
  362. /*let's get the body*/
  363. pkt->msg=xmalloc(pkt->hdr.sz);
  364. memcpy(pkt->msg, buf+sizeof(pkt_hdr), pkt->hdr.sz);
  365. }
  366. return err;
  367. }
  368. ssize_t pkt_recv_tcp(PACKET *pkt)
  369. {
  370. ssize_t err=-1;
  371. /* we get the hdr... */
  372. if(pkt->pkt_flags & PKT_RECV_TIMEOUT)
  373. err=inet_recv_timeout(pkt->sk, &pkt->hdr, sizeof(pkt_hdr),
  374. pkt->flags, pkt->timeout);
  375. else
  376. err=inet_recv(pkt->sk, &pkt->hdr, sizeof(pkt_hdr),
  377. pkt->flags);
  378. if(err != sizeof(pkt_hdr))
  379. return -1;
  380. /* ...and verify it */
  381. ints_network_to_host(&pkt->hdr, pkt_hdr_iinfo);
  382. if(pkt_verify_hdr(*pkt)) {
  383. debug(DBG_NOISE, RED(ERROR_MSG) "Malformed header", ERROR_POS);
  384. return -1;
  385. }
  386. pkt->msg=0;
  387. if(pkt->hdr.sz) {
  388. /* let's get the body */
  389. pkt->msg=xmalloc(pkt->hdr.sz);
  390. if(pkt->pkt_flags & PKT_RECV_TIMEOUT)
  391. err=inet_recv_timeout(pkt->sk, pkt->msg, pkt->hdr.sz,
  392. pkt->flags, pkt->timeout);
  393. else
  394. err=inet_recv(pkt->sk, pkt->msg, pkt->hdr.sz,
  395. pkt->flags);
  396. if(err != pkt->hdr.sz) {
  397. debug(DBG_NOISE, RED(ERROR_MSG) "Cannot recv the "
  398. "pkt's body", ERROR_FUNC);
  399. return -1;
  400. }
  401. }
  402. return err;
  403. }
  404. ssize_t pkt_recv(PACKET *pkt)
  405. {
  406. ssize_t err=-1;
  407. switch(pkt->sk_type) {
  408. case SKT_UDP:
  409. case SKT_BCAST:
  410. err=pkt_recv_udp(pkt);
  411. break;
  412. case SKT_TCP:
  413. err=pkt_recv_tcp(pkt);
  414. break;
  415. default:
  416. fatal("Unkown socket_type. Something's very wrong!! Be aware");
  417. break;
  418. }
  419. /* let's finish it */
  420. pkt_unpack(pkt);
  421. return err;
  422. }
  423. int pkt_tcp_connect(inet_prefix *host, short port, interface *dev)
  424. {
  425. int sk;
  426. PACKET pkt;
  427. const char *ntop;
  428. ssize_t err;
  429. ntop=inet_to_str(*host);
  430. setzero(&pkt, sizeof(PACKET));
  431. if((sk=new_tcp_conn(host, port, dev?dev->dev_name:0))==-1)
  432. goto finish;
  433. /*
  434. * Now we receive the first pkt from the server.
  435. * It is an ack.
  436. * Let's hope it isn't NEGATIVE (-_+)
  437. */
  438. pkt_addsk(&pkt, host->family, sk, SKT_TCP);
  439. pkt.flags=MSG_WAITALL;
  440. pkt_addport(&pkt, port);
  441. if((err=pkt_recv(&pkt)) < 0) {
  442. error("Connection to %s failed: it wasn't possible to receive "
  443. "the ACK", ntop);
  444. ERROR_FINISH(sk, -1, finish);
  445. }
  446. /* ...Last famous words */
  447. if(pkt.hdr.op != ACK_AFFERMATIVE) {
  448. u_char err;
  449. memcpy(&err, pkt.msg, pkt.hdr.sz);
  450. error("Cannot connect to %s:%d: %s",
  451. ntop, port, rq_strerror(err));
  452. ERROR_FINISH(sk, -1, finish);
  453. }
  454. finish:
  455. pkt_free(&pkt, 0);
  456. return sk;
  457. }
  458. void pkt_fill_hdr(pkt_hdr *hdr, u_char flags, int id, u_char op, size_t sz)
  459. {
  460. hdr->ntk_id[0]='n';
  461. hdr->ntk_id[1]='t';
  462. hdr->ntk_id[2]='k';
  463. hdr->id = !id ? rand() : id;
  464. hdr->flags = flags;
  465. hdr->op = op;
  466. hdr->sz = sz;
  467. }
  468. /*
  469. * add_pkt_op: Add the `exec_f' in the pkt_exec_functions array.
  470. * `op' must be add int the pkt_op_tbl if it is a request that will be
  471. * received or if it is an op that will be sent with send_rq().
  472. */
  473. void add_pkt_op(u_char op, char sk_type, u_short port, int (*exec_f)(PACKET pkt))
  474. {
  475. pkt_op_tbl[op].sk_type = sk_type;
  476. pkt_op_tbl[op].port = port;
  477. pkt_op_tbl[op].exec_func = exec_f;
  478. }
  479. /*
  480. * send_rq
  481. *
  482. * This functions send a `rq' request, with an id set to `rq_id', to
  483. * `pkt->to'.
  484. *
  485. * If `pkt->sk' is non zero, it will be used to send the request.
  486. * If `pkt->sk' is 0, it will create a new socket and connection to `pkt->to',
  487. * the new socket is stored in `pkt->sk'.
  488. *
  489. * If `pkt->hdr.sz` is > 0 it includes the `pkt->msg' in the packet otherwise
  490. * it will be NULL.
  491. *
  492. * If `rpkt' is not null it will receive and store the reply pkt in `rpkt'.
  493. *
  494. * If `check_ack' is set, send_rq checks the reply pkt ACK and its id; if the
  495. * test fails it gives an appropriate error message.
  496. *
  497. * If `rpkt' is not null send_rq confronts the OP of the received reply pkt
  498. * with `re'; if the test fails it gives an appropriate error message.
  499. *
  500. * If `pkt'->hdr.flags has the ASYNC_REPLY set, the `rpkt' will be received with
  501. * the pkt_queue, in this case, if `rpkt'->from is set to a valid ip, it will
  502. * be used to check the sender ip of the reply pkt.
  503. *
  504. * If `pkt'->dev is not null and the PKT_BIND_DEV flag is set in
  505. * `pkt'->pkt_flags, it will bind the socket of the outgoing/ingoing packet to
  506. * the device named `pkt'->dev->dev_name.
  507. *
  508. *
  509. * On failure a negative value is returned, otherwise 0.
  510. * The error values are defined in pkts.h.
  511. */
  512. int send_rq(PACKET *pkt, int pkt_flags, u_char rq, int rq_id, u_char re,
  513. int check_ack, PACKET *rpkt)
  514. {
  515. ssize_t err;
  516. int ret=0;
  517. const char *ntop=0;
  518. const u_char *rq_str=0, *re_str=0;
  519. inet_prefix *wanted_from=0;
  520. if(op_verify(rq)) {
  521. error("\"%s\" request/reply is not valid!", rq_str);
  522. return SEND_RQ_ERR_RQ;
  523. }
  524. rq_str = !re_verify(rq) ? re_to_str(rq) : rq_to_str(rq);
  525. if(re && re_verify(re)) {
  526. error("\"%s\" reply is not valid!", re_str);
  527. return SEND_RQ_ERR_RE;
  528. }
  529. ntop=inet_to_str(pkt->to);
  530. /* * * the request building process * * */
  531. if(check_ack)
  532. pkt->hdr.flags|=SEND_ACK;
  533. pkt_fill_hdr(&pkt->hdr, pkt->hdr.flags, rq_id, rq, pkt->hdr.sz);
  534. if(!pkt->hdr.sz)
  535. pkt->msg=0;
  536. if(!pkt->port) {
  537. if(!pkt_op_tbl[rq].port && !pkt->sk) {
  538. error("send_rq: The rq %s doesn't have an associated "
  539. "port.", rq_str);
  540. ERROR_FINISH(ret, SEND_RQ_ERR_PORT, finish);
  541. }
  542. pkt_addport(pkt, pkt_op_tbl[rq].port);
  543. }
  544. /* If the PKT_BIND_DEV flag is set we can use pkt->dev */
  545. pkt->dev = (pkt->pkt_flags & PKT_BIND_DEV) ? pkt->dev : 0;
  546. if(!pkt->sk_type)
  547. pkt->sk_type=pkt_op_tbl[rq].sk_type;
  548. if(!pkt->sk) {
  549. if(!pkt->to.family || !pkt->to.len) {
  550. error("pkt->to isn't set. I can't create the new connection");
  551. ERROR_FINISH(ret, SEND_RQ_ERR_TO, finish);
  552. }
  553. if(pkt->sk_type==SKT_TCP)
  554. pkt->sk=pkt_tcp_connect(&pkt->to, pkt->port, pkt->dev);
  555. else if(pkt->sk_type==SKT_UDP)
  556. pkt->sk=new_udp_conn(&pkt->to, pkt->port, pkt->dev->dev_name);
  557. else if(pkt->sk_type==SKT_BCAST) {
  558. if(!pkt->dev)
  559. fatal(RED(ERROR_MSG) "cannot broadcast the packet: "
  560. "device not specified", ERROR_FUNC);
  561. pkt->sk=new_bcast_conn(&pkt->to, pkt->port, pkt->dev->dev_idx);
  562. } else
  563. fatal("Unkown socket_type. Something's very wrong!! Be aware");
  564. if(pkt->sk==-1) {
  565. error("Couldn't connect to %s to launch the %s request", ntop, rq_str);
  566. ERROR_FINISH(ret, SEND_RQ_ERR_CONNECT, finish);
  567. }
  568. }
  569. /* Set the LOWDELAY TOS if necessary */
  570. if(pkt->pkt_flags & PKT_SET_LOWDELAY)
  571. set_tos_sk(pkt->sk, 1);
  572. if(pkt->pkt_flags & PKT_NONBLOCK)
  573. set_nonblock_sk(pkt->sk);
  574. /*Let's send the request*/
  575. err=pkt_send(pkt);
  576. if(err==-1) {
  577. error("Cannot send the %s request to %s:%d.", rq_str, ntop, pkt->port);
  578. ERROR_FINISH(ret, SEND_RQ_ERR_SEND, finish);
  579. }
  580. /*
  581. * * * the reply * *
  582. */
  583. if(rpkt) {
  584. if(rpkt->from.data[0] && rpkt->from.len) {
  585. wanted_from=&rpkt->from;
  586. ntop=inet_to_str(rpkt->from);
  587. }
  588. setzero(rpkt, sizeof(PACKET));
  589. pkt_addport(rpkt, pkt->port);
  590. pkt_addsk(rpkt, pkt->to.family, pkt->sk, pkt->sk_type);
  591. rpkt->flags=MSG_WAITALL;
  592. pkt_addtimeout(rpkt, pkt->timeout, pkt->pkt_flags&PKT_RECV_TIMEOUT,
  593. pkt->pkt_flags&PKT_SEND_TIMEOUT);
  594. if(pkt->pkt_flags & PKT_COMPRESSED)
  595. pkt_addcompress(rpkt);
  596. debug(DBG_NOISE, "Receiving reply for the %s request"
  597. " (id 0x%x)", rq_str, pkt->hdr.id);
  598. if(pkt->hdr.flags & ASYNC_REPLY) {
  599. pkt_queue *pq;
  600. /* Receive the pkt in the async way */
  601. err=pkt_q_wait_recv(pkt->hdr.id, wanted_from, rpkt, &pq);
  602. pkt_q_del(pq, 0);
  603. } else {
  604. if(pkt->sk_type==SKT_UDP) {
  605. inet_copy(&rpkt->from, &pkt->to);
  606. ntop=inet_to_str(rpkt->from);
  607. }
  608. /* Receive the pkt in the standard way */
  609. err=pkt_recv(rpkt);
  610. }
  611. if(err==-1) {
  612. error("Error while receving the reply for the %s request"
  613. " from %s.", rq_str, ntop);
  614. ERROR_FINISH(ret, SEND_RQ_ERR_RECV, finish);
  615. }
  616. if((rpkt->hdr.op == ACK_NEGATIVE) && check_ack) {
  617. u_char err_ack;
  618. memcpy(&err_ack, rpkt->msg, sizeof(u_char));
  619. error("%s failed. The node %s replied: %s", rq_str, ntop,
  620. rq_strerror(err_ack));
  621. ERROR_FINISH(ret, SEND_RQ_ERR_REPLY, finish);
  622. } else if(rpkt->hdr.op != re && check_ack) {
  623. error("The node %s replied %s but we asked %s!", ntop,
  624. re_to_str(rpkt->hdr.op), re_str);
  625. ERROR_FINISH(ret, SEND_RQ_ERR_RECVOP, finish);
  626. }
  627. if(check_ack && rpkt->hdr.id != pkt->hdr.id) {
  628. error("The id (0x%x) of the reply (%s) doesn't match the"
  629. " id of our request (0x%x)", rpkt->hdr.id,
  630. re_str, pkt->hdr.id);
  631. ERROR_FINISH(ret, SEND_RQ_ERR_RECVID, finish);
  632. }
  633. }
  634. finish:
  635. return ret;
  636. }
  637. /*
  638. * forward_pkt: forwards the received packet `rpkt' to `to'.
  639. */
  640. int forward_pkt(PACKET rpkt, inet_prefix to)
  641. {
  642. int err;
  643. rpkt.sk=0; /* create a new connection */
  644. pkt_addto(&rpkt, &to);
  645. err=send_rq(&rpkt, 0, rpkt.hdr.op, rpkt.hdr.id, 0, 0, 0);
  646. if(!err)
  647. inet_close(&rpkt.sk);
  648. return err;
  649. }
  650. /*
  651. * pkt_err: Sends back to "pkt.from" an error pkt, with ACK_NEGATIVE,
  652. * containing the "err" code.
  653. * If `free_pkt' is not 0, `pkt' will be freed.
  654. */
  655. int pkt_err(PACKET pkt, u_char err, int free_pkt)
  656. {
  657. char *msg;
  658. u_char flags=0;
  659. pkt_addto(&pkt, &pkt.from);
  660. if(pkt.hdr.flags & ASYNC_REPLY) {
  661. flags|=ASYNC_REPLIED;
  662. pkt.sk=0;
  663. }
  664. /* It's useless to compress this pkt */
  665. pkt.pkt_flags&=~PKT_COMPRESSED;
  666. pkt_fill_hdr(&pkt.hdr, flags, pkt.hdr.id, ACK_NEGATIVE, sizeof(u_char));
  667. pkt.msg=msg=xmalloc(sizeof(u_char));
  668. memcpy(msg, &err, sizeof(u_char));
  669. err=send_rq(&pkt, 0, ACK_NEGATIVE, pkt.hdr.id, 0, 0, 0);
  670. if(pkt.hdr.flags & ASYNC_REPLY)
  671. pkt_free(&pkt, 1);
  672. else
  673. pkt_free(&pkt, 0);
  674. return err;
  675. }
  676. /*
  677. * pkt_exec
  678. *
  679. * It "executes" the received `pkt' passing it to the function which associated
  680. * to `pkt'.hdr.op.
  681. *
  682. * `acpt_idx' is the accept table index of the connection where the pkt was
  683. * received.
  684. */
  685. int pkt_exec(PACKET pkt, int acpt_idx)
  686. {
  687. const char *ntop;
  688. const u_char *op_str;
  689. int (*exec_f)(PACKET pkt);
  690. int err=0;
  691. if(!re_verify(pkt.hdr.op))
  692. op_str=re_to_str(pkt.hdr.op);
  693. else if(!rq_verify(pkt.hdr.op))
  694. op_str=rq_to_str(pkt.hdr.op);
  695. else {
  696. debug(DBG_SOFT, "Dropped pkt from %s: bad op value",
  697. inet_to_str(pkt.from));
  698. return -1; /* bad op */
  699. }
  700. if((err=add_rq(pkt.hdr.op, &accept_tbl[acpt_idx].rqtbl))) {
  701. ntop=inet_to_str(pkt.from);
  702. error("From %s: Cannot process the %s request: %s", ntop,
  703. op_str, rq_strerror(err));
  704. pkt_err(pkt, err, 1);
  705. return -1;
  706. }
  707. if(op_filter_test(pkt.hdr.op)) {
  708. /* Drop the pkt, `pkt.hdr.op' has been filtered */
  709. #ifdef DEBUG
  710. ntop=inet_to_str(pkt.from);
  711. debug(DBG_INSANE, "FILTERED %s from %s, id 0x%x", op_str, ntop,
  712. pkt.hdr.id);
  713. #endif
  714. return err;
  715. }
  716. /* Call the function associated to `pkt.hdr.op' */
  717. exec_f = pkt_op_tbl[pkt.hdr.op].exec_func;
  718. #ifdef DEBUG
  719. if(pkt.hdr.op != ECHO_ME && pkt.hdr.op != ECHO_REPLY) {
  720. ntop=inet_to_str(pkt.from);
  721. debug(DBG_INSANE, "Received %s from %s, id 0x%x", op_str, ntop,
  722. pkt.hdr.id);
  723. }
  724. #endif
  725. if(exec_f)
  726. err=(*exec_f)(pkt);
  727. else if(pkt_q_counter) {
  728. debug(DBG_INSANE, "pkt_exec: %s Async reply, id 0x%x", op_str,
  729. pkt.hdr.id);
  730. /*
  731. * There isn't a function to handle this pkt, so maybe it is
  732. * an async reply
  733. */
  734. pkt_q_add_pkt(pkt);
  735. }
  736. return err;
  737. }
  738. /*
  739. * * * Pkt queue functions * * *
  740. */
  741. pthread_attr_t wait_and_unlock_attr;
  742. void pkt_queue_init(void)
  743. {
  744. pkt_q=(pkt_queue *)clist_init(&pkt_q_counter);
  745. pthread_attr_init(&wait_and_unlock_attr);
  746. pthread_attr_setdetachstate(&wait_and_unlock_attr, PTHREAD_CREATE_DETACHED);
  747. }
  748. void pkt_queue_close(void)
  749. {
  750. pkt_queue *pq=pkt_q, *next;
  751. if(pkt_q_counter)
  752. list_safe_for(pq, next)
  753. pkt_q_del(pq, 1);
  754. pthread_attr_destroy(&wait_and_unlock_attr);
  755. }
  756. /*
  757. * wait_and_unlock
  758. *
  759. * It waits REQUEST_TIMEOUT seconds, then it unlocks `pq'->mtx.
  760. * This prevents the dead lock in pkt_q_wait_recv()
  761. */
  762. void *wait_and_unlock(void *m)
  763. {
  764. pkt_queue *pq, **pq_ptr;
  765. int i;
  766. pq_ptr=(pkt_queue **)m;
  767. pq=*pq_ptr;
  768. if(!pq)
  769. return 0;
  770. for(i=0; i<REQUEST_TIMEOUT; i++) {
  771. sleep(1);
  772. if(!(*pq_ptr) || (pq->flags & PKT_Q_PKT_RECEIVED) ||
  773. !(pq->flags & PKT_Q_MTX_LOCKED) ||
  774. pthread_mutex_trylock(&pq->mtx) != EBUSY)
  775. break;
  776. }
  777. if(!(*pq_ptr) || (pq->flags & PKT_Q_PKT_RECEIVED) ||
  778. !(pq->flags & PKT_Q_MTX_LOCKED) ||
  779. pthread_mutex_trylock(&pq->mtx) != EBUSY)
  780. goto finish;
  781. debug(DBG_INSANE, "pq->pkt.hdr.id: 0x%x Timeoutted. mtx: 0x%X", pq->pkt.hdr.id, &pq->mtx);
  782. pthread_mutex_unlock(&pq->mtx);
  783. pq->flags|=PKT_Q_TIMEOUT;
  784. finish:
  785. if(pq_ptr)
  786. xfree(pq_ptr);
  787. return 0;
  788. }
  789. /*
  790. * pkt_q_wait_recv
  791. *
  792. * adds a new struct in pkt_q and waits REQUEST_TIMEOUT
  793. * seconds until a reply with an id equal to `id' is received.
  794. * If `from' is not null, the sender ip of the reply is considered too.
  795. * The received reply pkt is copied in `rpkt' (if `rpkt' isn't null).
  796. * In `ret_pq' is stored the address of the pkt_queue struct that
  797. * corresponds to `rpkt'.
  798. * After the use of this function pkt_q_del() must be called.
  799. * On error -1 is returned.
  800. */
  801. int pkt_q_wait_recv(int id, inet_prefix *from, PACKET *rpkt, pkt_queue **ret_pq)
  802. {
  803. pthread_t thread;
  804. pkt_queue *pq, **pq_ptr;
  805. pq=xzalloc(sizeof(pkt_queue));
  806. pq_ptr=xmalloc(sizeof(pkt_queue *));
  807. *pq_ptr=pq;
  808. pthread_mutex_init(&pq->mtx, 0);
  809. pq->flags|=PKT_Q_MTX_LOCKED;
  810. *ret_pq=pq;
  811. if(!pkt_q_counter)
  812. pkt_queue_init();
  813. pq->pkt.hdr.id=id;
  814. if(from) {
  815. debug(DBG_INSANE, "0x%x wanted_rfrom %s activated", id,
  816. inet_to_str(*from));
  817. inet_copy(&pq->pkt.from, from);
  818. pq->flags|=PKT_Q_CHECK_FROM;
  819. }
  820. clist_add(&pkt_q, &pkt_q_counter, pq);
  821. /* Be sure to unlock me after the timeout */
  822. pthread_create(&thread, &wait_and_unlock_attr, wait_and_unlock,
  823. (void *)pq_ptr);
  824. if(pq->flags & PKT_Q_MTX_LOCKED) {
  825. debug(DBG_INSANE, "pkt_q_wait_recv: Locking 0x%x!", &pq->mtx);
  826. /* Freeze! */
  827. pthread_mutex_lock(&pq->mtx);
  828. pthread_mutex_lock(&pq->mtx);
  829. }
  830. debug(DBG_INSANE, "We've been unlocked: timeout %d", (pq->flags & PKT_Q_TIMEOUT));
  831. if(pq->flags & PKT_Q_TIMEOUT)
  832. return -1;
  833. if(rpkt)
  834. pkt_copy(rpkt, &pq->pkt);
  835. /* When *pq_ptr is set to 0, the wait_and_unlock thread exits */
  836. *pq_ptr=0;
  837. return 0;
  838. }
  839. /*
  840. * pkt_q_add_pkt: Copy the reply pkt in the struct of pkt_q which has the same
  841. * hdr.id, then unlock the mutex of the pkt_q struct.
  842. * If the struct in pkt_q isn't found, -1 is returned.
  843. */
  844. int pkt_q_add_pkt(PACKET pkt)
  845. {
  846. pkt_queue *pq=pkt_q, *next=0;
  847. int ret=-1;
  848. list_safe_for(pq, next) {
  849. debug(DBG_INSANE, "pkt_q_add_pkt: %d == %d. data[0]: %d, async replied: %d",
  850. pq->pkt.hdr.id, pkt.hdr.id, pq->pkt.from.data[0],
  851. (pkt.hdr.flags & ASYNC_REPLIED));
  852. if(pq->pkt.hdr.id == pkt.hdr.id) {
  853. if(pq->pkt.from.data[0] && (pq->flags & PKT_Q_CHECK_FROM) &&
  854. memcmp(pq->pkt.from.data, pkt.from.data, MAX_IP_SZ))
  855. continue; /* The wanted from ip and the
  856. real from ip don't match */
  857. if(!(pkt.hdr.flags & ASYNC_REPLIED))
  858. continue;
  859. pkt_copy(&pq->pkt, &pkt);
  860. /* Now it's possible to read the reply,
  861. * pkt_q_wait_recv() is now hot again */
  862. while(pthread_mutex_trylock(&pq->mtx) != EBUSY)
  863. usleep(5000);
  864. debug(DBG_INSANE, "pkt_q_add_pkt: Unlocking 0x%X ", &pq->mtx);
  865. pq->flags&=~PKT_Q_MTX_LOCKED & ~PKT_Q_TIMEOUT;
  866. pq->flags|=PKT_Q_PKT_RECEIVED;
  867. pthread_mutex_unlock(&pq->mtx);
  868. pthread_mutex_unlock(&pq->mtx);
  869. ret=0;
  870. }
  871. }
  872. return ret;
  873. }
  874. /*
  875. * pkt_q_del: Deletes `pq' from the pkt_q llist and frees the `pq' struct. The
  876. * `pq'->pkt is also freed and the pq->pkt.sk socket is closed if `close_socket'
  877. * is non zero.
  878. */
  879. void pkt_q_del(pkt_queue *pq, int close_socket)
  880. {
  881. pthread_mutex_unlock(&pq->mtx);
  882. pthread_mutex_destroy(&pq->mtx);
  883. pkt_free(&pq->pkt, close_socket);
  884. clist_del(&pkt_q, &pkt_q_counter, pq);
  885. }