https://bz.apache.org/SpamAssassin/show_bug.cgi?id=8432
Bug ID: 8432
Summary: TCP fallback for truncated UDP replies ignores the
port from dns_server [ip]:port; retries go to port 53
and fail
Product: Spamassassin
Version: SVN Trunk (Latest Devel Version)
Hardware: PC
OS: Linux
Status: NEW
Severity: major
Priority: P2
Component: spamassassin
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: Undefined
`Mail::SpamAssassin::DnsResolver::load_resolver()` strips the port from
`dns_server` entries when configuring the underlying Net::DNS::Resolver object:
```perl
my @ns_addr_port =
$self->available_nameservers();
# drop port numbers,
Net::DNS::Resolver can't take them
@ns_addr_port =
map(/^\[(.*)\]:(\d+)\z/ ? $1 : $_, @ns_addr_port);
$res->nameservers(@ns_addr_port);
```
This is fine for SA's own async query
engine (which honors `[ip]:port`), but the bug 8225 TCP-fallback code
(DnsResolver.pm, ~line 846, `# bug 8225 - Do TCP fallback ... by retrying using
Net::DNS::Resolver bgsend and bgread`) retries through that same port-stripped
resolver. With a resolver configured on a nonstandard port (e.g. `dns_server
127.0.0.1:5352` for a local unbound), the retry is sent to port 53, where
nothing listens. The retry times out after the hardcoded `udp_timeout(3)` and
`bgread()` returns undef without setting `$!` or `$@`, producing the low-signal
error:
```
info:
dns: bad dns tcp fallback reply: errno=
```
Consequences: every lookup whose reply exceeds
the UDP payload size silently fails. Most visibly this breaks SPF:
`T_SPF_TEMPERROR` for any sender domain with a large TXT record set (e.g.
github.com, TXT currently 1928 bytes), and raises scan times from ~8 s to ~36 s
because SPF burns its full timeout budget waiting for the fallback that never
returns.
## Steps to reproduce
1. Run a local
recursive resolver on a nonstandard port; configure `dns_server
127.0.0.1:5352`. Nothing must listen on 127.0.0.1:53.
2. Scan a
message from a domain whose TXT answer exceeds the UDP payload size:
`spamassassin -D
dns,spf < message.eml`
3. Observed (SA 4.0.2, Net::DNS
1.54):
```
dbg: dns: bgsend, DNS servers: [127.0.0.1]:5352
dbg:
dns: bgread: received 39 bytes from 127.0.0.1 # truncated UDP reply, TC
set
dbg: dns: TCP
fallback retry with github.com, TXT, IN
info: dns: bad dns tcp
fallback reply: errno= # after ~3 s
dbg: spf: ... result: temperror ...
Time-out on DNS 'TXT' lookup of 'github.com'
```
Control: with
the same resolver reachable on port 53 and `dns_server 127.0.0.1`, the fallback
succeeds and SPF returns pass. A plain Net::DNS::Resolver created with `port =>
5352` performs the identical UDP-truncation → TCP retry sequence correctly,
which isolates the failure to SA's port stripping.
## Current status in trunk
Both the port-stripping in `load_resolver()` and the fallback delegating to
`get_resolver()` are unchanged in trunk HEAD (checked in the GitHub mirror,
lib/Mail/SpamAssassin/DnsResolver.pm as of commit 67445fc, 2025-01-16). The
related recent commit 67445fc only switches Plugin/DKIM.pm to SA's custom
resolver; it does not address the reopened 8225 issue.
--
You are receiving this mail because:
You are the assignee for the bug.
