/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <errno.h>
#include <poll.h>
#include <pthread.h>
#include <resolv.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <unistd.h>

#include "sd-resolve.h"

#include "alloc-util.h"
#include "dns-def.h"
#include "errno-util.h"
#include "fd-util.h"
#include "io-util.h"
#include "list.h"
#include "memory-util.h"
#include "missing_syscall.h"
#include "missing_threads.h"
#include "process-util.h"
#include "resolve-private.h"
#include "socket-util.h"

#define WORKERS_MIN 1U
#define WORKERS_MAX 16U
#define QUERIES_MAX 256U
#define BUFSIZE 10240U

typedef enum {
        REQUEST_ADDRINFO,
        RESPONSE_ADDRINFO,
        REQUEST_NAMEINFO,
        RESPONSE_NAMEINFO,
        REQUEST_TERMINATE,
        RESPONSE_DIED
} QueryType;

enum {
        REQUEST_RECV_FD,
        REQUEST_SEND_FD,
        RESPONSE_RECV_FD,
        RESPONSE_SEND_FD,
        _FD_MAX
};

struct sd_resolve {
        unsigned n_ref;

        bool dead:1;
        pid_t original_pid;

        int fds[_FD_MAX];

        pthread_t workers[WORKERS_MAX];
        unsigned n_valid_workers;

        unsigned current_id;
        sd_resolve_query* query_array[QUERIES_MAX];
        unsigned n_queries, n_done, n_outstanding;

        sd_event_source *event_source;
        sd_event *event;

        sd_resolve_query *current;

        sd_resolve **default_resolve_ptr;
        pid_t tid;

        LIST_HEAD(sd_resolve_query, queries);
};

struct sd_resolve_query {
        unsigned n_ref;

        sd_resolve *resolve;

        QueryType type:4;
        bool done:1;
        bool floating:1;
        unsigned id;

        int ret;
        int _errno;
        int _h_errno;
        struct addrinfo *addrinfo;
        char *serv, *host;

        union {
                sd_resolve_getaddrinfo_handler_t getaddrinfo_handler;
                sd_resolve_getnameinfo_handler_t getnameinfo_handler;
        };

        void *userdata;
        sd_resolve_destroy_t destroy_callback;

        LIST_FIELDS(sd_resolve_query, queries);
};

typedef struct RHeader {
        QueryType type;
        unsigned id;
        size_t length;
} RHeader;

typedef struct AddrInfoRequest {
        struct RHeader header;
        bool hints_valid;
        int ai_flags;
        int ai_family;
        int ai_socktype;
        int ai_protocol;
        size_t node_len, service_len;
} AddrInfoRequest;

typedef struct AddrInfoResponse {
        struct RHeader header;
        int ret;
        int _errno;
        int _h_errno;
        /* followed by addrinfo_serialization[] */
} AddrInfoResponse;

typedef struct AddrInfoSerialization {
        int ai_flags;
        int ai_family;
        int ai_socktype;
        int ai_protocol;
        size_t ai_addrlen;
        size_t canonname_len;
        /* Followed by ai_addr amd ai_canonname with variable lengths */
} AddrInfoSerialization;

typedef struct NameInfoRequest {
        struct RHeader header;
        int flags;
        socklen_t sockaddr_len;
        bool gethost:1, getserv:1;
} NameInfoRequest;

typedef struct NameInfoResponse {
        struct RHeader header;
        size_t hostlen, servlen;
        int ret;
        int _errno;
        int _h_errno;
} NameInfoResponse;

typedef union Packet {
        RHeader rheader;
        AddrInfoRequest addrinfo_request;
        AddrInfoResponse addrinfo_response;
        NameInfoRequest nameinfo_request;
        NameInfoResponse nameinfo_response;
} Packet;

static int getaddrinfo_done(sd_resolve_query* q);
static int getnameinfo_done(sd_resolve_query *q);

static void resolve_query_disconnect(sd_resolve_query *q);

#define RESOLVE_DONT_DESTROY(resolve) \
        _cleanup_(sd_resolve_unrefp) _unused_ sd_resolve *_dont_destroy_##resolve = sd_resolve_ref(resolve)

static void query_assign_errno(sd_resolve_query *q, int ret, int error, int h_error) {
        assert(q);

        q->ret = ret;
        q->_errno = abs(error);
        q->_h_errno = h_error;
}

static int send_died(int out_fd) {
        RHeader rh = {
                .type = RESPONSE_DIED,
                .length = sizeof(RHeader),
        };

        assert(out_fd >= 0);

        if (send(out_fd, &rh, rh.length, MSG_NOSIGNAL) < 0)
                return -errno;

        return 0;
}

static void *serialize_addrinfo(void *p, const struct addrinfo *ai, size_t *length, size_t maxlength) {
        AddrInfoSerialization s;
        size_t cnl, l;

        assert(p);
        assert(ai);
        assert(length);
        assert(*length <= maxlength);

        cnl = ai->ai_canonname ? strlen(ai->ai_canonname)+1 : 0;
        l = sizeof(AddrInfoSerialization) + ai->ai_addrlen + cnl;

        if (*length + l > maxlength)
                return NULL;

        s = (AddrInfoSerialization) {
                .ai_flags = ai->ai_flags,
                .ai_family = ai->ai_family,
                .ai_socktype = ai->ai_socktype,
                .ai_protocol = ai->ai_protocol,
                .ai_addrlen = ai->ai_addrlen,
                .canonname_len = cnl,
        };

        memcpy((uint8_t*) p, &s, sizeof(AddrInfoSerialization));
        memcpy((uint8_t*) p + sizeof(AddrInfoSerialization), ai->ai_addr, ai->ai_addrlen);
        memcpy_safe((char*) p + sizeof(AddrInfoSerialization) + ai->ai_addrlen,
                    ai->ai_canonname, cnl);

        *length += l;
        return (uint8_t*) p + l;
}

static int send_addrinfo_reply(
                int out_fd,
                unsigned id,
                int ret,
                struct addrinfo *ai,
                int _errno,
                int _h_errno) {

        AddrInfoResponse resp = {};
        union {
                AddrInfoSerialization ais;
                uint8_t space[BUFSIZE];
        } buffer;
        struct iovec iov[2];
        struct msghdr mh;

        assert(out_fd >= 0);

        resp = (AddrInfoResponse) {
                .header.type = RESPONSE_ADDRINFO,
                .header.id = id,
                .header.length = sizeof(AddrInfoResponse),
                .ret = ret,
                ._errno = _errno,
                ._h_errno = _h_errno,
        };

        msan_unpoison(&resp, sizeof(resp));

        if (ret == 0 && ai) {
                void *p = &buffer;
                struct addrinfo *k;

                for (k = ai; k; k = k->ai_next) {
                        p = serialize_addrinfo(p, k, &resp.header.length, (uint8_t*) &buffer + BUFSIZE - (uint8_t*) p);
                        if (!p) {
                                freeaddrinfo(ai);
                                return -ENOBUFS;
                        }
                }
        }

        if (ai)
                freeaddrinfo(ai);

        iov[0] = IOVEC_MAKE(&resp, sizeof(AddrInfoResponse));
        iov[1] = IOVEC_MAKE(&buffer, resp.header.length - sizeof(AddrInfoResponse));

        mh = (struct msghdr) {
                .msg_iov = iov,
                .msg_iovlen = ELEMENTSOF(iov)
        };

        if (sendmsg(out_fd, &mh, MSG_NOSIGNAL) < 0)
                return -errno;

        return 0;
}

static int send_nameinfo_reply(
                int out_fd,
                unsigned id,
                int ret,
                const char *host,
                const char *serv,
                int _errno,
                int _h_errno) {

        NameInfoResponse resp = {};
        struct iovec iov[3];
        struct msghdr mh;
        size_t hl, sl;

        assert(out_fd >= 0);

        sl = serv ? strlen(serv)+1 : 0;
        hl = host ? strlen(host)+1 : 0;

        resp = (NameInfoResponse) {
                .header.type = RESPONSE_NAMEINFO,
                .header.id = id,
                .header.length = sizeof(NameInfoResponse) + hl + sl,
                .hostlen = hl,
                .servlen = sl,
                .ret = ret,
                ._errno = _errno,
                ._h_errno = _h_errno,
        };

        msan_unpoison(&resp, sizeof(resp));

        iov[0] = IOVEC_MAKE(&resp, sizeof(NameInfoResponse));
        iov[1] = IOVEC_MAKE((void*) host, hl);
        iov[2] = IOVEC_MAKE((void*) serv, sl);

        mh = (struct msghdr) {
                .msg_iov = iov,
                .msg_iovlen = ELEMENTSOF(iov)
        };

        if (sendmsg(out_fd, &mh, MSG_NOSIGNAL) < 0)
                return -errno;

        return 0;
}

static int handle_request(int out_fd, const Packet *packet, size_t length) {
        const RHeader *req;

        assert(out_fd >= 0);
        assert(packet);

        req = &packet->rheader;

        assert_return(length >= sizeof(RHeader), -EIO);
        assert_return(length == req->length, -EIO);

        switch (req->type) {

        case REQUEST_ADDRINFO: {
               const AddrInfoRequest *ai_req = &packet->addrinfo_request;
               struct addrinfo hints, *result = NULL;
               const char *node, *service;
               int ret;

               assert_return(length >= sizeof(AddrInfoRequest), -EBADMSG);
               assert_return(length == sizeof(AddrInfoRequest) + ai_req->node_len + ai_req->service_len, -EBADMSG);

               hints = (struct addrinfo) {
                       .ai_flags = ai_req->ai_flags,
                       .ai_family = ai_req->ai_family,
                       .ai_socktype = ai_req->ai_socktype,
                       .ai_protocol = ai_req->ai_protocol,
               };

               msan_unpoison(&hints, sizeof(hints));

               node = ai_req->node_len ? (const char*) ai_req + sizeof(AddrInfoRequest) : NULL;
               service = ai_req->service_len ? (const char*) ai_req + sizeof(AddrInfoRequest) + ai_req->node_len : NULL;

               ret = getaddrinfo(node, service,
                                 ai_req->hints_valid ? &hints : NULL,
                                 &result);

               /* send_addrinfo_reply() frees result */
               return send_addrinfo_reply(out_fd, req->id, ret, result, errno, h_errno);
        }

        case REQUEST_NAMEINFO: {
               const NameInfoRequest *ni_req = &packet->nameinfo_request;
               char hostbuf[NI_MAXHOST], servbuf[NI_MAXSERV];
               union sockaddr_union sa;
               int ret;

               assert_return(length >= sizeof(NameInfoRequest), -EBADMSG);
               assert_return(length == sizeof(NameInfoRequest) + ni_req->sockaddr_len, -EBADMSG);
               assert_return(ni_req->sockaddr_len <= sizeof(sa), -EBADMSG);

               memcpy(&sa, (const uint8_t *) ni_req + sizeof(NameInfoRequest), ni_req->sockaddr_len);

               ret = getnameinfo(&sa.sa, ni_req->sockaddr_len,
                                 ni_req->gethost ? hostbuf : NULL, ni_req->gethost ? sizeof(hostbuf) : 0,
                                 ni_req->getserv ? servbuf : NULL, ni_req->getserv ? sizeof(servbuf) : 0,
                                 ni_req->flags);

               return send_nameinfo_reply(out_fd, req->id, ret,
                                          ret == 0 && ni_req->gethost ? hostbuf : NULL,
                                          ret == 0 && ni_req->getserv ? servbuf : NULL,
                                          errno, h_errno);
        }

        case REQUEST_TERMINATE:
                 /* Quit */
                 return -ECONNRESET;

        default:
                assert_not_reached();
        }

        return 0;
}

static void* thread_worker(void *p) {
        sd_resolve *resolve = p;

        /* Assign a pretty name to this thread */
        (void) pthread_setname_np(pthread_self(), "sd-resolve");

        while (!resolve->dead) {
                union {
                        Packet packet;
                        uint8_t space[BUFSIZE];
                } buf;
                ssize_t length;

                length = recv(resolve->fds[REQUEST_RECV_FD], &buf, sizeof buf, 0);
                if (length < 0) {
                        if (ERRNO_IS_TRANSIENT(errno))
                                continue;

                        break;
                }
                if (length == 0)
                        break;

                if (handle_request(resolve->fds[RESPONSE_SEND_FD], &buf.packet, (size_t) length) < 0)
                        break;
        }

        send_died(resolve->fds[RESPONSE_SEND_FD]);

        return NULL;
}

static int start_threads(sd_resolve *resolve, unsigned extra) {
        sigset_t ss, saved_ss;
        unsigned n;
        int r, k;

        assert_se(sigfillset(&ss) >= 0);

        /* No signals in forked off threads please. We set the mask before forking, so that the threads never exist
         * with a different mask than a fully blocked one */
        r = pthread_sigmask(SIG_BLOCK, &ss, &saved_ss);
        if (r > 0)
                return -r;

        n = resolve->n_outstanding + extra;
        n = CLAMP(n, WORKERS_MIN, WORKERS_MAX);

        while (resolve->n_valid_workers < n) {
                r = pthread_create(&resolve->workers[resolve->n_valid_workers], NULL, thread_worker, resolve);
                if (r > 0) {
                        r = -r;
                        goto finish;
                }

                resolve->n_valid_workers++;
        }

        r = 0;

finish:
        k = pthread_sigmask(SIG_SETMASK, &saved_ss, NULL);
        if (k > 0 && r >= 0)
                r = -k;

        return r;
}

static bool resolve_pid_changed(sd_resolve *r) {
        assert(r);

        /* We don't support people creating a resolver and keeping it
         * around after fork(). Let's complain. */

        return r->original_pid != getpid_cached();
}

_public_ int sd_resolve_new(sd_resolve **ret) {
        _cleanup_(sd_resolve_unrefp) sd_resolve *resolve = NULL;
        int i;

        assert_return(ret, -EINVAL);

        resolve = new0(sd_resolve, 1);
        if (!resolve)
                return -ENOMEM;

        resolve->n_ref = 1;
        resolve->original_pid = getpid_cached();

        for (i = 0; i < _FD_MAX; i++)
                resolve->fds[i] = -EBADF;

        if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + REQUEST_RECV_FD) < 0)
                return -errno;

        if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + RESPONSE_RECV_FD) < 0)
                return -errno;

        for (i = 0; i < _FD_MAX; i++)
                resolve->fds[i] = fd_move_above_stdio(resolve->fds[i]);

        (void) fd_inc_sndbuf(resolve->fds[REQUEST_SEND_FD], QUERIES_MAX * BUFSIZE);
        (void) fd_increase_rxbuf(resolve->fds[REQUEST_RECV_FD], QUERIES_MAX * BUFSIZE);
        (void) fd_inc_sndbuf(resolve->fds[RESPONSE_SEND_FD], QUERIES_MAX * BUFSIZE);
        (void) fd_increase_rxbuf(resolve->fds[RESPONSE_RECV_FD], QUERIES_MAX * BUFSIZE);

        (void) fd_nonblock(resolve->fds[RESPONSE_RECV_FD], true);

        *ret = TAKE_PTR(resolve);
        return 0;
}

_public_ int sd_resolve_default(sd_resolve **ret) {
        static thread_local sd_resolve *default_resolve = NULL;
        sd_resolve *e = NULL;
        int r;

        if (!ret)
                return !!default_resolve;

        if (default_resolve) {
                *ret = sd_resolve_ref(default_resolve);
                return 0;
        }

        r = sd_resolve_new(&e);
        if (r < 0)
                return r;

        e->default_resolve_ptr = &default_resolve;
        e->tid = gettid();
        default_resolve = e;

        *ret = e;
        return 1;
}

_public_ int sd_resolve_get_tid(sd_resolve *resolve, pid_t *tid) {
        assert_return(resolve, -EINVAL);
        assert_return(tid, -EINVAL);
        assert_return(!resolve_pid_changed(resolve), -ECHILD);

        if (resolve->tid != 0) {
                *tid = resolve->tid;
                return 0;
        }

        if (resolve->event)
                return sd_event_get_tid(resolve->event, tid);

        return -ENXIO;
}

static sd_resolve *resolve_free(sd_resolve *resolve) {
        PROTECT_ERRNO;
        sd_resolve_query *q;
        unsigned i;

        assert(resolve);

        while ((q = resolve->queries)) {
                assert(q->floating);
                resolve_query_disconnect(q);
                sd_resolve_query_unref(q);
        }

        if (resolve->default_resolve_ptr)
                *(resolve->default_resolve_ptr) = NULL;

        resolve->dead = true;

        sd_resolve_detach_event(resolve);

        if (resolve->fds[REQUEST_SEND_FD] >= 0) {

                RHeader req = {
                        .type = REQUEST_TERMINATE,
                        .length = sizeof req,
                };

                /* Send one termination packet for each worker */
                for (i = 0; i < resolve->n_valid_workers; i++)
                        (void) send(resolve->fds[REQUEST_SEND_FD], &req, req.length, MSG_NOSIGNAL);
        }

        /* Now terminate them and wait until they are gone.
           If we get an error than most likely the thread already exited. */
        for (i = 0; i < resolve->n_valid_workers; i++)
                (void) pthread_join(resolve->workers[i], NULL);

        /* Close all communication channels */
        close_many(resolve->fds, _FD_MAX);

        return mfree(resolve);
}

DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_resolve, sd_resolve, resolve_free);

_public_ int sd_resolve_get_fd(sd_resolve *resolve) {
        assert_return(resolve, -EINVAL);
        assert_return(!resolve_pid_changed(resolve), -ECHILD);

        return resolve->fds[RESPONSE_RECV_FD];
}

_public_ int sd_resolve_get_events(sd_resolve *resolve) {
        assert_return(resolve, -EINVAL);
        assert_return(!resolve_pid_changed(resolve), -ECHILD);

        return resolve->n_queries > resolve->n_done ? POLLIN : 0;
}

_public_ int sd_resolve_get_timeout(sd_resolve *resolve, uint64_t *usec) {
        assert_return(resolve, -EINVAL);
        assert_return(usec, -EINVAL);
        assert_return(!resolve_pid_changed(resolve), -ECHILD);

        *usec = UINT64_MAX;
        return 0;
}

static sd_resolve_query *lookup_query(sd_resolve *resolve, unsigned id) {
        sd_resolve_query *q;

        assert(resolve);

        q = resolve->query_array[id % QUERIES_MAX];
        if (q)
                if (q->id == id)
                        return q;

        return NULL;
}

static int complete_query(sd_resolve *resolve, sd_resolve_query *q) {
        int r;

        assert(q);
        assert(!q->done);
        assert(q->resolve == resolve);

        q->done = true;
        resolve->n_done++;

        resolve->current = sd_resolve_query_ref(q);

        switch (q->type) {

        case REQUEST_ADDRINFO:
                r = getaddrinfo_done(q);
                break;

        case REQUEST_NAMEINFO:
                r = getnameinfo_done(q);
                break;

        default:
                assert_not_reached();
        }

        resolve->current = NULL;

        if (q->floating) {
                resolve_query_disconnect(q);
                sd_resolve_query_unref(q);
        }

        sd_resolve_query_unref(q);

        return r;
}

static int unserialize_addrinfo(const void **p, size_t *length, struct addrinfo **ret_ai) {
        AddrInfoSerialization s;
        struct addrinfo *ai;
        size_t l;

        assert(p);
        assert(*p);
        assert(ret_ai);
        assert(length);

        if (*length < sizeof(AddrInfoSerialization))
                return -EBADMSG;

        memcpy(&s, *p, sizeof(s));

        l = sizeof(AddrInfoSerialization) + s.ai_addrlen + s.canonname_len;
        if (*length < l)
                return -EBADMSG;

        ai = new(struct addrinfo, 1);
        if (!ai)
                return -ENOMEM;

        *ai = (struct addrinfo) {
                .ai_flags = s.ai_flags,
                .ai_family = s.ai_family,
                .ai_socktype = s.ai_socktype,
                .ai_protocol = s.ai_protocol,
                .ai_addrlen = s.ai_addrlen,
        };

        if (s.ai_addrlen > 0) {
                ai->ai_addr = memdup((const uint8_t*) *p + sizeof(AddrInfoSerialization), s.ai_addrlen);
                if (!ai->ai_addr) {
                        free(ai);
                        return -ENOMEM;
                }
        }

        if (s.canonname_len > 0) {
                ai->ai_canonname = memdup((const uint8_t*) *p + sizeof(AddrInfoSerialization) + s.ai_addrlen, s.canonname_len);
                if (!ai->ai_canonname) {
                        free(ai->ai_addr);
                        free(ai);
                        return -ENOMEM;
                }
        }

        *length -= l;
        *ret_ai = ai;
        *p = ((const uint8_t*) *p) + l;

        return 0;
}

static int handle_response(sd_resolve *resolve, const Packet *packet, size_t length) {
        const RHeader *resp;
        sd_resolve_query *q;
        int r;

        assert(resolve);
        assert(packet);

        resp = &packet->rheader;
        assert_return(length >= sizeof(RHeader), -EIO);
        assert_return(length == resp->length, -EIO);

        if (resp->type == RESPONSE_DIED) {
                resolve->dead = true;
                return 0;
        }

        assert(resolve->n_outstanding > 0);
        resolve->n_outstanding--;

        q = lookup_query(resolve, resp->id);
        if (!q)
                return 0;

        switch (resp->type) {

        case RESPONSE_ADDRINFO: {
                const AddrInfoResponse *ai_resp = &packet->addrinfo_response;
                const void *p;
                size_t l;
                struct addrinfo *prev = NULL;

                assert_return(length >= sizeof(AddrInfoResponse), -EBADMSG);
                assert_return(q->type == REQUEST_ADDRINFO, -EBADMSG);

                query_assign_errno(q, ai_resp->ret, ai_resp->_errno, ai_resp->_h_errno);

                l = length - sizeof(AddrInfoResponse);
                p = (const uint8_t*) resp + sizeof(AddrInfoResponse);

                while (l > 0 && p) {
                        struct addrinfo *ai = NULL;

                        r = unserialize_addrinfo(&p, &l, &ai);
                        if (r < 0) {
                                query_assign_errno(q, EAI_SYSTEM, r, 0);
                                freeaddrinfo(q->addrinfo);
                                q->addrinfo = NULL;
                                break;
                        }

                        if (prev)
                                prev->ai_next = ai;
                        else
                                q->addrinfo = ai;

                        prev = ai;
                }

                return complete_query(resolve, q);
        }

        case RESPONSE_NAMEINFO: {
                const NameInfoResponse *ni_resp = &packet->nameinfo_response;

                assert_return(length >= sizeof(NameInfoResponse), -EBADMSG);
                assert_return(q->type == REQUEST_NAMEINFO, -EBADMSG);

                if (ni_resp->hostlen > DNS_HOSTNAME_MAX ||
                    ni_resp->servlen > DNS_HOSTNAME_MAX ||
                    sizeof(NameInfoResponse) + ni_resp->hostlen + ni_resp->servlen > length)
                        query_assign_errno(q, EAI_SYSTEM, EIO, 0);
                else {
                        query_assign_errno(q, ni_resp->ret, ni_resp->_errno, ni_resp->_h_errno);

                        if (ni_resp->hostlen > 0) {
                                q->host = strndup((const char*) ni_resp + sizeof(NameInfoResponse),
                                                  ni_resp->hostlen-1);
                                if (!q->host)
                                        query_assign_errno(q, EAI_MEMORY, ENOMEM, 0);
                        }

                        if (ni_resp->servlen > 0) {
                                q->serv = strndup((const char*) ni_resp + sizeof(NameInfoResponse) + ni_resp->hostlen,
                                                  ni_resp->servlen-1);
                                if (!q->serv)
                                        query_assign_errno(q, EAI_MEMORY, ENOMEM, 0);
                        }
                }

                return complete_query(resolve, q);
        }

        default:
                return 0;
        }
}

_public_ int sd_resolve_process(sd_resolve *resolve) {
        RESOLVE_DONT_DESTROY(resolve);

        union {
                Packet packet;
                uint8_t space[BUFSIZE];
        } buf;
        ssize_t l;
        int r;

        assert_return(resolve, -EINVAL);
        assert_return(!resolve_pid_changed(resolve), -ECHILD);

        /* We don't allow recursively invoking sd_resolve_process(). */
        assert_return(!resolve->current, -EBUSY);

        l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof buf, 0);
        if (l < 0) {
                if (ERRNO_IS_TRANSIENT(errno))
                        return 0;

                return -errno;
        }
        if (l == 0)
                return -ECONNREFUSED;

        r = handle_response(resolve, &buf.packet, (size_t) l);
        if (r < 0)
                return r;

        return 1;
}

_public_ int sd_resolve_wait(sd_resolve *resolve, uint64_t timeout_usec) {
        int r;

        assert_return(resolve, -EINVAL);
        assert_return(!resolve_pid_changed(resolve), -ECHILD);

        if (resolve->n_done >= resolve->n_queries)
                return 0;

        do {
                r = fd_wait_for_event(resolve->fds[RESPONSE_RECV_FD], POLLIN, timeout_usec);
        } while (r == -EINTR);

        if (r < 0)
                return r;
        if (r == 0)
                return -ETIMEDOUT;

        return sd_resolve_process(resolve);
}

static int alloc_query(sd_resolve *resolve, bool floating, sd_resolve_query **_q) {
        sd_resolve_query *q;
        int r;

        assert(resolve);
        assert(_q);

        if (resolve->n_queries >= QUERIES_MAX)
                return -ENOBUFS;

        r = start_threads(resolve, 1);
        if (r < 0)
                return r;

        while (resolve->query_array[resolve->current_id % QUERIES_MAX])
                resolve->current_id++;

        q = resolve->query_array[resolve->current_id % QUERIES_MAX] = new0(sd_resolve_query, 1);
        if (!q)
                return -ENOMEM;

        q->n_ref = 1;
        q->resolve = resolve;
        q->floating = floating;
        q->id = resolve->current_id++;

        if (!floating)
                sd_resolve_ref(resolve);

        LIST_PREPEND(queries, resolve->queries, q);
        resolve->n_queries++;

        *_q = q;
        return 0;
}

int resolve_getaddrinfo_with_destroy_callback(
                sd_resolve *resolve,
                sd_resolve_query **ret_query,
                const char *node, const char *service,
                const struct addrinfo *hints,
                sd_resolve_getaddrinfo_handler_t callback,
                sd_resolve_destroy_t destroy_callback,
                void *userdata) {

        _cleanup_(sd_resolve_query_unrefp) sd_resolve_query *q = NULL;
        size_t node_len, service_len;
        AddrInfoRequest req = {};
        struct iovec iov[3];
        struct msghdr mh = {};
        int r;

        assert_return(resolve, -EINVAL);
        assert_return(node || service, -EINVAL);
        assert_return(callback, -EINVAL);
        assert_return(!resolve_pid_changed(resolve), -ECHILD);

        r = alloc_query(resolve, !ret_query, &q);
        if (r < 0)
                return r;

        q->type = REQUEST_ADDRINFO;
        q->getaddrinfo_handler = callback;
        q->userdata = userdata;

        node_len = node ? strlen(node) + 1 : 0;
        service_len = service ? strlen(service) + 1 : 0;

        req = (AddrInfoRequest) {
                .node_len = node_len,
                .service_len = service_len,

                .header.id = q->id,
                .header.type = REQUEST_ADDRINFO,
                .header.length = sizeof(AddrInfoRequest) + node_len + service_len,

                .hints_valid = hints,
                .ai_flags = hints ? hints->ai_flags : 0,
                .ai_family = hints ? hints->ai_family : 0,
                .ai_socktype = hints ? hints->ai_socktype : 0,
                .ai_protocol = hints ? hints->ai_protocol : 0,
        };

        msan_unpoison(&req, sizeof(req));

        iov[mh.msg_iovlen++] = IOVEC_MAKE(&req, sizeof(AddrInfoRequest));
        if (node)
                iov[mh.msg_iovlen++] = IOVEC_MAKE((void*) node, req.node_len);
        if (service)
                iov[mh.msg_iovlen++] = IOVEC_MAKE((void*) service, req.service_len);
        mh.msg_iov = iov;

        if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0)
                return -errno;

        resolve->n_outstanding++;
        q->destroy_callback = destroy_callback;

        if (ret_query)
                *ret_query = q;

        TAKE_PTR(q);

        return 0;
}

_public_ int sd_resolve_getaddrinfo(
                sd_resolve *resolve,
                sd_resolve_query **ret_query,
                const char *node, const char *service,
                const struct addrinfo *hints,
                sd_resolve_getaddrinfo_handler_t callback,
                void *userdata) {

        return resolve_getaddrinfo_with_destroy_callback(resolve, ret_query, node, service, hints, callback, NULL, userdata);
}

static int getaddrinfo_done(sd_resolve_query* q) {
        assert(q);
        assert(q->done);
        assert(q->getaddrinfo_handler);

        errno = q->_errno;
        h_errno = q->_h_errno;

        return q->getaddrinfo_handler(q, q->ret, q->addrinfo, q->userdata);
}

int resolve_getnameinfo_with_destroy_callback(
                sd_resolve *resolve,
                sd_resolve_query **ret_query,
                const struct sockaddr *sa, socklen_t salen,
                int flags,
                uint64_t get,
                sd_resolve_getnameinfo_handler_t callback,
                sd_resolve_destroy_t destroy_callback,
                void *userdata) {

        _cleanup_(sd_resolve_query_unrefp) sd_resolve_query *q = NULL;
        NameInfoRequest req = {};
        struct iovec iov[2];
        struct msghdr mh;
        int r;

        assert_return(resolve, -EINVAL);
        assert_return(sa, -EINVAL);
        assert_return(salen >= sizeof(struct sockaddr), -EINVAL);
        assert_return(salen <= sizeof(union sockaddr_union), -EINVAL);
        assert_return((get & ~SD_RESOLVE_GET_BOTH) == 0, -EINVAL);
        assert_return(callback, -EINVAL);
        assert_return(!resolve_pid_changed(resolve), -ECHILD);

        r = alloc_query(resolve, !ret_query, &q);
        if (r < 0)
                return r;

        q->type = REQUEST_NAMEINFO;
        q->getnameinfo_handler = callback;
        q->userdata = userdata;

        req = (NameInfoRequest) {
                .header.id = q->id,
                .header.type = REQUEST_NAMEINFO,
                .header.length = sizeof(NameInfoRequest) + salen,

                .flags = flags,
                .sockaddr_len = salen,
                .gethost = !!(get & SD_RESOLVE_GET_HOST),
                .getserv = !!(get & SD_RESOLVE_GET_SERVICE),
        };

        msan_unpoison(&req, sizeof(req));

        iov[0] = IOVEC_MAKE(&req, sizeof(NameInfoRequest));
        iov[1] = IOVEC_MAKE((void*) sa, salen);

        mh = (struct msghdr) {
                .msg_iov = iov,
                .msg_iovlen = ELEMENTSOF(iov)
        };

        if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0)
                return -errno;

        resolve->n_outstanding++;
        q->destroy_callback = destroy_callback;

        if (ret_query)
                *ret_query = q;

        TAKE_PTR(q);

        return 0;
}

_public_ int sd_resolve_getnameinfo(
                sd_resolve *resolve,
                sd_resolve_query **ret_query,
                const struct sockaddr *sa, socklen_t salen,
                int flags,
                uint64_t get,
                sd_resolve_getnameinfo_handler_t callback,
                void *userdata) {

        return resolve_getnameinfo_with_destroy_callback(resolve, ret_query, sa, salen, flags, get, callback, NULL, userdata);
}

static int getnameinfo_done(sd_resolve_query *q) {

        assert(q);
        assert(q->done);
        assert(q->getnameinfo_handler);

        errno = q->_errno;
        h_errno = q->_h_errno;

        return q->getnameinfo_handler(q, q->ret, q->host, q->serv, q->userdata);
}

static void resolve_freeaddrinfo(struct addrinfo *ai) {
        while (ai) {
                struct addrinfo *next = ai->ai_next;

                free(ai->ai_addr);
                free(ai->ai_canonname);
                free(ai);
                ai = next;
        }
}

static void resolve_query_disconnect(sd_resolve_query *q) {
        sd_resolve *resolve;
        unsigned i;

        assert(q);

        if (!q->resolve)
                return;

        resolve = q->resolve;
        assert(resolve->n_queries > 0);

        if (q->done) {
                assert(resolve->n_done > 0);
                resolve->n_done--;
        }

        i = q->id % QUERIES_MAX;
        assert(resolve->query_array[i] == q);
        resolve->query_array[i] = NULL;
        LIST_REMOVE(queries, resolve->queries, q);
        resolve->n_queries--;

        q->resolve = NULL;
        if (!q->floating)
                sd_resolve_unref(resolve);
}

static sd_resolve_query *resolve_query_free(sd_resolve_query *q) {
        assert(q);

        resolve_query_disconnect(q);

        if (q->destroy_callback)
                q->destroy_callback(q->userdata);

        resolve_freeaddrinfo(q->addrinfo);
        free(q->host);
        free(q->serv);

        return mfree(q);
}

DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_resolve_query, sd_resolve_query, resolve_query_free);

_public_ int sd_resolve_query_is_done(sd_resolve_query *q) {
        assert_return(q, -EINVAL);
        assert_return(!resolve_pid_changed(q->resolve), -ECHILD);

        return q->done;
}

_public_ void* sd_resolve_query_set_userdata(sd_resolve_query *q, void *userdata) {
        void *ret;

        assert_return(q, NULL);
        assert_return(!resolve_pid_changed(q->resolve), NULL);

        ret = q->userdata;
        q->userdata = userdata;

        return ret;
}

_public_ void* sd_resolve_query_get_userdata(sd_resolve_query *q) {
        assert_return(q, NULL);
        assert_return(!resolve_pid_changed(q->resolve), NULL);

        return q->userdata;
}

_public_ sd_resolve *sd_resolve_query_get_resolve(sd_resolve_query *q) {
        assert_return(q, NULL);
        assert_return(!resolve_pid_changed(q->resolve), NULL);

        return q->resolve;
}

_public_ int sd_resolve_query_get_destroy_callback(sd_resolve_query *q, sd_resolve_destroy_t *destroy_callback) {
        assert_return(q, -EINVAL);

        if (destroy_callback)
                *destroy_callback = q->destroy_callback;

        return !!q->destroy_callback;
}

_public_ int sd_resolve_query_set_destroy_callback(sd_resolve_query *q, sd_resolve_destroy_t destroy_callback) {
        assert_return(q, -EINVAL);

        q->destroy_callback = destroy_callback;
        return 0;
}

_public_ int sd_resolve_query_get_floating(sd_resolve_query *q) {
        assert_return(q, -EINVAL);

        return q->floating;
}

_public_ int sd_resolve_query_set_floating(sd_resolve_query *q, int b) {
        assert_return(q, -EINVAL);

        if (q->floating == !!b)
                return 0;

        if (!q->resolve) /* Already disconnected */
                return -ESTALE;

        q->floating = b;

        if (b) {
                sd_resolve_query_ref(q);
                sd_resolve_unref(q->resolve);
        } else {
                sd_resolve_ref(q->resolve);
                sd_resolve_query_unref(q);
        }

        return 1;
}

static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
        sd_resolve *resolve = ASSERT_PTR(userdata);
        int r;

        r = sd_resolve_process(resolve);
        if (r < 0)
                return r;

        return 1;
}

_public_ int sd_resolve_attach_event(sd_resolve *resolve, sd_event *event, int64_t priority) {
        int r;

        assert_return(resolve, -EINVAL);
        assert_return(!resolve->event, -EBUSY);

        assert(!resolve->event_source);

        if (event)
                resolve->event = sd_event_ref(event);
        else {
                r = sd_event_default(&resolve->event);
                if (r < 0)
                        return r;
        }

        r = sd_event_add_io(resolve->event, &resolve->event_source, resolve->fds[RESPONSE_RECV_FD], POLLIN, io_callback, resolve);
        if (r < 0)
                goto fail;

        r = sd_event_source_set_priority(resolve->event_source, priority);
        if (r < 0)
                goto fail;

        return 0;

fail:
        sd_resolve_detach_event(resolve);
        return r;
}

_public_  int sd_resolve_detach_event(sd_resolve *resolve) {
        assert_return(resolve, -EINVAL);

        if (!resolve->event)
                return 0;

        resolve->event_source = sd_event_source_disable_unref(resolve->event_source);
        resolve->event = sd_event_unref(resolve->event);
        return 1;
}

_public_ sd_event *sd_resolve_get_event(sd_resolve *resolve) {
        assert_return(resolve, NULL);

        return resolve->event;
}
