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.

1429 lines
33 KiB

  1. /***
  2. This file is part of libasyncns.
  3. Copyright 2005-2008 Lennart Poettering
  4. libasyncns is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as
  6. published by the Free Software Foundation, either version 2.1 of the
  7. License, or (at your option) any later version.
  8. libasyncns is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with libasyncns. If not, see
  14. <http://www.gnu.org/licenses/>.
  15. ***/
  16. #ifdef HAVE_CONFIG_H
  17. #include <config.h>
  18. #endif
  19. /* #undef HAVE_PTHREAD */
  20. #include <assert.h>
  21. #include <fcntl.h>
  22. #include <signal.h>
  23. #include <unistd.h>
  24. #include <sys/select.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <errno.h>
  29. #include <sys/wait.h>
  30. #include <sys/types.h>
  31. #include <pwd.h>
  32. #include <netinet/in.h>
  33. #include <arpa/nameser.h>
  34. #include <resolv.h>
  35. #include <dirent.h>
  36. #include <sys/time.h>
  37. #include <sys/resource.h>
  38. #include <stdint.h>
  39. #ifdef HAVE_SYS_PRCTL_H
  40. #include <sys/prctl.h>
  41. #endif
  42. #if HAVE_PTHREAD
  43. #include <pthread.h>
  44. #endif
  45. #include "asyncns.h"
  46. #ifndef MSG_NOSIGNAL
  47. #define MSG_NOSIGNAL 0
  48. #endif
  49. #define MAX_WORKERS 16
  50. #define MAX_QUERIES 256
  51. #define BUFSIZE (10240)
  52. typedef enum {
  53. REQUEST_ADDRINFO,
  54. RESPONSE_ADDRINFO,
  55. REQUEST_NAMEINFO,
  56. RESPONSE_NAMEINFO,
  57. REQUEST_TERMINATE,
  58. RESPONSE_DIED
  59. } query_type_t;
  60. enum {
  61. REQUEST_RECV_FD = 0,
  62. REQUEST_SEND_FD = 1,
  63. RESPONSE_RECV_FD = 2,
  64. RESPONSE_SEND_FD = 3,
  65. MESSAGE_FD_MAX = 4
  66. };
  67. struct asyncns {
  68. int fds[4];
  69. #ifndef HAVE_PTHREAD
  70. pid_t workers[MAX_WORKERS];
  71. #else
  72. pthread_t workers[MAX_WORKERS];
  73. #endif
  74. unsigned valid_workers;
  75. unsigned current_id, current_index;
  76. asyncns_query_t* queries[MAX_QUERIES];
  77. asyncns_query_t *done_head, *done_tail;
  78. int n_queries;
  79. int dead;
  80. };
  81. struct asyncns_query {
  82. asyncns_t *asyncns;
  83. int done;
  84. unsigned id;
  85. query_type_t type;
  86. asyncns_query_t *done_next, *done_prev;
  87. int ret;
  88. int _errno;
  89. int _h_errno;
  90. struct addrinfo *addrinfo;
  91. char *serv, *host;
  92. void *userdata;
  93. };
  94. typedef struct rheader {
  95. query_type_t type;
  96. unsigned id;
  97. size_t length;
  98. } rheader_t;
  99. typedef struct addrinfo_request {
  100. struct rheader header;
  101. int hints_is_null;
  102. int ai_flags;
  103. int ai_family;
  104. int ai_socktype;
  105. int ai_protocol;
  106. size_t node_len, service_len;
  107. } addrinfo_request_t;
  108. typedef struct addrinfo_response {
  109. struct rheader header;
  110. int ret;
  111. int _errno;
  112. int _h_errno;
  113. /* followed by addrinfo_serialization[] */
  114. } addrinfo_response_t;
  115. typedef struct addrinfo_serialization {
  116. int ai_flags;
  117. int ai_family;
  118. int ai_socktype;
  119. int ai_protocol;
  120. size_t ai_addrlen;
  121. size_t canonname_len;
  122. /* Followed by ai_addr amd ai_canonname with variable lengths */
  123. } addrinfo_serialization_t;
  124. typedef struct nameinfo_request {
  125. struct rheader header;
  126. int flags;
  127. socklen_t sockaddr_len;
  128. int gethost, getserv;
  129. } nameinfo_request_t;
  130. typedef struct nameinfo_response {
  131. struct rheader header;
  132. size_t hostlen, servlen;
  133. int ret;
  134. int _errno;
  135. int _h_errno;
  136. } nameinfo_response_t;
  137. typedef struct res_request {
  138. struct rheader header;
  139. int class;
  140. int type;
  141. size_t dname_len;
  142. } res_request_t;
  143. typedef struct res_response {
  144. struct rheader header;
  145. int ret;
  146. int _errno;
  147. int _h_errno;
  148. } res_response_t;
  149. typedef union packet {
  150. rheader_t rheader;
  151. addrinfo_request_t addrinfo_request;
  152. addrinfo_response_t addrinfo_response;
  153. nameinfo_request_t nameinfo_request;
  154. nameinfo_response_t nameinfo_response;
  155. res_request_t res_request;
  156. res_response_t res_response;
  157. } packet_t;
  158. static char *asyncns_strndup(const char *s, size_t l) {
  159. size_t a;
  160. char *n;
  161. a = strlen(s);
  162. if (a > l)
  163. a = l;
  164. if (!(n = malloc(a+1)))
  165. return NULL;
  166. memcpy(n, s, a);
  167. n[a] = 0;
  168. return n;
  169. }
  170. #ifndef HAVE_PTHREAD
  171. static int close_allv(const int except_fds[]) {
  172. struct rlimit rl;
  173. int fd, maxfd;
  174. #ifdef __linux__
  175. DIR *d;
  176. assert(except_fds);
  177. if ((d = opendir("/proc/self/fd"))) {
  178. struct dirent *de;
  179. while ((de = readdir(d))) {
  180. int found;
  181. long l;
  182. char *e = NULL;
  183. int i;
  184. if (de->d_name[0] == '.')
  185. continue;
  186. errno = 0;
  187. l = strtol(de->d_name, &e, 10);
  188. if (errno != 0 || !e || *e) {
  189. closedir(d);
  190. errno = EINVAL;
  191. return -1;
  192. }
  193. fd = (int) l;
  194. if ((long) fd != l) {
  195. closedir(d);
  196. errno = EINVAL;
  197. return -1;
  198. }
  199. if (fd < 3)
  200. continue;
  201. if (fd == dirfd(d))
  202. continue;
  203. found = 0;
  204. for (i = 0; except_fds[i] >= 0; i++)
  205. if (except_fds[i] == fd) {
  206. found = 1;
  207. break;
  208. }
  209. if (found)
  210. continue;
  211. if (close(fd) < 0) {
  212. int saved_errno;
  213. saved_errno = errno;
  214. closedir(d);
  215. errno = saved_errno;
  216. return -1;
  217. }
  218. }
  219. closedir(d);
  220. return 0;
  221. }
  222. #endif
  223. if (getrlimit(RLIMIT_NOFILE, &rl) > 0)
  224. maxfd = (int) rl.rlim_max;
  225. else
  226. maxfd = sysconf(_SC_OPEN_MAX);
  227. for (fd = 3; fd < maxfd; fd++) {
  228. int i, found;
  229. found = 0;
  230. for (i = 0; except_fds[i] >= 0; i++)
  231. if (except_fds[i] == fd) {
  232. found = 1;
  233. continue;
  234. }
  235. if (found)
  236. continue;
  237. if (close(fd) < 0 && errno != EBADF)
  238. return -1;
  239. }
  240. return 0;
  241. }
  242. static int reset_sigsv(const int except[]) {
  243. int sig;
  244. assert(except);
  245. for (sig = 1; sig < NSIG; sig++) {
  246. int reset = 1;
  247. switch (sig) {
  248. case SIGKILL:
  249. case SIGSTOP:
  250. reset = 0;
  251. break;
  252. default: {
  253. int i;
  254. for (i = 0; except[i] > 0; i++) {
  255. if (sig == except[i]) {
  256. reset = 0;
  257. break;
  258. }
  259. }
  260. }
  261. }
  262. if (reset) {
  263. struct sigaction sa;
  264. memset(&sa, 0, sizeof(sa));
  265. sa.sa_handler = SIG_DFL;
  266. /* On Linux the first two RT signals are reserved by
  267. * glibc, and sigaction() will return EINVAL for them. */
  268. if ((sigaction(sig, &sa, NULL) < 0))
  269. if (errno != EINVAL)
  270. return -1;
  271. }
  272. }
  273. return 0;
  274. }
  275. static int ignore_sigsv(const int ignore[]) {
  276. int i;
  277. assert(ignore);
  278. for (i = 0; ignore[i] > 0; i++) {
  279. struct sigaction sa;
  280. memset(&sa, 0, sizeof(sa));
  281. sa.sa_handler = SIG_IGN;
  282. if ((sigaction(ignore[i], &sa, NULL) < 0))
  283. return -1;
  284. }
  285. return 0;
  286. }
  287. #endif
  288. static int fd_nonblock(int fd) {
  289. int i;
  290. assert(fd >= 0);
  291. if ((i = fcntl(fd, F_GETFL, 0)) < 0)
  292. return -1;
  293. if (i & O_NONBLOCK)
  294. return 0;
  295. return fcntl(fd, F_SETFL, i | O_NONBLOCK);
  296. }
  297. static int fd_cloexec(int fd) {
  298. int v;
  299. assert(fd >= 0);
  300. if ((v = fcntl(fd, F_GETFD, 0)) < 0)
  301. return -1;
  302. if (v & FD_CLOEXEC)
  303. return 0;
  304. return fcntl(fd, F_SETFD, v | FD_CLOEXEC);
  305. }
  306. static int send_died(int out_fd) {
  307. rheader_t rh;
  308. assert(out_fd > 0);
  309. memset(&rh, 0, sizeof(rh));
  310. rh.type = RESPONSE_DIED;
  311. rh.id = 0;
  312. rh.length = sizeof(rh);
  313. return send(out_fd, &rh, rh.length, MSG_NOSIGNAL);
  314. }
  315. static void *serialize_addrinfo(void *p, const struct addrinfo *ai, size_t *length, size_t maxlength) {
  316. addrinfo_serialization_t s;
  317. size_t cnl, l;
  318. assert(p);
  319. assert(ai);
  320. assert(length);
  321. assert(*length <= maxlength);
  322. cnl = (ai->ai_canonname ? strlen(ai->ai_canonname)+1 : 0);
  323. l = sizeof(addrinfo_serialization_t) + ai->ai_addrlen + cnl;
  324. if (*length + l > maxlength)
  325. return NULL;
  326. s.ai_flags = ai->ai_flags;
  327. s.ai_family = ai->ai_family;
  328. s.ai_socktype = ai->ai_socktype;
  329. s.ai_protocol = ai->ai_protocol;
  330. s.ai_addrlen = ai->ai_addrlen;
  331. s.canonname_len = cnl;
  332. memcpy((uint8_t*) p, &s, sizeof(addrinfo_serialization_t));
  333. memcpy((uint8_t*) p + sizeof(addrinfo_serialization_t), ai->ai_addr, ai->ai_addrlen);
  334. if (ai->ai_canonname)
  335. strcpy((char*) p + sizeof(addrinfo_serialization_t) + ai->ai_addrlen, ai->ai_canonname);
  336. *length += l;
  337. return (uint8_t*) p + l;
  338. }
  339. static int send_addrinfo_reply(int out_fd, unsigned id, int ret, struct addrinfo *ai, int _errno, int _h_errno) {
  340. addrinfo_response_t data[BUFSIZE/sizeof(addrinfo_response_t) + 1];
  341. addrinfo_response_t *resp = data;
  342. assert(out_fd >= 0);
  343. memset(data, 0, sizeof(data));
  344. resp->header.type = RESPONSE_ADDRINFO;
  345. resp->header.id = id;
  346. resp->header.length = sizeof(addrinfo_response_t);
  347. resp->ret = ret;
  348. resp->_errno = _errno;
  349. resp->_h_errno = _h_errno;
  350. if (ret == 0 && ai) {
  351. void *p = data + 1;
  352. struct addrinfo *k;
  353. for (k = ai; k; k = k->ai_next) {
  354. if (!(p = serialize_addrinfo(p, k, &resp->header.length, (char*) data + BUFSIZE - (char*) p))) {
  355. resp->ret = EAI_MEMORY;
  356. break;
  357. }
  358. }
  359. }
  360. if (ai)
  361. freeaddrinfo(ai);
  362. return send(out_fd, resp, resp->header.length, MSG_NOSIGNAL);
  363. }
  364. static int send_nameinfo_reply(int out_fd, unsigned id, int ret, const char *host, const char *serv, int _errno, int _h_errno) {
  365. nameinfo_response_t data[BUFSIZE/sizeof(nameinfo_response_t) + 1];
  366. size_t hl, sl;
  367. nameinfo_response_t *resp = data;
  368. assert(out_fd >= 0);
  369. sl = serv ? strlen(serv)+1 : 0;
  370. hl = host ? strlen(host)+1 : 0;
  371. memset(data, 0, sizeof(data));
  372. resp->header.type = RESPONSE_NAMEINFO;
  373. resp->header.id = id;
  374. resp->header.length = sizeof(nameinfo_response_t) + hl + sl;
  375. resp->ret = ret;
  376. resp->_errno = _errno;
  377. resp->_h_errno = _h_errno;
  378. resp->hostlen = hl;
  379. resp->servlen = sl;
  380. assert(sizeof(data) >= resp->header.length);
  381. if (host)
  382. memcpy((uint8_t *)data + sizeof(nameinfo_response_t), host, hl);
  383. if (serv)
  384. memcpy((uint8_t *)data + sizeof(nameinfo_response_t) + hl, serv, sl);
  385. return send(out_fd, resp, resp->header.length, MSG_NOSIGNAL);
  386. }
  387. static int handle_request(int out_fd, const packet_t *packet, size_t length) {
  388. const rheader_t *req;
  389. assert(out_fd >= 0);
  390. req = &packet->rheader;
  391. assert(req);
  392. assert(length >= sizeof(rheader_t));
  393. assert(length == req->length);
  394. switch (req->type) {
  395. case REQUEST_ADDRINFO: {
  396. struct addrinfo ai, *result = NULL;
  397. const addrinfo_request_t *ai_req = &packet->addrinfo_request;
  398. const char *node, *service;
  399. int ret;
  400. assert(length >= sizeof(addrinfo_request_t));
  401. assert(length == sizeof(addrinfo_request_t) + ai_req->node_len + ai_req->service_len);
  402. memset(&ai, 0, sizeof(ai));
  403. ai.ai_flags = ai_req->ai_flags;
  404. ai.ai_family = ai_req->ai_family;
  405. ai.ai_socktype = ai_req->ai_socktype;
  406. ai.ai_protocol = ai_req->ai_protocol;
  407. node = ai_req->node_len ? (const char*) ai_req + sizeof(addrinfo_request_t) : NULL;
  408. service = ai_req->service_len ? (const char*) ai_req + sizeof(addrinfo_request_t) + ai_req->node_len : NULL;
  409. ret = getaddrinfo(node, service,
  410. ai_req->hints_is_null ? NULL : &ai,
  411. &result);
  412. /* send_addrinfo_reply() frees result */
  413. return send_addrinfo_reply(out_fd, req->id, ret, result, errno, h_errno);
  414. }
  415. case REQUEST_NAMEINFO: {
  416. int ret;
  417. const nameinfo_request_t *ni_req = &packet->nameinfo_request;
  418. char hostbuf[NI_MAXHOST], servbuf[NI_MAXSERV];
  419. struct sockaddr_storage sa;
  420. assert(length >= sizeof(nameinfo_request_t));
  421. assert(length == sizeof(nameinfo_request_t) + ni_req->sockaddr_len);
  422. memcpy(&sa, (const uint8_t *) ni_req + sizeof(nameinfo_request_t), ni_req->sockaddr_len);
  423. ret = getnameinfo((struct sockaddr *)&sa, ni_req->sockaddr_len,
  424. ni_req->gethost ? hostbuf : NULL, ni_req->gethost ? sizeof(hostbuf) : 0,
  425. ni_req->getserv ? servbuf : NULL, ni_req->getserv ? sizeof(servbuf) : 0,
  426. ni_req->flags);
  427. return send_nameinfo_reply(out_fd, req->id, ret,
  428. ret == 0 && ni_req->gethost ? hostbuf : NULL,
  429. ret == 0 && ni_req->getserv ? servbuf : NULL,
  430. errno, h_errno);
  431. }
  432. case REQUEST_TERMINATE:
  433. /* Quit */
  434. return -1;
  435. default:
  436. ;
  437. }
  438. return 0;
  439. }
  440. #ifndef HAVE_PTHREAD
  441. static int process_worker(int in_fd, int out_fd) {
  442. int have_death_sig = 0;
  443. int good_fds[3];
  444. int ret = 1;
  445. const int ignore_sigs[] = {
  446. SIGINT,
  447. SIGHUP,
  448. SIGPIPE,
  449. SIGUSR1,
  450. SIGUSR2,
  451. -1
  452. };
  453. assert(in_fd > 2);
  454. assert(out_fd > 2);
  455. close(0);
  456. close(1);
  457. close(2);
  458. if (open("/dev/null", O_RDONLY) != 0)
  459. goto fail;
  460. if (open("/dev/null", O_WRONLY) != 1)
  461. goto fail;
  462. if (open("/dev/null", O_WRONLY) != 2)
  463. goto fail;
  464. if (chdir("/") < 0)
  465. goto fail;
  466. if (geteuid() == 0) {
  467. struct passwd *pw;
  468. int r;
  469. if ((pw = getpwnam("nobody"))) {
  470. #ifdef HAVE_SETRESUID
  471. r = setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
  472. #elif HAVE_SETREUID
  473. r = setreuid(pw->pw_uid, pw->pw_uid);
  474. #else
  475. if ((r = setuid(pw->pw_uid)) >= 0)
  476. r = seteuid(pw->pw_uid);
  477. #endif
  478. if (r < 0)
  479. goto fail;
  480. }
  481. }
  482. if (reset_sigsv(ignore_sigs) < 0)
  483. goto fail;
  484. if (ignore_sigsv(ignore_sigs) < 0)
  485. goto fail;
  486. good_fds[0] = in_fd; good_fds[1] = out_fd; good_fds[2] = -1;
  487. if (close_allv(good_fds) < 0)
  488. goto fail;
  489. #ifdef PR_SET_PDEATHSIG
  490. if (prctl(PR_SET_PDEATHSIG, SIGTERM) >= 0)
  491. have_death_sig = 1;
  492. #endif
  493. if (!have_death_sig)
  494. fd_nonblock(in_fd);
  495. while (getppid() > 1) { /* if the parent PID is 1 our parent process died. */
  496. packet_t buf[BUFSIZE/sizeof(packet_t) + 1];
  497. ssize_t length;
  498. if (!have_death_sig) {
  499. fd_set fds;
  500. struct timeval tv;
  501. tv.tv_usec = 500000;
  502. tv.tv_sec = 0;
  503. FD_ZERO(&fds);
  504. FD_SET(in_fd, &fds);
  505. if (select(in_fd+1, &fds, NULL, NULL, &tv) < 0)
  506. break;
  507. if (getppid() == 1)
  508. break;
  509. }
  510. if ((length = recv(in_fd, buf, sizeof(buf), 0)) <= 0) {
  511. if (length < 0 &&
  512. (errno == EAGAIN || errno == EINTR))
  513. continue;
  514. break;
  515. }
  516. if (handle_request(out_fd, buf, (size_t) length) < 0)
  517. break;
  518. }
  519. ret = 0;
  520. fail:
  521. send_died(out_fd);
  522. return ret;
  523. }
  524. #else
  525. static void* thread_worker(void *p) {
  526. asyncns_t *asyncns = p;
  527. sigset_t fullset;
  528. int in_fd = asyncns->fds[REQUEST_RECV_FD];
  529. /* No signals in this thread please */
  530. sigfillset(&fullset);
  531. pthread_sigmask(SIG_BLOCK, &fullset, NULL);
  532. fd_nonblock(in_fd);
  533. while (!asyncns->dead) {
  534. packet_t buf[BUFSIZE/sizeof(packet_t) + 1];
  535. ssize_t length;
  536. if ((length = recv(in_fd, buf, sizeof(buf), 0)) <= 0) {
  537. if (!asyncns->dead) {
  538. fd_set fds;
  539. struct timeval tv;
  540. tv.tv_usec = 500000;
  541. tv.tv_sec = 0;
  542. FD_ZERO(&fds);
  543. FD_SET(in_fd, &fds);
  544. if (select(in_fd+1, &fds, NULL, NULL, &tv) < 0) {
  545. perror("test");
  546. break;
  547. }
  548. }
  549. if (length < 0 &&
  550. (errno == EAGAIN || errno == EINTR)) {
  551. continue;
  552. }
  553. break;
  554. }
  555. if (asyncns->dead)
  556. break;
  557. if (handle_request(asyncns->fds[RESPONSE_SEND_FD], buf, (size_t) length) < 0)
  558. break;
  559. }
  560. send_died(asyncns->fds[RESPONSE_SEND_FD]);
  561. return NULL;
  562. }
  563. #endif
  564. asyncns_t* asyncns_new(unsigned n_proc) {
  565. asyncns_t *asyncns = NULL;
  566. int i;
  567. assert(n_proc >= 1);
  568. if (n_proc > MAX_WORKERS)
  569. n_proc = MAX_WORKERS;
  570. if (!(asyncns = malloc(sizeof(asyncns_t)))) {
  571. errno = ENOMEM;
  572. goto fail;
  573. }
  574. asyncns->dead = 0;
  575. asyncns->valid_workers = 0;
  576. for (i = 0; i < MESSAGE_FD_MAX; i++)
  577. asyncns->fds[i] = -1;
  578. memset(asyncns->queries, 0, sizeof(asyncns->queries));
  579. if (socketpair(PF_UNIX, SOCK_DGRAM, 0, asyncns->fds) < 0 ||
  580. socketpair(PF_UNIX, SOCK_DGRAM, 0, asyncns->fds+2) < 0)
  581. goto fail;
  582. for (i = 0; i < MESSAGE_FD_MAX; i++)
  583. fd_cloexec(asyncns->fds[i]);
  584. for (asyncns->valid_workers = 0; asyncns->valid_workers < n_proc; asyncns->valid_workers++) {
  585. #ifndef HAVE_PTHREAD
  586. if ((asyncns->workers[asyncns->valid_workers] = fork()) < 0)
  587. goto fail;
  588. else if (asyncns->workers[asyncns->valid_workers] == 0) {
  589. int ret;
  590. close(asyncns->fds[REQUEST_SEND_FD]);
  591. close(asyncns->fds[RESPONSE_RECV_FD]);
  592. ret = process_worker(asyncns->fds[REQUEST_RECV_FD], asyncns->fds[RESPONSE_SEND_FD]);
  593. close(asyncns->fds[REQUEST_RECV_FD]);
  594. close(asyncns->fds[RESPONSE_SEND_FD]);
  595. _exit(ret);
  596. }
  597. #else
  598. int r;
  599. if ((r = pthread_create(&asyncns->workers[asyncns->valid_workers], NULL, thread_worker, asyncns)) != 0) {
  600. errno = r;
  601. goto fail;
  602. }
  603. #endif
  604. }
  605. #ifndef HAVE_PTHREAD
  606. close(asyncns->fds[REQUEST_RECV_FD]);
  607. close(asyncns->fds[RESPONSE_SEND_FD]);
  608. asyncns->fds[REQUEST_RECV_FD] = asyncns->fds[RESPONSE_SEND_FD] = -1;
  609. #endif
  610. asyncns->current_index = asyncns->current_id = 0;
  611. asyncns->done_head = asyncns->done_tail = NULL;
  612. asyncns->n_queries = 0;
  613. fd_nonblock(asyncns->fds[RESPONSE_RECV_FD]);
  614. return asyncns;
  615. fail:
  616. if (asyncns)
  617. asyncns_free(asyncns);
  618. return NULL;
  619. }
  620. void asyncns_free(asyncns_t *asyncns) {
  621. int i;
  622. int saved_errno = errno;
  623. unsigned p;
  624. assert(asyncns);
  625. asyncns->dead = 1;
  626. if (asyncns->fds[REQUEST_SEND_FD] >= 0) {
  627. rheader_t req;
  628. memset(&req, 0, sizeof(req));
  629. req.type = REQUEST_TERMINATE;
  630. req.length = sizeof(req);
  631. req.id = 0;
  632. /* Send one termination packet for each worker */
  633. for (p = 0; p < asyncns->valid_workers; p++)
  634. send(asyncns->fds[REQUEST_SEND_FD], &req, req.length, MSG_NOSIGNAL);
  635. }
  636. /* Now terminate them and wait until they are gone. */
  637. for (p = 0; p < asyncns->valid_workers; p++) {
  638. #ifndef HAVE_PTHREAD
  639. kill(asyncns->workers[p], SIGTERM);
  640. for (;;) {
  641. if (waitpid(asyncns->workers[p], NULL, 0) >= 0 || errno != EINTR)
  642. break;
  643. }
  644. #else
  645. for (;;) {
  646. if (pthread_join(asyncns->workers[p], NULL) != EINTR)
  647. break;
  648. }
  649. #endif
  650. }
  651. /* Close all communication channels */
  652. for (i = 0; i < MESSAGE_FD_MAX; i++)
  653. if (asyncns->fds[i] >= 0)
  654. close(asyncns->fds[i]);
  655. for (p = 0; p < MAX_QUERIES; p++)
  656. if (asyncns->queries[p])
  657. asyncns_cancel(asyncns, asyncns->queries[p]);
  658. free(asyncns);
  659. errno = saved_errno;
  660. }
  661. int asyncns_fd(asyncns_t *asyncns) {
  662. assert(asyncns);
  663. return asyncns->fds[RESPONSE_RECV_FD];
  664. }
  665. static asyncns_query_t *lookup_query(asyncns_t *asyncns, unsigned id) {
  666. asyncns_query_t *q;
  667. assert(asyncns);
  668. if ((q = asyncns->queries[id % MAX_QUERIES]))
  669. if (q->id == id)
  670. return q;
  671. return NULL;
  672. }
  673. static void complete_query(asyncns_t *asyncns, asyncns_query_t *q) {
  674. assert(asyncns);
  675. assert(q);
  676. assert(!q->done);
  677. q->done = 1;
  678. if ((q->done_prev = asyncns->done_tail))
  679. asyncns->done_tail->done_next = q;
  680. else
  681. asyncns->done_head = q;
  682. asyncns->done_tail = q;
  683. q->done_next = NULL;
  684. }
  685. static const void *unserialize_addrinfo(const void *p, struct addrinfo **ret_ai, size_t *length) {
  686. addrinfo_serialization_t s;
  687. size_t l;
  688. struct addrinfo *ai;
  689. assert(p);
  690. assert(ret_ai);
  691. assert(length);
  692. if (*length < sizeof(addrinfo_serialization_t))
  693. return NULL;
  694. memcpy(&s, p, sizeof(s));
  695. l = sizeof(addrinfo_serialization_t) + s.ai_addrlen + s.canonname_len;
  696. if (*length < l)
  697. return NULL;
  698. if (!(ai = malloc(sizeof(struct addrinfo))))
  699. goto fail;
  700. ai->ai_addr = NULL;
  701. ai->ai_canonname = NULL;
  702. ai->ai_next = NULL;
  703. if (s.ai_addrlen && !(ai->ai_addr = malloc(s.ai_addrlen)))
  704. goto fail;
  705. if (s.canonname_len && !(ai->ai_canonname = malloc(s.canonname_len)))
  706. goto fail;
  707. ai->ai_flags = s.ai_flags;
  708. ai->ai_family = s.ai_family;
  709. ai->ai_socktype = s.ai_socktype;
  710. ai->ai_protocol = s.ai_protocol;
  711. ai->ai_addrlen = s.ai_addrlen;
  712. if (ai->ai_addr)
  713. memcpy(ai->ai_addr, (const uint8_t*) p + sizeof(addrinfo_serialization_t), s.ai_addrlen);
  714. if (ai->ai_canonname)
  715. memcpy(ai->ai_canonname, (const uint8_t*) p + sizeof(addrinfo_serialization_t) + s.ai_addrlen, s.canonname_len);
  716. *length -= l;
  717. *ret_ai = ai;
  718. return (const uint8_t*) p + l;
  719. fail:
  720. if (ai)
  721. asyncns_freeaddrinfo(ai);
  722. return NULL;
  723. }
  724. static int handle_response(asyncns_t *asyncns, const packet_t *packet, size_t length) {
  725. const rheader_t *resp;
  726. asyncns_query_t *q;
  727. assert(asyncns);
  728. resp = &packet->rheader;
  729. assert(resp);
  730. assert(length >= sizeof(rheader_t));
  731. assert(length == resp->length);
  732. if (resp->type == RESPONSE_DIED) {
  733. asyncns->dead = 1;
  734. return 0;
  735. }
  736. if (!(q = lookup_query(asyncns, resp->id)))
  737. return 0;
  738. switch (resp->type) {
  739. case RESPONSE_ADDRINFO: {
  740. const addrinfo_response_t *ai_resp = &packet->addrinfo_response;
  741. const void *p;
  742. size_t l;
  743. struct addrinfo *prev = NULL;
  744. assert(length >= sizeof(addrinfo_response_t));
  745. assert(q->type == REQUEST_ADDRINFO);
  746. q->ret = ai_resp->ret;
  747. q->_errno = ai_resp->_errno;
  748. q->_h_errno = ai_resp->_h_errno;
  749. l = length - sizeof(addrinfo_response_t);
  750. p = (const uint8_t*) resp + sizeof(addrinfo_response_t);
  751. while (l > 0 && p) {
  752. struct addrinfo *ai = NULL;
  753. p = unserialize_addrinfo(p, &ai, &l);
  754. if (!p || !ai) {
  755. q->ret = EAI_MEMORY;
  756. break;
  757. }
  758. if (prev)
  759. prev->ai_next = ai;
  760. else
  761. q->addrinfo = ai;
  762. prev = ai;
  763. }
  764. complete_query(asyncns, q);
  765. break;
  766. }
  767. case RESPONSE_NAMEINFO: {
  768. const nameinfo_response_t *ni_resp = &packet->nameinfo_response;
  769. assert(length >= sizeof(nameinfo_response_t));
  770. assert(q->type == REQUEST_NAMEINFO);
  771. q->ret = ni_resp->ret;
  772. q->_errno = ni_resp->_errno;
  773. q->_h_errno = ni_resp->_h_errno;
  774. if (ni_resp->hostlen)
  775. if (!(q->host = asyncns_strndup((const char*) ni_resp + sizeof(nameinfo_response_t), ni_resp->hostlen-1)))
  776. q->ret = EAI_MEMORY;
  777. if (ni_resp->servlen)
  778. if (!(q->serv = asyncns_strndup((const char*) ni_resp + sizeof(nameinfo_response_t) + ni_resp->hostlen, ni_resp->servlen-1)))
  779. q->ret = EAI_MEMORY;
  780. complete_query(asyncns, q);
  781. break;
  782. }
  783. default:
  784. ;
  785. }
  786. return 0;
  787. }
  788. int asyncns_wait(asyncns_t *asyncns, int block) {
  789. int handled = 0;
  790. assert(asyncns);
  791. for (;;) {
  792. packet_t buf[BUFSIZE/sizeof(packet_t) + 1];
  793. ssize_t l;
  794. if (asyncns->dead) {
  795. errno = ECHILD;
  796. return -1;
  797. }
  798. if (((l = recv(asyncns->fds[RESPONSE_RECV_FD], buf, sizeof(buf), 0)) < 0)) {
  799. fd_set fds;
  800. if (errno != EAGAIN)
  801. return -1;
  802. if (!block || handled)
  803. return 0;
  804. FD_ZERO(&fds);
  805. FD_SET(asyncns->fds[RESPONSE_RECV_FD], &fds);
  806. if (select(asyncns->fds[RESPONSE_RECV_FD]+1, &fds, NULL, NULL, NULL) < 0)
  807. return -1;
  808. continue;
  809. }
  810. if (handle_response(asyncns, buf, (size_t) l) < 0)
  811. return -1;
  812. handled = 1;
  813. }
  814. }
  815. static asyncns_query_t *alloc_query(asyncns_t *asyncns) {
  816. asyncns_query_t *q;
  817. assert(asyncns);
  818. if (asyncns->n_queries >= MAX_QUERIES) {
  819. errno = ENOMEM;
  820. return NULL;
  821. }
  822. while (asyncns->queries[asyncns->current_index]) {
  823. asyncns->current_index++;
  824. asyncns->current_id++;
  825. while (asyncns->current_index >= MAX_QUERIES)
  826. asyncns->current_index -= MAX_QUERIES;
  827. }
  828. if (!(q = asyncns->queries[asyncns->current_index] = malloc(sizeof(asyncns_query_t)))) {
  829. errno = ENOMEM;
  830. return NULL;
  831. }
  832. asyncns->n_queries++;
  833. q->asyncns = asyncns;
  834. q->done = 0;
  835. q->id = asyncns->current_id;
  836. q->done_next = q->done_prev = NULL;
  837. q->ret = 0;
  838. q->_errno = 0;
  839. q->_h_errno = 0;
  840. q->addrinfo = NULL;
  841. q->userdata = NULL;
  842. q->host = q->serv = NULL;
  843. return q;
  844. }
  845. asyncns_query_t* asyncns_getaddrinfo(asyncns_t *asyncns, const char *node, const char *service, const struct addrinfo *hints) {
  846. addrinfo_request_t data[BUFSIZE/sizeof(addrinfo_request_t) + 1];
  847. addrinfo_request_t *req = data;
  848. asyncns_query_t *q;
  849. assert(asyncns);
  850. assert(node || service);
  851. if (asyncns->dead) {
  852. errno = ECHILD;
  853. return NULL;
  854. }
  855. if (!(q = alloc_query(asyncns)))
  856. return NULL;
  857. memset(req, 0, sizeof(addrinfo_request_t));
  858. req->node_len = node ? strlen(node)+1 : 0;
  859. req->service_len = service ? strlen(service)+1 : 0;
  860. req->header.id = q->id;
  861. req->header.type = q->type = REQUEST_ADDRINFO;
  862. req->header.length = sizeof(addrinfo_request_t) + req->node_len + req->service_len;
  863. if (req->header.length > BUFSIZE) {
  864. errno = ENOMEM;
  865. goto fail;
  866. }
  867. if (!(req->hints_is_null = !hints)) {
  868. req->ai_flags = hints->ai_flags;
  869. req->ai_family = hints->ai_family;
  870. req->ai_socktype = hints->ai_socktype;
  871. req->ai_protocol = hints->ai_protocol;
  872. }
  873. if (node)
  874. strcpy((char*) req + sizeof(addrinfo_request_t), node);
  875. if (service)
  876. strcpy((char*) req + sizeof(addrinfo_request_t) + req->node_len, service);
  877. if (send(asyncns->fds[REQUEST_SEND_FD], req, req->header.length, MSG_NOSIGNAL) < 0)
  878. goto fail;
  879. return q;
  880. fail:
  881. if (q)
  882. asyncns_cancel(asyncns, q);
  883. return NULL;
  884. }
  885. int asyncns_getaddrinfo_done(asyncns_t *asyncns, asyncns_query_t* q, struct addrinfo **ret_res) {
  886. int ret;
  887. assert(asyncns);
  888. assert(q);
  889. assert(q->asyncns == asyncns);
  890. assert(q->type == REQUEST_ADDRINFO);
  891. if (asyncns->dead) {
  892. errno = ECHILD;
  893. return EAI_SYSTEM;
  894. }
  895. if (!q->done)
  896. return EAI_AGAIN;
  897. *ret_res = q->addrinfo;
  898. q->addrinfo = NULL;
  899. ret = q->ret;
  900. if (ret == EAI_SYSTEM)
  901. errno = q->_errno;
  902. if (ret != 0)
  903. h_errno = q->_h_errno;
  904. asyncns_cancel(asyncns, q);
  905. return ret;
  906. }
  907. asyncns_query_t* asyncns_getnameinfo(asyncns_t *asyncns, const struct sockaddr *sa, socklen_t salen, int flags, int gethost, int getserv) {
  908. nameinfo_request_t data[BUFSIZE/sizeof(nameinfo_request_t) + 1];
  909. nameinfo_request_t *req = data;
  910. asyncns_query_t *q;
  911. assert(asyncns);
  912. assert(sa);
  913. assert(salen > 0);
  914. if (asyncns->dead) {
  915. errno = ECHILD;
  916. return NULL;
  917. }
  918. if (!(q = alloc_query(asyncns)))
  919. return NULL;
  920. memset(req, 0, sizeof(nameinfo_request_t));
  921. req->header.id = q->id;
  922. req->header.type = q->type = REQUEST_NAMEINFO;
  923. req->header.length = sizeof(nameinfo_request_t) + salen;
  924. if (req->header.length > BUFSIZE) {
  925. errno = ENOMEM;
  926. goto fail;
  927. }
  928. req->flags = flags;
  929. req->sockaddr_len = salen;
  930. req->gethost = gethost;
  931. req->getserv = getserv;
  932. memcpy((uint8_t*) req + sizeof(nameinfo_request_t), sa, salen);
  933. if (send(asyncns->fds[REQUEST_SEND_FD], req, req->header.length, MSG_NOSIGNAL) < 0)
  934. goto fail;
  935. return q;
  936. fail:
  937. if (q)
  938. asyncns_cancel(asyncns, q);
  939. return NULL;
  940. }
  941. int asyncns_getnameinfo_done(asyncns_t *asyncns, asyncns_query_t* q, char *ret_host, size_t hostlen, char *ret_serv, size_t servlen) {
  942. int ret;
  943. assert(asyncns);
  944. assert(q);
  945. assert(q->asyncns == asyncns);
  946. assert(q->type == REQUEST_NAMEINFO);
  947. assert(!ret_host || hostlen);
  948. assert(!ret_serv || servlen);
  949. if (asyncns->dead) {
  950. errno = ECHILD;
  951. return EAI_SYSTEM;
  952. }
  953. if (!q->done)
  954. return EAI_AGAIN;
  955. if (ret_host && q->host) {
  956. strncpy(ret_host, q->host, hostlen);
  957. ret_host[hostlen-1] = 0;
  958. }
  959. if (ret_serv && q->serv) {
  960. strncpy(ret_serv, q->serv, servlen);
  961. ret_serv[servlen-1] = 0;
  962. }
  963. ret = q->ret;
  964. if (ret == EAI_SYSTEM)
  965. errno = q->_errno;
  966. if (ret != 0)
  967. h_errno = q->_h_errno;
  968. asyncns_cancel(asyncns, q);
  969. return ret;
  970. }
  971. static asyncns_query_t * asyncns_res(asyncns_t *asyncns, query_type_t qtype, const char *dname, int class, int type) {
  972. res_request_t data[BUFSIZE/sizeof(res_request_t) + 1];
  973. res_request_t *req = data;
  974. asyncns_query_t *q;
  975. assert(asyncns);
  976. assert(dname);
  977. if (asyncns->dead) {
  978. errno = ECHILD;
  979. return NULL;
  980. }
  981. if (!(q = alloc_query(asyncns)))
  982. return NULL;
  983. memset(req, 0, sizeof(res_request_t));
  984. req->dname_len = strlen(dname) + 1;
  985. req->header.id = q->id;
  986. req->header.type = q->type = qtype;
  987. req->header.length = sizeof(res_request_t) + req->dname_len;
  988. if (req->header.length > BUFSIZE) {
  989. errno = ENOMEM;
  990. goto fail;
  991. }
  992. req->class = class;
  993. req->type = type;
  994. strcpy((char*) req + sizeof(res_request_t), dname);
  995. if (send(asyncns->fds[REQUEST_SEND_FD], req, req->header.length, MSG_NOSIGNAL) < 0)
  996. goto fail;
  997. return q;
  998. fail:
  999. if (q)
  1000. asyncns_cancel(asyncns, q);
  1001. return NULL;
  1002. }
  1003. asyncns_query_t* asyncns_getnext(asyncns_t *asyncns) {
  1004. assert(asyncns);
  1005. return asyncns->done_head;
  1006. }
  1007. int asyncns_getnqueries(asyncns_t *asyncns) {
  1008. assert(asyncns);
  1009. return asyncns->n_queries;
  1010. }
  1011. void asyncns_cancel(asyncns_t *asyncns, asyncns_query_t* q) {
  1012. int i;
  1013. int saved_errno = errno;
  1014. assert(asyncns);
  1015. assert(q);
  1016. assert(q->asyncns == asyncns);
  1017. assert(asyncns->n_queries > 0);
  1018. if (q->done) {
  1019. if (q->done_prev)
  1020. q->done_prev->done_next = q->done_next;
  1021. else
  1022. asyncns->done_head = q->done_next;
  1023. if (q->done_next)
  1024. q->done_next->done_prev = q->done_prev;
  1025. else
  1026. asyncns->done_tail = q->done_prev;
  1027. }
  1028. i = q->id % MAX_QUERIES;
  1029. assert(asyncns->queries[i] == q);
  1030. asyncns->queries[i] = NULL;
  1031. asyncns_freeaddrinfo(q->addrinfo);
  1032. free(q->host);
  1033. free(q->serv);
  1034. asyncns->n_queries--;
  1035. free(q);
  1036. errno = saved_errno;
  1037. }
  1038. void asyncns_freeaddrinfo(struct addrinfo *ai) {
  1039. int saved_errno = errno;
  1040. while (ai) {
  1041. struct addrinfo *next = ai->ai_next;
  1042. free(ai->ai_addr);
  1043. free(ai->ai_canonname);
  1044. free(ai);
  1045. ai = next;
  1046. }
  1047. errno = saved_errno;
  1048. }
  1049. void asyncns_freeanswer(unsigned char *answer) {
  1050. int saved_errno = errno;
  1051. if (!answer)
  1052. return;
  1053. /* Please note that this function is new in libasyncns 0.4. In
  1054. * older versions you were supposed to free the answer directly
  1055. * with free(). Hence, if this function is changed to do more than
  1056. * just a simple free() this must be considered ABI/API breakage! */
  1057. free(answer);
  1058. errno = saved_errno;
  1059. }
  1060. int asyncns_isdone(asyncns_t *asyncns, asyncns_query_t*q) {
  1061. assert(asyncns);
  1062. assert(q);
  1063. assert(q->asyncns == asyncns);
  1064. return q->done;
  1065. }
  1066. void asyncns_setuserdata(asyncns_t *asyncns, asyncns_query_t *q, void *userdata) {
  1067. assert(q);
  1068. assert(asyncns);
  1069. assert(q->asyncns = asyncns);
  1070. q->userdata = userdata;
  1071. }
  1072. void* asyncns_getuserdata(asyncns_t *asyncns, asyncns_query_t *q) {
  1073. assert(q);
  1074. assert(asyncns);
  1075. assert(q->asyncns = asyncns);
  1076. return q->userdata;
  1077. }