Events: raise msg:fail:internal & msg:complete for -Mrm. Bug 2310
[users/heiko/exim.git] / src / src / ip.c
index e85dcb23e9331a07ee82b9af46f53cbee5abf351..633e0c2f9e041026d5e8e4d218168852f60af5f6 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
@@ -173,7 +173,7 @@ int sock, backlog = 5;
 if (  (sock = socket(SOCK_STREAM, AF_INET, 0)) < 0
    && setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN, &backlog, sizeof(backlog))
    )
-  tcp_fastopen_ok = TRUE;
+  f.tcp_fastopen_ok = TRUE;
 close(sock);
 # endif
 }
@@ -250,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)
@@ -262,6 +266,7 @@ if (fastopen_blob && tcp_fastopen_ok)
     DEBUG(D_transport|D_v)
       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 ?  2 : 1;
     }
   else if (errno == EINPROGRESS)       /* expected if we had no cookie for peer */
@@ -308,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;
@@ -339,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
@@ -591,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
@@ -601,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;