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.

util.c 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035
  1. /* Copyright (c) 2014, Vsevolod Stakhov
  2. * All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. * * Redistributions of source code must retain the above copyright
  7. * notice, this list of conditions and the following disclaimer.
  8. * * Redistributions in binary form must reproduce the above copyright
  9. * notice, this list of conditions and the following disclaimer in the
  10. * documentation and/or other materials provided with the distribution.
  11. *
  12. * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
  13. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  14. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  15. * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
  16. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  17. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  18. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  19. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  20. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  21. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22. */
  23. #include <sys/socket.h>
  24. #include <netinet/in.h>
  25. #include <arpa/inet.h>
  26. #include <sys/un.h>
  27. #include <sys/stat.h>
  28. #include <unistd.h>
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <errno.h>
  33. #include <netdb.h>
  34. #include <fcntl.h>
  35. #include <ctype.h>
  36. #include "ottery.h"
  37. #include "util.h"
  38. #include "logger.h"
  39. #include "rdns.h"
  40. inline void
  41. rdns_request_remove_from_hash (struct rdns_request *req)
  42. {
  43. /* Remove from id hashes */
  44. if (req->io) {
  45. khiter_t k;
  46. k = kh_get(rdns_requests_hash, req->io->requests, req->id);
  47. if (k != kh_end(req->io->requests)) {
  48. kh_del(rdns_requests_hash, req->io->requests, k);
  49. }
  50. }
  51. }
  52. static int
  53. rdns_make_socket_nonblocking (int fd)
  54. {
  55. int ofl;
  56. ofl = fcntl (fd, F_GETFL, 0);
  57. if (fcntl (fd, F_SETFL, ofl | O_NONBLOCK) == -1) {
  58. return -1;
  59. }
  60. return 0;
  61. }
  62. static int
  63. rdns_make_inet_socket (int type, struct addrinfo *addr, struct sockaddr **psockaddr,
  64. socklen_t *psocklen)
  65. {
  66. int fd = -1;
  67. struct addrinfo *cur;
  68. cur = addr;
  69. while (cur) {
  70. /* Create socket */
  71. fd = socket (cur->ai_family, type, 0);
  72. if (fd == -1) {
  73. goto out;
  74. }
  75. if (rdns_make_socket_nonblocking (fd) < 0) {
  76. goto out;
  77. }
  78. /* Set close on exec */
  79. if (fcntl (fd, F_SETFD, FD_CLOEXEC) == -1) {
  80. goto out;
  81. }
  82. if (psockaddr) {
  83. *psockaddr = cur->ai_addr;
  84. *psocklen = cur->ai_addrlen;
  85. }
  86. break;
  87. out:
  88. if (fd != -1) {
  89. close (fd);
  90. }
  91. fd = -1;
  92. cur = cur->ai_next;
  93. }
  94. return (fd);
  95. }
  96. static int
  97. rdns_make_unix_socket (const char *path, struct sockaddr_un *addr, int type)
  98. {
  99. int fd = -1, serrno;
  100. if (path == NULL) {
  101. return -1;
  102. }
  103. addr->sun_family = AF_UNIX;
  104. memset (addr->sun_path, 0, sizeof (addr->sun_path));
  105. memccpy (addr->sun_path, path, 0, sizeof (addr->sun_path) - 1);
  106. #ifdef FREEBSD
  107. addr->sun_len = SUN_LEN (addr);
  108. #endif
  109. fd = socket (PF_LOCAL, type, 0);
  110. if (fd == -1) {
  111. return -1;
  112. }
  113. if (rdns_make_socket_nonblocking (fd) < 0) {
  114. goto out;
  115. }
  116. /* Set close on exec */
  117. if (fcntl (fd, F_SETFD, FD_CLOEXEC) == -1) {
  118. goto out;
  119. }
  120. return (fd);
  121. out:
  122. serrno = errno;
  123. if (fd != -1) {
  124. close (fd);
  125. }
  126. errno = serrno;
  127. return (-1);
  128. }
  129. /**
  130. * Make a universal socket
  131. * @param credits host, ip or path to unix socket
  132. * @param port port (used for network sockets)
  133. * @param async make this socket asynced
  134. * @param is_server make this socket as server socket
  135. * @param try_resolve try name resolution for a socket (BLOCKING)
  136. */
  137. int
  138. rdns_make_client_socket (const char *credits,
  139. uint16_t port,
  140. int type,
  141. struct sockaddr **psockaddr,
  142. socklen_t *psocklen)
  143. {
  144. struct sockaddr_un un;
  145. struct stat st;
  146. struct addrinfo hints, *res;
  147. int r;
  148. char portbuf[8];
  149. if (*credits == '/') {
  150. r = stat (credits, &st);
  151. if (r == -1) {
  152. /* Unix socket doesn't exists it must be created first */
  153. errno = ENOENT;
  154. return -1;
  155. }
  156. else {
  157. if ((st.st_mode & S_IFSOCK) == 0) {
  158. /* Path is not valid socket */
  159. errno = EINVAL;
  160. return -1;
  161. }
  162. else {
  163. r = rdns_make_unix_socket (credits, &un, type);
  164. if (r != -1 && psockaddr) {
  165. struct sockaddr *cpy;
  166. cpy = calloc (1, sizeof (un));
  167. *psocklen = sizeof (un);
  168. if (cpy == NULL) {
  169. close (r);
  170. return -1;
  171. }
  172. memcpy (cpy, &un, *psocklen);
  173. *psockaddr = cpy;
  174. }
  175. return r;
  176. }
  177. }
  178. }
  179. else {
  180. /* TCP related part */
  181. memset (&hints, 0, sizeof (hints));
  182. hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
  183. hints.ai_socktype = type; /* Type of the socket */
  184. hints.ai_flags = 0;
  185. hints.ai_protocol = 0; /* Any protocol */
  186. hints.ai_canonname = NULL;
  187. hints.ai_addr = NULL;
  188. hints.ai_next = NULL;
  189. hints.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV;
  190. snprintf (portbuf, sizeof (portbuf), "%d", (int)port);
  191. if (getaddrinfo (credits, portbuf, &hints, &res) == 0) {
  192. r = rdns_make_inet_socket (type, res, psockaddr, psocklen);
  193. if (r != -1 && psockaddr) {
  194. struct sockaddr *cpy;
  195. cpy = calloc (1, *psocklen);
  196. if (cpy == NULL) {
  197. close (r);
  198. freeaddrinfo (res);
  199. return -1;
  200. }
  201. memcpy (cpy, *psockaddr, *psocklen);
  202. *psockaddr = cpy;
  203. }
  204. freeaddrinfo (res);
  205. return r;
  206. }
  207. else {
  208. return -1;
  209. }
  210. }
  211. /* Not reached */
  212. return -1;
  213. }
  214. const char *
  215. rdns_strerror (enum dns_rcode rcode)
  216. {
  217. rcode &= 0xf;
  218. static char numbuf[16];
  219. if ('\0' == dns_rcodes[rcode][0]) {
  220. snprintf (numbuf, sizeof (numbuf), "UNKNOWN: %d", (int)rcode);
  221. return numbuf;
  222. }
  223. return dns_rcodes[rcode];
  224. }
  225. const char *
  226. rdns_strtype (enum rdns_request_type type)
  227. {
  228. return dns_types[type];
  229. }
  230. enum rdns_request_type
  231. rdns_type_fromstr (const char *str)
  232. {
  233. if (str) {
  234. if (strcmp (str, "a") == 0) {
  235. return RDNS_REQUEST_A;
  236. }
  237. else if (strcmp (str, "ns") == 0) {
  238. return RDNS_REQUEST_NS;
  239. }
  240. else if (strcmp (str, "soa") == 0) {
  241. return RDNS_REQUEST_SOA;
  242. }
  243. else if (strcmp (str, "ptr") == 0) {
  244. return RDNS_REQUEST_PTR;
  245. }
  246. else if (strcmp (str, "mx") == 0) {
  247. return RDNS_REQUEST_MX;
  248. }
  249. else if (strcmp (str, "srv") == 0) {
  250. return RDNS_REQUEST_SRV;
  251. }
  252. else if (strcmp (str, "txt") == 0) {
  253. return RDNS_REQUEST_TXT;
  254. }
  255. else if (strcmp (str, "spf") == 0) {
  256. return RDNS_REQUEST_SPF;
  257. }
  258. else if (strcmp (str, "aaaa") == 0) {
  259. return RDNS_REQUEST_AAAA;
  260. }
  261. else if (strcmp (str, "tlsa") == 0) {
  262. return RDNS_REQUEST_TLSA;
  263. }
  264. else if (strcmp (str, "cname") == 0) {
  265. return RDNS_REQUEST_CNAME;
  266. }
  267. else if (strcmp (str, "any") == 0) {
  268. return RDNS_REQUEST_ANY;
  269. }
  270. }
  271. return RDNS_REQUEST_INVALID;
  272. }
  273. const char *
  274. rdns_str_from_type (enum rdns_request_type rcode)
  275. {
  276. switch (rcode) {
  277. case RDNS_REQUEST_INVALID:
  278. return "(invalid)";
  279. case RDNS_REQUEST_A:
  280. return "a";
  281. case RDNS_REQUEST_NS:
  282. return "ns";
  283. case RDNS_REQUEST_SOA:
  284. return "soa";
  285. case RDNS_REQUEST_PTR:
  286. return "ptr";
  287. case RDNS_REQUEST_MX:
  288. return "mx";
  289. case RDNS_REQUEST_TXT:
  290. return "txt";
  291. case RDNS_REQUEST_SRV:
  292. return "srv";
  293. case RDNS_REQUEST_SPF:
  294. return "spf";
  295. case RDNS_REQUEST_AAAA:
  296. return "aaaa";
  297. case RDNS_REQUEST_TLSA:
  298. return "tlsa";
  299. case RDNS_REQUEST_CNAME:
  300. return "cname";
  301. case RDNS_REQUEST_ANY:
  302. return "any";
  303. default:
  304. return "(unknown)";
  305. }
  306. }
  307. enum dns_rcode
  308. rdns_rcode_fromstr (const char *str)
  309. {
  310. if (str) {
  311. if (strcmp (str, "noerror") == 0) {
  312. return RDNS_RC_NOERROR;
  313. }
  314. else if (strcmp (str, "formerr") == 0) {
  315. return RDNS_RC_FORMERR;
  316. }
  317. else if (strcmp (str, "servfail") == 0) {
  318. return RDNS_RC_SERVFAIL;
  319. }
  320. else if (strcmp (str, "nxdomain") == 0) {
  321. return RDNS_RC_NXDOMAIN;
  322. }
  323. else if (strcmp (str, "notimp") == 0) {
  324. return RDNS_RC_NOTIMP;
  325. }
  326. else if (strcmp (str, "yxdomain") == 0) {
  327. return RDNS_RC_YXDOMAIN;
  328. }
  329. else if (strcmp (str, "yxrrset") == 0) {
  330. return RDNS_RC_YXRRSET;
  331. }
  332. else if (strcmp (str, "nxrrset") == 0) {
  333. return RDNS_RC_NXRRSET;
  334. }
  335. else if (strcmp (str, "notauth") == 0) {
  336. return RDNS_RC_NOTAUTH;
  337. }
  338. else if (strcmp (str, "notzone") == 0) {
  339. return RDNS_RC_NOTZONE;
  340. }
  341. else if (strcmp (str, "timeout") == 0) {
  342. return RDNS_RC_TIMEOUT;
  343. }
  344. else if (strcmp (str, "neterr") == 0) {
  345. return RDNS_RC_NETERR;
  346. }
  347. else if (strcmp (str, "norec") == 0) {
  348. return RDNS_RC_NOREC;
  349. }
  350. }
  351. return RDNS_RC_INVALID;
  352. }
  353. uint16_t
  354. rdns_permutor_generate_id (void)
  355. {
  356. uint16_t id;
  357. id = ottery_rand_unsigned ();
  358. return id;
  359. }
  360. struct rdns_reply *
  361. rdns_make_reply (struct rdns_request *req, enum dns_rcode rcode)
  362. {
  363. struct rdns_reply *rep;
  364. rep = malloc (sizeof (struct rdns_reply));
  365. if (rep != NULL) {
  366. rep->request = req;
  367. rep->resolver = req->resolver;
  368. rep->entries = NULL;
  369. rep->code = rcode;
  370. req->reply = rep;
  371. rep->flags = 0;
  372. rep->requested_name = req->requested_names[0].name;
  373. }
  374. return rep;
  375. }
  376. void
  377. rdns_reply_free (struct rdns_reply *rep)
  378. {
  379. struct rdns_reply_entry *entry, *tmp;
  380. /* We don't need to free data for faked replies */
  381. if (!rep->request || rep->request->state != RDNS_REQUEST_FAKE) {
  382. LL_FOREACH_SAFE (rep->entries, entry, tmp) {
  383. switch (entry->type) {
  384. case RDNS_REQUEST_PTR:
  385. free (entry->content.ptr.name);
  386. break;
  387. case RDNS_REQUEST_NS:
  388. free (entry->content.ns.name);
  389. break;
  390. case RDNS_REQUEST_MX:
  391. free (entry->content.mx.name);
  392. break;
  393. case RDNS_REQUEST_TXT:
  394. case RDNS_REQUEST_SPF:
  395. free (entry->content.txt.data);
  396. break;
  397. case RDNS_REQUEST_SRV:
  398. free (entry->content.srv.target);
  399. break;
  400. case RDNS_REQUEST_TLSA:
  401. free (entry->content.tlsa.data);
  402. break;
  403. case RDNS_REQUEST_SOA:
  404. free (entry->content.soa.mname);
  405. free (entry->content.soa.admin);
  406. break;
  407. case RDNS_REQUEST_CNAME:
  408. free(entry->content.cname.name);
  409. break;
  410. default:
  411. break;
  412. }
  413. free (entry);
  414. }
  415. }
  416. free (rep);
  417. }
  418. void
  419. rdns_request_free (struct rdns_request *req)
  420. {
  421. unsigned int i;
  422. if (req != NULL) {
  423. if (req->packet != NULL) {
  424. free (req->packet);
  425. }
  426. for (i = 0; i < req->qcount; i ++) {
  427. free (req->requested_names[i].name);
  428. }
  429. if (req->requested_names != NULL) {
  430. free (req->requested_names);
  431. }
  432. if (req->reply != NULL) {
  433. rdns_reply_free (req->reply);
  434. }
  435. if (req->async_event) {
  436. if (req->state == RDNS_REQUEST_WAIT_REPLY) {
  437. /* Remove timer */
  438. req->async->del_timer (req->async->data,
  439. req->async_event);
  440. rdns_request_remove_from_hash(req);
  441. req->async_event = NULL;
  442. }
  443. else if (req->state == RDNS_REQUEST_WAIT_SEND) {
  444. /* Remove retransmit event */
  445. req->async->del_write (req->async->data,
  446. req->async_event);
  447. rdns_request_remove_from_hash(req);
  448. req->async_event = NULL;
  449. }
  450. else if (req->state == RDNS_REQUEST_FAKE) {
  451. req->async->del_write (req->async->data,
  452. req->async_event);
  453. req->async_event = NULL;
  454. }
  455. }
  456. if (req->state == RDNS_REQUEST_TCP) {
  457. if (req->async_event) {
  458. req->async->del_timer (req->async->data,
  459. req->async_event);
  460. }
  461. rdns_request_remove_from_hash(req);
  462. }
  463. #ifdef TWEETNACL
  464. if (req->curve_plugin_data != NULL) {
  465. req->resolver->curve_plugin->cb.curve_plugin.finish_cb (
  466. req, req->resolver->curve_plugin->data);
  467. }
  468. #endif
  469. if (req->io != NULL && req->state > RDNS_REQUEST_NEW) {
  470. REF_RELEASE (req->io);
  471. REF_RELEASE (req->resolver);
  472. }
  473. free (req);
  474. }
  475. }
  476. void
  477. rdns_ioc_free (struct rdns_io_channel *ioc)
  478. {
  479. struct rdns_request *req;
  480. if (IS_CHANNEL_TCP(ioc)) {
  481. rdns_ioc_tcp_reset(ioc);
  482. }
  483. kh_foreach_value(ioc->requests, req, {
  484. REF_RELEASE (req);
  485. });
  486. if (ioc->async_io) {
  487. ioc->resolver->async->del_read(ioc->resolver->async->data,
  488. ioc->async_io);
  489. }
  490. kh_destroy(rdns_requests_hash, ioc->requests);
  491. if (ioc->sock != -1) {
  492. close(ioc->sock);
  493. }
  494. if (ioc->saddr != NULL) {
  495. free(ioc->saddr);
  496. }
  497. free (ioc);
  498. }
  499. struct rdns_io_channel *
  500. rdns_ioc_new (struct rdns_server *serv,
  501. struct rdns_resolver *resolver,
  502. bool is_tcp)
  503. {
  504. struct rdns_io_channel *nioc;
  505. if (is_tcp) {
  506. nioc = calloc (1, sizeof (struct rdns_io_channel)
  507. + sizeof (struct rdns_tcp_channel));
  508. }
  509. else {
  510. nioc = calloc (1, sizeof (struct rdns_io_channel));
  511. }
  512. if (nioc == NULL) {
  513. rdns_err ("calloc fails to allocate rdns_io_channel");
  514. return NULL;
  515. }
  516. nioc->struct_magic = RDNS_IO_CHANNEL_TAG;
  517. nioc->srv = serv;
  518. nioc->resolver = resolver;
  519. nioc->sock = rdns_make_client_socket (serv->name, serv->port,
  520. is_tcp ? SOCK_STREAM : SOCK_DGRAM, &nioc->saddr, &nioc->slen);
  521. if (nioc->sock == -1) {
  522. rdns_err ("cannot open socket to %s: %s", serv->name,
  523. strerror (errno));
  524. free (nioc);
  525. return NULL;
  526. }
  527. if (is_tcp) {
  528. /* We also need to connect a TCP channel and set a TCP buffer */
  529. nioc->tcp = (struct rdns_tcp_channel *)(((unsigned char *)nioc) + sizeof(*nioc));
  530. if (!rdns_ioc_tcp_connect(nioc)) {
  531. rdns_err ("cannot connect TCP socket to %s: %s", serv->name,
  532. strerror (errno));
  533. close (nioc->sock);
  534. free (nioc);
  535. return NULL;
  536. }
  537. nioc->flags |= RDNS_CHANNEL_TCP;
  538. }
  539. else {
  540. nioc->flags |= RDNS_CHANNEL_ACTIVE;
  541. nioc->async_io = resolver->async->add_read(resolver->async->data,
  542. nioc->sock, nioc);
  543. }
  544. nioc->requests = kh_init(rdns_requests_hash);
  545. REF_INIT_RETAIN (nioc, rdns_ioc_free);
  546. return nioc;
  547. }
  548. void
  549. rdns_resolver_release (struct rdns_resolver *resolver)
  550. {
  551. REF_RELEASE (resolver);
  552. }
  553. struct rdns_request*
  554. rdns_request_retain (struct rdns_request *req)
  555. {
  556. REF_RETAIN (req);
  557. return req;
  558. }
  559. void
  560. rdns_request_unschedule (struct rdns_request *req, bool remove_from_hash)
  561. {
  562. struct rdns_resolver *resolver = req->resolver;
  563. switch (req->state) {
  564. case RDNS_REQUEST_WAIT_REPLY:
  565. /* We have a timer pending */
  566. if (req->async_event) {
  567. req->async->del_timer (req->async->data,
  568. req->async_event);
  569. if (remove_from_hash) {
  570. rdns_request_remove_from_hash(req);
  571. }
  572. req->async_event = NULL;
  573. }
  574. break;
  575. case RDNS_REQUEST_WAIT_SEND:
  576. /* We have write request pending */
  577. if (req->async_event) {
  578. req->async->del_write (req->async->data,
  579. req->async_event);
  580. /* Remove from id hashes */
  581. if (remove_from_hash) {
  582. rdns_request_remove_from_hash(req);
  583. }
  584. req->async_event = NULL;
  585. }
  586. break;
  587. case RDNS_REQUEST_TCP:
  588. /* We also have a timer */
  589. if (req->async_event) {
  590. if (remove_from_hash) {
  591. rdns_request_remove_from_hash(req);
  592. }
  593. req->async->del_timer(req->async->data,
  594. req->async_event);
  595. req->async_event = NULL;
  596. }
  597. default:
  598. /* Nothing to unschedule, so blame if we have any event pending */
  599. if (req->async_event) {
  600. rdns_err("internal error: have unexpected pending async state on stage %d",
  601. req->state);
  602. }
  603. break;
  604. }
  605. }
  606. void
  607. rdns_request_release (struct rdns_request *req)
  608. {
  609. rdns_request_unschedule (req, true);
  610. REF_RELEASE (req);
  611. }
  612. void
  613. rdns_ioc_tcp_reset (struct rdns_io_channel *ioc)
  614. {
  615. struct rdns_resolver *resolver = ioc->resolver;
  616. if (IS_CHANNEL_CONNECTED(ioc)) {
  617. if (ioc->tcp->async_write) {
  618. resolver->async->del_write (resolver->async->data, ioc->tcp->async_write);
  619. ioc->tcp->async_write = NULL;
  620. }
  621. if (ioc->tcp->async_read) {
  622. resolver->async->del_read (resolver->async->data, ioc->tcp->async_read);
  623. ioc->tcp->async_read = NULL;
  624. }
  625. /* Clean all buffers and temporaries */
  626. if (ioc->tcp->cur_read_buf) {
  627. free (ioc->tcp->cur_read_buf);
  628. ioc->tcp->read_buf_allocated = 0;
  629. ioc->tcp->next_read_size = 0;
  630. ioc->tcp->cur_read = 0;
  631. ioc->tcp->cur_read_buf = NULL;
  632. }
  633. struct rdns_tcp_output_chain *oc, *tmp;
  634. DL_FOREACH_SAFE(ioc->tcp->output_chain, oc, tmp) {
  635. DL_DELETE (ioc->tcp->output_chain, oc);
  636. free (oc);
  637. }
  638. ioc->tcp->cur_output_chains = 0;
  639. ioc->tcp->output_chain = NULL;
  640. ioc->flags &= ~RDNS_CHANNEL_CONNECTED;
  641. }
  642. /* Remove all requests pending as we are unable to complete them */
  643. struct rdns_request *req;
  644. kh_foreach_value(ioc->requests, req, {
  645. struct rdns_reply *rep = rdns_make_reply (req, RDNS_RC_NETERR);
  646. /*
  647. * Unschedule request explicitly as we set state to RDNS_REQUEST_REPLIED
  648. * that will prevent timer from being removed on req dtor.
  649. *
  650. * We skip hash removal here, as the hash will be cleared as a single
  651. * operation afterwards.
  652. */
  653. rdns_request_unschedule(req, false);
  654. req->state = RDNS_REQUEST_REPLIED;
  655. req->func (rep, req->arg);
  656. REF_RELEASE (req);
  657. });
  658. if (ioc->sock != -1) {
  659. close (ioc->sock);
  660. ioc->sock = -1;
  661. }
  662. if (ioc->saddr) {
  663. free (ioc->saddr);
  664. ioc->saddr = NULL;
  665. }
  666. kh_clear(rdns_requests_hash, ioc->requests);
  667. }
  668. bool
  669. rdns_ioc_tcp_connect (struct rdns_io_channel *ioc)
  670. {
  671. struct rdns_resolver *resolver = ioc->resolver;
  672. if (IS_CHANNEL_CONNECTED(ioc)) {
  673. rdns_err ("trying to connect already connected IO channel!");
  674. return false;
  675. }
  676. if (ioc->flags & RDNS_CHANNEL_TCP_CONNECTING) {
  677. /* Already connecting channel, ignore connect request */
  678. return true;
  679. }
  680. if (ioc->sock == -1) {
  681. ioc->sock = rdns_make_client_socket (ioc->srv->name, ioc->srv->port,
  682. SOCK_STREAM, &ioc->saddr, &ioc->slen);
  683. if (ioc->sock == -1) {
  684. rdns_err ("cannot open socket to %s: %s", ioc->srv->name,
  685. strerror (errno));
  686. if (ioc->saddr) {
  687. free (ioc->saddr);
  688. ioc->saddr = NULL;
  689. }
  690. return false;
  691. }
  692. }
  693. int r = connect (ioc->sock, ioc->saddr, ioc->slen);
  694. if (r == -1) {
  695. if (errno != EAGAIN && errno != EINTR && errno != EINPROGRESS) {
  696. rdns_err ("cannot connect a TCP socket: %s for server %s",
  697. strerror(errno), ioc->srv->name);
  698. close (ioc->sock);
  699. if (ioc->saddr) {
  700. free (ioc->saddr);
  701. ioc->saddr = NULL;
  702. }
  703. ioc->sock = -1;
  704. return false;
  705. }
  706. else {
  707. /* We need to wait for write readiness here */
  708. if (ioc->tcp->async_write != NULL) {
  709. rdns_err("internal rdns error: write event is already registered on connect");
  710. }
  711. else {
  712. ioc->tcp->async_write = resolver->async->add_write(resolver->async->data,
  713. ioc->sock, ioc);
  714. }
  715. /* Prevent double connect attempts */
  716. ioc->flags |= RDNS_CHANNEL_TCP_CONNECTING;
  717. }
  718. }
  719. else {
  720. /* Always be ready to read from a TCP socket */
  721. ioc->flags |= RDNS_CHANNEL_CONNECTED|RDNS_CHANNEL_ACTIVE;
  722. ioc->flags &= ~RDNS_CHANNEL_TCP_CONNECTING;
  723. ioc->tcp->async_read = resolver->async->add_read(resolver->async->data,
  724. ioc->sock, ioc);
  725. }
  726. return true;
  727. }
  728. static bool
  729. rdns_resolver_conf_process_line (struct rdns_resolver *resolver,
  730. const char *line, rdns_resolv_conf_cb cb, void *ud)
  731. {
  732. const char *p, *c, *end;
  733. bool has_obrace = false, ret;
  734. unsigned int port = dns_port;
  735. char *cpy_buf;
  736. end = line + strlen (line);
  737. if (end - line > sizeof ("nameserver") - 1 &&
  738. strncmp (line, "nameserver", sizeof ("nameserver") - 1) == 0) {
  739. p = line + sizeof ("nameserver") - 1;
  740. /* Skip spaces */
  741. while (isspace (*p)) {
  742. p ++;
  743. }
  744. if (*p == '[') {
  745. has_obrace = true;
  746. p ++;
  747. }
  748. if (isxdigit (*p) || *p == ':') {
  749. c = p;
  750. while (isxdigit (*p) || *p == ':' || *p == '.') {
  751. p ++;
  752. }
  753. if (has_obrace && *p != ']') {
  754. return false;
  755. }
  756. else if (*p != '\0' && !isspace (*p) && *p != '#') {
  757. return false;
  758. }
  759. if (has_obrace) {
  760. p ++;
  761. if (*p == ':') {
  762. /* Maybe we have a port definition */
  763. port = strtoul (p + 1, NULL, 10);
  764. if (port == 0 || port > UINT16_MAX) {
  765. return false;
  766. }
  767. }
  768. }
  769. cpy_buf = malloc (p - c + 1);
  770. assert (cpy_buf != NULL);
  771. memcpy (cpy_buf, c, p - c);
  772. cpy_buf[p - c] = '\0';
  773. if (cb == NULL) {
  774. ret = rdns_resolver_add_server (resolver, cpy_buf, port, 0,
  775. default_io_cnt) != NULL;
  776. }
  777. else {
  778. ret = cb (resolver, cpy_buf, port, 0,
  779. default_io_cnt, ud);
  780. }
  781. free (cpy_buf);
  782. return ret;
  783. }
  784. else {
  785. return false;
  786. }
  787. }
  788. /* XXX: skip unknown resolv.conf lines */
  789. return false;
  790. }
  791. bool
  792. rdns_resolver_parse_resolv_conf_cb (struct rdns_resolver *resolver,
  793. const char *path, rdns_resolv_conf_cb cb, void *ud)
  794. {
  795. FILE *in;
  796. char buf[BUFSIZ];
  797. char *p;
  798. bool processed = false;
  799. in = fopen (path, "r");
  800. if (in == NULL) {
  801. return false;
  802. }
  803. while (!feof (in)) {
  804. if (fgets (buf, sizeof (buf) - 1, in) == NULL) {
  805. break;
  806. }
  807. /* Strip trailing spaces */
  808. p = buf + strlen (buf) - 1;
  809. while (p > buf &&
  810. (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')) {
  811. *p-- = '\0';
  812. }
  813. if (rdns_resolver_conf_process_line (resolver, buf, cb, ud)) {
  814. processed = true;
  815. }
  816. }
  817. fclose (in);
  818. return processed;
  819. }
  820. bool
  821. rdns_resolver_parse_resolv_conf (struct rdns_resolver *resolver, const char *path)
  822. {
  823. return rdns_resolver_parse_resolv_conf_cb (resolver, path, NULL, NULL);
  824. }
  825. bool
  826. rdns_request_has_type (struct rdns_request *req, enum rdns_request_type type)
  827. {
  828. unsigned int i;
  829. for (i = 0; i < req->qcount; i ++) {
  830. if (req->requested_names[i].type == type) {
  831. return true;
  832. }
  833. }
  834. return false;
  835. }
  836. const struct rdns_request_name *
  837. rdns_request_get_name (struct rdns_request *req, unsigned int *count)
  838. {
  839. if (count != NULL) {
  840. *count = req->qcount;
  841. }
  842. return req->requested_names;
  843. }
  844. const char*
  845. rdns_request_get_server (struct rdns_request *req)
  846. {
  847. if (req && req->io) {
  848. return req->io->srv->name;
  849. }
  850. return NULL;
  851. }
  852. char *
  853. rdns_generate_ptr_from_str (const char *str)
  854. {
  855. union {
  856. struct in_addr v4;
  857. struct in6_addr v6;
  858. } addr;
  859. char *res = NULL;
  860. unsigned char *bytes;
  861. size_t len;
  862. if (inet_pton (AF_INET, str, &addr.v4) == 1) {
  863. bytes = (unsigned char *)&addr.v4;
  864. len = 4 * 4 + sizeof ("in-addr.arpa");
  865. res = malloc (len);
  866. if (res) {
  867. snprintf (res, len, "%u.%u.%u.%u.in-addr.arpa",
  868. (unsigned)bytes[3]&0xFF,
  869. (unsigned)bytes[2]&0xFF,
  870. (unsigned)bytes[1]&0xFF,
  871. (unsigned)bytes[0]&0xFF);
  872. }
  873. }
  874. else if (inet_pton (AF_INET6, str, &addr.v6) == 1) {
  875. bytes = (unsigned char *)&addr.v6;
  876. len = 2*32 + sizeof ("ip6.arpa");
  877. res = malloc (len);
  878. if (res) {
  879. snprintf(res, len,
  880. "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
  881. "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
  882. bytes[15]&0xF, bytes[15] >> 4, bytes[14]&0xF, bytes[14] >> 4,
  883. bytes[13]&0xF, bytes[13] >> 4, bytes[12]&0xF, bytes[12] >> 4,
  884. bytes[11]&0xF, bytes[11] >> 4, bytes[10]&0xF, bytes[10] >> 4,
  885. bytes[9]&0xF, bytes[9] >> 4, bytes[8]&0xF, bytes[8] >> 4,
  886. bytes[7]&0xF, bytes[7] >> 4, bytes[6]&0xF, bytes[6] >> 4,
  887. bytes[5]&0xF, bytes[5] >> 4, bytes[4]&0xF, bytes[4] >> 4,
  888. bytes[3]&0xF, bytes[3] >> 4, bytes[2]&0xF, bytes[2] >> 4,
  889. bytes[1]&0xF, bytes[1] >> 4, bytes[0]&0xF, bytes[0] >> 4);
  890. }
  891. }
  892. return res;
  893. }