parse and send the ack_delay_exponent in the transport parameters

This commit is contained in:
Marten Seemann
2019-01-07 15:09:14 +07:00
parent ee75f5e2f2
commit 155ebd18a2
5 changed files with 43 additions and 3 deletions

View File

@@ -380,6 +380,7 @@ func (c *client) createNewTLSSession(version protocol.VersionNumber) error {
IdleTimeout: c.config.IdleTimeout,
MaxBidiStreams: uint64(c.config.MaxIncomingStreams),
MaxUniStreams: uint64(c.config.MaxIncomingUniStreams),
AckDelayExponent: protocol.AckDelayExponent,
DisableMigration: true,
}

View File

@@ -23,8 +23,9 @@ var _ = Describe("Transport Parameters", func() {
MaxUniStreams: 7331,
IdleTimeout: 42 * time.Second,
OriginalConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
AckDelayExponent: 14,
}
Expect(p.String()).To(Equal("&handshake.TransportParameters{OriginalConnectionID: 0xdeadbeef, InitialMaxStreamDataBidiLocal: 0x1234, InitialMaxStreamDataBidiRemote: 0x2345, InitialMaxStreamDataUni: 0x3456, InitialMaxData: 0x4567, MaxBidiStreams: 1337, MaxUniStreams: 7331, IdleTimeout: 42s}"))
Expect(p.String()).To(Equal("&handshake.TransportParameters{OriginalConnectionID: 0xdeadbeef, InitialMaxStreamDataBidiLocal: 0x1234, InitialMaxStreamDataBidiRemote: 0x2345, InitialMaxStreamDataUni: 0x3456, InitialMaxData: 0x4567, MaxBidiStreams: 1337, MaxUniStreams: 7331, IdleTimeout: 42s, AckDelayExponent: 14}"))
})
getRandomValue := func() uint64 {
@@ -45,6 +46,7 @@ var _ = Describe("Transport Parameters", func() {
DisableMigration: true,
StatelessResetToken: bytes.Repeat([]byte{100}, 16),
OriginalConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
AckDelayExponent: 13,
}
b := &bytes.Buffer{}
params.marshal(b)
@@ -61,6 +63,7 @@ var _ = Describe("Transport Parameters", func() {
Expect(p.DisableMigration).To(Equal(params.DisableMigration))
Expect(p.StatelessResetToken).To(Equal(params.StatelessResetToken))
Expect(p.OriginalConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}))
Expect(p.AckDelayExponent).To(Equal(uint8(13)))
})
It("errors when the stateless_reset_token has the wrong length", func() {
@@ -89,6 +92,22 @@ var _ = Describe("Transport Parameters", func() {
Expect(p.unmarshal(b.Bytes(), protocol.PerspectiveServer)).To(MatchError("wrong length for disable_migration: 6 (expected empty)"))
})
It("errors when the ack_delay_exponenent is too large", func() {
b := &bytes.Buffer{}
(&TransportParameters{AckDelayExponent: 21}).marshal(b)
p := &TransportParameters{}
Expect(p.unmarshal(b.Bytes(), protocol.PerspectiveServer)).To(MatchError("invalid value for ack_delay_exponent: 21 (maximum 20)"))
})
It("doesn't send the ack_delay_exponent, if it has the default value", func() {
b := &bytes.Buffer{}
(&TransportParameters{AckDelayExponent: protocol.DefaultAckDelayExponent}).marshal(b)
defaultLen := b.Len()
b.Reset()
(&TransportParameters{AckDelayExponent: protocol.DefaultAckDelayExponent + 1}).marshal(b)
Expect(b.Len()).To(Equal(defaultLen + 2 /* parameter ID */ + 2 /* length field */ + 1 /* value */))
})
It("errors when the varint value has the wrong length", func() {
b := &bytes.Buffer{}
utils.BigEndian.WriteUint16(b, uint16(initialMaxStreamDataBidiLocalParameterID))

View File

@@ -25,6 +25,7 @@ const (
initialMaxStreamDataUniParameterID transportParameterID = 0x7
initialMaxStreamsBidiParameterID transportParameterID = 0x8
initialMaxStreamsUniParameterID transportParameterID = 0x9
ackDelayExponentParameterID transportParameterID = 0xa
disableMigrationParameterID transportParameterID = 0xc
)
@@ -35,6 +36,8 @@ type TransportParameters struct {
InitialMaxStreamDataUni protocol.ByteCount
InitialMaxData protocol.ByteCount
AckDelayExponent uint8
MaxPacketSize protocol.ByteCount
MaxUniStreams uint64
@@ -65,7 +68,8 @@ func (p *TransportParameters) unmarshal(data []byte, sentBy protocol.Perspective
initialMaxStreamsBidiParameterID,
initialMaxStreamsUniParameterID,
idleTimeoutParameterID,
maxPacketSizeParameterID:
maxPacketSizeParameterID,
ackDelayExponentParameterID:
if err := p.readNumericTransportParameter(r, paramID, int(paramLen)); err != nil {
return err
}
@@ -147,6 +151,11 @@ func (p *TransportParameters) readNumericTransportParameter(
return fmt.Errorf("invalid value for max_packet_size: %d (minimum 1200)", val)
}
p.MaxPacketSize = protocol.ByteCount(val)
case ackDelayExponentParameterID:
if val > 20 {
return fmt.Errorf("invalid value for ack_delay_exponent: %d (maximum 20)", val)
}
p.AckDelayExponent = uint8(val)
default:
return fmt.Errorf("TransportParameter BUG: transport parameter %d not found", paramID)
}
@@ -186,6 +195,13 @@ func (p *TransportParameters) marshal(b *bytes.Buffer) {
utils.BigEndian.WriteUint16(b, uint16(maxPacketSizeParameterID))
utils.BigEndian.WriteUint16(b, uint16(utils.VarIntLen(uint64(protocol.MaxReceivePacketSize))))
utils.WriteVarInt(b, uint64(protocol.MaxReceivePacketSize))
// ack_delay_exponent
// Only send it if is different from the default value.
if p.AckDelayExponent != protocol.DefaultAckDelayExponent {
utils.BigEndian.WriteUint16(b, uint16(ackDelayExponentParameterID))
utils.BigEndian.WriteUint16(b, uint16(utils.VarIntLen(uint64(p.AckDelayExponent))))
utils.WriteVarInt(b, uint64(p.AckDelayExponent))
}
// disable_migration
if p.DisableMigration {
utils.BigEndian.WriteUint16(b, uint16(disableMigrationParameterID))
@@ -206,5 +222,5 @@ func (p *TransportParameters) marshal(b *bytes.Buffer) {
// String returns a string representation, intended for logging.
func (p *TransportParameters) String() string {
return fmt.Sprintf("&handshake.TransportParameters{OriginalConnectionID: %s, InitialMaxStreamDataBidiLocal: %#x, InitialMaxStreamDataBidiRemote: %#x, InitialMaxStreamDataUni: %#x, InitialMaxData: %#x, MaxBidiStreams: %d, MaxUniStreams: %d, IdleTimeout: %s}", p.OriginalConnectionID, p.InitialMaxStreamDataBidiLocal, p.InitialMaxStreamDataBidiRemote, p.InitialMaxStreamDataUni, p.InitialMaxData, p.MaxBidiStreams, p.MaxUniStreams, p.IdleTimeout)
return fmt.Sprintf("&handshake.TransportParameters{OriginalConnectionID: %s, InitialMaxStreamDataBidiLocal: %#x, InitialMaxStreamDataBidiRemote: %#x, InitialMaxStreamDataUni: %#x, InitialMaxData: %#x, MaxBidiStreams: %d, MaxUniStreams: %d, IdleTimeout: %s, AckDelayExponent: %d}", p.OriginalConnectionID, p.InitialMaxStreamDataBidiLocal, p.InitialMaxStreamDataBidiRemote, p.InitialMaxStreamDataUni, p.InitialMaxData, p.MaxBidiStreams, p.MaxUniStreams, p.IdleTimeout, p.AckDelayExponent)
}

View File

@@ -63,3 +63,6 @@ const MinStatelessResetSize = 1 /* first byte */ + 22 /* random bytes */ + 16 /*
// MinConnectionIDLenInitial is the minimum length of the destination connection ID on an Initial packet.
const MinConnectionIDLenInitial = 8
// DefaultAckDelayExponent is the default ack delay exponent
const DefaultAckDelayExponent = 3

View File

@@ -427,6 +427,7 @@ func (s *server) createNewSession(
IdleTimeout: s.config.IdleTimeout,
MaxBidiStreams: uint64(s.config.MaxIncomingStreams),
MaxUniStreams: uint64(s.config.MaxIncomingUniStreams),
AckDelayExponent: protocol.AckDelayExponent,
DisableMigration: true,
// TODO(#855): generate a real token
StatelessResetToken: bytes.Repeat([]byte{42}, 16),