155f491ae4baa971c605409017eb7ad4966384d0
[platform/upstream/glib2.0.git] / gio / libasyncns / asyncns.c
1 /***
2   This file is part of libasyncns.
3
4   Copyright 2005-2008 Lennart Poettering
5
6   libasyncns is free software; you can redistribute it and/or modify
7   it under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation, either version 2.1 of the
9   License, or (at your option) any later version.
10
11   libasyncns is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with libasyncns. If not, see
18   <http://www.gnu.org/licenses/>.
19 ***/
20
21 #ifdef HAVE_CONFIG_H
22 #include "g-asyncns.h"
23 #endif
24
25 /* #undef HAVE_PTHREAD */
26
27 #include <assert.h>
28 #include <fcntl.h>
29 #include <signal.h>
30 #include <unistd.h>
31
32 #ifdef HAVE_SYS_SELECT_H
33 #include <sys/select.h>
34 #endif
35
36 #include <stdio.h>
37 #include <string.h>
38 #include <stdlib.h>
39 #include <errno.h>
40 #include <sys/wait.h>
41 #include <sys/types.h>
42 #include <pwd.h>
43 #include <netinet/in.h>
44 #include <arpa/nameser.h>
45 #include <resolv.h>
46 #include <dirent.h>
47
48 #ifdef HAVE_SYS_TIME_H
49 #include <sys/time.h>
50 #endif
51
52 #include <sys/resource.h>
53 #ifdef HAVE_STDINT_H
54 #include <stdint.h>
55 #endif
56 #ifdef HAVE_INTTYPES_H
57 #include <inttypes.h>
58 #endif
59
60 #ifdef HAVE_SYS_PRCTL_H
61 #include <sys/prctl.h>
62 #endif
63
64 #if HAVE_PTHREAD
65 #include <pthread.h>
66 #endif
67
68 #include "asyncns.h"
69
70 #ifndef MSG_NOSIGNAL
71 #define MSG_NOSIGNAL 0
72 #endif
73
74 #define MAX_WORKERS 16
75 #define MAX_QUERIES 256
76 #define BUFSIZE (10240)
77
78 typedef enum {
79     REQUEST_ADDRINFO,
80     RESPONSE_ADDRINFO,
81     REQUEST_NAMEINFO,
82     RESPONSE_NAMEINFO,
83     REQUEST_RES_QUERY,
84     REQUEST_RES_SEARCH,
85     RESPONSE_RES,
86     REQUEST_TERMINATE,
87     RESPONSE_DIED
88 } query_type_t;
89
90 enum {
91     REQUEST_RECV_FD = 0,
92     REQUEST_SEND_FD = 1,
93     RESPONSE_RECV_FD = 2,
94     RESPONSE_SEND_FD = 3,
95     MESSAGE_FD_MAX = 4
96 };
97
98 struct asyncns {
99     int fds[4];
100
101 #ifndef HAVE_PTHREAD
102     pid_t workers[MAX_WORKERS];
103 #else
104     pthread_t workers[MAX_WORKERS];
105 #endif
106     unsigned valid_workers;
107
108     unsigned current_id, current_index;
109     _g_asyncns_query_t* queries[MAX_QUERIES];
110
111     _g_asyncns_query_t *done_head, *done_tail;
112
113     int n_queries;
114     int dead;
115 };
116
117 struct _g_asyncns_query {
118     _g_asyncns_t *asyncns;
119     int done;
120     unsigned id;
121     query_type_t type;
122     _g_asyncns_query_t *done_next, *done_prev;
123     int ret;
124     int _errno;
125     int _h_errno;
126     struct addrinfo *addrinfo;
127     char *serv, *host;
128     void *userdata;
129 };
130
131 typedef struct rheader {
132     query_type_t type;
133     unsigned id;
134     size_t length;
135 } rheader_t;
136
137 typedef struct addrinfo_request {
138     struct rheader header;
139     int hints_is_null;
140     int ai_flags;
141     int ai_family;
142     int ai_socktype;
143     int ai_protocol;
144     size_t node_len, service_len;
145 } addrinfo_request_t;
146
147 typedef struct addrinfo_response {
148     struct rheader header;
149     int ret;
150     int _errno;
151     int _h_errno;
152     /* followed by addrinfo_serialization[] */
153 } addrinfo_response_t;
154
155 typedef struct addrinfo_serialization {
156     int ai_flags;
157     int ai_family;
158     int ai_socktype;
159     int ai_protocol;
160     size_t ai_addrlen;
161     size_t canonname_len;
162     /* Followed by ai_addr amd ai_canonname with variable lengths */
163 } addrinfo_serialization_t;
164
165 typedef struct nameinfo_request {
166     struct rheader header;
167     int flags;
168     socklen_t sockaddr_len;
169     int gethost, getserv;
170 } nameinfo_request_t;
171
172 typedef struct nameinfo_response {
173     struct rheader header;
174     size_t hostlen, servlen;
175     int ret;
176     int _errno;
177     int _h_errno;
178 } nameinfo_response_t;
179
180 typedef struct res_request {
181     struct rheader header;
182     int class;
183     int type;
184     size_t dname_len;
185 } res_request_t;
186
187 typedef struct res_response {
188     struct rheader header;
189     int ret;
190     int _errno;
191     int _h_errno;
192 } res_response_t;
193
194 typedef union packet {
195     rheader_t rheader;
196     addrinfo_request_t addrinfo_request;
197     addrinfo_response_t addrinfo_response;
198     nameinfo_request_t nameinfo_request;
199     nameinfo_response_t nameinfo_response;
200     res_request_t res_request;
201     res_response_t res_response;
202 } packet_t;
203
204 #ifndef HAVE_STRNDUP
205
206 static char *strndup(const char *s, size_t l) {
207     size_t a;
208     char *n;
209
210     a = strlen(s);
211     if (a > l)
212         a = l;
213
214     if (!(n = malloc(a+1)))
215         return NULL;
216
217     memcpy(n, s, a);
218     n[a] = 0;
219
220     return n;
221 }
222
223 #endif
224
225 #ifndef HAVE_PTHREAD
226
227 static int close_allv(const int except_fds[]) {
228     struct rlimit rl;
229     int fd, maxfd;
230
231 #ifdef __linux__
232
233     DIR *d;
234
235     assert(except_fds);
236
237     if ((d = opendir("/proc/self/fd"))) {
238
239         struct dirent *de;
240
241         while ((de = readdir(d))) {
242             int found;
243             long l;
244             char *e = NULL;
245             int i;
246
247             if (de->d_name[0] == '.')
248                 continue;
249
250             errno = 0;
251             l = strtol(de->d_name, &e, 10);
252             if (errno != 0 || !e || *e) {
253                 closedir(d);
254                 errno = EINVAL;
255                 return -1;
256             }
257
258             fd = (int) l;
259
260             if ((long) fd != l) {
261                 closedir(d);
262                 errno = EINVAL;
263                 return -1;
264             }
265
266             if (fd < 3)
267                 continue;
268
269             if (fd == dirfd(d))
270                 continue;
271
272             found = 0;
273             for (i = 0; except_fds[i] >= 0; i++)
274                 if (except_fds[i] == fd) {
275                     found = 1;
276                     break;
277                 }
278
279             if (found)
280                 continue;
281
282             if (close(fd) < 0) {
283                 int saved_errno;
284
285                 saved_errno = errno;
286                 closedir(d);
287                 errno = saved_errno;
288
289                 return -1;
290             }
291         }
292
293         closedir(d);
294         return 0;
295     }
296
297 #endif
298
299     if (getrlimit(RLIMIT_NOFILE, &rl) > 0)
300         maxfd = (int) rl.rlim_max;
301     else
302         maxfd = sysconf(_SC_OPEN_MAX);
303
304     for (fd = 3; fd < maxfd; fd++) {
305         int i, found;
306
307         found = 0;
308         for (i = 0; except_fds[i] >= 0; i++)
309             if (except_fds[i] == fd) {
310                 found = 1;
311                 continue;
312             }
313
314         if (found)
315             continue;
316
317         if (close(fd) < 0 && errno != EBADF)
318             return -1;
319     }
320
321     return 0;
322 }
323
324 static int reset_sigsv(const int except[]) {
325     int sig;
326     assert(except);
327
328     for (sig = 1; sig < NSIG; sig++) {
329         int reset = 1;
330
331         switch (sig) {
332             case SIGKILL:
333             case SIGSTOP:
334                 reset = 0;
335                 break;
336
337             default: {
338                 int i;
339
340                 for (i = 0; except[i] > 0; i++) {
341                     if (sig == except[i]) {
342                         reset = 0;
343                         break;
344                     }
345                 }
346             }
347         }
348
349         if (reset) {
350             struct sigaction sa;
351
352             memset(&sa, 0, sizeof(sa));
353             sa.sa_handler = SIG_DFL;
354
355             /* On Linux the first two RT signals are reserved by
356              * glibc, and sigaction() will return EINVAL for them. */
357             if ((sigaction(sig, &sa, NULL) < 0))
358                 if (errno != EINVAL)
359                     return -1;
360         }
361     }
362
363     return 0;
364 }
365
366 static int ignore_sigsv(const int ignore[]) {
367     int i;
368     assert(ignore);
369
370     for (i = 0; ignore[i] > 0; i++) {
371         struct sigaction sa;
372
373         memset(&sa, 0, sizeof(sa));
374         sa.sa_handler = SIG_IGN;
375
376         if ((sigaction(ignore[i], &sa, NULL) < 0))
377             return -1;
378     }
379
380     return 0;
381 }
382
383 #endif
384
385 static int fd_nonblock(int fd) {
386     int i;
387     assert(fd >= 0);
388
389     if ((i = fcntl(fd, F_GETFL, 0)) < 0)
390         return -1;
391
392     if (i & O_NONBLOCK)
393         return 0;
394
395     return fcntl(fd, F_SETFL, i | O_NONBLOCK);
396 }
397
398 static int fd_cloexec(int fd) {
399     int v;
400     assert(fd >= 0);
401
402     if ((v = fcntl(fd, F_GETFD, 0)) < 0)
403         return -1;
404
405     if (v & FD_CLOEXEC)
406         return 0;
407
408     return fcntl(fd, F_SETFD, v | FD_CLOEXEC);
409 }
410
411 static int send_died(int out_fd) {
412     rheader_t rh;
413     assert(out_fd > 0);
414
415     memset(&rh, 0, sizeof(rh));
416     rh.type = RESPONSE_DIED;
417     rh.id = 0;
418     rh.length = sizeof(rh);
419
420     return send(out_fd, &rh, rh.length, MSG_NOSIGNAL);
421 }
422
423 static void *serialize_addrinfo(void *p, const struct addrinfo *ai, size_t *length, size_t maxlength) {
424     addrinfo_serialization_t s;
425     size_t cnl, l;
426     assert(p);
427     assert(ai);
428     assert(length);
429     assert(*length <= maxlength);
430
431     cnl = (ai->ai_canonname ? strlen(ai->ai_canonname)+1 : 0);
432     l = sizeof(addrinfo_serialization_t) + ai->ai_addrlen + cnl;
433
434     if (*length + l > maxlength)
435         return NULL;
436
437     s.ai_flags = ai->ai_flags;
438     s.ai_family = ai->ai_family;
439     s.ai_socktype = ai->ai_socktype;
440     s.ai_protocol = ai->ai_protocol;
441     s.ai_addrlen = ai->ai_addrlen;
442     s.canonname_len = cnl;
443
444     memcpy((uint8_t*) p, &s, sizeof(addrinfo_serialization_t));
445     memcpy((uint8_t*) p + sizeof(addrinfo_serialization_t), ai->ai_addr, ai->ai_addrlen);
446
447     if (ai->ai_canonname)
448         strcpy((char*) p + sizeof(addrinfo_serialization_t) + ai->ai_addrlen, ai->ai_canonname);
449
450     *length += l;
451     return (uint8_t*) p + l;
452 }
453
454 static int send_addrinfo_reply(int out_fd, unsigned id, int ret, struct addrinfo *ai, int _errno, int _h_errno) {
455     addrinfo_response_t data[BUFSIZE/sizeof(addrinfo_response_t) + 1];
456     addrinfo_response_t *resp = data;
457     assert(out_fd >= 0);
458
459     memset(data, 0, sizeof(data));
460     resp->header.type = RESPONSE_ADDRINFO;
461     resp->header.id = id;
462     resp->header.length = sizeof(addrinfo_response_t);
463     resp->ret = ret;
464     resp->_errno = _errno;
465     resp->_h_errno = _h_errno;
466
467     if (ret == 0 && ai) {
468         void *p = data + 1;
469         struct addrinfo *k;
470
471         for (k = ai; k; k = k->ai_next) {
472
473             if (!(p = serialize_addrinfo(p, k, &resp->header.length, (char*) data + BUFSIZE - (char*) p))) {
474                 resp->ret = EAI_MEMORY;
475                 break;
476             }
477         }
478     }
479
480     if (ai)
481         freeaddrinfo(ai);
482
483     return send(out_fd, resp, resp->header.length, MSG_NOSIGNAL);
484 }
485
486 static int send_nameinfo_reply(int out_fd, unsigned id, int ret, const char *host, const char *serv, int _errno, int _h_errno) {
487     nameinfo_response_t data[BUFSIZE/sizeof(nameinfo_response_t) + 1];
488     size_t hl, sl;
489     nameinfo_response_t *resp = data;
490
491     assert(out_fd >= 0);
492
493     sl = serv ? strlen(serv)+1 : 0;
494     hl = host ? strlen(host)+1 : 0;
495
496     memset(data, 0, sizeof(data));
497     resp->header.type = RESPONSE_NAMEINFO;
498     resp->header.id = id;
499     resp->header.length = sizeof(nameinfo_response_t) + hl + sl;
500     resp->ret = ret;
501     resp->_errno = _errno;
502     resp->_h_errno = _h_errno;
503     resp->hostlen = hl;
504     resp->servlen = sl;
505
506     assert(sizeof(data) >= resp->header.length);
507
508     if (host)
509         memcpy((uint8_t *)data + sizeof(nameinfo_response_t), host, hl);
510
511     if (serv)
512         memcpy((uint8_t *)data + sizeof(nameinfo_response_t) + hl, serv, sl);
513
514     return send(out_fd, resp, resp->header.length, MSG_NOSIGNAL);
515 }
516
517 static int send_res_reply(int out_fd, unsigned id, const unsigned char *answer, int ret, int _errno, int _h_errno) {
518     res_response_t data[BUFSIZE/sizeof(res_response_t) + 1];
519     res_response_t *resp = data;
520
521     assert(out_fd >= 0);
522
523     memset(data, 0, sizeof(data));
524     resp->header.type = RESPONSE_RES;
525     resp->header.id = id;
526     resp->header.length = sizeof(res_response_t) + (ret < 0 ? 0 : ret);
527     resp->ret = ret;
528     resp->_errno = _errno;
529     resp->_h_errno = _h_errno;
530
531     assert(sizeof(data) >= resp->header.length);
532
533     if (ret > 0)
534         memcpy((uint8_t *)data + sizeof(res_response_t), answer, ret);
535
536     return send(out_fd, resp, resp->header.length, MSG_NOSIGNAL);
537 }
538
539 static int handle_request(int out_fd, const packet_t *packet, size_t length) {
540     const rheader_t *req;
541     assert(out_fd >= 0);
542
543     req = &packet->rheader;
544     assert(req);
545     assert(length >= sizeof(rheader_t));
546     assert(length == req->length);
547
548     switch (req->type) {
549
550         case REQUEST_ADDRINFO: {
551             struct addrinfo ai, *result = NULL;
552             const addrinfo_request_t *ai_req = &packet->addrinfo_request;
553             const char *node, *service;
554             int ret;
555
556             assert(length >= sizeof(addrinfo_request_t));
557             assert(length == sizeof(addrinfo_request_t) + ai_req->node_len + ai_req->service_len);
558
559             memset(&ai, 0, sizeof(ai));
560             ai.ai_flags = ai_req->ai_flags;
561             ai.ai_family = ai_req->ai_family;
562             ai.ai_socktype = ai_req->ai_socktype;
563             ai.ai_protocol = ai_req->ai_protocol;
564
565             node = ai_req->node_len ? (const char*) ai_req + sizeof(addrinfo_request_t) : NULL;
566             service = ai_req->service_len ? (const char*) ai_req + sizeof(addrinfo_request_t) + ai_req->node_len : NULL;
567
568             ret = getaddrinfo(node, service,
569                               ai_req->hints_is_null ? NULL : &ai,
570                               &result);
571
572             /* send_addrinfo_reply() frees result */
573             return send_addrinfo_reply(out_fd, req->id, ret, result, errno, h_errno);
574         }
575
576         case REQUEST_NAMEINFO: {
577             int ret;
578             const nameinfo_request_t *ni_req = &packet->nameinfo_request;
579             char hostbuf[NI_MAXHOST], servbuf[NI_MAXSERV];
580             struct sockaddr_storage sa;
581
582             assert(length >= sizeof(nameinfo_request_t));
583             assert(length == sizeof(nameinfo_request_t) + ni_req->sockaddr_len);
584
585             memcpy(&sa, (const uint8_t *) ni_req + sizeof(nameinfo_request_t), ni_req->sockaddr_len);
586
587             ret = getnameinfo((struct sockaddr *)&sa, ni_req->sockaddr_len,
588                               ni_req->gethost ? hostbuf : NULL, ni_req->gethost ? sizeof(hostbuf) : 0,
589                               ni_req->getserv ? servbuf : NULL, ni_req->getserv ? sizeof(servbuf) : 0,
590                               ni_req->flags);
591
592             return send_nameinfo_reply(out_fd, req->id, ret,
593                                        ret == 0 && ni_req->gethost ? hostbuf : NULL,
594                                        ret == 0 && ni_req->getserv ? servbuf : NULL,
595                                        errno, h_errno);
596         }
597
598         case REQUEST_RES_QUERY:
599         case REQUEST_RES_SEARCH: {
600             int ret;
601             HEADER answer[BUFSIZE/sizeof(HEADER) + 1];
602             const res_request_t *res_req = &packet->res_request;
603             const char *dname;
604
605             assert(length >= sizeof(res_request_t));
606             assert(length == sizeof(res_request_t) + res_req->dname_len);
607
608             dname = (const char *) req + sizeof(res_request_t);
609
610             if (req->type == REQUEST_RES_QUERY)
611                 ret = res_query(dname, res_req->class, res_req->type, (unsigned char *) answer, BUFSIZE);
612             else
613                 ret = res_search(dname, res_req->class, res_req->type, (unsigned char *) answer, BUFSIZE);
614
615             return send_res_reply(out_fd, req->id, (unsigned char *) answer, ret, errno, h_errno);
616         }
617
618         case REQUEST_TERMINATE:
619             /* Quit */
620             return -1;
621
622         default:
623             ;
624     }
625
626     return 0;
627 }
628
629 #ifndef HAVE_PTHREAD
630
631 static int process_worker(int in_fd, int out_fd) {
632     int have_death_sig = 0;
633     int good_fds[3];
634     int ret = 1;
635
636     const int ignore_sigs[] = {
637         SIGINT,
638         SIGHUP,
639         SIGPIPE,
640         SIGUSR1,
641         SIGUSR2,
642         -1
643     };
644
645     assert(in_fd > 2);
646     assert(out_fd > 2);
647
648     close(0);
649     close(1);
650     close(2);
651
652     if (open("/dev/null", O_RDONLY) != 0)
653         goto fail;
654
655     if (open("/dev/null", O_WRONLY) != 1)
656         goto fail;
657
658     if (open("/dev/null", O_WRONLY) != 2)
659         goto fail;
660
661     if (chdir("/") < 0)
662         goto fail;
663
664     if (geteuid() == 0) {
665         struct passwd *pw;
666         int r;
667
668         if ((pw = getpwnam("nobody"))) {
669 #ifdef HAVE_SETRESUID
670             r = setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
671 #elif HAVE_SETREUID
672             r = setreuid(pw->pw_uid, pw->pw_uid);
673 #else
674             if ((r = setuid(pw->pw_uid)) >= 0)
675                 r = seteuid(pw->pw_uid);
676 #endif
677             if (r < 0)
678                 goto fail;
679         }
680     }
681
682     if (reset_sigsv(ignore_sigs) < 0)
683         goto fail;
684
685     if (ignore_sigsv(ignore_sigs) < 0)
686         goto fail;
687
688     good_fds[0] = in_fd; good_fds[1] = out_fd; good_fds[2] = -1;
689     if (close_allv(good_fds) < 0)
690         goto fail;
691
692 #ifdef PR_SET_PDEATHSIG
693     if (prctl(PR_SET_PDEATHSIG, SIGTERM) >= 0)
694         have_death_sig = 1;
695 #endif
696
697     if (!have_death_sig)
698         fd_nonblock(in_fd);
699
700     while (getppid() > 1) { /* if the parent PID is 1 our parent process died. */
701         packet_t buf[BUFSIZE/sizeof(packet_t) + 1];
702         ssize_t length;
703
704         if (!have_death_sig) {
705             fd_set fds;
706             struct timeval tv = { 0, 500000 };
707
708             FD_ZERO(&fds);
709             FD_SET(in_fd, &fds);
710
711             if (select(in_fd+1, &fds, NULL, NULL, &tv) < 0)
712                 break;
713
714             if (getppid() == 1)
715                 break;
716         }
717
718         if ((length = recv(in_fd, buf, sizeof(buf), 0)) <= 0) {
719
720             if (length < 0 &&
721                 (errno == EAGAIN || errno == EINTR))
722                 continue;
723
724             break;
725         }
726
727         if (handle_request(out_fd, buf, (size_t) length) < 0)
728             break;
729     }
730
731     ret = 0;
732
733 fail:
734     send_died(out_fd);
735
736     return ret;
737 }
738
739 #else
740
741 static void* thread_worker(void *p) {
742     _g_asyncns_t *asyncns = p;
743     sigset_t fullset;
744
745     /* No signals in this thread please */
746     sigfillset(&fullset);
747     pthread_sigmask(SIG_BLOCK, &fullset, NULL);
748
749     while (!asyncns->dead) {
750         packet_t buf[BUFSIZE/sizeof(packet_t) + 1];
751         ssize_t length;
752
753         if ((length = recv(asyncns->fds[REQUEST_RECV_FD], buf, sizeof(buf), 0)) <= 0) {
754
755             if (length < 0 &&
756                 (errno == EAGAIN || errno == EINTR))
757                 continue;
758
759             break;
760         }
761
762         if (asyncns->dead)
763             break;
764
765         if (handle_request(asyncns->fds[RESPONSE_SEND_FD], buf, (size_t) length) < 0)
766             break;
767     }
768
769     send_died(asyncns->fds[RESPONSE_SEND_FD]);
770
771     return NULL;
772 }
773
774 #endif
775
776 _g_asyncns_t* _g_asyncns_new(unsigned n_proc) {
777     _g_asyncns_t *asyncns = NULL;
778     int i;
779     assert(n_proc >= 1);
780
781     if (n_proc > MAX_WORKERS)
782         n_proc = MAX_WORKERS;
783
784     if (!(asyncns = malloc(sizeof(_g_asyncns_t)))) {
785         errno = ENOMEM;
786         goto fail;
787     }
788
789     asyncns->dead = 0;
790     asyncns->valid_workers = 0;
791
792     for (i = 0; i < MESSAGE_FD_MAX; i++)
793         asyncns->fds[i] = -1;
794
795     memset(asyncns->queries, 0, sizeof(asyncns->queries));
796
797     if (socketpair(PF_UNIX, SOCK_DGRAM, 0, asyncns->fds) < 0 ||
798         socketpair(PF_UNIX, SOCK_DGRAM, 0, asyncns->fds+2) < 0)
799         goto fail;
800
801     for (i = 0; i < MESSAGE_FD_MAX; i++)
802         fd_cloexec(asyncns->fds[i]);
803
804     for (asyncns->valid_workers = 0; asyncns->valid_workers < n_proc; asyncns->valid_workers++) {
805
806 #ifndef HAVE_PTHREAD
807         if ((asyncns->workers[asyncns->valid_workers] = fork()) < 0)
808             goto fail;
809         else if (asyncns->workers[asyncns->valid_workers] == 0) {
810             int ret;
811
812             close(asyncns->fds[REQUEST_SEND_FD]);
813             close(asyncns->fds[RESPONSE_RECV_FD]);
814             ret = process_worker(asyncns->fds[REQUEST_RECV_FD], asyncns->fds[RESPONSE_SEND_FD]);
815             close(asyncns->fds[REQUEST_RECV_FD]);
816             close(asyncns->fds[RESPONSE_SEND_FD]);
817             _exit(ret);
818         }
819 #else
820         int r;
821
822         if ((r = pthread_create(&asyncns->workers[asyncns->valid_workers], NULL, thread_worker, asyncns)) != 0) {
823             errno = r;
824             goto fail;
825         }
826 #endif
827     }
828
829 #ifndef HAVE_PTHREAD
830     close(asyncns->fds[REQUEST_RECV_FD]);
831     close(asyncns->fds[RESPONSE_SEND_FD]);
832     asyncns->fds[REQUEST_RECV_FD] = asyncns->fds[RESPONSE_SEND_FD] = -1;
833 #endif
834
835     asyncns->current_index = asyncns->current_id = 0;
836     asyncns->done_head = asyncns->done_tail = NULL;
837     asyncns->n_queries = 0;
838
839     fd_nonblock(asyncns->fds[RESPONSE_RECV_FD]);
840
841     return asyncns;
842
843 fail:
844     if (asyncns)
845         _g_asyncns_free(asyncns);
846
847     return NULL;
848 }
849
850 void _g_asyncns_free(_g_asyncns_t *asyncns) {
851     int i;
852     int saved_errno = errno;
853     unsigned p;
854
855     assert(asyncns);
856
857     asyncns->dead = 1;
858
859     if (asyncns->fds[REQUEST_SEND_FD] >= 0) {
860         rheader_t req;
861
862         memset(&req, 0, sizeof(req));
863         req.type = REQUEST_TERMINATE;
864         req.length = sizeof(req);
865         req.id = 0;
866
867         /* Send one termination packet for each worker */
868         for (p = 0; p < asyncns->valid_workers; p++)
869             send(asyncns->fds[REQUEST_SEND_FD], &req, req.length, MSG_NOSIGNAL);
870     }
871
872     /* Now terminate them and wait until they are gone. */
873     for (p = 0; p < asyncns->valid_workers; p++) {
874 #ifndef HAVE_PTHREAD
875         kill(asyncns->workers[p], SIGTERM);
876         for (;;) {
877             if (waitpid(asyncns->workers[p], NULL, 0) >= 0 || errno != EINTR)
878                 break;
879         }
880 #else
881         for (;;) {
882             if (pthread_join(asyncns->workers[p], NULL) != EINTR)
883                 break;
884         }
885 #endif
886     }
887
888     /* Close all communication channels */
889     for (i = 0; i < MESSAGE_FD_MAX; i++)
890         if (asyncns->fds[i] >= 0)
891             close(asyncns->fds[i]);
892
893     for (p = 0; p < MAX_QUERIES; p++)
894         if (asyncns->queries[p])
895             _g_asyncns_cancel(asyncns, asyncns->queries[p]);
896
897     free(asyncns);
898
899     errno = saved_errno;
900 }
901
902 int _g_asyncns_fd(_g_asyncns_t *asyncns) {
903     assert(asyncns);
904
905     return asyncns->fds[RESPONSE_RECV_FD];
906 }
907
908 static _g_asyncns_query_t *lookup_query(_g_asyncns_t *asyncns, unsigned id) {
909     _g_asyncns_query_t *q;
910     assert(asyncns);
911
912     if ((q = asyncns->queries[id % MAX_QUERIES]))
913         if (q->id == id)
914             return q;
915
916     return NULL;
917 }
918
919 static void complete_query(_g_asyncns_t *asyncns, _g_asyncns_query_t *q) {
920     assert(asyncns);
921     assert(q);
922     assert(!q->done);
923
924     q->done = 1;
925
926     if ((q->done_prev = asyncns->done_tail))
927         asyncns->done_tail->done_next = q;
928     else
929         asyncns->done_head = q;
930
931     asyncns->done_tail = q;
932     q->done_next = NULL;
933 }
934
935 static const void *unserialize_addrinfo(const void *p, struct addrinfo **ret_ai, size_t *length) {
936     addrinfo_serialization_t s;
937     size_t l;
938     struct addrinfo *ai;
939     assert(p);
940     assert(ret_ai);
941     assert(length);
942
943     if (*length < sizeof(addrinfo_serialization_t))
944         return NULL;
945
946     memcpy(&s, p, sizeof(s));
947
948     l = sizeof(addrinfo_serialization_t) + s.ai_addrlen + s.canonname_len;
949     if (*length < l)
950         return NULL;
951
952     if (!(ai = malloc(sizeof(struct addrinfo))))
953         goto fail;
954
955     ai->ai_addr = NULL;
956     ai->ai_canonname = NULL;
957     ai->ai_next = NULL;
958
959     if (s.ai_addrlen && !(ai->ai_addr = malloc(s.ai_addrlen)))
960         goto fail;
961
962     if (s.canonname_len && !(ai->ai_canonname = malloc(s.canonname_len)))
963         goto fail;
964
965     ai->ai_flags = s.ai_flags;
966     ai->ai_family = s.ai_family;
967     ai->ai_socktype = s.ai_socktype;
968     ai->ai_protocol = s.ai_protocol;
969     ai->ai_addrlen = s.ai_addrlen;
970
971     if (ai->ai_addr)
972         memcpy(ai->ai_addr, (const uint8_t*) p + sizeof(addrinfo_serialization_t), s.ai_addrlen);
973
974     if (ai->ai_canonname)
975         memcpy(ai->ai_canonname, (const uint8_t*) p + sizeof(addrinfo_serialization_t) + s.ai_addrlen, s.canonname_len);
976
977     *length -= l;
978     *ret_ai = ai;
979
980     return (const uint8_t*) p + l;
981
982
983 fail:
984     if (ai)
985         _g_asyncns_freeaddrinfo(ai);
986
987     return NULL;
988 }
989
990 static int handle_response(_g_asyncns_t *asyncns, const packet_t *packet, size_t length) {
991     const rheader_t *resp;
992     _g_asyncns_query_t *q;
993
994     assert(asyncns);
995
996     resp = &packet->rheader;
997     assert(resp);
998     assert(length >= sizeof(rheader_t));
999     assert(length == resp->length);
1000
1001     if (resp->type == RESPONSE_DIED) {
1002         asyncns->dead = 1;
1003         return 0;
1004     }
1005
1006     if (!(q = lookup_query(asyncns, resp->id)))
1007         return 0;
1008
1009     switch (resp->type) {
1010         case RESPONSE_ADDRINFO: {
1011             const addrinfo_response_t *ai_resp = &packet->addrinfo_response;
1012             const void *p;
1013             size_t l;
1014             struct addrinfo *prev = NULL;
1015
1016             assert(length >= sizeof(addrinfo_response_t));
1017             assert(q->type == REQUEST_ADDRINFO);
1018
1019             q->ret = ai_resp->ret;
1020             q->_errno = ai_resp->_errno;
1021             q->_h_errno = ai_resp->_h_errno;
1022             l = length - sizeof(addrinfo_response_t);
1023             p = (const uint8_t*) resp + sizeof(addrinfo_response_t);
1024
1025             while (l > 0 && p) {
1026                 struct addrinfo *ai = NULL;
1027                 p = unserialize_addrinfo(p, &ai, &l);
1028
1029                 if (!p || !ai) {
1030                     q->ret = EAI_MEMORY;
1031                     break;
1032                 }
1033
1034                 if (prev)
1035                     prev->ai_next = ai;
1036                 else
1037                     q->addrinfo = ai;
1038
1039                 prev = ai;
1040             }
1041
1042             complete_query(asyncns, q);
1043             break;
1044         }
1045
1046         case RESPONSE_NAMEINFO: {
1047             const nameinfo_response_t *ni_resp = &packet->nameinfo_response;
1048
1049             assert(length >= sizeof(nameinfo_response_t));
1050             assert(q->type == REQUEST_NAMEINFO);
1051
1052             q->ret = ni_resp->ret;
1053             q->_errno = ni_resp->_errno;
1054             q->_h_errno = ni_resp->_h_errno;
1055
1056             if (ni_resp->hostlen)
1057                 if (!(q->host = strndup((const char*) ni_resp + sizeof(nameinfo_response_t), ni_resp->hostlen-1)))
1058                     q->ret = EAI_MEMORY;
1059
1060             if (ni_resp->servlen)
1061                 if (!(q->serv = strndup((const char*) ni_resp + sizeof(nameinfo_response_t) + ni_resp->hostlen, ni_resp->servlen-1)))
1062                     q->ret = EAI_MEMORY;
1063
1064             complete_query(asyncns, q);
1065             break;
1066         }
1067
1068         case RESPONSE_RES: {
1069             const res_response_t *res_resp = &packet->res_response;
1070
1071             assert(length >= sizeof(res_response_t));
1072             assert(q->type == REQUEST_RES_QUERY || q->type == REQUEST_RES_SEARCH);
1073
1074             q->ret = res_resp->ret;
1075             q->_errno = res_resp->_errno;
1076             q->_h_errno = res_resp->_h_errno;
1077
1078             if (res_resp->ret >= 0)  {
1079                 if (!(q->serv = malloc(res_resp->ret))) {
1080                     q->ret = -1;
1081                     q->_errno = ENOMEM;
1082                 } else
1083                     memcpy(q->serv, (const char *)resp + sizeof(res_response_t), res_resp->ret);
1084             }
1085
1086             complete_query(asyncns, q);
1087             break;
1088         }
1089
1090         default:
1091             ;
1092     }
1093
1094     return 0;
1095 }
1096
1097 int _g_asyncns_wait(_g_asyncns_t *asyncns, int block) {
1098     int handled = 0;
1099     assert(asyncns);
1100
1101     for (;;) {
1102         packet_t buf[BUFSIZE/sizeof(packet_t) + 1];
1103         ssize_t l;
1104
1105         if (asyncns->dead) {
1106             errno = ECHILD;
1107             return -1;
1108         }
1109
1110         if (((l = recv(asyncns->fds[RESPONSE_RECV_FD], buf, sizeof(buf), 0)) < 0)) {
1111             fd_set fds;
1112
1113             if (errno != EAGAIN)
1114                 return -1;
1115
1116             if (!block || handled)
1117                 return 0;
1118
1119             FD_ZERO(&fds);
1120             FD_SET(asyncns->fds[RESPONSE_RECV_FD], &fds);
1121
1122             if (select(asyncns->fds[RESPONSE_RECV_FD]+1, &fds, NULL, NULL, NULL) < 0)
1123                 return -1;
1124
1125             continue;
1126         }
1127
1128         if (handle_response(asyncns, buf, (size_t) l) < 0)
1129             return -1;
1130
1131         handled = 1;
1132     }
1133 }
1134
1135 static _g_asyncns_query_t *alloc_query(_g_asyncns_t *asyncns) {
1136     _g_asyncns_query_t *q;
1137     assert(asyncns);
1138
1139     if (asyncns->n_queries >= MAX_QUERIES) {
1140         errno = ENOMEM;
1141         return NULL;
1142     }
1143
1144     while (asyncns->queries[asyncns->current_index]) {
1145
1146         asyncns->current_index++;
1147         asyncns->current_id++;
1148
1149         while (asyncns->current_index >= MAX_QUERIES)
1150             asyncns->current_index -= MAX_QUERIES;
1151     }
1152
1153     if (!(q = asyncns->queries[asyncns->current_index] = malloc(sizeof(_g_asyncns_query_t)))) {
1154         errno = ENOMEM;
1155         return NULL;
1156     }
1157
1158     asyncns->n_queries++;
1159
1160     q->asyncns = asyncns;
1161     q->done = 0;
1162     q->id = asyncns->current_id;
1163     q->done_next = q->done_prev = NULL;
1164     q->ret = 0;
1165     q->_errno = 0;
1166     q->_h_errno = 0;
1167     q->addrinfo = NULL;
1168     q->userdata = NULL;
1169     q->host = q->serv = NULL;
1170
1171     return q;
1172 }
1173
1174 _g_asyncns_query_t* _g_asyncns_getaddrinfo(_g_asyncns_t *asyncns, const char *node, const char *service, const struct addrinfo *hints) {
1175     addrinfo_request_t data[BUFSIZE/sizeof(addrinfo_request_t) + 1];
1176     addrinfo_request_t *req = data;
1177     _g_asyncns_query_t *q;
1178     assert(asyncns);
1179     assert(node || service);
1180
1181     if (asyncns->dead) {
1182         errno = ECHILD;
1183         return NULL;
1184     }
1185
1186     if (!(q = alloc_query(asyncns)))
1187         return NULL;
1188
1189     memset(req, 0, sizeof(addrinfo_request_t));
1190
1191     req->node_len = node ? strlen(node)+1 : 0;
1192     req->service_len = service ? strlen(service)+1 : 0;
1193
1194     req->header.id = q->id;
1195     req->header.type = q->type = REQUEST_ADDRINFO;
1196     req->header.length = sizeof(addrinfo_request_t) + req->node_len + req->service_len;
1197
1198     if (req->header.length > BUFSIZE) {
1199         errno = ENOMEM;
1200         goto fail;
1201     }
1202
1203     if (!(req->hints_is_null = !hints)) {
1204         req->ai_flags = hints->ai_flags;
1205         req->ai_family = hints->ai_family;
1206         req->ai_socktype = hints->ai_socktype;
1207         req->ai_protocol = hints->ai_protocol;
1208     }
1209
1210     if (node)
1211         strcpy((char*) req + sizeof(addrinfo_request_t), node);
1212
1213     if (service)
1214         strcpy((char*) req + sizeof(addrinfo_request_t) + req->node_len, service);
1215
1216     if (send(asyncns->fds[REQUEST_SEND_FD], req, req->header.length, MSG_NOSIGNAL) < 0)
1217         goto fail;
1218
1219     return q;
1220
1221 fail:
1222     if (q)
1223         _g_asyncns_cancel(asyncns, q);
1224
1225     return NULL;
1226 }
1227
1228 int _g_asyncns_getaddrinfo_done(_g_asyncns_t *asyncns, _g_asyncns_query_t* q, struct addrinfo **ret_res) {
1229     int ret;
1230     assert(asyncns);
1231     assert(q);
1232     assert(q->asyncns == asyncns);
1233     assert(q->type == REQUEST_ADDRINFO);
1234
1235     if (asyncns->dead) {
1236         errno = ECHILD;
1237         return EAI_SYSTEM;
1238     }
1239
1240     if (!q->done)
1241         return EAI_AGAIN;
1242
1243     *ret_res = q->addrinfo;
1244     q->addrinfo = NULL;
1245
1246     ret = q->ret;
1247
1248     if (ret == EAI_SYSTEM)
1249         errno = q->_errno;
1250
1251     if (ret != 0)
1252         h_errno = q->_h_errno;
1253
1254     _g_asyncns_cancel(asyncns, q);
1255
1256     return ret;
1257 }
1258
1259 _g_asyncns_query_t* _g_asyncns_getnameinfo(_g_asyncns_t *asyncns, const struct sockaddr *sa, socklen_t salen, int flags, int gethost, int getserv) {
1260     nameinfo_request_t data[BUFSIZE/sizeof(nameinfo_request_t) + 1];
1261     nameinfo_request_t *req = data;
1262     _g_asyncns_query_t *q;
1263
1264     assert(asyncns);
1265     assert(sa);
1266     assert(salen > 0);
1267
1268     if (asyncns->dead) {
1269         errno = ECHILD;
1270         return NULL;
1271     }
1272
1273     if (!(q = alloc_query(asyncns)))
1274         return NULL;
1275
1276     memset(req, 0, sizeof(nameinfo_request_t));
1277
1278     req->header.id = q->id;
1279     req->header.type = q->type = REQUEST_NAMEINFO;
1280     req->header.length = sizeof(nameinfo_request_t) + salen;
1281
1282     if (req->header.length > BUFSIZE) {
1283         errno = ENOMEM;
1284         goto fail;
1285     }
1286
1287     req->flags = flags;
1288     req->sockaddr_len = salen;
1289     req->gethost = gethost;
1290     req->getserv = getserv;
1291
1292     memcpy((uint8_t*) req + sizeof(nameinfo_request_t), sa, salen);
1293
1294     if (send(asyncns->fds[REQUEST_SEND_FD], req, req->header.length, MSG_NOSIGNAL) < 0)
1295         goto fail;
1296
1297     return q;
1298
1299 fail:
1300     if (q)
1301         _g_asyncns_cancel(asyncns, q);
1302
1303     return NULL;
1304 }
1305
1306 int _g_asyncns_getnameinfo_done(_g_asyncns_t *asyncns, _g_asyncns_query_t* q, char *ret_host, size_t hostlen, char *ret_serv, size_t servlen) {
1307     int ret;
1308     assert(asyncns);
1309     assert(q);
1310     assert(q->asyncns == asyncns);
1311     assert(q->type == REQUEST_NAMEINFO);
1312     assert(!ret_host || hostlen);
1313     assert(!ret_serv || servlen);
1314
1315     if (asyncns->dead) {
1316         errno = ECHILD;
1317         return EAI_SYSTEM;
1318     }
1319
1320     if (!q->done)
1321         return EAI_AGAIN;
1322
1323     if (ret_host && q->host) {
1324         strncpy(ret_host, q->host, hostlen);
1325         ret_host[hostlen-1] = 0;
1326     }
1327
1328     if (ret_serv && q->serv) {
1329         strncpy(ret_serv, q->serv, servlen);
1330         ret_serv[servlen-1] = 0;
1331     }
1332
1333     ret = q->ret;
1334
1335     if (ret == EAI_SYSTEM)
1336         errno = q->_errno;
1337
1338     if (ret != 0)
1339         h_errno = q->_h_errno;
1340
1341     _g_asyncns_cancel(asyncns, q);
1342
1343     return ret;
1344 }
1345
1346 static _g_asyncns_query_t * _g_asyncns_res(_g_asyncns_t *asyncns, query_type_t qtype, const char *dname, int class, int type) {
1347     res_request_t data[BUFSIZE/sizeof(res_request_t) + 1];
1348     res_request_t *req = data;
1349     _g_asyncns_query_t *q;
1350
1351     assert(asyncns);
1352     assert(dname);
1353
1354     if (asyncns->dead) {
1355         errno = ECHILD;
1356         return NULL;
1357     }
1358
1359     if (!(q = alloc_query(asyncns)))
1360         return NULL;
1361
1362     memset(req, 0, sizeof(res_request_t));
1363
1364     req->dname_len = strlen(dname) + 1;
1365
1366     req->header.id = q->id;
1367     req->header.type = q->type = qtype;
1368     req->header.length = sizeof(res_request_t) + req->dname_len;
1369
1370     if (req->header.length > BUFSIZE) {
1371         errno = ENOMEM;
1372         goto fail;
1373     }
1374
1375     req->class = class;
1376     req->type = type;
1377
1378     strcpy((char*) req + sizeof(res_request_t), dname);
1379
1380     if (send(asyncns->fds[REQUEST_SEND_FD], req, req->header.length, MSG_NOSIGNAL) < 0)
1381         goto fail;
1382
1383     return q;
1384
1385 fail:
1386     if (q)
1387         _g_asyncns_cancel(asyncns, q);
1388
1389     return NULL;
1390 }
1391
1392 _g_asyncns_query_t* _g_asyncns_res_query(_g_asyncns_t *asyncns, const char *dname, int class, int type) {
1393     return _g_asyncns_res(asyncns, REQUEST_RES_QUERY, dname, class, type);
1394 }
1395
1396 _g_asyncns_query_t* _g_asyncns_res_search(_g_asyncns_t *asyncns, const char *dname, int class, int type) {
1397     return _g_asyncns_res(asyncns, REQUEST_RES_SEARCH, dname, class, type);
1398 }
1399
1400 int _g_asyncns_res_done(_g_asyncns_t *asyncns, _g_asyncns_query_t* q, unsigned char **answer) {
1401     int ret;
1402     assert(asyncns);
1403     assert(q);
1404     assert(q->asyncns == asyncns);
1405     assert(q->type == REQUEST_RES_QUERY || q->type == REQUEST_RES_SEARCH);
1406     assert(answer);
1407
1408     if (asyncns->dead) {
1409         errno = ECHILD;
1410         return -ECHILD;
1411     }
1412
1413     if (!q->done) {
1414         errno = EAGAIN;
1415         return -EAGAIN;
1416     }
1417
1418     *answer = (unsigned char *)q->serv;
1419     q->serv = NULL;
1420
1421     ret = q->ret;
1422
1423     if (ret < 0) {
1424         errno = q->_errno;
1425         h_errno = q->_h_errno;
1426     }
1427
1428     _g_asyncns_cancel(asyncns, q);
1429
1430     return ret < 0 ? -errno : ret;
1431 }
1432
1433 _g_asyncns_query_t* _g_asyncns_getnext(_g_asyncns_t *asyncns) {
1434     assert(asyncns);
1435     return asyncns->done_head;
1436 }
1437
1438 int _g_asyncns_getnqueries(_g_asyncns_t *asyncns) {
1439     assert(asyncns);
1440     return asyncns->n_queries;
1441 }
1442
1443 void _g_asyncns_cancel(_g_asyncns_t *asyncns, _g_asyncns_query_t* q) {
1444     int i;
1445     int saved_errno = errno;
1446
1447     assert(asyncns);
1448     assert(q);
1449     assert(q->asyncns == asyncns);
1450     assert(asyncns->n_queries > 0);
1451
1452     if (q->done) {
1453
1454         if (q->done_prev)
1455             q->done_prev->done_next = q->done_next;
1456         else
1457             asyncns->done_head = q->done_next;
1458
1459         if (q->done_next)
1460             q->done_next->done_prev = q->done_prev;
1461         else
1462             asyncns->done_tail = q->done_prev;
1463     }
1464
1465     i = q->id % MAX_QUERIES;
1466     assert(asyncns->queries[i] == q);
1467     asyncns->queries[i] = NULL;
1468
1469     _g_asyncns_freeaddrinfo(q->addrinfo);
1470     free(q->host);
1471     free(q->serv);
1472
1473     asyncns->n_queries--;
1474     free(q);
1475
1476     errno = saved_errno;
1477 }
1478
1479 void _g_asyncns_freeaddrinfo(struct addrinfo *ai) {
1480     int saved_errno = errno;
1481
1482     while (ai) {
1483         struct addrinfo *next = ai->ai_next;
1484
1485         free(ai->ai_addr);
1486         free(ai->ai_canonname);
1487         free(ai);
1488
1489         ai = next;
1490     }
1491
1492     errno = saved_errno;
1493 }
1494
1495 void _g_asyncns_freeanswer(unsigned char *answer) {
1496     int saved_errno = errno;
1497
1498     if (!answer)
1499         return;
1500
1501     /* Please note that this function is new in libasyncns 0.4. In
1502      * older versions you were supposed to free the answer directly
1503      * with free(). Hence, if this function is changed to do more than
1504      * just a simple free() this must be considered ABI/API breakage! */
1505
1506     free(answer);
1507
1508     errno = saved_errno;
1509 }
1510
1511 int _g_asyncns_isdone(_g_asyncns_t *asyncns, _g_asyncns_query_t*q) {
1512     assert(asyncns);
1513     assert(q);
1514     assert(q->asyncns == asyncns);
1515
1516     return q->done;
1517 }
1518
1519 void _g_asyncns_setuserdata(_g_asyncns_t *asyncns, _g_asyncns_query_t *q, void *userdata) {
1520     assert(q);
1521     assert(asyncns);
1522     assert(q->asyncns = asyncns);
1523
1524     q->userdata = userdata;
1525 }
1526
1527 void* _g_asyncns_getuserdata(_g_asyncns_t *asyncns, _g_asyncns_query_t *q) {
1528     assert(q);
1529     assert(asyncns);
1530     assert(q->asyncns = asyncns);
1531
1532     return q->userdata;
1533 }