summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-txt/ChangeLog7
-rw-r--r--doc/doc-txt/NewStuff9
-rw-r--r--doc/doc-txt/OptionLists.txt3
-rw-r--r--src/src/macros.h5
-rw-r--r--src/src/routers/manualroute.c79
-rw-r--r--src/src/routers/manualroute.h4
-rw-r--r--src/src/routers/rf_lookup_hostlist.c9
-rw-r--r--test/confs/055749
-rw-r--r--test/scripts/0000-Basic/055728
-rw-r--r--test/stderr/05572
-rw-r--r--test/stdout/05368
-rw-r--r--test/stdout/055716
12 files changed, 195 insertions, 24 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 7f6590ec6..9695d2d61 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.492 2007/03/13 11:26:49 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.493 2007/03/13 15:32:47 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
@@ -163,6 +163,11 @@ PH/37 If a message is not accepted after it has had an id assigned (e.g.
lack of a "<=" line in the log, and they are now listed as "not
accepted".
+PH/38 The host_find_failed option in the manualroute router can now be set
+ to "ignore", to completely ignore a host whose IP address cannot be
+ found. If all hosts are ignored, the behaviour is controlled by the new
+ host_all_ignored option.
+
Exim version 4.66
-----------------
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 37368ac4d..bd43aecf8 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.144 2007/03/13 11:06:48 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.145 2007/03/13 15:32:47 ph10 Exp $
New Features in Exim
--------------------
@@ -394,6 +394,13 @@ Version 4.67
19. The exigrep utility now has a -v option, which inverts the matching
condition.
+20. The host_find_failed option in the manualroute router can now be set to
+ "ignore". This causes it to completely ignore a host whose IP address
+ cannot be found. If all the hosts in the list are ignored, the behaviour is
+ controlled by the new host_all_ignored option, which takes the same values
+ as host_find_failed, except that it cannot be set to "ignore". Its default
+ is "defer".
+
Version 4.66
------------
diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt
index 4d7e3bdad..fe080c567 100644
--- a/doc/doc-txt/OptionLists.txt
+++ b/doc/doc-txt/OptionLists.txt
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.30 2007/02/06 14:49:13 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.31 2007/03/13 15:32:47 ph10 Exp $
LISTS OF EXIM OPTIONS
---------------------
@@ -258,6 +258,7 @@ helo_verify_hosts host list unset main
hide_child_in_errmsg false redirect 4.00
hold_domains domain list unset main 1.70
home_directory string* unset transports 4.00 replaces individual options
+host_all_ignored string "defer" manualroute 4.67
host_find_failed string "freeze" manualroute 4.00
host_lookup host list unset main 3.00
host_lookup_order string list "bydns:byaddr" main 4.30
diff --git a/src/src/macros.h b/src/src/macros.h
index 00e040b5f..f6aca465c 100644
--- a/src/src/macros.h
+++ b/src/src/macros.h
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/macros.h,v 1.32 2007/02/06 11:11:40 ph10 Exp $ */
+/* $Cambridge: exim/src/src/macros.h,v 1.33 2007/03/13 15:32:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -754,13 +754,14 @@ enum {
#define topt_no_body 0x040 /* Omit body */
#define topt_escape_headers 0x080 /* Apply escape check to headers */
-/* Codes for the host_find_failed option. */
+/* Codes for the host_find_failed and host_all_ignored options. */
#define hff_freeze 0
#define hff_defer 1
#define hff_pass 2
#define hff_decline 3
#define hff_fail 4
+#define hff_ignore 5
/* Router information flags */
diff --git a/src/src/routers/manualroute.c b/src/src/routers/manualroute.c
index a6bbcd499..ab304a95f 100644
--- a/src/src/routers/manualroute.c
+++ b/src/src/routers/manualroute.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/manualroute.c,v 1.5 2007/01/08 10:50:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/manualroute.c,v 1.6 2007/03/13 15:32:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -16,6 +16,8 @@
/* Options specific to the manualroute router. */
optionlist manualroute_router_options[] = {
+ { "host_all_ignored", opt_stringptr,
+ (void *)(offsetof(manualroute_router_options_block, host_all_ignored)) },
{ "host_find_failed", opt_stringptr,
(void *)(offsetof(manualroute_router_options_block, host_find_failed)) },
{ "hosts_randomize", opt_bool,
@@ -37,14 +39,30 @@ int manualroute_router_options_count =
/* Default private options block for the manualroute router. */
manualroute_router_options_block manualroute_router_option_defaults = {
- hff_freeze, /* host_find_failed code */
+ -1, /* host_all_ignored code (unset) */
+ -1, /* host_find_failed code (unset) */
FALSE, /* hosts_randomize */
+ US"defer", /* host_all_ignored */
US"freeze", /* host_find_failed */
NULL, /* route_data */
NULL /* route_list */
};
+/* Names and values for host_find_failed and host_all_ignored. */
+
+static uschar *hff_names[] = {
+ US"ignore", /* MUST be first - not valid for host_all_ignored */
+ US"decline",
+ US"defer",
+ US"fail",
+ US"freeze",
+ US"pass" };
+
+static int hff_codes[] = { hff_ignore, hff_decline, hff_defer, hff_fail,
+ hff_freeze, hff_pass };
+
+static int hff_count= sizeof(hff_codes)/sizeof(int);
@@ -60,23 +78,34 @@ manualroute_router_init(router_instance *rblock)
{
manualroute_router_options_block *ob =
(manualroute_router_options_block *)(rblock->options_block);
+int i;
/* Host_find_failed must be a recognized word */
-if (Ustrcmp(ob->host_find_failed, "freeze") == 0)
- ob->hff_code = hff_freeze;
-else if (Ustrcmp(ob->host_find_failed, "decline") == 0)
- ob->hff_code = hff_decline;
-else if (Ustrcmp(ob->host_find_failed, "defer") == 0)
- ob->hff_code = hff_defer;
-else if (Ustrcmp(ob->host_find_failed, "pass") == 0)
- ob->hff_code = hff_pass;
-else if (Ustrcmp(ob->host_find_failed, "fail") == 0)
- ob->hff_code = hff_fail;
-else
+for (i = 0; i < hff_count; i++)
+ {
+ if (Ustrcmp(ob->host_find_failed, hff_names[i]) == 0)
+ {
+ ob->hff_code = hff_codes[i];
+ break;
+ }
+ }
+if (ob->hff_code < 0)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n "
"unrecognized setting for host_find_failed option", rblock->name);
+for (i = 1; i < hff_count; i++) /* NB starts at 1 to skip "ignore" */
+ {
+ if (Ustrcmp(ob->host_all_ignored, hff_names[i]) == 0)
+ {
+ ob->hai_code = hff_codes[i];
+ break;
+ }
+ }
+if (ob->hai_code < 0)
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n "
+ "unrecognized setting for host_all_ignored option", rblock->name);
+
/* One of route_list or route_data must be specified */
if ((ob->route_list == NULL && ob->route_data == NULL) ||
@@ -401,6 +430,30 @@ rc = rf_lookup_hostlist(rblock, addr, rblock->ignore_target_hosts, lookup_type,
ob->hff_code, addr_new);
if (rc != OK) return rc;
+/* If host_find_failed is set to "ignore", it is possible for all the hosts to
+be ignored, in which case we will end up with an empty host list. What happens
+is controlled by host_all_ignored. */
+
+if (addr->host_list == NULL)
+ {
+ int i;
+ DEBUG(D_route) debug_printf("host_find_failed ignored every host\n");
+ if (ob->hai_code == hff_decline) return DECLINE;
+ if (ob->hai_code == hff_pass) return PASS;
+
+ for (i = 0; i < hff_count; i++)
+ if (ob->hai_code == hff_codes[i]) break;
+
+ addr->message = string_sprintf("lookup failed for all hosts in %s router: "
+ "host_find_failed=ignore host_all_ignored=%s", rblock->name, hff_names[i]);
+
+ if (ob->hai_code == hff_defer) return DEFER;
+ if (ob->hai_code == hff_fail) return FAIL;
+
+ addr->special_action = SPECIAL_FREEZE;
+ return DEFER;
+ }
+
/* Finally, since we have done all the routing here, there must be a transport
defined for these hosts. It will be a remote one, as a local transport is
dealt with above. However, we don't need one if verifying only. */
diff --git a/src/src/routers/manualroute.h b/src/src/routers/manualroute.h
index 6249d3f6c..38413999b 100644
--- a/src/src/routers/manualroute.h
+++ b/src/src/routers/manualroute.h
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/manualroute.h,v 1.5 2007/01/08 10:50:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/manualroute.h,v 1.6 2007/03/13 15:32:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -12,8 +12,10 @@
/* Structure for the private options. */
typedef struct {
+ int hai_code;
int hff_code;
BOOL hosts_randomize;
+ uschar *host_all_ignored;
uschar *host_find_failed;
uschar *route_data;
uschar *route_list;
diff --git a/src/src/routers/rf_lookup_hostlist.c b/src/src/routers/rf_lookup_hostlist.c
index 74b59173c..a5beb49f4 100644
--- a/src/src/routers/rf_lookup_hostlist.c
+++ b/src/src/routers/rf_lookup_hostlist.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/rf_lookup_hostlist.c,v 1.8 2007/01/08 10:50:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/rf_lookup_hostlist.c,v 1.9 2007/03/13 15:32:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -157,6 +157,13 @@ for (h = addr->host_list; h != NULL; prev = h, h = next_h)
if (rc == HOST_FIND_FAILED)
{
+ if (hff_code == hff_ignore)
+ {
+ if (prev == NULL) addr->host_list = next_h; else prev->next = next_h;
+ h = prev; /* Because the loop sets prev to h */
+ continue; /* With the next host */
+ }
+
if (hff_code == hff_pass) return PASS;
if (hff_code == hff_decline) return DECLINE;
diff --git a/test/confs/0557 b/test/confs/0557
new file mode 100644
index 000000000..3b134db34
--- /dev/null
+++ b/test/confs/0557
@@ -0,0 +1,49 @@
+# Exim test configuration 0557
+
+X=
+Y=
+HOSTS=
+HAI=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+rfc1413_query_timeout = 0s
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+
+# ----- Routers -----
+
+begin routers
+
+r1:
+ driver = manualroute
+ route_list = * HOSTS
+X host_find_failed = ignore
+Y host_all_ignored = HAI
+ no_more
+ self = send
+ transport = t1
+
+r2:
+ driver = accept
+ transport = t2
+
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+ driver = smtp
+
+t2:
+ driver = appendfile
+ file = /dev/null
+
+# End
diff --git a/test/scripts/0000-Basic/0557 b/test/scripts/0000-Basic/0557
new file mode 100644
index 000000000..8e05b4719
--- /dev/null
+++ b/test/scripts/0000-Basic/0557
@@ -0,0 +1,28 @@
+# host_find_failed=ignore
+1
+exim -DX=# -DY=# -bt userx@test.ex
+****
+1
+exim -DY=# -DHOSTS=a.non.exist -bt userx@test.ex
+****
+1
+exim -DY=# -DHOSTS=a.non.exist:b.non.exist -bt userx@test.ex
+****
+exim -DY=# -DHOSTS=a.non.exist:127.0.0.1 -bt userx@test.ex
+****
+exim -DY=# -DHOSTS=127.0.0.1:b.non.exist:127.0.0.2 -bt userx@test.ex
+****
+1
+exim -DHOSTS=a.non.exist -DHAI=defer -bt userx@test.ex
+****
+2
+exim -DHOSTS=a.non.exist -DHAI=decline -bt userx@test.ex
+****
+2
+exim -DHOSTS=a.non.exist -DHAI=fail -bt userx@test.ex
+****
+exim -DHOSTS=a.non.exist -DHAI=pass -bt userx@test.ex
+****
+1
+exim -DHOSTS=a.non.exist -DHAI=freeze -bt userx@test.ex
+****
diff --git a/test/stderr/0557 b/test/stderr/0557
new file mode 100644
index 000000000..8e5906ca8
--- /dev/null
+++ b/test/stderr/0557
@@ -0,0 +1,2 @@
+LOG: MAIN
+ error in r1 router: no host(s) specified for domain *
diff --git a/test/stdout/0536 b/test/stdout/0536
index cc4ce1e60..1ec52de1e 100644
--- a/test/stdout/0536
+++ b/test/stdout/0536
@@ -22,10 +22,10 @@
590 Main code
590 5.4.3 Main and extended code
550 Wrong code
-451 Temporary local problem - please try later
-490 Temporary local problem - please try later
-490 4.4.3 Temporary local problem - please try later
-451 Temporary local problem - please try later
+451 No code
+490 Main code
+490 4.4.3 Main and extended code
+451 Wrong code
221 myhost.test.ex closing connection
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
250-myhost.test.ex Hello CALLER at test.ex
diff --git a/test/stdout/0557 b/test/stdout/0557
new file mode 100644
index 000000000..5077c0d0a
--- /dev/null
+++ b/test/stdout/0557
@@ -0,0 +1,16 @@
+userx@test.ex cannot be resolved at this time: error in r1 router: no host(s) specified for domain *
+userx@test.ex cannot be resolved at this time: lookup failed for all hosts in r1 router: host_find_failed=ignore host_all_ignored=defer
+userx@test.ex cannot be resolved at this time: lookup failed for all hosts in r1 router: host_find_failed=ignore host_all_ignored=defer
+userx@test.ex
+ router = r1, transport = t1
+ host 127.0.0.1 [127.0.0.1]
+userx@test.ex
+ router = r1, transport = t1
+ host 127.0.0.1 [127.0.0.1]
+ host 127.0.0.2 [127.0.0.2]
+userx@test.ex cannot be resolved at this time: lookup failed for all hosts in r1 router: host_find_failed=ignore host_all_ignored=defer
+userx@test.ex is undeliverable: Unrouteable address
+userx@test.ex is undeliverable: lookup failed for all hosts in r1 router: host_find_failed=ignore host_all_ignored=fail
+userx@test.ex
+ router = r2, transport = t2
+userx@test.ex cannot be resolved at this time: lookup failed for all hosts in r1 router: host_find_failed=ignore host_all_ignored=freeze