net/dns: timeout DOH requests after 10s without response headers

If a client socket is remotely lost but the client is not sent an RST in
response to the next request, the socket might sit in RTO for extended
lengths of time, resulting in "no internet" for users. Instead, timeout
after 10s, which will close the underlying socket, recovering from the
situation more promptly.

Updates #10967

Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
James Tucker 2024-02-23 22:51:17 -08:00 committed by James Tucker
parent 0c5e65eb3f
commit 8d0d46462b
1 changed files with 3 additions and 0 deletions

View File

@ -405,6 +405,9 @@ func (f *forwarder) getKnownDoHClientForProvider(urlBase string) (c *http.Client
Transport: &http.Transport{
ForceAttemptHTTP2: true,
IdleConnTimeout: dohTransportTimeout,
// On mobile platforms TCP KeepAlive is disabled in the dialer,
// ensure that we timeout if the connection appears to be hung.
ResponseHeaderTimeout: 10 * time.Second,
DialContext: func(ctx context.Context, netw, addr string) (net.Conn, error) {
if !strings.HasPrefix(netw, "tcp") {
return nil, fmt.Errorf("unexpected network %q", netw)