Implement a generic interface to forward resolver queries to the lka
authoreric <eric@openbsd.org>
Wed, 25 Jul 2018 16:00:48 +0000 (16:00 +0000)
committereric <eric@openbsd.org>
Wed, 25 Jul 2018 16:00:48 +0000 (16:00 +0000)
process.  Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend.  So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@

usr.sbin/smtpd/dns.c
usr.sbin/smtpd/lka.c
usr.sbin/smtpd/mta.c
usr.sbin/smtpd/mta_session.c
usr.sbin/smtpd/pony.c
usr.sbin/smtpd/resolver.c [new file with mode: 0644]
usr.sbin/smtpd/smtp.c
usr.sbin/smtpd/smtp_session.c
usr.sbin/smtpd/smtpd.c
usr.sbin/smtpd/smtpd.h
usr.sbin/smtpd/smtpd/Makefile

index a37e3cd..86645fa 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dns.c,v 1.86 2018/05/31 21:06:12 gilles Exp $ */
+/*     $OpenBSD: dns.c,v 1.87 2018/07/25 16:00:48 eric Exp $   */
 
 /*
  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -58,7 +58,6 @@ struct dns_session {
 
 static void dns_lookup_host(struct dns_session *, const char *, int);
 static void dns_dispatch_host(struct asr_result *, void *);
-static void dns_dispatch_ptr(struct asr_result *, void *);
 static void dns_dispatch_mx(struct asr_result *, void *);
 static void dns_dispatch_mx_preference(struct asr_result *, void *);
 
@@ -134,16 +133,6 @@ dns_imsg(struct mproc *p, struct imsg *imsg)
                dns_lookup_host(s, host, -1);
                return;
 
-       case IMSG_MTA_DNS_PTR:
-       case IMSG_SMTP_DNS_PTR:
-               sa = (struct sockaddr *)&ss;
-               m_get_sockaddr(&m, sa);
-               m_end(&m);
-               as = getnameinfo_async(sa, sa->sa_len, s->name, sizeof(s->name),
-                   NULL, 0, 0, NULL);
-               event_asr_run(as, dns_dispatch_ptr, s);
-               return;
-
        case IMSG_MTA_DNS_MX:
                m_get_string(&m, &domain);
                m_end(&m);
@@ -240,21 +229,6 @@ dns_dispatch_host(struct asr_result *ar, void *arg)
        free(s);
 }
 
-static void
-dns_dispatch_ptr(struct asr_result *ar, void *arg)
-{
-       struct dns_session      *s = arg;
-
-       /* The error code could be more precise, but we don't currently care */
-       m_create(s->p,  s->type, 0, 0, -1);
-       m_add_id(s->p, s->reqid);
-       m_add_int(s->p, ar->ar_gai_errno ? DNS_ENOTFOUND : DNS_OK);
-       if (ar->ar_gai_errno == 0)
-               m_add_string(s->p, s->name);
-       m_close(s->p);
-       free(s);
-}
-
 static void
 dns_dispatch_mx(struct asr_result *ar, void *arg)
 {
index 7888915..8f67210 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: lka.c,v 1.206 2018/06/16 19:41:26 gilles Exp $        */
+/*     $OpenBSD: lka.c,v 1.207 2018/07/25 16:00:48 eric Exp $  */
 
 /*
  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -88,9 +88,12 @@ lka_imsg(struct mproc *p, struct imsg *imsg)
 
        switch (imsg->hdr.type) {
 
+       case IMSG_GETADDRINFO:
+       case IMSG_GETNAMEINFO:
+               resolver_dispatch_request(p, imsg);
+               return;
+
        case IMSG_MTA_DNS_HOST:
-       case IMSG_MTA_DNS_PTR:
-       case IMSG_SMTP_DNS_PTR:
        case IMSG_MTA_DNS_MX:
        case IMSG_MTA_DNS_MX_PREFERENCE:
                dns_imsg(p, imsg);
index 71657c2..5b39838 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mta.c,v 1.220 2018/07/08 13:06:37 gilles Exp $        */
+/*     $OpenBSD: mta.c,v 1.221 2018/07/25 16:00:48 eric Exp $  */
 
 /*
  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -312,10 +312,6 @@ mta_imsg(struct mproc *p, struct imsg *imsg)
                mta_on_preference(relay, preference);
                return;
 
-       case IMSG_MTA_DNS_PTR:
-               mta_session_imsg(p, imsg);
-               return;
-
        case IMSG_MTA_TLS_INIT:
                mta_session_imsg(p, imsg);
                return;
index e1def0b..f68266e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mta_session.c,v 1.104 2018/07/25 15:24:26 gilles Exp $        */
+/*     $OpenBSD: mta_session.c,v 1.105 2018/07/25 16:00:48 eric Exp $  */
 
 /*
  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -141,6 +141,7 @@ static void mta_session_init(void);
 static void mta_start(int fd, short ev, void *arg);
 static void mta_io(struct io *, int, void *);
 static void mta_free(struct mta_session *);
+static void mta_getnameinfo_cb(void *, int, const char *, const char *);
 static void mta_on_ptr(void *, void *, void *);
 static void mta_on_timeout(struct runq *, void *);
 static void mta_connect(struct mta_session *);
@@ -242,12 +243,7 @@ mta_session(struct mta_relay *relay, struct mta_route *route)
                evtimer_set(&s->ev, mta_start, s);
                evtimer_add(&s->ev, &tv);
        } else if (waitq_wait(&route->dst->ptrname, mta_on_ptr, s)) {
-               m_create(p_lka,  IMSG_MTA_DNS_PTR, 0, 0, -1);
-               m_add_id(p_lka, s->id);
-               m_add_sockaddr(p_lka, s->route->dst->sa);
-               m_close(p_lka);
-               tree_xset(&wait_ptr, s->id, s);
-               s->flags |= MTA_WAIT;
+               resolver_getnameinfo(s->route->dst->sa, 0, mta_getnameinfo_cb, s);
        }
 }
 
@@ -257,12 +253,11 @@ mta_session_imsg(struct mproc *p, struct imsg *imsg)
        struct ca_vrfy_resp_msg *resp_ca_vrfy;
        struct ca_cert_resp_msg *resp_ca_cert;
        struct mta_session      *s;
-       struct mta_host         *h;
        struct msg               m;
        uint64_t                 reqid;
        const char              *name;
        void                    *ssl;
-       int                      dnserror, status;
+       int                      status;
        struct stat              sb;
        
        switch (imsg->hdr.type) {
@@ -313,26 +308,6 @@ mta_session_imsg(struct mproc *p, struct imsg *imsg)
                mta_enter_state(s, MTA_MAIL);
                return;
 
-       case IMSG_MTA_DNS_PTR:
-               m_msg(&m, imsg);
-               m_get_id(&m, &reqid);
-               m_get_int(&m, &dnserror);
-               if (dnserror)
-                       name = NULL;
-               else
-                       m_get_string(&m, &name);
-               m_end(&m);
-               s = mta_tree_pop(&wait_ptr, reqid);
-               if (s == NULL)
-                       return;
-
-               h = s->route->dst;
-               h->lastptrquery = time(NULL);
-               if (name)
-                       h->ptrname = xstrdup(name);
-               waitq_run(&h->ptrname, h->ptrname);
-               return;
-
        case IMSG_MTA_TLS_INIT:
                resp_ca_cert = imsg->data;
                s = mta_tree_pop(&wait_ssl_init, resp_ca_cert->reqid);
@@ -464,6 +439,19 @@ mta_free(struct mta_session *s)
        mta_route_collect(relay, route);
 }
 
+static void
+mta_getnameinfo_cb(void *arg, int gaierrno, const char *host, const char *serv)
+{
+       struct mta_session *s = arg;
+       struct mta_host *h;
+
+       h = s->route->dst;
+       h->lastptrquery = time(NULL);
+       if (host)
+               h->ptrname = xstrdup(host);
+       waitq_run(&h->ptrname, h->ptrname);
+}
+
 static void
 mta_on_timeout(struct runq *runq, void *arg)
 {
index f7b3d8e..7af7f01 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pony.c,v 1.20 2018/05/24 11:38:24 gilles Exp $        */
+/*     $OpenBSD: pony.c,v 1.21 2018/07/25 16:00:48 eric Exp $  */
 
 /*
  * Copyright (c) 2014 Gilles Chehade <gilles@poolp.org>
@@ -56,6 +56,13 @@ pony_imsg(struct mproc *p, struct imsg *imsg)
                pony_shutdown();
 
        switch (imsg->hdr.type) {
+
+       case IMSG_GETADDRINFO:
+       case IMSG_GETADDRINFO_END:
+       case IMSG_GETNAMEINFO:
+               resolver_dispatch_result(p, imsg);
+               return;
+
        case IMSG_CONF_START:
                return;
        case IMSG_CONF_END:
@@ -75,7 +82,6 @@ pony_imsg(struct mproc *p, struct imsg *imsg)
                return;
 
        /* smtp imsg */
-       case IMSG_SMTP_DNS_PTR:
        case IMSG_SMTP_CHECK_SENDER:
        case IMSG_SMTP_EXPAND_RCPT:
        case IMSG_SMTP_LOOKUP_HELO:
@@ -104,7 +110,6 @@ pony_imsg(struct mproc *p, struct imsg *imsg)
        case IMSG_MTA_DNS_HOST:
        case IMSG_MTA_DNS_HOST_END:
        case IMSG_MTA_DNS_MX_PREFERENCE:
-       case IMSG_MTA_DNS_PTR:
        case IMSG_MTA_TLS_INIT:
        case IMSG_MTA_TLS_VERIFY:
        case IMSG_CTL_RESUME_ROUTE:
diff --git a/usr.sbin/smtpd/resolver.c b/usr.sbin/smtpd/resolver.c
new file mode 100644 (file)
index 0000000..fbb6ee0
--- /dev/null
@@ -0,0 +1,366 @@
+/*     $OpenBSD: resolver.c,v 1.1 2018/07/25 16:00:48 eric Exp $       */
+
+/*
+ * Copyright (c) 2017-2018 Eric Faurot <eric@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/tree.h>
+#include <sys/queue.h>
+#include <netinet/in.h>
+
+#include <asr.h>
+#include <ctype.h>
+#include <errno.h>
+#include <imsg.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "smtpd.h"
+#include "log.h"
+
+#define p_resolver p_lka
+
+struct request {
+       SPLAY_ENTRY(request)     entry;
+       uint32_t                 id;
+       void                    (*cb_ai)(void *, int, struct addrinfo *);
+       void                    (*cb_ni)(void *, int, const char *, const char *);
+       void                    *arg;
+       struct addrinfo         *ai;
+};
+
+struct session {
+       uint32_t         reqid;
+       struct mproc    *proc;
+       char            *host;
+       char            *serv;
+};
+
+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 int request_cmp(struct request *, struct request *);
+SPLAY_PROTOTYPE(reqtree, request, entry, request_cmp);
+
+static struct reqtree reqs;
+
+void
+resolver_getaddrinfo(const char *hostname, const char *servname,
+    const struct addrinfo *hints, void (*cb)(void *, int, struct addrinfo *),
+    void *arg)
+{
+       struct request *req;
+
+       resolver_init();
+
+       req = calloc(1, sizeof(*req));
+       if (req == NULL) {
+               cb(arg, EAI_MEMORY, NULL);
+               return;
+       }
+
+       while (req->id == 0 || SPLAY_FIND(reqtree, &reqs, req))
+               req->id = arc4random();
+       req->cb_ai = cb;
+       req->arg = arg;
+
+       SPLAY_INSERT(reqtree, &reqs, req);
+
+       m_create(p_resolver, IMSG_GETADDRINFO, req->id, 0, -1);
+       m_add_int(p_resolver, hints ? hints->ai_flags : 0);
+       m_add_int(p_resolver, hints ? hints->ai_family : 0);
+       m_add_int(p_resolver, hints ? hints->ai_socktype : 0);
+       m_add_int(p_resolver, hints ? hints->ai_protocol : 0);
+       m_add_string(p_resolver, hostname);
+       m_add_string(p_resolver, servname ? servname : "");
+       m_close(p_resolver);
+}
+
+void
+resolver_getnameinfo(const struct sockaddr *sa, int flags,
+    void(*cb)(void *, int, const char *, const char *), void *arg)
+{
+       struct request *req;
+
+       resolver_init();
+
+       req = calloc(1, sizeof(*req));
+       if (req == NULL) {
+               cb(arg, EAI_MEMORY, NULL, NULL);
+               return;
+       }
+
+       while (req->id == 0 || SPLAY_FIND(reqtree, &reqs, req))
+               req->id = arc4random();
+       req->cb_ni = cb;
+       req->arg = arg;
+
+       SPLAY_INSERT(reqtree, &reqs, req);
+
+       m_create(p_resolver, IMSG_GETNAMEINFO, req->id, 0, -1);
+       m_add_sockaddr(p_resolver, sa);
+       m_add_int(p_resolver, flags);
+       m_close(p_resolver);
+}
+
+void
+resolver_dispatch_request(struct mproc *proc, struct imsg *imsg)
+{
+       const char *hostname, *servname;
+       struct session *s;
+       struct asr_query *q;
+       struct addrinfo hints;
+       struct sockaddr_storage ss;
+       struct sockaddr *sa;
+       struct msg m;
+       uint32_t reqid;
+       int flags, save_errno;
+
+       reqid = imsg->hdr.peerid;
+       m_msg(&m, imsg);
+
+       switch (imsg->hdr.type) {
+
+       case IMSG_GETADDRINFO:
+               servname = NULL;
+               memset(&hints, 0 , sizeof(hints));
+               m_get_int(&m, &hints.ai_flags);
+               m_get_int(&m, &hints.ai_family);
+               m_get_int(&m, &hints.ai_socktype);
+               m_get_int(&m, &hints.ai_protocol);
+               m_get_string(&m, &hostname);
+               if (!m_is_eom(&m))
+                       m_get_string(&m, &servname);
+               m_end(&m);
+
+               s = NULL;
+               q = NULL;
+               if ((s = calloc(1, sizeof(*s))) &&
+                   (q = getaddrinfo_async(hostname, servname, &hints, NULL)) &&
+                   (event_asr_run(q, resolver_getaddrinfo_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_GETADDRINFO_END, reqid, 0, -1);
+               m_add_int(proc, EAI_SYSTEM);
+               m_add_int(proc, save_errno);
+               m_close(proc);
+               break;
+
+       case IMSG_GETNAMEINFO:
+               sa = (struct sockaddr*)&ss;
+               m_get_sockaddr(&m, sa);
+               m_get_int(&m, &flags);
+               m_end(&m);
+
+               s = NULL;
+               q = NULL;
+               if ((s = calloc(1, sizeof(*s))) &&
+                   (s->host = malloc(NI_MAXHOST)) &&
+                   (s->serv = malloc(NI_MAXSERV)) &&
+                   (q = getnameinfo_async(sa, sa->sa_len, s->host, NI_MAXHOST,
+                       s->serv, NI_MAXSERV, flags, NULL)) &&
+                   (event_asr_run(q, resolver_getnameinfo_cb, s))) {
+                       s->reqid = reqid;
+                       s->proc = proc;
+                       break;
+               }
+               save_errno = errno;
+
+               if (q)
+                       asr_abort(q);
+               if (s) {
+                       free(s->host);
+                       free(s->serv);
+                       free(s);
+               }
+
+               m_create(proc, IMSG_GETNAMEINFO, reqid, 0, -1);
+               m_add_int(proc, EAI_SYSTEM);
+               m_add_int(proc, save_errno);
+               m_add_string(proc, "");
+               m_add_string(proc, "");
+               m_close(proc);
+               break;
+
+       default:
+               fatalx("%s: %s", __func__, imsg_to_str(imsg->hdr.type));
+       }
+}
+
+void
+resolver_dispatch_result(struct mproc *proc, struct imsg *imsg)
+{
+       struct request key, *req;
+       struct sockaddr_storage ss;
+       struct addrinfo *ai;
+       struct msg m;
+       const char *cname, *host, *serv;
+       int gai_errno;
+
+       key.id = imsg->hdr.peerid;
+       req = SPLAY_FIND(reqtree, &reqs, &key);
+       if (req == NULL)
+               fatalx("%s: unknown request %08x", __func__, imsg->hdr.peerid);
+
+       m_msg(&m, imsg);
+
+       switch (imsg->hdr.type) {
+
+       case IMSG_GETADDRINFO:
+               ai = calloc(1, sizeof(*ai));
+               if (ai == NULL) {
+                       log_warn("%s: calloc", __func__);
+                       break;
+               }
+               m_get_int(&m, &ai->ai_flags);
+               m_get_int(&m, &ai->ai_family);
+               m_get_int(&m, &ai->ai_socktype);
+               m_get_int(&m, &ai->ai_protocol);
+               m_get_sockaddr(&m, (struct sockaddr *)&ss);
+               m_get_string(&m, &cname);
+               m_end(&m);
+
+               ai->ai_addr = malloc(ss.ss_len);
+               if (ai->ai_addr == NULL) {
+                       log_warn("%s: malloc", __func__);
+                       free(ai);
+                       break;
+               }
+
+               memmove(ai->ai_addr, &ss, ss.ss_len);
+
+               if (cname[0]) {
+                       ai->ai_canonname = strdup(cname);
+                       if (ai->ai_canonname == NULL) {
+                               log_warn("%s: strdup", __func__);
+                               free(ai->ai_addr);
+                               free(ai);
+                               break;
+                       }
+               }
+
+               ai->ai_next = req->ai;
+               req->ai = ai;
+               break;
+
+       case IMSG_GETADDRINFO_END:
+               m_get_int(&m, &gai_errno);
+               m_get_int(&m, &errno);
+               m_end(&m);
+
+               SPLAY_REMOVE(reqtree, &reqs, req);
+               req->cb_ai(req->arg, gai_errno, req->ai);
+               free(req);
+               break;
+
+       case IMSG_GETNAMEINFO:
+               m_get_int(&m, &gai_errno);
+               m_get_int(&m, &errno);
+               m_get_string(&m, &host);
+               m_get_string(&m, &serv);
+               m_end(&m);
+
+               SPLAY_REMOVE(reqtree, &reqs, req);
+               req->cb_ni(req->arg, gai_errno, host[0] ? host : NULL,
+                   serv[0] ? serv : NULL);
+               free(req);
+               break;
+       }
+}
+
+static void
+resolver_init(void)
+{
+       static int init = 0;
+
+       if (init == 0) {
+               SPLAY_INIT(&reqs);
+               init = 1;
+       }
+}
+
+static void
+resolver_getaddrinfo_cb(struct asr_result *ar, void *arg)
+{
+       struct session *s = arg;
+       struct addrinfo *ai;
+
+       for (ai = ar->ar_addrinfo; ai; ai = ai->ai_next) {
+               m_create(s->proc, IMSG_GETADDRINFO, s->reqid, 0, -1);
+               m_add_int(s->proc, ai->ai_flags);
+               m_add_int(s->proc, ai->ai_family);
+               m_add_int(s->proc, ai->ai_socktype);
+               m_add_int(s->proc, ai->ai_protocol);
+               m_add_sockaddr(s->proc, ai->ai_addr);
+               m_add_string(s->proc, ai->ai_canonname ?
+                   ai->ai_canonname : "");
+               m_close(s->proc);
+       }
+
+       m_create(s->proc, IMSG_GETADDRINFO_END, s->reqid, 0, -1);
+       m_add_int(s->proc, ar->ar_gai_errno);
+       m_add_int(s->proc, ar->ar_errno);
+       m_close(s->proc);
+
+       freeaddrinfo(ar->ar_addrinfo);
+       free(s);
+}
+
+static void
+resolver_getnameinfo_cb(struct asr_result *ar, void *arg)
+{
+       struct session *s = arg;
+
+       m_create(s->proc, IMSG_GETNAMEINFO, s->reqid, 0, -1);
+       m_add_int(s->proc, ar->ar_gai_errno);
+       m_add_int(s->proc, ar->ar_errno);
+       m_add_string(s->proc, s->host ? s->host : "");
+       m_add_string(s->proc, s->serv ? s->serv : "");
+       m_close(s->proc);
+
+       free(s->host);
+       free(s->serv);
+       free(s);
+}
+
+static int
+request_cmp(struct request *a, struct request *b)
+{
+       if (a->id < b->id)
+               return -1;
+       if (a->id > b->id)
+               return 1;
+       return 0;
+}
+
+SPLAY_GENERATE(reqtree, request, entry, request_cmp);
index a6d6367..80fc099 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: smtp.c,v 1.158 2018/06/18 18:14:39 gilles Exp $       */
+/*     $OpenBSD: smtp.c,v 1.159 2018/07/25 16:00:48 eric Exp $ */
 
 /*
  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -62,7 +62,6 @@ void
 smtp_imsg(struct mproc *p, struct imsg *imsg)
 {
        switch (imsg->hdr.type) {
-       case IMSG_SMTP_DNS_PTR:
        case IMSG_SMTP_CHECK_SENDER:
        case IMSG_SMTP_EXPAND_RCPT:
        case IMSG_SMTP_LOOKUP_HELO:
index aa0d985..689d651 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: smtp_session.c,v 1.333 2018/07/08 13:06:37 gilles Exp $       */
+/*     $OpenBSD: smtp_session.c,v 1.334 2018/07/25 16:00:48 eric Exp $ */
 
 /*
  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -158,6 +158,7 @@ struct smtp_session {
 static int smtp_mailaddr(struct mailaddr *, char *, int, char **, const char *);
 static void smtp_session_init(void);
 static int smtp_lookup_servername(struct smtp_session *);
+static void smtp_getnameinfo_cb(void *, int, const char *, const char *);
 static void smtp_connected(struct smtp_session *);
 static void smtp_send_banner(struct smtp_session *);
 static void smtp_tls_verified(struct smtp_session *);
@@ -203,7 +204,6 @@ static struct { int code; const char *cmd; } commands[] = {
        { -1, NULL },
 };
 
-static struct tree wait_lka_ptr;
 static struct tree wait_lka_helo;
 static struct tree wait_lka_mail;
 static struct tree wait_lka_rcpt;
@@ -519,7 +519,6 @@ smtp_session_init(void)
        static int      init = 0;
 
        if (!init) {
-               tree_init(&wait_lka_ptr);
                tree_init(&wait_lka_helo);
                tree_init(&wait_lka_mail);
                tree_init(&wait_lka_rcpt);
@@ -576,11 +575,8 @@ smtp_session(struct listener *listener, int sock,
                if (smtp_lookup_servername(s))
                        smtp_connected(s);
        } else {
-               m_create(p_lka,  IMSG_SMTP_DNS_PTR, 0, 0, -1);
-               m_add_id(p_lka, s->id);
-               m_add_sockaddr(p_lka, (struct sockaddr *)&s->ss);
-               m_close(p_lka);
-               tree_xset(&wait_lka_ptr, s->id, s);
+               resolver_getnameinfo((struct sockaddr *)&s->ss, 0,
+                   smtp_getnameinfo_cb, s);
        }
 
        /* session may have been freed by now */
@@ -588,6 +584,20 @@ smtp_session(struct listener *listener, int sock,
        return (0);
 }
 
+static void
+smtp_getnameinfo_cb(void *arg, int gaierrno, const char *host, const char *serv)
+{
+       struct smtp_session *s = arg;
+
+       if (gaierrno)
+               host = "<unknown>";
+
+       (void)strlcpy(s->hostname, host, sizeof(s->hostname));
+
+       if (smtp_lookup_servername(s))
+               smtp_connected(s);
+}
+
 void
 smtp_session_imsg(struct mproc *p, struct imsg *imsg)
 {
@@ -601,24 +611,10 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
        const char                      *line, *helo;
        uint64_t                         reqid, evpid;
        uint32_t                         msgid;
-       int                              status, success, dnserror;
+       int                              status, success;
        void                            *ssl_ctx;
 
        switch (imsg->hdr.type) {
-       case IMSG_SMTP_DNS_PTR:
-               m_msg(&m, imsg);
-               m_get_id(&m, &reqid);
-               m_get_int(&m, &dnserror);
-               if (dnserror)
-                       line = "<unknown>";
-               else
-                       m_get_string(&m, &line);
-               m_end(&m);
-               s = tree_xpop(&wait_lka_ptr, reqid);
-               (void)strlcpy(s->hostname, line, sizeof s->hostname);
-               if (smtp_lookup_servername(s))
-                       smtp_connected(s);
-               return;
 
        case IMSG_SMTP_CHECK_SENDER:
                m_msg(&m, imsg);
index 1816cb4..77fee03 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: smtpd.c,v 1.301 2018/06/28 17:40:10 tim Exp $ */
+/*     $OpenBSD: smtpd.c,v 1.302 2018/07/25 16:00:48 eric Exp $        */
 
 /*
  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -1775,6 +1775,10 @@ imsg_to_str(int type)
 
        CASE(IMSG_CTL_SMTP_SESSION);
 
+       CASE(IMSG_GETADDRINFO);
+       CASE(IMSG_GETADDRINFO_END);
+       CASE(IMSG_GETNAMEINFO);
+
        CASE(IMSG_SETUP_KEY);
        CASE(IMSG_SETUP_PEER);
        CASE(IMSG_SETUP_DONE);
@@ -1829,7 +1833,6 @@ imsg_to_str(int type)
        CASE(IMSG_MTA_DELIVERY_HOLD);
        CASE(IMSG_MTA_DNS_HOST);
        CASE(IMSG_MTA_DNS_HOST_END);
-       CASE(IMSG_MTA_DNS_PTR);
        CASE(IMSG_MTA_DNS_MX);
        CASE(IMSG_MTA_DNS_MX_PREFERENCE);
        CASE(IMSG_MTA_HOLDQ_RELEASE);
@@ -1852,7 +1855,6 @@ imsg_to_str(int type)
        CASE(IMSG_SCHED_ENVELOPE_TRANSFER);
 
        CASE(IMSG_SMTP_AUTHENTICATE);
-       CASE(IMSG_SMTP_DNS_PTR);
        CASE(IMSG_SMTP_MESSAGE_COMMIT);
        CASE(IMSG_SMTP_MESSAGE_CREATE);
        CASE(IMSG_SMTP_MESSAGE_ROLLBACK);
index a69e216..6e06639 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: smtpd.h,v 1.555 2018/06/18 18:19:14 gilles Exp $      */
+/*     $OpenBSD: smtpd.h,v 1.556 2018/07/25 16:00:48 eric Exp $        */
 
 /*
  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -23,6 +23,7 @@
 #endif
 
 #include <netinet/in.h>
+#include <netdb.h>
 #include <event.h>
 
 #include "smtpd-defines.h"
@@ -199,6 +200,10 @@ enum imsg_type {
 
        IMSG_CTL_SMTP_SESSION,
 
+       IMSG_GETADDRINFO,
+       IMSG_GETADDRINFO_END,
+       IMSG_GETNAMEINFO,
+
        IMSG_SETUP_KEY,
        IMSG_SETUP_PEER,
        IMSG_SETUP_DONE,
@@ -255,7 +260,6 @@ enum imsg_type {
        IMSG_MTA_DELIVERY_HOLD,
        IMSG_MTA_DNS_HOST,
        IMSG_MTA_DNS_HOST_END,
-       IMSG_MTA_DNS_PTR,
        IMSG_MTA_DNS_MX,
        IMSG_MTA_DNS_MX_PREFERENCE,
        IMSG_MTA_HOLDQ_RELEASE,
@@ -278,7 +282,6 @@ enum imsg_type {
        IMSG_SCHED_ENVELOPE_TRANSFER,
 
        IMSG_SMTP_AUTHENTICATE,
-       IMSG_SMTP_DNS_PTR,
        IMSG_SMTP_MESSAGE_COMMIT,
        IMSG_SMTP_MESSAGE_CREATE,
        IMSG_SMTP_MESSAGE_ROLLBACK,
@@ -1362,6 +1365,15 @@ int pony(void);
 void pony_imsg(struct mproc *, struct imsg *);
 
 
+/* resolver.c */
+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_dispatch_request(struct mproc *, struct imsg *);
+void resolver_dispatch_result(struct mproc *, struct imsg *);
+
+
 /* smtp.c */
 void smtp_postfork(void);
 void smtp_postprivdrop(void);
index 4d7793c..a2afda8 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.91 2018/06/03 14:04:06 gilles Exp $
+#      $OpenBSD: Makefile,v 1.92 2018/07/25 16:00:48 eric Exp $
 
 .PATH:         ${.CURDIR}/..
 
@@ -35,6 +35,7 @@ SRCS+=        parse.y
 SRCS+= pony.c
 SRCS+= queue.c
 SRCS+= queue_backend.c
+SRCS+= resolver.c
 SRCS+= ruleset.c
 SRCS+= runq.c
 SRCS+= scheduler.c