(void *)offsetof(smtp_transport_options_block, delay_after_cutoff) },
#ifndef DISABLE_DKIM
{ "dkim_canon", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_canon) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_canon) },
{ "dkim_domain", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_domain) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_domain) },
{ "dkim_private_key", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_private_key) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_private_key) },
{ "dkim_selector", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_selector) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_selector) },
{ "dkim_sign_headers", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_sign_headers) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_sign_headers) },
{ "dkim_strict", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_strict) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_strict) },
#endif
{ "dns_qualify_single", opt_bool,
(void *)offsetof(smtp_transport_options_block, dns_qualify_single) },
US"*" /* tls_verify_cert_hostnames */
#endif
#ifndef DISABLE_DKIM
- ,NULL, /* dkim_canon */
- NULL, /* dkim_domain */
- NULL, /* dkim_private_key */
- NULL, /* dkim_selector */
- NULL, /* dkim_sign_headers */
- NULL /* dkim_strict */
+ , {NULL, /* dkim_canon */
+ NULL, /* dkim_domain */
+ NULL, /* dkim_private_key */
+ NULL, /* dkim_selector */
+ NULL, /* dkim_sign_headers */
+ NULL} /* dkim_strict */
#endif
};
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 */
/*************************************************
check_response(host_item *host, int *errno_value, int more_errno,
uschar *buffer, int *yield, uschar **message, BOOL *pass_message)
{
-uschar *pl = US"";
-
-if (smtp_use_pipelining &&
- (Ustrcmp(smtp_command, "MAIL") == 0 ||
- Ustrcmp(smtp_command, "RCPT") == 0 ||
- Ustrcmp(smtp_command, "DATA") == 0))
- pl = US"pipelined ";
+uschar * pl = pipelining_active ? US"pipelined " : US"";
*yield = '4'; /* Default setting is to give a temporary error */
case DNS_AGAIN:
return DEFER; /* just defer this TLS'd conn */
- case DNS_NOMATCH:
+ case DNS_NODATA: /* no TLSA RR for this lookup */
+ case DNS_NOMATCH: /* no records at all for this lookup */
return dane_required ? FAIL : FAIL_FORCED;
default:
ehlo_response(uschar * buf, size_t bsize, uschar checks)
{
#ifdef SUPPORT_TLS
-if (checks & PEER_OFFERED_TLS)
- if (pcre_exec(regex_STARTTLS, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_TLS;
+if ( checks & PEER_OFFERED_TLS
+ && pcre_exec(regex_STARTTLS, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_TLS;
#endif
- if ( checks & PEER_OFFERED_IGNQ
- && pcre_exec(regex_IGNOREQUOTA, NULL, CS buf, bsize, 0,
- PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_IGNQ;
+if ( checks & PEER_OFFERED_IGNQ
+ && pcre_exec(regex_IGNOREQUOTA, NULL, CS buf, bsize, 0,
+ PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_IGNQ;
#ifndef DISABLE_PRDR
- if ( checks & PEER_OFFERED_PRDR
- && pcre_exec(regex_PRDR, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_PRDR;
+if ( checks & PEER_OFFERED_PRDR
+ && pcre_exec(regex_PRDR, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_PRDR;
#endif
#ifdef SUPPORT_I18N
- if ( checks & PEER_OFFERED_UTF8
- && pcre_exec(regex_UTF8, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_UTF8;
+if ( checks & PEER_OFFERED_UTF8
+ && pcre_exec(regex_UTF8, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_UTF8;
#endif
- if ( checks & PEER_OFFERED_DSN
- && pcre_exec(regex_DSN, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_DSN;
+if ( checks & PEER_OFFERED_DSN
+ && pcre_exec(regex_DSN, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_DSN;
- if ( checks & PEER_OFFERED_PIPE
- && pcre_exec(regex_PIPELINING, NULL, CS buf, bsize, 0,
- PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_PIPE;
+if ( checks & PEER_OFFERED_PIPE
+ && pcre_exec(regex_PIPELINING, NULL, CS buf, bsize, 0,
+ PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_PIPE;
- if ( checks & PEER_OFFERED_SIZE
- && pcre_exec(regex_SIZE, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_SIZE;
+if ( checks & PEER_OFFERED_SIZE
+ && pcre_exec(regex_SIZE, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_SIZE;
return checks;
}
if (esmtp || lmtp)
peer_offered = ehlo_response(buffer, Ustrlen(buffer),
- PEER_OFFERED_TLS
- | 0 /* IGNQ checked later */
- | 0 /* PRDR checked later */
- | 0 /* UTF8 checked later */
- | 0 /* DSN checked later */
- | 0 /* PIPE checked later */
- | 0 /* SIZE checked later */
+ PEER_OFFERED_TLS /* others checked later */
);
/* Set tls_offered if the response to EHLO specifies support for STARTTLS. */
case FAIL: goto RESPONSE_FAILED;
}
}
+pipelining_active = smtp_use_pipelining;
/* The setting up of the SMTP call is now complete. Any subsequent errors are
message-specific. */
{
if (dsn_ret == dsn_ret_hdrs)
{
- Ustrcpy(p, " RET=HDRS");
- while (*p) p++;
+ Ustrcpy(p, " RET=HDRS"); p += 9;
}
else if (dsn_ret == dsn_ret_full)
{
- Ustrcpy(p, " RET=FULL");
- while (*p) p++;
+ Ustrcpy(p, " RET=FULL"); p += 9;
}
if (dsn_envid != NULL)
{
that max_rcpt will be large, so all addresses will be done at once. */
for (addr = first_addr;
- address_count < max_rcpt && addr != NULL;
+ addr && address_count < max_rcpt;
addr = addr->next)
{
int count;
if (addr->transport_return != PENDING_DEFER) continue;
address_count++;
- no_flush = smtp_use_pipelining && (!mua_wrapper || addr->next != NULL);
+ no_flush = smtp_use_pipelining && (!mua_wrapper || addr->next);
/* Add any DSN flags to the rcpt command and add to the sent string */
p = buffer;
*p = 0;
- if (smtp_use_dsn && (addr->dsn_flags & rf_dsnlasthop) != 1)
+ if (smtp_use_dsn && !(addr->dsn_flags & rf_dsnlasthop))
{
if ((addr->dsn_flags & rf_dsnflags) != 0)
{
}
}
- if (addr->dsn_orcpt != NULL)
+ if (addr->dsn_orcpt)
{
string_format(p, sizeof(buffer) - (p-buffer), " ORCPT=%s",
addr->dsn_orcpt);
case -1: goto END_OFF; /* Timeout on RCPT */
default: goto RESPONSE_FAILED; /* I/O error, or any MAIL/DATA error */
}
+ pipelining_active = FALSE;
}
/* Save the first address of the next batch. */
well as body. Set the appropriate timeout value to be used for each chunk.
(Haven't been able to make it work using select() for writing yet.) */
-if (!ok) ok = TRUE; else
+if (!ok)
+ ok = TRUE;
+else
{
+ transport_ctx tctx = {
+ tblock,
+ addrlist,
+ US".", US"..", /* Escaping strings */
+ topt_use_crlf | topt_end_dot | topt_escape_headers
+ | (tblock->body_only ? topt_no_headers : 0)
+ | (tblock->headers_only ? topt_no_body : 0)
+ | (tblock->return_path_add ? topt_add_return_path : 0)
+ | (tblock->delivery_date_add ? topt_add_delivery_date : 0)
+ | (tblock->envelope_to_add ? topt_add_envelope_to : 0)
+ };
+
sigalrm_seen = FALSE;
transport_write_timeout = ob->data_timeout;
smtp_command = US"sending data block"; /* For error messages */
transport_count = 0;
#ifndef DISABLE_DKIM
- ok = dkim_transport_write_message(addrlist, inblock.sock,
- topt_use_crlf | topt_end_dot | topt_escape_headers |
- (tblock->body_only? topt_no_headers : 0) |
- (tblock->headers_only? topt_no_body : 0) |
- (tblock->return_path_add? topt_add_return_path : 0) |
- (tblock->delivery_date_add? topt_add_delivery_date : 0) |
- (tblock->envelope_to_add? topt_add_envelope_to : 0),
- 0, /* No size limit */
- tblock->add_headers, tblock->remove_headers,
- US".", US"..", /* Escaping strings */
- tblock->rewrite_rules, tblock->rewrite_existflags,
- ob->dkim_private_key, ob->dkim_domain, ob->dkim_selector,
- ob->dkim_canon, ob->dkim_strict, ob->dkim_sign_headers
- );
+ ok = dkim_transport_write_message(inblock.sock, &tctx, &ob->dkim);
#else
- ok = transport_write_message(addrlist, inblock.sock,
- topt_use_crlf | topt_end_dot | topt_escape_headers |
- (tblock->body_only? topt_no_headers : 0) |
- (tblock->headers_only? topt_no_body : 0) |
- (tblock->return_path_add? topt_add_return_path : 0) |
- (tblock->delivery_date_add? topt_add_delivery_date : 0) |
- (tblock->envelope_to_add? topt_add_envelope_to : 0),
- 0, /* No size limit */
- tblock->add_headers, tblock->remove_headers,
- US".", US"..", /* Escaping strings */
- tblock->rewrite_rules, tblock->rewrite_existflags);
+ ok = transport_write_message(inblock.sock, &tctx, 0);
#endif
/* transport_write_message() uses write() because it is called from other
int delivery_time = (int)(time(NULL) - start_delivery_time);
int len;
uschar *conf = NULL;
+
send_rset = FALSE;
+ pipelining_active = FALSE;
/* Set up confirmation if needed - applies only to SMTP */