ソースを参照
Fix TCP keepalive setup on OpenBSD
Fixes #457.
OpenBSD has no user-settable per-socket TCP keepalive options:
TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT do not exist on OpenBSD,
keepalive timing is controlled system-wide via the sysctls
net.inet.tcp.keepidle and net.inet.tcp.keepintvl. Go reflects this in
src/net/tcpsockopt_openbsd.go: setKeepAliveIdle / Interval / Count
return ENOPROTOOPT for any non-negative value, and only short-circuit
to nil for negative values that explicitly mean "leave alone".
mtg builds a net.KeepAliveConfig with zero-valued Idle / Interval /
Count whenever the user does not override them in the config (which
is the default and the documented expectation). It then hands that
config to (*TCPConn).SetKeepAliveConfig in two places:
- network/sockopts.go: applied to every connection accepted by
internal/utils.Listener.Accept and to every server-side dial that
goes through the v1 default network.
- network/v2/sockopts.go: applied to every connection produced by
the v2 network's DialContext.
On OpenBSD both calls fail with "set tcp ...: protocol not available".
The user-visible effect is that:
- `mtg doctor` reports the error for every Telegram DC.
- `mtg run` accepts incoming TCP connections at the kernel level but
Listener.Accept then closes each one before the proxy server ever
sees it, so the client appears to hang on a half-open socket and
nothing is logged.
- There is no configuration workaround. Setting [network]
keep-alive.disabled = true only zeroes Enable; Go still calls
setKeepAliveIdle / Interval / Count, which still fail.
This change extracts the keepalive setup behind an applyKeepAlive
helper that has a per-platform implementation, following the same
build-tag pattern already used for sockopts_lowat, sockopts_congestion,
sockopts_reuseaddr and sockopts_usertimeout. On every supported
platform except OpenBSD it still calls SetKeepAliveConfig and the
behaviour is unchanged. On OpenBSD it calls SetKeepAlive(cfg.Enable)
instead, which only flips SO_KEEPALIVE on or off and never touches
the missing per-socket options. OpenBSD users get the system-wide
sysctl-controlled keepalive timing, which is the only thing the
kernel exposes anyway.
Verified by cross-building (`GOOS=openbsd GOARCH=amd64 go build ./...`
and `GOARCH=arm64`) and by running `go test ./network/...` on linux.
pull/459/head