SMTP: Do no send EHLO twice when STARTTLS is unavailable (fixes #2050)

This commit is contained in:
mdecimus 2025-08-23 20:31:57 +02:00
parent ac33b79bdc
commit 7395f76bba
2 changed files with 31 additions and 24 deletions

View file

@ -926,7 +926,7 @@ impl QueuedMessage {
.and_then(|ip| ip.host.as_deref())
.or(conn_strategy.ehlo_hostname.as_deref())
.unwrap_or(server.core.network.server_name.as_str());
let params = SessionParams {
let mut params = SessionParams {
session_id: message.span_id,
server: &server,
credentials: remote_host.credentials(),
@ -934,6 +934,7 @@ impl QueuedMessage {
hostname: envelope.mx,
local_hostname,
conn_strategy,
capabilities: None,
};
// Prepare TLS connector
@ -1132,6 +1133,7 @@ impl QueuedMessage {
continue 'next_host;
} else {
// TLS is not required, proceed in plain-text
params.capabilities = Some(capabilities);
message
.deliver(
smtp_client,

View file

@ -25,6 +25,7 @@ pub struct SessionParams<'x> {
pub server: &'x Server,
pub hostname: &'x str,
pub credentials: Option<&'x Credentials<String>>,
pub capabilities: Option<EhloResponse<String>>,
pub is_smtp: bool,
pub local_hostname: &'x str,
pub conn_strategy: &'x ConnectionStrategy,
@ -37,33 +38,37 @@ impl MessageWrapper {
mut smtp_client: SmtpClient<T>,
rcpt_idxs: Vec<usize>,
statuses: &mut Vec<DeliveryResult>,
params: SessionParams<'_>,
mut params: SessionParams<'_>,
) {
// Obtain capabilities
let time = Instant::now();
let capabilities = match smtp_client.say_helo(&params).await {
Ok(capabilities) => {
trc::event!(
Delivery(DeliveryEvent::Ehlo),
SpanId = params.session_id,
Hostname = params.hostname.to_string(),
Details = capabilities.capabilities(),
Elapsed = time.elapsed(),
);
let capabilities = if let Some(capabilities) = params.capabilities.take() {
capabilities
} else {
match smtp_client.say_helo(&params).await {
Ok(capabilities) => {
trc::event!(
Delivery(DeliveryEvent::Ehlo),
SpanId = params.session_id,
Hostname = params.hostname.to_string(),
Details = capabilities.capabilities(),
Elapsed = time.elapsed(),
);
capabilities
}
Err(status) => {
trc::event!(
Delivery(DeliveryEvent::EhloRejected),
SpanId = params.session_id,
Hostname = params.hostname.to_string(),
CausedBy = from_error_status(&status),
Elapsed = time.elapsed(),
);
smtp_client.quit().await;
statuses.push(DeliveryResult::domain(status, rcpt_idxs));
return;
capabilities
}
Err(status) => {
trc::event!(
Delivery(DeliveryEvent::EhloRejected),
SpanId = params.session_id,
Hostname = params.hostname.to_string(),
CausedBy = from_error_status(&status),
Elapsed = time.elapsed(),
);
smtp_client.quit().await;
statuses.push(DeliveryResult::domain(status, rcpt_idxs));
return;
}
}
};