aboutsummaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
authorKatie Hockman <katie@golang.org>2020-10-28 15:13:33 -0400
committerKatie Hockman <katie@golang.org>2020-11-07 02:12:20 +0000
commitc9b9cd73bb7a7828d34f4a7844f16c3fbc0674dd (patch)
tree0564a331780d6dd47ce03bd76d8887269bfc8b96 /src/crypto
parentf7ef5ca54a103ed67425e1efe6d39d3bc8067bad (diff)
downloadgo-c9b9cd73bb7a7828d34f4a7844f16c3fbc0674dd.tar.gz
go-c9b9cd73bb7a7828d34f4a7844f16c3fbc0674dd.zip
crypto/tls: set Deadline before sending close notify alert
This change also documents the need to set a Deadline before calling Read or Write. Fixes #31224 Change-Id: I89d6fe3ecb0a0076b4c61765f61c88056f951406 Reviewed-on: https://go-review.googlesource.com/c/go/+/266037 Trust: Katie Hockman <katie@golang.org> Run-TryBot: Katie Hockman <katie@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Filippo Valsorda <filippo@golang.org>
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/tls/conn.go22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go
index f1d4cb926c..ada19d6e7a 100644
--- a/src/crypto/tls/conn.go
+++ b/src/crypto/tls/conn.go
@@ -1074,6 +1074,11 @@ var (
)
// Write writes data to the connection.
+//
+// As Write calls Handshake, in order to prevent indefinite blocking a deadline
+// must be set for both Read and Write before Write is called when the handshake
+// has not yet completed. See SetDeadline, SetReadDeadline, and
+// SetWriteDeadline.
func (c *Conn) Write(b []byte) (int, error) {
// interlock with Close below
for {
@@ -1232,8 +1237,12 @@ func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
return nil
}
-// Read can be made to time out and return a net.Error with Timeout() == true
-// after a fixed time limit; see SetDeadline and SetReadDeadline.
+// Read reads data from the connection.
+//
+// As Read calls Handshake, in order to prevent indefinite blocking a deadline
+// must be set for both Read and Write before Read is called when the handshake
+// has not yet completed. See SetDeadline, SetReadDeadline, and
+// SetWriteDeadline.
func (c *Conn) Read(b []byte) (int, error) {
if err := c.Handshake(); err != nil {
return 0, err
@@ -1301,9 +1310,10 @@ func (c *Conn) Close() error {
}
var alertErr error
-
if c.handshakeComplete() {
- alertErr = c.closeNotify()
+ if err := c.closeNotify(); err != nil {
+ alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err)
+ }
}
if err := c.conn.Close(); err != nil {
@@ -1330,8 +1340,12 @@ func (c *Conn) closeNotify() error {
defer c.out.Unlock()
if !c.closeNotifySent {
+ // Set a Write Deadline to prevent possibly blocking forever.
+ c.SetWriteDeadline(time.Now().Add(time.Second * 5))
c.closeNotifyErr = c.sendAlertLocked(alertCloseNotify)
c.closeNotifySent = true
+ // Any subsequent writes will fail.
+ c.SetWriteDeadline(time.Now())
}
return c.closeNotifyErr
}