Make the guide gateway IPv4-only to stop IPv6 stalls
Serve only A/ANY queries; answer AAAA and all other record types with NOERROR and no data, for overrides and forwarded names alike. The console LAN has no IPv6 route, so returning a real AAAA made clients stall on an unreachable address. This fixes the PS5 Payload Manager looping on "synchronizing repositories": its dual-stack catalog host itsplk.github.io handed back an IPv6 address and the manager's libcurl download (no timeout) hung on it indefinitely. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
+17
-10
@@ -218,21 +218,31 @@ def dns_response(packet, use_tcp=False):
|
||||
return struct.pack("!HHHHHH", transaction_id, response_flags | 1, 0, 0, 0, 0)
|
||||
|
||||
question = packet[12:question_end]
|
||||
is_exception = match_any(name, EXCEPTIONS)
|
||||
address = None if is_exception else override_for(name)
|
||||
|
||||
# Default-deny: a name matching no rule returns NXDOMAIN.
|
||||
if not is_exception and address is None:
|
||||
return struct.pack("!HHHHHH", transaction_id, response_flags | 3, 1, 0, 0, 0) + question
|
||||
|
||||
noerror_nodata = struct.pack("!HHHHHH", transaction_id, response_flags, 1, 0, 0, 0) + question
|
||||
|
||||
# IPv4-only resolver. Only A (and ANY) queries are served; AAAA and any other
|
||||
# record type get NOERROR with no data. The console LAN has no IPv6 route, so
|
||||
# handing back an AAAA record would make clients stall on an unreachable IPv6
|
||||
# address -- this is what left the PS5 Payload Manager looping on "synchronizing
|
||||
# repositories" for the dual-stack itsplk.github.io host.
|
||||
if qclass != 1 or qtype not in (1, 255):
|
||||
return noerror_nodata
|
||||
|
||||
# Exceptions bypass overrides and are forwarded upstream (nanoDNS semantics).
|
||||
if match_any(name, EXCEPTIONS):
|
||||
if is_exception:
|
||||
try:
|
||||
return forward_query(packet, use_tcp=use_tcp)
|
||||
except (OSError, ValueError) as error:
|
||||
print(f"DNS upstream failure for {name}: {error}", flush=True)
|
||||
return error_response(packet, 2) # SERVFAIL
|
||||
|
||||
address = override_for(name)
|
||||
if address is None:
|
||||
# Default-deny: a name matching no rule returns NXDOMAIN.
|
||||
return struct.pack("!HHHHHH", transaction_id, response_flags | 3, 1, 0, 0, 0) + question
|
||||
|
||||
if qclass == 1 and qtype in (1, 255):
|
||||
answer = (
|
||||
b"\xc0\x0c"
|
||||
+ struct.pack("!HHIH", 1, 1, 60, 4)
|
||||
@@ -240,9 +250,6 @@ def dns_response(packet, use_tcp=False):
|
||||
)
|
||||
return struct.pack("!HHHHHH", transaction_id, response_flags, 1, 1, 0, 0) + question + answer
|
||||
|
||||
# NOERROR with no data prevents IPv6 or unsupported record fallback.
|
||||
return struct.pack("!HHHHHH", transaction_id, response_flags, 1, 0, 0, 0) + question
|
||||
|
||||
|
||||
class ThreadingUDPServer(socketserver.ThreadingUDPServer):
|
||||
allow_reuse_address = True
|
||||
|
||||
@@ -207,6 +207,17 @@ overrides (spoof) → NXDOMAIN. Unlike upstream nanoDNS, a name matching no rule
|
||||
blocked by default. The PS5 sends DNS only to `net-utils01`; that host must be
|
||||
allowed to reach the configured upstream resolver on UDP/TCP 53.
|
||||
|
||||
The gateway is **IPv4-only**: it serves only `A` (and `ANY`) queries. `AAAA` and
|
||||
any other record type return NOERROR with no data, for both overrides and
|
||||
forwarded names. The console LAN has no IPv6 route, so returning a real `AAAA`
|
||||
would make clients stall on an unreachable IPv6 address. This specifically fixed
|
||||
the PS5 Payload Manager looping forever on "synchronizing repositories": its
|
||||
catalog host `itsplk.github.io` is dual-stack, the console tried the IPv6 address,
|
||||
and the manager's libcurl download has no timeout, so the hung connection never
|
||||
returned. The official Payload Manager repository needs only `itsplk.github.io`
|
||||
(catalog), `github.com` (payload `url`s) and `release-assets.githubusercontent.com`
|
||||
(release-download redirect target), all already in `[exceptions]`.
|
||||
|
||||
The gateway additionally restricts which source clients it answers, via
|
||||
`[general] allowed_clients`. It defaults to the console VLAN `192.168.40.0/28`,
|
||||
the server VLAN `192.168.20.0/24`, and the trusted management VLAN
|
||||
|
||||
Reference in New Issue
Block a user