mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 16:33:47 +03:00
queue: retry with another IP when first attempt fails for dualstack remote servers
mox was already giving another try for received errors after the `HELO`/`EHLO` command. Now mox do the same for received errors when trying to deliver the message to the remote SMTP server. This should help to deliver messages to SMTP server that rejects incoming messages because of bad ipv4 or ipv6 configuration (for example for servers checking reverse DNS records). mox will now try to deliver messages on both ip family instead before considering the error as permanent. fix #149
This commit is contained in:
parent
d74610c345
commit
feb8e6c379
1 changed files with 10 additions and 4 deletions
|
@ -639,13 +639,15 @@ func deliverHost(log mlog.Log, resolver dns.Resolver, dialer smtpclient.Dialer,
|
|||
err = fmt.Errorf("storing recipient domain tls status: %w", err)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
inspectError := func(err error) error {
|
||||
if cerr, ok := err.(smtpclient.Error); ok {
|
||||
// If we are being rejected due to policy reasons on the first
|
||||
// attempt and remote has both IPv4 and IPv6, we'll give it
|
||||
// another try. Our first IP may be in a block list, the address for
|
||||
// the other family perhaps is not.
|
||||
if cerr.Permanent && m0.Attempts == 1 && dualstack && strings.HasPrefix(cerr.Secode, "7.") {
|
||||
log.Debugx("change error type from permanent to transient", err, slog.Any("host", host), slog.Any("secode", cerr.Secode))
|
||||
cerr.Permanent = false
|
||||
}
|
||||
// If server does not implement requiretls, respond with that code. ../rfc/8689:301
|
||||
|
@ -653,9 +655,13 @@ func deliverHost(log mlog.Log, resolver dns.Resolver, dialer smtpclient.Dialer,
|
|||
cerr.Secode = smtp.SePol7MissingReqTLS30
|
||||
metricRequireTLSUnsupported.WithLabelValues("norequiretls").Inc()
|
||||
}
|
||||
err = cerr
|
||||
return cerr
|
||||
}
|
||||
return deliverResult{err: err}
|
||||
return err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return deliverResult{err: inspectError(err)}
|
||||
}
|
||||
|
||||
// SMTP session is ready. Finally try to actually deliver.
|
||||
|
@ -695,7 +701,7 @@ func deliverHost(log mlog.Log, resolver dns.Resolver, dialer smtpclient.Dialer,
|
|||
resps, err := sc.DeliverMultiple(ctx, mailFrom, rcpts, size, msg, has8bit, smtputf8, m0.RequireTLS != nil && *m0.RequireTLS)
|
||||
if err != nil && len(resps) == len(msgResps) {
|
||||
// If error and it applies to all recipients, return a single error.
|
||||
return deliverResult{err: err}
|
||||
return deliverResult{err: inspectError(err)}
|
||||
}
|
||||
var ntodo []*msgResp
|
||||
for i, mr := range todo[:n] {
|
||||
|
|
Loading…
Reference in a new issue