Cutthrough: fix multi-message initiating connections. Bug 2230
[exim.git] / src / src / verify.c
index a9ec730d10720de07489d111d14bdf16d8e20062..dd54518480fbc8962588064aa9fa126dd78a16b4 100644 (file)
@@ -1380,6 +1380,7 @@ if(fd >= 0)
   _cutthrough_puts(US"QUIT\r\n", 6);   /* avoid recursion */
   _cutthrough_flush_send();
   cutthrough.fd = -1;                  /* avoid recursion via read timeout */
+  cutthrough.nrcpt = 0;                        /* permit re-cutthrough on subsequent message */
 
   /* Wait a short time for response, and discard it */
   cutthrough_response(fd, '2', NULL, 1);
@@ -2165,7 +2166,7 @@ return yield;
 *************************************************/
 
 /* This function checks those header lines that contain addresses, and verifies
-that all the addresses therein are syntactially correct.
+that all the addresses therein are 5322-syntactially correct.
 
 Arguments:
   msgptr     where to put an error message
@@ -2181,7 +2182,7 @@ header_line *h;
 uschar *colon, *s;
 int yield = OK;
 
-for (h = header_list; h != NULL && yield == OK; h = h->next)
+for (h = header_list; h && yield == OK; h = h->next)
   {
   if (h->type != htype_from &&
       h->type != htype_reply_to &&
@@ -2200,7 +2201,7 @@ for (h = header_list; h != NULL && yield == OK; h = h->next)
 
   parse_allow_group = TRUE;
 
-  while (*s != 0)
+  while (*s)
     {
     uschar *ss = parse_find_address_end(s, FALSE);
     uschar *recipient, *errmess;
@@ -2217,7 +2218,7 @@ for (h = header_list; h != NULL && yield == OK; h = h->next)
     /* Permit an unqualified address only if the message is local, or if the
     sending host is configured to be permitted to send them. */
 
-    if (recipient != NULL && domain == 0)
+    if (recipient && !domain)
       {
       if (h->type == htype_from || h->type == htype_sender)
         {
@@ -2233,7 +2234,7 @@ for (h = header_list; h != NULL && yield == OK; h = h->next)
     /* It's an error if no address could be extracted, except for the special
     case of an empty address. */
 
-    if (recipient == NULL && Ustrcmp(errmess, "empty address") != 0)
+    if (!recipient && Ustrcmp(errmess, "empty address") != 0)
       {
       uschar *verb = US"is";
       uschar *t = ss;
@@ -2263,7 +2264,7 @@ for (h = header_list; h != NULL && yield == OK; h = h->next)
       /* deconst cast ok as we're passing a non-const to string_printing() */
       *msgptr = US string_printing(
         string_sprintf("%s: failing address in \"%.*s:\" header %s: %.*s",
-          errmess, tt - h->text, h->text, verb, len, s));
+          errmess, (int)(tt - h->text), h->text, verb, len, s));
 
       yield = FAIL;
       break;          /* Out of address loop */
@@ -2271,7 +2272,7 @@ for (h = header_list; h != NULL && yield == OK; h = h->next)
 
     /* Advance to the next address */
 
-    s = ss + (terminator? 1:0);
+    s = ss + (terminator ? 1 : 0);
     while (isspace(*s)) s++;
     }   /* Next address */
 
@@ -2564,7 +2565,7 @@ for (i = 0; i < 3 && !done; i++)
           while (ss > s && isspace(ss[-1])) ss--;
           *log_msgptr = string_sprintf("syntax error in '%.*s' header when "
             "scanning for sender: %s in \"%.*s\"",
-            endname - h->text, h->text, *log_msgptr, ss - s, s);
+            (int)(endname - h->text), h->text, *log_msgptr, (int)(ss - s), s);
           yield = FAIL;
           done = TRUE;
           break;
@@ -2592,11 +2593,9 @@ for (i = 0; i < 3 && !done; i++)
         {
         *verrno = vaddr->basic_errno;
         if (smtp_return_error_details)
-          {
           *user_msgptr = string_sprintf("Rejected after DATA: "
             "could not verify \"%.*s\" header address\n%s: %s",
-            endname - h->text, h->text, vaddr->address, vaddr->message);
-          }
+            (int)(endname - h->text), h->text, vaddr->address, vaddr->message);
         }
 
       /* Success or defer */
@@ -2657,6 +2656,7 @@ verify_get_ident(int port)
 int sock, host_af, qlen;
 int received_sender_port, received_interface_port, n;
 uschar *p;
+blob early_data;
 uschar buffer[2048];
 
 /* Default is no ident. Check whether we want to do an ident check for this
@@ -2682,8 +2682,15 @@ if (ip_bind(sock, host_af, interface_address, 0) < 0)
   goto END_OFF;
   }
 
+/* Construct and send the query. */
+
+qlen = snprintf(CS buffer, sizeof(buffer), "%d , %d\r\n",
+  sender_host_port, interface_port);
+early_data.data = buffer;
+early_data.len = qlen;
+
 if (ip_connect(sock, host_af, sender_host_address, port,
-               rfc1413_query_timeout, TRUE) < 0)
+               rfc1413_query_timeout, &early_data) < 0)
   {
   if (errno == ETIMEDOUT && LOGGING(ident_timeout))
     log_write(0, LOG_MAIN, "ident connection to %s timed out",
@@ -2694,16 +2701,6 @@ if (ip_connect(sock, host_af, sender_host_address, port,
   goto END_OFF;
   }
 
-/* Construct and send the query. */
-
-sprintf(CS buffer, "%d , %d\r\n", sender_host_port, interface_port);
-qlen = Ustrlen(buffer);
-if (send(sock, buffer, qlen, 0) < 0)
-  {
-  DEBUG(D_ident) debug_printf("ident send failed: %s\n", strerror(errno));
-  goto END_OFF;
-  }
-
 /* Read a response line. We put it into the rest of the buffer, using several
 recv() calls if necessary. */
 
@@ -3154,18 +3151,16 @@ verify_check_this_host(const uschar **listptr, unsigned int *cache_bits,
 int rc;
 unsigned int *local_cache_bits = cache_bits;
 const uschar *save_host_address = deliver_host_address;
-check_host_block cb;
-cb.host_name = host_name;
-cb.host_address = host_address;
+check_host_block cb = { .host_name = host_name, .host_address = host_address };
 
-if (valueptr != NULL) *valueptr = NULL;
+if (valueptr) *valueptr = NULL;
 
 /* If the host address starts off ::ffff: it is an IPv6 address in
 IPv4-compatible mode. Find the IPv4 part for checking against IPv4
 addresses. */
 
-cb.host_ipv4 = (Ustrncmp(host_address, "::ffff:", 7) == 0)?
-  host_address + 7 : host_address;
+cb.host_ipv4 = Ustrncmp(host_address, "::ffff:", 7) == 0
+  host_address + 7 : host_address;
 
 /* During the running of the check, put the IP address into $host_address. In
 the case of calls from the smtp transport, it will already be there. However,