systemNameservers validated the whole host:port string with net.ParseIP, which rejects anything carrying a port, so a legal resolv.conf entry such as "nameserver 8.8.8.8:5353" was silently skipped and the following SplitHostPort branch (missing port defaults to 53) could never run. Split first, validate the host only, and reassemble with JoinHostPort, which also brackets IPv6 addresses.
The Init fallback chain (hop/metadata DNS -> resolv.conf "system-N" -> hardcoded default) was also untestable: the resolv.conf rung, added in 684a0dd, depends on the host's file, so TestInit_DefaultExchanger failed on any machine that has one. Introduce a resolvConfPath indirection (a no-op var on Windows, where systemNameservers never reads a file) and add TestInit_SystemNameservers, which exposed the parser bug above.
When no forwarder or dns metadata is configured, the DNS handler now
reads system nameservers from /etc/resolv.conf (Unix) before falling
back to the hardcoded 127.0.0.1:53 default. This makes the DNS proxy
work out-of-the-box without requiring explicit DNS server configuration.
Fixesgo-gost/gost#89
The readTimeout field (default 15s) was being applied via xnet.Pipe to both
directions of a bidirectional proxy connection. During asymmetric transfers
(e.g. HTTP file download), the direction reading from the tunnel sees no
data after the initial request is forwarded, causing SetReadDeadline to fire
after 15s and abort the entire transfer.
Fix: add a separate idleTimeout field (default 0=disabled) to the metadata
structs in both forward/local and forward/remote handlers, and switch
xnet.Pipe to use idleTimeout instead of readTimeout. The readTimeout field
now only applies to the initial protocol sniffing/handshake phase.
Also document readTimeout vs idleTimeout semantics across all 24 locations
in the x/ module where these timeouts appear:
- readTimeout: handshake sniffing deadline (handlers), upstream response
header timeout (http.Transport), or transport-level read deadline
- idleTimeout: idle read deadline per Pipe direction (0=disabled)
- ReadTimeout on Sniffer/SnifferBuilder: upstream response header/TLS
handshake read timeout during sniffing
Fix bufpool leak when PackBuffer fails by extracting packResponse helper.
Add write deadline before conn.Write to prevent goroutine hangs on slow
clients. Log async exchange errors instead of silently discarding them.
Raise defaultBufferSize from 1024 to 4096 to match EDNS0 standard.
Deduplicate lookupHosts TypeA/TypeAAAA branches.