marshal and unmarshal the retry_source_connection_id TP

This commit is contained in:
Marten Seemann 2020-05-24 16:33:49 +07:00
parent fb2a5f413e
commit 4451f3bf5c
2 changed files with 47 additions and 5 deletions

View file

@ -43,15 +43,16 @@ var _ = Describe("Transport Parameters", func() {
MaxIdleTimeout: 42 * time.Second,
OriginalDestinationConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
InitialSourceConnectionID: protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad},
RetrySourceConnectionID: &protocol.ConnectionID{0xde, 0xad, 0xc0, 0xde},
AckDelayExponent: 14,
MaxAckDelay: 37 * time.Millisecond,
StatelessResetToken: &[16]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00},
ActiveConnectionIDLimit: 123,
}
Expect(p.String()).To(Equal("&wire.TransportParameters{OriginalDestinationConnectionID: 0xdeadbeef, InitialSourceConnectionID: 0xdecafbad, 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}"))
})
It("has a string representation, if there's no stateless reset token", func() {
It("has a string representation, if there's no stateless reset token and no Retry source connection id", func() {
p := &TransportParameters{
InitialMaxStreamDataBidiLocal: 1234,
InitialMaxStreamDataBidiRemote: 2345,
@ -84,6 +85,7 @@ var _ = Describe("Transport Parameters", func() {
StatelessResetToken: &token,
OriginalDestinationConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
InitialSourceConnectionID: protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad},
RetrySourceConnectionID: &protocol.ConnectionID{0xde, 0xad, 0xc0, 0xde},
AckDelayExponent: 13,
MaxAckDelay: 42 * time.Millisecond,
ActiveConnectionIDLimit: getRandomValue(),
@ -103,11 +105,32 @@ var _ = Describe("Transport Parameters", func() {
Expect(p.StatelessResetToken).To(Equal(params.StatelessResetToken))
Expect(p.OriginalDestinationConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}))
Expect(p.InitialSourceConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad}))
Expect(p.RetrySourceConnectionID).To(Equal(&protocol.ConnectionID{0xde, 0xad, 0xc0, 0xde}))
Expect(p.AckDelayExponent).To(Equal(uint8(13)))
Expect(p.MaxAckDelay).To(Equal(42 * time.Millisecond))
Expect(p.ActiveConnectionIDLimit).To(Equal(params.ActiveConnectionIDLimit))
})
It("doesn't marshal a retry_source_connection_id, if no Retry was performed", func() {
data := (&TransportParameters{
StatelessResetToken: &token,
}).Marshal(protocol.PerspectiveServer)
p := &TransportParameters{}
Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(Succeed())
Expect(p.RetrySourceConnectionID).To(BeNil())
})
It("marshals a zero-length retry_source_connection_id", func() {
data := (&TransportParameters{
RetrySourceConnectionID: &protocol.ConnectionID{},
StatelessResetToken: &token,
}).Marshal(protocol.PerspectiveServer)
p := &TransportParameters{}
Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(Succeed())
Expect(p.RetrySourceConnectionID).ToNot(BeNil())
Expect(p.RetrySourceConnectionID.Len()).To(BeZero())
})
It("errors when the stateless_reset_token has the wrong length", func() {
b := &bytes.Buffer{}
utils.WriteVarInt(b, uint64(statelessResetTokenParameterID))

View file

@ -41,6 +41,7 @@ const (
preferredAddressParameterID transportParameterID = 0xd
activeConnectionIDLimitParameterID transportParameterID = 0xe
initialSourceConnectionIDParameterID transportParameterID = 0xf
retrySourceConnectionIDParameterID transportParameterID = 0x10
)
// PreferredAddress is the value encoding in the preferred_address transport parameter
@ -76,6 +77,7 @@ type TransportParameters struct {
OriginalDestinationConnectionID protocol.ConnectionID
InitialSourceConnectionID protocol.ConnectionID
RetrySourceConnectionID *protocol.ConnectionID // use a pointer here to distinguish zero-length connection IDs from missing transport parameters
StatelessResetToken *[16]byte
ActiveConnectionIDLimit uint64
@ -171,6 +173,12 @@ func (p *TransportParameters) unmarshal(data []byte, sentBy protocol.Perspective
case initialSourceConnectionIDParameterID:
p.InitialSourceConnectionID, _ = protocol.ReadConnectionID(r, int(paramLen))
readInitialSourceConnectionID = true
case retrySourceConnectionIDParameterID:
if sentBy == protocol.PerspectiveClient {
return errors.New("client sent a retry_source_connection_id")
}
connID, _ := protocol.ReadConnectionID(r, int(paramLen))
p.RetrySourceConnectionID = &connID
default:
r.Seek(int64(paramLen), io.SeekCurrent)
}
@ -378,7 +386,12 @@ func (p *TransportParameters) Marshal(pers protocol.Perspective) []byte {
utils.WriteVarInt(b, uint64(initialSourceConnectionIDParameterID))
utils.WriteVarInt(b, uint64(p.InitialSourceConnectionID.Len()))
b.Write(p.InitialSourceConnectionID.Bytes())
// retry_source_connection_id
if pers == protocol.PerspectiveServer && p.RetrySourceConnectionID != nil {
utils.WriteVarInt(b, uint64(retrySourceConnectionIDParameterID))
utils.WriteVarInt(b, uint64(p.RetrySourceConnectionID.Len()))
b.Write(p.RetrySourceConnectionID.Bytes())
}
return b.Bytes()
}
@ -440,8 +453,14 @@ func (p *TransportParameters) ValidFor0RTT(tp *TransportParameters) bool {
// String returns a string representation, intended for logging.
func (p *TransportParameters) String() string {
logString := "&wire.TransportParameters{OriginalDestinationConnectionID: %s, InitialSourceConnectionID: %s, InitialMaxStreamDataBidiLocal: %d, InitialMaxStreamDataBidiRemote: %d, InitialMaxStreamDataUni: %d, InitialMaxData: %d, MaxBidiStreamNum: %d, MaxUniStreamNum: %d, MaxIdleTimeout: %s, AckDelayExponent: %d, MaxAckDelay: %s, ActiveConnectionIDLimit: %d"
logParams := []interface{}{p.OriginalDestinationConnectionID, p.InitialSourceConnectionID, p.InitialMaxStreamDataBidiLocal, p.InitialMaxStreamDataBidiRemote, p.InitialMaxStreamDataUni, p.InitialMaxData, p.MaxBidiStreamNum, p.MaxUniStreamNum, p.MaxIdleTimeout, p.AckDelayExponent, p.MaxAckDelay, p.ActiveConnectionIDLimit}
logString := "&wire.TransportParameters{OriginalDestinationConnectionID: %s, InitialSourceConnectionID: %s, "
logParams := []interface{}{p.OriginalDestinationConnectionID, p.InitialSourceConnectionID}
if p.RetrySourceConnectionID != nil {
logString += "RetrySourceConnectionID: %s, "
logParams = append(logParams, p.RetrySourceConnectionID)
}
logString += "InitialMaxStreamDataBidiLocal: %d, InitialMaxStreamDataBidiRemote: %d, InitialMaxStreamDataUni: %d, InitialMaxData: %d, MaxBidiStreamNum: %d, MaxUniStreamNum: %d, MaxIdleTimeout: %s, AckDelayExponent: %d, MaxAckDelay: %s, ActiveConnectionIDLimit: %d"
logParams = append(logParams, []interface{}{p.InitialMaxStreamDataBidiLocal, p.InitialMaxStreamDataBidiRemote, p.InitialMaxStreamDataUni, p.InitialMaxData, p.MaxBidiStreamNum, p.MaxUniStreamNum, p.MaxIdleTimeout, p.AckDelayExponent, p.MaxAckDelay, p.ActiveConnectionIDLimit}...)
if p.StatelessResetToken != nil { // the client never sends a stateless reset token
logString += ", StatelessResetToken: %#x"
logParams = append(logParams, *p.StatelessResetToken)