Hello,

sorry for the terrifc delay.

On 2023/10/01 14:59:15 +0200, Philipp <philipp+open...@bureaucracy.de> wrote:
> Hi
> 
> Setting Null MX is a way for domainowners to indicate that the domain
> does not accept mail. Currently a Null MX causes a tempfail and the
> mail will be queued and tried to resubmitted till a timeout. With the
> attached patch a Null MX causes a permfail. This way the sender will
> directly get a bounce with the message "Domain does not accept mail".

I'm not sure how much widespread the usage is, but it doesn't seem a
bad feature.  It's simple to implement and it provides some (very
small) value.

In general I'm OK with the idea, but would need some OKs from other
developers too.

There is one part of the RFC7505 that I'd like to quote and discuss
with you however.  The last paragraph of the section 3 says:

: A domain that advertises a null MX MUST NOT advertise any other MX
: RR.

Your implementation handles the case where there are more than one MX
by setting the `nullmx' field in the shared struct when we encounter
one, and then don't process the other MXs when that field is set.
This is fine.

However, I think we can simplify here by not honouring the Null MX
when there are other MX records.  We're not violating the RFC.  See
diff below to see what I mean.  The only difference is in dns.c, the
rest is the same with yours.

So far I've only compile-tested the code.  I don't have a spare domain
to test and don't know of anyone using a Null MX.

> Because some domains set the MX record to "localhost." to get a similar
> efect the secound patch ignores "localhost." MX entries and handles a MX
> containing only "localhost." records like a Null MX.

This could be simplified too.  On top of diff below, it would need
just something among the lines of:

        -       if (rr.rr.mx.preference == 0 && !strcmp(buf, "")) {
        +       if ((rr.rr.mx.preference == 0 && !strcmp(buf, "")) ||
        +           !strcasecmp(buf, "localhost")) {
                        if (found)
                                continue;
                        m_create(s->p, IMSG_MTA_DNS_HOST_END, 0, 0, -1);

I'm still not convinced about this part however.  It feels wrong to me
to hardcode such a check, it seems too much paranoic.  The follow-up
would be to check for localhost in dns_dispatch_host too?  ;)


Thanks,

Omar Polo


diff 2d025d839f99dc09ee525c11a4ed09a0f3bbe7d0 
8d6138e5b1e0bc112ff2584d8528e6bc95a39b6f
commit - 2d025d839f99dc09ee525c11a4ed09a0f3bbe7d0
commit + 8d6138e5b1e0bc112ff2584d8528e6bc95a39b6f
blob - 4cf5d23d1d14b5400c6f4429dae0a4f6490073d4
blob + effc07d142895fb2b622242efcd5c69da7f3b67c
--- usr.sbin/smtpd/dns.c
+++ usr.sbin/smtpd/dns.c
@@ -259,8 +259,22 @@ dns_dispatch_mx(struct asr_result *ar, void *arg)
                unpack_rr(&pack, &rr);
                if (rr.rr_type != T_MX)
                        continue;
+
                print_dname(rr.rr.mx.exchange, buf, sizeof(buf));
                buf[strlen(buf) - 1] = '\0';
+
+               if (rr.rr.mx.preference == 0 && !strcmp(buf, "")) {
+                       if (found)
+                               continue;
+                       m_create(s->p, IMSG_MTA_DNS_HOST_END, 0, 0, -1);
+                       m_add_id(s->p, s->reqid);
+                       m_add_int(s->p, DNS_NULLMX);
+                       m_close(s->p);
+                       free(s);
+                       found++;
+                       break;
+               }
+
                dns_lookup_host(s, buf, rr.rr.mx.preference);
                found++;
        }
blob - c0d0fc02931b90409441035d2744923af9e42df1
blob + 25e158b68a88c8485428a2476c1c557f8c60404d
--- usr.sbin/smtpd/mta.c
+++ usr.sbin/smtpd/mta.c
@@ -1088,6 +1088,10 @@ mta_on_mx(void *tag, void *arg, void *data)
                else
                        relay->failstr = "No MX found for domain";
                break;
+       case DNS_NULLMX:
+               relay->fail = IMSG_MTA_DELIVERY_PERMFAIL;
+               relay->failstr = "Domain does not accept mail";
+               break;
        default:
                fatalx("bad DNS lookup error code");
                break;
blob - 6781286928da45e6159bce81ff2437011ebdef72
blob + 9f4732d1c27f6ef9f62951f0207f209a83038dcf
--- usr.sbin/smtpd/smtpd.h
+++ usr.sbin/smtpd/smtpd.h
@@ -1026,6 +1026,8 @@ enum dns_error {
        DNS_EINVAL,
        DNS_ENONAME,
        DNS_ENOTFOUND,
+       /* rfc 7505 */
+       DNS_NULLMX,
 };
 
 enum lka_resp_status {

Reply via email to