@@ -94,7 +94,6 @@ type Conn struct {
94
94
rawInput bytes.Buffer // raw input, starting with a record header
95
95
input bytes.Reader // application data waiting to be read, from rawInput.Next
96
96
hand bytes.Buffer // handshake data waiting to be read
97
- outBuf []byte // scratch buffer used by out.encrypt
98
97
buffering bool // whether records are buffered in sendBuf
99
98
sendBuf []byte // a buffer of records waiting to be sent
100
99
@@ -928,18 +927,37 @@ func (c *Conn) flush() (int, error) {
928
927
return n , err
929
928
}
930
929
930
+ // outBufPool pools the record-sized scratch buffers used by writeRecordLocked.
931
+ var outBufPool = sync.Pool {
932
+ New : func () interface {} {
933
+ return new ([]byte )
934
+ },
935
+ }
936
+
931
937
// writeRecordLocked writes a TLS record with the given type and payload to the
932
938
// connection and updates the record layer state.
933
939
func (c * Conn ) writeRecordLocked (typ recordType , data []byte ) (int , error ) {
940
+ outBufPtr := outBufPool .Get ().(* []byte )
941
+ outBuf := * outBufPtr
942
+ defer func () {
943
+ // You might be tempted to simplify this by just passing &outBuf to Put,
944
+ // but that would make the local copy of the outBuf slice header escape
945
+ // to the heap, causing an allocation. Instead, we keep around the
946
+ // pointer to the slice header returned by Get, which is already on the
947
+ // heap, and overwrite and return that.
948
+ * outBufPtr = outBuf
949
+ outBufPool .Put (outBufPtr )
950
+ }()
951
+
934
952
var n int
935
953
for len (data ) > 0 {
936
954
m := len (data )
937
955
if maxPayload := c .maxPayloadSizeForWrite (typ ); m > maxPayload {
938
956
m = maxPayload
939
957
}
940
958
941
- _ , c . outBuf = sliceForAppend (c . outBuf [:0 ], recordHeaderLen )
942
- c . outBuf [0 ] = byte (typ )
959
+ _ , outBuf = sliceForAppend (outBuf [:0 ], recordHeaderLen )
960
+ outBuf [0 ] = byte (typ )
943
961
vers := c .vers
944
962
if vers == 0 {
945
963
// Some TLS servers fail if the record version is
@@ -950,17 +968,17 @@ func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
950
968
// See RFC 8446, Section 5.1.
951
969
vers = VersionTLS12
952
970
}
953
- c . outBuf [1 ] = byte (vers >> 8 )
954
- c . outBuf [2 ] = byte (vers )
955
- c . outBuf [3 ] = byte (m >> 8 )
956
- c . outBuf [4 ] = byte (m )
971
+ outBuf [1 ] = byte (vers >> 8 )
972
+ outBuf [2 ] = byte (vers )
973
+ outBuf [3 ] = byte (m >> 8 )
974
+ outBuf [4 ] = byte (m )
957
975
958
976
var err error
959
- c . outBuf , err = c .out .encrypt (c . outBuf , data [:m ], c .config .rand ())
977
+ outBuf , err = c .out .encrypt (outBuf , data [:m ], c .config .rand ())
960
978
if err != nil {
961
979
return n , err
962
980
}
963
- if _ , err := c .write (c . outBuf ); err != nil {
981
+ if _ , err := c .write (outBuf ); err != nil {
964
982
return n , err
965
983
}
966
984
n += m
0 commit comments