summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
authorEric Faurot <eric@cvs.openbsd.org>2011-07-20 10:22:55 +0000
committerEric Faurot <eric@cvs.openbsd.org>2011-07-20 10:22:55 +0000
commit8e9f07389c9968fc6313dfa520da7ec09d892b76 (patch)
treeb96d1787bf2ee1a41d9c28812ceba6b8e15aa5ab /usr.sbin/smtpd
parent78cc6364dc5e6e09fe86328fe858d182fa0d8dab (diff)
Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there. ok gilles@
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/dns.c46
-rw-r--r--usr.sbin/smtpd/mta.c20
-rw-r--r--usr.sbin/smtpd/smtpd.h10
3 files changed, 50 insertions, 26 deletions
diff --git a/usr.sbin/smtpd/dns.c b/usr.sbin/smtpd/dns.c
index f587eed5a08..e1a66e92a06 100644
--- a/usr.sbin/smtpd/dns.c
+++ b/usr.sbin/smtpd/dns.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dns.c,v 1.43 2011/07/03 17:48:40 nicm Exp $ */
+/* $OpenBSD: dns.c,v 1.44 2011/07/20 10:22:54 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -72,6 +72,7 @@ static void dns_asr_handler(int, short, void *);
static void dns_asr_dispatch_host(struct dnssession *);
static void dns_asr_dispatch_mx(struct dnssession *);
static void dns_asr_dispatch_cname(struct dnssession *);
+static void dns_reply(struct dns *, int);
struct asr *asr = NULL;
@@ -168,10 +169,14 @@ dns_async(struct imsgev *asker, int type, struct dns *query)
env->stats->lka.queries_failure++;
dnssession_destroy(dnssession);
noasr:
- query->error = EAI_AGAIN;
- if (type != IMSG_DNS_PTR)
- type = IMSG_DNS_HOST_END;
- imsg_compose_event(asker, type, 0, 0, -1, query, sizeof(*query));
+ query->error = DNS_RETRY;
+ dns_reply(query, type != IMSG_DNS_PTR ? IMSG_DNS_HOST_END : type);
+}
+
+static void
+dns_reply(struct dns *query, int type)
+{
+ imsg_compose_event(query->asker, type, 0, 0, -1, query, sizeof(*query));
}
static void
@@ -222,13 +227,27 @@ dns_asr_dispatch_mx(struct dnssession *dnssession)
return;
}
- if (ar.ar_err)
- goto hosts; /* empty list */
+ if (ar.ar_err) {
+ /* temporary internal error, except for invalid name */
+ query->error = (ar.ar_err == EASR_NAME) ? DNS_EINVAL : DNS_RETRY;
+ dns_reply(query, IMSG_DNS_HOST_END);
+ dnssession_destroy(dnssession);
+ return;
+ }
packed_init(&pack, ar.ar_data, ar.ar_datalen);
unpack_header(&pack, &h);
unpack_query(&pack, &q);
+ /* check if the domain name exists */
+ /* XXX what about other DNS error codes? */
+ if (RCODE(h.flags) == ERR_NAME) {
+ query->error = DNS_ENONAME;
+ dns_reply(query, IMSG_DNS_HOST_END);
+ dnssession_destroy(dnssession);
+ return;
+ }
+
if (h.ancount == 0)
/* fallback to host if no MX is found. */
dnssession_mx_insert(dnssession, query->host, 0);
@@ -243,7 +262,6 @@ dns_asr_dispatch_mx(struct dnssession *dnssession)
free(ar.ar_data);
ar.ar_data = NULL;
-hosts:
/* Now we have a sorted list of MX to resolve. Simply "turn" this
* MX session into a regular host session.
*/
@@ -264,11 +282,11 @@ next:
/* query all listed hosts in turn */
while (dnssession->aq == NULL) {
if (dnssession->mxcurrent == dnssession->mxarraysz) {
- query->error = (dnssession->mxfound) ? 0 : EAI_NONAME;
+ /* XXX although not likely, this can still be temporary */
+ query->error = (dnssession->mxfound) ? DNS_OK : DNS_ENOTFOUND;
if (query->error)
env->stats->lka.queries_failure++;
- imsg_compose_event(query->asker, IMSG_DNS_HOST_END, 0,
- 0, -1, query, sizeof(*query));
+ dns_reply(query, IMSG_DNS_HOST_END);
dnssession_destroy(dnssession);
return;
}
@@ -280,8 +298,7 @@ next:
free(ar.ar_cname);
memcpy(&query->ss, &ar.ar_sa.sa, ar.ar_sa.sa.sa_len);
query->error = 0;
- imsg_compose_event(query->asker, IMSG_DNS_HOST, 0, 0, -1, query,
- sizeof(*query));
+ dns_reply(query, IMSG_DNS_HOST);
dnssession->mxfound++;
}
@@ -317,8 +334,7 @@ dns_asr_dispatch_cname(struct dnssession *dnssession)
query->error = ar.ar_err;
break;
}
- imsg_compose_event(query->asker, IMSG_DNS_PTR, 0, 0, -1, query,
- sizeof(*query));
+ dns_reply(query, IMSG_DNS_PTR);
dnssession_destroy(dnssession);
}
diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c
index 935131b5e8d..7959cc09407 100644
--- a/usr.sbin/smtpd/mta.c
+++ b/usr.sbin/smtpd/mta.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta.c,v 1.109 2011/07/19 13:15:54 eric Exp $ */
+/* $OpenBSD: mta.c,v 1.110 2011/07/20 10:22:54 eric Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -552,15 +552,15 @@ mta_pickup(struct mta_session *s, void *p)
case MTA_MX:
/* LKA responded to DNS lookup. */
- error = *(int *)p;
- if (error == EAI_AGAIN) {
- mta_status(s, "100 MX lookup failed temporarily");
- mta_enter_state(s, MTA_DONE, NULL);
- } else if (error == EAI_NONAME) {
- mta_status(s, "600 Domain does not exist");
- mta_enter_state(s, MTA_DONE, NULL);
- } else if (error) {
- mta_status(s, "600 Unable to resolve DNS for domain");
+ if ((error = *(int *)p)) {
+ if (error == DNS_RETRY)
+ mta_status(s, "100 MX lookup failed temporarily");
+ else if (error == DNS_EINVAL)
+ mta_status(s, "600 Invalid domain name");
+ else if (error == DNS_ENONAME)
+ mta_status(s, "600 Domain does not exist");
+ else if (error == DNS_ENOTFOUND)
+ mta_status(s, "600 No MX address found for domain");
mta_enter_state(s, MTA_DONE, NULL);
} else
mta_enter_state(s, MTA_DATA, NULL);
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index f2a92a0e976..1be8b5c8c8b 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.227 2011/06/09 17:41:52 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.228 2011/07/20 10:22:54 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -745,6 +745,14 @@ struct forward_req {
struct envelope envelope;
};
+enum dns_status {
+ DNS_OK = 0,
+ DNS_RETRY,
+ DNS_EINVAL,
+ DNS_ENONAME,
+ DNS_ENOTFOUND,
+};
+
struct dns {
u_int64_t id;
char host[MAXHOSTNAMELEN];