@@ -1074,6 +1074,11 @@ var (
1074
1074
)
1075
1075
1076
1076
// Write writes data to the connection.
1077
+ //
1078
+ // As Write calls Handshake, in order to prevent indefinite blocking a deadline
1079
+ // must be set for both Read and Write before Write is called when the handshake
1080
+ // has not yet completed. See SetDeadline, SetReadDeadline, and
1081
+ // SetWriteDeadline.
1077
1082
func (c * Conn ) Write (b []byte ) (int , error ) {
1078
1083
// interlock with Close below
1079
1084
for {
@@ -1232,8 +1237,12 @@ func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
1232
1237
return nil
1233
1238
}
1234
1239
1235
- // Read can be made to time out and return a net.Error with Timeout() == true
1236
- // after a fixed time limit; see SetDeadline and SetReadDeadline.
1240
+ // Read reads data from the connection.
1241
+ //
1242
+ // As Read calls Handshake, in order to prevent indefinite blocking a deadline
1243
+ // must be set for both Read and Write before Read is called when the handshake
1244
+ // has not yet completed. See SetDeadline, SetReadDeadline, and
1245
+ // SetWriteDeadline.
1237
1246
func (c * Conn ) Read (b []byte ) (int , error ) {
1238
1247
if err := c .Handshake (); err != nil {
1239
1248
return 0 , err
@@ -1301,9 +1310,10 @@ func (c *Conn) Close() error {
1301
1310
}
1302
1311
1303
1312
var alertErr error
1304
-
1305
1313
if c .handshakeComplete () {
1306
- alertErr = c .closeNotify ()
1314
+ if err := c .closeNotify (); err != nil {
1315
+ alertErr = fmt .Errorf ("tls: failed to send closeNotify alert (but connection was closed anyway): %w" , err )
1316
+ }
1307
1317
}
1308
1318
1309
1319
if err := c .conn .Close (); err != nil {
@@ -1330,8 +1340,12 @@ func (c *Conn) closeNotify() error {
1330
1340
defer c .out .Unlock ()
1331
1341
1332
1342
if ! c .closeNotifySent {
1343
+ // Set a Write Deadline to prevent possibly blocking forever.
1344
+ c .SetWriteDeadline (time .Now ().Add (time .Second * 5 ))
1333
1345
c .closeNotifyErr = c .sendAlertLocked (alertCloseNotify )
1334
1346
c .closeNotifySent = true
1347
+ // Any subsequent writes will fail.
1348
+ c .SetWriteDeadline (time .Now ())
1335
1349
}
1336
1350
return c .closeNotifyErr
1337
1351
}
0 commit comments