[exim-cvs] Bug 1031: Experimental TPDA

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] Bug 1031: Experimental TPDA
Gitweb: http://git.exim.org/exim.git/commitdiff/d68218c76f4dc65a3e308fa75d071526ad0e0f49
Commit:     d68218c76f4dc65a3e308fa75d071526ad0e0f49
Parent:     4d8d62b965c7379e85aeb6e43534c89d06099ad2
Author:     Jeremy Harris <jgh@???>
AuthorDate: Mon Sep 30 10:12:12 2013 -0700
Committer:  Todd Lyons <tlyons@???>
CommitDate: Mon Sep 30 10:14:27 2013 -0700


    Bug 1031: Experimental TPDA


    Remove whitespace
---
 doc/doc-txt/experimental-spec.txt              |   84 ++++++++++++++++++++++++
 src/src/EDITME                                 |    4 +
 src/src/config.h.defaults                      |    1 +
 src/src/deliver.c                              |   40 +++++++++++
 src/src/exim.c                                 |    3 +
 src/src/expand.c                               |   10 +++
 src/src/globals.c                              |   11 +++
 src/src/globals.h                              |   12 ++++
 src/src/structs.h                              |    3 +
 src/src/transport.c                            |    4 +
 src/src/transports/smtp.c                      |   76 +++++++++++++++++++++-
 src/src/transports/smtp.h                      |    3 +
 test/confs/5700                                |   67 +++++++++++++++++++
 test/log/5700                                  |   22 ++++++
 test/paniclog/5700                             |    2 +
 test/scripts/5700-tpt-post-dlv-action/5700     |   64 ++++++++++++++++++
 test/scripts/5700-tpt-post-dlv-action/REQUIRES |    1 +
 test/stderr/5700                               |    2 +
 test/stdout/5700                               |   60 +++++++++++++++++
 19 files changed, 468 insertions(+), 1 deletions(-)


diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt
index 9f59990..3e8f5c5 100644
--- a/doc/doc-txt/experimental-spec.txt
+++ b/doc/doc-txt/experimental-spec.txt
@@ -844,6 +844,90 @@ b. Configure, somewhere before the DATA ACL, the control option to



+Transport post-delivery actions
+--------------------------------------------------------------
+
+An arbitrary per-transport string can be expanded on successful delivery,
+and (for SMTP transports) a second string on deferrals caused by a host error.
+This feature may be used, for example, to write exim internal log information
+(not available otherwise) into a database.
+
+In order to use the feature, you must set
+
+EXPERIMENTAL_TPDA=yes
+
+in your Local/Makefile
+
+and define the expandable strings in the runtime config file, to
+be executed at end of delivery.
+
+Additionally, there are 6 more variables, available at end of
+delivery:
+
+tpda_delivery_ip             IP of host, which has accepted delivery
+tpda_delivery_port           Port of remote host which has accepted delivery
+tpda_delivery_fqdn           FQDN of host, which has accepted delivery
+tpda_delivery_local_part     local part of address being delivered
+tpda_delivery_domain         domain part of address being delivered
+tpda_delivery_confirmation   SMTP confirmation message
+
+In case of a deferral caused by a host-error:
+tpda_defer_errno             Error number
+tpda_defer_errstr            Error string possibly containing more details
+
+The $router_name and $transport_name variables are also usable.
+
+
+To take action after successful deliveries, set the following option
+on any transport of interest.
+
+tpda_delivery_action
+
+An example might look like:
+
+tpda_delivery_action = \
+${lookup pgsql {SELECT * FROM record_Delivery( \
+    '${quote_pgsql:$sender_address_domain}',\
+    '${quote_pgsql:${lc:$sender_address_local_part}}', \
+    '${quote_pgsql:$tpda_delivery_domain}', \
+    '${quote_pgsql:${lc:$tpda_delivery_local_part}}', \
+    '${quote_pgsql:$tpda_delivery_ip}', \
+    '${quote_pgsql:${lc:$tpda_delivery_fqdn}}', \
+    '${quote_pgsql:$message_exim_id}')}}
+
+The string is expanded after the delivery completes and any
+side-effects will happen.  The result is then discarded.
+Note that for complex operations an ACL expansion can be used.
+
+
+In order to log host deferrals, add the following option to an SMTP
+transport:
+
+tpda_host_defer_action
+
+This is a private option of the SMTP transport. It is intended to
+log failures of remote hosts. It is executed only when exim has
+attempted to deliver a message to a remote host and failed due to
+an error which doesn't seem to be related to the individual
+message, sender, or recipient address.
+See section 45.2 of the exim documentation for more details on how
+this is determined.
+
+Example:
+
+tpda_host_defer_action = \
+${lookup mysql {insert into delivlog set \
+    msgid = '${quote_mysql:$message_exim_id}', \
+    senderlp = '${quote_mysql:${lc:$sender_address_local_part}}', \
+    senderdom = '${quote_mysql:$sender_address_domain}', \
+    delivlp = '${quote_mysql:${lc:$tpda_delivery_local_part}}', \
+    delivdom = '${quote_mysql:$tpda_delivery_domain}', \
+    delivip = '${quote_mysql:$tpda_delivery_ip}', \
+    delivport = '${quote_mysql:$tpda_delivery_port}', \
+    delivfqdn = '${quote_mysql:$tpda_delivery_fqdn}', \
+    deliverrno = '${quote_mysql:$tpda_defer_errno}', \
+    deliverrstr = '${quote_mysql:$tpda_defer_errstr}' \
+    }}


--------------------------------------------------------------
End of file
diff --git a/src/src/EDITME b/src/src/EDITME
index e29c1eb..1db70f7 100644
--- a/src/src/EDITME
+++ b/src/src/EDITME
@@ -469,6 +469,10 @@ EXIM_MONITOR=eximon.bin
# Uncomment the following line to add Per-Recipient-Data-Response support.
# EXPERIMENTAL_PRDR=yes

+# Uncomment the following line to support Transport post-delivery actions,
+# eg. for logging to a database.
+# EXPERIMENTAL_TPDA=yes
+

 ###############################################################################
 #                 THESE ARE THINGS YOU MIGHT WANT TO SPECIFY                  #
diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults
index 1594f68..bf7ac63 100644
--- a/src/src/config.h.defaults
+++ b/src/src/config.h.defaults
@@ -170,6 +170,7 @@ it's a default value. */
 #define EXPERIMENTAL_PRDR
 #define EXPERIMENTAL_SPF
 #define EXPERIMENTAL_SRS
+#define EXPERIMENTAL_TPDA


/* For developers */
#define WANT_DEEPER_PRINTF_CHECKS
diff --git a/src/src/deliver.c b/src/src/deliver.c
index 23e63d5..bc6a69f 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -695,6 +695,15 @@ the log line, and reset the store afterwards. Remote deliveries should always
have a pointer to the host item that succeeded; local deliveries can have a
pointer to a single host item in their host list, for use by the transport. */

+#ifdef EXPERIMENTAL_TPDA
+  tpda_delivery_ip = NULL;    /* presume no successful remote delivery */
+  tpda_delivery_port = 0;
+  tpda_delivery_fqdn = NULL;
+  tpda_delivery_local_part = NULL;
+  tpda_delivery_domain = NULL;
+  tpda_delivery_confirmation = NULL;
+#endif
+
 s = reset_point = store_get(size);


 log_address = string_log_address(addr, (log_write_selector & L_all_parents) != 0, TRUE);
@@ -741,7 +750,12 @@ if ((log_extra_selector & LX_delivery_size) != 0)
 if (addr->transport->info->local)
   {
   if (addr->host_list != NULL)
+    {
     s = string_append(s, &size, &ptr, 2, US" H=", addr->host_list->name);
+    #ifdef EXPERIMENTAL_TPDA
+      tpda_delivery_fqdn = addr->host_list->name;
+    #endif
+    }
   if (addr->shadow_message != NULL)
     s = string_cat(s, &size, &ptr, addr->shadow_message,
       Ustrlen(addr->shadow_message));
@@ -760,6 +774,15 @@ else
         addr->host_used->port));
     if (continue_sequence > 1)
       s = string_cat(s, &size, &ptr, US"*", 1);
+
+    #ifdef EXPERIMENTAL_TPDA
+    tpda_delivery_ip =           addr->host_used->address;
+    tpda_delivery_port =         addr->host_used->port;
+    tpda_delivery_fqdn =         addr->host_used->name;
+    tpda_delivery_local_part =   addr->local_part;
+    tpda_delivery_domain =       addr->domain;
+    tpda_delivery_confirmation = addr->message;
+    #endif
     }


#ifdef SUPPORT_TLS
@@ -827,6 +850,23 @@ store we used to build the line after writing it. */

 s[ptr] = 0;
 log_write(0, flags, "%s", s);
+
+#ifdef EXPERIMENTAL_TPDA
+if (addr->transport->tpda_delivery_action)
+  {
+  DEBUG(D_deliver)
+    debug_printf("  TPDA(Delivery): tpda_deliver_action=|%s| tpda_delivery_IP=%s\n",
+      addr->transport->tpda_delivery_action, tpda_delivery_ip);
+
+  router_name =    addr->router->name;
+  transport_name = addr->transport->name;
+  if (!expand_string(addr->transport->tpda_delivery_action) && *expand_string_message)
+    log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand tpda_deliver_action in %s: %s\n",
+      transport_name, expand_string_message);
+  router_name = NULL;
+  transport_name = NULL;
+  }
+#endif
 store_reset(reset_point);
 return;
 }
diff --git a/src/src/exim.c b/src/src/exim.c
index 8ab0456..c5053ba 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -825,6 +825,9 @@ fprintf(f, "Support for:");
 #ifdef EXPERIMENTAL_PRDR
   fprintf(f, " Experimental_PRDR");
 #endif
+#ifdef EXPERIMENTAL_TPDA
+  fprintf(f, " Experimental_TPDA");
+#endif
 fprintf(f, "\n");


 fprintf(f, "Lookups (built-in):");
diff --git a/src/src/expand.c b/src/src/expand.c
index edef45d..a22ee2a 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -677,6 +677,16 @@ static var_entry var_table[] = {
   { "tod_logfile",         vtype_todlf,       NULL },
   { "tod_zone",            vtype_todzone,     NULL },
   { "tod_zulu",            vtype_todzulu,     NULL },
+#ifdef EXPERIMENTAL_TPDA
+  { "tpda_defer_errno",     vtype_int,         &tpda_defer_errno },
+  { "tpda_defer_errstr",    vtype_stringptr,   &tpda_defer_errstr },
+  { "tpda_delivery_confirmation", vtype_stringptr,   &tpda_delivery_confirmation },
+  { "tpda_delivery_domain", vtype_stringptr,   &tpda_delivery_domain },
+  { "tpda_delivery_fqdn",   vtype_stringptr,   &tpda_delivery_fqdn },
+  { "tpda_delivery_ip",     vtype_stringptr,   &tpda_delivery_ip },
+  { "tpda_delivery_local_part",vtype_stringptr,&tpda_delivery_local_part },
+  { "tpda_delivery_port",   vtype_int,         &tpda_delivery_port },
+#endif
   { "transport_name",      vtype_stringptr,   &transport_name },
   { "value",               vtype_stringptr,   &lookup_value },
   { "version_number",      vtype_stringptr,   &version_string },
diff --git a/src/src/globals.c b/src/src/globals.c
index 05bb0ae..d4589cd 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -1280,6 +1280,17 @@ int     thismessage_size_limit = 0;
 int     timeout_frozen_after   = 0;
 BOOL    timestamps_utc         = FALSE;


+#ifdef EXPERIMENTAL_TPDA
+int     tpda_defer_errno        = 0;
+uschar *tpda_defer_errstr       = NULL;
+uschar *tpda_delivery_ip        = NULL;
+int     tpda_delivery_port      = 0;
+uschar *tpda_delivery_fqdn      = NULL;
+uschar *tpda_delivery_local_part= NULL;
+uschar *tpda_delivery_domain    = NULL;
+uschar *tpda_delivery_confirmation = NULL;
+#endif
+
 transport_instance  *transports = NULL;


 transport_instance  transport_defaults = {
diff --git a/src/src/globals.h b/src/src/globals.h
index 2cc1688..104b5fa 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -834,6 +834,18 @@ extern int     test_harness_load_avg;  /* For use when testing */
 extern int     thismessage_size_limit; /* Limit for this message */
 extern int     timeout_frozen_after;   /* Max time to keep frozen messages */
 extern BOOL    timestamps_utc;         /* Use UTC for all times */
+
+#ifdef EXPERIMENTAL_TPDA
+extern int     tpda_defer_errno;        /* error number set when a remote delivery is deferred with a host error */
+extern uschar *tpda_defer_errstr;       /* error string set when a remote delivery is deferred with a host error */
+extern uschar *tpda_delivery_ip;        /* IP of host, which has accepted delivery */
+extern int     tpda_delivery_port;       /* port of host, which has accepted delivery */
+extern uschar *tpda_delivery_fqdn;      /* FQDN of host, which has accepted delivery */
+extern uschar *tpda_delivery_local_part;/* local part of address being delivered */
+extern uschar *tpda_delivery_domain;    /* domain part of address being delivered */
+extern uschar *tpda_delivery_confirmation; /* SMTP confirmation message */
+#endif
+
 extern uschar *transport_name;         /* Name of transport last started */
 extern int     transport_count;        /* Count of bytes transported */
 extern int     transport_newlines;     /* Accurate count of number of newline chars transported */
diff --git a/src/src/structs.h b/src/src/structs.h
index 53aa210..baf9a0f 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -184,6 +184,9 @@ typedef struct transport_instance {
   BOOL    log_fail_output;
   BOOL    log_defer_output;
   BOOL    retry_use_local_part;   /* Defaults true for local, false for remote */
+#ifdef EXPERIMENTAL_TPDA
+  uschar  *tpda_delivery_action;  /* String to expand on success */
+#endif
 } transport_instance;



diff --git a/src/src/transport.c b/src/src/transport.c
index 7dd1afb..d2540be 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -94,6 +94,10 @@ optionlist optionlist_transports[] = {
                  (void *)offsetof(transport_instance, shadow_condition) },
   { "shadow_transport", opt_stringptr|opt_public,
                  (void *)offsetof(transport_instance, shadow) },
+#ifdef EXPERIMENTAL_TPDA
+  { "tpda_delivery_action",opt_stringptr | opt_public,
+                 (void *)offsetof(transport_instance, tpda_delivery_action) },
+#endif
   { "transport_filter", opt_stringptr|opt_public,
                  (void *)offsetof(transport_instance, filter_command) },
   { "transport_filter_timeout", opt_time|opt_public,
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index b18720c..9918f31 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -156,6 +156,10 @@ optionlist smtp_transport_options[] = {
   { "tls_verify_certificates", opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) }
 #endif
+#ifdef EXPERIMENTAL_TPDA
+ ,{ "tpda_host_defer_action", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, tpda_host_defer_action) },
+#endif
 };


 /* Size of the options list. An extern variable has to be used so that its
@@ -233,6 +237,9 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   NULL,                /* dkim_sign_headers */
   NULL                 /* dkim_strict */
 #endif
+#ifdef EXPERIMENTAL_TPDA
+ ,NULL                 /* tpda_host_defer_action */
+#endif
 };



@@ -577,6 +584,59 @@ else



+#ifdef EXPERIMENTAL_TPDA
+/*************************************************
+*   Post-defer action                            *
+*************************************************/
+
+/* This expands an arbitrary per-transport string.
+   It might, for example, be used to write to the database log.
+
+Arguments:
+  ob                    transport options block
+  addr                  the address item containing error information
+  host                  the current host
+
+Returns:   nothing
+*/
+
+static void
+tpda_deferred(smtp_transport_options_block *ob, address_item *addr, host_item *host)
+{
+uschar *action = ob->tpda_host_defer_action;
+if (!action)
+    return;
+
+tpda_delivery_ip =         string_copy(host->address);
+tpda_delivery_port =       (host->port == PORT_NONE)? 25 : host->port;
+tpda_delivery_fqdn =       string_copy(host->name);
+tpda_delivery_local_part = string_copy(addr->local_part);
+tpda_delivery_domain =     string_copy(addr->domain);
+tpda_defer_errno =         addr->basic_errno;
+
+tpda_defer_errstr = addr->message
+  ? addr->basic_errno > 0
+    ? string_sprintf("%s: %s", addr->message, strerror(addr->basic_errno))
+    : string_copy(addr->message)
+  : addr->basic_errno > 0
+    ? string_copy(strerror(addr->basic_errno))
+    : NULL;
+
+DEBUG(D_transport)
+  debug_printf("  TPDA(host defer): tpda_host_defer_action=|%s| tpda_delivery_IP=%s\n",
+    action, tpda_delivery_ip);
+
+router_name =    addr->router->name;
+transport_name = addr->transport->name;
+if (!expand_string(action) && *expand_string_message)
+  log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand tpda_defer_action in %s: %s\n",
+    transport_name, expand_string_message);
+router_name = transport_name = NULL;
+}
+#endif
+
+
+
 /*************************************************
 *           Synchronize SMTP responses           *
 *************************************************/
@@ -1912,7 +1972,12 @@ if (!ok) ok = TRUE; else


     /* Set up confirmation if needed - applies only to SMTP */


-    if ((log_extra_selector & LX_smtp_confirmation) != 0 && !lmtp)
+    if (
+        #ifndef EXPERIMENTAL_TPDA
+          (log_extra_selector & LX_smtp_confirmation) != 0 &&
+        #endif
+          !lmtp
+       )
       {
       uschar *s = string_printing(buffer);
       conf = (s == buffer)? (uschar *)string_copy(s) : s;
@@ -3051,6 +3116,11 @@ for (cutoff_retry = 0; expired &&
                          first_addr->basic_errno != ERRNO_TLSFAILURE)
         write_logs(first_addr, host);


+      #ifdef EXPERIMENTAL_TPDA
+      if (rc == DEFER)
+        tpda_deferred(ob, first_addr, host);
+      #endif
+
       /* If STARTTLS was accepted, but there was a failure in setting up the
       TLS session (usually a certificate screwup), and the host is not in
       hosts_require_tls, and tls_tempfail_tryclear is true, try again, with
@@ -3073,6 +3143,10 @@ for (cutoff_retry = 0; expired &&
           expanded_hosts != NULL, &message_defer, TRUE);
         if (rc == DEFER && first_addr->basic_errno != ERRNO_AUTHFAIL)
           write_logs(first_addr, host);
+        #ifdef EXPERIMENTAL_TPDA
+        if (rc == DEFER)
+          tpda_deferred(ob, first_addr, host);
+        #endif
         }
       #endif
       }
diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h
index 8e85294..0d88016 100644
--- a/src/src/transports/smtp.h
+++ b/src/src/transports/smtp.h
@@ -73,6 +73,9 @@ typedef struct {
   uschar *dkim_sign_headers;
   uschar *dkim_strict;
   #endif
+  #ifdef EXPERIMENTAL_TPDA
+  uschar *tpda_host_defer_action;
+  #endif
 } smtp_transport_options_block;


 /* Data for reading the private options. */
diff --git a/test/confs/5700 b/test/confs/5700
new file mode 100644
index 0000000..52b2801
--- /dev/null
+++ b/test/confs/5700
@@ -0,0 +1,67 @@
+# Exim test configuration 5700
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+rfc1413_query_timeout = 0s
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+acl_smtp_data = accept
+
+
+# ----- ACL -----
+
+begin acl
+
+logger:
+    accept condition = ${if eq {$acl_arg2}{domain1}}
+       logwrite = \
+        $acl_arg1 \
+        ip <$tpda_delivery_ip> \
+        port <$tpda_delivery_port> \
+        fqdn <$tpda_delivery_fqdn> \
+        local_part <$tpda_delivery_local_part> \
+        domain <$tpda_delivery_domain> \
+        confirmation <$tpda_delivery_confirmation> \
+        errno <$tpda_defer_errno> \
+        errstr <$tpda_defer_errstr> \
+        router <$router_name> \
+        transport <$transport_name>
+
+    accept logwrite = $this_expansion_will_fail
+
+# ----- Routers -----
+
+begin routers
+
+dump_bounces:
+  driver = redirect
+  senders = :
+  data = :blackhole:
+
+others:
+  driver = manualroute
+  route_list = * 127.0.0.1 byname
+  self = send
+  transport = smtp
+  no_more
+
+
+# ----- Transports -----
+
+begin transports
+
+smtp:
+  driver = smtp
+  port = PORT_S
+  command_timeout = 1s
+  final_timeout = 1s
+  tpda_delivery_action =   ${acl {logger} {delivery} {$domain} }
+  tpda_host_defer_action = ${acl {logger} {deferral} {$domain} }
+
+# End
diff --git a/test/log/5700 b/test/log/5700
new file mode 100644
index 0000000..d119365
--- /dev/null
+++ b/test/log/5700
@@ -0,0 +1,22 @@
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqf
+1999-03-02 09:44:33 10HmaY-0005vi-00 => userx@domain1 R=others T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmaY-0005vi-00 delivery ip <127.0.0.1> port <1224> fqdn <127.0.0.1> local_part <userx> domain <domain1> confirmation <250 OK> errno <0> errstr <> router <others> transport <smtp>
+1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqf
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqf
+1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@domain2 R=others T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmaX-0005vi-00 failed to expand tpda_deliver_action in smtp: error from acl "logger"
+
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqf
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after EHLO the.local.host.name: Connection timed out
+1999-03-02 09:44:33 10HmaZ-0005vi-00 deferral ip <127.0.0.1> port <1224> fqdn <127.0.0.1> local_part <userx> domain <domain1> confirmation <> errno <110> errstr <SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after EHLO the.local.host.name: Connection timed out> router <others> transport <smtp>
+1999-03-02 09:44:33 10HmaZ-0005vi-00 == userx@domain1 R=others T=smtp defer (dd): Connection timed out: SMTP timeout while connected to 127.0.0.1 [127.0.0.1] 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: <CALLER@???> R=dump_bounces
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
diff --git a/test/paniclog/5700 b/test/paniclog/5700
new file mode 100644
index 0000000..4f28d19
--- /dev/null
+++ b/test/paniclog/5700
@@ -0,0 +1,2 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 failed to expand tpda_deliver_action in smtp: error from acl "logger"
+
diff --git a/test/scripts/5700-tpt-post-dlv-action/5700 b/test/scripts/5700-tpt-post-dlv-action/5700
new file mode 100644
index 0000000..b85231b
--- /dev/null
+++ b/test/scripts/5700-tpt-post-dlv-action/5700
@@ -0,0 +1,64 @@
+# Arbtirary expansion after transport
+# (EXPERIMENTAL_TPDA)
+#
+need_ipv4
+#
+exim -odq userx@domain1
+A deliverable message
+****
+server PORT_S
+220 ESMTP
+EHLO
+250-OK
+250 HELP
+MAIL
+250 OK
+RCPT
+250 OK
+DATA
+354 More...
+.
+250 OK
+QUIT
+220 OK
+****
+exim -qqf
+****
+#
+#
+#
+#
+exim -odq userx@domain2
+A deliverable message which will hit a coding error in the config
+****
+server PORT_S
+220 ESMTP
+EHLO
+250-OK
+250 HELP
+MAIL
+250 OK
+RCPT
+250 OK
+DATA
+354 More...
+.
+250 OK
+QUIT
+220 OK
+****
+exim -qqf
+****
+#
+#
+#
+server PORT_S
+220 ESMTP
+EHLO
+*sleep 4
+****
+exim -odi userx@domain1
+A message which will hit a timeout at the destination server
+.
+****
+#
diff --git a/test/scripts/5700-tpt-post-dlv-action/REQUIRES b/test/scripts/5700-tpt-post-dlv-action/REQUIRES
new file mode 100644
index 0000000..4444658
--- /dev/null
+++ b/test/scripts/5700-tpt-post-dlv-action/REQUIRES
@@ -0,0 +1 @@
+support Experimental_TPDA
diff --git a/test/stderr/5700 b/test/stderr/5700
new file mode 100644
index 0000000..4f28d19
--- /dev/null
+++ b/test/stderr/5700
@@ -0,0 +1,2 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 failed to expand tpda_deliver_action in smtp: error from acl "logger"
+
diff --git a/test/stdout/5700 b/test/stdout/5700
new file mode 100644
index 0000000..a45b44c
--- /dev/null
+++ b/test/stdout/5700
@@ -0,0 +1,60 @@
+
+******** SERVER ********
+Listening on port 1224 ... 
+Connection request from [127.0.0.1]
+220 ESMTP
+EHLO the.local.host.name
+250-OK
+250 HELP
+MAIL FROM:<CALLER@???>
+250 OK
+RCPT TO:<userx@domain1>
+250 OK
+DATA
+354 More...
+Received: from CALLER by the.local.host.name with local (Exim x.yz)
+    (envelope-from <CALLER@???>)
+    id 10HmaY-0005vi-00
+    for userx@domain1; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaY-0005vi-00@???>
+From: CALLER_NAME <CALLER@???>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+A deliverable message
+.
+250 OK
+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:<CALLER@???>
+250 OK
+RCPT TO:<userx@domain2>
+250 OK
+DATA
+354 More...
+Received: from CALLER by the.local.host.name with local (Exim x.yz)
+    (envelope-from <CALLER@???>)
+    id 10HmaX-0005vi-00
+    for userx@domain2; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaX-0005vi-00@???>
+From: CALLER_NAME <CALLER@???>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+A deliverable message which will hit a coding error in the config
+.
+250 OK
+QUIT
+220 OK
+End of script
+Listening on port 1224 ... 
+Connection request from [127.0.0.1]
+220 ESMTP
+EHLO the.local.host.name
+*sleep 4
+End of script