mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 20:57:36 +03:00
Merge pull request #2349 from lucas-clemente/coalesced-packets
implement sending of coalesced packets
This commit is contained in:
commit
73937e8753
12 changed files with 645 additions and 358 deletions
|
@ -7,9 +7,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type packetBuffer struct {
|
type packetBuffer struct {
|
||||||
Slice []byte
|
Data []byte
|
||||||
|
|
||||||
// refCount counts how many packets the Slice is used in.
|
// refCount counts how many packets Data is used in.
|
||||||
// It doesn't support concurrent use.
|
// It doesn't support concurrent use.
|
||||||
// It is > 1 when used for coalesced packet.
|
// It is > 1 when used for coalesced packet.
|
||||||
refCount int
|
refCount int
|
||||||
|
@ -50,8 +50,13 @@ func (b *packetBuffer) Release() {
|
||||||
b.putBack()
|
b.putBack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Len returns the length of Data
|
||||||
|
func (b *packetBuffer) Len() protocol.ByteCount {
|
||||||
|
return protocol.ByteCount(len(b.Data))
|
||||||
|
}
|
||||||
|
|
||||||
func (b *packetBuffer) putBack() {
|
func (b *packetBuffer) putBack() {
|
||||||
if cap(b.Slice) != int(protocol.MaxReceivePacketSize) {
|
if cap(b.Data) != int(protocol.MaxReceivePacketSize) {
|
||||||
panic("putPacketBuffer called with packet of wrong size!")
|
panic("putPacketBuffer called with packet of wrong size!")
|
||||||
}
|
}
|
||||||
bufferPool.Put(b)
|
bufferPool.Put(b)
|
||||||
|
@ -62,14 +67,14 @@ var bufferPool sync.Pool
|
||||||
func getPacketBuffer() *packetBuffer {
|
func getPacketBuffer() *packetBuffer {
|
||||||
buf := bufferPool.Get().(*packetBuffer)
|
buf := bufferPool.Get().(*packetBuffer)
|
||||||
buf.refCount = 1
|
buf.refCount = 1
|
||||||
buf.Slice = buf.Slice[:protocol.MaxReceivePacketSize]
|
buf.Data = buf.Data[:0]
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
bufferPool.New = func() interface{} {
|
bufferPool.New = func() interface{} {
|
||||||
return &packetBuffer{
|
return &packetBuffer{
|
||||||
Slice: make([]byte, 0, protocol.MaxReceivePacketSize),
|
Data: make([]byte, 0, protocol.MaxReceivePacketSize),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
var _ = Describe("Buffer Pool", func() {
|
var _ = Describe("Buffer Pool", func() {
|
||||||
It("returns buffers of cap", func() {
|
It("returns buffers of cap", func() {
|
||||||
buf := getPacketBuffer()
|
buf := getPacketBuffer()
|
||||||
Expect(buf.Slice).To(HaveCap(int(protocol.MaxReceivePacketSize)))
|
Expect(buf.Data).To(HaveCap(int(protocol.MaxReceivePacketSize)))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("releases buffers", func() {
|
It("releases buffers", func() {
|
||||||
|
@ -18,9 +18,15 @@ var _ = Describe("Buffer Pool", func() {
|
||||||
buf.Release()
|
buf.Release()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("gets the length", func() {
|
||||||
|
buf := getPacketBuffer()
|
||||||
|
buf.Data = append(buf.Data, []byte("foobar")...)
|
||||||
|
Expect(buf.Len()).To(BeEquivalentTo(6))
|
||||||
|
})
|
||||||
|
|
||||||
It("panics if wrong-sized buffers are passed", func() {
|
It("panics if wrong-sized buffers are passed", func() {
|
||||||
buf := getPacketBuffer()
|
buf := getPacketBuffer()
|
||||||
buf.Slice = make([]byte, 10)
|
buf.Data = make([]byte, 10)
|
||||||
Expect(func() { buf.Release() }).To(Panic())
|
Expect(func() { buf.Release() }).To(Panic())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,10 @@ const MaxStreamFrameSorterGaps = 1000
|
||||||
// very small STREAM frames to consume a lot of memory.
|
// very small STREAM frames to consume a lot of memory.
|
||||||
const MinStreamFrameBufferSize = 128
|
const MinStreamFrameBufferSize = 128
|
||||||
|
|
||||||
|
// MinCoalescedPacketSize is the minimum size of a coalesced packet that we pack.
|
||||||
|
// If a packet has less than this number of bytes, we won't coalesce any more packets onto it.
|
||||||
|
const MinCoalescedPacketSize = 128
|
||||||
|
|
||||||
// MaxCryptoStreamOffset is the maximum offset allowed on any of the crypto streams.
|
// MaxCryptoStreamOffset is the maximum offset allowed on any of the crypto streams.
|
||||||
// This limits the size of the ClientHello and Certificates that can be received.
|
// This limits the size of the ClientHello and Certificates that can be received.
|
||||||
const MaxCryptoStreamOffset = 16 * (1 << 10)
|
const MaxCryptoStreamOffset = 16 * (1 << 10)
|
||||||
|
|
|
@ -49,18 +49,18 @@ func (mr *MockPackerMockRecorder) HandleTransportParameters(arg0 interface{}) *g
|
||||||
}
|
}
|
||||||
|
|
||||||
// MaybePackAckPacket mocks base method
|
// MaybePackAckPacket mocks base method
|
||||||
func (m *MockPacker) MaybePackAckPacket() (*packedPacket, error) {
|
func (m *MockPacker) MaybePackAckPacket(arg0 bool) (*packedPacket, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "MaybePackAckPacket")
|
ret := m.ctrl.Call(m, "MaybePackAckPacket", arg0)
|
||||||
ret0, _ := ret[0].(*packedPacket)
|
ret0, _ := ret[0].(*packedPacket)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// MaybePackAckPacket indicates an expected call of MaybePackAckPacket
|
// MaybePackAckPacket indicates an expected call of MaybePackAckPacket
|
||||||
func (mr *MockPackerMockRecorder) MaybePackAckPacket() *gomock.Call {
|
func (mr *MockPackerMockRecorder) MaybePackAckPacket(arg0 interface{}) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaybePackAckPacket", reflect.TypeOf((*MockPacker)(nil).MaybePackAckPacket))
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaybePackAckPacket", reflect.TypeOf((*MockPacker)(nil).MaybePackAckPacket), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MaybePackProbePacket mocks base method
|
// MaybePackProbePacket mocks base method
|
||||||
|
@ -78,6 +78,21 @@ func (mr *MockPackerMockRecorder) MaybePackProbePacket(arg0 interface{}) *gomock
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaybePackProbePacket", reflect.TypeOf((*MockPacker)(nil).MaybePackProbePacket), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaybePackProbePacket", reflect.TypeOf((*MockPacker)(nil).MaybePackProbePacket), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PackCoalescedPacket mocks base method
|
||||||
|
func (m *MockPacker) PackCoalescedPacket() (*coalescedPacket, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "PackCoalescedPacket")
|
||||||
|
ret0, _ := ret[0].(*coalescedPacket)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// PackCoalescedPacket indicates an expected call of PackCoalescedPacket
|
||||||
|
func (mr *MockPackerMockRecorder) PackCoalescedPacket() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackCoalescedPacket", reflect.TypeOf((*MockPacker)(nil).PackCoalescedPacket))
|
||||||
|
}
|
||||||
|
|
||||||
// PackConnectionClose mocks base method
|
// PackConnectionClose mocks base method
|
||||||
func (m *MockPacker) PackConnectionClose(arg0 *wire.ConnectionCloseFrame) (*packedPacket, error) {
|
func (m *MockPacker) PackConnectionClose(arg0 *wire.ConnectionCloseFrame) (*packedPacket, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
|
|
@ -218,7 +218,7 @@ func (h *packetHandlerMap) listen() {
|
||||||
defer close(h.listening)
|
defer close(h.listening)
|
||||||
for {
|
for {
|
||||||
buffer := getPacketBuffer()
|
buffer := getPacketBuffer()
|
||||||
data := buffer.Slice
|
data := buffer.Data[:protocol.MaxReceivePacketSize]
|
||||||
// The packet size should not exceed protocol.MaxReceivePacketSize bytes
|
// The packet size should not exceed protocol.MaxReceivePacketSize bytes
|
||||||
// If it does, we only read a truncated packet, which will then end up undecryptable
|
// If it does, we only read a truncated packet, which will then end up undecryptable
|
||||||
n, addr, err := h.conn.ReadFrom(data)
|
n, addr, err := h.conn.ReadFrom(data)
|
||||||
|
|
330
packet_packer.go
330
packet_packer.go
|
@ -15,9 +15,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type packer interface {
|
type packer interface {
|
||||||
|
PackCoalescedPacket() (*coalescedPacket, error)
|
||||||
PackPacket() (*packedPacket, error)
|
PackPacket() (*packedPacket, error)
|
||||||
MaybePackProbePacket(protocol.EncryptionLevel) (*packedPacket, error)
|
MaybePackProbePacket(protocol.EncryptionLevel) (*packedPacket, error)
|
||||||
MaybePackAckPacket() (*packedPacket, error)
|
MaybePackAckPacket(handshakeConfirmed bool) (*packedPacket, error)
|
||||||
PackConnectionClose(*wire.ConnectionCloseFrame) (*packedPacket, error)
|
PackConnectionClose(*wire.ConnectionCloseFrame) (*packedPacket, error)
|
||||||
|
|
||||||
HandleTransportParameters(*handshake.TransportParameters)
|
HandleTransportParameters(*handshake.TransportParameters)
|
||||||
|
@ -35,15 +36,25 @@ type payload struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type packedPacket struct {
|
type packedPacket struct {
|
||||||
|
buffer *packetBuffer
|
||||||
|
*packetContents
|
||||||
|
}
|
||||||
|
|
||||||
|
type packetContents struct {
|
||||||
header *wire.ExtendedHeader
|
header *wire.ExtendedHeader
|
||||||
raw []byte
|
|
||||||
ack *wire.AckFrame
|
ack *wire.AckFrame
|
||||||
frames []ackhandler.Frame
|
frames []ackhandler.Frame
|
||||||
|
|
||||||
buffer *packetBuffer
|
length protocol.ByteCount
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packedPacket) EncryptionLevel() protocol.EncryptionLevel {
|
type coalescedPacket struct {
|
||||||
|
buffer *packetBuffer
|
||||||
|
|
||||||
|
packets []*packetContents
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *packetContents) EncryptionLevel() protocol.EncryptionLevel {
|
||||||
if !p.header.IsLongHeader {
|
if !p.header.IsLongHeader {
|
||||||
return protocol.Encryption1RTT
|
return protocol.Encryption1RTT
|
||||||
}
|
}
|
||||||
|
@ -59,11 +70,11 @@ func (p *packedPacket) EncryptionLevel() protocol.EncryptionLevel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packedPacket) IsAckEliciting() bool {
|
func (p *packetContents) IsAckEliciting() bool {
|
||||||
return ackhandler.HasAckElicitingFrames(p.frames)
|
return ackhandler.HasAckElicitingFrames(p.frames)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packedPacket) ToAckHandlerPacket(now time.Time, q *retransmissionQueue) *ackhandler.Packet {
|
func (p *packetContents) ToAckHandlerPacket(now time.Time, q *retransmissionQueue) *ackhandler.Packet {
|
||||||
largestAcked := protocol.InvalidPacketNumber
|
largestAcked := protocol.InvalidPacketNumber
|
||||||
if p.ack != nil {
|
if p.ack != nil {
|
||||||
largestAcked = p.ack.LargestAcked()
|
largestAcked = p.ack.LargestAcked()
|
||||||
|
@ -86,7 +97,7 @@ func (p *packedPacket) ToAckHandlerPacket(now time.Time, q *retransmissionQueue)
|
||||||
PacketNumber: p.header.PacketNumber,
|
PacketNumber: p.header.PacketNumber,
|
||||||
LargestAcked: largestAcked,
|
LargestAcked: largestAcked,
|
||||||
Frames: p.frames,
|
Frames: p.frames,
|
||||||
Length: protocol.ByteCount(len(p.raw)),
|
Length: p.length,
|
||||||
EncryptionLevel: encLevel,
|
EncryptionLevel: encLevel,
|
||||||
SendTime: now,
|
SendTime: now,
|
||||||
}
|
}
|
||||||
|
@ -138,10 +149,6 @@ type packetPacker struct {
|
||||||
version protocol.VersionNumber
|
version protocol.VersionNumber
|
||||||
cryptoSetup sealingManager
|
cryptoSetup sealingManager
|
||||||
|
|
||||||
// Once both Initial and Handshake keys are dropped, we only send 1-RTT packets.
|
|
||||||
droppedInitial bool
|
|
||||||
droppedHandshake bool
|
|
||||||
|
|
||||||
initialStream cryptoStream
|
initialStream cryptoStream
|
||||||
handshakeStream cryptoStream
|
handshakeStream cryptoStream
|
||||||
|
|
||||||
|
@ -188,10 +195,6 @@ func newPacketPacker(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) handshakeConfirmed() bool {
|
|
||||||
return p.droppedInitial && p.droppedHandshake
|
|
||||||
}
|
|
||||||
|
|
||||||
// PackConnectionClose packs a packet that ONLY contains a ConnectionCloseFrame
|
// PackConnectionClose packs a packet that ONLY contains a ConnectionCloseFrame
|
||||||
func (p *packetPacker) PackConnectionClose(ccf *wire.ConnectionCloseFrame) (*packedPacket, error) {
|
func (p *packetPacker) PackConnectionClose(ccf *wire.ConnectionCloseFrame) (*packedPacket, error) {
|
||||||
payload := payload{
|
payload := payload{
|
||||||
|
@ -222,13 +225,13 @@ func (p *packetPacker) PackConnectionClose(ccf *wire.ConnectionCloseFrame) (*pac
|
||||||
hdr = p.getShortHeader(s.KeyPhase())
|
hdr = p.getShortHeader(s.KeyPhase())
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.writeAndSealPacket(hdr, payload, encLevel, sealer)
|
return p.writeSinglePacket(hdr, payload, encLevel, sealer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) MaybePackAckPacket() (*packedPacket, error) {
|
func (p *packetPacker) MaybePackAckPacket(handshakeConfirmed bool) (*packedPacket, error) {
|
||||||
var encLevel protocol.EncryptionLevel
|
var encLevel protocol.EncryptionLevel
|
||||||
var ack *wire.AckFrame
|
var ack *wire.AckFrame
|
||||||
if !p.handshakeConfirmed() {
|
if !handshakeConfirmed {
|
||||||
ack = p.acks.GetAckFrame(protocol.EncryptionInitial)
|
ack = p.acks.GetAckFrame(protocol.EncryptionInitial)
|
||||||
if ack != nil {
|
if ack != nil {
|
||||||
encLevel = protocol.EncryptionInitial
|
encLevel = protocol.EncryptionInitial
|
||||||
|
@ -258,121 +261,156 @@ func (p *packetPacker) MaybePackAckPacket() (*packedPacket, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return p.writeAndSealPacket(hdr, payload, encLevel, sealer)
|
return p.writeSinglePacket(hdr, payload, encLevel, sealer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PackPacket packs a new packet
|
// PackCoalescedPacket packs a new packet.
|
||||||
// the other controlFrames are sent in the next packet, but might be queued and sent in the next packet if the packet would overflow MaxPacketSize otherwise
|
// 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.
|
||||||
|
func (p *packetPacker) PackCoalescedPacket() (*coalescedPacket, error) {
|
||||||
|
buffer := getPacketBuffer()
|
||||||
|
packet, err := p.packCoalescedPacket(buffer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(packet.packets) == 0 { // nothing to send
|
||||||
|
buffer.Release()
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return packet, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *packetPacker) packCoalescedPacket(buffer *packetBuffer) (*coalescedPacket, error) {
|
||||||
|
packet := &coalescedPacket{
|
||||||
|
buffer: buffer,
|
||||||
|
packets: make([]*packetContents, 0, 3),
|
||||||
|
}
|
||||||
|
// Try packing an Initial packet.
|
||||||
|
contents, err := p.maybeAppendCryptoPacket(buffer, protocol.EncryptionInitial)
|
||||||
|
if err != nil && err != handshake.ErrKeysDropped {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if contents != nil {
|
||||||
|
packet.packets = append(packet.packets, contents)
|
||||||
|
}
|
||||||
|
if buffer.Len() >= p.maxPacketSize-protocol.MinCoalescedPacketSize {
|
||||||
|
return packet, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a Handshake packet.
|
||||||
|
contents, err = p.maybeAppendCryptoPacket(buffer, protocol.EncryptionHandshake)
|
||||||
|
if err != nil && err != handshake.ErrKeysDropped && err != handshake.ErrKeysNotYetAvailable {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if contents != nil {
|
||||||
|
packet.packets = append(packet.packets, contents)
|
||||||
|
}
|
||||||
|
if buffer.Len() >= p.maxPacketSize-protocol.MinCoalescedPacketSize {
|
||||||
|
return packet, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a 0-RTT / 1-RTT packet.
|
||||||
|
contents, err = p.maybeAppendAppDataPacket(buffer)
|
||||||
|
if err == handshake.ErrKeysNotYetAvailable {
|
||||||
|
return packet, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if contents != nil {
|
||||||
|
packet.packets = append(packet.packets, contents)
|
||||||
|
}
|
||||||
|
return packet, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PackPacket packs a packet in the application data packet number space.
|
||||||
|
// It should be called after the handshake is confirmed.
|
||||||
func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
||||||
if !p.handshakeConfirmed() {
|
buffer := getPacketBuffer()
|
||||||
packet, err := p.maybePackCryptoPacket()
|
contents, err := p.maybeAppendAppDataPacket(buffer)
|
||||||
|
if err != nil || contents == nil {
|
||||||
|
buffer.Release()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &packedPacket{
|
||||||
|
buffer: buffer,
|
||||||
|
packetContents: contents,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *packetPacker) maybeAppendCryptoPacket(buffer *packetBuffer, encLevel protocol.EncryptionLevel) (*packetContents, error) {
|
||||||
|
var sealer sealer
|
||||||
|
var s cryptoStream
|
||||||
|
var hasRetransmission bool
|
||||||
|
maxPacketSize := p.maxPacketSize
|
||||||
|
switch encLevel {
|
||||||
|
case protocol.EncryptionInitial:
|
||||||
|
if p.perspective == protocol.PerspectiveClient {
|
||||||
|
maxPacketSize = protocol.MinInitialPacketSize
|
||||||
|
}
|
||||||
|
s = p.initialStream
|
||||||
|
hasRetransmission = p.retransmissionQueue.HasInitialData()
|
||||||
|
var err error
|
||||||
|
sealer, err = p.cryptoSetup.GetInitialSealer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if packet != nil {
|
case protocol.EncryptionHandshake:
|
||||||
return packet, nil
|
s = p.handshakeStream
|
||||||
|
hasRetransmission = p.retransmissionQueue.HasHandshakeData()
|
||||||
|
var err error
|
||||||
|
sealer, err = p.cryptoSetup.GetHandshakeSealer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.maybePackAppDataPacket()
|
var ack *wire.AckFrame
|
||||||
}
|
if encLevel != protocol.EncryptionHandshake || buffer.Len() == 0 {
|
||||||
|
ack = p.acks.GetAckFrame(encLevel)
|
||||||
func (p *packetPacker) maybePackCryptoPacket() (*packedPacket, error) {
|
|
||||||
// Try packing an Initial packet.
|
|
||||||
packet, err := p.maybePackInitialPacket()
|
|
||||||
if err == handshake.ErrKeysDropped {
|
|
||||||
p.droppedInitial = true
|
|
||||||
} else if err != nil || packet != nil {
|
|
||||||
return packet, err
|
|
||||||
}
|
}
|
||||||
|
if !s.HasData() && !hasRetransmission && ack == nil {
|
||||||
// No Initial was packed. Try packing a Handshake packet.
|
|
||||||
packet, err = p.maybePackHandshakePacket()
|
|
||||||
if err == handshake.ErrKeysDropped {
|
|
||||||
p.droppedHandshake = true
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
if err == handshake.ErrKeysNotYetAvailable {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return packet, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *packetPacker) maybePackInitialPacket() (*packedPacket, error) {
|
|
||||||
sealer, err := p.cryptoSetup.GetInitialSealer()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
hasRetransmission := p.retransmissionQueue.HasInitialData()
|
|
||||||
ack := p.acks.GetAckFrame(protocol.EncryptionInitial)
|
|
||||||
if !p.initialStream.HasData() && !hasRetransmission && ack == nil {
|
|
||||||
// nothing to send
|
// nothing to send
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return p.packCryptoPacket(protocol.EncryptionInitial, sealer, ack, hasRetransmission)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *packetPacker) maybePackHandshakePacket() (*packedPacket, error) {
|
remainingLen := maxPacketSize - buffer.Len() - protocol.ByteCount(sealer.Overhead())
|
||||||
sealer, err := p.cryptoSetup.GetHandshakeSealer()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
hasRetransmission := p.retransmissionQueue.HasHandshakeData()
|
|
||||||
ack := p.acks.GetAckFrame(protocol.EncryptionHandshake)
|
|
||||||
if !p.handshakeStream.HasData() && !hasRetransmission && ack == nil {
|
|
||||||
// nothing to send
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return p.packCryptoPacket(protocol.EncryptionHandshake, sealer, ack, hasRetransmission)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *packetPacker) packCryptoPacket(
|
|
||||||
encLevel protocol.EncryptionLevel,
|
|
||||||
sealer handshake.LongHeaderSealer,
|
|
||||||
ack *wire.AckFrame,
|
|
||||||
hasRetransmission bool,
|
|
||||||
) (*packedPacket, error) {
|
|
||||||
s := p.initialStream
|
|
||||||
if encLevel == protocol.EncryptionHandshake {
|
|
||||||
s = p.handshakeStream
|
|
||||||
}
|
|
||||||
|
|
||||||
var payload payload
|
var payload payload
|
||||||
if ack != nil {
|
if ack != nil {
|
||||||
payload.ack = ack
|
payload.ack = ack
|
||||||
payload.length = ack.Length(p.version)
|
payload.length = ack.Length(p.version)
|
||||||
|
remainingLen -= payload.length
|
||||||
}
|
}
|
||||||
hdr := p.getLongHeader(encLevel)
|
hdr := p.getLongHeader(encLevel)
|
||||||
hdrLen := hdr.GetLength(p.version)
|
remainingLen -= hdr.GetLength(p.version)
|
||||||
if hasRetransmission {
|
if hasRetransmission {
|
||||||
for {
|
for {
|
||||||
var f wire.Frame
|
var f wire.Frame
|
||||||
switch encLevel {
|
switch encLevel {
|
||||||
case protocol.EncryptionInitial:
|
case protocol.EncryptionInitial:
|
||||||
remainingLen := protocol.MinInitialPacketSize - hdrLen - protocol.ByteCount(sealer.Overhead()) - payload.length
|
|
||||||
f = p.retransmissionQueue.GetInitialFrame(remainingLen)
|
f = p.retransmissionQueue.GetInitialFrame(remainingLen)
|
||||||
case protocol.EncryptionHandshake:
|
case protocol.EncryptionHandshake:
|
||||||
remainingLen := p.maxPacketSize - hdrLen - protocol.ByteCount(sealer.Overhead()) - payload.length
|
|
||||||
f = p.retransmissionQueue.GetHandshakeFrame(remainingLen)
|
f = p.retransmissionQueue.GetHandshakeFrame(remainingLen)
|
||||||
}
|
}
|
||||||
if f == nil {
|
if f == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
payload.frames = append(payload.frames, ackhandler.Frame{Frame: f})
|
payload.frames = append(payload.frames, ackhandler.Frame{Frame: f})
|
||||||
payload.length += f.Length(p.version)
|
frameLen := f.Length(p.version)
|
||||||
|
payload.length += frameLen
|
||||||
|
remainingLen -= frameLen
|
||||||
}
|
}
|
||||||
} else if s.HasData() {
|
} else if s.HasData() {
|
||||||
cf := s.PopCryptoFrame(p.maxPacketSize - hdrLen - protocol.ByteCount(sealer.Overhead()) - payload.length)
|
cf := s.PopCryptoFrame(remainingLen)
|
||||||
payload.frames = []ackhandler.Frame{{Frame: cf}}
|
payload.frames = []ackhandler.Frame{{Frame: cf}}
|
||||||
payload.length += cf.Length(p.version)
|
payload.length += cf.Length(p.version)
|
||||||
}
|
}
|
||||||
return p.writeAndSealPacket(hdr, payload, encLevel, sealer)
|
return p.appendPacket(buffer, hdr, payload, encLevel, sealer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) maybePackAppDataPacket() (*packedPacket, error) {
|
func (p *packetPacker) maybeAppendAppDataPacket(buffer *packetBuffer) (*packetContents, error) {
|
||||||
var sealer sealer
|
var sealer sealer
|
||||||
var header *wire.ExtendedHeader
|
var header *wire.ExtendedHeader
|
||||||
var encLevel protocol.EncryptionLevel
|
var encLevel protocol.EncryptionLevel
|
||||||
|
@ -395,8 +433,8 @@ func (p *packetPacker) maybePackAppDataPacket() (*packedPacket, error) {
|
||||||
}
|
}
|
||||||
headerLen := header.GetLength(p.version)
|
headerLen := header.GetLength(p.version)
|
||||||
|
|
||||||
maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLen
|
maxSize := p.maxPacketSize - buffer.Len() - protocol.ByteCount(sealer.Overhead()) - headerLen
|
||||||
payload := p.composeNextPacket(maxSize)
|
payload := p.composeNextPacket(maxSize, encLevel != protocol.Encryption0RTT && buffer.Len() == 0)
|
||||||
|
|
||||||
// check if we have anything to send
|
// check if we have anything to send
|
||||||
if len(payload.frames) == 0 && payload.ack == nil {
|
if len(payload.frames) == 0 && payload.ack == nil {
|
||||||
|
@ -415,16 +453,19 @@ func (p *packetPacker) maybePackAppDataPacket() (*packedPacket, error) {
|
||||||
p.numNonAckElicitingAcks = 0
|
p.numNonAckElicitingAcks = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.writeAndSealPacket(header, payload, encLevel, sealer)
|
return p.appendPacket(buffer, header, payload, encLevel, sealer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) composeNextPacket(maxFrameSize protocol.ByteCount) payload {
|
func (p *packetPacker) composeNextPacket(maxFrameSize protocol.ByteCount, ackAllowed bool) payload {
|
||||||
var payload payload
|
var payload payload
|
||||||
|
|
||||||
// TODO: we don't need to request ACKs when sending 0-RTT packets
|
var ack *wire.AckFrame
|
||||||
if ack := p.acks.GetAckFrame(protocol.Encryption1RTT); ack != nil {
|
if ackAllowed {
|
||||||
payload.ack = ack
|
ack = p.acks.GetAckFrame(protocol.Encryption1RTT)
|
||||||
payload.length += ack.Length(p.version)
|
if ack != nil {
|
||||||
|
payload.ack = ack
|
||||||
|
payload.length += ack.Length(p.version)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
@ -450,16 +491,26 @@ func (p *packetPacker) composeNextPacket(maxFrameSize protocol.ByteCount) payloa
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) MaybePackProbePacket(encLevel protocol.EncryptionLevel) (*packedPacket, error) {
|
func (p *packetPacker) MaybePackProbePacket(encLevel protocol.EncryptionLevel) (*packedPacket, error) {
|
||||||
|
var contents *packetContents
|
||||||
|
var err error
|
||||||
|
buffer := getPacketBuffer()
|
||||||
switch encLevel {
|
switch encLevel {
|
||||||
case protocol.EncryptionInitial:
|
case protocol.EncryptionInitial:
|
||||||
return p.maybePackInitialPacket()
|
contents, err = p.maybeAppendCryptoPacket(buffer, protocol.EncryptionInitial)
|
||||||
case protocol.EncryptionHandshake:
|
case protocol.EncryptionHandshake:
|
||||||
return p.maybePackHandshakePacket()
|
contents, err = p.maybeAppendCryptoPacket(buffer, protocol.EncryptionHandshake)
|
||||||
case protocol.Encryption1RTT:
|
case protocol.Encryption1RTT:
|
||||||
return p.maybePackAppDataPacket()
|
contents, err = p.maybeAppendAppDataPacket(buffer)
|
||||||
default:
|
default:
|
||||||
panic("unknown encryption level")
|
panic("unknown encryption level")
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &packedPacket{
|
||||||
|
buffer: buffer,
|
||||||
|
packetContents: contents,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) getSealerAndHeader(encLevel protocol.EncryptionLevel) (sealer, *wire.ExtendedHeader, error) {
|
func (p *packetPacker) getSealerAndHeader(encLevel protocol.EncryptionLevel) (sealer, *wire.ExtendedHeader, error) {
|
||||||
|
@ -541,15 +592,33 @@ func (p *packetPacker) getLongHeader(encLevel protocol.EncryptionLevel) *wire.Ex
|
||||||
return hdr
|
return hdr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) writeAndSealPacket(
|
// writeSinglePacket packs a single packet.
|
||||||
|
func (p *packetPacker) writeSinglePacket(
|
||||||
header *wire.ExtendedHeader,
|
header *wire.ExtendedHeader,
|
||||||
payload payload,
|
payload payload,
|
||||||
encLevel protocol.EncryptionLevel,
|
encLevel protocol.EncryptionLevel,
|
||||||
sealer sealer,
|
sealer sealer,
|
||||||
) (*packedPacket, error) {
|
) (*packedPacket, error) {
|
||||||
|
buffer := getPacketBuffer()
|
||||||
|
contents, err := p.appendPacket(buffer, header, payload, encLevel, sealer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &packedPacket{
|
||||||
|
buffer: buffer,
|
||||||
|
packetContents: contents,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *packetPacker) appendPacket(
|
||||||
|
buffer *packetBuffer,
|
||||||
|
header *wire.ExtendedHeader,
|
||||||
|
payload payload,
|
||||||
|
encLevel protocol.EncryptionLevel,
|
||||||
|
sealer sealer,
|
||||||
|
) (*packetContents, error) {
|
||||||
var paddingLen protocol.ByteCount
|
var paddingLen protocol.ByteCount
|
||||||
pnLen := protocol.ByteCount(header.PacketNumberLen)
|
pnLen := protocol.ByteCount(header.PacketNumberLen)
|
||||||
|
|
||||||
if encLevel != protocol.Encryption1RTT {
|
if encLevel != protocol.Encryption1RTT {
|
||||||
if p.perspective == protocol.PerspectiveClient && header.Type == protocol.PacketTypeInitial {
|
if p.perspective == protocol.PerspectiveClient && header.Type == protocol.PacketTypeInitial {
|
||||||
headerLen := header.GetLength(p.version)
|
headerLen := header.GetLength(p.version)
|
||||||
|
@ -561,67 +630,54 @@ func (p *packetPacker) writeAndSealPacket(
|
||||||
} else if payload.length < 4-pnLen {
|
} else if payload.length < 4-pnLen {
|
||||||
paddingLen = 4 - pnLen - payload.length
|
paddingLen = 4 - pnLen - payload.length
|
||||||
}
|
}
|
||||||
return p.writeAndSealPacketWithPadding(header, payload, paddingLen, encLevel, sealer)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *packetPacker) writeAndSealPacketWithPadding(
|
hdrOffset := buffer.Len()
|
||||||
header *wire.ExtendedHeader,
|
buf := bytes.NewBuffer(buffer.Data)
|
||||||
payload payload,
|
if err := header.Write(buf, p.version); err != nil {
|
||||||
paddingLen protocol.ByteCount,
|
|
||||||
encLevel protocol.EncryptionLevel,
|
|
||||||
sealer sealer,
|
|
||||||
) (*packedPacket, error) {
|
|
||||||
packetBuffer := getPacketBuffer()
|
|
||||||
buffer := bytes.NewBuffer(packetBuffer.Slice[:0])
|
|
||||||
|
|
||||||
if err := header.Write(buffer, p.version); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
payloadOffset := buffer.Len()
|
payloadOffset := buf.Len()
|
||||||
|
|
||||||
if payload.ack != nil {
|
if payload.ack != nil {
|
||||||
if err := payload.ack.Write(buffer, p.version); err != nil {
|
if err := payload.ack.Write(buf, p.version); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if paddingLen > 0 {
|
if paddingLen > 0 {
|
||||||
buffer.Write(bytes.Repeat([]byte{0}, int(paddingLen)))
|
buf.Write(bytes.Repeat([]byte{0}, int(paddingLen)))
|
||||||
}
|
}
|
||||||
for _, frame := range payload.frames {
|
for _, frame := range payload.frames {
|
||||||
if err := frame.Write(buffer, p.version); err != nil {
|
if err := frame.Write(buf, p.version); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if payloadSize := protocol.ByteCount(buffer.Len()-payloadOffset) - paddingLen; payloadSize != payload.length {
|
if payloadSize := protocol.ByteCount(buf.Len()-payloadOffset) - paddingLen; payloadSize != payload.length {
|
||||||
fmt.Printf("%#v\n", payload)
|
|
||||||
return nil, fmt.Errorf("PacketPacker BUG: payload size inconsistent (expected %d, got %d bytes)", payload.length, payloadSize)
|
return nil, fmt.Errorf("PacketPacker BUG: payload size inconsistent (expected %d, got %d bytes)", payload.length, payloadSize)
|
||||||
}
|
}
|
||||||
if size := protocol.ByteCount(buffer.Len() + sealer.Overhead()); size > p.maxPacketSize {
|
if size := protocol.ByteCount(buf.Len() + sealer.Overhead()); size > p.maxPacketSize {
|
||||||
return nil, fmt.Errorf("PacketPacker BUG: packet too large (%d bytes, allowed %d bytes)", size, p.maxPacketSize)
|
return nil, fmt.Errorf("PacketPacker BUG: packet too large (%d bytes, allowed %d bytes)", size, p.maxPacketSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
raw := buffer.Bytes()
|
raw := buffer.Data
|
||||||
_ = sealer.Seal(raw[payloadOffset:payloadOffset], raw[payloadOffset:], header.PacketNumber, raw[:payloadOffset])
|
// encrypt the packet
|
||||||
raw = raw[0 : buffer.Len()+sealer.Overhead()]
|
raw = raw[:buf.Len()]
|
||||||
|
_ = sealer.Seal(raw[payloadOffset:payloadOffset], raw[payloadOffset:], header.PacketNumber, raw[hdrOffset:payloadOffset])
|
||||||
|
raw = raw[0 : buf.Len()+sealer.Overhead()]
|
||||||
|
// apply header protection
|
||||||
pnOffset := payloadOffset - int(header.PacketNumberLen)
|
pnOffset := payloadOffset - int(header.PacketNumberLen)
|
||||||
sealer.EncryptHeader(
|
sealer.EncryptHeader(raw[pnOffset+4:pnOffset+4+16], &raw[hdrOffset], raw[pnOffset:payloadOffset])
|
||||||
raw[pnOffset+4:pnOffset+4+16],
|
buffer.Data = raw
|
||||||
&raw[0],
|
|
||||||
raw[pnOffset:payloadOffset],
|
|
||||||
)
|
|
||||||
|
|
||||||
num := p.pnManager.PopPacketNumber(encLevel)
|
num := p.pnManager.PopPacketNumber(encLevel)
|
||||||
if num != header.PacketNumber {
|
if num != header.PacketNumber {
|
||||||
return nil, errors.New("packetPacker BUG: Peeked and Popped packet numbers do not match")
|
return nil, errors.New("packetPacker BUG: Peeked and Popped packet numbers do not match")
|
||||||
}
|
}
|
||||||
return &packedPacket{
|
return &packetContents{
|
||||||
header: header,
|
header: header,
|
||||||
raw: raw,
|
|
||||||
ack: payload.ack,
|
ack: payload.ack,
|
||||||
frames: payload.frames,
|
frames: payload.frames,
|
||||||
buffer: packetBuffer,
|
length: buffer.Len() - hdrOffset,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -175,38 +175,39 @@ 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.PackPacket()
|
p, err := packer.PackCoalescedPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p).ToNot(BeNil())
|
Expect(p).ToNot(BeNil())
|
||||||
Expect(p.frames).To(Equal([]ackhandler.Frame{{Frame: f}}))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
|
Expect(p.packets[0].frames).To(Equal([]ackhandler.Frame{{Frame: f}}))
|
||||||
hdrRawEncrypted := append([]byte{}, hdrRaw...)
|
hdrRawEncrypted := append([]byte{}, hdrRaw...)
|
||||||
hdrRawEncrypted[0] ^= 0xff
|
hdrRawEncrypted[0] ^= 0xff
|
||||||
hdrRawEncrypted[len(hdrRaw)-2] ^= 0xff
|
hdrRawEncrypted[len(hdrRaw)-2] ^= 0xff
|
||||||
hdrRawEncrypted[len(hdrRaw)-1] ^= 0xff
|
hdrRawEncrypted[len(hdrRaw)-1] ^= 0xff
|
||||||
Expect(p.raw[0:len(hdrRaw)]).To(Equal(hdrRawEncrypted))
|
Expect(p.buffer.Data[0:len(hdrRaw)]).To(Equal(hdrRawEncrypted))
|
||||||
Expect(p.raw[len(p.raw)-4:]).To(Equal([]byte{0xde, 0xca, 0xfb, 0xad}))
|
Expect(p.buffer.Data[p.buffer.Len()-4:]).To(Equal([]byte{0xde, 0xca, 0xfb, 0xad}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("packing packets", func() {
|
Context("packing packets", func() {
|
||||||
var sealer *mocks.MockShortHeaderSealer
|
// getSealer gets a sealer that's expected to seal exactly one packet
|
||||||
|
getSealer := func() *mocks.MockShortHeaderSealer {
|
||||||
BeforeEach(func() {
|
sealer := mocks.NewMockShortHeaderSealer(mockCtrl)
|
||||||
sealer = mocks.NewMockShortHeaderSealer(mockCtrl)
|
|
||||||
sealer.EXPECT().KeyPhase().Return(protocol.KeyPhaseOne).AnyTimes()
|
sealer.EXPECT().KeyPhase().Return(protocol.KeyPhaseOne).AnyTimes()
|
||||||
sealer.EXPECT().Overhead().Return(7).AnyTimes()
|
sealer.EXPECT().Overhead().Return(7).AnyTimes()
|
||||||
sealer.EXPECT().EncryptHeader(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
sealer.EXPECT().EncryptHeader(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||||
sealer.EXPECT().Seal(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(dst, src []byte, pn protocol.PacketNumber, associatedData []byte) []byte {
|
sealer.EXPECT().Seal(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(dst, src []byte, pn protocol.PacketNumber, associatedData []byte) []byte {
|
||||||
return append(src, bytes.Repeat([]byte{0}, sealer.Overhead())...)
|
return append(src, bytes.Repeat([]byte{0}, sealer.Overhead())...)
|
||||||
}).AnyTimes()
|
}).AnyTimes()
|
||||||
})
|
return sealer
|
||||||
|
}
|
||||||
|
|
||||||
Context("packing ACK packets", func() {
|
Context("packing ACK packets", func() {
|
||||||
It("doesn't pack a packet if there's no ACK to send", func() {
|
It("doesn't pack a packet if there's no ACK to send", func() {
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
||||||
p, err := packer.MaybePackAckPacket()
|
p, err := packer.MaybePackAckPacket(false)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p).To(BeNil())
|
Expect(p).To(BeNil())
|
||||||
})
|
})
|
||||||
|
@ -214,11 +215,11 @@ var _ = Describe("Packet packer", func() {
|
||||||
It("packs Handshake ACK-only packets", func() {
|
It("packs Handshake ACK-only packets", func() {
|
||||||
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))
|
||||||
sealingManager.EXPECT().GetHandshakeSealer().Return(sealer, nil)
|
sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil)
|
||||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 10}}}
|
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 10}}}
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake).Return(ack)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake).Return(ack)
|
||||||
p, err := packer.MaybePackAckPacket()
|
p, err := packer.MaybePackAckPacket(false)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(p).ToNot(BeNil())
|
Expect(p).ToNot(BeNil())
|
||||||
Expect(p.EncryptionLevel()).To(Equal(protocol.EncryptionHandshake))
|
Expect(p.EncryptionLevel()).To(Equal(protocol.EncryptionHandshake))
|
||||||
|
@ -228,12 +229,10 @@ var _ = Describe("Packet packer", func() {
|
||||||
It("packs 1-RTT ACK-only packets", func() {
|
It("packs 1-RTT ACK-only packets", func() {
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 10}}}
|
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 10}}}
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake)
|
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(ack)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(ack)
|
||||||
p, err := packer.MaybePackAckPacket()
|
p, err := packer.MaybePackAckPacket(true)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(p).ToNot(BeNil())
|
Expect(p).ToNot(BeNil())
|
||||||
Expect(p.EncryptionLevel()).To(Equal(protocol.Encryption1RTT))
|
Expect(p.EncryptionLevel()).To(Equal(protocol.Encryption1RTT))
|
||||||
|
@ -255,29 +254,29 @@ var _ = Describe("Packet packer", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("packs a 0-RTT packet", func() {
|
It("packs a 0-RTT packet", func() {
|
||||||
sealingManager.EXPECT().Get0RTTSealer().Return(sealer, nil).AnyTimes()
|
sealingManager.EXPECT().Get0RTTSealer().Return(getSealer(), nil).AnyTimes()
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption0RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption0RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption0RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption0RTT).Return(protocol.PacketNumber(0x42))
|
||||||
cf := ackhandler.Frame{Frame: &wire.MaxDataFrame{ByteOffset: 0x1337}}
|
cf := ackhandler.Frame{Frame: &wire.MaxDataFrame{ByteOffset: 0x1337}}
|
||||||
framer.EXPECT().AppendControlFrames(nil, gomock.Any()).DoAndReturn(func(frames []ackhandler.Frame, _ protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount) {
|
framer.EXPECT().AppendControlFrames(nil, gomock.Any()).DoAndReturn(func(frames []ackhandler.Frame, _ protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount) {
|
||||||
return append(frames, cf), cf.Length(packer.version)
|
return append(frames, cf), cf.Length(packer.version)
|
||||||
})
|
})
|
||||||
|
// TODO: check sizes
|
||||||
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.PackPacket()
|
p, err := packer.PackCoalescedPacket()
|
||||||
Expect(p).ToNot(BeNil())
|
Expect(p).ToNot(BeNil())
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.header.Type).To(Equal(protocol.PacketType0RTT))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
Expect(p.EncryptionLevel()).To(Equal(protocol.Encryption0RTT))
|
Expect(p.packets[0].header.Type).To(Equal(protocol.PacketType0RTT))
|
||||||
Expect(p.frames).To(Equal([]ackhandler.Frame{cf}))
|
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.Encryption0RTT))
|
||||||
|
Expect(p.packets[0].frames).To(Equal([]ackhandler.Frame{cf}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("packing normal packets", func() {
|
Context("packing normal packets", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(nil, nil).AnyTimes()
|
|
||||||
sealingManager.EXPECT().GetHandshakeSealer().Return(nil, nil).AnyTimes()
|
|
||||||
initialStream.EXPECT().HasData().AnyTimes()
|
initialStream.EXPECT().HasData().AnyTimes()
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial).AnyTimes()
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial).AnyTimes()
|
||||||
handshakeStream.EXPECT().HasData().AnyTimes()
|
handshakeStream.EXPECT().HasData().AnyTimes()
|
||||||
|
@ -287,7 +286,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
It("returns nil when no packet is queued", func() {
|
It("returns nil when no packet is queued", func() {
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
// don't expect any calls to PopPacketNumber
|
// don't expect any calls to PopPacketNumber
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
||||||
framer.EXPECT().AppendControlFrames(nil, gomock.Any())
|
framer.EXPECT().AppendControlFrames(nil, gomock.Any())
|
||||||
framer.EXPECT().AppendStreamFrames(nil, gomock.Any())
|
framer.EXPECT().AppendStreamFrames(nil, gomock.Any())
|
||||||
|
@ -299,7 +298,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
It("packs single packets", func() {
|
It("packs single packets", func() {
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
f := &wire.StreamFrame{
|
f := &wire.StreamFrame{
|
||||||
|
@ -313,13 +312,13 @@ var _ = Describe("Packet packer", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
f.Write(b, packer.version)
|
f.Write(b, packer.version)
|
||||||
Expect(p.frames).To(Equal([]ackhandler.Frame{{Frame: f}}))
|
Expect(p.frames).To(Equal([]ackhandler.Frame{{Frame: f}}))
|
||||||
Expect(p.raw).To(ContainSubstring(b.String()))
|
Expect(p.buffer.Data).To(ContainSubstring(b.String()))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("stores the encryption level a packet was sealed with", func() {
|
It("stores the encryption level a packet was sealed with", func() {
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
expectAppendStreamFrames(ackhandler.Frame{Frame: &wire.StreamFrame{
|
expectAppendStreamFrames(ackhandler.Frame{Frame: &wire.StreamFrame{
|
||||||
|
@ -336,7 +335,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Largest: 42, Smallest: 1}}}
|
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Largest: 42, Smallest: 1}}}
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(ack)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(ack)
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
expectAppendStreamFrames()
|
expectAppendStreamFrames()
|
||||||
p, err := packer.PackPacket()
|
p, err := packer.PackPacket()
|
||||||
|
@ -353,7 +352,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
ErrorCode: 0x1337,
|
ErrorCode: 0x1337,
|
||||||
ReasonPhrase: "foobar",
|
ReasonPhrase: "foobar",
|
||||||
}
|
}
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
p, err := packer.PackConnectionClose(&ccf)
|
p, err := packer.PackConnectionClose(&ccf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.frames).To(HaveLen(1))
|
Expect(p.frames).To(HaveLen(1))
|
||||||
|
@ -363,7 +362,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
It("packs control frames", func() {
|
It("packs control frames", func() {
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
||||||
frames := []ackhandler.Frame{
|
frames := []ackhandler.Frame{
|
||||||
{Frame: &wire.ResetStreamFrame{}},
|
{Frame: &wire.ResetStreamFrame{}},
|
||||||
|
@ -375,12 +374,12 @@ var _ = Describe("Packet packer", func() {
|
||||||
Expect(p).ToNot(BeNil())
|
Expect(p).ToNot(BeNil())
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.frames).To(Equal(frames))
|
Expect(p.frames).To(Equal(frames))
|
||||||
Expect(p.raw).NotTo(BeEmpty())
|
Expect(p.buffer.Len()).ToNot(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("accounts for the space consumed by control frames", func() {
|
It("accounts for the space consumed by control frames", func() {
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
||||||
var maxSize protocol.ByteCount
|
var maxSize protocol.ByteCount
|
||||||
gomock.InOrder(
|
gomock.InOrder(
|
||||||
|
@ -405,6 +404,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
Expect(f.Length(packer.version)).To(BeEquivalentTo(2))
|
Expect(f.Length(packer.version)).To(BeEquivalentTo(2))
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen1)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen1)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
|
sealer := getSealer()
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
|
@ -412,10 +412,10 @@ var _ = Describe("Packet packer", func() {
|
||||||
packet, err := packer.PackPacket()
|
packet, err := packer.PackPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
// cut off the tag that the mock sealer added
|
// cut off the tag that the mock sealer added
|
||||||
packet.raw = packet.raw[:len(packet.raw)-sealer.Overhead()]
|
packet.buffer.Data = packet.buffer.Data[:packet.buffer.Len()-protocol.ByteCount(sealer.Overhead())]
|
||||||
hdr, _, _, err := wire.ParsePacket(packet.raw, len(packer.getDestConnID()))
|
hdr, _, _, err := wire.ParsePacket(packet.buffer.Data, len(packer.getDestConnID()))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
r := bytes.NewReader(packet.raw)
|
r := bytes.NewReader(packet.buffer.Data)
|
||||||
extHdr, err := hdr.ParseExtended(r, packer.version)
|
extHdr, err := hdr.ParseExtended(r, packer.version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(extHdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen1))
|
Expect(extHdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen1))
|
||||||
|
@ -454,7 +454,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
}
|
}
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
expectAppendStreamFrames(ackhandler.Frame{Frame: f1}, ackhandler.Frame{Frame: f2}, ackhandler.Frame{Frame: f3})
|
expectAppendStreamFrames(ackhandler.Frame{Frame: f1}, ackhandler.Frame{Frame: f2}, ackhandler.Frame{Frame: f3})
|
||||||
|
@ -472,7 +472,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
for i := 0; i < protocol.MaxNonAckElicitingAcks; i++ {
|
for i := 0; i < protocol.MaxNonAckElicitingAcks; i++ {
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}})
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}})
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
expectAppendStreamFrames()
|
expectAppendStreamFrames()
|
||||||
|
@ -488,7 +488,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
sendMaxNumNonAckElicitingAcks()
|
sendMaxNumNonAckElicitingAcks()
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}})
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}})
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
expectAppendStreamFrames()
|
expectAppendStreamFrames()
|
||||||
|
@ -499,7 +499,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
// make sure the next packet doesn't contain another PING
|
// make sure the next packet doesn't contain another PING
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}})
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}})
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
expectAppendStreamFrames()
|
expectAppendStreamFrames()
|
||||||
|
@ -514,7 +514,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
sendMaxNumNonAckElicitingAcks()
|
sendMaxNumNonAckElicitingAcks()
|
||||||
// nothing to send
|
// nothing to send
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
expectAppendControlFrames()
|
expectAppendControlFrames()
|
||||||
expectAppendStreamFrames()
|
expectAppendStreamFrames()
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
||||||
|
@ -526,7 +526,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
expectAppendStreamFrames()
|
expectAppendStreamFrames()
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}}
|
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}}
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(ack)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Return(ack)
|
||||||
p, err = packer.PackPacket()
|
p, err = packer.PackPacket()
|
||||||
|
@ -539,7 +539,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
sendMaxNumNonAckElicitingAcks()
|
sendMaxNumNonAckElicitingAcks()
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
||||||
expectAppendStreamFrames()
|
expectAppendStreamFrames()
|
||||||
expectAppendControlFrames(ackhandler.Frame{Frame: &wire.MaxDataFrame{}})
|
expectAppendControlFrames(ackhandler.Frame{Frame: &wire.MaxDataFrame{}})
|
||||||
|
@ -553,7 +553,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
Context("max packet size", func() {
|
Context("max packet size", func() {
|
||||||
It("sets the maximum packet size", func() {
|
It("sets the maximum packet size", func() {
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2).Times(2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2).Times(2)
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil).Times(2)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil).Times(2)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Times(2)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Times(2)
|
||||||
var initialMaxPacketSize protocol.ByteCount
|
var initialMaxPacketSize protocol.ByteCount
|
||||||
framer.EXPECT().AppendControlFrames(gomock.Any(), gomock.Any()).Do(func(_ []ackhandler.Frame, maxLen protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount) {
|
framer.EXPECT().AppendControlFrames(gomock.Any(), gomock.Any()).Do(func(_ []ackhandler.Frame, maxLen protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount) {
|
||||||
|
@ -578,7 +578,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
|
|
||||||
It("doesn't increase the max packet size", func() {
|
It("doesn't increase the max packet size", func() {
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2).Times(2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2).Times(2)
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil).Times(2)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil).Times(2)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Times(2)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT).Times(2)
|
||||||
var initialMaxPacketSize protocol.ByteCount
|
var initialMaxPacketSize protocol.ByteCount
|
||||||
framer.EXPECT().AppendControlFrames(gomock.Any(), gomock.Any()).Do(func(_ []ackhandler.Frame, maxLen protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount) {
|
framer.EXPECT().AppendControlFrames(gomock.Any(), gomock.Any()).Do(func(_ []ackhandler.Frame, maxLen protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount) {
|
||||||
|
@ -614,10 +614,12 @@ var _ = Describe("Packet packer", func() {
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
||||||
initialStream.EXPECT().HasData().Return(true).AnyTimes()
|
initialStream.EXPECT().HasData().Return(true).AnyTimes()
|
||||||
initialStream.EXPECT().PopCryptoFrame(gomock.Any()).Return(f)
|
initialStream.EXPECT().PopCryptoFrame(gomock.Any()).Return(f)
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(sealer, nil)
|
sealingManager.EXPECT().GetInitialSealer().Return(getSealer(), nil)
|
||||||
p, err := packer.PackPacket()
|
sealingManager.EXPECT().GetHandshakeSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
|
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
|
p, err := packer.PackCoalescedPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
checkLength(p.raw)
|
checkLength(p.buffer.Data)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("packs a maximum size Handshake packet", func() {
|
It("packs a maximum size Handshake packet", func() {
|
||||||
|
@ -625,7 +627,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
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))
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(mocks.NewMockShortHeaderSealer(mockCtrl), nil)
|
sealingManager.EXPECT().GetInitialSealer().Return(mocks.NewMockShortHeaderSealer(mockCtrl), nil)
|
||||||
sealingManager.EXPECT().GetHandshakeSealer().Return(sealer, nil)
|
sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake)
|
||||||
initialStream.EXPECT().HasData()
|
initialStream.EXPECT().HasData()
|
||||||
|
@ -636,12 +638,105 @@ 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.PackPacket()
|
p, err := packer.PackCoalescedPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.frames).To(HaveLen(1))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
Expect(p.raw).To(HaveLen(int(packer.maxPacketSize)))
|
Expect(p.packets[0].frames).To(HaveLen(1))
|
||||||
Expect(p.header.IsLongHeader).To(BeTrue())
|
Expect(p.packets[0].header.IsLongHeader).To(BeTrue())
|
||||||
checkLength(p.raw)
|
Expect(p.buffer.Len()).To(BeEquivalentTo(packer.maxPacketSize))
|
||||||
|
checkLength(p.buffer.Data)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("packs a coalesced packet with Initial / Handshake", func() {
|
||||||
|
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x24), protocol.PacketNumberLen2)
|
||||||
|
pnManager.EXPECT().PopPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x24))
|
||||||
|
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
|
pnManager.EXPECT().PopPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x42))
|
||||||
|
sealingManager.EXPECT().GetInitialSealer().Return(getSealer(), nil)
|
||||||
|
sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil)
|
||||||
|
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
||||||
|
// don't EXPECT any calls for a Handshake ACK frame
|
||||||
|
initialStream.EXPECT().HasData().Return(true).Times(2)
|
||||||
|
initialStream.EXPECT().PopCryptoFrame(gomock.Any()).DoAndReturn(func(size protocol.ByteCount) *wire.CryptoFrame {
|
||||||
|
return &wire.CryptoFrame{Offset: 0x42, Data: []byte("initial")}
|
||||||
|
})
|
||||||
|
handshakeStream.EXPECT().HasData().Return(true).Times(2)
|
||||||
|
handshakeStream.EXPECT().PopCryptoFrame(gomock.Any()).DoAndReturn(func(size protocol.ByteCount) *wire.CryptoFrame {
|
||||||
|
return &wire.CryptoFrame{Offset: 0x1337, Data: []byte("handshake")}
|
||||||
|
})
|
||||||
|
p, err := packer.PackCoalescedPacket()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p.packets).To(HaveLen(2))
|
||||||
|
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
||||||
|
Expect(p.packets[0].frames).To(HaveLen(1))
|
||||||
|
Expect(p.packets[0].frames[0].Frame.(*wire.CryptoFrame).Data).To(Equal([]byte("initial")))
|
||||||
|
Expect(p.packets[1].EncryptionLevel()).To(Equal(protocol.EncryptionHandshake))
|
||||||
|
Expect(p.packets[1].frames).To(HaveLen(1))
|
||||||
|
Expect(p.packets[1].frames[0].Frame.(*wire.CryptoFrame).Data).To(Equal([]byte("handshake")))
|
||||||
|
hdr, _, rest, err := wire.ParsePacket(p.buffer.Data, 0)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(hdr.Type).To(Equal(protocol.PacketTypeInitial))
|
||||||
|
hdr, _, rest, err = wire.ParsePacket(rest, 0)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(hdr.Type).To(Equal(protocol.PacketTypeHandshake))
|
||||||
|
Expect(rest).To(BeEmpty())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("packs a coalesced packet with Handshake / 1-RTT", func() {
|
||||||
|
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(0x42), protocol.PacketNumberLen2)
|
||||||
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
|
sealingManager.EXPECT().GetInitialSealer().Return(nil, handshake.ErrKeysDropped)
|
||||||
|
sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil)
|
||||||
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake)
|
||||||
|
// don't EXPECT any calls for a 1-RTT ACK frame
|
||||||
|
handshakeStream.EXPECT().HasData().Return(true).Times(2)
|
||||||
|
handshakeStream.EXPECT().PopCryptoFrame(gomock.Any()).DoAndReturn(func(size protocol.ByteCount) *wire.CryptoFrame {
|
||||||
|
return &wire.CryptoFrame{Offset: 0x1337, Data: []byte("handshake")}
|
||||||
|
})
|
||||||
|
expectAppendControlFrames()
|
||||||
|
expectAppendStreamFrames(ackhandler.Frame{Frame: &wire.StreamFrame{Data: []byte("foobar")}})
|
||||||
|
p, err := packer.PackCoalescedPacket()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p.packets).To(HaveLen(2))
|
||||||
|
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionHandshake))
|
||||||
|
Expect(p.packets[0].frames).To(HaveLen(1))
|
||||||
|
Expect(p.packets[0].frames[0].Frame.(*wire.CryptoFrame).Data).To(Equal([]byte("handshake")))
|
||||||
|
Expect(p.packets[1].EncryptionLevel()).To(Equal(protocol.Encryption1RTT))
|
||||||
|
Expect(p.packets[1].frames).To(HaveLen(1))
|
||||||
|
Expect(p.packets[1].frames[0].Frame.(*wire.StreamFrame).Data).To(Equal([]byte("foobar")))
|
||||||
|
hdr, _, rest, err := wire.ParsePacket(p.buffer.Data, 0)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(hdr.Type).To(Equal(protocol.PacketTypeHandshake))
|
||||||
|
hdr, _, rest, err = wire.ParsePacket(rest, 0)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(hdr.IsLongHeader).To(BeFalse())
|
||||||
|
Expect(rest).To(BeEmpty())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("doesn't add a coalesced packet if the remaining size is smaller than MaxCoalescedPacketSize", func() {
|
||||||
|
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(size protocol.ByteCount) *wire.CryptoFrame {
|
||||||
|
s := size - protocol.MinCoalescedPacketSize
|
||||||
|
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()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p.packets).To(HaveLen(1))
|
||||||
|
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
||||||
|
Expect(len(p.buffer.Data)).To(BeEquivalentTo(maxPacketSize - protocol.MinCoalescedPacketSize))
|
||||||
|
checkLength(p.buffer.Data)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("adds retransmissions", func() {
|
It("adds retransmissions", func() {
|
||||||
|
@ -650,36 +745,42 @@ var _ = Describe("Packet packer", func() {
|
||||||
retransmissionQueue.AddHandshake(&wire.CryptoFrame{Data: []byte("Handshake")})
|
retransmissionQueue.AddHandshake(&wire.CryptoFrame{Data: []byte("Handshake")})
|
||||||
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))
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(sealer, nil)
|
sealingManager.EXPECT().GetInitialSealer().Return(getSealer(), nil)
|
||||||
|
sealingManager.EXPECT().GetHandshakeSealer().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.PackPacket()
|
p, err := packer.PackCoalescedPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
Expect(p.frames).To(Equal([]ackhandler.Frame{{Frame: f}}))
|
Expect(p.packets[0].EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
||||||
Expect(p.header.IsLongHeader).To(BeTrue())
|
Expect(p.packets[0].frames).To(Equal([]ackhandler.Frame{{Frame: f}}))
|
||||||
checkLength(p.raw)
|
Expect(p.packets[0].header.IsLongHeader).To(BeTrue())
|
||||||
|
checkLength(p.buffer.Data)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("sends an Initial packet containing only an ACK", func() {
|
It("sends an Initial packet containing only an ACK", func() {
|
||||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 10, Largest: 20}}}
|
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 10, Largest: 20}}}
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial).Return(ack)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial).Return(ack)
|
||||||
initialStream.EXPECT().HasData().Times(2)
|
initialStream.EXPECT().HasData().Times(2)
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(sealer, nil)
|
sealingManager.EXPECT().GetInitialSealer().Return(getSealer(), nil)
|
||||||
|
sealingManager.EXPECT().GetHandshakeSealer().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.PackPacket()
|
p, err := packer.PackCoalescedPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.ack).To(Equal(ack))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
|
Expect(p.packets[0].ack).To(Equal(ack))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("doesn't pack anything if there's nothing to send at Initial and Handshake keys are not yet available", func() {
|
It("doesn't pack anything if there's nothing to send at Initial and Handshake keys are not yet available", func() {
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(sealer, 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)
|
||||||
initialStream.EXPECT().HasData()
|
initialStream.EXPECT().HasData()
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
||||||
p, err := packer.PackPacket()
|
p, err := packer.PackCoalescedPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p).To(BeNil())
|
Expect(p).To(BeNil())
|
||||||
})
|
})
|
||||||
|
@ -691,12 +792,14 @@ var _ = Describe("Packet packer", func() {
|
||||||
initialStream.EXPECT().HasData()
|
initialStream.EXPECT().HasData()
|
||||||
handshakeStream.EXPECT().HasData().Times(2)
|
handshakeStream.EXPECT().HasData().Times(2)
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(mocks.NewMockShortHeaderSealer(mockCtrl), nil)
|
sealingManager.EXPECT().GetInitialSealer().Return(mocks.NewMockShortHeaderSealer(mockCtrl), nil)
|
||||||
sealingManager.EXPECT().GetHandshakeSealer().Return(sealer, nil)
|
sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil)
|
||||||
|
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.PackPacket()
|
p, err := packer.PackCoalescedPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p.ack).To(Equal(ack))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
|
Expect(p.packets[0].ack).To(Equal(ack))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("pads Initial packets to the required minimum packet size", func() {
|
It("pads Initial packets to the required minimum packet size", func() {
|
||||||
|
@ -705,19 +808,23 @@ var _ = Describe("Packet packer", func() {
|
||||||
f := &wire.CryptoFrame{Data: []byte("foobar")}
|
f := &wire.CryptoFrame{Data: []byte("foobar")}
|
||||||
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))
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(sealer, nil)
|
sealingManager.EXPECT().GetInitialSealer().Return(getSealer(), nil)
|
||||||
|
sealingManager.EXPECT().GetHandshakeSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
|
sealingManager.EXPECT().Get0RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
|
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
||||||
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
|
||||||
packet, err := packer.PackPacket()
|
p, err := packer.PackCoalescedPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(packet.header.Token).To(Equal(token))
|
Expect(p.buffer.Len()).To(BeEquivalentTo(protocol.MinInitialPacketSize))
|
||||||
Expect(packet.raw).To(HaveLen(protocol.MinInitialPacketSize))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
Expect(packet.frames).To(HaveLen(1))
|
Expect(p.packets[0].header.Token).To(Equal(token))
|
||||||
cf := packet.frames[0].Frame.(*wire.CryptoFrame)
|
Expect(p.packets[0].frames).To(HaveLen(1))
|
||||||
|
cf := p.packets[0].frames[0].Frame.(*wire.CryptoFrame)
|
||||||
Expect(cf.Data).To(Equal([]byte("foobar")))
|
Expect(cf.Data).To(Equal([]byte("foobar")))
|
||||||
checkLength(packet.raw)
|
checkLength(p.buffer.Data)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("adds an ACK frame", func() {
|
It("adds an ACK frame", func() {
|
||||||
|
@ -725,42 +832,21 @@ var _ = Describe("Packet packer", func() {
|
||||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 42, Largest: 1337}}}
|
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 42, Largest: 1337}}}
|
||||||
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))
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(sealer, nil)
|
sealingManager.EXPECT().GetInitialSealer().Return(getSealer(), nil)
|
||||||
|
sealingManager.EXPECT().GetHandshakeSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
|
sealingManager.EXPECT().Get0RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
|
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial).Return(ack)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial).Return(ack)
|
||||||
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.version = protocol.VersionTLS
|
packer.version = protocol.VersionTLS
|
||||||
packer.perspective = protocol.PerspectiveClient
|
packer.perspective = protocol.PerspectiveClient
|
||||||
packet, err := packer.PackPacket()
|
p, err := packer.PackCoalescedPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(packet.raw).To(HaveLen(protocol.MinInitialPacketSize))
|
Expect(p.packets).To(HaveLen(1))
|
||||||
Expect(packet.ack).To(Equal(ack))
|
Expect(p.packets[0].ack).To(Equal(ack))
|
||||||
Expect(packet.frames).To(HaveLen(1))
|
Expect(p.packets[0].frames).To(HaveLen(1))
|
||||||
})
|
Expect(p.buffer.Len()).To(BeEquivalentTo(protocol.MinInitialPacketSize))
|
||||||
|
|
||||||
It("stops packing crypto packets when the keys are dropped", func() {
|
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(nil, handshake.ErrKeysDropped)
|
|
||||||
sealingManager.EXPECT().GetHandshakeSealer().Return(nil, handshake.ErrKeysDropped)
|
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
|
||||||
expectAppendControlFrames(ackhandler.Frame{Frame: &wire.PingFrame{}})
|
|
||||||
expectAppendStreamFrames()
|
|
||||||
packet, err := packer.PackPacket()
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
Expect(packet).ToNot(BeNil())
|
|
||||||
|
|
||||||
// now the packer should have realized that the handshake is confirmed
|
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x43), protocol.PacketNumberLen2)
|
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x43))
|
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
|
||||||
expectAppendControlFrames(ackhandler.Frame{Frame: &wire.PingFrame{}})
|
|
||||||
expectAppendStreamFrames()
|
|
||||||
packet, err = packer.PackPacket()
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
Expect(packet).ToNot(BeNil())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -768,7 +854,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
It("packs an Initial probe packet", func() {
|
It("packs an Initial probe packet", func() {
|
||||||
f := &wire.CryptoFrame{Data: []byte("Initial")}
|
f := &wire.CryptoFrame{Data: []byte("Initial")}
|
||||||
retransmissionQueue.AddInitial(f)
|
retransmissionQueue.AddInitial(f)
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(sealer, nil)
|
sealingManager.EXPECT().GetInitialSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial)
|
||||||
initialStream.EXPECT().HasData()
|
initialStream.EXPECT().HasData()
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
|
@ -780,13 +866,13 @@ var _ = Describe("Packet packer", func() {
|
||||||
Expect(packet.EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
Expect(packet.EncryptionLevel()).To(Equal(protocol.EncryptionInitial))
|
||||||
Expect(packet.frames).To(HaveLen(1))
|
Expect(packet.frames).To(HaveLen(1))
|
||||||
Expect(packet.frames[0].Frame).To(Equal(f))
|
Expect(packet.frames[0].Frame).To(Equal(f))
|
||||||
checkLength(packet.raw)
|
checkLength(packet.buffer.Data)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("packs a Handshake probe packet", func() {
|
It("packs a Handshake probe packet", func() {
|
||||||
f := &wire.CryptoFrame{Data: []byte("Handshake")}
|
f := &wire.CryptoFrame{Data: []byte("Handshake")}
|
||||||
retransmissionQueue.AddHandshake(f)
|
retransmissionQueue.AddHandshake(f)
|
||||||
sealingManager.EXPECT().GetHandshakeSealer().Return(sealer, nil)
|
sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake)
|
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake)
|
||||||
handshakeStream.EXPECT().HasData()
|
handshakeStream.EXPECT().HasData()
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
|
@ -798,13 +884,13 @@ var _ = Describe("Packet packer", func() {
|
||||||
Expect(packet.EncryptionLevel()).To(Equal(protocol.EncryptionHandshake))
|
Expect(packet.EncryptionLevel()).To(Equal(protocol.EncryptionHandshake))
|
||||||
Expect(packet.frames).To(HaveLen(1))
|
Expect(packet.frames).To(HaveLen(1))
|
||||||
Expect(packet.frames[0].Frame).To(Equal(f))
|
Expect(packet.frames[0].Frame).To(Equal(f))
|
||||||
checkLength(packet.raw)
|
checkLength(packet.buffer.Data)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("packs a 1-RTT probe packet", func() {
|
It("packs a 1-RTT probe packet", func() {
|
||||||
f := &wire.StreamFrame{Data: []byte("1-RTT")}
|
f := &wire.StreamFrame{Data: []byte("1-RTT")}
|
||||||
retransmissionQueue.AddInitial(f)
|
retransmissionQueue.AddInitial(f)
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(sealer, nil)
|
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
|
||||||
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT)
|
||||||
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
|
||||||
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
|
||||||
|
@ -824,25 +910,24 @@ var _ = Describe("Packet packer", func() {
|
||||||
|
|
||||||
var _ = Describe("Converting to AckHandler packets", func() {
|
var _ = Describe("Converting to AckHandler packets", func() {
|
||||||
It("convert a packet", func() {
|
It("convert a packet", func() {
|
||||||
packet := &packedPacket{
|
packet := &packetContents{
|
||||||
header: &wire.ExtendedHeader{Header: wire.Header{}},
|
header: &wire.ExtendedHeader{Header: wire.Header{}},
|
||||||
frames: []ackhandler.Frame{{Frame: &wire.MaxDataFrame{}}, {Frame: &wire.PingFrame{}}},
|
frames: []ackhandler.Frame{{Frame: &wire.MaxDataFrame{}}, {Frame: &wire.PingFrame{}}},
|
||||||
ack: &wire.AckFrame{AckRanges: []wire.AckRange{{Largest: 100, Smallest: 80}}},
|
ack: &wire.AckFrame{AckRanges: []wire.AckRange{{Largest: 100, Smallest: 80}}},
|
||||||
raw: []byte("foobar"),
|
length: 42,
|
||||||
}
|
}
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
p := packet.ToAckHandlerPacket(t, nil)
|
p := packet.ToAckHandlerPacket(t, nil)
|
||||||
Expect(p.Length).To(Equal(protocol.ByteCount(6)))
|
Expect(p.Length).To(Equal(protocol.ByteCount(42)))
|
||||||
Expect(p.Frames).To(Equal(packet.frames))
|
Expect(p.Frames).To(Equal(packet.frames))
|
||||||
Expect(p.LargestAcked).To(Equal(protocol.PacketNumber(100)))
|
Expect(p.LargestAcked).To(Equal(protocol.PacketNumber(100)))
|
||||||
Expect(p.SendTime).To(Equal(t))
|
Expect(p.SendTime).To(Equal(t))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("sets the LargestAcked to invalid, if the packet doesn't have an ACK frame", func() {
|
It("sets the LargestAcked to invalid, if the packet doesn't have an ACK frame", func() {
|
||||||
packet := &packedPacket{
|
packet := &packetContents{
|
||||||
header: &wire.ExtendedHeader{Header: wire.Header{}},
|
header: &wire.ExtendedHeader{Header: wire.Header{}},
|
||||||
frames: []ackhandler.Frame{{Frame: &wire.MaxDataFrame{}}, {Frame: &wire.PingFrame{}}},
|
frames: []ackhandler.Frame{{Frame: &wire.MaxDataFrame{}}, {Frame: &wire.PingFrame{}}},
|
||||||
raw: []byte("foobar"),
|
|
||||||
}
|
}
|
||||||
p := packet.ToAckHandlerPacket(time.Now(), nil)
|
p := packet.ToAckHandlerPacket(time.Now(), nil)
|
||||||
Expect(p.LargestAcked).To(Equal(protocol.InvalidPacketNumber))
|
Expect(p.LargestAcked).To(Equal(protocol.InvalidPacketNumber))
|
||||||
|
@ -850,13 +935,12 @@ var _ = Describe("Converting to AckHandler packets", func() {
|
||||||
|
|
||||||
It("doesn't overwrite the OnLost callback, if it is set", func() {
|
It("doesn't overwrite the OnLost callback, if it is set", func() {
|
||||||
var pingLost bool
|
var pingLost bool
|
||||||
packet := &packedPacket{
|
packet := &packetContents{
|
||||||
header: &wire.ExtendedHeader{Header: wire.Header{Type: protocol.PacketTypeHandshake}},
|
header: &wire.ExtendedHeader{Header: wire.Header{Type: protocol.PacketTypeHandshake}},
|
||||||
frames: []ackhandler.Frame{
|
frames: []ackhandler.Frame{
|
||||||
{Frame: &wire.MaxDataFrame{}},
|
{Frame: &wire.MaxDataFrame{}},
|
||||||
{Frame: &wire.PingFrame{}, OnLost: func(wire.Frame) { pingLost = true }},
|
{Frame: &wire.PingFrame{}, OnLost: func(wire.Frame) { pingLost = true }},
|
||||||
},
|
},
|
||||||
raw: []byte("foobar"),
|
|
||||||
}
|
}
|
||||||
p := packet.ToAckHandlerPacket(time.Now(), newRetransmissionQueue(protocol.VersionTLS))
|
p := packet.ToAckHandlerPacket(time.Now(), newRetransmissionQueue(protocol.VersionTLS))
|
||||||
Expect(p.Frames).To(HaveLen(2))
|
Expect(p.Frames).To(HaveLen(2))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package quic
|
package quic
|
||||||
|
|
||||||
type sendQueue struct {
|
type sendQueue struct {
|
||||||
queue chan *packedPacket
|
queue chan *packetBuffer
|
||||||
closeCalled chan struct{} // runStopped when Close() is called
|
closeCalled chan struct{} // runStopped when Close() is called
|
||||||
runStopped chan struct{} // runStopped when the run loop returns
|
runStopped chan struct{} // runStopped when the run loop returns
|
||||||
conn connection
|
conn connection
|
||||||
|
@ -12,12 +12,12 @@ func newSendQueue(conn connection) *sendQueue {
|
||||||
conn: conn,
|
conn: conn,
|
||||||
runStopped: make(chan struct{}),
|
runStopped: make(chan struct{}),
|
||||||
closeCalled: make(chan struct{}),
|
closeCalled: make(chan struct{}),
|
||||||
queue: make(chan *packedPacket, 1),
|
queue: make(chan *packetBuffer, 1),
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *sendQueue) Send(p *packedPacket) {
|
func (h *sendQueue) Send(p *packetBuffer) {
|
||||||
h.queue <- p
|
h.queue <- p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,10 +34,10 @@ func (h *sendQueue) Run() error {
|
||||||
// make sure that all queued packets are actually sent out
|
// make sure that all queued packets are actually sent out
|
||||||
shouldClose = true
|
shouldClose = true
|
||||||
case p := <-h.queue:
|
case p := <-h.queue:
|
||||||
if err := h.conn.Write(p.raw); err != nil {
|
if err := h.conn.Write(p.Data); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.buffer.Release()
|
p.Release()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,11 @@ var _ = Describe("Send Queue", func() {
|
||||||
q = newSendQueue(c)
|
q = newSendQueue(c)
|
||||||
})
|
})
|
||||||
|
|
||||||
getPacket := func(b []byte) *packedPacket {
|
getPacket := func(b []byte) *packetBuffer {
|
||||||
buf := getPacketBuffer()
|
buf := getPacketBuffer()
|
||||||
buf.Slice = buf.Slice[:len(b)]
|
buf.Data = buf.Data[:len(b)]
|
||||||
copy(buf.Slice, b)
|
copy(buf.Data, b)
|
||||||
return &packedPacket{
|
return buf
|
||||||
buffer: buf,
|
|
||||||
raw: buf.Slice,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
It("sends a packet", func() {
|
It("sends a packet", func() {
|
||||||
|
@ -30,7 +27,7 @@ var _ = Describe("Send Queue", func() {
|
||||||
q.Send(p)
|
q.Send(p)
|
||||||
|
|
||||||
written := make(chan struct{})
|
written := make(chan struct{})
|
||||||
c.EXPECT().Write(p.raw).Do(func([]byte) { close(written) })
|
c.EXPECT().Write([]byte("foobar")).Do(func([]byte) { close(written) })
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
|
|
|
@ -516,7 +516,7 @@ func (s *baseServer) sendServerBusy(remoteAddr net.Addr, hdr *wire.Header) error
|
||||||
sealer, _ := handshake.NewInitialAEAD(hdr.DestConnectionID, protocol.PerspectiveServer)
|
sealer, _ := handshake.NewInitialAEAD(hdr.DestConnectionID, protocol.PerspectiveServer)
|
||||||
packetBuffer := getPacketBuffer()
|
packetBuffer := getPacketBuffer()
|
||||||
defer packetBuffer.Release()
|
defer packetBuffer.Release()
|
||||||
buf := bytes.NewBuffer(packetBuffer.Slice[:0])
|
buf := bytes.NewBuffer(packetBuffer.Data)
|
||||||
|
|
||||||
ccf := &wire.ConnectionCloseFrame{ErrorCode: qerr.ServerBusy}
|
ccf := &wire.ConnectionCloseFrame{ErrorCode: qerr.ServerBusy}
|
||||||
|
|
||||||
|
|
114
session.go
114
session.go
|
@ -164,6 +164,7 @@ type session struct {
|
||||||
earlySessionReadyChan chan struct{}
|
earlySessionReadyChan chan struct{}
|
||||||
handshakeCompleteChan chan struct{} // is closed when the handshake completes
|
handshakeCompleteChan chan struct{} // is closed when the handshake completes
|
||||||
handshakeComplete bool
|
handshakeComplete bool
|
||||||
|
handshakeConfirmed bool
|
||||||
|
|
||||||
receivedRetry bool
|
receivedRetry bool
|
||||||
receivedFirstPacket bool
|
receivedFirstPacket bool
|
||||||
|
@ -1139,6 +1140,9 @@ func (s *session) handleCloseError(closeErr closeError) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *session) dropEncryptionLevel(encLevel protocol.EncryptionLevel) {
|
func (s *session) dropEncryptionLevel(encLevel protocol.EncryptionLevel) {
|
||||||
|
if encLevel == protocol.EncryptionHandshake {
|
||||||
|
s.handshakeConfirmed = true
|
||||||
|
}
|
||||||
s.sentPacketHandler.DropPackets(encLevel)
|
s.sentPacketHandler.DropPackets(encLevel)
|
||||||
s.receivedPacketHandler.DropPackets(encLevel)
|
s.receivedPacketHandler.DropPackets(encLevel)
|
||||||
}
|
}
|
||||||
|
@ -1247,7 +1251,7 @@ sendLoop:
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *session) maybeSendAckOnlyPacket() error {
|
func (s *session) maybeSendAckOnlyPacket() error {
|
||||||
packet, err := s.packer.MaybePackAckPacket()
|
packet, err := s.packer.MaybePackAckPacket(s.handshakeConfirmed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1305,6 +1309,23 @@ func (s *session) sendPacket() (bool, error) {
|
||||||
}
|
}
|
||||||
s.windowUpdateQueue.QueueAll()
|
s.windowUpdateQueue.QueueAll()
|
||||||
|
|
||||||
|
if !s.handshakeConfirmed {
|
||||||
|
now := time.Now()
|
||||||
|
packet, err := s.packer.PackCoalescedPacket()
|
||||||
|
if err != nil || packet == nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
for _, p := range packet.packets {
|
||||||
|
if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() {
|
||||||
|
s.firstAckElicitingPacketAfterIdleSentTime = now
|
||||||
|
}
|
||||||
|
s.sentPacketHandler.SentPacket(p.ToAckHandlerPacket(now, s.retransmissionQueue))
|
||||||
|
}
|
||||||
|
s.connIDManager.SentPacket()
|
||||||
|
s.logCoalescedPacket(now, packet)
|
||||||
|
s.sendQueue.Send(packet.buffer)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
packet, err := s.packer.PackPacket()
|
packet, err := s.packer.PackPacket()
|
||||||
if err != nil || packet == nil {
|
if err != nil || packet == nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -1314,36 +1335,14 @@ func (s *session) sendPacket() (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *session) sendPackedPacket(packet *packedPacket) {
|
func (s *session) sendPackedPacket(packet *packedPacket) {
|
||||||
if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && packet.IsAckEliciting() {
|
|
||||||
s.firstAckElicitingPacketAfterIdleSentTime = time.Now()
|
|
||||||
}
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
s.sentPacketHandler.SentPacket(packet.ToAckHandlerPacket(now, s.retransmissionQueue))
|
if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && packet.IsAckEliciting() {
|
||||||
if s.traceCallback != nil {
|
s.firstAckElicitingPacketAfterIdleSentTime = now
|
||||||
frames := make([]wire.Frame, 0, len(packet.frames))
|
|
||||||
for _, f := range packet.frames {
|
|
||||||
frames = append(frames, f.Frame)
|
|
||||||
}
|
|
||||||
s.traceCallback(quictrace.Event{
|
|
||||||
Time: now,
|
|
||||||
EventType: quictrace.PacketSent,
|
|
||||||
TransportState: s.sentPacketHandler.GetStats(),
|
|
||||||
EncryptionLevel: packet.EncryptionLevel(),
|
|
||||||
PacketNumber: packet.header.PacketNumber,
|
|
||||||
PacketSize: protocol.ByteCount(len(packet.raw)),
|
|
||||||
Frames: frames,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
if s.qlogger != nil {
|
s.sentPacketHandler.SentPacket(packet.ToAckHandlerPacket(time.Now(), s.retransmissionQueue))
|
||||||
frames := make([]wire.Frame, 0, len(packet.frames))
|
|
||||||
for _, f := range packet.frames {
|
|
||||||
frames = append(frames, f.Frame)
|
|
||||||
}
|
|
||||||
s.qlogger.SentPacket(now, packet.header, protocol.ByteCount(len(packet.raw)), packet.ack, frames)
|
|
||||||
}
|
|
||||||
s.logPacket(packet)
|
|
||||||
s.connIDManager.SentPacket()
|
s.connIDManager.SentPacket()
|
||||||
s.sendQueue.Send(packet)
|
s.logPacket(now, packet)
|
||||||
|
s.sendQueue.Send(packet.buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *session) sendConnectionClose(quicErr *qerr.QuicError) ([]byte, error) {
|
func (s *session) sendConnectionClose(quicErr *qerr.QuicError) ([]byte, error) {
|
||||||
|
@ -1365,25 +1364,66 @@ func (s *session) sendConnectionClose(quicErr *qerr.QuicError) ([]byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.logPacket(packet)
|
s.logPacket(time.Now(), packet)
|
||||||
return packet.raw, s.conn.Write(packet.raw)
|
return packet.buffer.Data, s.conn.Write(packet.buffer.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *session) logPacket(packet *packedPacket) {
|
func (s *session) logPacketContents(now time.Time, p *packetContents) {
|
||||||
|
// qlog
|
||||||
|
if s.qlogger != nil {
|
||||||
|
frames := make([]wire.Frame, 0, len(p.frames))
|
||||||
|
for _, f := range p.frames {
|
||||||
|
frames = append(frames, f.Frame)
|
||||||
|
}
|
||||||
|
s.qlogger.SentPacket(now, p.header, p.length, p.ack, frames)
|
||||||
|
}
|
||||||
|
|
||||||
|
// quic-trace
|
||||||
|
if s.traceCallback != nil {
|
||||||
|
frames := make([]wire.Frame, 0, len(p.frames))
|
||||||
|
for _, f := range p.frames {
|
||||||
|
frames = append(frames, f.Frame)
|
||||||
|
}
|
||||||
|
s.traceCallback(quictrace.Event{
|
||||||
|
Time: now,
|
||||||
|
EventType: quictrace.PacketSent,
|
||||||
|
TransportState: s.sentPacketHandler.GetStats(),
|
||||||
|
EncryptionLevel: p.EncryptionLevel(),
|
||||||
|
PacketNumber: p.header.PacketNumber,
|
||||||
|
PacketSize: p.length,
|
||||||
|
Frames: frames,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// quic-go logging
|
||||||
if !s.logger.Debug() {
|
if !s.logger.Debug() {
|
||||||
// We don't need to allocate the slices for calling the format functions
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.logger.Debugf("-> Sending packet 0x%x (%d bytes) for connection %s, %s", packet.header.PacketNumber, len(packet.raw), s.logID, packet.EncryptionLevel())
|
p.header.Log(s.logger)
|
||||||
packet.header.Log(s.logger)
|
if p.ack != nil {
|
||||||
if packet.ack != nil {
|
wire.LogFrame(s.logger, p.ack, true)
|
||||||
wire.LogFrame(s.logger, packet.ack, true)
|
|
||||||
}
|
}
|
||||||
for _, frame := range packet.frames {
|
for _, frame := range p.frames {
|
||||||
wire.LogFrame(s.logger, frame.Frame, true)
|
wire.LogFrame(s.logger, frame.Frame, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *session) logCoalescedPacket(now time.Time, packet *coalescedPacket) {
|
||||||
|
if s.logger.Debug() {
|
||||||
|
s.logger.Debugf("-> Sending coalesced packet (%d parts, %d bytes) for connection %s", len(packet.packets), packet.buffer.Len(), s.logID)
|
||||||
|
}
|
||||||
|
for _, p := range packet.packets {
|
||||||
|
s.logPacketContents(now, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *session) logPacket(now time.Time, packet *packedPacket) {
|
||||||
|
if s.logger.Debug() {
|
||||||
|
s.logger.Debugf("-> Sending packet %#x (%d bytes) for connection %s, %s", packet.header.PacketNumber, packet.buffer.Len(), s.logID, packet.EncryptionLevel())
|
||||||
|
}
|
||||||
|
s.logPacketContents(now, packet.packetContents)
|
||||||
|
}
|
||||||
|
|
||||||
// AcceptStream returns the next stream openend by the peer
|
// AcceptStream returns the next stream openend by the peer
|
||||||
func (s *session) AcceptStream(ctx context.Context) (Stream, error) {
|
func (s *session) AcceptStream(ctx context.Context) (Stream, error) {
|
||||||
return s.streamsMap.AcceptStream(ctx)
|
return s.streamsMap.AcceptStream(ctx)
|
||||||
|
|
164
session_test.go
164
session_test.go
|
@ -54,12 +54,12 @@ var _ = Describe("Session", func() {
|
||||||
|
|
||||||
getPacket := func(pn protocol.PacketNumber) *packedPacket {
|
getPacket := func(pn protocol.PacketNumber) *packedPacket {
|
||||||
buffer := getPacketBuffer()
|
buffer := getPacketBuffer()
|
||||||
data := buffer.Slice[:0]
|
buffer.Data = append(buffer.Data, []byte("foobar")...)
|
||||||
data = append(data, []byte("foobar")...)
|
|
||||||
return &packedPacket{
|
return &packedPacket{
|
||||||
raw: data,
|
|
||||||
buffer: buffer,
|
buffer: buffer,
|
||||||
header: &wire.ExtendedHeader{PacketNumber: pn},
|
packetContents: &packetContents{
|
||||||
|
header: &wire.ExtendedHeader{PacketNumber: pn},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,12 +417,14 @@ var _ = Describe("Session", func() {
|
||||||
streamManager.EXPECT().CloseWithError(qerr.ApplicationError(0, ""))
|
streamManager.EXPECT().CloseWithError(qerr.ApplicationError(0, ""))
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
|
buffer := getPacketBuffer()
|
||||||
|
buffer.Data = append(buffer.Data, []byte("connection close")...)
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).DoAndReturn(func(f *wire.ConnectionCloseFrame) (*packedPacket, error) {
|
packer.EXPECT().PackConnectionClose(gomock.Any()).DoAndReturn(func(f *wire.ConnectionCloseFrame) (*packedPacket, error) {
|
||||||
Expect(f.IsApplicationError).To(BeTrue())
|
Expect(f.IsApplicationError).To(BeTrue())
|
||||||
Expect(f.ErrorCode).To(Equal(qerr.NoError))
|
Expect(f.ErrorCode).To(Equal(qerr.NoError))
|
||||||
Expect(f.FrameType).To(BeZero())
|
Expect(f.FrameType).To(BeZero())
|
||||||
Expect(f.ReasonPhrase).To(BeEmpty())
|
Expect(f.ReasonPhrase).To(BeEmpty())
|
||||||
return &packedPacket{raw: []byte("connection close")}, nil
|
return &packedPacket{buffer: buffer}, nil
|
||||||
})
|
})
|
||||||
mconn.EXPECT().Write([]byte("connection close"))
|
mconn.EXPECT().Write([]byte("connection close"))
|
||||||
sess.shutdown()
|
sess.shutdown()
|
||||||
|
@ -434,7 +436,7 @@ var _ = Describe("Session", func() {
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
sess.shutdown()
|
sess.shutdown()
|
||||||
sess.shutdown()
|
sess.shutdown()
|
||||||
|
@ -450,7 +452,7 @@ var _ = Describe("Session", func() {
|
||||||
Expect(f.IsApplicationError).To(BeTrue())
|
Expect(f.IsApplicationError).To(BeTrue())
|
||||||
Expect(f.ErrorCode).To(BeEquivalentTo(0x1337))
|
Expect(f.ErrorCode).To(BeEquivalentTo(0x1337))
|
||||||
Expect(f.ReasonPhrase).To(Equal("test error"))
|
Expect(f.ReasonPhrase).To(Equal("test error"))
|
||||||
return &packedPacket{}, nil
|
return &packedPacket{buffer: getPacketBuffer()}, nil
|
||||||
})
|
})
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
sess.CloseWithError(0x1337, "test error")
|
sess.CloseWithError(0x1337, "test error")
|
||||||
|
@ -468,7 +470,7 @@ var _ = Describe("Session", func() {
|
||||||
Expect(f.FrameType).To(BeEquivalentTo(0x42))
|
Expect(f.FrameType).To(BeEquivalentTo(0x42))
|
||||||
Expect(f.ErrorCode).To(BeEquivalentTo(0x1337))
|
Expect(f.ErrorCode).To(BeEquivalentTo(0x1337))
|
||||||
Expect(f.ReasonPhrase).To(Equal("test error"))
|
Expect(f.ReasonPhrase).To(Equal("test error"))
|
||||||
return &packedPacket{}, nil
|
return &packedPacket{buffer: getPacketBuffer()}, nil
|
||||||
})
|
})
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
sess.closeLocal(testErr)
|
sess.closeLocal(testErr)
|
||||||
|
@ -485,7 +487,7 @@ var _ = Describe("Session", func() {
|
||||||
Expect(f.IsApplicationError).To(BeFalse())
|
Expect(f.IsApplicationError).To(BeFalse())
|
||||||
Expect(f.ErrorCode).To(BeEquivalentTo(0x15a))
|
Expect(f.ErrorCode).To(BeEquivalentTo(0x15a))
|
||||||
Expect(f.ReasonPhrase).To(BeEmpty())
|
Expect(f.ReasonPhrase).To(BeEmpty())
|
||||||
return &packedPacket{}, nil
|
return &packedPacket{buffer: getPacketBuffer()}, nil
|
||||||
})
|
})
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
sess.CloseWithError(0x1337, "test error")
|
sess.CloseWithError(0x1337, "test error")
|
||||||
|
@ -518,7 +520,7 @@ var _ = Describe("Session", func() {
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
returned := make(chan struct{})
|
returned := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
|
@ -607,7 +609,7 @@ var _ = Describe("Session", func() {
|
||||||
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, handshake.ErrDecryptionFailed)
|
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, handshake.ErrDecryptionFailed)
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
go func() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
cryptoSetup.EXPECT().RunHandshake().MaxTimes(1)
|
cryptoSetup.EXPECT().RunHandshake().MaxTimes(1)
|
||||||
|
@ -629,7 +631,7 @@ var _ = Describe("Session", func() {
|
||||||
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, wire.ErrInvalidReservedBits)
|
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, wire.ErrInvalidReservedBits)
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
|
@ -653,7 +655,7 @@ var _ = Describe("Session", func() {
|
||||||
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, testErr)
|
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, testErr)
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
runErr := make(chan error)
|
runErr := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
|
@ -679,7 +681,7 @@ var _ = Describe("Session", func() {
|
||||||
}, nil)
|
}, nil)
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
|
@ -875,7 +877,7 @@ var _ = Describe("Session", func() {
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
|
@ -884,6 +886,7 @@ var _ = Describe("Session", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("sends packets", func() {
|
It("sends packets", func() {
|
||||||
|
sess.handshakeConfirmed = true
|
||||||
packer.EXPECT().PackPacket().Return(getPacket(1), nil)
|
packer.EXPECT().PackPacket().Return(getPacket(1), nil)
|
||||||
sess.receivedPacketHandler.ReceivedPacket(0x035e, protocol.Encryption1RTT, time.Now(), true)
|
sess.receivedPacketHandler.ReceivedPacket(0x035e, protocol.Encryption1RTT, time.Now(), true)
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
|
@ -893,6 +896,7 @@ var _ = Describe("Session", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("doesn't send packets if there's nothing to send", func() {
|
It("doesn't send packets if there's nothing to send", func() {
|
||||||
|
sess.handshakeConfirmed = true
|
||||||
packer.EXPECT().PackPacket().Return(nil, nil)
|
packer.EXPECT().PackPacket().Return(nil, nil)
|
||||||
sess.receivedPacketHandler.ReceivedPacket(0x035e, protocol.Encryption1RTT, time.Now(), true)
|
sess.receivedPacketHandler.ReceivedPacket(0x035e, protocol.Encryption1RTT, time.Now(), true)
|
||||||
sent, err := sess.sendPacket()
|
sent, err := sess.sendPacket()
|
||||||
|
@ -905,12 +909,13 @@ var _ = Describe("Session", func() {
|
||||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||||
sph.EXPECT().SendMode().Return(ackhandler.SendAck)
|
sph.EXPECT().SendMode().Return(ackhandler.SendAck)
|
||||||
sph.EXPECT().ShouldSendNumPackets().Return(1000)
|
sph.EXPECT().ShouldSendNumPackets().Return(1000)
|
||||||
packer.EXPECT().MaybePackAckPacket()
|
packer.EXPECT().MaybePackAckPacket(false)
|
||||||
sess.sentPacketHandler = sph
|
sess.sentPacketHandler = sph
|
||||||
Expect(sess.sendPackets()).To(Succeed())
|
Expect(sess.sendPackets()).To(Succeed())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("adds a BLOCKED frame when it is connection-level flow control blocked", func() {
|
It("adds a BLOCKED frame when it is connection-level flow control blocked", func() {
|
||||||
|
sess.handshakeConfirmed = true
|
||||||
fc := mocks.NewMockConnectionFlowController(mockCtrl)
|
fc := mocks.NewMockConnectionFlowController(mockCtrl)
|
||||||
fc.EXPECT().IsNewlyBlocked().Return(true, protocol.ByteCount(1337))
|
fc.EXPECT().IsNewlyBlocked().Return(true, protocol.ByteCount(1337))
|
||||||
packer.EXPECT().PackPacket().Return(getPacket(1), nil)
|
packer.EXPECT().PackPacket().Return(getPacket(1), nil)
|
||||||
|
@ -996,13 +1001,14 @@ var _ = Describe("Session", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sph = mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
sph = mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||||
|
sess.handshakeConfirmed = true
|
||||||
sess.sentPacketHandler = sph
|
sess.sentPacketHandler = sph
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
// make the go routine return
|
// make the go routine return
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
|
@ -1113,11 +1119,15 @@ var _ = Describe("Session", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("scheduling sending", func() {
|
Context("scheduling sending", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
sess.handshakeConfirmed = true
|
||||||
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
// make the go routine return
|
// make the go routine return
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
sess.shutdown()
|
sess.shutdown()
|
||||||
|
@ -1177,8 +1187,77 @@ var _ = Describe("Session", func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("sends coalesced packets before the handshake is confirmed", func() {
|
||||||
|
sess.handshakeConfirmed = false
|
||||||
|
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||||
|
sess.sentPacketHandler = sph
|
||||||
|
buffer := getPacketBuffer()
|
||||||
|
buffer.Data = append(buffer.Data, []byte("foobar")...)
|
||||||
|
packer.EXPECT().PackCoalescedPacket().Return(&coalescedPacket{
|
||||||
|
buffer: buffer,
|
||||||
|
packets: []*packetContents{
|
||||||
|
{
|
||||||
|
header: &wire.ExtendedHeader{
|
||||||
|
Header: wire.Header{
|
||||||
|
IsLongHeader: true,
|
||||||
|
Type: protocol.PacketTypeInitial,
|
||||||
|
},
|
||||||
|
PacketNumber: 13,
|
||||||
|
},
|
||||||
|
length: 123,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: &wire.ExtendedHeader{
|
||||||
|
Header: wire.Header{
|
||||||
|
IsLongHeader: true,
|
||||||
|
Type: protocol.PacketTypeHandshake,
|
||||||
|
},
|
||||||
|
PacketNumber: 37,
|
||||||
|
},
|
||||||
|
length: 1234,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
||||||
|
|
||||||
|
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||||
|
sph.EXPECT().SendMode().Return(ackhandler.SendAny).AnyTimes()
|
||||||
|
sph.EXPECT().TimeUntilSend().Return(time.Now()).AnyTimes()
|
||||||
|
sph.EXPECT().ShouldSendNumPackets().Return(1).AnyTimes()
|
||||||
|
sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
|
||||||
|
Expect(p.EncryptionLevel).To(Equal(protocol.EncryptionInitial))
|
||||||
|
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(13)))
|
||||||
|
Expect(p.Length).To(BeEquivalentTo(123))
|
||||||
|
})
|
||||||
|
sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
|
||||||
|
Expect(p.EncryptionLevel).To(Equal(protocol.EncryptionHandshake))
|
||||||
|
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(37)))
|
||||||
|
Expect(p.Length).To(BeEquivalentTo(1234))
|
||||||
|
})
|
||||||
|
sent := make(chan struct{})
|
||||||
|
mconn.EXPECT().Write([]byte("foobar")).Do(func([]byte) { close(sent) })
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
cryptoSetup.EXPECT().RunHandshake().MaxTimes(1)
|
||||||
|
sess.run()
|
||||||
|
}()
|
||||||
|
|
||||||
|
sess.scheduleSending()
|
||||||
|
Eventually(sent).Should(BeClosed())
|
||||||
|
|
||||||
|
// make sure the go routine returns
|
||||||
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
|
expectReplaceWithClosed()
|
||||||
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
|
cryptoSetup.EXPECT().Close()
|
||||||
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
|
sess.shutdown()
|
||||||
|
Eventually(sess.Context().Done()).Should(BeClosed())
|
||||||
|
})
|
||||||
|
|
||||||
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().PackPacket().AnyTimes()
|
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
||||||
finishHandshake := make(chan struct{})
|
finishHandshake := make(chan struct{})
|
||||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||||
sess.sentPacketHandler = sph
|
sess.sentPacketHandler = sph
|
||||||
|
@ -1206,7 +1285,7 @@ var _ = Describe("Session", func() {
|
||||||
// make sure the go routine returns
|
// make sure the go routine returns
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
sess.shutdown()
|
sess.shutdown()
|
||||||
|
@ -1215,7 +1294,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().PackPacket().AnyTimes()
|
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
||||||
finishHandshake := make(chan struct{})
|
finishHandshake := make(chan struct{})
|
||||||
sessionRunner.EXPECT().Retire(clientDestConnID)
|
sessionRunner.EXPECT().Retire(clientDestConnID)
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -1247,7 +1326,7 @@ var _ = Describe("Session", func() {
|
||||||
// make sure the go routine returns
|
// make sure the go routine returns
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
sess.shutdown()
|
sess.shutdown()
|
||||||
|
@ -1255,10 +1334,10 @@ 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().PackPacket().AnyTimes()
|
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
go func() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
|
@ -1276,17 +1355,19 @@ 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().PackPacket().DoAndReturn(func() (*packedPacket, error) {
|
packer.EXPECT().PackCoalescedPacket().DoAndReturn(func() (*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{}))
|
||||||
defer close(done)
|
defer close(done)
|
||||||
return &packedPacket{
|
return &packedPacket{
|
||||||
header: &wire.ExtendedHeader{},
|
packetContents: &packetContents{
|
||||||
|
header: &wire.ExtendedHeader{},
|
||||||
|
},
|
||||||
buffer: getPacketBuffer(),
|
buffer: getPacketBuffer(),
|
||||||
}, nil
|
}, nil
|
||||||
})
|
})
|
||||||
packer.EXPECT().PackPacket().AnyTimes()
|
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
||||||
go func() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
cryptoSetup.EXPECT().RunHandshake()
|
cryptoSetup.EXPECT().RunHandshake()
|
||||||
|
@ -1301,9 +1382,8 @@ var _ = Describe("Session", func() {
|
||||||
// make sure the go routine returns
|
// make sure the go routine returns
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
|
||||||
sess.shutdown()
|
sess.shutdown()
|
||||||
Eventually(sess.Context().Done()).Should(BeClosed())
|
Eventually(sess.Context().Done()).Should(BeClosed())
|
||||||
})
|
})
|
||||||
|
@ -1318,7 +1398,7 @@ var _ = Describe("Session", func() {
|
||||||
}()
|
}()
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
sess.shutdown()
|
sess.shutdown()
|
||||||
|
@ -1337,7 +1417,7 @@ var _ = Describe("Session", func() {
|
||||||
}()
|
}()
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
Expect(sess.CloseWithError(0x1337, testErr.Error())).To(Succeed())
|
Expect(sess.CloseWithError(0x1337, testErr.Error())).To(Succeed())
|
||||||
|
@ -1361,7 +1441,7 @@ var _ = Describe("Session", func() {
|
||||||
}
|
}
|
||||||
streamManager.EXPECT().UpdateLimits(params)
|
streamManager.EXPECT().UpdateLimits(params)
|
||||||
packer.EXPECT().HandleTransportParameters(params)
|
packer.EXPECT().HandleTransportParameters(params)
|
||||||
packer.EXPECT().PackPacket().MaxTimes(3)
|
packer.EXPECT().PackCoalescedPacket().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)
|
||||||
|
@ -1374,7 +1454,7 @@ var _ = Describe("Session", func() {
|
||||||
Expect(s).To(BeAssignableToTypeOf(&closedLocalSession{}))
|
Expect(s).To(BeAssignableToTypeOf(&closedLocalSession{}))
|
||||||
s.shutdown()
|
s.shutdown()
|
||||||
}).Times(4) // initial connection ID + initial client dest conn ID + 2 newly issued conn IDs
|
}).Times(4) // initial connection ID + initial client dest conn ID + 2 newly issued conn IDs
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
sess.shutdown()
|
sess.shutdown()
|
||||||
|
@ -1406,7 +1486,7 @@ var _ = Describe("Session", func() {
|
||||||
// make the go routine return
|
// make the go routine return
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
sess.shutdown()
|
sess.shutdown()
|
||||||
|
@ -1417,7 +1497,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().PackPacket().Do(func() (*packedPacket, error) {
|
packer.EXPECT().PackCoalescedPacket().Do(func() (*packedPacket, error) {
|
||||||
close(sent)
|
close(sent)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
})
|
})
|
||||||
|
@ -1430,7 +1510,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().PackPacket().Do(func() (*packedPacket, error) {
|
packer.EXPECT().PackCoalescedPacket().Do(func() (*packedPacket, error) {
|
||||||
close(sent)
|
close(sent)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
})
|
})
|
||||||
|
@ -1506,7 +1586,7 @@ var _ = Describe("Session", func() {
|
||||||
sess.lastPacketReceivedTime = time.Now().Add(-time.Minute)
|
sess.lastPacketReceivedTime = time.Now().Add(-time.Minute)
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).DoAndReturn(func(f *wire.ConnectionCloseFrame) (*packedPacket, error) {
|
packer.EXPECT().PackConnectionClose(gomock.Any()).DoAndReturn(func(f *wire.ConnectionCloseFrame) (*packedPacket, error) {
|
||||||
Expect(f.ErrorCode).To(Equal(qerr.NoError))
|
Expect(f.ErrorCode).To(Equal(qerr.NoError))
|
||||||
return &packedPacket{}, nil
|
return &packedPacket{buffer: getPacketBuffer()}, nil
|
||||||
})
|
})
|
||||||
// the handshake timeout is irrelevant here, since it depends on the time the session was created,
|
// the handshake timeout is irrelevant here, since it depends on the time the session was created,
|
||||||
// and not on the last network activity
|
// and not on the last network activity
|
||||||
|
@ -1526,7 +1606,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().PackPacket().AnyTimes()
|
packer.EXPECT().PackCoalescedPacket().AnyTimes()
|
||||||
gomock.InOrder(
|
gomock.InOrder(
|
||||||
sessionRunner.EXPECT().Retire(clientDestConnID),
|
sessionRunner.EXPECT().Retire(clientDestConnID),
|
||||||
sessionRunner.EXPECT().Remove(gomock.Any()),
|
sessionRunner.EXPECT().Remove(gomock.Any()),
|
||||||
|
@ -1562,7 +1642,7 @@ var _ = Describe("Session", func() {
|
||||||
}()
|
}()
|
||||||
Consistently(sess.Context().Done()).ShouldNot(BeClosed())
|
Consistently(sess.Context().Done()).ShouldNot(BeClosed())
|
||||||
// make the go routine return
|
// make the go routine return
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
|
@ -1738,7 +1818,7 @@ var _ = Describe("Client Session", func() {
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
}, []byte{0}))).To(BeTrue())
|
}, []byte{0}))).To(BeTrue())
|
||||||
// make sure the go routine returns
|
// make sure the go routine returns
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
|
@ -1863,7 +1943,7 @@ var _ = Describe("Client Session", func() {
|
||||||
Expect(s).To(BeAssignableToTypeOf(&closedLocalSession{}))
|
Expect(s).To(BeAssignableToTypeOf(&closedLocalSession{}))
|
||||||
s.shutdown()
|
s.shutdown()
|
||||||
})
|
})
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil).MaxTimes(1)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{buffer: getPacketBuffer()}, nil).MaxTimes(1)
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
mconn.EXPECT().Write(gomock.Any())
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
}
|
}
|
||||||
|
@ -1885,7 +1965,7 @@ var _ = Describe("Client Session", func() {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
packer.EXPECT().HandleTransportParameters(gomock.Any())
|
packer.EXPECT().HandleTransportParameters(gomock.Any())
|
||||||
packer.EXPECT().PackPacket().MaxTimes(1)
|
packer.EXPECT().PackCoalescedPacket().MaxTimes(1)
|
||||||
sess.processTransportParameters(params)
|
sess.processTransportParameters(params)
|
||||||
cf, _ := sess.framer.AppendControlFrames(nil, protocol.MaxByteCount)
|
cf, _ := sess.framer.AppendControlFrames(nil, protocol.MaxByteCount)
|
||||||
Expect(cf).To(HaveLen(1))
|
Expect(cf).To(HaveLen(1))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue