Debug: output type of process as it terminates
[exim.git] / src / src / transports / smtp.c
index 11a996c6515f9eeea008397eed703c96a62c5d95..3b4aea192e04eadc93f5c26007bb62c5adc526dc 100644 (file)
@@ -43,6 +43,10 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(smtp_transport_options_block, dkim.dkim_canon) },
   { "dkim_domain", opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, dkim.dkim_domain) },
+  { "dkim_hash", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, dkim.dkim_hash) },
+  { "dkim_identity", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, dkim.dkim_identity) },
   { "dkim_private_key", opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, dkim.dkim_private_key) },
   { "dkim_selector", opt_stringptr,
@@ -201,87 +205,89 @@ void smtp_transport_closedown(transport_instance *tblock) {}
 /* Default private options block for the smtp transport. */
 
 smtp_transport_options_block smtp_transport_option_defaults = {
-  NULL,                /* hosts */
-  NULL,                /* fallback_hosts */
-  NULL,                /* hostlist */
-  NULL,                /* fallback_hostlist */
-  NULL,                /* authenticated_sender */
-  US"$primary_hostname", /* helo_data */
-  NULL,                /* interface */
-  NULL,                /* port */
-  US"smtp",            /* protocol */
-  NULL,                /* DSCP */
-  NULL,                /* serialize_hosts */
-  NULL,                /* hosts_try_auth */
-  NULL,                /* hosts_require_auth */
-  US"*",               /* hosts_try_chunking */
+  .hosts =                     NULL,
+  .hosts =                     NULL,
+  .hostlist =                  NULL,
+  .fallback_hostlist =         NULL,
+  .authenticated_sender =      NULL,
+  .helo_data =                 US"$primary_hostname",
+  .interface =                 NULL,
+  .port =                      NULL,
+  .protocol =                  US"smtp",
+  .dscp =                      NULL,
+  .serialize_hosts =           NULL,
+  .hosts_try_auth =            NULL,
+  .hosts_require_auth =                NULL,
+  .hosts_try_chunking =                US"*",
 #ifdef EXPERIMENTAL_DANE
-  NULL,                /* hosts_try_dane */
-  NULL,                /* hosts_require_dane */
+  .hosts_try_dane =            NULL,
+  .hosts_require_dane =                NULL,
 #endif
-  NULL,                /* hosts_try_fastopen */
+  .hosts_try_fastopen =                NULL,
 #ifndef DISABLE_PRDR
-  US"*",               /* hosts_try_prdr */
+  .hosts_try_prdr =            US"*",
 #endif
 #ifndef DISABLE_OCSP
-  US"*",               /* hosts_request_ocsp (except under DANE; tls_client_start()) */
-  NULL,                /* hosts_require_ocsp */
+  .hosts_request_ocsp =                US"*",               /* hosts_request_ocsp (except under DANE; tls_client_start()) */
+  .hosts_require_ocsp =                NULL,
 #endif
-  NULL,                /* hosts_require_tls */
-  NULL,                /* hosts_avoid_tls */
-  NULL,                /* hosts_verify_avoid_tls */
-  NULL,                /* hosts_avoid_pipelining */
-  NULL,                /* hosts_avoid_esmtp */
+  .hosts_require_tls =         NULL,
+  .hosts_avoid_tls =           NULL,
+  .hosts_verify_avoid_tls =    NULL,
+  .hosts_avoid_pipelining =    NULL,
+  .hosts_avoid_esmtp =         NULL,
 #ifdef SUPPORT_TLS
-  NULL,                /* hosts_nopass_tls */
-  US"*",              /* hosts_noproxy_tls */
+  .hosts_nopass_tls =          NULL,
+  .hosts_noproxy_tls =         US"*",
 #endif
-  5*60,                /* command_timeout */
-  5*60,                /* connect_timeout; shorter system default overrides */
-  5*60,                /* data timeout */
-  10*60,               /* final timeout */
-  1024,                /* size_addition */
-  5,                   /* hosts_max_try */
-  50,                  /* hosts_max_try_hardlimit */
-  TRUE,                /* address_retry_include_sender */
-  FALSE,               /* allow_localhost */
-  FALSE,               /* authenticated_sender_force */
-  FALSE,               /* gethostbyname */
-  TRUE,                /* dns_qualify_single */
-  FALSE,               /* dns_search_parents */
-  { NULL, NULL },      /* dnssec_domains {request,require} */
-  TRUE,                /* delay_after_cutoff */
-  FALSE,               /* hosts_override */
-  FALSE,               /* hosts_randomize */
-  TRUE,                /* keepalive */
-  FALSE,               /* lmtp_ignore_quota */
-  NULL,                       /* expand_retry_include_ip_address */
-  TRUE                 /* retry_include_ip_address */
+  .command_timeout =           5*60,
+  .connect_timeout =           5*60,
+  .data_timeout =              5*60,
+  .final_timeout =             10*60,
+  .size_addition =             1024,
+  .hosts_max_try =             5,
+  .hosts_max_try_hardlimit =   50,
+  .address_retry_include_sender = TRUE,
+  .allow_localhost =           FALSE,
+  .authenticated_sender_force =        FALSE,
+  .gethostbyname =             FALSE,
+  .dns_qualify_single =                TRUE,
+  .dns_search_parents =                FALSE,
+  .dnssec = { .request=NULL, .require=NULL },
+  .delay_after_cutoff =                TRUE,
+  .hosts_override =            FALSE,
+  .hosts_randomize =           FALSE,
+  .keepalive =                 TRUE,
+  .lmtp_ignore_quota =         FALSE,
+  .expand_retry_include_ip_address =   NULL,
+  .retry_include_ip_address =  TRUE,
 #ifdef SUPPORT_SOCKS
- ,NULL                 /* socks_proxy */
+  .socks_proxy =               NULL,
 #endif
 #ifdef SUPPORT_TLS
- ,NULL,                /* tls_certificate */
-  NULL,                /* tls_crl */
-  NULL,                /* tls_privatekey */
-  NULL,                /* tls_require_ciphers */
-  NULL,                /* tls_sni */
-  US"system",          /* tls_verify_certificates */
-  EXIM_CLIENT_DH_DEFAULT_MIN_BITS,
-                       /* tls_dh_min_bits */
-  TRUE,                /* tls_tempfail_tryclear */
-  NULL,                /* tls_verify_hosts */
-  US"*",               /* tls_try_verify_hosts */
-  US"*"                /* tls_verify_cert_hostnames */
+  .tls_certificate =           NULL,
+  .tls_crl =                   NULL,
+  .tls_privatekey =            NULL,
+  .tls_require_ciphers =       NULL,
+  .tls_sni =                   NULL,
+  .tls_verify_certificates =   US"system",
+  .tls_dh_min_bits =           EXIM_CLIENT_DH_DEFAULT_MIN_BITS,
+  .tls_tempfail_tryclear =     TRUE,
+  .tls_verify_hosts =          NULL,
+  .tls_try_verify_hosts =      US"*",
+  .tls_verify_cert_hostnames = US"*",
 #endif
 #ifndef DISABLE_DKIM
- , {NULL,              /* dkim_canon */
-    NULL,              /* dkim_domain */
-    NULL,              /* dkim_private_key */
-    NULL,              /* dkim_selector */
-    NULL,              /* dkim_sign_headers */
-    NULL,              /* dkim_strict */
-    FALSE}            /* dot_stuffed */
+ .dkim =
+   {.dkim_domain =             NULL,
+    .dkim_identity =           NULL,
+    .dkim_private_key =                NULL,
+    .dkim_selector =           NULL,
+    .dkim_canon =              NULL,
+    .dkim_sign_headers =       NULL,
+    .dkim_strict =             NULL,
+    .dkim_hash =               US"sha256",
+    .dot_stuffed =             FALSE},
 #endif
 };
 
@@ -1018,7 +1024,7 @@ if (is_esmtp && regex_match_and_setup(regex_AUTH, buffer, 0, -1))
     If one is found, attempt to authenticate by calling its client function.
     */
 
-    for (au = auths; !smtp_authenticated && au != NULL; au = au->next)
+    for (au = auths; !smtp_authenticated && au; au = au->next)
       {
       uschar *p = names;
       if (!au->client ||
@@ -1035,7 +1041,7 @@ if (is_esmtp && regex_match_and_setup(regex_AUTH, buffer, 0, -1))
 
       /* Loop to scan supported server mechanisms */
 
-      while (*p != 0)
+      while (*p)
        {
        int rc;
        int len = Ustrlen(au->public_name);
@@ -2504,6 +2510,12 @@ for (addr = sx->first_addr, address_count = 0;
   BOOL no_flush;
   uschar * rcpt_addr;
 
+  if (tcp_out_fastopen && !tcp_out_fastopen_logged)
+    {
+    setflag(addr, af_tcp_fastopen_conn);
+    if (tcp_out_fastopen > 1) setflag(addr, af_tcp_fastopen);
+    }
+
   addr->dsn_aware = sx->peer_offered & OPTION_DSN
     ? dsn_support_yes : dsn_support_no;
 
@@ -2557,6 +2569,7 @@ for (addr = sx->first_addr, address_count = 0;
     }
   }      /* Loop for next address */
 
+tcp_out_fastopen_logged = TRUE;
 sx->next_addr = addr;
 return 0;
 }
@@ -2714,15 +2727,15 @@ address_item *addr;
 int yield = OK;
 int save_errno;
 int rc;
-time_t start_delivery_time = time(NULL);
+struct timeval start_delivery_time;
 
 BOOL pass_message = FALSE;
 uschar *message = NULL;
 uschar new_message_id[MESSAGE_ID_LENGTH + 1];
-uschar *p;
 
 smtp_context sx;
 
+gettimeofday(&start_delivery_time, NULL);
 suppress_tls = suppress_tls;  /* stop compiler warning when no TLS support */
 *message_defer = FALSE;
 
@@ -2889,7 +2902,7 @@ if (!(sx.peer_offered & OPTION_CHUNKING) && !sx.ok)
 else
   {
   transport_ctx tctx = {
-    sx.inblock.sock,
+    {sx.inblock.sock},
     tblock,
     addrlist,
     US".", US"..",    /* Escaping strings */
@@ -3036,10 +3049,11 @@ else
   if (sx.ok)
     {
     int flag = '=';
-    int delivery_time = (int)(time(NULL) - start_delivery_time);
+    struct timeval delivery_time;
     int len;
-    uschar *conf = NULL;
+    uschar * conf = NULL;
 
+    timesince(&delivery_time, &start_delivery_time);
     sx.send_rset = FALSE;
     pipelining_active = FALSE;
 
@@ -3054,7 +3068,7 @@ else
       {
       const uschar *s = string_printing(sx.buffer);
       /* deconst cast ok here as string_printing was checked to have alloc'n'copied */
-      conf = (s == sx.buffer)? (uschar *)string_copy(s) : US s;
+      conf = (s == sx.buffer)? US string_copy(s) : US s;
       }
 
     /* Process all transported addresses - for LMTP or PRDR, read a status for
@@ -3114,14 +3128,15 @@ else
       actual host that was used. */
 
       addr->transport_return = OK;
-      addr->more_errno = delivery_time;
+      addr->more_errno = delivery_time.tv_sec;
+      addr->delivery_usec = delivery_time.tv_usec;
       addr->host_used = host;
       addr->special_action = flag;
       addr->message = conf;
 #ifndef DISABLE_PRDR
-      if (sx.prdr_active) addr->flags |= af_prdr_used;
+      if (sx.prdr_active) setflag(addr, af_prdr_used);
 #endif
-      if (sx.peer_offered & OPTION_CHUNKING) addr->flags |= af_chunking_used;
+      if (sx.peer_offered & OPTION_CHUNKING) setflag(addr, af_chunking_used);
       flag = '-';
 
 #ifndef DISABLE_PRDR
@@ -3138,7 +3153,7 @@ else
         else
           sprintf(CS sx.buffer, "%.500s\n", addr->unique);
 
-        DEBUG(D_deliver) debug_printf("S:journalling %s\n", sx.buffer);
+        DEBUG(D_deliver) debug_printf("S:journalling %s", sx.buffer);
         len = Ustrlen(CS sx.buffer);
         if (write(journal_fd, sx.buffer, len) != len)
           log_write(0, LOG_MAIN|LOG_PANIC, "failed to write journal for "
@@ -3495,10 +3510,10 @@ propagate it from the initial
            if ((pid = fork()))
              {
              DEBUG(D_transport) debug_printf("proxy-prox final-pid %d\n", pid);
-             _exit(pid ? EXIT_FAILURE : EXIT_SUCCESS);
+             _exit(pid < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
              }
            smtp_proxy_tls(sx.buffer, sizeof(sx.buffer), pfd[0], sx.ob->command_timeout);
-           exim_exit(0);
+           exim_exit(0, US"TLS proxy");
            }
          }
 #endif
@@ -4160,7 +4175,7 @@ for (cutoff_retry = 0;
       {
       if (  !host->address
          || host->status != hstatus_unusable_expired
-        || host->last_try > received_time)
+        || host->last_try > received_time.tv_sec)
         continue;
       DEBUG(D_transport) debug_printf("trying expired host %s [%s]%s\n",
           host->name, host->address, pistring);
@@ -4480,7 +4495,7 @@ for (cutoff_retry = 0;
         for (last_rule = retry->rules;
              last_rule->next;
              last_rule = last_rule->next);
-        timedout = time(NULL) - received_time > last_rule->timeout;
+        timedout = time(NULL) - received_time.tv_sec > last_rule->timeout;
         }
       else timedout = TRUE;    /* No rule => timed out */