Fix Mac build
[exim.git] / src / src / ip.c
index ee91293fafece78926e8faba4d19a35cc3deff31..ef133bf9f0bd780445b25a6368bfd2aaad90b226 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2017 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions for doing things with sockets. With the advent of IPv6 this has
@@ -171,10 +171,9 @@ tfo_probe(void)
 int sock, backlog = 5;
 
 if (  (sock = socket(SOCK_STREAM, AF_INET, 0)) < 0
-   && setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN,
-                   &connect_backlog, sizeof(smtp_connect_backlog))
+   && setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN, &backlog, sizeof(backlog))
    )
-  tcp_fastopen_ok = TRUE;
+  f.tcp_fastopen_ok = TRUE;
 close(sock);
 # endif
 }
@@ -251,9 +250,13 @@ if (timeout > 0) alarm(timeout);
 this peer, can send data in the SYN packet.  The peer can send data
 before it gets our ACK of its SYN,ACK - the latter is useful for
 the SMTP banner.  Other (than SMTP) cases of TCP connections can
-possibly use the data-on-syn, so support that too.  */
+possibly use the data-on-syn, so support that too.
 
-if (fastopen_blob && tcp_fastopen_ok)
+This is a Linux implementation.  It might be useable on FreeBSD; I have
+not checked.  I think MacOS has a "connectx" call for this purpose,
+rather than using "sendto" ? */
+
+if (fastopen_blob && f.tcp_fastopen_ok)
   {
   if ((rc = sendto(sock, fastopen_blob->data, fastopen_blob->len,
                    MSG_FASTOPEN | MSG_DONTWAIT, s_ptr, s_len)) >= 0)
@@ -261,9 +264,10 @@ if (fastopen_blob && tcp_fastopen_ok)
        /* seen for with-data, proper TFO opt, with-cookie case */
     {
     DEBUG(D_transport|D_v)
-      debug_printf("non-TFO mode connection attempt to %s, %d data\n",
-       address, fastopen_blob->len);
-    tcp_out_fastopen = fastopen_blob->len > 0 ?  2 : 1;
+      debug_printf("non-TFO mode connection attempt to %s, %lu data\n",
+       address, (unsigned long)fastopen_blob->len);
+    /*XXX also seen on successful TFO, sigh */
+    tcp_out_fastopen = fastopen_blob->len > 0 ?  TFO_USED : TFO_ATTEMPTED;
     }
   else if (errno == EINPROGRESS)       /* expected if we had no cookie for peer */
        /* seen for no-data, proper TFO option, both cookie-request and with-cookie cases */
@@ -276,7 +280,7 @@ if (fastopen_blob && tcp_fastopen_ok)
       fastopen_blob->len > 0 ? "with"  : "no");
     if (!fastopen_blob->data)
       {
-      tcp_out_fastopen = 1;            /* we tried; unknown if useful yet */
+      tcp_out_fastopen = TFO_ATTEMPTED;                /* we tried; unknown if useful yet */
       rc = 0;
       }
     else
@@ -294,8 +298,8 @@ else
   {
 legacy_connect:
   DEBUG(D_transport|D_v) if (fastopen_blob)
-    debug_printf("non-TFO mode connection attempt to %s, %d data\n",
-      address, fastopen_blob->len);
+    debug_printf("non-TFO mode connection attempt to %s, %lu data\n",
+      address, (unsigned long)fastopen_blob->len);
   if ((rc = connect(sock, s_ptr, s_len)) >= 0)
     if (  fastopen_blob && fastopen_blob->data && fastopen_blob->len
        && send(sock, fastopen_blob->data, fastopen_blob->len, 0) < 0)
@@ -309,7 +313,7 @@ alarm(0);
 can't think of any other way of doing this. It converts a connection refused
 into a timeout if the timeout is set to 999999. */
 
-if (running_in_test_harness  && save_errno == ECONNREFUSED && timeout == 999999)
+if (f.running_in_test_harness  && save_errno == ECONNREFUSED && timeout == 999999)
   {
   rc = -1;
   save_errno = EINTR;
@@ -340,7 +344,7 @@ return -1;
 Arguments:
   type          SOCK_DGRAM or SOCK_STREAM
   af            AF_INET6 or AF_INET for the socket type
-  address       the remote address, in text form
+  hostname     host name, or ip address (as text)
   portlo,porthi the remote port range
   timeout       a timeout
   connhost     if not NULL, host_item to be filled in with connection details
@@ -592,7 +596,7 @@ getting interrupted, and the possibility of select() returning with a positive
 result but no ready descriptor. Is this in fact possible?
 
 Arguments:
-  sock        the socket
+  cctx        the connection context (socket fd, possibly TLS context)
   buffer      to read into
   bufsize     the buffer size
   timeout     the timeout
@@ -602,24 +606,24 @@ Returns:      > 0 => that much data read
 */
 
 int
-ip_recv(int sock, uschar *buffer, int buffsize, int timeout)
+ip_recv(client_conn_ctx * cctx, uschar * buffer, int buffsize, int timeout)
 {
 int rc;
 
-if (!fd_ready(sock, timeout))
+if (!fd_ready(cctx->sock, timeout))
   return -1;
 
 /* The socket is ready, read from it (via TLS if it's active). On EOF (i.e.
 close down of the connection), set errno to zero; otherwise leave it alone. */
 
 #ifdef SUPPORT_TLS
-if (tls_out.active == sock)
-  rc = tls_read(FALSE, buffer, buffsize);
-else if (tls_in.active == sock)
-  rc = tls_read(TRUE, buffer, buffsize);
+if (cctx->tls_ctx)                                     /* client TLS */
+  rc = tls_read(cctx->tls_ctx, buffer, buffsize);
+else if (tls_in.active.sock == cctx->sock)             /* server TLS */
+  rc = tls_read(NULL, buffer, buffsize);
 else
 #endif
-  rc = recv(sock, buffer, buffsize, 0);
+  rc = recv(cctx->sock, buffer, buffsize, 0);
 
 if (rc > 0) return rc;
 if (rc == 0) errno = 0;