net: TCP connection erroneously duplicates message on Windows #58764
Labels
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
OS-Windows
Milestone
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Write
data and the server conn in a wrapper that records allRead
data.What did you expect to see?
There should be no different in the bytes that the client sent and the bytes the server received.
What did you see instead?
At some point after ~2.7 MB a chunk of data is received twice.
Details
This problem was originally encountered in the tests for https://github.com/jackc/pgx. pgx has need of non-blocking IO (see #36973 and #15735). It also needs this supported when using TLS. Since the desired functionality doesn't presently exist in Go it has an internal package
nbconn
that wraps up a lot of complicated code in a way that presents anet.Conn
that supports non-blocking IO even over TLS.One of the tests consistently encounters a
tls: bad record MAC
on Windows but not on Linux or Mac. Given the complicated code it would be obvious to assume that the problem is in thatnbconn
package. However, after many hours of debugging I believe I have ruled that out. I have a reproducible test case that creates anet.Conn
for a client and server and records everything written and read for the client to server stream. The TLS connection and the nbconn connection are on top of / use those recording connections. The recorded connections observe the repeated data (which obviously will corrupt the TLS connection).Given that the repeated data is observed below the TLS connection I don't believe it is plausible that the bug exists in either pgx or the tls package. It seems likelier that it is a problem in the net package, the Go runtime, or Windows itself.
I have a test case at https://github.com/jackc/golang-windows-dupreads. It always fails on Windows but succeeds on other platforms. I've reduced the test as much as possible, but unfortunately I am unable to reproduce it without the particular pattern of reads and writes produced by
nbconn
andtls
.Here is the core of the test. It creates a server on localhost and establishes a connection to it. It wraps both connections in recorders. Then it performs some activity. Lastly, it checks to see if the bytes written and the bytes read match:
Run with
go test
Observations:
The text was updated successfully, but these errors were encountered: