• Brad Fitzpatrick's avatar
    crypto/tls: don't block in Conn.Close if Writes are in-flight · 4ffba768
    Brad Fitzpatrick authored
    Conn.Close sends an encrypted "close notify" to signal secure EOF.
    But writing that involves acquiring mutexes (handshake mutex + the
    c.out mutex) and writing to the network. But if the reason we're
    calling Conn.Close is because the network is already being
    problematic, then Close might block, waiting for one of those mutexes.
    
    Instead of blocking, and instead of introducing new API (at least for
    now), distinguish between a normal Close (one that sends a secure EOF)
    and a resource-releasing destructor-style Close based on whether there
    are existing Write calls in-flight.
    
    Because io.Writer and io.Closer aren't defined with respect to
    concurrent usage, a Close with active Writes is already undefined, and
    should only be used during teardown after failures (e.g. deadlines or
    cancelations by HTTP users). A normal user will do a Write then
    serially do a Close, and things are unchanged for that case.
    
    This should fix the leaked goroutines and hung net/http.Transport
    requests when there are network errors while making TLS requests.
    
    Change-Id: If3f8c69d6fdcebf8c70227f41ad042ccc3f20ac9
    Reviewed-on: https://go-review.googlesource.com/18572Reviewed-by: 's avatarAdam Langley <agl@golang.org>
    Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
    Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    4ffba768
conn.go 29.9 KB