X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fip.c;h=ef133bf9f0bd780445b25a6368bfd2aaad90b226;hb=9fa3eec7bb2e6a14a0b62dbc713c0ba5b2b5cd34;hp=ee91293fafece78926e8faba4d19a35cc3deff31;hpb=10ac8d7f410e55043b0b182fb77f2e8fb6a7aed4;p=exim.git diff --git a/src/src/ip.c b/src/src/ip.c index ee91293fa..ef133bf9f 100644 --- a/src/src/ip.c +++ b/src/src/ip.c @@ -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;