From: eric Date: Thu, 13 Jun 2019 11:45:34 +0000 (+0000) Subject: extend the resolver interface to delegate res_query() calls to the lka. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=01361951f211b839499798d3635b123b338840d4;p=openbsd extend the resolver interface to delegate res_query() calls to the lka. ok gilles@ sunil@ --- diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c index fcb4ad6b866..d5d55410231 100644 --- a/usr.sbin/smtpd/lka.c +++ b/usr.sbin/smtpd/lka.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka.c,v 1.233 2019/01/05 09:43:39 gilles Exp $ */ +/* $OpenBSD: lka.c,v 1.234 2019/06/13 11:45:34 eric Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard @@ -102,6 +102,7 @@ lka_imsg(struct mproc *p, struct imsg *imsg) case IMSG_GETADDRINFO: case IMSG_GETNAMEINFO: + case IMSG_RES_QUERY: resolver_dispatch_request(p, imsg); return; diff --git a/usr.sbin/smtpd/pony.c b/usr.sbin/smtpd/pony.c index aeb7a52204e..026d647307a 100644 --- a/usr.sbin/smtpd/pony.c +++ b/usr.sbin/smtpd/pony.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pony.c,v 1.26 2018/12/23 16:37:53 eric Exp $ */ +/* $OpenBSD: pony.c,v 1.27 2019/06/13 11:45:35 eric Exp $ */ /* * Copyright (c) 2014 Gilles Chehade @@ -60,6 +60,7 @@ pony_imsg(struct mproc *p, struct imsg *imsg) case IMSG_GETADDRINFO: case IMSG_GETADDRINFO_END: case IMSG_GETNAMEINFO: + case IMSG_RES_QUERY: resolver_dispatch_result(p, imsg); return; diff --git a/usr.sbin/smtpd/resolver.c b/usr.sbin/smtpd/resolver.c index 5422141647b..ce047b24927 100644 --- a/usr.sbin/smtpd/resolver.c +++ b/usr.sbin/smtpd/resolver.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolver.c,v 1.4 2018/11/12 12:31:49 eric Exp $ */ +/* $OpenBSD: resolver.c,v 1.5 2019/06/13 11:45:35 eric Exp $ */ /* * Copyright (c) 2017-2018 Eric Faurot @@ -43,6 +43,7 @@ struct request { uint32_t id; void (*cb_ai)(void *, int, struct addrinfo *); void (*cb_ni)(void *, int, const char *, const char *); + void (*cb_res)(void *, int, int, int, const void *, int); void *arg; struct addrinfo *ai; }; @@ -59,6 +60,7 @@ SPLAY_HEAD(reqtree, request); static void resolver_init(void); static void resolver_getaddrinfo_cb(struct asr_result *, void *); static void resolver_getnameinfo_cb(struct asr_result *, void *); +static void resolver_res_query_cb(struct asr_result *, void *); static int request_cmp(struct request *, struct request *); SPLAY_PROTOTYPE(reqtree, request, entry, request_cmp); @@ -124,10 +126,38 @@ resolver_getnameinfo(const struct sockaddr *sa, int flags, m_close(p_resolver); } +void +resolver_res_query(const char *dname, int class, int type, + void (*cb)(void *, int, int, int, const void *, int), void *arg) +{ + struct request *req; + + resolver_init(); + + req = calloc(1, sizeof(*req)); + if (req == NULL) { + cb(arg, NETDB_INTERNAL, 0, 0, NULL, 0); + return; + } + + while (req->id == 0 || SPLAY_FIND(reqtree, &reqs, req)) + req->id = arc4random(); + req->cb_res = cb; + req->arg = arg; + + SPLAY_INSERT(reqtree, &reqs, req); + + m_create(p_resolver, IMSG_RES_QUERY, req->id, 0, -1); + m_add_string(p_resolver, dname); + m_add_int(p_resolver, class); + m_add_int(p_resolver, type); + m_close(p_resolver); +} + void resolver_dispatch_request(struct mproc *proc, struct imsg *imsg) { - const char *hostname, *servname; + const char *hostname, *servname, *dname; struct session *s; struct asr_query *q; struct addrinfo hints; @@ -135,7 +165,7 @@ resolver_dispatch_request(struct mproc *proc, struct imsg *imsg) struct sockaddr *sa; struct msg m; uint32_t reqid; - int flags, save_errno; + int class, type, flags, save_errno; reqid = imsg->hdr.peerid; m_msg(&m, imsg); @@ -211,6 +241,37 @@ resolver_dispatch_request(struct mproc *proc, struct imsg *imsg) m_close(proc); break; + case IMSG_RES_QUERY: + m_get_string(&m, &dname); + m_get_int(&m, &class); + m_get_int(&m, &type); + m_end(&m); + + s = NULL; + q = NULL; + if ((s = calloc(1, sizeof(*s))) && + (q = res_query_async(dname, class, type, NULL)) && + (event_asr_run(q, resolver_res_query_cb, s))) { + s->reqid = reqid; + s->proc = proc; + break; + } + save_errno = errno; + + if (q) + asr_abort(q); + if (s) + free(s); + + m_create(proc, IMSG_RES_QUERY, reqid, 0, -1); + m_add_int(proc, NETDB_INTERNAL); + m_add_int(proc, save_errno); + m_add_int(proc, 0); + m_add_int(proc, 0); + m_add_data(proc, NULL, 0); + m_close(proc); + break; + default: fatalx("%s: %s", __func__, imsg_to_str(imsg->hdr.type)); } @@ -224,7 +285,9 @@ resolver_dispatch_result(struct mproc *proc, struct imsg *imsg) struct addrinfo *ai; struct msg m; const char *cname, *host, *serv; - int gai_errno; + const void *data; + size_t datalen; + int gai_errno, herrno, rcode, count; key.id = imsg->hdr.peerid; req = SPLAY_FIND(reqtree, &reqs, &key); @@ -293,6 +356,19 @@ resolver_dispatch_result(struct mproc *proc, struct imsg *imsg) req->cb_ni(req->arg, gai_errno, host, serv); free(req); break; + + case IMSG_RES_QUERY: + m_get_int(&m, &herrno); + m_get_int(&m, &errno); + m_get_int(&m, &rcode); + m_get_int(&m, &count); + m_get_data(&m, &data, &datalen); + m_end(&m); + + SPLAY_REMOVE(reqtree, &reqs, req); + req->cb_res(req->arg, herrno, rcode, count, data, datalen); + free(req); + break; } } @@ -351,6 +427,23 @@ resolver_getnameinfo_cb(struct asr_result *ar, void *arg) free(s); } +static void +resolver_res_query_cb(struct asr_result *ar, void *arg) +{ + struct session *s = arg; + + m_create(s->proc, IMSG_RES_QUERY, s->reqid, 0, -1); + m_add_int(s->proc, ar->ar_h_errno); + m_add_int(s->proc, ar->ar_errno); + m_add_int(s->proc, ar->ar_rcode); + m_add_int(s->proc, ar->ar_count); + m_add_data(s->proc, ar->ar_data, ar->ar_datalen); + m_close(s->proc); + + free(ar->ar_data); + free(s); +} + static int request_cmp(struct request *a, struct request *b) { diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index 2a32f81ce90..d2c4da6b070 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.319 2019/06/05 06:40:13 gilles Exp $ */ +/* $OpenBSD: smtpd.c,v 1.320 2019/06/13 11:45:35 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -1905,6 +1905,7 @@ imsg_to_str(int type) CASE(IMSG_GETADDRINFO); CASE(IMSG_GETADDRINFO_END); CASE(IMSG_GETNAMEINFO); + CASE(IMSG_RES_QUERY); CASE(IMSG_CERT_INIT); CASE(IMSG_CERT_CERTIFICATE); diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index 7bc3691f23b..74e758f5665 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.622 2019/06/05 06:40:13 gilles Exp $ */ +/* $OpenBSD: smtpd.h,v 1.623 2019/06/13 11:45:35 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -207,6 +207,7 @@ enum imsg_type { IMSG_GETADDRINFO, IMSG_GETADDRINFO_END, IMSG_GETNAMEINFO, + IMSG_RES_QUERY, IMSG_CERT_INIT, IMSG_CERT_CERTIFICATE, @@ -1530,6 +1531,8 @@ void resolver_getaddrinfo(const char *, const char *, const struct addrinfo *, void(*)(void *, int, struct addrinfo*), void *); void resolver_getnameinfo(const struct sockaddr *, int, void(*)(void *, int, const char *, const char *), void *); +void resolver_res_query(const char *, int, int, + void (*cb)(void *, int, int, int, const void *, int), void *); void resolver_dispatch_request(struct mproc *, struct imsg *); void resolver_dispatch_result(struct mproc *, struct imsg *);