Re: [exim] Usage of dnsdb primary mx

Top Page
Delete this message
Reply to this message
Author: Phil Pennock
Date:  
To: exim-users
New-Topics: Re: [exim] Usage of dnsdb primary mx
Subject: Re: [exim] Usage of dnsdb primary mx
On 2009-05-26 at 15:08 -0700, Phil Pennock wrote:
> On 2009-05-25 at 11:47 +0100, Mike Cardwell wrote:
> > Thomas Klaver wrote:
> >
> > > Is it possible to retrieve the highest prioritized MX record using a
> > > dnsdb lookup? If so, how?
> >
> > The results returned by dnsdb when doing an mx or mxh lookup are not
> > ordered by priority:
> >
> > root@haven:~# exim4 -be '${lookup dnsdb{mx=googlemail.com}}'
> > 30 alt3.gmail-smtp-in.l.google.com
> > 40 alt4.gmail-smtp-in.l.google.com
> > 5 gmail-smtp-in.l.google.com
> > 10 alt1.gmail-smtp-in.l.google.com
> > 20 alt2.gmail-smtp-in.l.google.com
> > root@haven:~#
> >
> > I'm not sure how you could pick out the item with the lowest priority
> > using Exim expansions.
>
> ${reduce{<\n ${lookup dnsdb{mx=googlemail.com}}}{65535 .}{${if <{${extract{1}{ }{$item}}}{${extract{1}{ }{$value}}}{$item}{$value}}}}


Note that this will reject a legitimate singleton MX at priority 65535.
It's better to just use a higher-than-16bit-unsigned start value. Eg,
70000. It will also result in "65535 ." being returned for the NOERROR
empty response case; eg, a lookup where there's an A record but no MX.

So the fix is to use 70000 as the initial seed and then check for
"70000 ." for errors. In an ACL, you might have:

warn set acl_m_lowest_mx = ${reduce{<\n ${lookup dnsdb{mx=$domain}}}{70000 .}{${if <{${extract{1}{ }{$item}}}{${extract{1}{ }{$value}}}{$item}{$value}}}}

  deny condition = ${if eq{$acl_m_lowest_mx}{70000 .}}
       message = "No MX records found for $domain"


Otherwise, because comparators like eq{} don't store the two tested
values in variables for use later in the expansion, you're stuck
re-evaluating -- which should be fast, because the results will be
cached, but not pretty. Even if we regard my first response as pretty,
this one does not qualify.

${if !eq{${reduce{<\n ${lookup dnsdb{mx=$domain}}}{70000 .}{${if <{${extract{1}{ }{$item}}}{${extract{1}{ }{$value}}}{$item}{$value}}}}}{70000 .}{${reduce{<\n ${lookup dnsdb{mx=$domain}}}{70000 .}{${if <{${extract{1}{ }{$item}}}{${extract{1}{ }{$value}}}{$item}{$value}}}}}fail}

However, just because it's not pretty, that doesn't mean it doesn't
work. Exim provides enough flexibility to let you do whatever you want,
rather than constraining you to the solutions which are provided by the
more normal convenience features.

Provided that you built Exim with dnsdb support, of course.

-Phil