Alternative TLS implementation in Go
b7ba182f28
After renegotiation support was added (af125a5193c) it's possible for a Write to block on a Read when racing to complete the handshake: 1. The Write determines that a handshake is needed and tries to take the neccesary locks in the correct order. 2. The Read also determines that a handshake is needed and wins the race to take the locks. 3. The Read goroutine completes the handshake and wins a race to unlock and relock c.in, which it'll hold when waiting for more network data. If the application-level protocol requires the Write to complete before data can be read then the system as a whole will deadlock. Unfortunately it doesn't appear possible to reverse the locking order of c.in and handshakeMutex because we might read a renegotiation request at any point and need to be able to do a handshake without unlocking. So this change adds a sync.Cond that indicates that a goroutine has committed to doing a handshake. Other interested goroutines can wait on that Cond when needed. The test for this isn't great. I was able to reproduce the deadlock with it only when building with -race. (Because -race happened to alter the timing just enough.) Fixes #17101. Change-Id: I4e8757f7b82a84e46c9963a977d089f0fb675495 Reviewed-on: https://go-review.googlesource.com/29164 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> |
||
---|---|---|
testdata | ||
alert.go | ||
cipher_suites.go | ||
common.go | ||
conn_test.go | ||
conn.go | ||
example_test.go | ||
generate_cert.go | ||
handshake_client_test.go | ||
handshake_client.go | ||
handshake_messages_test.go | ||
handshake_messages.go | ||
handshake_server_test.go | ||
handshake_server.go | ||
handshake_test.go | ||
key_agreement.go | ||
prf_test.go | ||
prf.go | ||
ticket.go | ||
tls_test.go | ||
tls.go |