From: Jasen Betts Date: Tue, 10 Nov 2015 16:58:33 +0000 (+0000) Subject: Events: add recipient-deferred events, both per-host and all-hosts. X-Git-Tag: exim-4_87_RC1~45 X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=commitdiff_plain;h=5ef5dd52d1ded8b0ffdf4708e1d00e4ef458b86a Events: add recipient-deferred events, both per-host and all-hosts. --- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 742243c2d..142d81e05 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -90,6 +90,12 @@ JH/18 Bug 1709: When built with TLS support, the tls_advertise_hosts option now HS/03 Add -bP config_file as a synonym for -bP configure_file, for consistency with the $config_file variable. +JH/19 Two additional event types: msg:rcpt:defer and msg:rcpt:host:defer. Both + in transport context, after the attempt, and per-recipient. The latter type + is per host attempted. The event data is the error message, and the errno + information encodes the lookup type (A vs. MX) used for the (first) host, + and the trailing two digits of the smtp 4xx reponse. + Exim version 4.86 ----------------- diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt index c93123c39..74614cd3f 100644 --- a/doc/doc-txt/experimental-spec.txt +++ b/doc/doc-txt/experimental-spec.txt @@ -798,6 +798,8 @@ expansion is done. The current list of events is: msg:complete after main per message msg:delivery after transport per recipient + msg:rcpt:host:defer after transport per recipient per host + msg:rcpt:defer after transport per recipient msg:host:defer after transport per attempt msg:fail:delivery after main per recipient msg:fail:internal after main per recipient @@ -811,16 +813,20 @@ variable to decide when to act. The value of the variable is a colon-separated list, defining a position in the tree of possible events; it may be used as a list or just matched on as a whole. There will be no whitespace. +New event types may be added in the future. + There is an auxilary variable, $event_data, for which the content is event_dependent: msg:delivery smtp confirmation mssage + msg:rcpt:host:defer error string + msg:rcpt:defer error string msg:host:defer error string tls:cert verification chain depth smtp:connect smtp banner -The msg:host:defer event populates one extra variable, $event_defer_errno. +The :defer events populate one extra variable, $event_defer_errno. The following variables are likely to be useful depending on the event type: @@ -848,7 +854,14 @@ event_action = ${if eq {msg:delivery}{$event_name} \ The string is expanded when each of the supported events occur and any side-effects of the expansion will happen. -Note that for complex operations an ACL expansion can be used. + +Note that for complex operations an ACL expansion can be used, +however due to the multiple contexts the Exim operates in +a) variables set in events raised from transports will not + be visible outside that transport call. +b) acl_m variables in a server context are lost on a new connection, + and after helo/ehlo/mail/starttls/rset commands + The expansion of the event_action option should normally diff --git a/src/src/acl.c b/src/src/acl.c index 064ee6ccb..911ecfed2 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -3743,7 +3743,12 @@ for (; cb != NULL; cb = cb->next) case ACLC_SET: { int old_pool = store_pool; - if (cb->u.varname[0] == 'c') store_pool = POOL_PERM; + if ( cb->u.varname[0] == 'c' +#ifdef EXPERIMENTAL_EVENT + || event_name /* An event is being delivered */ +#endif + ) + store_pool = POOL_PERM; acl_var_create(cb->u.varname)->data.ptr = string_copy(arg); store_pool = old_pool; } diff --git a/src/src/deliver.c b/src/src/deliver.c index e1f4e0e29..65f148c07 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -785,12 +785,14 @@ if (action) return NULL; } -static void +void msg_event_raise(const uschar * event, const address_item * addr) { const uschar * save_domain = deliver_domain; uschar * save_local = deliver_localpart; const uschar * save_host = deliver_host; +const uschar * save_address = deliver_host_address; +const int save_port = deliver_host_port; if (!addr->transport) return; @@ -802,9 +804,13 @@ deliver_localpart = addr->local_part; deliver_host = addr->host_used ? addr->host_used->name : NULL; (void) event_raise(addr->transport->event_action, event, - addr->host_used || Ustrcmp(addr->transport->driver_name, "lmtp") == 0 - ? addr->message : NULL); + addr->host_used + || Ustrcmp(addr->transport->driver_name, "smtp") == 0 + || Ustrcmp(addr->transport->driver_name, "lmtp") == 0 + ? addr->message : NULL); +deliver_host_port = save_port; +deliver_host_address = save_address; deliver_host = save_host; deliver_localpart = save_local; deliver_domain = save_domain; diff --git a/src/src/functions.h b/src/src/functions.h index 6f6c643b8..e9f7ab658 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -166,6 +166,7 @@ extern void enq_end(uschar *); extern BOOL enq_start(uschar *, unsigned); #ifdef EXPERIMENTAL_EVENT extern uschar *event_raise(uschar *, const uschar *, uschar *); +extern void msg_event_raise(const uschar *, const address_item *); #endif extern void exim_exit(int); extern void exim_nullstd(void); diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 59afe42aa..66d632fad 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -919,12 +919,22 @@ while (count-- > 0) addr->basic_errno = ERRNO_RCPT4XX; addr->more_errno |= ((buffer[1] - '0')*10 + buffer[2] - '0') << 8; +#ifdef EXPERIMENTAL_EVENT + event_defer_errno = addr->more_errno; + msg_event_raise(US"msg:rcpt:host:defer", addr); +#endif + /* Log temporary errors if there are more hosts to be tried. If not, log this last one in the == line. */ if (host->next) log_write(0, LOG_MAIN, "H=%s [%s]: %s", host->name, host->address, addr->message); +#ifdef EXPERIMENTAL_EVENT + else + msg_event_raise(US"msg:rcpt:defer", addr); +#endif + /* Do not put this message on the list of those waiting for specific hosts, as otherwise it is likely to be tried too often. */ diff --git a/test/confs/5700 b/test/confs/5700 index 7a060cdb6..db1aa2a6e 100644 --- a/test/confs/5700 +++ b/test/confs/5700 @@ -46,6 +46,18 @@ ev_msg_fail: domain <$domain> \ reason <$event_data> +ev_msg_log: + accept logwrite = . \ + $acl_arg1 \ + ip <$host_address> \ + port <$host_port> \ + fqdn <$host> \ + local_part <$local_part> \ + domain <$domain> \ + $acl_arg2 \ + router <$router_name> \ + transport <$transport_name> + ev_msg: accept condition = ${if eq {fail} {${listextract{2}{$event_name}}}} acl = ev_msg_fail @@ -57,29 +69,21 @@ ev_msg: logwrite = $this_expansion_will_fail accept condition = ${if eq {$event_name}{msg:delivery}} - logwrite = . \ - delivery \ - ip <$host_address> \ - port <$host_port> \ - fqdn <$host> \ - local_part <$local_part> \ - domain <$domain> \ - confirmation <$event_data> \ - router <$router_name> \ - transport <$transport_name> + acl = ev_msg_log delivery "confirmation <$event_data>" accept condition = ${if eq {$event_name}{msg:host:defer}} - logwrite = . \ - deferral \ - ip <$host_address> \ - port <$host_port> \ - fqdn <$host> \ - local_part <$local_part> \ - domain <$domain> \ - errno <$event_defer_errno> \ - errstr <$event_data> \ - router <$router_name> \ - transport <$transport_name> + acl = ev_msg_log "host deferral" \ + "errno <$event_defer_errno> errstr <$event_data>" + + accept condition = ${if eq {$event_name}{msg:rcpt:defer}} + set acl_m_ev_lkup = ${eval:$event_defer_errno & 0xff} + set acl_m_ev_lkup = ${if = {$acl_m_ev_lkup}{65} {A} \ + { ${if = {$acl_m_ev_lkup}{77} {MX} \ + {$acl_m_ev_lkup}}}} + set acl_m_ev_code = 4${eval:$event_defer_errno >>8} + acl = ev_msg_log "rcpt deferral" \ + "err <$event_defer_errno>:<$acl_m_ev_lkup:$acl_m_ev_code> \ + errstr <$event_data>" logger: warn logwrite = event $event_name @@ -105,6 +109,7 @@ others: route_list = * 127.0.0.1 byname self = send transport = smtp + errors_to = "" no_more diff --git a/test/log/5700 b/test/log/5700 index 6af2a9011..37eace605 100644 --- a/test/log/5700 +++ b/test/log/5700 @@ -41,17 +41,32 @@ 1999-03-02 09:44:33 10HmaZ-0005vi-00 . [127.0.0.1] -> [127.0.0.1]:1224 1999-03-02 09:44:33 10HmaZ-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP timeout after EHLO the.local.host.name: Connection timed out 1999-03-02 09:44:33 10HmaZ-0005vi-00 event msg:host:defer -1999-03-02 09:44:33 10HmaZ-0005vi-00 . deferral ip <127.0.0.1> port <1224> fqdn <127.0.0.1> local_part domain errno <110> errstr router transport +1999-03-02 09:44:33 10HmaZ-0005vi-00 . host deferral ip <127.0.0.1> port <1224> fqdn <127.0.0.1> local_part domain errno <110> errstr router transport 1999-03-02 09:44:33 10HmaZ-0005vi-00 == userx@domain1 R=others T=smtp defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after EHLO the.local.host.name 1999-03-02 09:44:33 10HmaZ-0005vi-00 ** userx@domain1: retry timeout exceeded -1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss -1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: R=dump_bounces -1999-03-02 09:44:33 10HmbA-0005vi-00 Completed -1999-03-02 09:44:33 10HmbA-0005vi-00 event msg:complete -1999-03-02 09:44:33 10HmbA-0005vi-00 . finished: 10HmbA-0005vi-00 +1999-03-02 09:44:33 10HmaZ-0005vi-00 userx@domain1: error ignored 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed 1999-03-02 09:44:33 10HmaZ-0005vi-00 event msg:complete 1999-03-02 09:44:33 10HmaZ-0005vi-00 . finished: 10HmaZ-0005vi-00 +1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 Start queue run: pid=pppp -qqf +1999-03-02 09:44:33 10HmbA-0005vi-00 event tcp:connect +1999-03-02 09:44:33 10HmbA-0005vi-00 . [127.0.0.1]:1111 +1999-03-02 09:44:33 10HmbA-0005vi-00 event smtp:connect +1999-03-02 09:44:33 10HmbA-0005vi-00 . [127.0.0.1] -> [127.0.0.1]:1224 +1999-03-02 09:44:33 10HmbA-0005vi-00 . banner <220 ESMTP> +1999-03-02 09:44:33 10HmbA-0005vi-00 event msg:rcpt:host:defer +1999-03-02 09:44:33 10HmbA-0005vi-00 event msg:rcpt:defer +1999-03-02 09:44:33 10HmbA-0005vi-00 . rcpt deferral ip <127.0.0.1> port <1224> fqdn <127.0.0.1> local_part domain err <12865>: errstr : 450 NOT RIGHT NOW> router transport +1999-03-02 09:44:33 10HmbA-0005vi-00 event tcp:close +1999-03-02 09:44:33 10HmbA-0005vi-00 . [127.0.0.1] -> [127.0.0.1]:1224 +1999-03-02 09:44:33 10HmbA-0005vi-00 == userx@domain1 R=others T=smtp defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 450 NOT RIGHT NOW +1999-03-02 09:44:33 10HmbA-0005vi-00 ** userx@domain1: retry timeout exceeded +1999-03-02 09:44:33 10HmbA-0005vi-00 userx@domain1: error ignored +1999-03-02 09:44:33 10HmbA-0005vi-00 Completed +1999-03-02 09:44:33 10HmbA-0005vi-00 event msg:complete +1999-03-02 09:44:33 10HmbA-0005vi-00 . finished: 10HmbA-0005vi-00 +1999-03-02 09:44:33 End queue run: pid=pppp -qqf 1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss 1999-03-02 09:44:33 Start queue run: pid=pppp -qqf 1999-03-02 09:44:33 10HmbB-0005vi-00 event tcp:connect @@ -64,24 +79,20 @@ 1999-03-02 09:44:33 10HmbB-0005vi-00 ** userx@domain1 R=others T=smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 GO AWAY 1999-03-02 09:44:33 10HmbB-0005vi-00 event msg:fail:delivery 1999-03-02 09:44:33 10HmbB-0005vi-00 . refused by fdqn <127.0.0.1> local_part domain -1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss -1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: R=dump_bounces -1999-03-02 09:44:33 10HmbC-0005vi-00 Completed -1999-03-02 09:44:33 10HmbC-0005vi-00 event msg:complete -1999-03-02 09:44:33 10HmbC-0005vi-00 . finished: 10HmbC-0005vi-00 +1999-03-02 09:44:33 10HmbB-0005vi-00 userx@domain1: error ignored 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed 1999-03-02 09:44:33 10HmbB-0005vi-00 event msg:complete 1999-03-02 09:44:33 10HmbB-0005vi-00 . finished: 10HmbB-0005vi-00 1999-03-02 09:44:33 End queue run: pid=pppp -qqf -1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbD-0005vi-00 cancelled by CALLER -1999-03-02 09:44:33 10HmbD-0005vi-00 event msg:fail:internal -1999-03-02 09:44:33 10HmbD-0005vi-00 . local_part domain reason -1999-03-02 09:44:33 10HmbE-0005vi-00 <= <> R=10HmbD-0005vi-00 U=EXIMUSER P=local S=sss -1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: R=dump_bounces -1999-03-02 09:44:33 10HmbE-0005vi-00 Completed -1999-03-02 09:44:33 10HmbE-0005vi-00 event msg:complete -1999-03-02 09:44:33 10HmbE-0005vi-00 . finished: 10HmbE-0005vi-00 +1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbC-0005vi-00 cancelled by CALLER +1999-03-02 09:44:33 10HmbC-0005vi-00 event msg:fail:internal +1999-03-02 09:44:33 10HmbC-0005vi-00 . local_part domain reason +1999-03-02 09:44:33 10HmbD-0005vi-00 <= <> R=10HmbC-0005vi-00 U=EXIMUSER P=local S=sss +1999-03-02 09:44:33 10HmbD-0005vi-00 => :blackhole: R=dump_bounces 1999-03-02 09:44:33 10HmbD-0005vi-00 Completed 1999-03-02 09:44:33 10HmbD-0005vi-00 event msg:complete 1999-03-02 09:44:33 10HmbD-0005vi-00 . finished: 10HmbD-0005vi-00 +1999-03-02 09:44:33 10HmbC-0005vi-00 Completed +1999-03-02 09:44:33 10HmbC-0005vi-00 event msg:complete +1999-03-02 09:44:33 10HmbC-0005vi-00 . finished: 10HmbC-0005vi-00 diff --git a/test/scripts/5700-events/5700 b/test/scripts/5700-events/5700 index f7cd8272c..8fb2010f2 100644 --- a/test/scripts/5700-events/5700 +++ b/test/scripts/5700-events/5700 @@ -1,5 +1,5 @@ # Arbitrary expansion after transport -# (EXPERIMENTAL_TPDA) +# (EXPERIMENTAL_EVENT) # need_ipv4 # @@ -67,6 +67,24 @@ A message which will hit a timeout at the destination server # # exim -odq userx@domain1 +A message which will get deferred +**** +server PORT_S +220 ESMTP +EHLO +250-OK +250 HELP +MAIL +250 OK +RCPT +450 NOT RIGHT NOW +QUIT +220 OK +**** +exim -qqf +**** +# +exim -odq userx@domain1 A message which will get refused **** server PORT_S diff --git a/test/stdout/5700 b/test/stdout/5700 index b185dca05..a8f3b7482 100644 --- a/test/stdout/5700 +++ b/test/stdout/5700 @@ -6,7 +6,7 @@ Connection request from [127.0.0.1] EHLO the.local.host.name 250-OK 250 HELP -MAIL FROM: +MAIL FROM:<> 250 OK RCPT TO: 250 OK @@ -32,7 +32,7 @@ Connection request from [127.0.0.1] EHLO the.local.host.name 250-OK 250 HELP -MAIL FROM: +MAIL FROM:<> 250 OK RCPT TO: 250 OK @@ -64,7 +64,20 @@ Connection request from [127.0.0.1] EHLO the.local.host.name 250-OK 250 HELP -MAIL FROM: +MAIL FROM:<> +250 OK +RCPT TO: +450 NOT RIGHT NOW +QUIT +220 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 ESMTP +EHLO the.local.host.name +250-OK +250 HELP +MAIL FROM:<> 250 OK RCPT TO: 550 GO AWAY