ph10 2005/09/13 16:40:07 BST
Modified files:
exim-doc/doc-txt ChangeLog
exim-src/src dns.c
exim-test-orig/AutoTest/stderr 186 320 363 392 427
Log:
Added a backwards-compatible interface to a fake DNS resolver for use by
the new test suite.
Revision Changes Path
1.229 +5 -0 exim/exim-doc/doc-txt/ChangeLog
1.10 +126 -33 exim/exim-src/src/dns.c
1.3 +26 -11 exim/exim-test-orig/AutoTest/stderr/186
1.5 +1 -0 exim/exim-test-orig/AutoTest/stderr/320
1.2 +1 -0 exim/exim-test-orig/AutoTest/stderr/363
1.2 +2 -0 exim/exim-test-orig/AutoTest/stderr/392
1.5 +2 -1 exim/exim-test-orig/AutoTest/stderr/427
Index: ChangeLog
===================================================================
RCS file: /home/cvs/exim/exim-doc/doc-txt/ChangeLog,v
retrieving revision 1.228
retrieving revision 1.229
diff -u -r1.228 -r1.229
--- ChangeLog 13 Sep 2005 11:27:45 -0000 1.228
+++ ChangeLog 13 Sep 2005 15:40:07 -0000 1.229
@@ -1,4 +1,4 @@
-$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.228 2005/09/13 11:27:45 ph10 Exp $
+$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.229 2005/09/13 15:40:07 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
@@ -182,6 +182,11 @@
PH/45 Added $smtp_command for the full command (cf $smtp_command_argument).
PH/46 Added extra information about PostgreSQL errors to the error string.
+
+PH/47 Added an interface to a fake DNS resolver for use by the new test suite,
+ avoiding the need to install special zones in a real server. This is
+ backwards compatible; if it can't find the fake resolver, it drops back.
+ Thus, both old and new test suites can be run.
Exim version 4.52
Index: dns.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/dns.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- dns.c 29 Jun 2005 10:56:35 -0000 1.9
+++ dns.c 13 Sep 2005 15:40:07 -0000 1.10
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/dns.c,v 1.9 2005/06/29 10:56:35 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/dns.c,v 1.10 2005/09/13 15:40:07 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -23,6 +23,120 @@
#endif
+/*************************************************
+* Fake DNS resolver *
+*************************************************/
+
+/* This function is called instead of res_search() when Exim is running in its
+test harness. It recognizes some special domain names, and uses them to force
+failure and retry responses (optionally with a delay). It also recognises the
+zones test.ex and 10.in-addr.arpa, and for those it calls an external utility
+that mock-up a nameserver, if it can find the utility. Otherwise, it passes its
+arguments on to res_search().
+
+Background: the original test suite required a real nameserver to carry the
+test.ex and 10.in-addr.arpa zones, whereas the new test suit has the fake
+server for portability. This code supports both.
+
+Arguments:
+ name the domain name
+ type the DNS record type
+ answerptr where to put the answer
+ size size of the answer area
+
+Returns: length of returned data, or -1 on error (h_errno set)
+*/
+
+static int
+fakens_search(uschar *name, int type, uschar *answerptr, int size)
+{
+int len = Ustrlen(name);
+uschar *endname = name + len;
+
+if (len >= 14 && Ustrcmp(endname - 14, "test.again.dns") == 0)
+ {
+ int delay = Uatoi(name); /* digits at the start of the name */
+ DEBUG(D_dns) debug_printf("Return from DNS lookup of %s (%s) faked for testing\n",
+ name, dns_text_type(type));
+ if (delay > 0)
+ {
+ DEBUG(D_dns) debug_printf("delaying %d seconds\n", delay);
+ sleep(delay);
+ }
+ h_errno = TRY_AGAIN;
+ return -1;
+ }
+
+if (len >= 13 && Ustrcmp(endname - 13, "test.fail.dns") == 0)
+ {
+ DEBUG(D_dns) debug_printf("Return from DNS lookup of %s (%s) faked for testing\n",
+ name, dns_text_type(type));
+ h_errno = NO_RECOVERY;
+ return -1;
+ }
+
+if (Ustrcmp(name, "test.ex") == 0 ||
+ (len > 8 && Ustrcmp(endname - 8, ".test.ex") == 0) ||
+ (len >= 16 && Ustrcmp(endname - 16, ".10.in-addr.arpa") == 0))
+ {
+ uschar utilname[256];
+ struct stat statbuf;
+
+ (void)string_format(utilname, sizeof(utilname), "%s/../bin/fakens",
+ spool_directory);
+
+ if (stat(CS utilname, &statbuf) >= 0)
+ {
+ pid_t pid;
+ int infd, outfd, rc;
+ uschar *argv[5];
+
+ DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) using fakens\n",
+ name, dns_text_type(type));
+
+ argv[0] = utilname;
+ argv[1] = spool_directory;
+ argv[2] = name;
+ argv[3] = dns_text_type(type);
+ argv[4] = NULL;
+
+ pid = child_open(argv, NULL, 0000, &infd, &outfd, FALSE);
+ if (pid < 0)
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to run fakens: %s",
+ strerror(errno));
+
+ len = 0;
+ rc = -1;
+ while (size > 0 && (rc = read(outfd, answerptr, size)) > 0)
+ {
+ len += rc;
+ answerptr += rc;
+ size -= rc;
+ }
+
+ if (rc < 0)
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "read from fakens failed: %s",
+ strerror(errno));
+
+ switch(child_close(pid, 0))
+ {
+ case 0: return len;
+ case 1: h_errno = HOST_NOT_FOUND; break;
+ case 2: h_errno = TRY_AGAIN; break;
+ default:
+ case 3: h_errno = NO_RECOVERY; break;
+ case 4: h_errno = NO_DATA; break;
+ }
+ return -1;
+ }
+ }
+
+/* Not test.ex or 10.in-addr.arpa, or fakens utility not found. */
+
+return res_search(CS name, C_IN, type, answerptr, size);
+}
+
+
/*************************************************
* Initialize and configure resolver *
@@ -334,8 +448,8 @@
int
dns_basic_lookup(dns_answer *dnsa, uschar *name, int type)
{
+int rc = -1;
#ifndef STAND_ALONE
-int rc;
uschar *save;
#endif
@@ -361,35 +475,6 @@
return previous->data.val;
}
-/* If we are running in the test harness, recognize a couple of special
-names that always give error returns. This makes it straightforward to
-test the handling of DNS errors. */
-
-if (running_in_test_harness)
- {
- uschar *endname = name + Ustrlen(name);
- if (Ustrcmp(endname - 14, "test.again.dns") == 0)
- {
- int delay = Uatoi(name); /* digits at the start of the name */
- DEBUG(D_dns) debug_printf("Real DNS lookup of %s (%s) bypassed for testing\n",
- name, dns_text_type(type));
- if (delay > 0)
- {
- DEBUG(D_dns) debug_printf("delaying %d seconds\n", delay);
- sleep(delay);
- }
- DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n");
- return dns_return(name, type, DNS_AGAIN);
- }
- if (Ustrcmp(endname - 13, "test.fail.dns") == 0)
- {
- DEBUG(D_dns) debug_printf("Real DNS lookup of %s (%s) bypassed for testing\n",
- name, dns_text_type(type));
- DEBUG(D_dns) debug_printf("returning DNS_FAIL\n");
- return dns_return(name, type, DNS_FAIL);
- }
- }
-
/* If configured, check the hygene of the name passed to lookup. Otherwise,
although DNS lookups may give REFUSED at the lower level, some resolvers
turn this into TRY_AGAIN, which is silly. Give a NOMATCH return, since such
@@ -438,10 +523,18 @@
#endif /* STAND_ALONE */
/* Call the resolver; for an overlong response, res_search() will return the
-number of bytes the message would need, so we need to check for this case.
-The effect is to truncate overlong data. */
+number of bytes the message would need, so we need to check for this case. The
+effect is to truncate overlong data.
+
+If we are running in the test harness, instead of calling the normal resolver
+(res_search), we call fakens_search(), which recognizes certain special
+domains, and interfaces to a fake nameserver for certain special zones. */
+
+if (running_in_test_harness)
+ dnsa->answerlen = fakens_search(name, type, dnsa->answer, MAXPACKET);
+else
+ dnsa->answerlen = res_search(CS name, C_IN, type, dnsa->answer, MAXPACKET);
-dnsa->answerlen = res_search(CS name, C_IN, type, dnsa->answer, MAXPACKET);
if (dnsa->answerlen > MAXPACKET) dnsa->answerlen = MAXPACKET;
if (dnsa->answerlen < 0) switch (h_errno)
Index: 186
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/stderr/186,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- 186 1 Aug 2005 13:20:29 -0000 1.2
+++ 186 13 Sep 2005 15:40:07 -0000 1.3
@@ -31,7 +31,9 @@
calling lookuphost router
lookuphost router called for ph10@???
domain = test.again.dns
-Real DNS lookup of test.again.dns (MX) bypassed for testing
+Return from DNS lookup of test.again.dns (MX) faked for testing
+DNS lookup of test.again.dns (MX) gave TRY_AGAIN
+test.again.dns in dns_again_means_nonexist? no (option unset)
returning DNS_AGAIN
lookuphost router: defer for ph10@???
message: host lookup did not complete
@@ -121,9 +123,13 @@
set transport smtp
finding IP address for test.again.dns
doing DNS lookup
-Real DNS lookup of test.again.dns (AAAA) bypassed for testing
+Return from DNS lookup of test.again.dns (AAAA) faked for testing
+DNS lookup of test.again.dns (AAAA) gave TRY_AGAIN
+test.again.dns in dns_again_means_nonexist? no (option unset)
returning DNS_AGAIN
-Real DNS lookup of test.again.dns (A) bypassed for testing
+Return from DNS lookup of test.again.dns (A) faked for testing
+DNS lookup of test.again.dns (A) gave TRY_AGAIN
+test.again.dns in dns_again_means_nonexist? no (option unset)
returning DNS_AGAIN
mug99 router: defer for mug99@???
message: host lookup for test.again.dns did not complete (DNS timeout?)
@@ -224,7 +230,8 @@
calling lookuphost router
lookuphost router called for ph10@???
domain = test.fail.dns
-Real DNS lookup of test.fail.dns (MX) bypassed for testing
+Return from DNS lookup of test.fail.dns (MX) faked for testing
+DNS lookup of test.fail.dns (MX) gave NO_RECOVERY
returning DNS_FAIL
lookuphost router: defer for ph10@???
message: host lookup did not complete
@@ -314,9 +321,11 @@
set transport smtp
finding IP address for test.fail.dns
doing DNS lookup
-Real DNS lookup of test.fail.dns (AAAA) bypassed for testing
+Return from DNS lookup of test.fail.dns (AAAA) faked for testing
+DNS lookup of test.fail.dns (AAAA) gave NO_RECOVERY
returning DNS_FAIL
-Real DNS lookup of test.fail.dns (A) bypassed for testing
+Return from DNS lookup of test.fail.dns (A) faked for testing
+DNS lookup of test.fail.dns (A) gave NO_RECOVERY
returning DNS_FAIL
mug99 router: defer for mug99@???
message: host lookup for test.fail.dns did not complete (DNS timeout?)
@@ -604,7 +613,9 @@
calling srv router
srv router called for srv@???
domain = test.again.dns
-Real DNS lookup of _smtp._tcp.test.again.dns (SRV) bypassed for testing
+Return from DNS lookup of _smtp._tcp.test.again.dns (SRV) faked for testing
+DNS lookup of _smtp._tcp.test.again.dns (SRV) gave TRY_AGAIN
+_smtp._tcp.test.again.dns in dns_again_means_nonexist? no (option unset)
returning DNS_AGAIN
test.again.dns in "test.fail.dns"? no (end of list)
srv router: defer for srv@???
@@ -622,17 +633,21 @@
calling srv router
srv router called for srv@???
domain = test.fail.dns
-Real DNS lookup of _smtp._tcp.test.fail.dns (SRV) bypassed for testing
+Return from DNS lookup of _smtp._tcp.test.fail.dns (SRV) faked for testing
+DNS lookup of _smtp._tcp.test.fail.dns (SRV) gave NO_RECOVERY
returning DNS_FAIL
test.fail.dns in "test.fail.dns"? yes (matched "test.fail.dns")
DNS_FAIL treated as DNS_NODATA (domain in srv_fail_domains)
-Real DNS lookup of test.fail.dns (MX) bypassed for testing
+Return from DNS lookup of test.fail.dns (MX) faked for testing
+DNS lookup of test.fail.dns (MX) gave NO_RECOVERY
returning DNS_FAIL
test.fail.dns in "test.fail.dns"? yes (matched "test.fail.dns")
DNS_FAIL treated as DNS_NODATA (domain in mx_fail_domains)
-Real DNS lookup of test.fail.dns (AAAA) bypassed for testing
+Return from DNS lookup of test.fail.dns (AAAA) faked for testing
+DNS lookup of test.fail.dns (AAAA) gave NO_RECOVERY
returning DNS_FAIL
-Real DNS lookup of test.fail.dns (A) bypassed for testing
+Return from DNS lookup of test.fail.dns (A) faked for testing
+DNS lookup of test.fail.dns (A) gave NO_RECOVERY
returning DNS_FAIL
srv router: defer for srv@???
message: host lookup did not complete
Index: 320
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/stderr/320,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- 320 12 Sep 2005 11:16:56 -0000 1.4
+++ 320 13 Sep 2005 15:40:07 -0000 1.5
@@ -1261,6 +1261,7 @@
>>> check dnslists = test.again.dns
>>> DNS list check: test.again.dns
>>> new DNS lookup for 1.44.44.44.test.again.dns
+>>> 1.44.44.44.test.again.dns in dns_again_means_nonexist? no (option unset)
LOG: DNS list lookup defer (probably timeout) for 1.44.44.44.test.again.dns: assumed not in list
>>> warn: condition test failed
>>> processing "warn"
Index: 363
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/stderr/363,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- 363 8 Oct 2004 14:50:08 -0000 1.1
+++ 363 13 Sep 2005 15:40:07 -0000 1.2
@@ -12,6 +12,7 @@
>>> DNS list check: +defer_unknown
>>> DNS list check: test.again.dns
>>> new DNS lookup for 1.0.0.10.test.again.dns
+>>> 1.0.0.10.test.again.dns in dns_again_means_nonexist? no (option unset)
LOG: DNS list lookup defer (probably timeout) for 1.0.0.10.test.again.dns: returned DEFER
>>> deny: condition test deferred
LOG: H=[10.0.0.1] F=<ph10@x> temporarily rejected RCPT <ph10@y>
Index: 392
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/stderr/392,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- 392 8 Oct 2004 14:50:08 -0000 1.1
+++ 392 13 Sep 2005 15:40:07 -0000 1.2
@@ -15,6 +15,7 @@
>>> calling skipped router
>>> skipped router declined for ph10@???
>>> calling temp router
+>>> test.again.dns in dns_again_means_nonexist? no (option unset)
>>> temp router: defer for ph10@???
>>> message: host lookup did not complete
>>> ----------- end verify ------------
@@ -35,6 +36,7 @@
>>> routing r1-ph10@???
>>> test.again.dns in "!testdb;fail"? yes (end of list)
>>> calling r1 router
+>>> test.again.dns in dns_again_means_nonexist? no (option unset)
>>> r1 router: defer for r1-ph10@???
>>> message: host lookup did not complete
>>> ----------- end verify ------------
Index: 427
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/stderr/427,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- 427 1 Aug 2005 13:20:29 -0000 1.4
+++ 427 13 Sep 2005 15:40:07 -0000 1.5
@@ -71,8 +71,9 @@
calling r2 router
r2 router called for delay@???
domain = 2.test.again.dns
-Real DNS lookup of 2.test.again.dns (MX) bypassed for testing
+Return from DNS lookup of 2.test.again.dns (MX) faked for testing
delaying 2 seconds
+DNS lookup of 2.test.again.dns (MX) gave TRY_AGAIN
returning DNS_AGAIN
r2 router: defer for delay@???
message: host lookup did not complete