mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
crypto/tls: buffer handshake messages.
This change causes TLS handshake messages to be buffered and written in
a single Write to the underlying net.Conn.
There are two reasons to want to do this:
Firstly, it's slightly preferable to do this in order to save sending
several, small packets over the network where a single one will do.
Secondly, since 37c28759ca errors from
Write have been returned from a handshake. This means that, if a peer
closes the connection during a handshake, a “broken pipe” error may
result from tls.Conn.Handshake(). This can mask any, more detailed,
fatal alerts that the peer may have sent because a read will never
happen.
Buffering handshake messages means that the peer will not receive, and
possibly reject, any of a flow while it's still being written.
Fixes #15709
Change-Id: I38dcff1abecc06e52b2de647ea98713ce0fb9a21
Reviewed-on: https://go-review.googlesource.com/23609
Reviewed-by: Andrew Gerrand <adg@golang.org>
Run-TryBot: Andrew Gerrand <adg@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
f6c0241999
commit
2a8c81ffaa
4 changed files with 93 additions and 7 deletions
|
|
@ -983,7 +983,7 @@ func (b *brokenConn) Write(data []byte) (int, error) {
|
|||
|
||||
func TestFailedWrite(t *testing.T) {
|
||||
// Test that a write error during the handshake is returned.
|
||||
for _, breakAfter := range []int{0, 1, 2, 3} {
|
||||
for _, breakAfter := range []int{0, 1} {
|
||||
c, s := net.Pipe()
|
||||
done := make(chan bool)
|
||||
|
||||
|
|
@ -1003,3 +1003,45 @@ func TestFailedWrite(t *testing.T) {
|
|||
<-done
|
||||
}
|
||||
}
|
||||
|
||||
// writeCountingConn wraps a net.Conn and counts the number of Write calls.
|
||||
type writeCountingConn struct {
|
||||
net.Conn
|
||||
|
||||
// numWrites is the number of writes that have been done.
|
||||
numWrites int
|
||||
}
|
||||
|
||||
func (wcc *writeCountingConn) Write(data []byte) (int, error) {
|
||||
wcc.numWrites++
|
||||
return wcc.Conn.Write(data)
|
||||
}
|
||||
|
||||
func TestBuffering(t *testing.T) {
|
||||
c, s := net.Pipe()
|
||||
done := make(chan bool)
|
||||
|
||||
clientWCC := &writeCountingConn{Conn: c}
|
||||
serverWCC := &writeCountingConn{Conn: s}
|
||||
|
||||
go func() {
|
||||
Server(serverWCC, testConfig).Handshake()
|
||||
serverWCC.Close()
|
||||
done <- true
|
||||
}()
|
||||
|
||||
err := Client(clientWCC, testConfig).Handshake()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
clientWCC.Close()
|
||||
<-done
|
||||
|
||||
if n := clientWCC.numWrites; n != 2 {
|
||||
t.Errorf("expected client handshake to complete with only two writes, but saw %d", n)
|
||||
}
|
||||
|
||||
if n := serverWCC.numWrites; n != 2 {
|
||||
t.Errorf("expected server handshake to complete with only two writes, but saw %d", n)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue