Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  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, "any") == 0) {
  265. return RDNS_REQUEST_ANY;
  266. }
  267. }
  268. return RDNS_REQUEST_INVALID;
  269. }
  270. const char *
  271. rdns_str_from_type (enum rdns_request_type rcode)
  272. {
  273. switch (rcode) {
  274. case RDNS_REQUEST_INVALID:
  275. return "(invalid)";
  276. case RDNS_REQUEST_A:
  277. return "a";
  278. case RDNS_REQUEST_NS:
  279. return "ns";
  280. case RDNS_REQUEST_SOA:
  281. return "soa";
  282. case RDNS_REQUEST_PTR:
  283. return "ptr";
  284. case RDNS_REQUEST_MX:
  285. return "mx";
  286. case RDNS_REQUEST_TXT:
  287. return "txt";
  288. case RDNS_REQUEST_SRV:
  289. return "srv";
  290. case RDNS_REQUEST_SPF:
  291. return "spf";
  292. case RDNS_REQUEST_AAAA:
  293. return "aaaa";
  294. case RDNS_REQUEST_TLSA:
  295. return "tlsa";
  296. case RDNS_REQUEST_ANY:
  297. return "any";
  298. default:
  299. return "(unknown)";
  300. }
  301. }
  302. enum dns_rcode
  303. rdns_rcode_fromstr (const char *str)
  304. {
  305. if (str) {
  306. if (strcmp (str, "noerror") == 0) {
  307. return RDNS_RC_NOERROR;
  308. }
  309. else if (strcmp (str, "formerr") == 0) {
  310. return RDNS_RC_FORMERR;
  311. }
  312. else if (strcmp (str, "servfail") == 0) {
  313. return RDNS_RC_SERVFAIL;
  314. }
  315. else if (strcmp (str, "nxdomain") == 0) {
  316. return RDNS_RC_NXDOMAIN;
  317. }
  318. else if (strcmp (str, "notimp") == 0) {
  319. return RDNS_RC_NOTIMP;
  320. }
  321. else if (strcmp (str, "yxdomain") == 0) {
  322. return RDNS_RC_YXDOMAIN;
  323. }
  324. else if (strcmp (str, "yxrrset") == 0) {
  325. return RDNS_RC_YXRRSET;
  326. }
  327. else if (strcmp (str, "nxrrset") == 0) {
  328. return RDNS_RC_NXRRSET;
  329. }
  330. else if (strcmp (str, "notauth") == 0) {
  331. return RDNS_RC_NOTAUTH;
  332. }
  333. else if (strcmp (str, "notzone") == 0) {
  334. return RDNS_RC_NOTZONE;
  335. }
  336. else if (strcmp (str, "timeout") == 0) {
  337. return RDNS_RC_TIMEOUT;
  338. }
  339. else if (strcmp (str, "neterr") == 0) {
  340. return RDNS_RC_NETERR;
  341. }
  342. else if (strcmp (str, "norec") == 0) {
  343. return RDNS_RC_NOREC;
  344. }
  345. }
  346. return RDNS_RC_INVALID;
  347. }
  348. uint16_t
  349. rdns_permutor_generate_id (void)
  350. {
  351. uint16_t id;
  352. id = ottery_rand_unsigned ();
  353. return id;
  354. }
  355. struct rdns_reply *
  356. rdns_make_reply (struct rdns_request *req, enum dns_rcode rcode)
  357. {
  358. struct rdns_reply *rep;
  359. rep = malloc (sizeof (struct rdns_reply));
  360. if (rep != NULL) {
  361. rep->request = req;
  362. rep->resolver = req->resolver;
  363. rep->entries = NULL;
  364. rep->code = rcode;
  365. req->reply = rep;
  366. rep->flags = 0;
  367. rep->requested_name = req->requested_names[0].name;
  368. }
  369. return rep;
  370. }
  371. void
  372. rdns_reply_free (struct rdns_reply *rep)
  373. {
  374. struct rdns_reply_entry *entry, *tmp;
  375. /* We don't need to free data for faked replies */
  376. if (!rep->request || rep->request->state != RDNS_REQUEST_FAKE) {
  377. LL_FOREACH_SAFE (rep->entries, entry, tmp) {
  378. switch (entry->type) {
  379. case RDNS_REQUEST_PTR:
  380. free (entry->content.ptr.name);
  381. break;
  382. case RDNS_REQUEST_NS:
  383. free (entry->content.ns.name);
  384. break;
  385. case RDNS_REQUEST_MX:
  386. free (entry->content.mx.name);
  387. break;
  388. case RDNS_REQUEST_TXT:
  389. case RDNS_REQUEST_SPF:
  390. free (entry->content.txt.data);
  391. break;
  392. case RDNS_REQUEST_SRV:
  393. free (entry->content.srv.target);
  394. break;
  395. case RDNS_REQUEST_TLSA:
  396. free (entry->content.tlsa.data);
  397. break;
  398. case RDNS_REQUEST_SOA:
  399. free (entry->content.soa.mname);
  400. free (entry->content.soa.admin);
  401. break;
  402. case RDNS_REQUEST_CNAME:
  403. free(entry->content.cname.name);
  404. break;
  405. default:
  406. break;
  407. }
  408. free (entry);
  409. }
  410. }
  411. free (rep);
  412. }
  413. void
  414. rdns_request_free (struct rdns_request *req)
  415. {
  416. unsigned int i;
  417. if (req != NULL) {
  418. if (req->packet != NULL) {
  419. free (req->packet);
  420. }
  421. for (i = 0; i < req->qcount; i ++) {
  422. free (req->requested_names[i].name);
  423. }
  424. if (req->requested_names != NULL) {
  425. free (req->requested_names);
  426. }
  427. if (req->reply != NULL) {
  428. rdns_reply_free (req->reply);
  429. }
  430. if (req->async_event) {
  431. if (req->state == RDNS_REQUEST_WAIT_REPLY) {
  432. /* Remove timer */
  433. req->async->del_timer (req->async->data,
  434. req->async_event);
  435. rdns_request_remove_from_hash(req);
  436. req->async_event = NULL;
  437. }
  438. else if (req->state == RDNS_REQUEST_WAIT_SEND) {
  439. /* Remove retransmit event */
  440. req->async->del_write (req->async->data,
  441. req->async_event);
  442. rdns_request_remove_from_hash(req);
  443. req->async_event = NULL;
  444. }
  445. else if (req->state == RDNS_REQUEST_FAKE) {
  446. req->async->del_write (req->async->data,
  447. req->async_event);
  448. req->async_event = NULL;
  449. }
  450. }
  451. if (req->state == RDNS_REQUEST_TCP) {
  452. if (req->async_event) {
  453. req->async->del_timer (req->async->data,
  454. req->async_event);
  455. }
  456. rdns_request_remove_from_hash(req);
  457. }
  458. #ifdef TWEETNACL
  459. if (req->curve_plugin_data != NULL) {
  460. req->resolver->curve_plugin->cb.curve_plugin.finish_cb (
  461. req, req->resolver->curve_plugin->data);
  462. }
  463. #endif
  464. if (req->io != NULL && req->state > RDNS_REQUEST_NEW) {
  465. REF_RELEASE (req->io);
  466. REF_RELEASE (req->resolver);
  467. }
  468. free (req);
  469. }
  470. }
  471. void
  472. rdns_ioc_free (struct rdns_io_channel *ioc)
  473. {
  474. struct rdns_request *req;
  475. if (IS_CHANNEL_TCP(ioc)) {
  476. rdns_ioc_tcp_reset(ioc);
  477. }
  478. kh_foreach_value(ioc->requests, req, {
  479. REF_RELEASE (req);
  480. });
  481. if (ioc->async_io) {
  482. ioc->resolver->async->del_read(ioc->resolver->async->data,
  483. ioc->async_io);
  484. }
  485. kh_destroy(rdns_requests_hash, ioc->requests);
  486. if (ioc->sock != -1) {
  487. close(ioc->sock);
  488. }
  489. if (ioc->saddr != NULL) {
  490. free(ioc->saddr);
  491. }
  492. free (ioc);
  493. }
  494. struct rdns_io_channel *
  495. rdns_ioc_new (struct rdns_server *serv,
  496. struct rdns_resolver *resolver,
  497. bool is_tcp)
  498. {
  499. struct rdns_io_channel *nioc;
  500. if (is_tcp) {
  501. nioc = calloc (1, sizeof (struct rdns_io_channel)
  502. + sizeof (struct rdns_tcp_channel));
  503. }
  504. else {
  505. nioc = calloc (1, sizeof (struct rdns_io_channel));
  506. }
  507. if (nioc == NULL) {
  508. rdns_err ("calloc fails to allocate rdns_io_channel");
  509. return NULL;
  510. }
  511. nioc->struct_magic = RDNS_IO_CHANNEL_TAG;
  512. nioc->srv = serv;
  513. nioc->resolver = resolver;
  514. nioc->sock = rdns_make_client_socket (serv->name, serv->port,
  515. is_tcp ? SOCK_STREAM : SOCK_DGRAM, &nioc->saddr, &nioc->slen);
  516. if (nioc->sock == -1) {
  517. rdns_err ("cannot open socket to %s: %s", serv->name,
  518. strerror (errno));
  519. free (nioc);
  520. return NULL;
  521. }
  522. if (is_tcp) {
  523. /* We also need to connect a TCP channel and set a TCP buffer */
  524. nioc->tcp = (struct rdns_tcp_channel *)(((unsigned char *)nioc) + sizeof(*nioc));
  525. if (!rdns_ioc_tcp_connect(nioc)) {
  526. rdns_err ("cannot connect TCP socket to %s: %s", serv->name,
  527. strerror (errno));
  528. close (nioc->sock);
  529. free (nioc);
  530. return NULL;
  531. }
  532. nioc->flags |= RDNS_CHANNEL_TCP;
  533. }
  534. else {
  535. nioc->flags |= RDNS_CHANNEL_ACTIVE;
  536. nioc->async_io = resolver->async->add_read(resolver->async->data,
  537. nioc->sock, nioc);
  538. }
  539. nioc->requests = kh_init(rdns_requests_hash);
  540. REF_INIT_RETAIN (nioc, rdns_ioc_free);
  541. return nioc;
  542. }
  543. void
  544. rdns_resolver_release (struct rdns_resolver *resolver)
  545. {
  546. REF_RELEASE (resolver);
  547. }
  548. struct rdns_request*
  549. rdns_request_retain (struct rdns_request *req)
  550. {
  551. REF_RETAIN (req);
  552. return req;
  553. }
  554. void
  555. rdns_request_unschedule (struct rdns_request *req, bool remove_from_hash)
  556. {
  557. struct rdns_resolver *resolver = req->resolver;
  558. switch (req->state) {
  559. case RDNS_REQUEST_WAIT_REPLY:
  560. /* We have a timer pending */
  561. if (req->async_event) {
  562. req->async->del_timer (req->async->data,
  563. req->async_event);
  564. if (remove_from_hash) {
  565. rdns_request_remove_from_hash(req);
  566. }
  567. req->async_event = NULL;
  568. }
  569. break;
  570. case RDNS_REQUEST_WAIT_SEND:
  571. /* We have write request pending */
  572. if (req->async_event) {
  573. req->async->del_write (req->async->data,
  574. req->async_event);
  575. /* Remove from id hashes */
  576. if (remove_from_hash) {
  577. rdns_request_remove_from_hash(req);
  578. }
  579. req->async_event = NULL;
  580. }
  581. break;
  582. case RDNS_REQUEST_TCP:
  583. /* We also have a timer */
  584. if (req->async_event) {
  585. if (remove_from_hash) {
  586. rdns_request_remove_from_hash(req);
  587. }
  588. req->async->del_timer(req->async->data,
  589. req->async_event);
  590. req->async_event = NULL;
  591. }
  592. default:
  593. /* Nothing to unschedule, so blame if we have any event pending */
  594. if (req->async_event) {
  595. rdns_err("internal error: have unexpected pending async state on stage %d",
  596. req->state);
  597. }
  598. break;
  599. }
  600. }
  601. void
  602. rdns_request_release (struct rdns_request *req)
  603. {
  604. rdns_request_unschedule (req, true);
  605. REF_RELEASE (req);
  606. }
  607. void
  608. rdns_ioc_tcp_reset (struct rdns_io_channel *ioc)
  609. {
  610. struct rdns_resolver *resolver = ioc->resolver;
  611. if (IS_CHANNEL_CONNECTED(ioc)) {
  612. if (ioc->tcp->async_write) {
  613. resolver->async->del_write (resolver->async->data, ioc->tcp->async_write);
  614. ioc->tcp->async_write = NULL;
  615. }
  616. if (ioc->tcp->async_read) {
  617. resolver->async->del_read (resolver->async->data, ioc->tcp->async_read);
  618. ioc->tcp->async_read = NULL;
  619. }
  620. /* Clean all buffers and temporaries */
  621. if (ioc->tcp->cur_read_buf) {
  622. free (ioc->tcp->cur_read_buf);
  623. ioc->tcp->read_buf_allocated = 0;
  624. ioc->tcp->next_read_size = 0;
  625. ioc->tcp->cur_read = 0;
  626. ioc->tcp->cur_read_buf = NULL;
  627. }
  628. struct rdns_tcp_output_chain *oc, *tmp;
  629. DL_FOREACH_SAFE(ioc->tcp->output_chain, oc, tmp) {
  630. DL_DELETE (ioc->tcp->output_chain, oc);
  631. free (oc);
  632. }
  633. ioc->tcp->cur_output_chains = 0;
  634. ioc->tcp->output_chain = NULL;
  635. ioc->flags &= ~RDNS_CHANNEL_CONNECTED;
  636. }
  637. /* Remove all requests pending as we are unable to complete them */
  638. struct rdns_request *req;
  639. kh_foreach_value(ioc->requests, req, {
  640. struct rdns_reply *rep = rdns_make_reply (req, RDNS_RC_NETERR);
  641. /*
  642. * Unschedule request explicitly as we set state to RDNS_REQUEST_REPLIED
  643. * that will prevent timer from being removed on req dtor.
  644. *
  645. * We skip hash removal here, as the hash will be cleared as a single
  646. * operation afterwards.
  647. */
  648. rdns_request_unschedule(req, false);
  649. req->state = RDNS_REQUEST_REPLIED;
  650. req->func (rep, req->arg);
  651. REF_RELEASE (req);
  652. });
  653. if (ioc->sock != -1) {
  654. close (ioc->sock);
  655. ioc->sock = -1;
  656. }
  657. if (ioc->saddr) {
  658. free (ioc->saddr);
  659. ioc->saddr = NULL;
  660. }
  661. kh_clear(rdns_requests_hash, ioc->requests);
  662. }
  663. bool
  664. rdns_ioc_tcp_connect (struct rdns_io_channel *ioc)
  665. {
  666. struct rdns_resolver *resolver = ioc->resolver;
  667. if (IS_CHANNEL_CONNECTED(ioc)) {
  668. rdns_err ("trying to connect already connected IO channel!");
  669. return false;
  670. }
  671. if (ioc->flags & RDNS_CHANNEL_TCP_CONNECTING) {
  672. /* Already connecting channel, ignore connect request */
  673. return true;
  674. }
  675. if (ioc->sock == -1) {
  676. ioc->sock = rdns_make_client_socket (ioc->srv->name, ioc->srv->port,
  677. SOCK_STREAM, &ioc->saddr, &ioc->slen);
  678. if (ioc->sock == -1) {
  679. rdns_err ("cannot open socket to %s: %s", ioc->srv->name,
  680. strerror (errno));
  681. if (ioc->saddr) {
  682. free (ioc->saddr);
  683. ioc->saddr = NULL;
  684. }
  685. return false;
  686. }
  687. }
  688. int r = connect (ioc->sock, ioc->saddr, ioc->slen);
  689. if (r == -1) {
  690. if (errno != EAGAIN && errno != EINTR && errno != EINPROGRESS) {
  691. rdns_err ("cannot connect a TCP socket: %s for server %s",
  692. strerror(errno), ioc->srv->name);
  693. close (ioc->sock);
  694. if (ioc->saddr) {
  695. free (ioc->saddr);
  696. ioc->saddr = NULL;
  697. }
  698. ioc->sock = -1;
  699. return false;
  700. }
  701. else {
  702. /* We need to wait for write readiness here */
  703. if (ioc->tcp->async_write != NULL) {
  704. rdns_err("internal rdns error: write event is already registered on connect");
  705. }
  706. else {
  707. ioc->tcp->async_write = resolver->async->add_write(resolver->async->data,
  708. ioc->sock, ioc);
  709. }
  710. /* Prevent double connect attempts */
  711. ioc->flags |= RDNS_CHANNEL_TCP_CONNECTING;
  712. }
  713. }
  714. else {
  715. /* Always be ready to read from a TCP socket */
  716. ioc->flags |= RDNS_CHANNEL_CONNECTED|RDNS_CHANNEL_ACTIVE;
  717. ioc->flags &= ~RDNS_CHANNEL_TCP_CONNECTING;
  718. ioc->tcp->async_read = resolver->async->add_read(resolver->async->data,
  719. ioc->sock, ioc);
  720. }
  721. return true;
  722. }
  723. static bool
  724. rdns_resolver_conf_process_line (struct rdns_resolver *resolver,
  725. const char *line, rdns_resolv_conf_cb cb, void *ud)
  726. {
  727. const char *p, *c, *end;
  728. bool has_obrace = false, ret;
  729. unsigned int port = dns_port;
  730. char *cpy_buf;
  731. end = line + strlen (line);
  732. if (end - line > sizeof ("nameserver") - 1 &&
  733. strncmp (line, "nameserver", sizeof ("nameserver") - 1) == 0) {
  734. p = line + sizeof ("nameserver") - 1;
  735. /* Skip spaces */
  736. while (isspace (*p)) {
  737. p ++;
  738. }
  739. if (*p == '[') {
  740. has_obrace = true;
  741. p ++;
  742. }
  743. if (isxdigit (*p) || *p == ':') {
  744. c = p;
  745. while (isxdigit (*p) || *p == ':' || *p == '.') {
  746. p ++;
  747. }
  748. if (has_obrace && *p != ']') {
  749. return false;
  750. }
  751. else if (*p != '\0' && !isspace (*p) && *p != '#') {
  752. return false;
  753. }
  754. if (has_obrace) {
  755. p ++;
  756. if (*p == ':') {
  757. /* Maybe we have a port definition */
  758. port = strtoul (p + 1, NULL, 10);
  759. if (port == 0 || port > UINT16_MAX) {
  760. return false;
  761. }
  762. }
  763. }
  764. cpy_buf = malloc (p - c + 1);
  765. assert (cpy_buf != NULL);
  766. memcpy (cpy_buf, c, p - c);
  767. cpy_buf[p - c] = '\0';
  768. if (cb == NULL) {
  769. ret = rdns_resolver_add_server (resolver, cpy_buf, port, 0,
  770. default_io_cnt) != NULL;
  771. }
  772. else {
  773. ret = cb (resolver, cpy_buf, port, 0,
  774. default_io_cnt, ud);
  775. }
  776. free (cpy_buf);
  777. return ret;
  778. }
  779. else {
  780. return false;
  781. }
  782. }
  783. /* XXX: skip unknown resolv.conf lines */
  784. return false;
  785. }
  786. bool
  787. rdns_resolver_parse_resolv_conf_cb (struct rdns_resolver *resolver,
  788. const char *path, rdns_resolv_conf_cb cb, void *ud)
  789. {
  790. FILE *in;
  791. char buf[BUFSIZ];
  792. char *p;
  793. bool processed = false;
  794. in = fopen (path, "r");
  795. if (in == NULL) {
  796. return false;
  797. }
  798. while (!feof (in)) {
  799. if (fgets (buf, sizeof (buf) - 1, in) == NULL) {
  800. break;
  801. }
  802. /* Strip trailing spaces */
  803. p = buf + strlen (buf) - 1;
  804. while (p > buf &&
  805. (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')) {
  806. *p-- = '\0';
  807. }
  808. if (rdns_resolver_conf_process_line (resolver, buf, cb, ud)) {
  809. processed = true;
  810. }
  811. }
  812. fclose (in);
  813. return processed;
  814. }
  815. bool
  816. rdns_resolver_parse_resolv_conf (struct rdns_resolver *resolver, const char *path)
  817. {
  818. return rdns_resolver_parse_resolv_conf_cb (resolver, path, NULL, NULL);
  819. }
  820. bool
  821. rdns_request_has_type (struct rdns_request *req, enum rdns_request_type type)
  822. {
  823. unsigned int i;
  824. for (i = 0; i < req->qcount; i ++) {
  825. if (req->requested_names[i].type == type) {
  826. return true;
  827. }
  828. }
  829. return false;
  830. }
  831. const struct rdns_request_name *
  832. rdns_request_get_name (struct rdns_request *req, unsigned int *count)
  833. {
  834. if (count != NULL) {
  835. *count = req->qcount;
  836. }
  837. return req->requested_names;
  838. }
  839. const char*
  840. rdns_request_get_server (struct rdns_request *req)
  841. {
  842. if (req && req->io) {
  843. return req->io->srv->name;
  844. }
  845. return NULL;
  846. }
  847. char *
  848. rdns_generate_ptr_from_str (const char *str)
  849. {
  850. union {
  851. struct in_addr v4;
  852. struct in6_addr v6;
  853. } addr;
  854. char *res = NULL;
  855. unsigned char *bytes;
  856. size_t len;
  857. if (inet_pton (AF_INET, str, &addr.v4) == 1) {
  858. bytes = (unsigned char *)&addr.v4;
  859. len = 4 * 4 + sizeof ("in-addr.arpa");
  860. res = malloc (len);
  861. if (res) {
  862. snprintf (res, len, "%u.%u.%u.%u.in-addr.arpa",
  863. (unsigned)bytes[3]&0xFF,
  864. (unsigned)bytes[2]&0xFF,
  865. (unsigned)bytes[1]&0xFF,
  866. (unsigned)bytes[0]&0xFF);
  867. }
  868. }
  869. else if (inet_pton (AF_INET6, str, &addr.v6) == 1) {
  870. bytes = (unsigned char *)&addr.v6;
  871. len = 2*32 + sizeof ("ip6.arpa");
  872. res = malloc (len);
  873. if (res) {
  874. snprintf(res, len,
  875. "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
  876. "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
  877. bytes[15]&0xF, bytes[15] >> 4, bytes[14]&0xF, bytes[14] >> 4,
  878. bytes[13]&0xF, bytes[13] >> 4, bytes[12]&0xF, bytes[12] >> 4,
  879. bytes[11]&0xF, bytes[11] >> 4, bytes[10]&0xF, bytes[10] >> 4,
  880. bytes[9]&0xF, bytes[9] >> 4, bytes[8]&0xF, bytes[8] >> 4,
  881. bytes[7]&0xF, bytes[7] >> 4, bytes[6]&0xF, bytes[6] >> 4,
  882. bytes[5]&0xF, bytes[5] >> 4, bytes[4]&0xF, bytes[4] >> 4,
  883. bytes[3]&0xF, bytes[3] >> 4, bytes[2]&0xF, bytes[2] >> 4,
  884. bytes[1]&0xF, bytes[1] >> 4, bytes[0]&0xF, bytes[0] >> 4);
  885. }
  886. }
  887. return res;
  888. }