Write writes data to the connection. As Write calls [Conn.Handshake], in order to prevent indefinite blocking a deadline must be set for both [Conn.Read] and Write before Write is called when the handshake has not yet completed. See [Conn.SetDeadline], [Conn.SetReadDeadline], and [Conn.SetWriteDead
(b []byte)
| 1267 | // has not yet completed. See [Conn.SetDeadline], [Conn.SetReadDeadline], and |
| 1268 | // [Conn.SetWriteDeadline]. |
| 1269 | func (c *Conn) Write(b []byte) (int, error) { |
| 1270 | // interlock with Close below |
| 1271 | for { |
| 1272 | x := c.activeCall.Load() |
| 1273 | if x&1 != 0 { |
| 1274 | return 0, net.ErrClosed |
| 1275 | } |
| 1276 | if c.activeCall.CompareAndSwap(x, x+2) { |
| 1277 | break |
| 1278 | } |
| 1279 | } |
| 1280 | defer c.activeCall.Add(-2) |
| 1281 | |
| 1282 | if err := c.Handshake(); err != nil { |
| 1283 | return 0, err |
| 1284 | } |
| 1285 | |
| 1286 | c.out.Lock() |
| 1287 | defer c.out.Unlock() |
| 1288 | |
| 1289 | if err := c.out.err; err != nil { |
| 1290 | return 0, err |
| 1291 | } |
| 1292 | |
| 1293 | if !c.isHandshakeComplete.Load() { |
| 1294 | return 0, alertInternalError |
| 1295 | } |
| 1296 | |
| 1297 | if c.closeNotifySent { |
| 1298 | return 0, errShutdown |
| 1299 | } |
| 1300 | |
| 1301 | // TLS 1.0 is susceptible to a chosen-plaintext |
| 1302 | // attack when using block mode ciphers due to predictable IVs. |
| 1303 | // This can be prevented by splitting each Application Data |
| 1304 | // record into two records, effectively randomizing the IV. |
| 1305 | // |
| 1306 | // https://www.openssl.org/~bodo/tls-cbc.txt |
| 1307 | // https://bugzilla.mozilla.org/show_bug.cgi?id=665814 |
| 1308 | // https://www.imperialviolet.org/2012/01/15/beastfollowup.html |
| 1309 | |
| 1310 | var m int |
| 1311 | if len(b) > 1 && c.vers == VersionTLS10 { |
| 1312 | if _, ok := c.out.cipher.(cipher.BlockMode); ok { |
| 1313 | n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1]) |
| 1314 | if err != nil { |
| 1315 | return n, c.out.setErrorLocked(err) |
| 1316 | } |
| 1317 | m, b = 1, b[1:] |
| 1318 | } |
| 1319 | } |
| 1320 | |
| 1321 | n, err := c.writeRecordLocked(recordTypeApplicationData, b) |
| 1322 | return n + m, c.out.setErrorLocked(err) |
| 1323 | } |
| 1324 | |
| 1325 | // handleRenegotiation processes a HelloRequest handshake message. |
| 1326 | func (c *Conn) handleRenegotiation() error { |
nothing calls this directly
no test coverage detected