Bugzilla #2: If the last fallback host listed was multihomed, only its
[exim.git] / src / src / transports / smtp.c
index a756f81db7fa8b208d64ce3d8deb72acc03d6dd5..edcdc409d799fe0482ae8059c572d3e23fdf0aec 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/smtp.c,v 1.5 2005/01/11 15:51:03 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/smtp.c,v 1.8 2005/03/22 15:45:35 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -35,6 +35,20 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(smtp_transport_options_block, data_timeout) },
   { "delay_after_cutoff", opt_bool,
       (void *)offsetof(smtp_transport_options_block, delay_after_cutoff) },
+#ifdef EXPERIMENTAL_DOMAINKEYS
+  { "dk_canon", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, dk_canon) },
+  { "dk_domain", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, dk_domain) },
+  { "dk_headers", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, dk_headers) },
+  { "dk_private_key", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, dk_private_key) },
+  { "dk_selector", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, dk_selector) },
+  { "dk_strict", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, dk_strict) },
+#endif
   { "dns_qualify_single",   opt_bool,
       (void *)offsetof(smtp_transport_options_block, dns_qualify_single) },
   { "dns_search_parents",   opt_bool,
@@ -140,7 +154,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   10*60,               /* final timeout */
   1024,                /* size_addition */
   5,                   /* hosts_max_try */
-  50,                  /* hosts_max_try_hardlimit */ 
+  50,                  /* hosts_max_try_hardlimit */
   FALSE,               /* allow_localhost */
   FALSE,               /* gethostbyname */
   TRUE,                /* dns_qualify_single */
@@ -158,6 +172,14 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   NULL,                /* tls_verify_certificates */
   TRUE                 /* tls_tempfail_tryclear */
   #endif
+  #ifdef EXPERIMENTAL_DOMAINKEYS
+ ,NULL,                /* dk_canon */
+  NULL,                /* dk_domain */
+  NULL,                /* dk_headers */
+  NULL,                /* dk_private_key */
+  NULL,                /* dk_selector */
+  NULL                 /* dk_strict */
+  #endif
 };
 
 
@@ -393,7 +415,7 @@ end the DATA. */
 if (*errno_value == ERRNO_FILTER_FAIL)
   {
   *message = US string_sprintf("transport filter process failed (%d)%s",
-    more_errno, 
+    more_errno,
     (more_errno == EX_EXECFAILED)? ": unable to execute command" : "");
   return FALSE;
   }
@@ -1394,6 +1416,23 @@ if (!ok) ok = TRUE; else
   DEBUG(D_transport|D_v)
     debug_printf("  SMTP>> writing message and terminating \".\"\n");
   transport_count = 0;
+#ifdef EXPERIMENTAL_DOMAINKEYS
+  if ( (ob->dk_private_key != NULL) && (ob->dk_selector != NULL) )
+    ok = dk_transport_write_message(addrlist, inblock.sock,
+      topt_use_crlf | topt_end_dot | topt_escape_headers |
+        (tblock->body_only? topt_no_headers : 0) |
+        (tblock->headers_only? topt_no_body : 0) |
+        (tblock->return_path_add? topt_add_return_path : 0) |
+        (tblock->delivery_date_add? topt_add_delivery_date : 0) |
+        (tblock->envelope_to_add? topt_add_envelope_to : 0),
+      0,            /* No size limit */
+      tblock->add_headers, tblock->remove_headers,
+      US".", US"..",    /* Escaping strings */
+      tblock->rewrite_rules, tblock->rewrite_existflags,
+      ob->dk_private_key, ob->dk_domain, ob->dk_selector,
+      ob->dk_canon, ob->dk_headers, ob->dk_strict);
+  else
+#endif
   ok = transport_write_message(addrlist, inblock.sock,
     topt_use_crlf | topt_end_dot | topt_escape_headers |
       (tblock->body_only? topt_no_headers : 0) |
@@ -1929,7 +1968,7 @@ int hosts_looked_up = 0;
 int hosts_retry = 0;
 int hosts_serial = 0;
 int hosts_total = 0;
-int total_hosts_tried = 0; 
+int total_hosts_tried = 0;
 address_item *addr;
 BOOL expired = TRUE;
 BOOL continuing = continue_hostname != NULL;
@@ -2096,8 +2135,8 @@ if (Ustrcmp(pistring, ":25") == 0) pistring = US"";
 .  If there are any addresses whose status is still DEFER, carry on to the
    next host/IPaddress, unless we have tried the number of hosts given
    by hosts_max_try or hosts_max_try_hardlimit; otherwise return. Note that
-   there is some fancy logic for hosts_max_try that means its limit can be 
-   overstepped in some circumstances. 
+   there is some fancy logic for hosts_max_try that means its limit can be
+   overstepped in some circumstances.
 
 If we get to the end of the list, all hosts have deferred at least one address,
 or not reached their retry times. If delay_after_cutoff is unset, it requests a
@@ -2114,7 +2153,7 @@ for (cutoff_retry = 0; expired &&
   int unexpired_hosts_tried = 0;
 
   for (host = hostlist;
-       host != NULL && 
+       host != NULL &&
          unexpired_hosts_tried < ob->hosts_max_try &&
          total_hosts_tried < ob->hosts_max_try_hardlimit;
        host = nexthost)
@@ -2133,11 +2172,6 @@ for (cutoff_retry = 0; expired &&
     uschar *retry_message_key = NULL;
     uschar *serialize_key = NULL;
 
-    /* Default next host is next host. :-) But this can vary if the
-    hosts_max_try limit is hit (see below). */
-
-    nexthost = host->next;
-
     /* Set the flag requesting that this host be added to the waiting
     database if the delivery fails temporarily or if we are running with
     queue_smtp or a 2-stage queue run. This gets unset for certain
@@ -2244,6 +2278,13 @@ for (cutoff_retry = 0; expired &&
       continue;      /* With next host */
       }
 
+    /* The default next host is the next host. :-) But this can vary if the
+    hosts_max_try limit is hit (see below). NOTE: we cannot put this setting
+    earlier than this, because a multihomed host whose addresses are not looked
+    up till just above will add to the host list. */
+
+    nexthost = host->next;
+
     /* If queue_smtp is set (-odqs or the first part of a 2-stage run), or the
     domain is in queue_smtp_domains, we don't actually want to attempt any
     deliveries. When doing a queue run, queue_smtp_domains is always unset. If
@@ -2421,9 +2462,9 @@ for (cutoff_retry = 0; expired &&
 
     /* This is for real. If the host is expired, we don't count it for
     hosts_max_retry. This ensures that all hosts must expire before an address
-    is timed out, unless hosts_max_try_hardlimit (which protects against 
+    is timed out, unless hosts_max_try_hardlimit (which protects against
     lunatic DNS configurations) is reached.
-    
+
     If the host is not expired and we are about to hit the hosts_max_retry
     limit, check to see if there is a subsequent hosts with a different MX
     value. If so, make that the next host, and don't count this one. This is a
@@ -2686,7 +2727,7 @@ for (addr = addrlist; addr != NULL; addr = addr->next)
   because of hosts_max_try or hosts_max_try_hardlimit. In the former case, this
   means we need to behave as if some hosts were skipped because their retry
   time had not come. Specifically, this prevents the address from timing out.
-  However, if we have hit hosts_max_try_hardlimit, we want to behave as if all 
+  However, if we have hit hosts_max_try_hardlimit, we want to behave as if all
   hosts were tried. */
 
   if (host != NULL)
@@ -2698,11 +2739,11 @@ for (addr = addrlist; addr != NULL; addr = addr->next)
           "hosts were tried\n");
       }
     else
-      {       
+      {
       DEBUG(D_transport)
         debug_printf("hosts_max_try limit caused some hosts to be skipped\n");
       setflag(addr, af_retry_skipped);
-      } 
+      }
     }
 
   if (queue_smtp)    /* no deliveries attempted */