implement the max_datagram_frame_size transport parameter

This commit is contained in:
Marten Seemann 2019-10-06 10:13:10 +02:00
parent d6eff22f9a
commit 021f70aac5
3 changed files with 27 additions and 13 deletions

View file

@ -46,11 +46,12 @@ var _ = Describe("Transport Parameters", func() {
MaxAckDelay: 37 * time.Millisecond, MaxAckDelay: 37 * time.Millisecond,
StatelessResetToken: &protocol.StatelessResetToken{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00}, StatelessResetToken: &protocol.StatelessResetToken{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00},
ActiveConnectionIDLimit: 123, ActiveConnectionIDLimit: 123,
MaxDatagramFrameSize: 876,
} }
Expect(p.String()).To(Equal("&wire.TransportParameters{OriginalDestinationConnectionID: 0xdeadbeef, InitialSourceConnectionID: 0xdecafbad, RetrySourceConnectionID: 0xdeadc0de, InitialMaxStreamDataBidiLocal: 1234, InitialMaxStreamDataBidiRemote: 2345, InitialMaxStreamDataUni: 3456, InitialMaxData: 4567, MaxBidiStreamNum: 1337, MaxUniStreamNum: 7331, MaxIdleTimeout: 42s, AckDelayExponent: 14, MaxAckDelay: 37ms, ActiveConnectionIDLimit: 123, StatelessResetToken: 0x112233445566778899aabbccddeeff00}")) Expect(p.String()).To(Equal("&wire.TransportParameters{OriginalDestinationConnectionID: 0xdeadbeef, InitialSourceConnectionID: 0xdecafbad, RetrySourceConnectionID: 0xdeadc0de, InitialMaxStreamDataBidiLocal: 1234, InitialMaxStreamDataBidiRemote: 2345, InitialMaxStreamDataUni: 3456, InitialMaxData: 4567, MaxBidiStreamNum: 1337, MaxUniStreamNum: 7331, MaxIdleTimeout: 42s, AckDelayExponent: 14, MaxAckDelay: 37ms, ActiveConnectionIDLimit: 123, StatelessResetToken: 0x112233445566778899aabbccddeeff00, MaxDatagramFrameSize: 876}"))
}) })
It("has a string representation, if there's no stateless reset token and no Retry source connection id", func() { It("has a string representation, if there's no stateless reset token, no Retry source connection id and no datagram support", func() {
p := &TransportParameters{ p := &TransportParameters{
InitialMaxStreamDataBidiLocal: 1234, InitialMaxStreamDataBidiLocal: 1234,
InitialMaxStreamDataBidiRemote: 2345, InitialMaxStreamDataBidiRemote: 2345,
@ -64,6 +65,7 @@ var _ = Describe("Transport Parameters", func() {
AckDelayExponent: 14, AckDelayExponent: 14,
MaxAckDelay: 37 * time.Second, MaxAckDelay: 37 * time.Second,
ActiveConnectionIDLimit: 89, ActiveConnectionIDLimit: 89,
MaxDatagramFrameSize: protocol.InvalidByteCount,
} }
Expect(p.String()).To(Equal("&wire.TransportParameters{OriginalDestinationConnectionID: 0xdeadbeef, InitialSourceConnectionID: (empty), InitialMaxStreamDataBidiLocal: 1234, InitialMaxStreamDataBidiRemote: 2345, InitialMaxStreamDataUni: 3456, InitialMaxData: 4567, MaxBidiStreamNum: 1337, MaxUniStreamNum: 7331, MaxIdleTimeout: 42s, AckDelayExponent: 14, MaxAckDelay: 37s, ActiveConnectionIDLimit: 89}")) Expect(p.String()).To(Equal("&wire.TransportParameters{OriginalDestinationConnectionID: 0xdeadbeef, InitialSourceConnectionID: (empty), InitialMaxStreamDataBidiLocal: 1234, InitialMaxStreamDataBidiRemote: 2345, InitialMaxStreamDataUni: 3456, InitialMaxData: 4567, MaxBidiStreamNum: 1337, MaxUniStreamNum: 7331, MaxIdleTimeout: 42s, AckDelayExponent: 14, MaxAckDelay: 37s, ActiveConnectionIDLimit: 89}"))
}) })
@ -87,6 +89,7 @@ var _ = Describe("Transport Parameters", func() {
AckDelayExponent: 13, AckDelayExponent: 13,
MaxAckDelay: 42 * time.Millisecond, MaxAckDelay: 42 * time.Millisecond,
ActiveConnectionIDLimit: getRandomValue(), ActiveConnectionIDLimit: getRandomValue(),
MaxDatagramFrameSize: protocol.ByteCount(getRandomValue()),
} }
data := params.Marshal(protocol.PerspectiveServer) data := params.Marshal(protocol.PerspectiveServer)
@ -107,6 +110,7 @@ var _ = Describe("Transport Parameters", func() {
Expect(p.AckDelayExponent).To(Equal(uint8(13))) Expect(p.AckDelayExponent).To(Equal(uint8(13)))
Expect(p.MaxAckDelay).To(Equal(42 * time.Millisecond)) Expect(p.MaxAckDelay).To(Equal(42 * time.Millisecond))
Expect(p.ActiveConnectionIDLimit).To(Equal(params.ActiveConnectionIDLimit)) Expect(p.ActiveConnectionIDLimit).To(Equal(params.ActiveConnectionIDLimit))
Expect(p.MaxDatagramFrameSize).To(Equal(params.MaxDatagramFrameSize))
}) })
It("doesn't marshal a retry_source_connection_id, if no Retry was performed", func() { It("doesn't marshal a retry_source_connection_id, if no Retry was performed", func() {

View file

@ -42,6 +42,8 @@ const (
activeConnectionIDLimitParameterID transportParameterID = 0xe activeConnectionIDLimitParameterID transportParameterID = 0xe
initialSourceConnectionIDParameterID transportParameterID = 0xf initialSourceConnectionIDParameterID transportParameterID = 0xf
retrySourceConnectionIDParameterID transportParameterID = 0x10 retrySourceConnectionIDParameterID transportParameterID = 0x10
// https://datatracker.ietf.org/doc/draft-ietf-quic-datagram/
maxDatagramFrameSizeParameterID transportParameterID = 0x20
) )
// PreferredAddress is the value encoding in the preferred_address transport parameter // PreferredAddress is the value encoding in the preferred_address transport parameter
@ -81,6 +83,8 @@ type TransportParameters struct {
StatelessResetToken *protocol.StatelessResetToken StatelessResetToken *protocol.StatelessResetToken
ActiveConnectionIDLimit uint64 ActiveConnectionIDLimit uint64
MaxDatagramFrameSize protocol.ByteCount
} }
// Unmarshal the transport parameters // Unmarshal the transport parameters
@ -96,12 +100,14 @@ func (p *TransportParameters) unmarshal(r *bytes.Reader, sentBy protocol.Perspec
var parameterIDs []transportParameterID var parameterIDs []transportParameterID
var ( var (
readAckDelayExponent bool
readMaxAckDelay bool
readOriginalDestinationConnectionID bool readOriginalDestinationConnectionID bool
readInitialSourceConnectionID bool readInitialSourceConnectionID bool
) )
p.AckDelayExponent = protocol.DefaultAckDelayExponent
p.MaxAckDelay = protocol.DefaultMaxAckDelay
p.MaxDatagramFrameSize = protocol.InvalidByteCount
for r.Len() > 0 { for r.Len() > 0 {
paramIDInt, err := utils.ReadVarInt(r) paramIDInt, err := utils.ReadVarInt(r)
if err != nil { if err != nil {
@ -118,12 +124,10 @@ func (p *TransportParameters) unmarshal(r *bytes.Reader, sentBy protocol.Perspec
parameterIDs = append(parameterIDs, paramID) parameterIDs = append(parameterIDs, paramID)
switch paramID { switch paramID {
case ackDelayExponentParameterID: case ackDelayExponentParameterID:
readAckDelayExponent = true
if err := p.readNumericTransportParameter(r, paramID, int(paramLen)); err != nil { if err := p.readNumericTransportParameter(r, paramID, int(paramLen)); err != nil {
return err return err
} }
case maxAckDelayParameterID: case maxAckDelayParameterID:
readMaxAckDelay = true
if err := p.readNumericTransportParameter(r, paramID, int(paramLen)); err != nil { if err := p.readNumericTransportParameter(r, paramID, int(paramLen)); err != nil {
return err return err
} }
@ -135,7 +139,8 @@ func (p *TransportParameters) unmarshal(r *bytes.Reader, sentBy protocol.Perspec
initialMaxStreamsUniParameterID, initialMaxStreamsUniParameterID,
maxIdleTimeoutParameterID, maxIdleTimeoutParameterID,
maxUDPPayloadSizeParameterID, maxUDPPayloadSizeParameterID,
activeConnectionIDLimitParameterID: activeConnectionIDLimitParameterID,
maxDatagramFrameSizeParameterID:
if err := p.readNumericTransportParameter(r, paramID, int(paramLen)); err != nil { if err := p.readNumericTransportParameter(r, paramID, int(paramLen)); err != nil {
return err return err
} }
@ -185,12 +190,6 @@ func (p *TransportParameters) unmarshal(r *bytes.Reader, sentBy protocol.Perspec
if sentBy == protocol.PerspectiveServer && !readOriginalDestinationConnectionID { if sentBy == protocol.PerspectiveServer && !readOriginalDestinationConnectionID {
return errors.New("missing original_destination_connection_id") return errors.New("missing original_destination_connection_id")
} }
if !readAckDelayExponent {
p.AckDelayExponent = protocol.DefaultAckDelayExponent
}
if !readMaxAckDelay {
p.MaxAckDelay = protocol.DefaultMaxAckDelay
}
if p.MaxUDPPayloadSize == 0 { if p.MaxUDPPayloadSize == 0 {
p.MaxUDPPayloadSize = protocol.MaxByteCount p.MaxUDPPayloadSize = protocol.MaxByteCount
} }
@ -305,6 +304,8 @@ func (p *TransportParameters) readNumericTransportParameter(
p.MaxAckDelay = maxAckDelay p.MaxAckDelay = maxAckDelay
case activeConnectionIDLimitParameterID: case activeConnectionIDLimitParameterID:
p.ActiveConnectionIDLimit = val p.ActiveConnectionIDLimit = val
case maxDatagramFrameSizeParameterID:
p.MaxDatagramFrameSize = protocol.ByteCount(val)
default: default:
return fmt.Errorf("TransportParameter BUG: transport parameter %d not found", paramID) return fmt.Errorf("TransportParameter BUG: transport parameter %d not found", paramID)
} }
@ -391,6 +392,9 @@ func (p *TransportParameters) Marshal(pers protocol.Perspective) []byte {
utils.WriteVarInt(b, uint64(p.RetrySourceConnectionID.Len())) utils.WriteVarInt(b, uint64(p.RetrySourceConnectionID.Len()))
b.Write(p.RetrySourceConnectionID.Bytes()) b.Write(p.RetrySourceConnectionID.Bytes())
} }
if p.MaxDatagramFrameSize != protocol.InvalidByteCount {
p.marshalVarintParam(b, maxDatagramFrameSizeParameterID, uint64(p.MaxDatagramFrameSize))
}
return b.Bytes() return b.Bytes()
} }
@ -463,6 +467,10 @@ func (p *TransportParameters) String() string {
logString += ", StatelessResetToken: %#x" logString += ", StatelessResetToken: %#x"
logParams = append(logParams, *p.StatelessResetToken) logParams = append(logParams, *p.StatelessResetToken)
} }
if p.MaxDatagramFrameSize != protocol.InvalidByteCount {
logString += ", MaxDatagramFrameSize: %d"
logParams = append(logParams, p.MaxDatagramFrameSize)
}
logString += "}" logString += "}"
return fmt.Sprintf(logString, logParams...) return fmt.Sprintf(logString, logParams...)
} }

View file

@ -294,6 +294,7 @@ var newSession = func(
ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs, ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs,
InitialSourceConnectionID: srcConnID, InitialSourceConnectionID: srcConnID,
RetrySourceConnectionID: retrySrcConnID, RetrySourceConnectionID: retrySrcConnID,
MaxDatagramFrameSize: protocol.InvalidByteCount, // disable DATAGRAMs
} }
if s.tracer != nil { if s.tracer != nil {
s.tracer.SentTransportParameters(params) s.tracer.SentTransportParameters(params)
@ -413,6 +414,7 @@ var newClientSession = func(
DisableActiveMigration: true, DisableActiveMigration: true,
ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs, ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs,
InitialSourceConnectionID: srcConnID, InitialSourceConnectionID: srcConnID,
MaxDatagramFrameSize: protocol.InvalidByteCount, // disable DATAGRAMs
} }
if s.tracer != nil { if s.tracer != nil {
s.tracer.SentTransportParameters(params) s.tracer.SentTransportParameters(params)