mirror of
https://github.com/golang/go
synced 2024-11-26 17:56:55 -07:00
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>
This commit is contained in:
parent
f7ef5ca54a
commit
c9b9cd73bb
@ -237,12 +237,18 @@ Do not send CLs removing the interior tags from such phrases.
|
|||||||
|
|
||||||
<p><!-- CL 256897 -->
|
<p><!-- CL 256897 -->
|
||||||
I/O operations on closing or closed TLS connections can now be detected using
|
I/O operations on closing or closed TLS connections can now be detected using
|
||||||
the new <a href="/pkg/net/#ErrClosed">ErrClosed</a> error. A typical use
|
the new <a href="/pkg/net/#ErrClosed">ErrClosed</a> error. A typical use
|
||||||
would be <code>errors.Is(err, net.ErrClosed)</code>. In earlier releases
|
would be <code>errors.Is(err, net.ErrClosed)</code>. In earlier releases
|
||||||
the only way to reliably detect this case was to match the string returned
|
the only way to reliably detect this case was to match the string returned
|
||||||
by the <code>Error</code> method with <code>"tls: use of closed connection"</code>.
|
by the <code>Error</code> method with <code>"tls: use of closed connection"</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p><!-- CL 266037 -->
|
||||||
|
A default deadline is set in <a href="/pkg/crypto/tls/#Conn.Close">Close</a>
|
||||||
|
before sending the close notify alert, in order to prevent blocking
|
||||||
|
indefinitely.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="crypto/x509"><a href="/pkg/crypto/x509">crypto/x509</a></h3>
|
<h3 id="crypto/x509"><a href="/pkg/crypto/x509">crypto/x509</a></h3>
|
||||||
|
|
||||||
<p><!-- CL 235078 -->
|
<p><!-- CL 235078 -->
|
||||||
|
@ -1074,6 +1074,11 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Write writes data to the connection.
|
// 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) {
|
func (c *Conn) Write(b []byte) (int, error) {
|
||||||
// interlock with Close below
|
// interlock with Close below
|
||||||
for {
|
for {
|
||||||
@ -1232,8 +1237,12 @@ func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read can be made to time out and return a net.Error with Timeout() == true
|
// Read reads data from the connection.
|
||||||
// after a fixed time limit; see SetDeadline and SetReadDeadline.
|
//
|
||||||
|
// 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) {
|
func (c *Conn) Read(b []byte) (int, error) {
|
||||||
if err := c.Handshake(); err != nil {
|
if err := c.Handshake(); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -1301,9 +1310,10 @@ func (c *Conn) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var alertErr error
|
var alertErr error
|
||||||
|
|
||||||
if c.handshakeComplete() {
|
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 {
|
if err := c.conn.Close(); err != nil {
|
||||||
@ -1330,8 +1340,12 @@ func (c *Conn) closeNotify() error {
|
|||||||
defer c.out.Unlock()
|
defer c.out.Unlock()
|
||||||
|
|
||||||
if !c.closeNotifySent {
|
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.closeNotifyErr = c.sendAlertLocked(alertCloseNotify)
|
||||||
c.closeNotifySent = true
|
c.closeNotifySent = true
|
||||||
|
// Any subsequent writes will fail.
|
||||||
|
c.SetWriteDeadline(time.Now())
|
||||||
}
|
}
|
||||||
return c.closeNotifyErr
|
return c.closeNotifyErr
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user