Provide readn() as a wrapper around read()
[exim.git] / src / src / smtp_in.c
index 3d5ad863f7d4e41228cd56b891f44667887c262e..36f6856772d0b02f74e2041c6e8b8986b3732fa8 100644 (file)
@@ -339,8 +339,10 @@ int fd, rc;
 fd_set fds;
 struct timeval tzero;
 
+#ifdef SUPPORT_TLS
 if (tls_in.active >= 0)
  return !tls_could_read();
+#endif
 
 if (smtp_inptr < smtp_inend)
   return FALSE;
@@ -1796,10 +1798,9 @@ for (i = 0; i < smtp_ch_index; i++)
   }
 
 if (s) s[ptr] = 0; else s = US"";
-log_write(0, LOG_MAIN, "no MAIL in SMTP connection from %s D=%s%s",
-  host_and_ident(FALSE),
-  readconf_printtime( (int) ((long)time(NULL) - (long)smtp_connection_start)),
-  s);
+log_write(0, LOG_MAIN, "no MAIL in %sSMTP connection from %s D=%s%s",
+  tcp_in_fastopen ? US"TFO " : US"",
+  host_and_ident(FALSE), string_timesince(&smtp_connection_start), s);
 }
 
 
@@ -1941,17 +1942,17 @@ while (v > smtp_cmd_data && *v != '=' && !isspace(*v))
 
 n = v;
 if (*v == '=')
-{
+  {
   while(isalpha(n[-1])) n--;
   /* RFC says SP, but TAB seen in wild and other major MTAs accept it */
   if (!isspace(n[-1])) return FALSE;
   n[-1] = 0;
-}
+  }
 else
-{
+  {
   n++;
   if (v == smtp_cmd_data) return FALSE;
-}
+  }
 *v++ = 0;
 *name = n;
 *value = v;
@@ -2331,6 +2332,28 @@ return FALSE;
 }
 
 
+
+
+#ifdef TCP_FASTOPEN
+static void
+tfo_in_check(void)
+{
+# ifdef TCP_INFO
+struct tcp_info tinfo;
+socklen_t len = sizeof(tinfo);
+
+if (  getsockopt(fileno(smtp_out), IPPROTO_TCP, TCP_INFO, &tinfo, &len) == 0
+   && tinfo.tcpi_state == TCP_SYN_RECV
+   )
+  {
+  DEBUG(D_receive) debug_printf("TCP_FASTOPEN mode connection\n");
+  tcp_in_fastopen = TRUE;
+  }
+# endif
+}
+#endif
+
+
 /*************************************************
 *          Start an SMTP session                 *
 *************************************************/
@@ -2353,7 +2376,7 @@ uschar *user_msg, *log_msg;
 uschar *code, *esc;
 uschar *p, *s, *ss;
 
-smtp_connection_start = time(NULL);
+gettimeofday(&smtp_connection_start, NULL);
 for (smtp_ch_index = 0; smtp_ch_index < SMTP_HBUFF_SIZE; smtp_ch_index++)
   smtp_connection_had[smtp_ch_index] = SCH_NONE;
 smtp_ch_index = 0;
@@ -2420,7 +2443,7 @@ else
 /* Set up the buffer for inputting using direct read() calls, and arrange to
 call the local functions instead of the standard C ones. */
 
-if (!(smtp_inbuffer = (uschar *)malloc(IN_BUFFER_SIZE)))
+if (!(smtp_inbuffer = US malloc(IN_BUFFER_SIZE)))
   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malloc() failed for SMTP input buffer");
 
 receive_getc = smtp_getc;
@@ -2526,7 +2549,7 @@ if (!sender_host_unknown)
 
     DEBUG(D_receive) debug_printf("checking for IP options\n");
 
-    if (getsockopt(fileno(smtp_out), IPPROTO_IP, IP_OPTIONS, (uschar *)(ipopt),
+    if (getsockopt(fileno(smtp_out), IPPROTO_IP, IP_OPTIONS, US (ipopt),
           &optlen) < 0)
       {
       if (errno != ENOPROTOOPT)
@@ -2552,11 +2575,11 @@ if (!sender_host_unknown)
       struct in_addr addr;
 
       #if OPTSTYLE == 1
-      uschar *optstart = (uschar *)(ipopt->__data);
+      uschar *optstart = US (ipopt->__data);
       #elif OPTSTYLE == 2
-      uschar *optstart = (uschar *)(ipopt->ip_opts);
+      uschar *optstart = US (ipopt->ip_opts);
       #else
-      uschar *optstart = (uschar *)(ipopt->ipopt_list);
+      uschar *optstart = US (ipopt->ipopt_list);
       #endif
 
       DEBUG(D_receive) debug_printf("IP options exist\n");
@@ -2565,7 +2588,7 @@ if (!sender_host_unknown)
       p += Ustrlen(p);
 
       for (opt = optstart; opt != NULL &&
-           opt < (uschar *)(ipopt) + optlen;)
+           opt < US (ipopt) + optlen;)
         {
         switch (*opt)
           {
@@ -2923,6 +2946,14 @@ if (!check_sync())
 /* Now output the banner */
 
 smtp_printf("%s", FALSE, ss);
+
+/* Attempt to see if we sent the banner before the last ACK of the 3-way
+handshake arrived.  If so we must have managed a TFO. */
+
+#ifdef TCP_FASTOPEN
+tfo_in_check();
+#endif
+
 return TRUE;
 }
 
@@ -5459,15 +5490,22 @@ while (done <= 0)
     just drop the call rather than sending QUIT, and it clutters up the logs.
     */
 
-    if (sender_address != NULL || recipients_count > 0)
-      log_write(L_lost_incoming_connection,
-          LOG_MAIN,
-          "unexpected %s while reading SMTP command from %s%s",
-          sender_host_unknown? "EOF" : "disconnection",
-          host_and_ident(FALSE), smtp_read_error);
+    if (sender_address || recipients_count > 0)
+      log_write(L_lost_incoming_connection, LOG_MAIN,
+       "unexpected %s while reading SMTP command from %s%s%s D=%s",
+       sender_host_unknown ? "EOF" : "disconnection",
+       tcp_in_fastopen && !tcp_in_fastopen_logged ? US"TFO " : US"",
+       host_and_ident(FALSE), smtp_read_error,
+       string_timesince(&smtp_connection_start)
+       );
 
-    else log_write(L_smtp_connection, LOG_MAIN, "%s lost%s",
-      smtp_get_connection_info(), smtp_read_error);
+    else
+      log_write(L_smtp_connection, LOG_MAIN, "%s %slost%s D=%s",
+        smtp_get_connection_info(),
+       tcp_in_fastopen && !tcp_in_fastopen_logged ? US"TFO " : US"",
+       smtp_read_error,
+       string_timesince(&smtp_connection_start)
+       );
 
     done = 1;
     break;