Move certificate name checking to mainline, default enabled
[exim.git] / src / src / transports / smtp.c
index 6d34922952ae6f0575c33f0f00b11e450506e231..f57ee69d033cf338b85dcaca29c3448080cc5bfa 100644 (file)
@@ -19,6 +19,11 @@ before the lower case letters). Some live in the transport_instance block so as
 to be publicly visible; these are flagged with opt_public. */
 
 optionlist smtp_transport_options[] = {
+  { "*expand_multi_domain",             opt_stringptr | opt_hidden | opt_public,
+      (void *)offsetof(transport_instance, expand_multi_domain) },
+  { "*expand_retry_include_ip_address", opt_stringptr | opt_hidden,
+       (void *)(offsetof(smtp_transport_options_block, expand_retry_include_ip_address)) },
+
   { "address_retry_include_sender", opt_bool,
       (void *)offsetof(smtp_transport_options_block, address_retry_include_sender) },
   { "allow_localhost",      opt_bool,
@@ -142,13 +147,13 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(smtp_transport_options_block, lmtp_ignore_quota) },
   { "max_rcpt",             opt_int | opt_public,
       (void *)offsetof(transport_instance, max_addresses) },
-  { "multi_domain",         opt_bool | opt_public,
+  { "multi_domain",         opt_expand_bool | opt_public,
       (void *)offsetof(transport_instance, multi_domain) },
   { "port",                 opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, port) },
   { "protocol",             opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, protocol) },
-  { "retry_include_ip_address", opt_bool,
+  { "retry_include_ip_address", opt_expand_bool,
       (void *)offsetof(smtp_transport_options_block, retry_include_ip_address) },
   { "serialize_hosts",      opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, serialize_hosts) },
@@ -171,10 +176,8 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(smtp_transport_options_block, tls_tempfail_tryclear) },
   { "tls_try_verify_hosts", opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, tls_try_verify_hosts) },
-#ifdef EXPERIMENTAL_CERTNAMES
   { "tls_verify_cert_hostnames", opt_stringptr,
       (void *)offsetof(smtp_transport_options_block,tls_verify_cert_hostnames)},
-#endif
   { "tls_verify_certificates", opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) },
   { "tls_verify_hosts",     opt_stringptr,
@@ -209,7 +212,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   NULL,                /* hosts_require_dane */
 #endif
 #ifndef DISABLE_PRDR
-  NULL,                /* hosts_try_prdr */
+  US"*",                /* hosts_try_prdr */
 #endif
 #ifndef DISABLE_OCSP
   US"*",               /* hosts_request_ocsp (except under DANE; tls_client_start()) */
@@ -241,6 +244,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   FALSE,               /* hosts_randomize */
   TRUE,                /* keepalive */
   FALSE,               /* lmtp_ignore_quota */
+  NULL,                       /* expand_retry_include_ip_address */
   TRUE                 /* retry_include_ip_address */
 #ifdef SUPPORT_TLS
  ,NULL,                /* tls_certificate */
@@ -256,10 +260,8 @@ smtp_transport_options_block smtp_transport_option_defaults = {
                        /* tls_dh_min_bits */
   TRUE,                /* tls_tempfail_tryclear */
   NULL,                /* tls_verify_hosts */
-  NULL                 /* tls_try_verify_hosts */
-# ifdef EXPERIMENTAL_CERTNAMES
- ,NULL                 /* tls_verify_cert_hostnames */
-# endif
+  NULL,                /* tls_try_verify_hosts */
+  US"*"                /* tls_verify_cert_hostnames */
 #endif
 #ifndef DISABLE_DKIM
  ,NULL,                /* dkim_canon */
@@ -277,7 +279,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
 static int     rf_list[] = {rf_notify_never, rf_notify_success,
                             rf_notify_failure, rf_notify_delay };
 
-static uschar *rf_names[] = { "NEVER", "SUCCESS", "FAILURE", "DELAY" };
+static uschar *rf_names[] = { US"NEVER", US"SUCCESS", US"FAILURE", US"DELAY" };
 #endif
 
 
@@ -640,7 +642,7 @@ msglog_line(host_item * host, uschar * message)
 
 
 
-#ifdef EXPERIMENTAL_TPDA
+#ifdef EXPERIMENTAL_EVENT
 /*************************************************
 *   Post-defer action                            *
 *************************************************/
@@ -656,9 +658,9 @@ Returns:   nothing
 */
 
 static void
-tpda_deferred(address_item *addr, host_item *host)
+deferred_event_raise(address_item *addr, host_item *host)
 {
-uschar * action = addr->transport->tpda_event_action;
+uschar * action = addr->transport->event_action;
 uschar * save_domain;
 uschar * save_local;
 
@@ -670,15 +672,15 @@ save_local = deliver_localpart;
 
 /*XXX would ip & port already be set up? */
 deliver_host_address = string_copy(host->address);
-deliver_host_port =    (host->port == PORT_NONE)? 25 : host->port;
-tpda_defer_errno =     addr->basic_errno;
+deliver_host_port =    host->port == PORT_NONE ? 25 : host->port;
+event_defer_errno =    addr->basic_errno;
 
 router_name =    addr->router->name;
 transport_name = addr->transport->name;
 deliver_domain = addr->domain;
 deliver_localpart = addr->local_part;
 
-(void) tpda_raise_event(action, US"msg:host:defer",
+(void) event_raise(action, US"msg:host:defer",
     addr->message
       ? addr->basic_errno > 0
        ? string_sprintf("%s: %s", addr->message, strerror(addr->basic_errno))
@@ -970,8 +972,7 @@ uschar *fail_reason = US"server did not advertise AUTH support";
 
 smtp_authenticated = FALSE;
 client_authenticator = client_authenticated_id = client_authenticated_sender = NULL;
-require_auth = verify_check_this_host(&(ob->hosts_require_auth), NULL,
-  host->name, host->address, NULL);
+require_auth = verify_check_given_host(&ob->hosts_require_auth, host);
 
 if (is_esmtp && !regex_AUTH) regex_AUTH =
     regex_must_compile(US"\\n250[\\s\\-]AUTH\\s+([\\-\\w\\s]+)(?:\\n|$)",
@@ -986,8 +987,7 @@ if (is_esmtp && regex_match_and_setup(regex_AUTH, buffer, 0, -1))
   regex match above. */
 
   if (require_auth == OK ||
-      verify_check_this_host(&(ob->hosts_try_auth), NULL, host->name,
-       host->address, NULL) == OK)
+      verify_check_given_host(&ob->hosts_try_auth, host) == OK)
     {
     auth_instance *au;
     fail_reason = US"no common mechanisms were found";
@@ -1167,7 +1167,7 @@ return FALSE;
 
 #ifdef EXPERIMENTAL_DANE
 int
-tlsa_lookup(host_item * host, dns_answer * dnsa,
+tlsa_lookup(const host_item * host, dns_answer * dnsa,
   BOOL dane_required, BOOL * dane)
 {
 /* move this out to host.c given the similarity to dns_lookup() ? */
@@ -1231,8 +1231,6 @@ Arguments:
   port            default TCP/IP port to use, in host byte order
   interface       interface to bind to, or NULL
   tblock          transport instance block
-  copy_host       TRUE if host set in addr->host_used must be copied, because
-                    it is specific to this call of the transport
   message_defer   set TRUE if yield is OK, but all addresses were deferred
                     because of a non-recipient, non-host failure, that is, a
                     4xx response to MAIL FROM, DATA, or ".". This is a defer
@@ -1253,7 +1251,7 @@ Returns:          OK    - the connection was made and the delivery attempted;
 
 static int
 smtp_deliver(address_item *addrlist, host_item *host, int host_af, int port,
-  uschar *interface, transport_instance *tblock, BOOL copy_host,
+  uschar *interface, transport_instance *tblock,
   BOOL *message_defer, BOOL suppress_tls)
 {
 address_item *addr;
@@ -1356,8 +1354,8 @@ if (continue_hostname == NULL)
   inblock.sock = outblock.sock =
     smtp_connect(host, host_af, port, interface, ob->connect_timeout,
                  ob->keepalive, ob->dscp
-#ifdef EXPERIMENTAL_TPDA
-                 , tblock->tpda_event_action
+#ifdef EXPERIMENTAL_EVENT
+                 , tblock->event_action
 #endif
                );
 
@@ -1375,14 +1373,12 @@ if (continue_hostname == NULL)
     tls_out.dane_verified = FALSE;
     tls_out.tlsa_usage = 0;
 
-    dane_required = verify_check_this_host(&ob->hosts_require_dane, NULL,
-                             host->name, host->address, NULL) == OK;
+    dane_required = verify_check_given_host(&ob->hosts_require_dane, host) == OK;
 
     if (host->dnssec == DS_YES)
       {
       if(  dane_required
-       || verify_check_this_host(&ob->hosts_try_dane, NULL,
-                             host->name, host->address, NULL) == OK
+       || verify_check_given_host(&ob->hosts_try_dane, host) == OK
        )
        if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK)
          return rc;
@@ -1413,15 +1409,21 @@ if (continue_hostname == NULL)
     if (!smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
       ob->command_timeout)) goto RESPONSE_FAILED;
 
-#ifdef EXPERIMENTAL_TPDA
-    if (tpda_raise_event(tblock->tpda_event_action, US"smtp:connect", buffer)
-       == DEFER)
+#ifdef EXPERIMENTAL_EVENT
+      {
+      uschar * s;
+      lookup_dnssec_authenticated = host->dnssec==DS_YES ? US"yes"
+       : host->dnssec==DS_NO ? US"no" : NULL;
+      s = event_raise(tblock->event_action, US"smtp:connect", buffer);
+      if (s)
        {
-       uschar *message = US"deferred by smtp:connect event expansion";
-       set_errno(addrlist, 0, message, DEFER, FALSE, NULL);
+       set_errno(addrlist, 0,
+         string_sprintf("deferred by smtp:connect event expansion: %s", s),
+         DEFER, FALSE, NULL);
        yield = DEFER;
        goto SEND_QUIT;
        }
+      }
 #endif
 
     /* Now check if the helo_data expansion went well, and sign off cleanly if
@@ -1472,8 +1474,7 @@ goto SEND_QUIT;
   mailers use upper case for some reason (the RFC is quite clear about case
   independence) so, for peace of mind, I gave in. */
 
-  esmtp = verify_check_this_host(&(ob->hosts_avoid_esmtp), NULL,
-     host->name, host->address, NULL) != OK;
+  esmtp = verify_check_given_host(&ob->hosts_avoid_esmtp, host) != OK;
 
   /* Alas; be careful, since this goto is not an error-out, so conceivably
   we might set data between here and the target which we assume to exist
@@ -1531,11 +1532,10 @@ goto SEND_QUIT;
 #endif
 
 #ifndef DISABLE_PRDR
-  prdr_offered = esmtp &&
-    (pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(buffer), 0,
-      PCRE_EOPT, NULL, 0) >= 0) &&
-    (verify_check_this_host(&(ob->hosts_try_prdr), NULL, host->name,
-      host->address, NULL) == OK);
+  prdr_offered = esmtp
+    && pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(buffer), 0,
+                 PCRE_EOPT, NULL, 0) >= 0
+    && verify_check_given_host(&ob->hosts_try_prdr, host) == OK;
 
   if (prdr_offered)
     {DEBUG(D_transport) debug_printf("PRDR usable\n");}
@@ -1565,9 +1565,9 @@ the client not be required to use TLS. If the response is bad, copy the buffer
 for error analysis. */
 
 #ifdef SUPPORT_TLS
-if (tls_offered && !suppress_tls &&
-      verify_check_this_host(&(ob->hosts_avoid_tls), NULL, host->name,
-        host->address, NULL) != OK)
+if (  tls_offered
+   && !suppress_tls
+   && verify_check_given_host(&ob->hosts_avoid_tls, host) != OK)
   {
   uschar buffer2[4096];
   if (smtp_write_command(&outblock, FALSE, "STARTTLS\r\n") < 0)
@@ -1685,8 +1685,7 @@ else if (
 # ifdef EXPERIMENTAL_DANE
        dane ||
 # endif
-        verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
-            host->address, NULL) == OK
+        verify_check_given_host(&ob->hosts_require_tls, host) == OK
        )
   {
   save_errno = ERRNO_TLSREQUIRED;
@@ -1726,21 +1725,19 @@ if (continue_hostname == NULL
   the current host, esmtp will be false, so PIPELINING can never be used. If
   the current host matches hosts_avoid_pipelining, don't do it. */
 
-  smtp_use_pipelining = esmtp &&
-    verify_check_this_host(&(ob->hosts_avoid_pipelining), NULL, host->name,
-      host->address, NULL) != OK &&
-    pcre_exec(regex_PIPELINING, NULL, CS buffer, Ustrlen(CS buffer), 0,
-      PCRE_EOPT, NULL, 0) >= 0;
+  smtp_use_pipelining = esmtp
+    && verify_check_given_host(&ob->hosts_avoid_pipelining, host) != OK
+    && pcre_exec(regex_PIPELINING, NULL, CS buffer, Ustrlen(CS buffer), 0,
+                 PCRE_EOPT, NULL, 0) >= 0;
 
   DEBUG(D_transport) debug_printf("%susing PIPELINING\n",
     smtp_use_pipelining? "" : "not ");
 
 #ifndef DISABLE_PRDR
-  prdr_offered = esmtp &&
-    pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(CS buffer), 0,
-      PCRE_EOPT, NULL, 0) >= 0 &&
-    verify_check_this_host(&(ob->hosts_try_prdr), NULL, host->name,
-      host->address, NULL) == OK;
+  prdr_offered = esmtp
+    && pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(CS buffer), 0,
+      PCRE_EOPT, NULL, 0) >= 0
+    && verify_check_given_host(&ob->hosts_try_prdr, host) == OK;
 
   if (prdr_offered)
     {DEBUG(D_transport) debug_printf("PRDR usable\n");}
@@ -1865,12 +1862,12 @@ if ((smtp_use_dsn) && (dsn_all_lasthop == FALSE))
   {
   if (dsn_ret == dsn_ret_hdrs)
     {
-    strcpy(p, " RET=HDRS");
+    Ustrcpy(p, " RET=HDRS");
     while (*p) p++;
     }
   else if (dsn_ret == dsn_ret_full)
     {
-    strcpy(p, " RET=FULL");
+    Ustrcpy(p, " RET=FULL");
     while (*p) p++;
     }
   if (dsn_envid != NULL)
@@ -1967,14 +1964,14 @@ for (addr = first_addr;
       {
       int i;
       BOOL first = TRUE;
-      strcpy(p, " NOTIFY=");
+      Ustrcpy(p, " NOTIFY=");
       while (*p) p++;
       for (i = 0; i < 4; i++)
         if ((addr->dsn_flags & rf_list[i]) != 0)
           {
           if (!first) *p++ = ',';
           first = FALSE;
-          strcpy(p, rf_names[i]);
+          Ustrcpy(p, rf_names[i]);
           while (*p) p++;
           }
       }
@@ -2199,26 +2196,13 @@ if (!ok) ok = TRUE; else
     int flag = '=';
     int delivery_time = (int)(time(NULL) - start_delivery_time);
     int len;
-    host_item *thost;
     uschar *conf = NULL;
     send_rset = FALSE;
 
-    /* Make a copy of the host if it is local to this invocation
-    of the transport. */
-
-    if (copy_host)
-      {
-      thost = store_get(sizeof(host_item));
-      *thost = *host;
-      thost->name = string_copy(host->name);
-      thost->address = string_copy(host->address);
-      }
-    else thost = host;
-
     /* Set up confirmation if needed - applies only to SMTP */
 
     if (
-#ifndef EXPERIMENTAL_TPDA
+#ifndef EXPERIMENTAL_EVENT
           (log_extra_selector & LX_smtp_confirmation) != 0 &&
 #endif
           !lmtp
@@ -2285,7 +2269,7 @@ if (!ok) ok = TRUE; else
 
       addr->transport_return = OK;
       addr->more_errno = delivery_time;
-      addr->host_used = thost;
+      addr->host_used = host;
       addr->special_action = flag;
       addr->message = conf;
 #ifndef DISABLE_PRDR
@@ -2540,15 +2524,15 @@ DEBUG(D_transport)
 if (completed_address && ok && send_quit)
   {
   BOOL more;
-  if (first_addr != NULL || continue_more ||
-        (
-           (tls_out.active < 0 ||
-           verify_check_this_host(&(ob->hosts_nopass_tls), NULL, host->name,
-             host->address, NULL) != OK)
+  if (  first_addr != NULL
+     || continue_more
+     || (  (  tls_out.active < 0
+           || verify_check_given_host(&ob->hosts_nopass_tls, host) != OK
+          )
         &&
            transport_check_waiting(tblock->name, host->name,
              tblock->connection_max_messages, new_message_id, &more)
-        ))
+     )  )
     {
     uschar *msg;
     BOOL pass_message;
@@ -2659,8 +2643,8 @@ case continue_more won't get set. */
 
 (void)close(inblock.sock);
 
-#ifdef EXPERIMENTAL_TPDA
-(void) tpda_raise_event(tblock->tpda_event_action, US"tcp:close", NULL);
+#ifdef EXPERIMENTAL_EVENT
+(void) event_raise(tblock->event_action, US"tcp:close", NULL);
 #endif
 
 continue_transport = NULL;
@@ -2847,8 +2831,7 @@ if (hostlist == NULL || (ob->hosts_override && ob->hosts != NULL))
 
     if (Ustrchr(s, '$') != NULL)
       {
-      expanded_hosts = expand_string(s);
-      if (expanded_hosts == NULL)
+      if (!(expanded_hosts = expand_string(s)))
         {
         addrlist->message = string_sprintf("failed to expand list of hosts "
           "\"%s\" in %s transport: %s", s, tblock->name, expand_string_message);
@@ -2876,7 +2859,7 @@ if (hostlist == NULL || (ob->hosts_override && ob->hosts != NULL))
     /* If there was no expansion of hosts, save the host list for
     next time. */
 
-    if (expanded_hosts == NULL) ob->hostlist = hostlist;
+    if (!expanded_hosts) ob->hostlist = hostlist;
     }
 
   /* This is not the first time this transport has been run in this delivery;
@@ -3188,14 +3171,20 @@ for (cutoff_retry = 0; expired &&
 
     if (cutoff_retry == 0)
       {
+      BOOL incl_ip;
       /* Ensure the status of the address is set by checking retry data if
-      necessary. There maybe host-specific retry data (applicable to all
+      necessary. There may be host-specific retry data (applicable to all
       messages) and also data for retries of a specific message at this host.
       If either of these retry records are actually read, the keys used are
       returned to save recomputing them later. */
 
+      if (exp_bool(addrlist, US"transport", tblock->name, D_transport,
+               US"retry_include_ip_address", ob->retry_include_ip_address,
+               ob->expand_retry_include_ip_address, &incl_ip) != OK)
+       continue;       /* with next host */
+
       host_is_expired = retry_check_address(addrlist->domain, host, pistring,
-        ob->retry_include_ip_address, &retry_host_key, &retry_message_key);
+        incl_ip, &retry_host_key, &retry_message_key);
 
       DEBUG(D_transport) debug_printf("%s [%s]%s status = %s\n", host->name,
         (host->address == NULL)? US"" : host->address, pistring,
@@ -3258,8 +3247,7 @@ for (cutoff_retry = 0; expired &&
     sending the message down a pre-existing connection. */
 
     if (!continuing &&
-        verify_check_this_host(&(ob->serialize_hosts), NULL, host->name,
-          host->address, NULL) == OK)
+        verify_check_given_host(&ob->serialize_hosts, host) == OK)
       {
       serialize_key = string_sprintf("host-serialize-%s", host->name);
       if (!enq_start(serialize_key))
@@ -3329,6 +3317,20 @@ for (cutoff_retry = 0; expired &&
 
     else
       {
+      host_item * thost;
+      /* Make a copy of the host if it is local to this invocation
+       of the transport. */
+
+      if (expanded_hosts)
+       {
+       thost = store_get(sizeof(host_item));
+       *thost = *host;
+       thost->name = string_copy(host->name);
+       thost->address = string_copy(host->address);
+       }
+      else
+        thost = host;
+
       if (!host_is_expired && ++unexpired_hosts_tried >= ob->hosts_max_try)
         {
         host_item *h;
@@ -3348,8 +3350,8 @@ for (cutoff_retry = 0; expired &&
       /* Attempt the delivery. */
 
       total_hosts_tried++;
-      rc = smtp_deliver(addrlist, host, host_af, port, interface, tblock,
-        expanded_hosts != NULL, &message_defer, FALSE);
+      rc = smtp_deliver(addrlist, thost, host_af, port, interface, tblock,
+        &message_defer, FALSE);
 
       /* Yield is one of:
          OK     => connection made, each address contains its result;
@@ -3370,9 +3372,9 @@ for (cutoff_retry = 0; expired &&
                          first_addr->basic_errno != ERRNO_TLSFAILURE)
         write_logs(first_addr, host);
 
-#ifdef EXPERIMENTAL_TPDA
+#ifdef EXPERIMENTAL_EVENT
       if (rc == DEFER)
-        tpda_deferred(first_addr, host);
+        deferred_event_raise(first_addr, host);
 #endif
 
       /* If STARTTLS was accepted, but there was a failure in setting up the
@@ -3388,20 +3390,19 @@ for (cutoff_retry = 0; expired &&
       if (  rc == DEFER
         && first_addr->basic_errno == ERRNO_TLSFAILURE
         && ob->tls_tempfail_tryclear
-        && verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
-             host->address, NULL) != OK
+        && verify_check_given_host(&ob->hosts_require_tls, host) != OK
         )
         {
         log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted "
           "to %s [%s] (not in hosts_require_tls)", host->name, host->address);
         first_addr = prepare_addresses(addrlist, host);
-        rc = smtp_deliver(addrlist, host, host_af, port, interface, tblock,
-          expanded_hosts != NULL, &message_defer, TRUE);
+        rc = smtp_deliver(addrlist, thost, host_af, port, interface, tblock,
+          &message_defer, TRUE);
         if (rc == DEFER && first_addr->basic_errno != ERRNO_AUTHFAIL)
           write_logs(first_addr, host);
-# ifdef EXPERIMENTAL_TPDA
+# ifdef EXPERIMENTAL_EVENT
         if (rc == DEFER)
-          tpda_deferred(first_addr, host);
+          deferred_event_raise(first_addr, host);
 # endif
         }
 #endif /*SUPPORT_TLS*/
@@ -3433,7 +3434,13 @@ for (cutoff_retry = 0; expired &&
       int delete_flag = (rc != DEFER)? rf_delete : 0;
       if (retry_host_key == NULL)
         {
-        retry_host_key = ob->retry_include_ip_address?
+       BOOL incl_ip;
+       if (exp_bool(addrlist, US"transport", tblock->name, D_transport,
+                 US"retry_include_ip_address", ob->retry_include_ip_address,
+                 ob->expand_retry_include_ip_address, &incl_ip) != OK)
+         incl_ip = TRUE;       /* error; use most-specific retry record */
+
+        retry_host_key = incl_ip ?
           string_sprintf("T:%S:%s%s", host->name, host->address, pistring) :
           string_sprintf("T:%S%s", host->name, pistring);
         }
@@ -3475,7 +3482,13 @@ for (cutoff_retry = 0; expired &&
       int delete_flag = message_defer? 0 : rf_delete;
       if (retry_message_key == NULL)
         {
-        retry_message_key = ob->retry_include_ip_address?
+       BOOL incl_ip;
+       if (exp_bool(addrlist, US"transport", tblock->name, D_transport,
+                 US"retry_include_ip_address", ob->retry_include_ip_address,
+                 ob->expand_retry_include_ip_address, &incl_ip) != OK)
+         incl_ip = TRUE;       /* error; use most-specific retry record */
+
+        retry_message_key = incl_ip ?
           string_sprintf("T:%S:%s%s:%s", host->name, host->address, pistring,
             message_id) :
           string_sprintf("T:%S%s:%s", host->name, pistring, message_id);