Skip to content

[tailscale-cherrypick] net/http: fix two bugs from CL 828504 - #183

Merged
bradfitz merged 1 commit into
tailscale.go1.27from
bradfitz/pick_fix
Sep 10, 2026
Merged

bradfitz merged 1 commit into
tailscale.go1.27from
bradfitz/pick_fix

Conversation

@bradfitz

Copy link
Copy Markdown
Member

CL 828504 ("net/http: don't pin bufio buffers on idle HTTP/1
keep-alive connections") broke keep-alive connections over net.Conn
implementations whose deadline errors don't wrap
os.ErrDeadlineExceeded, such as gVisor's gonet (used by Tailscale's
netstack). Its idle buffer release probe sets a short read deadline
and uses errors.Is(err, os.ErrDeadlineExceeded) to distinguish
"connection merely idle" from a real error, so a bespoke timeout error
caused the server to close every keep-alive connection about 50ms
after each response. Likewise in connReader.handleReadErrorLocked.

So use old-school net.Error checks instead for compatibility.

CL 828504 also introduced a second bug, present even with modern
net.Conn implementations: the probe's expected timeout error reached
connReader.handleReadErrorLocked, which canceled the connection-level
context that every subsequent request's context on that connection
derives from. Any request arriving after an idle period longer than
50ms thus began with an already-canceled Context.

Updates golang#80735

Updates #174

Reviewed-on: https://go-review.googlesource.com/c/go/+/830364
Reviewed-by: Nicholas Husin nsh@golang.org
Reviewed-by: Dmitri Shuralyov dmitshur@google.com
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com golang-scoped@luci-project-accounts.iam.gserviceaccount.com
Reviewed-by: Nicholas Husin husin@google.com
Reviewed-by: Davanum Srinivas (dims) davanum@gmail.com
(cherry picked from commit b35e1f9)

CL 828504 ("net/http: don't pin bufio buffers on idle HTTP/1
keep-alive connections") broke keep-alive connections over net.Conn
implementations whose deadline errors don't wrap
os.ErrDeadlineExceeded, such as gVisor's gonet (used by Tailscale's
netstack). Its idle buffer release probe sets a short read deadline
and uses errors.Is(err, os.ErrDeadlineExceeded) to distinguish
"connection merely idle" from a real error, so a bespoke timeout error
caused the server to close every keep-alive connection about 50ms
after each response. Likewise in connReader.handleReadErrorLocked.

So use old-school net.Error checks instead for compatibility.

CL 828504 also introduced a second bug, present even with modern
net.Conn implementations: the probe's expected timeout error reached
connReader.handleReadErrorLocked, which canceled the connection-level
context that every subsequent request's context on that connection
derives from. Any request arriving after an idle period longer than
50ms thus began with an already-canceled Context.

Updates golang#80735

Updates #174

Change-Id: Ia69d79e8e1fc30aec9e716ed5691db7474b05f0e
Reviewed-on: https://go-review.googlesource.com/c/go/+/830364
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Davanum Srinivas (dims) <davanum@gmail.com>
(cherry picked from commit b35e1f9)
@bradfitz
bradfitz merged commit c6e3412 into tailscale.go1.27 Sep 10, 2026
5 checks passed
@bradfitz
bradfitz deleted the bradfitz/pick_fix branch September 10, 2026 03:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant