mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 12:47:36 +03:00
add a way to pack coalesced packets smaller than the usual packet size
This commit is contained in:
parent
fd5ecee85d
commit
98233f6743
5 changed files with 113 additions and 53 deletions
|
@ -79,18 +79,18 @@ func (mr *MockPackerMockRecorder) MaybePackProbePacket(arg0 interface{}) *gomock
|
||||||
}
|
}
|
||||||
|
|
||||||
// PackCoalescedPacket mocks base method
|
// PackCoalescedPacket mocks base method
|
||||||
func (m *MockPacker) PackCoalescedPacket() (*coalescedPacket, error) {
|
func (m *MockPacker) PackCoalescedPacket(arg0 protocol.ByteCount) (*coalescedPacket, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "PackCoalescedPacket")
|
ret := m.ctrl.Call(m, "PackCoalescedPacket", arg0)
|
||||||
ret0, _ := ret[0].(*coalescedPacket)
|
ret0, _ := ret[0].(*coalescedPacket)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// PackCoalescedPacket indicates an expected call of PackCoalescedPacket
|
// PackCoalescedPacket indicates an expected call of PackCoalescedPacket
|
||||||
func (mr *MockPackerMockRecorder) PackCoalescedPacket() *gomock.Call {
|
func (mr *MockPackerMockRecorder) PackCoalescedPacket(arg0 interface{}) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackCoalescedPacket", reflect.TypeOf((*MockPacker)(nil).PackCoalescedPacket))
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackCoalescedPacket", reflect.TypeOf((*MockPacker)(nil).PackCoalescedPacket), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PackConnectionClose mocks base method
|
// PackConnectionClose mocks base method
|
||||||
|
|
|
@ -17,7 +17,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type packer interface {
|
type packer interface {
|
||||||
PackCoalescedPacket() (*coalescedPacket, error)
|
PackCoalescedPacket(protocol.ByteCount) (*coalescedPacket, error)
|
||||||
PackPacket() (*packedPacket, error)
|
PackPacket() (*packedPacket, error)
|
||||||
MaybePackProbePacket(protocol.EncryptionLevel) (*packedPacket, error)
|
MaybePackProbePacket(protocol.EncryptionLevel) (*packedPacket, error)
|
||||||
MaybePackAckPacket(handshakeConfirmed bool) (*packedPacket, error)
|
MaybePackAckPacket(handshakeConfirmed bool) (*packedPacket, error)
|
||||||
|
@ -323,14 +323,14 @@ func (p *packetPacker) padPacket(buffer *packetBuffer) {
|
||||||
// PackCoalescedPacket packs a new packet.
|
// PackCoalescedPacket packs a new packet.
|
||||||
// It packs an Initial / Handshake if there is data to send in these packet number spaces.
|
// It packs an Initial / Handshake if there is data to send in these packet number spaces.
|
||||||
// It should only be called before the handshake is confirmed.
|
// It should only be called before the handshake is confirmed.
|
||||||
func (p *packetPacker) PackCoalescedPacket() (*coalescedPacket, error) {
|
func (p *packetPacker) PackCoalescedPacket(maxPacketSize protocol.ByteCount) (*coalescedPacket, error) {
|
||||||
buffer := getPacketBuffer()
|
buffer := getPacketBuffer()
|
||||||
packet, err := p.packCoalescedPacket(buffer)
|
packet, err := p.packCoalescedPacket(buffer, maxPacketSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(packet.packets) == 0 { // nothing to send
|
if packet == nil || len(packet.packets) == 0 { // nothing to send
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -342,37 +342,45 @@ func (p *packetPacker) PackCoalescedPacket() (*coalescedPacket, error) {
|
||||||
return packet, nil
|
return packet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) packCoalescedPacket(buffer *packetBuffer) (*coalescedPacket, error) {
|
func (p *packetPacker) packCoalescedPacket(buffer *packetBuffer, maxPacketSize protocol.ByteCount) (*coalescedPacket, error) {
|
||||||
|
maxPacketSize = utils.MinByteCount(maxPacketSize, p.maxPacketSize)
|
||||||
|
if p.perspective == protocol.PerspectiveClient {
|
||||||
|
maxPacketSize = protocol.MinInitialPacketSize
|
||||||
|
}
|
||||||
|
if maxPacketSize < protocol.MinCoalescedPacketSize {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
packet := &coalescedPacket{
|
packet := &coalescedPacket{
|
||||||
buffer: buffer,
|
buffer: buffer,
|
||||||
packets: make([]*packetContents, 0, 3),
|
packets: make([]*packetContents, 0, 3),
|
||||||
}
|
}
|
||||||
// Try packing an Initial packet.
|
// Try packing an Initial packet.
|
||||||
contents, err := p.maybeAppendCryptoPacket(buffer, protocol.EncryptionInitial)
|
contents, err := p.maybeAppendCryptoPacket(buffer, maxPacketSize, protocol.EncryptionInitial)
|
||||||
if err != nil && err != handshake.ErrKeysDropped {
|
if err != nil && err != handshake.ErrKeysDropped {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if contents != nil {
|
if contents != nil {
|
||||||
packet.packets = append(packet.packets, contents)
|
packet.packets = append(packet.packets, contents)
|
||||||
}
|
}
|
||||||
if buffer.Len() >= p.maxPacketSize-protocol.MinCoalescedPacketSize {
|
if buffer.Len() >= maxPacketSize-protocol.MinCoalescedPacketSize {
|
||||||
return packet, nil
|
return packet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a Handshake packet.
|
// Add a Handshake packet.
|
||||||
contents, err = p.maybeAppendCryptoPacket(buffer, protocol.EncryptionHandshake)
|
contents, err = p.maybeAppendCryptoPacket(buffer, maxPacketSize, protocol.EncryptionHandshake)
|
||||||
if err != nil && err != handshake.ErrKeysDropped && err != handshake.ErrKeysNotYetAvailable {
|
if err != nil && err != handshake.ErrKeysDropped && err != handshake.ErrKeysNotYetAvailable {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if contents != nil {
|
if contents != nil {
|
||||||
packet.packets = append(packet.packets, contents)
|
packet.packets = append(packet.packets, contents)
|
||||||
}
|
}
|
||||||
if buffer.Len() >= p.maxPacketSize-protocol.MinCoalescedPacketSize {
|
if buffer.Len() >= maxPacketSize-protocol.MinCoalescedPacketSize {
|
||||||
return packet, nil
|
return packet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a 0-RTT / 1-RTT packet.
|
// Add a 0-RTT / 1-RTT packet.
|
||||||
contents, err = p.maybeAppendAppDataPacket(buffer)
|
contents, err = p.maybeAppendAppDataPacket(buffer, maxPacketSize)
|
||||||
if err == handshake.ErrKeysNotYetAvailable {
|
if err == handshake.ErrKeysNotYetAvailable {
|
||||||
return packet, nil
|
return packet, nil
|
||||||
}
|
}
|
||||||
|
@ -389,7 +397,7 @@ func (p *packetPacker) packCoalescedPacket(buffer *packetBuffer) (*coalescedPack
|
||||||
// It should be called after the handshake is confirmed.
|
// It should be called after the handshake is confirmed.
|
||||||
func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
||||||
buffer := getPacketBuffer()
|
buffer := getPacketBuffer()
|
||||||
contents, err := p.maybeAppendAppDataPacket(buffer)
|
contents, err := p.maybeAppendAppDataPacket(buffer, p.maxPacketSize)
|
||||||
if err != nil || contents == nil {
|
if err != nil || contents == nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -400,16 +408,12 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) maybeAppendCryptoPacket(buffer *packetBuffer, encLevel protocol.EncryptionLevel) (*packetContents, error) {
|
func (p *packetPacker) maybeAppendCryptoPacket(buffer *packetBuffer, maxPacketSize protocol.ByteCount, encLevel protocol.EncryptionLevel) (*packetContents, error) {
|
||||||
var sealer sealer
|
var sealer sealer
|
||||||
var s cryptoStream
|
var s cryptoStream
|
||||||
var hasRetransmission bool
|
var hasRetransmission bool
|
||||||
maxPacketSize := p.maxPacketSize
|
|
||||||
switch encLevel {
|
switch encLevel {
|
||||||
case protocol.EncryptionInitial:
|
case protocol.EncryptionInitial:
|
||||||
if p.perspective == protocol.PerspectiveClient {
|
|
||||||
maxPacketSize = protocol.MinInitialPacketSize
|
|
||||||
}
|
|
||||||
s = p.initialStream
|
s = p.initialStream
|
||||||
hasRetransmission = p.retransmissionQueue.HasInitialData()
|
hasRetransmission = p.retransmissionQueue.HasInitialData()
|
||||||
var err error
|
var err error
|
||||||
|
@ -471,7 +475,7 @@ func (p *packetPacker) maybeAppendCryptoPacket(buffer *packetBuffer, encLevel pr
|
||||||
return p.appendPacket(buffer, hdr, payload, encLevel, sealer)
|
return p.appendPacket(buffer, hdr, payload, encLevel, sealer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) maybeAppendAppDataPacket(buffer *packetBuffer) (*packetContents, error) {
|
func (p *packetPacker) maybeAppendAppDataPacket(buffer *packetBuffer, maxPacketSize protocol.ByteCount) (*packetContents, error) {
|
||||||
var sealer sealer
|
var sealer sealer
|
||||||
var header *wire.ExtendedHeader
|
var header *wire.ExtendedHeader
|
||||||
var encLevel protocol.EncryptionLevel
|
var encLevel protocol.EncryptionLevel
|
||||||
|
@ -494,7 +498,7 @@ func (p *packetPacker) maybeAppendAppDataPacket(buffer *packetBuffer) (*packetCo
|
||||||
}
|
}
|
||||||
headerLen := header.GetLength(p.version)
|
headerLen := header.GetLength(p.version)
|
||||||
|
|
||||||
maxSize := p.maxPacketSize - buffer.Len() - protocol.ByteCount(sealer.Overhead()) - headerLen
|
maxSize := maxPacketSize - buffer.Len() - protocol.ByteCount(sealer.Overhead()) - headerLen
|
||||||
payload := p.composeNextPacket(maxSize, encLevel != protocol.Encryption0RTT && buffer.Len() == 0)
|
payload := p.composeNextPacket(maxSize, encLevel != protocol.Encryption0RTT && buffer.Len() == 0)
|
||||||
|
|
||||||
// check if we have anything to send
|
// check if we have anything to send
|
||||||
|
@ -557,11 +561,11 @@ func (p *packetPacker) MaybePackProbePacket(encLevel protocol.EncryptionLevel) (
|
||||||
buffer := getPacketBuffer()
|
buffer := getPacketBuffer()
|
||||||
switch encLevel {
|
switch encLevel {
|
||||||
case protocol.EncryptionInitial:
|
case protocol.EncryptionInitial:
|
||||||
contents, err = p.maybeAppendCryptoPacket(buffer, protocol.EncryptionInitial)
|
contents, err = p.maybeAppendCryptoPacket(buffer, p.maxPacketSize, protocol.EncryptionInitial)
|
||||||
case protocol.EncryptionHandshake:
|
case protocol.EncryptionHandshake:
|
||||||
contents, err = p.maybeAppendCryptoPacket(buffer, protocol.EncryptionHandshake)
|
contents, err = p.maybeAppendCryptoPacket(buffer, p.maxPacketSize, protocol.EncryptionHandshake)
|
||||||
case protocol.Encryption1RTT:
|
case protocol.Encryption1RTT:
|
||||||
contents, err = p.maybeAppendAppDataPacket(buffer)
|
contents, err = p.maybeAppendAppDataPacket(buffer, p.maxPacketSize)
|
||||||
default:
|
default:
|
||||||
panic("unknown encryption level")
|
panic("unknown encryption level")
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
f := &wire.StreamFrame{Data: []byte{0xde, 0xca, 0xfb, 0xad}}
|
f := &wire.StreamFrame{Data: []byte{0xde, 0xca, 0xfb, 0xad}}
|
||||||
expectAppendStreamFrames(ackhandler.Frame{Frame: f})
|
expectAppendStreamFrames(ackhandler.Frame{Frame: f})
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p).ToNot(BeNil())
|
Expect(p).ToNot(BeNil())
|
||||||
Expect(p.packets).To(HaveLen(1))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
|
@ -266,7 +266,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
framer.EXPECT().AppendStreamFrames(gomock.Any(), gomock.Any()).DoAndReturn(func(frames []ackhandler.Frame, _ protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount) {
|
framer.EXPECT().AppendStreamFrames(gomock.Any(), gomock.Any()).DoAndReturn(func(frames []ackhandler.Frame, _ protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount) {
|
||||||
return frames, 0
|
return frames, 0
|
||||||
})
|
})
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(p).ToNot(BeNil())
|
Expect(p).ToNot(BeNil())
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.packets).To(HaveLen(1))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
|
@ -535,7 +535,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
sealingManager.EXPECT().GetHandshakeSealer().Return(sealer, nil)
|
sealingManager.EXPECT().GetHandshakeSealer().Return(sealer, nil)
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
packer.retransmissionQueue.AddHandshake(&wire.PingFrame{})
|
packer.retransmissionQueue.AddHandshake(&wire.PingFrame{})
|
||||||
packet, err := packer.PackCoalescedPacket()
|
packet, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(packet).ToNot(BeNil())
|
Expect(packet).ToNot(BeNil())
|
||||||
Expect(packet.packets).To(HaveLen(1))
|
Expect(packet.packets).To(HaveLen(1))
|
||||||
|
@ -784,7 +784,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(getSealer(), nil)
|
sealingManager.EXPECT().GetInitialSealer().Return(getSealer(), nil)
|
||||||
sealingManager.EXPECT().GetHandshakeSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
sealingManager.EXPECT().GetHandshakeSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
checkLength(p.buffer.Data)
|
checkLength(p.buffer.Data)
|
||||||
})
|
})
|
||||||
|
@ -805,7 +805,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
Expect(f.Length(packer.version)).To(Equal(size))
|
Expect(f.Length(packer.version)).To(Equal(size))
|
||||||
return f
|
return f
|
||||||
})
|
})
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.packets).To(HaveLen(1))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
Expect(p.packets[0].frames).To(HaveLen(1))
|
Expect(p.packets[0].frames).To(HaveLen(1))
|
||||||
|
@ -832,7 +832,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
handshakeStream.EXPECT().PopCryptoFrame(gomock.Any()).DoAndReturn(func(size protocol.ByteCount) *wire.CryptoFrame {
|
handshakeStream.EXPECT().PopCryptoFrame(gomock.Any()).DoAndReturn(func(size protocol.ByteCount) *wire.CryptoFrame {
|
||||||
return &wire.CryptoFrame{Offset: 0x1337, Data: []byte("handshake")}
|
return &wire.CryptoFrame{Offset: 0x1337, Data: []byte("handshake")}
|
||||||
})
|
})
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.packets).To(HaveLen(2))
|
Expect(p.packets).To(HaveLen(2))
|
||||||
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
||||||
|
@ -868,7 +868,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
})
|
})
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
expectAppendStreamFrames(ackhandler.Frame{Frame: &wire.StreamFrame{Data: []byte("foobar")}})
|
expectAppendStreamFrames(ackhandler.Frame{Frame: &wire.StreamFrame{Data: []byte("foobar")}})
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.buffer.Data).To(HaveLen(protocol.MinInitialPacketSize))
|
Expect(p.buffer.Data).To(HaveLen(protocol.MinInitialPacketSize))
|
||||||
Expect(p.packets).To(HaveLen(2))
|
Expect(p.packets).To(HaveLen(2))
|
||||||
|
@ -903,7 +903,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
})
|
})
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
expectAppendStreamFrames(ackhandler.Frame{Frame: &wire.StreamFrame{Data: []byte("foobar")}})
|
expectAppendStreamFrames(ackhandler.Frame{Frame: &wire.StreamFrame{Data: []byte("foobar")}})
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.packets).To(HaveLen(2))
|
Expect(p.packets).To(HaveLen(2))
|
||||||
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionHandshake))
|
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionHandshake))
|
||||||
|
@ -935,7 +935,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
Expect(f.Length(packer.version)).To(Equal(s))
|
Expect(f.Length(packer.version)).To(Equal(s))
|
||||||
return f
|
return f
|
||||||
})
|
})
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.packets).To(HaveLen(1))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
||||||
|
@ -943,6 +943,62 @@ var _ = Describe("Packet packer", func() {
|
||||||
checkLength(p.buffer.Data)
|
checkLength(p.buffer.Data)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("doesn't pack a coalesced packet if there's not enough space", func() {
|
||||||
|
p, err := packer.PackCoalescedPacket(protocol.MinCoalescedPacketSize - 1)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p).To(BeNil())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("packs a small packet", func() {
|
||||||
|
const size = protocol.MinCoalescedPacketSize + 10
|
||||||
|
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x24), protocol.PacketNumberLen2)
|
||||||
|
pnManager.EXPECT().PopPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x24))
|
||||||
|
sealingManager.EXPECT().GetInitialSealer().Return(getSealer(), nil)
|
||||||
|
// don't EXPECT any calls to GetHandshakeSealer and Get1RTTSealer
|
||||||
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
||||||
|
initialStream.EXPECT().HasData().Return(true).Times(2)
|
||||||
|
initialStream.EXPECT().PopCryptoFrame(gomock.Any()).DoAndReturn(func(s protocol.ByteCount) *wire.CryptoFrame {
|
||||||
|
f := &wire.CryptoFrame{Offset: 0x1337}
|
||||||
|
f.Data = bytes.Repeat([]byte{'f'}, int(s-f.Length(packer.version)-1))
|
||||||
|
Expect(f.Length(packer.version)).To(Equal(s))
|
||||||
|
return f
|
||||||
|
})
|
||||||
|
p, err := packer.PackCoalescedPacket(size)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p).ToNot(BeNil())
|
||||||
|
Expect(len(p.buffer.Data)).To(Equal(size))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("packs a small packet, that includes a 1-RTT packet", func() {
|
||||||
|
const size = 2 * protocol.MinCoalescedPacketSize
|
||||||
|
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x24), protocol.PacketNumberLen2)
|
||||||
|
pnManager.EXPECT().PopPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x24))
|
||||||
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x24), protocol.PacketNumberLen2)
|
||||||
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x24))
|
||||||
|
sealingManager.EXPECT().GetInitialSealer().Return(nil, handshake.ErrKeysDropped)
|
||||||
|
sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil)
|
||||||
|
oneRTTSealer := getSealer()
|
||||||
|
sealingManager.EXPECT().Get1RTTSealer().Return(oneRTTSealer, nil)
|
||||||
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake)
|
||||||
|
handshakeStream.EXPECT().HasData().Return(true).Times(2)
|
||||||
|
handshakeStream.EXPECT().PopCryptoFrame(gomock.Any()).Return(&wire.CryptoFrame{
|
||||||
|
Offset: 0x1337,
|
||||||
|
Data: []byte("foobar"),
|
||||||
|
})
|
||||||
|
expectAppendControlFrames()
|
||||||
|
var appDataSize protocol.ByteCount
|
||||||
|
framer.EXPECT().AppendStreamFrames(gomock.Any(), gomock.Any()).DoAndReturn(func(frames []ackhandler.Frame, maxSize protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount) {
|
||||||
|
appDataSize = maxSize
|
||||||
|
f := &wire.StreamFrame{Data: []byte("foobar")}
|
||||||
|
return append(frames, ackhandler.Frame{Frame: f}), f.Length(packer.version)
|
||||||
|
})
|
||||||
|
p, err := packer.PackCoalescedPacket(size)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p).ToNot(BeNil())
|
||||||
|
Expect(p.packets).To(HaveLen(2))
|
||||||
|
Expect(appDataSize).To(Equal(size - p.packets[0].length - p.packets[1].header.GetLength(packer.version) - protocol.ByteCount(oneRTTSealer.Overhead())))
|
||||||
|
})
|
||||||
|
|
||||||
It("adds retransmissions", func() {
|
It("adds retransmissions", func() {
|
||||||
f := &wire.CryptoFrame{Data: []byte("Initial")}
|
f := &wire.CryptoFrame{Data: []byte("Initial")}
|
||||||
retransmissionQueue.AddInitial(f)
|
retransmissionQueue.AddInitial(f)
|
||||||
|
@ -954,7 +1010,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
||||||
initialStream.EXPECT().HasData()
|
initialStream.EXPECT().HasData()
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.packets).To(HaveLen(1))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
||||||
|
@ -972,7 +1028,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x42))
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.packets).To(HaveLen(1))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
Expect(p.packets[0].ack).To(Equal(ack))
|
Expect(p.packets[0].ack).To(Equal(ack))
|
||||||
|
@ -984,7 +1040,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
initialStream.EXPECT().HasData()
|
initialStream.EXPECT().HasData()
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p).To(BeNil())
|
Expect(p).To(BeNil())
|
||||||
})
|
})
|
||||||
|
@ -1000,7 +1056,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x42))
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.packets).To(HaveLen(1))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
Expect(p.packets[0].ack).To(Equal(ack))
|
Expect(p.packets[0].ack).To(Equal(ack))
|
||||||
|
@ -1020,7 +1076,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
initialStream.EXPECT().HasData().Return(true).Times(2)
|
initialStream.EXPECT().HasData().Return(true).Times(2)
|
||||||
initialStream.EXPECT().PopCryptoFrame(gomock.Any()).Return(f)
|
initialStream.EXPECT().PopCryptoFrame(gomock.Any()).Return(f)
|
||||||
packer.perspective = protocol.PerspectiveClient
|
packer.perspective = protocol.PerspectiveClient
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.buffer.Len()).To(BeEquivalentTo(protocol.MinInitialPacketSize))
|
Expect(p.buffer.Len()).To(BeEquivalentTo(protocol.MinInitialPacketSize))
|
||||||
Expect(p.packets).To(HaveLen(1))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
|
@ -1044,7 +1100,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
initialStream.EXPECT().PopCryptoFrame(gomock.Any()).Return(f)
|
initialStream.EXPECT().PopCryptoFrame(gomock.Any()).Return(f)
|
||||||
packer.version = protocol.VersionTLS
|
packer.version = protocol.VersionTLS
|
||||||
packer.perspective = protocol.PerspectiveClient
|
packer.perspective = protocol.PerspectiveClient
|
||||||
p, err := packer.PackCoalescedPacket()
|
p, err := packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.packets).To(HaveLen(1))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
Expect(p.packets[0].ack).To(Equal(ack))
|
Expect(p.packets[0].ack).To(Equal(ack))
|
||||||
|
|
|
@ -1427,7 +1427,7 @@ func (s *session) sendPacket() (bool, error) {
|
||||||
|
|
||||||
if !s.handshakeConfirmed {
|
if !s.handshakeConfirmed {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
packet, err := s.packer.PackCoalescedPacket()
|
packet, err := s.packer.PackCoalescedPacket(protocol.MaxByteCount)
|
||||||
if err != nil || packet == nil {
|
if err != nil || packet == nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1369,7 +1369,7 @@ var _ = Describe("Session", func() {
|
||||||
sess.sentPacketHandler = sph
|
sess.sentPacketHandler = sph
|
||||||
buffer := getPacketBuffer()
|
buffer := getPacketBuffer()
|
||||||
buffer.Data = append(buffer.Data, []byte("foobar")...)
|
buffer.Data = append(buffer.Data, []byte("foobar")...)
|
||||||
packer.EXPECT().PackCoalescedPacket().Return(&coalescedPacket{
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).Return(&coalescedPacket{
|
||||||
buffer: buffer,
|
buffer: buffer,
|
||||||
packets: []*packetContents{
|
packets: []*packetContents{
|
||||||
{
|
{
|
||||||
|
@ -1394,7 +1394,7 @@ var _ = Describe("Session", func() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, nil)
|
}, nil)
|
||||||
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).AnyTimes()
|
||||||
|
|
||||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||||
sph.EXPECT().SendMode().Return(ackhandler.SendAny).AnyTimes()
|
sph.EXPECT().SendMode().Return(ackhandler.SendAny).AnyTimes()
|
||||||
|
@ -1445,7 +1445,7 @@ var _ = Describe("Session", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("cancels the HandshakeComplete context and informs the SentPacketHandler when the handshake completes", func() {
|
It("cancels the HandshakeComplete context and informs the SentPacketHandler when the handshake completes", func() {
|
||||||
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).AnyTimes()
|
||||||
finishHandshake := make(chan struct{})
|
finishHandshake := make(chan struct{})
|
||||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||||
sess.sentPacketHandler = sph
|
sess.sentPacketHandler = sph
|
||||||
|
@ -1482,7 +1482,7 @@ var _ = Describe("Session", func() {
|
||||||
|
|
||||||
It("sends a session ticket when the handshake completes", func() {
|
It("sends a session ticket when the handshake completes", func() {
|
||||||
const size = protocol.MaxPostHandshakeCryptoFrameSize * 3 / 2
|
const size = protocol.MaxPostHandshakeCryptoFrameSize * 3 / 2
|
||||||
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).AnyTimes()
|
||||||
finishHandshake := make(chan struct{})
|
finishHandshake := make(chan struct{})
|
||||||
sessionRunner.EXPECT().Retire(clientDestConnID)
|
sessionRunner.EXPECT().Retire(clientDestConnID)
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -1525,7 +1525,7 @@ var _ = Describe("Session", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("doesn't cancel the HandshakeComplete context when the handshake fails", func() {
|
It("doesn't cancel the HandshakeComplete context when the handshake fails", func() {
|
||||||
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).AnyTimes()
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
|
@ -1547,7 +1547,7 @@ var _ = Describe("Session", func() {
|
||||||
It("sends a HANDSHAKE_DONE frame when the handshake completes", func() {
|
It("sends a HANDSHAKE_DONE frame when the handshake completes", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
sessionRunner.EXPECT().Retire(clientDestConnID)
|
sessionRunner.EXPECT().Retire(clientDestConnID)
|
||||||
packer.EXPECT().PackCoalescedPacket().DoAndReturn(func() (*packedPacket, error) {
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).DoAndReturn(func(protocol.ByteCount) (*packedPacket, error) {
|
||||||
frames, _ := sess.framer.AppendControlFrames(nil, protocol.MaxByteCount)
|
frames, _ := sess.framer.AppendControlFrames(nil, protocol.MaxByteCount)
|
||||||
Expect(frames).ToNot(BeEmpty())
|
Expect(frames).ToNot(BeEmpty())
|
||||||
Expect(frames[0].Frame).To(BeEquivalentTo(&wire.HandshakeDoneFrame{}))
|
Expect(frames[0].Frame).To(BeEquivalentTo(&wire.HandshakeDoneFrame{}))
|
||||||
|
@ -1559,7 +1559,7 @@ var _ = Describe("Session", func() {
|
||||||
buffer: getPacketBuffer(),
|
buffer: getPacketBuffer(),
|
||||||
}, nil
|
}, nil
|
||||||
})
|
})
|
||||||
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).AnyTimes()
|
||||||
go func() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
cryptoSetup.EXPECT().RunHandshake()
|
cryptoSetup.EXPECT().RunHandshake()
|
||||||
|
@ -1630,7 +1630,7 @@ var _ = Describe("Session", func() {
|
||||||
}
|
}
|
||||||
streamManager.EXPECT().UpdateLimits(params)
|
streamManager.EXPECT().UpdateLimits(params)
|
||||||
packer.EXPECT().HandleTransportParameters(params)
|
packer.EXPECT().HandleTransportParameters(params)
|
||||||
packer.EXPECT().PackCoalescedPacket().MaxTimes(3)
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).MaxTimes(3)
|
||||||
Expect(sess.earlySessionReady()).ToNot(BeClosed())
|
Expect(sess.earlySessionReady()).ToNot(BeClosed())
|
||||||
sessionRunner.EXPECT().GetStatelessResetToken(gomock.Any()).Times(2)
|
sessionRunner.EXPECT().GetStatelessResetToken(gomock.Any()).Times(2)
|
||||||
sessionRunner.EXPECT().Add(gomock.Any(), sess).Times(2)
|
sessionRunner.EXPECT().Add(gomock.Any(), sess).Times(2)
|
||||||
|
@ -1677,7 +1677,7 @@ var _ = Describe("Session", func() {
|
||||||
setRemoteIdleTimeout(5 * time.Second)
|
setRemoteIdleTimeout(5 * time.Second)
|
||||||
sess.lastPacketReceivedTime = time.Now().Add(-5 * time.Second / 2)
|
sess.lastPacketReceivedTime = time.Now().Add(-5 * time.Second / 2)
|
||||||
sent := make(chan struct{})
|
sent := make(chan struct{})
|
||||||
packer.EXPECT().PackCoalescedPacket().Do(func() (*packedPacket, error) {
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).Do(func(protocol.ByteCount) (*packedPacket, error) {
|
||||||
close(sent)
|
close(sent)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
})
|
})
|
||||||
|
@ -1690,7 +1690,7 @@ var _ = Describe("Session", func() {
|
||||||
setRemoteIdleTimeout(time.Hour)
|
setRemoteIdleTimeout(time.Hour)
|
||||||
sess.lastPacketReceivedTime = time.Now().Add(-protocol.MaxKeepAliveInterval).Add(-time.Millisecond)
|
sess.lastPacketReceivedTime = time.Now().Add(-protocol.MaxKeepAliveInterval).Add(-time.Millisecond)
|
||||||
sent := make(chan struct{})
|
sent := make(chan struct{})
|
||||||
packer.EXPECT().PackCoalescedPacket().Do(func() (*packedPacket, error) {
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).Do(func(protocol.ByteCount) (*packedPacket, error) {
|
||||||
close(sent)
|
close(sent)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
})
|
})
|
||||||
|
@ -1794,7 +1794,7 @@ var _ = Describe("Session", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("closes the session due to the idle timeout after handshake", func() {
|
It("closes the session due to the idle timeout after handshake", func() {
|
||||||
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).AnyTimes()
|
||||||
gomock.InOrder(
|
gomock.InOrder(
|
||||||
sessionRunner.EXPECT().Retire(clientDestConnID),
|
sessionRunner.EXPECT().Retire(clientDestConnID),
|
||||||
sessionRunner.EXPECT().Remove(gomock.Any()),
|
sessionRunner.EXPECT().Remove(gomock.Any()),
|
||||||
|
@ -2180,7 +2180,7 @@ var _ = Describe("Client Session", func() {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
packer.EXPECT().HandleTransportParameters(gomock.Any())
|
packer.EXPECT().HandleTransportParameters(gomock.Any())
|
||||||
packer.EXPECT().PackCoalescedPacket().MaxTimes(1)
|
packer.EXPECT().PackCoalescedPacket(protocol.MaxByteCount).MaxTimes(1)
|
||||||
qlogger.EXPECT().ReceivedTransportParameters(params)
|
qlogger.EXPECT().ReceivedTransportParameters(params)
|
||||||
sess.processTransportParameters(params)
|
sess.processTransportParameters(params)
|
||||||
// make sure the connection ID is not retired
|
// make sure the connection ID is not retired
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue