chiark / gitweb /
d81012467f209b6dddcab3609e829849c887c45f
[elogind.git] / src / libsystemd / sd-resolve / sd-resolve.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2005-2008 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <assert.h>
23 #include <fcntl.h>
24 #include <signal.h>
25 #include <unistd.h>
26 #include <sys/select.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <sys/wait.h>
32 #include <sys/types.h>
33 #include <pwd.h>
34 #include <netinet/in.h>
35 #include <arpa/nameser.h>
36 #include <resolv.h>
37 #include <dirent.h>
38 #include <sys/time.h>
39 #include <sys/resource.h>
40 #include <stdint.h>
41 #include <pthread.h>
42 #include <sys/prctl.h>
43 #include <sys/poll.h>
44
45 #include "util.h"
46 #include "list.h"
47 #include "socket-util.h"
48 #include "sd-resolve.h"
49
50 #define WORKERS_MIN 1
51 #define WORKERS_MAX 16
52 #define QUERIES_MAX 256
53 #define BUFSIZE 10240
54
55 typedef enum {
56         REQUEST_ADDRINFO,
57         RESPONSE_ADDRINFO,
58         REQUEST_NAMEINFO,
59         RESPONSE_NAMEINFO,
60         REQUEST_RES_QUERY,
61         REQUEST_RES_SEARCH,
62         RESPONSE_RES,
63         REQUEST_TERMINATE,
64         RESPONSE_DIED
65 } QueryType;
66
67 enum {
68         REQUEST_RECV_FD,
69         REQUEST_SEND_FD,
70         RESPONSE_RECV_FD,
71         RESPONSE_SEND_FD,
72         _FD_MAX
73 };
74
75 struct sd_resolve {
76         bool dead:1;
77         pid_t original_pid;
78
79         int fds[_FD_MAX];
80
81         pthread_t workers[WORKERS_MAX];
82         unsigned n_valid_workers;
83
84         unsigned current_id, current_index;
85         sd_resolve_query* queries[QUERIES_MAX];
86         unsigned n_queries;
87
88         LIST_HEAD(sd_resolve_query, done);
89         sd_resolve_query *done_tail;
90         unsigned n_done;
91 };
92
93 struct sd_resolve_query {
94         sd_resolve *resolve;
95         bool done:1;
96         unsigned id;
97         QueryType type;
98
99         int ret;
100         int _errno;
101         int _h_errno;
102         struct addrinfo *addrinfo;
103         char *serv, *host;
104
105         void *userdata;
106
107         LIST_FIELDS(sd_resolve_query, done);
108 };
109
110 typedef struct RHeader {
111         QueryType type;
112         unsigned id;
113         size_t length;
114 } RHeader;
115
116 typedef struct AddrInfoRequest {
117         struct RHeader header;
118         bool hints_valid;
119         int ai_flags;
120         int ai_family;
121         int ai_socktype;
122         int ai_protocol;
123         size_t node_len, service_len;
124 } AddrInfoRequest;
125
126 typedef struct AddrInfoResponse {
127         struct RHeader header;
128         int ret;
129         int _errno;
130         int _h_errno;
131         /* followed by addrinfo_serialization[] */
132 } AddrInfoResponse;
133
134 typedef struct AddrInfoSerialization {
135         int ai_flags;
136         int ai_family;
137         int ai_socktype;
138         int ai_protocol;
139         size_t ai_addrlen;
140         size_t canonname_len;
141         /* Followed by ai_addr amd ai_canonname with variable lengths */
142 } AddrInfoSerialization;
143
144 typedef struct NameInfoRequest {
145         struct RHeader header;
146         int flags;
147         socklen_t sockaddr_len;
148         bool gethost:1, getserv:1;
149 } NameInfoRequest;
150
151 typedef struct NameInfoResponse {
152         struct RHeader header;
153         size_t hostlen, servlen;
154         int ret;
155         int _errno;
156         int _h_errno;
157 } NameInfoResponse;
158
159 typedef struct ResRequest {
160         struct RHeader header;
161         int class;
162         int type;
163         size_t dname_len;
164 } ResRequest;
165
166 typedef struct ResResponse {
167         struct RHeader header;
168         int ret;
169         int _errno;
170         int _h_errno;
171 } ResResponse;
172
173 typedef union Packet {
174         RHeader rheader;
175         AddrInfoRequest addrinfo_request;
176         AddrInfoResponse addrinfo_response;
177         NameInfoRequest nameinfo_request;
178         NameInfoResponse nameinfo_response;
179         ResRequest res_request;
180         ResResponse res_response;
181 } Packet;
182
183 static int send_died(int out_fd) {
184         RHeader rh = {};
185
186         assert(out_fd >= 0);
187
188         rh.type = RESPONSE_DIED;
189         rh.length = sizeof(rh);
190
191         if (send(out_fd, &rh, rh.length, MSG_NOSIGNAL) < 0)
192                 return -errno;
193
194         return 0;
195 }
196
197 static void *serialize_addrinfo(void *p, const struct addrinfo *ai, size_t *length, size_t maxlength) {
198         AddrInfoSerialization s;
199         size_t cnl, l;
200
201         assert(p);
202         assert(ai);
203         assert(length);
204         assert(*length <= maxlength);
205
206         cnl = ai->ai_canonname ? strlen(ai->ai_canonname)+1 : 0;
207         l = sizeof(AddrInfoSerialization) + ai->ai_addrlen + cnl;
208
209         if (*length + l > maxlength)
210                 return NULL;
211
212         s.ai_flags = ai->ai_flags;
213         s.ai_family = ai->ai_family;
214         s.ai_socktype = ai->ai_socktype;
215         s.ai_protocol = ai->ai_protocol;
216         s.ai_addrlen = ai->ai_addrlen;
217         s.canonname_len = cnl;
218
219         memcpy((uint8_t*) p, &s, sizeof(AddrInfoSerialization));
220         memcpy((uint8_t*) p + sizeof(AddrInfoSerialization), ai->ai_addr, ai->ai_addrlen);
221
222         if (ai->ai_canonname)
223                 memcpy((char*) p + sizeof(AddrInfoSerialization) + ai->ai_addrlen, ai->ai_canonname, cnl);
224
225         *length += l;
226         return (uint8_t*) p + l;
227 }
228
229 static int send_addrinfo_reply(
230                 int out_fd,
231                 unsigned id,
232                 int ret,
233                 struct addrinfo *ai,
234                 int _errno,
235                 int _h_errno) {
236
237         AddrInfoResponse resp = {};
238         struct msghdr mh = {};
239         struct iovec iov[2];
240         union {
241                 AddrInfoSerialization ais;
242                 uint8_t space[BUFSIZE];
243         } buffer;
244
245         assert(out_fd >= 0);
246
247         resp.header.type = RESPONSE_ADDRINFO;
248         resp.header.id = id;
249         resp.header.length = sizeof(AddrInfoResponse);
250         resp.ret = ret;
251         resp._errno = _errno;
252         resp._h_errno = _h_errno;
253
254         if (ret == 0 && ai) {
255                 void *p = &buffer;
256                 struct addrinfo *k;
257
258                 for (k = ai; k; k = k->ai_next) {
259                         p = serialize_addrinfo(p, k, &resp.header.length, (uint8_t*) &buffer + BUFSIZE - (uint8_t*) p);
260                         if (!p) {
261                                 freeaddrinfo(ai);
262                                 return -ENOBUFS;
263                         }
264                 }
265         }
266
267         if (ai)
268                 freeaddrinfo(ai);
269
270         iov[0] = (struct iovec) { .iov_base = &resp, .iov_len = sizeof(AddrInfoResponse) };
271         iov[1] = (struct iovec) { .iov_base = &buffer, .iov_len = resp.header.length - sizeof(AddrInfoResponse) };
272
273         mh.msg_iov = iov;
274         mh.msg_iovlen = ELEMENTSOF(iov);
275
276         if (sendmsg(out_fd, &mh, MSG_NOSIGNAL) < 0)
277                 return -errno;
278
279         return 0;
280 }
281
282 static int send_nameinfo_reply(
283                 int out_fd,
284                 unsigned id,
285                 int ret,
286                 const char *host,
287                 const char *serv,
288                 int _errno,
289                 int _h_errno) {
290
291         NameInfoResponse resp = {};
292         struct msghdr mh = {};
293         struct iovec iov[3];
294         size_t hl, sl;
295
296         assert(out_fd >= 0);
297
298         sl = serv ? strlen(serv)+1 : 0;
299         hl = host ? strlen(host)+1 : 0;
300
301         resp.header.type = RESPONSE_NAMEINFO;
302         resp.header.id = id;
303         resp.header.length = sizeof(NameInfoResponse) + hl + sl;
304         resp.ret = ret;
305         resp._errno = _errno;
306         resp._h_errno = _h_errno;
307         resp.hostlen = hl;
308         resp.servlen = sl;
309
310         iov[0] = (struct iovec) { .iov_base = &resp, .iov_len = sizeof(NameInfoResponse) };
311         iov[1] = (struct iovec) { .iov_base = (void*) host, .iov_len = hl };
312         iov[2] = (struct iovec) { .iov_base = (void*) serv, .iov_len = sl };
313
314         mh.msg_iov = iov;
315         mh.msg_iovlen = ELEMENTSOF(iov);
316
317         if (sendmsg(out_fd, &mh, MSG_NOSIGNAL) < 0)
318                 return -errno;
319
320         return 0;
321 }
322
323 static int send_res_reply(int out_fd, unsigned id, const unsigned char *answer, int ret, int _errno, int _h_errno) {
324         struct msghdr mh = {};
325         struct iovec iov[2];
326         ResResponse resp = {};
327         size_t l;
328
329         assert(out_fd >= 0);
330
331         l = ret > 0 ? (size_t) ret : 0;
332
333         resp.header.type = RESPONSE_RES;
334         resp.header.id = id;
335         resp.header.length = sizeof(ResResponse) + l;
336         resp.ret = ret;
337         resp._errno = _errno;
338         resp._h_errno = _h_errno;
339
340         iov[0] = (struct iovec) { .iov_base = &resp, .iov_len = sizeof(ResResponse) };
341         iov[1] = (struct iovec) { .iov_base = (void*) answer, .iov_len = l };
342
343         mh.msg_iov = iov;
344         mh.msg_iovlen = ELEMENTSOF(iov);
345
346         if (sendmsg(out_fd, &mh, MSG_NOSIGNAL) < 0)
347                 return -errno;
348
349         return 0;
350 }
351
352 static int handle_request(int out_fd, const Packet *packet, size_t length) {
353         const RHeader *req;
354
355         assert(out_fd >= 0);
356         assert(packet);
357
358         req = &packet->rheader;
359
360         assert(length >= sizeof(RHeader));
361         assert(length == req->length);
362
363         switch (req->type) {
364
365         case REQUEST_ADDRINFO: {
366                const AddrInfoRequest *ai_req = &packet->addrinfo_request;
367                struct addrinfo hints = {}, *result = NULL;
368                const char *node, *service;
369                int ret;
370
371                assert(length >= sizeof(AddrInfoRequest));
372                assert(length == sizeof(AddrInfoRequest) + ai_req->node_len + ai_req->service_len);
373
374                hints.ai_flags = ai_req->ai_flags;
375                hints.ai_family = ai_req->ai_family;
376                hints.ai_socktype = ai_req->ai_socktype;
377                hints.ai_protocol = ai_req->ai_protocol;
378
379                node = ai_req->node_len ? (const char*) ai_req + sizeof(AddrInfoRequest) : NULL;
380                service = ai_req->service_len ? (const char*) ai_req + sizeof(AddrInfoRequest) + ai_req->node_len : NULL;
381
382                ret = getaddrinfo(
383                                node, service,
384                                ai_req->hints_valid ? &hints : NULL,
385                                &result);
386
387                /* send_addrinfo_reply() frees result */
388                return send_addrinfo_reply(out_fd, req->id, ret, result, errno, h_errno);
389         }
390
391         case REQUEST_NAMEINFO: {
392                const NameInfoRequest *ni_req = &packet->nameinfo_request;
393                char hostbuf[NI_MAXHOST], servbuf[NI_MAXSERV];
394                union sockaddr_union sa;
395                int ret;
396
397                assert(length >= sizeof(NameInfoRequest));
398                assert(length == sizeof(NameInfoRequest) + ni_req->sockaddr_len);
399                assert(sizeof(sa) >= ni_req->sockaddr_len);
400
401                memcpy(&sa, (const uint8_t *) ni_req + sizeof(NameInfoRequest), ni_req->sockaddr_len);
402
403                ret = getnameinfo(&sa.sa, ni_req->sockaddr_len,
404                                ni_req->gethost ? hostbuf : NULL, ni_req->gethost ? sizeof(hostbuf) : 0,
405                                ni_req->getserv ? servbuf : NULL, ni_req->getserv ? sizeof(servbuf) : 0,
406                                ni_req->flags);
407
408                return send_nameinfo_reply(out_fd, req->id, ret,
409                                ret == 0 && ni_req->gethost ? hostbuf : NULL,
410                                ret == 0 && ni_req->getserv ? servbuf : NULL,
411                                errno, h_errno);
412         }
413
414         case REQUEST_RES_QUERY:
415         case REQUEST_RES_SEARCH: {
416                  const ResRequest *res_req = &packet->res_request;
417                  union {
418                          HEADER header;
419                          uint8_t space[BUFSIZE];
420                  } answer;
421                  const char *dname;
422                  int ret;
423
424                  assert(length >= sizeof(ResRequest));
425                  assert(length == sizeof(ResRequest) + res_req->dname_len);
426
427                  dname = (const char *) req + sizeof(ResRequest);
428
429                  if (req->type == REQUEST_RES_QUERY)
430                          ret = res_query(dname, res_req->class, res_req->type, (unsigned char *) &answer, BUFSIZE);
431                  else
432                          ret = res_search(dname, res_req->class, res_req->type, (unsigned char *) &answer, BUFSIZE);
433
434                  return send_res_reply(out_fd, req->id, (unsigned char *) &answer, ret, errno, h_errno);
435         }
436
437         case REQUEST_TERMINATE:
438                  /* Quit */
439                  return -ECONNRESET;
440
441         default:
442                 assert_not_reached("Unknown request");
443         }
444
445         return 0;
446 }
447
448 static void* thread_worker(void *p) {
449         sd_resolve *resolve = p;
450         sigset_t fullset;
451
452         /* No signals in this thread please */
453         assert_se(sigfillset(&fullset) == 0);
454         assert_se(pthread_sigmask(SIG_BLOCK, &fullset, NULL) == 0);
455
456         /* Assign a pretty name to this thread */
457         prctl(PR_SET_NAME, (unsigned long) "sd-resolve");
458
459         while (!resolve->dead) {
460                 union {
461                         Packet packet;
462                         uint8_t space[BUFSIZE];
463                 } buf;
464                 ssize_t length;
465
466                 length = recv(resolve->fds[REQUEST_RECV_FD], &buf, sizeof(buf), 0);
467                 if (length < 0) {
468                         if (errno == EINTR)
469                                 continue;
470
471                         break;
472                 }
473                 if (length == 0)
474                         break;
475
476                 if (resolve->dead)
477                         break;
478
479                 if (handle_request(resolve->fds[RESPONSE_SEND_FD], &buf.packet, (size_t) length) < 0)
480                         break;
481         }
482
483         send_died(resolve->fds[RESPONSE_SEND_FD]);
484
485         return NULL;
486 }
487
488 static int start_threads(sd_resolve *resolve, unsigned extra) {
489         unsigned n;
490         int r;
491
492         n = resolve->n_queries - resolve->n_done + extra;
493
494         if (n < WORKERS_MIN)
495                 n = WORKERS_MIN;
496         if (n > WORKERS_MAX)
497                 n = WORKERS_MAX;
498
499         while (resolve->n_valid_workers < n) {
500
501                 r = pthread_create(&resolve->workers[resolve->n_valid_workers], NULL, thread_worker, resolve);
502                 if (r != 0)
503                         return -r;
504
505                 resolve->n_valid_workers ++;
506         }
507
508         return 0;
509 }
510
511 static bool resolve_pid_changed(sd_resolve *r) {
512         assert(r);
513
514         /* We don't support people creating a resolver and keeping it
515          * around after fork(). Let's complain. */
516
517         return r->original_pid != getpid();
518 }
519
520 _public_ int sd_resolve_new(sd_resolve **ret) {
521         sd_resolve *resolve = NULL;
522         int i, r;
523
524         assert_return(ret, -EINVAL);
525
526         resolve = new0(sd_resolve, 1);
527         if (!resolve)
528                 return -ENOMEM;
529
530         for (i = 0; i < _FD_MAX; i++)
531                 resolve->fds[i] = -1;
532
533         resolve->original_pid = getpid();
534
535         r = socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + REQUEST_RECV_FD);
536         if (r < 0) {
537                 r = -errno;
538                 goto fail;
539         }
540
541         r = socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + RESPONSE_RECV_FD);
542         if (r < 0) {
543                 r = -errno;
544                 goto fail;
545         }
546
547         fd_inc_sndbuf(resolve->fds[REQUEST_SEND_FD], QUERIES_MAX * BUFSIZE);
548         fd_inc_rcvbuf(resolve->fds[REQUEST_RECV_FD], QUERIES_MAX * BUFSIZE);
549         fd_inc_sndbuf(resolve->fds[RESPONSE_SEND_FD], QUERIES_MAX * BUFSIZE);
550         fd_inc_rcvbuf(resolve->fds[RESPONSE_RECV_FD], QUERIES_MAX * BUFSIZE);
551
552         fd_nonblock(resolve->fds[RESPONSE_RECV_FD], true);
553
554         *ret = resolve;
555         return 0;
556
557 fail:
558         if (resolve)
559                 sd_resolve_unref(resolve);
560
561         return r;
562 }
563
564 _public_ sd_resolve* sd_resolve_unref(sd_resolve *resolve) {
565         PROTECT_ERRNO;
566
567         unsigned i;
568
569         assert_return(resolve, NULL);
570         assert_return(!resolve_pid_changed(resolve), NULL);
571
572         resolve->dead = true;
573
574         if (resolve->fds[REQUEST_SEND_FD] >= 0) {
575
576                 RHeader req = {
577                         .type = REQUEST_TERMINATE,
578                         .length = sizeof(req)
579                 };
580
581                 /* Send one termination packet for each worker */
582                 for (i = 0; i < resolve->n_valid_workers; i++)
583                         send(resolve->fds[REQUEST_SEND_FD], &req, req.length, MSG_NOSIGNAL);
584         }
585
586         /* Now terminate them and wait until they are gone. */
587         for (i = 0; i < resolve->n_valid_workers; i++) {
588                 for (;;) {
589                         if (pthread_join(resolve->workers[i], NULL) != EINTR)
590                                 break;
591                 }
592         }
593
594         /* Close all communication channels */
595         for (i = 0; i < _FD_MAX; i++)
596                 safe_close(resolve->fds[i]);
597
598         for (i = 0; i < QUERIES_MAX && resolve->n_queries > 0; i++)
599                 if (resolve->queries[i])
600                         sd_resolve_cancel(resolve->queries[i]);
601
602         free(resolve);
603         return NULL;
604 }
605
606 _public_ int sd_resolve_get_fd(sd_resolve *resolve) {
607         assert_return(resolve, -EINVAL);
608         assert_return(!resolve_pid_changed(resolve), -ECHILD);
609
610         return resolve->fds[RESPONSE_RECV_FD];
611 }
612
613 _public_ int sd_resolve_get_events(sd_resolve *resolve) {
614         assert_return(resolve, -EINVAL);
615         assert_return(!resolve_pid_changed(resolve), -ECHILD);
616
617         return resolve->n_queries > resolve->n_done ? POLLIN : 0;
618 }
619
620 _public_ int sd_resolve_get_timeout(sd_resolve *resolve, uint64_t *usec) {
621         assert_return(resolve, -EINVAL);
622         assert_return(usec, -EINVAL);
623         assert_return(!resolve_pid_changed(resolve), -ECHILD);
624
625         *usec = (uint64_t) -1;
626         return 0;
627 }
628
629 static sd_resolve_query *lookup_query(sd_resolve *resolve, unsigned id) {
630         sd_resolve_query *q;
631
632         assert(resolve);
633
634         q = resolve->queries[id % QUERIES_MAX];
635         if (q)
636                 if (q->id == id)
637                         return q;
638
639         return NULL;
640 }
641
642 static void complete_query(sd_resolve_query *q) {
643         assert(q);
644         assert(!q->done);
645
646         q->done = true;
647         LIST_PREPEND(done, q->resolve->done, q);
648         q->resolve->n_done ++;
649 }
650
651 static int unserialize_addrinfo(const void **p, size_t *length, struct addrinfo **ret_ai) {
652         AddrInfoSerialization s;
653         size_t l;
654         struct addrinfo *ai;
655
656         assert(p);
657         assert(*p);
658         assert(ret_ai);
659         assert(length);
660
661         if (*length < sizeof(AddrInfoSerialization))
662                 return -EBADMSG;
663
664         memcpy(&s, *p, sizeof(s));
665
666         l = sizeof(AddrInfoSerialization) + s.ai_addrlen + s.canonname_len;
667         if (*length < l)
668                 return -EBADMSG;
669
670         ai = new0(struct addrinfo, 1);
671         if (!ai)
672                 return -ENOMEM;
673
674         ai->ai_flags = s.ai_flags;
675         ai->ai_family = s.ai_family;
676         ai->ai_socktype = s.ai_socktype;
677         ai->ai_protocol = s.ai_protocol;
678         ai->ai_addrlen = s.ai_addrlen;
679
680         if (s.ai_addrlen > 0) {
681                 ai->ai_addr = memdup((const uint8_t*) *p + sizeof(AddrInfoSerialization), s.ai_addrlen);
682                 if (!ai->ai_addr) {
683                         free(ai);
684                         return -ENOMEM;
685                 }
686         }
687
688         if (s.canonname_len > 0) {
689                 ai->ai_canonname = memdup((const uint8_t*) *p + sizeof(AddrInfoSerialization) + s.ai_addrlen, s.canonname_len);
690                 if (!ai->ai_canonname) {
691                         free(ai->ai_addr);
692                         free(ai);
693                         return -ENOMEM;
694                 }
695         }
696
697         *length -= l;
698         *ret_ai = ai;
699         *p = ((const uint8_t*) *p) + l;
700
701         return 0;
702 }
703
704 static int handle_response(sd_resolve *resolve, const Packet *packet, size_t length) {
705         const RHeader *resp;
706         sd_resolve_query *q;
707         int r;
708
709         assert(resolve);
710
711         resp = &packet->rheader;
712         assert(resp);
713         assert(length >= sizeof(RHeader));
714         assert(length == resp->length);
715
716         if (resp->type == RESPONSE_DIED) {
717                 resolve->dead = true;
718                 return 0;
719         }
720
721         q = lookup_query(resolve, resp->id);
722         if (!q)
723                 return 0;
724
725         switch (resp->type) {
726
727         case RESPONSE_ADDRINFO: {
728                 const AddrInfoResponse *ai_resp = &packet->addrinfo_response;
729                 const void *p;
730                 size_t l;
731                 struct addrinfo *prev = NULL;
732
733                 assert(length >= sizeof(AddrInfoResponse));
734                 assert(q->type == REQUEST_ADDRINFO);
735
736                 q->ret = ai_resp->ret;
737                 q->_errno = ai_resp->_errno;
738                 q->_h_errno = ai_resp->_h_errno;
739
740                 l = length - sizeof(AddrInfoResponse);
741                 p = (const uint8_t*) resp + sizeof(AddrInfoResponse);
742
743                 while (l > 0 && p) {
744                         struct addrinfo *ai = NULL;
745
746                         r = unserialize_addrinfo(&p, &l, &ai);
747                         if (r < 0) {
748                                 q->ret = EAI_SYSTEM;
749                                 q->_errno = -r;
750                                 q->_h_errno = 0;
751                                 freeaddrinfo(q->addrinfo);
752                                 q->addrinfo = NULL;
753                                 break;
754                         }
755
756                         if (prev)
757                                 prev->ai_next = ai;
758                         else
759                                 q->addrinfo = ai;
760
761                         prev = ai;
762                 }
763
764                 complete_query(q);
765                 break;
766         }
767
768         case RESPONSE_NAMEINFO: {
769                 const NameInfoResponse *ni_resp = &packet->nameinfo_response;
770
771                 assert(length >= sizeof(NameInfoResponse));
772                 assert(q->type == REQUEST_NAMEINFO);
773
774                 q->ret = ni_resp->ret;
775                 q->_errno = ni_resp->_errno;
776                 q->_h_errno = ni_resp->_h_errno;
777
778                 if (ni_resp->hostlen > 0) {
779                         q->host = strndup((const char*) ni_resp + sizeof(NameInfoResponse), ni_resp->hostlen-1);
780                         if (!q->host) {
781                                 q->ret = EAI_MEMORY;
782                                 q->_errno = ENOMEM;
783                                 q->_h_errno = 0;
784                         }
785                 }
786
787                 if (ni_resp->servlen > 0) {
788                         q->serv = strndup((const char*) ni_resp + sizeof(NameInfoResponse) + ni_resp->hostlen, ni_resp->servlen-1);
789                         if (!q->serv) {
790                                 q->ret = EAI_MEMORY;
791                                 q->_errno = ENOMEM;
792                                 q->_h_errno = 0;
793                         }
794                 }
795
796                 complete_query(q);
797                 break;
798         }
799
800         case RESPONSE_RES: {
801                 const ResResponse *res_resp = &packet->res_response;
802
803                 assert(length >= sizeof(ResResponse));
804                 assert(q->type == REQUEST_RES_QUERY || q->type == REQUEST_RES_SEARCH);
805
806                 q->ret = res_resp->ret;
807                 q->_errno = res_resp->_errno;
808                 q->_h_errno = res_resp->_h_errno;
809
810                 if (res_resp->ret >= 0)  {
811                         q->serv = memdup((const char *)resp + sizeof(ResResponse), res_resp->ret);
812                         if (!q->serv) {
813                                 q->ret = -1;
814                                 q->_errno = ENOMEM;
815                                 q->_h_errno = 0;
816                         }
817                 }
818
819                 complete_query(q);
820                 break;
821         }
822
823         default:
824                 ;
825         }
826
827         return 0;
828 }
829
830 _public_ int sd_resolve_process(sd_resolve *resolve) {
831         int n_processed = 0, r;
832
833         assert_return(resolve, -EINVAL);
834         assert_return(!resolve_pid_changed(resolve), -ECHILD);
835
836         for (;;) {
837                 ssize_t l;
838                 union {
839                         Packet packet;
840                         uint8_t space[BUFSIZE];
841                 } buf;
842
843                 l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof(buf), 0);
844                 if (l < 0) {
845                         if (errno == EAGAIN)
846                                 return n_processed;
847
848                         return -errno;
849                 }
850                 if (l == 0)
851                         return -ECONNREFUSED;
852
853                 r = handle_response(resolve, &buf.packet, (size_t) l);
854                 if (r < 0)
855                         return r;
856
857                 n_processed++;
858         }
859 }
860
861 _public_ int sd_resolve_wait(sd_resolve *resolve, uint64_t timeout_usec) {
862         int r;
863
864         assert_return(resolve, -EINVAL);
865         assert_return(!resolve_pid_changed(resolve), -ECHILD);
866
867         if (resolve->n_queries <= 0)
868                 return 0;
869
870         do {
871                 r = fd_wait_for_event(resolve->fds[RESPONSE_RECV_FD], POLLIN, timeout_usec);
872         } while (r == -EINTR);
873
874         if (r < 0)
875                 return r;
876
877         return sd_resolve_process(resolve);
878 }
879
880 static int alloc_query(sd_resolve *resolve, sd_resolve_query **_q) {
881         sd_resolve_query *q;
882         int r;
883
884         assert(resolve);
885         assert(_q);
886
887         if (resolve->n_queries >= QUERIES_MAX)
888                 return -ENOBUFS;
889
890         r = start_threads(resolve, 1);
891         if (r < 0)
892                 return r;
893
894         while (resolve->queries[resolve->current_index]) {
895                 resolve->current_index++;
896                 resolve->current_id++;
897
898                 resolve->current_index %= QUERIES_MAX;
899         }
900
901         q = resolve->queries[resolve->current_index] = new0(sd_resolve_query, 1);
902         if (!q)
903                 return -ENOMEM;
904
905         resolve->n_queries++;
906
907         q->resolve = resolve;
908         q->id = resolve->current_id;
909
910         *_q = q;
911         return 0;
912 }
913
914 _public_ int sd_resolve_getaddrinfo(
915                 sd_resolve *resolve,
916                 sd_resolve_query **_q,
917                 const char *node,
918                 const char *service,
919                 const struct addrinfo *hints) {
920
921         AddrInfoRequest req = {};
922         struct msghdr mh = {};
923         struct iovec iov[3];
924         sd_resolve_query *q;
925         int r;
926
927         assert_return(resolve, -EINVAL);
928         assert_return(node || service, -EINVAL);
929         assert_return(_q, -EINVAL);
930         assert_return(!resolve_pid_changed(resolve), -ECHILD);
931
932         r = alloc_query(resolve, &q);
933         if (r < 0)
934                 return r;
935
936         req.node_len = node ? strlen(node)+1 : 0;
937         req.service_len = service ? strlen(service)+1 : 0;
938
939         req.header.id = q->id;
940         req.header.type = q->type = REQUEST_ADDRINFO;
941         req.header.length = sizeof(AddrInfoRequest) + req.node_len + req.service_len;
942
943         if (hints) {
944                 req.hints_valid = true;
945                 req.ai_flags = hints->ai_flags;
946                 req.ai_family = hints->ai_family;
947                 req.ai_socktype = hints->ai_socktype;
948                 req.ai_protocol = hints->ai_protocol;
949         }
950
951         iov[mh.msg_iovlen++] = (struct iovec) { .iov_base = &req, .iov_len = sizeof(AddrInfoRequest) };
952
953         if (node)
954                 iov[mh.msg_iovlen++] = (struct iovec) { .iov_base = (void*) node, .iov_len = req.node_len };
955
956         if (service)
957                 iov[mh.msg_iovlen++] = (struct iovec) { .iov_base = (void*) service, .iov_len = req.service_len };
958
959         mh.msg_iov = iov;
960
961         if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) {
962                 sd_resolve_cancel(q);
963                 return -errno;
964         }
965
966         *_q = q;
967         return 0;
968 }
969
970 _public_ int sd_resolve_getaddrinfo_done(sd_resolve_query* q, struct addrinfo **ret_res) {
971         int ret;
972
973         if (!q) {
974                 errno = EINVAL;
975                 return EAI_SYSTEM;
976         }
977
978         if (q->type != REQUEST_ADDRINFO) {
979                 errno = ENOTTY;
980                 return EAI_SYSTEM;
981         }
982
983         if (resolve_pid_changed(q->resolve)) {
984                 errno = ECHILD;
985                 return EAI_SYSTEM;
986         }
987         if (!q->done)
988                 return EAI_AGAIN;
989
990         if (ret_res) {
991                 *ret_res = q->addrinfo;
992                 q->addrinfo = NULL;
993         }
994
995         ret = q->ret;
996
997         if (ret != 0) {
998                 errno = q->_errno;
999                 h_errno = q->_h_errno;
1000         }
1001
1002         sd_resolve_cancel(q);
1003
1004         return ret;
1005 }
1006
1007 _public_ int sd_resolve_getnameinfo(
1008                 sd_resolve *resolve,
1009                 sd_resolve_query**_q,
1010                 const struct sockaddr *sa, socklen_t salen,
1011                 int flags,
1012                 int gethost, int getserv) {
1013
1014         NameInfoRequest req = {};
1015         struct msghdr mh = {};
1016         struct iovec iov[2];
1017         sd_resolve_query *q;
1018         int r;
1019
1020         assert_return(resolve, -EINVAL);
1021         assert_return(sa, -EINVAL);
1022         assert_return(salen >= sizeof(struct sockaddr), -EINVAL);
1023         assert_return(salen <= sizeof(union sockaddr_union), -EINVAL);
1024         assert_return(_q, -EINVAL);
1025         assert_return(!resolve_pid_changed(resolve), -ECHILD);
1026
1027         r = alloc_query(resolve, &q);
1028         if (r < 0)
1029                 return r;
1030
1031         req.header.id = q->id;
1032         req.header.type = q->type = REQUEST_NAMEINFO;
1033         req.header.length = sizeof(NameInfoRequest) + salen;
1034
1035         req.flags = flags;
1036         req.sockaddr_len = salen;
1037         req.gethost = !!gethost;
1038         req.getserv = !!getserv;
1039
1040         iov[0] = (struct iovec) { .iov_base = &req, .iov_len = sizeof(NameInfoRequest) };
1041         iov[1] = (struct iovec) { .iov_base = (void*) sa, .iov_len = salen };
1042
1043         mh.msg_iov = iov;
1044         mh.msg_iovlen = 2;
1045
1046         if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) {
1047                 sd_resolve_cancel(q);
1048                 return -errno;
1049         }
1050
1051         *_q = q;
1052         return 0;
1053 }
1054
1055 _public_ int sd_resolve_getnameinfo_done(sd_resolve_query* q, char **ret_host, char **ret_serv) {
1056         int ret;
1057
1058         if (!q) {
1059                 errno = EINVAL;
1060                 return EAI_SYSTEM;
1061         }
1062
1063         if (q->type != REQUEST_NAMEINFO) {
1064                 errno = ENOTTY;
1065                 return EAI_SYSTEM;
1066         }
1067
1068         if (resolve_pid_changed(q->resolve)) {
1069                 errno = ECHILD;
1070                 return EAI_SYSTEM;
1071         }
1072
1073         if (!q->done)
1074                 return EAI_AGAIN;
1075
1076         if (ret_host) {
1077                 *ret_host = q->host;
1078                 q->host = NULL;
1079         }
1080
1081         if (ret_serv) {
1082                 *ret_serv = q->serv;
1083                 q->serv = NULL;
1084         }
1085
1086         ret = q->ret;
1087
1088         if (ret != 0) {
1089                 errno = q->_errno;
1090                 h_errno = q->_h_errno;
1091         }
1092
1093         sd_resolve_cancel(q);
1094
1095         return ret;
1096 }
1097
1098 static int resolve_res(
1099                 sd_resolve *resolve,
1100                 sd_resolve_query **_q,
1101                 QueryType qtype,
1102                 const char *dname,
1103                 int class, int type) {
1104
1105         struct msghdr mh = {};
1106         struct iovec iov[2];
1107         ResRequest req = {};
1108         sd_resolve_query *q;
1109         int r;
1110
1111         assert_return(resolve, -EINVAL);
1112         assert_return(dname, -EINVAL);
1113         assert_return(_q, -EINVAL);
1114         assert_return(!resolve_pid_changed(resolve), -ECHILD);
1115
1116         r = alloc_query(resolve, &q);
1117         if (r < 0)
1118                 return r;
1119
1120         req.dname_len = strlen(dname) + 1;
1121         req.class = class;
1122         req.type = type;
1123
1124         req.header.id = q->id;
1125         req.header.type = q->type = qtype;
1126         req.header.length = sizeof(ResRequest) + req.dname_len;
1127
1128         iov[0] = (struct iovec) { .iov_base = &req, .iov_len = sizeof(ResRequest) };
1129         iov[1] = (struct iovec) { .iov_base = (void*) dname, .iov_len = req.dname_len };
1130
1131         mh.msg_iov = iov;
1132         mh.msg_iovlen = 2;
1133
1134         if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) {
1135                 sd_resolve_cancel(q);
1136                 return -errno;
1137         }
1138
1139         *_q = q;
1140         return 0;
1141 }
1142
1143 _public_ int sd_resolve_res_query(sd_resolve *resolve, sd_resolve_query** q, const char *dname, int class, int type) {
1144         return resolve_res(resolve, q, REQUEST_RES_QUERY, dname, class, type);
1145 }
1146
1147 _public_ int sd_resolve_res_search(sd_resolve *resolve, sd_resolve_query** q, const char *dname, int class, int type) {
1148         return resolve_res(resolve, q, REQUEST_RES_SEARCH, dname, class, type);
1149 }
1150
1151 _public_ int sd_resolve_res_done(sd_resolve_query* q, unsigned char **answer) {
1152         int ret;
1153
1154         assert_return(q, -EINVAL);
1155         assert_return(answer, -EINVAL);
1156         assert_return(q->type == REQUEST_RES_QUERY || q->type == REQUEST_RES_SEARCH, -ENOTTY);
1157         assert_return(!resolve_pid_changed(q->resolve), -ECHILD);
1158
1159         if (!q->done)
1160                 return -EAGAIN;
1161
1162         *answer = (unsigned char *) q->serv;
1163         q->serv = NULL;
1164
1165         ret = q->ret;
1166
1167         if (ret != 0) {
1168                 errno = q->_errno;
1169                 h_errno = q->_h_errno;
1170         }
1171
1172         sd_resolve_cancel(q);
1173
1174         return ret < 0 ? -errno : ret;
1175 }
1176
1177 _public_ int sd_resolve_get_next(sd_resolve *resolve, sd_resolve_query **q) {
1178         assert_return(resolve, -EINVAL);
1179         assert_return(q, -EINVAL);
1180         assert_return(!resolve_pid_changed(resolve), -ECHILD);
1181
1182         *q = resolve->done;
1183         return !!resolve->done;
1184 }
1185
1186 _public_ int sd_resolve_get_n_queries(sd_resolve *resolve) {
1187         assert_return(resolve, -EINVAL);
1188         assert_return(!resolve_pid_changed(resolve), -ECHILD);
1189
1190         return resolve->n_queries;
1191 }
1192
1193 _public_ int sd_resolve_cancel(sd_resolve_query* q) {
1194         PROTECT_ERRNO;
1195         int i;
1196
1197         if (!q)
1198                 return 0;
1199
1200         assert_return(!resolve_pid_changed(q->resolve), -ECHILD);
1201
1202         assert(q->resolve);
1203         assert(q->resolve->n_queries > 0);
1204
1205         if (q->done) {
1206                 LIST_REMOVE(done, q->resolve->done, q);
1207                 q->resolve->n_done--;
1208         }
1209
1210         i = q->id % QUERIES_MAX;
1211         assert(q->resolve->queries[i] == q);
1212         q->resolve->queries[i] = NULL;
1213         q->resolve->n_queries--;
1214
1215         sd_resolve_freeaddrinfo(q->addrinfo);
1216         free(q->host);
1217         free(q->serv);
1218         free(q);
1219
1220         return 0;
1221 }
1222
1223 _public_ void sd_resolve_freeaddrinfo(struct addrinfo *ai) {
1224
1225         while (ai) {
1226                 struct addrinfo *next = ai->ai_next;
1227
1228                 free(ai->ai_addr);
1229                 free(ai->ai_canonname);
1230                 free(ai);
1231
1232                 ai = next;
1233         }
1234 }
1235
1236 _public_ int sd_resolve_is_done(sd_resolve_query *q) {
1237         assert_return(q, -EINVAL);
1238         assert_return(!resolve_pid_changed(q->resolve), -ECHILD);
1239
1240         return q->done;
1241 }
1242
1243 _public_ void* sd_resolve_set_userdata(sd_resolve_query *q, void *userdata) {
1244         void *ret;
1245
1246         assert_return(q, NULL);
1247         assert_return(!resolve_pid_changed(q->resolve), NULL);
1248
1249         ret = q->userdata;
1250         q->userdata = userdata;
1251
1252         return ret;
1253 }
1254
1255 _public_ void* sd_resolve_get_userdata(sd_resolve_query *q) {
1256         assert_return(q, NULL);
1257         assert_return(!resolve_pid_changed(q->resolve), NULL);
1258
1259         return q->userdata;
1260 }