diff --git a/internal/handshake/transport_parameter_test.go b/internal/handshake/transport_parameter_test.go index 1628c4ac1..48ccc3711 100644 --- a/internal/handshake/transport_parameter_test.go +++ b/internal/handshake/transport_parameter_test.go @@ -139,10 +139,16 @@ var _ = Describe("Transport Parameters", func() { }) It("doesn't send the max_ack_delay, if it has the default value", func() { - dataDefault := (&TransportParameters{MaxAckDelay: protocol.DefaultMaxAckDelay}).Marshal() - defaultLen := len(dataDefault) - data := (&TransportParameters{MaxAckDelay: protocol.DefaultMaxAckDelay + time.Millisecond}).Marshal() - Expect(len(data)).To(Equal(defaultLen + 2 /* parameter ID */ + 2 /* length field */ + 1 /* value */)) + const num = 1000 + var defaultLen, dataLen int + // marshal 1000 times to average out the greasing transport parameter + for i := 0; i < num; i++ { + dataDefault := (&TransportParameters{MaxAckDelay: protocol.DefaultMaxAckDelay}).Marshal() + defaultLen += len(dataDefault) + data := (&TransportParameters{MaxAckDelay: protocol.DefaultMaxAckDelay + time.Millisecond}).Marshal() + dataLen += len(data) + } + Expect(float32(dataLen) / num).To(BeNumerically("~", float32(defaultLen)/num+2 /* parameter ID */ +2 /* length field */ +1 /* value */, 1)) }) It("errors when the ack_delay_exponenent is too large", func() { @@ -152,10 +158,16 @@ var _ = Describe("Transport Parameters", func() { }) It("doesn't send the ack_delay_exponent, if it has the default value", func() { - dataDefault := (&TransportParameters{AckDelayExponent: protocol.DefaultAckDelayExponent}).Marshal() - defaultLen := len(dataDefault) - data := (&TransportParameters{AckDelayExponent: protocol.DefaultAckDelayExponent + 1}).Marshal() - Expect(len(data)).To(Equal(defaultLen + 2 /* parameter ID */ + 2 /* length field */ + 1 /* value */)) + const num = 1000 + var defaultLen, dataLen int + // marshal 1000 times to average out the greasing transport parameter + for i := 0; i < num; i++ { + dataDefault := (&TransportParameters{AckDelayExponent: protocol.DefaultAckDelayExponent}).Marshal() + defaultLen += len(dataDefault) + data := (&TransportParameters{AckDelayExponent: protocol.DefaultAckDelayExponent + 1}).Marshal() + dataLen += len(data) + } + Expect(float32(dataLen) / num).To(BeNumerically("~", float32(defaultLen)/num+2 /* parameter ID */ +2 /* length field */ +1 /* value */, 1)) }) It("sets the default value for the ack_delay_exponent, when no value was sent", func() { diff --git a/internal/handshake/transport_parameters.go b/internal/handshake/transport_parameters.go index 724c3586e..0c9928046 100644 --- a/internal/handshake/transport_parameters.go +++ b/internal/handshake/transport_parameters.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "math/rand" "sort" "time" @@ -13,6 +14,10 @@ import ( "github.com/lucas-clemente/quic-go/internal/utils" ) +func init() { + rand.Seed(time.Now().UTC().UnixNano()) +} + type transportParameterID uint16 const ( @@ -204,6 +209,14 @@ func (p *TransportParameters) Marshal() []byte { b := &bytes.Buffer{} b.Write([]byte{0, 0}) // length. Will be replaced later + // add a greased value + utils.BigEndian.WriteUint16(b, uint16(27+31*rand.Intn(100))) + len := rand.Intn(16) + randomData := make([]byte, len) + rand.Read(randomData) + utils.BigEndian.WriteUint16(b, uint16(len)) + b.Write(randomData) + // initial_max_stream_data_bidi_local p.marshalVarintParam(b, initialMaxStreamDataBidiLocalParameterID, uint64(p.InitialMaxStreamDataBidiLocal)) // initial_max_stream_data_bidi_remote