Fix identd connections on FreeBSD under TCP Fast Open
[exim.git] / src / src / verify.c
index a9ec730d10720de07489d111d14bdf16d8e20062..5c093bf31ca087f611454755327df700ae186058 100644 (file)
@@ -2682,8 +2682,11 @@ if (ip_bind(sock, host_af, interface_address, 0) < 0)
   goto END_OFF;
   }
 
+/*XXX could take advantage of TFO early-data.  Hmm, what are the
+error returns; can we differentiate connect from data fails?
+Do we need to? */
 if (ip_connect(sock, host_af, sender_host_address, port,
-               rfc1413_query_timeout, TRUE) < 0)
+               rfc1413_query_timeout, &tcp_fastopen_nodata) < 0)
   {
   if (errno == ETIMEDOUT && LOGGING(ident_timeout))
     log_write(0, LOG_MAIN, "ident connection to %s timed out",
@@ -2699,10 +2702,24 @@ if (ip_connect(sock, host_af, sender_host_address, port,
 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;
-  }
+  if (errno == ENOTCONN)       /* seen for TFO on FreeBSD */
+    {
+    struct timeval tv = { .tv_sec = 0, .tv_usec = 500*1000 };
+    fd_set s;
+
+    FD_ZERO(&s); FD_SET(sock, &s);
+    (void) select(sock+1, NULL,  (SELECT_ARG2_TYPE *)&s, (SELECT_ARG2_TYPE *)&s, &tv);
+    if (send(sock, buffer, qlen, 0) < 0)
+      {
+      DEBUG(D_ident) debug_printf("ident re-send failed: %s\n", strerror(errno));
+      goto END_OFF;
+      }
+    }
+  else
+    {
+    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 +3171,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,