summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2016-10-18 23:35:35 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2016-10-18 23:35:35 +0100
commit8d330698b5121d75af35b62b420314f68026d1e5 (patch)
tree7df47b37cd0c30992df6d2605c489611082cf970
parentc039ce6150634eb51a120406b5b7784823430eb5 (diff)
downloadexim4-8d330698b5121d75af35b62b420314f68026d1e5.tar.gz
Avoid pure-ACK TCP segments during command phase
-rw-r--r--src/src/smtp_in.c13
-rw-r--r--src/src/transports/smtp.c10
-rw-r--r--src/src/verify.c5
3 files changed, 26 insertions, 2 deletions
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 17dd78cd8..9282352ac 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -143,6 +143,8 @@ static BOOL pipelining_advertised;
static BOOL rcpt_smtp_response_same;
static BOOL rcpt_in_progress;
static int nonmail_command_count;
+static int off = 0;
+static int on = 1;
static BOOL smtp_exit_function_called = 0;
#ifdef SUPPORT_I18N
static BOOL smtputf8_advertised;
@@ -3544,6 +3546,12 @@ while (done <= 0)
}
#endif
+#ifdef TCP_QUICKACK
+ if (smtp_in) /* Avoid pure-ACKs while in cmd pingpong phase */
+ (void) setsockopt(fileno(smtp_in), IPPROTO_TCP, TCP_QUICKACK,
+ US &off, sizeof(off));
+#endif
+
switch(smtp_read_command(TRUE))
{
/* The AUTH command is not permitted to occur inside a transaction, and may
@@ -4826,6 +4834,11 @@ while (done <= 0)
"354 Enter message, ending with \".\" on a line by itself\r\n");
}
+#ifdef TCP_QUICKACK
+ if (smtp_in) /* all ACKs needed to ramp window up for bulk data */
+ (void) setsockopt(fileno(smtp_in), IPPROTO_TCP, TCP_QUICKACK,
+ US &on, sizeof(on));
+#endif
done = 3;
message_ended = END_NOTENDED; /* Indicate in middle of data */
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index af2d40fa0..c64439786 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -286,6 +286,7 @@ static uschar *smtp_command; /* Points to last cmd for error messages */
static uschar *mail_command; /* Points to MAIL cmd for error messages */
static BOOL update_waiting; /* TRUE to update the "wait" database */
static BOOL pipelining_active; /* current transaction is in pipe mode */
+static int off = 0; /* for use by setsockopt */
/*************************************************
@@ -1705,7 +1706,12 @@ if (continue_hostname == NULL)
if (!lflags.smtps)
{
- BOOL good_response = smtp_read_response(&inblock, buffer, sizeof(buffer),
+ BOOL good_response;
+
+#ifdef TCP_QUICKACK
+ (void) setsockopt(inblock.sock, IPPROTO_TCP, TCP_QUICKACK, US &off, sizeof(off));
+#endif
+ good_response = smtp_read_response(&inblock, buffer, sizeof(buffer),
'2', ob->command_timeout);
#ifdef EXPERIMENTAL_DSN_INFO
smtp_greeting = string_copy(buffer);
@@ -1732,7 +1738,7 @@ if (continue_hostname == NULL)
/* Now check if the helo_data expansion went well, and sign off cleanly if
it didn't. */
- if (helo_data == NULL)
+ if (!helo_data)
{
uschar *message = string_sprintf("failed to expand helo_data: %s",
expand_string_message);
diff --git a/src/src/verify.c b/src/src/verify.c
index ff9a5a5c0..f8f1809cb 100644
--- a/src/src/verify.c
+++ b/src/src/verify.c
@@ -41,6 +41,8 @@ static tree_node *dnsbl_cache = NULL;
static uschar cutthrough_response(char, uschar **);
+static int off = 0; /* for use by setsockopt */
+
/*************************************************
* Retrieve a callout cache record *
@@ -683,6 +685,9 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount.
if (!smtps || (smtps && tls_out.active >= 0))
#endif
{
+#ifdef TCP_QUICKACK
+ (void) setsockopt(inblock.sock, IPPROTO_TCP, TCP_QUICKACK, US &off, sizeof(off));
+#endif
if (!(done= smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer), '2', callout)))
goto RESPONSE_FAILED;