X-Git-Url: https://git.exim.org/users/jgh/exim.git/blobdiff_plain/8d330698b5121d75af35b62b420314f68026d1e5..87cb4a166c47b57df48c2918e47801d77639fbb0:/src/src/transports/smtp.c diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index c64439786..a19e85ffb 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -124,6 +124,8 @@ optionlist smtp_transport_options[] = { { "hosts_try_dane", opt_stringptr, (void *)offsetof(smtp_transport_options_block, hosts_try_dane) }, #endif + { "hosts_try_fastopen", opt_stringptr, + (void *)offsetof(smtp_transport_options_block, hosts_try_fastopen) }, #ifndef DISABLE_PRDR { "hosts_try_prdr", opt_stringptr, (void *)offsetof(smtp_transport_options_block, hosts_try_prdr) }, @@ -209,6 +211,7 @@ smtp_transport_options_block smtp_transport_option_defaults = { NULL, /* hosts_try_dane */ NULL, /* hosts_require_dane */ #endif + NULL, /* hosts_try_fastopen */ #ifndef DISABLE_PRDR US"*", /* hosts_try_prdr */ #endif @@ -282,11 +285,11 @@ static uschar *rf_names[] = { US"NEVER", US"SUCCESS", US"FAILURE", US"DELAY" }; /* Local statics */ -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 */ +static uschar *smtp_command; /* Points to last cmd for error messages */ +static uschar *mail_command; /* Points to MAIL cmd for error messages */ +static uschar *data_command = US""; /* Points to DATA cmd for error messages */ +static BOOL update_waiting; /* TRUE to update the "wait" database */ +static BOOL pipelining_active; /* current transaction is in pipe mode */ /************************************************* @@ -1388,10 +1391,14 @@ uschar * buffer = tctx->buffer; /* Write SMTP chunk header command */ if (chunk_size > 0) + { if((cmd_count = smtp_write_command(tctx->outblock, FALSE, "BDAT %u%s\r\n", chunk_size, flags & tc_chunk_last ? " LAST" : "") ) < 0) return ERROR; + if (flags & tc_chunk_last) + data_command = string_copy(big_buffer); /* Save for later error message */ + } prev_cmd_count = cmd_count += tctx->cmd_count; @@ -1586,6 +1593,7 @@ lflags.dane_required = verify_check_given_host(&ob->hosts_require_dane, host) == *message_defer = FALSE; smtp_command = US"initial connection"; +buffer[0] = '\0'; if (max_rcpt == 0) max_rcpt = 999999; /* Set up the buffer for reading SMTP response packets. */ @@ -2171,10 +2179,10 @@ set it up. This cannot be done until the identify of the host is known. */ if (tblock->filter_command != NULL) { BOOL rc; - uschar buffer[64]; - sprintf(CS buffer, "%.50s transport", tblock->name); + uschar fbuf[64]; + sprintf(CS fbuf, "%.50s transport", tblock->name); rc = transport_set_up_command(&transport_filter_argv, tblock->filter_command, - TRUE, DEFER, addrlist, buffer, NULL); + TRUE, DEFER, addrlist, fbuf, NULL); transport_filter_timeout = tblock->filter_timeout; /* On failure, copy the error to all addresses, abandon the SMTP call, and @@ -2509,6 +2517,7 @@ if ( !(peer_offered & PEER_OFFERED_CHUNKING) default: goto RESPONSE_FAILED; /* I/O error, or any MAIL/DATA error */ } pipelining_active = FALSE; + data_command = string_copy(big_buffer); /* Save for later error message */ } /* If there were no good recipients (but otherwise there have been no @@ -2732,7 +2741,7 @@ else #else "LMTP error after %s: %s", #endif - big_buffer, string_printing(buffer)); + data_command, string_printing(buffer)); setflag(addr, af_pass_message); /* Allow message to go to user */ if (buffer[0] == '5') addr->transport_return = FAIL; @@ -3165,8 +3174,9 @@ HDEBUG(D_transport|D_acl|D_v) debug_printf(" SMTP(close)>>\n"); if (lflags.send_quit) { shutdown(outblock.sock, SHUT_WR); - for (rc = 16; read(inblock.sock, inbuffer, sizeof(inbuffer)) > 0 && rc > 0;) - rc--; /* drain socket */ + if (fcntl(inblock.sock, F_SETFL, O_NONBLOCK) == 0) + for (rc = 16; read(inblock.sock, inbuffer, sizeof(inbuffer)) > 0 && rc > 0;) + rc--; /* drain socket */ } (void)close(inblock.sock);