Mailing List Archive

DNS Loop In Callout
I have run across a very strange DNS loop in a recipient callout
verification. I've looked through archives and done as much debugging as
I could without much luck. Basically, what is happening is, I have a
series of transports that are used to send messages to specific hosts on
specific ports. An example of one of these would be:

port_redir_smtp2525:
driver = smtp
hosts = $acl_m6
port = 2525
headers_remove = X-Scanner
interface = 63.208.196.165
connect_timeout = 2m
command_timeout = 2m
data_timeout = 2m
final_timeout = 5m

Where $acl_m6 contains a hostname. In my test case, that hostname is
"test.krellis.org". I have callout verification turned on in my recipient
ACL thusly:

require message = User unknown
verify = recipient/callout=5s,defer_ok/no_details

When test.krellis.org resolves to a single IP address, this works fine.
However, when test.krellis.org resolves to multiple IP addresses, I
encounter a never-ending DNS query loop. A -d+all session shows:

16:55:34 54758 ---0 Get 0x81ce888 32 dns.c 810
16:55:34 54758 ---0 Get 0x81ce8a8 32 dns.c 810
16:55:34 54758 ---0 Get 0x81ce8c8 40 host.c 2046
16:55:34 54758 fully qualified name = test.krellis.org
16:55:34 54758 test.krellis.org 1.2.3.9 mx=-1 sort=-62
16:55:34 54758 test.krellis.org 1.2.3.4 mx=-1 sort=-40
16:55:34 54758 DNS lookup of test.krellis.org (A) succeeded
16:55:34 54758 ---0 Get 0x81ce8f0 32 dns.c 810
16:55:34 54758 ---0 Get 0x81ce910 32 dns.c 810
16:55:34 54758 ---0 Get 0x81ce930 40 host.c 2046
16:55:34 54758 fully qualified name = test.krellis.org
16:55:34 54758 test.krellis.org 1.2.3.9 mx=-1 sort=-472
16:55:34 54758 test.krellis.org 1.2.3.4 mx=-1 sort=-302
16:55:34 54758 DNS lookup of test.krellis.org (A) succeeded
16:55:34 54758 ---0 Get 0x81ce958 32 dns.c 810
16:55:34 54758 ---0 Get 0x81ce978 32 dns.c 810
16:55:34 54758 ---0 Get 0x81ce998 40 host.c 2046
16:55:34 54758 fully qualified name = test.krellis.org
16:55:34 54758 test.krellis.org 1.2.3.4 mx=-1 sort=-67
16:55:34 54758 test.krellis.org 1.2.3.9 mx=-1 sort=-44
16:55:34 54758 DNS lookup of test.krellis.org (A) succeeded

Over and over again. I have a full session available with
test.krellis.org resolving to both a single A record and multiple A
records. I can send that as necessary for debugging.

Actual deliveries with the round-robin in place succeed past the DNS
lookup with no problem, so something seems to be going wonky in the
callout code when there are multiple IP addresses returned by DNS.

I can provide more information, full configurations, and session
transcripts to anyone who needs them to help debug this. I didn't have
much luck stepping through blindly with a debugger trying to find
something obvious wrong, but I'm not at all familiar with the Exim sources
at this point, so my chances weren't so hot.

Any help anyone can provide with this would be greatly appreciated. I
apologize if this would have been better suited to -users, I wasn't
entirely clear from the site & docs what would be best for trying to hunt
down a bug of this nature.

Tim Wilde

--
Tim Wilde
twilde@dyndns.org
Systems Administrator
Dynamic Network Services, Inc.
http://www.dyndns.org/
Re: DNS Loop In Callout [ In reply to ]
On Thu, 2 Dec 2004, Tim Wilde wrote:

> I have run across a very strange DNS loop in a recipient callout verification.

This is fixed by the following change in version 4.44

30. Exim went into a mad DNS loop when attempting to do a callout where the
host was specified on an smtp transport, and looking it up yielded more
than one IP address.

Tony.
--
f.a.n.finch <dot@dotat.at> http://dotat.at/
MALIN HEBRIDES: NORTHEAST 4 OR 5 INCREASING 6. RAIN LATER. GOOD BECOMING
MODERATE.
Re: DNS Loop In Callout [ In reply to ]
On Fri, 3 Dec 2004, Tony Finch wrote:

> On Thu, 2 Dec 2004, Tim Wilde wrote:
>
>> I have run across a very strange DNS loop in a recipient callout
>> verification.
>
> This is fixed by the following change in version 4.44
>
> 30. Exim went into a mad DNS loop when attempting to do a callout where the
> host was specified on an smtp transport, and looking it up yielded more
> than one IP address.

Any chance of a patch against 4.43 that addresses this (or a ballpark idea
when to expect 4.44)? We have an application we really need to have
callouts enabled for in this situation. Thanks for your help.

Tim Wilde

--
Tim Wilde
twilde@dyndns.org
Systems Administrator
Dynamic Network Services, Inc.
http://www.dyndns.org/
Re: DNS Loop In Callout [ In reply to ]
On Fri, 3 Dec 2004, Tim Wilde wrote:

> Any chance of a patch against 4.43 that addresses this (or a ballpark idea
> when to expect 4.44)? We have an application we really need to have callouts
> enabled for in this situation. Thanks for your help.

The fix is in the snapshot in

ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/Testing/exim-snapshot.tar.gz
ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/Testing/exim-snapshot.tar.gz.sig

The patch is below.

Regards,
Philip

--
Philip Hazel University of Cambridge Computing Service,
ph10@cus.cam.ac.uk Cambridge, England. Phone: +44 1223 334714.


*** exim-4.43/src/verify.c Tue Oct 5 09:32:08 2004
--- verify.c Fri Nov 12 16:23:13 2004
***************
*** 1015,1028 ****
else
{
uschar *canonical_name;
! host_item *host;
host_build_hostlist(&host_list, s, tf.hosts_randomize);

/* Just ignore failures to find a host address. If we don't manage
! to find any addresses, the callout will defer. */

! for (host = host_list; host != NULL; host = host->next)
{
if (tf.gethostbyname || string_is_ip_address(host->name, NULL))
(void)host_find_byname(host, NULL, &canonical_name, TRUE);
else
--- 1037,1054 ----
else
{
uschar *canonical_name;
! host_item *host, *nexthost;
host_build_hostlist(&host_list, s, tf.hosts_randomize);

/* Just ignore failures to find a host address. If we don't manage
! to find any addresses, the callout will defer. Note that more than
! one address may be found for a single host, which will result in
! additional host items being inserted into the chain. Hence we must
! save the next host first. */

! for (host = host_list; host != NULL; host = nexthost)
{
+ nexthost = host->next;
if (tf.gethostbyname || string_is_ip_address(host->name, NULL))
(void)host_find_byname(host, NULL, &canonical_name, TRUE);
else