2017-12-12 02:51:45 +00:00
package quic
import (
"bytes"
2018-01-03 19:19:49 +00:00
"math"
2017-12-12 02:51:45 +00:00
2018-01-20 18:07:01 +00:00
"github.com/golang/mock/gomock"
2017-12-12 02:51:45 +00:00
"github.com/lucas-clemente/quic-go/ackhandler"
2018-01-03 19:19:49 +00:00
"github.com/lucas-clemente/quic-go/internal/flowcontrol"
"github.com/lucas-clemente/quic-go/internal/handshake"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/wire"
2017-12-12 02:51:45 +00:00
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
2018-01-03 19:19:49 +00:00
type mockSealer struct { }
func ( s * mockSealer ) Seal ( dst , src [ ] byte , packetNumber protocol . PacketNumber , associatedData [ ] byte ) [ ] byte {
return append ( src , bytes . Repeat ( [ ] byte { 0 } , 12 ) ... )
}
func ( s * mockSealer ) Overhead ( ) int { return 12 }
var _ handshake . Sealer = & mockSealer { }
2017-12-12 02:51:45 +00:00
type mockCryptoSetup struct {
2018-01-03 19:19:49 +00:00
handleErr error
divNonce [ ] byte
encLevelSeal protocol . EncryptionLevel
encLevelSealCrypto protocol . EncryptionLevel
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
var _ handshake . CryptoSetup = & mockCryptoSetup { }
2017-12-12 02:51:45 +00:00
2018-01-03 19:19:49 +00:00
func ( m * mockCryptoSetup ) HandleCryptoStream ( ) error {
return m . handleErr
}
2017-12-12 02:51:45 +00:00
func ( m * mockCryptoSetup ) Open ( dst , src [ ] byte , packetNumber protocol . PacketNumber , associatedData [ ] byte ) ( [ ] byte , protocol . EncryptionLevel , error ) {
return nil , protocol . EncryptionUnspecified , nil
}
func ( m * mockCryptoSetup ) GetSealer ( ) ( protocol . EncryptionLevel , handshake . Sealer ) {
2018-01-03 19:19:49 +00:00
return m . encLevelSeal , & mockSealer { }
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
func ( m * mockCryptoSetup ) GetSealerForCryptoStream ( ) ( protocol . EncryptionLevel , handshake . Sealer ) {
return m . encLevelSealCrypto , & mockSealer { }
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
func ( m * mockCryptoSetup ) GetSealerWithEncryptionLevel ( protocol . EncryptionLevel ) ( handshake . Sealer , error ) {
return & mockSealer { } , nil
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
func ( m * mockCryptoSetup ) DiversificationNonce ( ) [ ] byte { return m . divNonce }
func ( m * mockCryptoSetup ) SetDiversificationNonce ( divNonce [ ] byte ) { m . divNonce = divNonce }
2018-01-20 18:07:01 +00:00
func ( m * mockCryptoSetup ) ConnectionState ( ) ConnectionState { panic ( "not implemented" ) }
2017-12-12 02:51:45 +00:00
var _ = Describe ( "Packet packer" , func ( ) {
var (
2018-01-20 18:07:01 +00:00
packer * packetPacker
publicHeaderLen protocol . ByteCount
maxFrameSize protocol . ByteCount
cryptoStream cryptoStreamI
mockStreamFramer * MockStreamFrameSource
2017-12-12 02:51:45 +00:00
)
BeforeEach ( func ( ) {
2018-01-03 19:19:49 +00:00
version := versionGQUICFrames
2018-01-20 18:07:01 +00:00
mockSender := NewMockStreamSender ( mockCtrl )
mockSender . EXPECT ( ) . onHasStreamData ( gomock . Any ( ) ) . AnyTimes ( )
cryptoStream = newCryptoStream ( mockSender , flowcontrol . NewStreamFlowController ( version . CryptoStreamID ( ) , false , flowcontrol . NewConnectionFlowController ( 1000 , 1000 , nil ) , 1000 , 1000 , 1000 , nil ) , version )
mockStreamFramer = NewMockStreamFrameSource ( mockCtrl )
packer = newPacketPacker (
0x1337 ,
1 ,
& mockCryptoSetup { encLevelSeal : protocol . EncryptionForwardSecure } ,
mockStreamFramer ,
protocol . PerspectiveServer ,
version ,
)
2017-12-12 02:51:45 +00:00
publicHeaderLen = 1 + 8 + 2 // 1 flag byte, 8 connection ID, 2 packet number
2018-01-03 19:19:49 +00:00
maxFrameSize = protocol . MaxPacketSize - protocol . ByteCount ( ( & mockSealer { } ) . Overhead ( ) ) - publicHeaderLen
packer . hasSentPacket = true
packer . version = version
2017-12-12 02:51:45 +00:00
} )
It ( "returns nil when no packet is queued" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) )
2018-01-03 19:19:49 +00:00
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( p ) . To ( BeNil ( ) )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
} )
It ( "packs single packets" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
2018-01-03 19:19:49 +00:00
f := & wire . StreamFrame {
2017-12-12 02:51:45 +00:00
StreamID : 5 ,
Data : [ ] byte { 0xDE , 0xCA , 0xFB , 0xAD } ,
}
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) ) . Return ( [ ] * wire . StreamFrame { f } )
2018-01-03 19:19:49 +00:00
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p ) . ToNot ( BeNil ( ) )
b := & bytes . Buffer { }
2018-01-03 19:19:49 +00:00
f . Write ( b , packer . version )
2018-01-20 18:07:01 +00:00
Expect ( p . frames ) . To ( Equal ( [ ] wire . Frame { f } ) )
2017-12-12 02:51:45 +00:00
Expect ( p . raw ) . To ( ContainSubstring ( string ( b . Bytes ( ) ) ) )
} )
It ( "stores the encryption level a packet was sealed with" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) ) . Return ( [ ] * wire . StreamFrame { {
2017-12-12 02:51:45 +00:00
StreamID : 5 ,
Data : [ ] byte ( "foobar" ) ,
2018-01-20 18:07:01 +00:00
} } )
packer . cryptoSetup . ( * mockCryptoSetup ) . encLevelSeal = protocol . EncryptionForwardSecure
2018-01-03 19:19:49 +00:00
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-03 19:19:49 +00:00
Expect ( p . encryptionLevel ) . To ( Equal ( protocol . EncryptionForwardSecure ) )
2017-12-12 02:51:45 +00:00
} )
2018-01-03 19:19:49 +00:00
Context ( "generating a packet header" , func ( ) {
const (
versionPublicHeader = protocol . Version39 // a QUIC version that uses the Public Header format
versionIETFHeader = protocol . VersionTLS // a QUIC version taht uses the IETF Header format
)
Context ( "Public Header (for gQUIC)" , func ( ) {
BeforeEach ( func ( ) {
packer . version = versionPublicHeader
} )
It ( "it omits the connection ID for forward-secure packets" , func ( ) {
ph := packer . getHeader ( protocol . EncryptionForwardSecure )
Expect ( ph . OmitConnectionID ) . To ( BeFalse ( ) )
packer . SetOmitConnectionID ( )
ph = packer . getHeader ( protocol . EncryptionForwardSecure )
Expect ( ph . OmitConnectionID ) . To ( BeTrue ( ) )
} )
It ( "doesn't omit the connection ID for non-forward-secure packets" , func ( ) {
packer . SetOmitConnectionID ( )
ph := packer . getHeader ( protocol . EncryptionSecure )
Expect ( ph . OmitConnectionID ) . To ( BeFalse ( ) )
} )
It ( "adds the Version Flag to the Public Header before the crypto handshake is finished" , func ( ) {
packer . perspective = protocol . PerspectiveClient
ph := packer . getHeader ( protocol . EncryptionSecure )
Expect ( ph . VersionFlag ) . To ( BeTrue ( ) )
} )
It ( "doesn't add the Version Flag to the Public Header for forward-secure packets" , func ( ) {
packer . perspective = protocol . PerspectiveClient
ph := packer . getHeader ( protocol . EncryptionForwardSecure )
Expect ( ph . VersionFlag ) . To ( BeFalse ( ) )
} )
Context ( "diversificaton nonces" , func ( ) {
var nonce [ ] byte
BeforeEach ( func ( ) {
nonce = bytes . Repeat ( [ ] byte { 'e' } , 32 )
packer . cryptoSetup . ( * mockCryptoSetup ) . divNonce = nonce
} )
It ( "doesn't include a div nonce, when sending a packet with initial encryption" , func ( ) {
ph := packer . getHeader ( protocol . EncryptionUnencrypted )
Expect ( ph . DiversificationNonce ) . To ( BeEmpty ( ) )
} )
It ( "includes a div nonce, when sending a packet with secure encryption" , func ( ) {
ph := packer . getHeader ( protocol . EncryptionSecure )
Expect ( ph . DiversificationNonce ) . To ( Equal ( nonce ) )
} )
It ( "doesn't include a div nonce, when sending a packet with forward-secure encryption" , func ( ) {
ph := packer . getHeader ( protocol . EncryptionForwardSecure )
Expect ( ph . DiversificationNonce ) . To ( BeEmpty ( ) )
} )
It ( "doesn't send a div nonce as a client" , func ( ) {
packer . perspective = protocol . PerspectiveClient
ph := packer . getHeader ( protocol . EncryptionSecure )
Expect ( ph . DiversificationNonce ) . To ( BeEmpty ( ) )
} )
} )
2017-12-12 02:51:45 +00:00
} )
2018-01-03 19:19:49 +00:00
Context ( "Header (for IETF draft QUIC)" , func ( ) {
BeforeEach ( func ( ) {
packer . version = versionIETFHeader
} )
It ( "uses the Long Header format for non-forward-secure packets" , func ( ) {
h := packer . getHeader ( protocol . EncryptionSecure )
Expect ( h . IsLongHeader ) . To ( BeTrue ( ) )
Expect ( h . PacketNumberLen ) . To ( Equal ( protocol . PacketNumberLen4 ) )
Expect ( h . Version ) . To ( Equal ( versionIETFHeader ) )
} )
It ( "uses the Short Header format for forward-secure packets" , func ( ) {
h := packer . getHeader ( protocol . EncryptionForwardSecure )
Expect ( h . IsLongHeader ) . To ( BeFalse ( ) )
Expect ( h . PacketNumberLen ) . To ( BeNumerically ( ">" , 0 ) )
} )
It ( "it omits the connection ID for forward-secure packets" , func ( ) {
h := packer . getHeader ( protocol . EncryptionForwardSecure )
Expect ( h . OmitConnectionID ) . To ( BeFalse ( ) )
packer . SetOmitConnectionID ( )
h = packer . getHeader ( protocol . EncryptionForwardSecure )
Expect ( h . OmitConnectionID ) . To ( BeTrue ( ) )
} )
It ( "doesn't omit the connection ID for non-forward-secure packets" , func ( ) {
packer . SetOmitConnectionID ( )
h := packer . getHeader ( protocol . EncryptionSecure )
Expect ( h . OmitConnectionID ) . To ( BeFalse ( ) )
} )
2017-12-12 02:51:45 +00:00
} )
} )
2018-01-20 18:07:01 +00:00
It ( "packs a CONNECTION_CLOSE" , func ( ) {
2018-01-03 19:19:49 +00:00
ccf := wire . ConnectionCloseFrame {
2017-12-12 02:51:45 +00:00
ErrorCode : 0x1337 ,
ReasonPhrase : "foobar" ,
}
2018-01-03 19:19:49 +00:00
p , err := packer . PackConnectionClose ( & ccf )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( HaveLen ( 1 ) )
Expect ( p . frames [ 0 ] ) . To ( Equal ( & ccf ) )
} )
2018-01-20 18:07:01 +00:00
It ( "doesn't send any other frames when sending a CONNECTION_CLOSE" , func ( ) {
// expect no mockStreamFramer.PopStreamFrames
ccf := & wire . ConnectionCloseFrame {
2017-12-12 02:51:45 +00:00
ErrorCode : 0x1337 ,
ReasonPhrase : "foobar" ,
}
2018-01-03 19:19:49 +00:00
packer . controlFrames = [ ] wire . Frame { & wire . MaxStreamDataFrame { StreamID : 37 } }
2018-01-20 18:07:01 +00:00
p , err := packer . PackConnectionClose ( ccf )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-20 18:07:01 +00:00
Expect ( p . frames ) . To ( Equal ( [ ] wire . Frame { ccf } ) )
2017-12-12 02:51:45 +00:00
} )
It ( "packs only control frames" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) )
2018-01-03 19:19:49 +00:00
packer . QueueControlFrame ( & wire . RstStreamFrame { } )
packer . QueueControlFrame ( & wire . MaxDataFrame { } )
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( p ) . ToNot ( BeNil ( ) )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( HaveLen ( 2 ) )
Expect ( p . raw ) . NotTo ( BeEmpty ( ) )
} )
It ( "increases the packet number" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( ) . Times ( 2 )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) ) . Times ( 2 )
2018-01-03 19:19:49 +00:00
packer . QueueControlFrame ( & wire . RstStreamFrame { } )
p1 , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p1 ) . ToNot ( BeNil ( ) )
2018-01-03 19:19:49 +00:00
packer . QueueControlFrame ( & wire . RstStreamFrame { } )
p2 , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p2 ) . ToNot ( BeNil ( ) )
2018-01-03 19:19:49 +00:00
Expect ( p2 . header . PacketNumber ) . To ( BeNumerically ( ">" , p1 . header . PacketNumber ) )
2017-12-12 02:51:45 +00:00
} )
2018-01-03 19:19:49 +00:00
It ( "packs a STOP_WAITING frame first" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) )
2017-12-12 02:51:45 +00:00
packer . packetNumberGenerator . next = 15
2018-01-03 19:19:49 +00:00
swf := & wire . StopWaitingFrame { LeastUnacked : 10 }
packer . QueueControlFrame ( & wire . RstStreamFrame { } )
packer . QueueControlFrame ( swf )
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p ) . ToNot ( BeNil ( ) )
Expect ( p . frames ) . To ( HaveLen ( 2 ) )
Expect ( p . frames [ 0 ] ) . To ( Equal ( swf ) )
} )
2018-01-03 19:19:49 +00:00
It ( "sets the LeastUnackedDelta length of a STOP_WAITING frame" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) )
2017-12-12 02:51:45 +00:00
packetNumber := protocol . PacketNumber ( 0xDECAFB ) // will result in a 4 byte packet number
packer . packetNumberGenerator . next = packetNumber
2018-01-03 19:19:49 +00:00
swf := & wire . StopWaitingFrame { LeastUnacked : packetNumber - 0x100 }
packer . QueueControlFrame ( & wire . RstStreamFrame { } )
packer . QueueControlFrame ( swf )
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-03 19:19:49 +00:00
Expect ( p . frames [ 0 ] . ( * wire . StopWaitingFrame ) . PacketNumberLen ) . To ( Equal ( protocol . PacketNumberLen4 ) )
2017-12-12 02:51:45 +00:00
} )
2018-01-03 19:19:49 +00:00
It ( "does not pack a packet containing only a STOP_WAITING frame" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) )
2018-01-03 19:19:49 +00:00
swf := & wire . StopWaitingFrame { LeastUnacked : 10 }
packer . QueueControlFrame ( swf )
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( p ) . To ( BeNil ( ) )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
} )
It ( "packs a packet if it has queued control frames, but no new control frames" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) )
2018-01-03 19:19:49 +00:00
packer . controlFrames = [ ] wire . Frame { & wire . BlockedFrame { } }
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p ) . ToNot ( BeNil ( ) )
} )
2018-01-03 19:19:49 +00:00
It ( "refuses to send a packet that doesn't contain crypto stream data, if it has never sent a packet before" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
2018-01-03 19:19:49 +00:00
packer . hasSentPacket = false
packer . controlFrames = [ ] wire . Frame { & wire . BlockedFrame { } }
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-03 19:19:49 +00:00
Expect ( p ) . To ( BeNil ( ) )
2017-12-12 02:51:45 +00:00
} )
It ( "packs many control frames into 1 packets" , func ( ) {
2018-01-03 19:19:49 +00:00
f := & wire . AckFrame { LargestAcked : 1 }
2017-12-12 02:51:45 +00:00
b := & bytes . Buffer { }
2018-01-03 19:19:49 +00:00
err := f . Write ( b , packer . version )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
maxFramesPerPacket := int ( maxFrameSize ) / b . Len ( )
var controlFrames [ ] wire . Frame
2017-12-12 02:51:45 +00:00
for i := 0 ; i < maxFramesPerPacket ; i ++ {
controlFrames = append ( controlFrames , f )
}
packer . controlFrames = controlFrames
2018-01-03 19:19:49 +00:00
payloadFrames , err := packer . composeNextPacket ( maxFrameSize , false )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( payloadFrames ) . To ( HaveLen ( maxFramesPerPacket ) )
2018-01-03 19:19:49 +00:00
payloadFrames , err = packer . composeNextPacket ( maxFrameSize , false )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( payloadFrames ) . To ( BeEmpty ( ) )
} )
It ( "packs a lot of control frames into 2 packets if they don't fit into one" , func ( ) {
2018-01-03 19:19:49 +00:00
blockedFrame := & wire . BlockedFrame { }
2018-01-20 18:07:01 +00:00
maxFramesPerPacket := int ( maxFrameSize ) / int ( blockedFrame . MinLength ( packer . version ) )
2018-01-03 19:19:49 +00:00
var controlFrames [ ] wire . Frame
2017-12-12 02:51:45 +00:00
for i := 0 ; i < maxFramesPerPacket + 10 ; i ++ {
controlFrames = append ( controlFrames , blockedFrame )
}
packer . controlFrames = controlFrames
2018-01-03 19:19:49 +00:00
payloadFrames , err := packer . composeNextPacket ( maxFrameSize , false )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( payloadFrames ) . To ( HaveLen ( maxFramesPerPacket ) )
2018-01-03 19:19:49 +00:00
payloadFrames , err = packer . composeNextPacket ( maxFrameSize , false )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( payloadFrames ) . To ( HaveLen ( 10 ) )
} )
It ( "only increases the packet number when there is an actual packet to send" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( ) . Times ( 2 )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) )
2017-12-12 02:51:45 +00:00
packer . packetNumberGenerator . nextToSkip = 1000
2018-01-03 19:19:49 +00:00
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( p ) . To ( BeNil ( ) )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( packer . packetNumberGenerator . Peek ( ) ) . To ( Equal ( protocol . PacketNumber ( 1 ) ) )
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) ) . Return ( [ ] * wire . StreamFrame { {
2017-12-12 02:51:45 +00:00
StreamID : 5 ,
Data : [ ] byte { 0xDE , 0xCA , 0xFB , 0xAD } ,
2018-01-20 18:07:01 +00:00
} } )
2018-01-03 19:19:49 +00:00
p , err = packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p ) . ToNot ( BeNil ( ) )
2018-01-03 19:19:49 +00:00
Expect ( p . header . PacketNumber ) . To ( Equal ( protocol . PacketNumber ( 1 ) ) )
2017-12-12 02:51:45 +00:00
Expect ( packer . packetNumberGenerator . Peek ( ) ) . To ( Equal ( protocol . PacketNumber ( 2 ) ) )
} )
2018-01-20 18:07:01 +00:00
It ( "adds a PING frame when it's supposed to send a retransmittable packet" , func ( ) {
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( ) . Times ( 2 )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) ) . Times ( 2 )
packer . QueueControlFrame ( & wire . AckFrame { } )
packer . QueueControlFrame ( & wire . StopWaitingFrame { } )
packer . MakeNextPacketRetransmittable ( )
p , err := packer . PackPacket ( )
Expect ( p ) . ToNot ( BeNil ( ) )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( HaveLen ( 3 ) )
Expect ( p . frames ) . To ( ContainElement ( & wire . PingFrame { } ) )
// make sure the next packet doesn't contain another PING
packer . QueueControlFrame ( & wire . AckFrame { } )
p , err = packer . PackPacket ( )
Expect ( p ) . ToNot ( BeNil ( ) )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( HaveLen ( 1 ) )
} )
It ( "waits until there's something to send before adding a PING frame" , func ( ) {
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( ) . Times ( 2 )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) ) . Times ( 2 )
packer . MakeNextPacketRetransmittable ( )
p , err := packer . PackPacket ( )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p ) . To ( BeNil ( ) )
packer . QueueControlFrame ( & wire . AckFrame { } )
p , err = packer . PackPacket ( )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( HaveLen ( 2 ) )
Expect ( p . frames ) . To ( ContainElement ( & wire . PingFrame { } ) )
} )
It ( "doesn't send a PING if it already sent another retransmittable frame" , func ( ) {
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( ) . Times ( 2 )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) ) . Times ( 2 )
packer . MakeNextPacketRetransmittable ( )
packer . QueueControlFrame ( & wire . MaxDataFrame { } )
p , err := packer . PackPacket ( )
Expect ( p ) . ToNot ( BeNil ( ) )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( HaveLen ( 1 ) )
packer . QueueControlFrame ( & wire . AckFrame { } )
p , err = packer . PackPacket ( )
Expect ( p ) . ToNot ( BeNil ( ) )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( HaveLen ( 1 ) )
} )
Context ( "STREAM frame handling" , func ( ) {
2018-01-03 19:19:49 +00:00
It ( "does not splits a STREAM frame with maximum size, for gQUIC frames" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( ) . Times ( 2 )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) ) . DoAndReturn ( func ( maxSize protocol . ByteCount ) [ ] * wire . StreamFrame {
f := & wire . StreamFrame {
Offset : 1 ,
StreamID : 5 ,
DataLenPresent : true ,
}
f . Data = bytes . Repeat ( [ ] byte { 'f' } , int ( maxSize - f . MinLength ( packer . version ) ) )
return [ ] * wire . StreamFrame { f }
} )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) )
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-20 18:07:01 +00:00
Expect ( p . frames ) . To ( HaveLen ( 1 ) )
Expect ( p . raw ) . To ( HaveLen ( int ( protocol . MaxPacketSize ) ) )
Expect ( p . frames [ 0 ] . ( * wire . StreamFrame ) . DataLenPresent ) . To ( BeFalse ( ) )
p , err = packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-20 18:07:01 +00:00
Expect ( p ) . To ( BeNil ( ) )
2017-12-12 02:51:45 +00:00
} )
2018-01-03 19:19:49 +00:00
It ( "does not splits a STREAM frame with maximum size, for IETF draft style frame" , func ( ) {
packer . version = versionIETFFrames
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( ) . Times ( 2 )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) ) . DoAndReturn ( func ( maxSize protocol . ByteCount ) [ ] * wire . StreamFrame {
f := & wire . StreamFrame {
Offset : 1 ,
StreamID : 5 ,
DataLenPresent : true ,
}
f . Data = bytes . Repeat ( [ ] byte { 'f' } , int ( maxSize - f . MinLength ( packer . version ) ) )
return [ ] * wire . StreamFrame { f }
} )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) )
2018-01-03 19:19:49 +00:00
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( HaveLen ( 1 ) )
2018-01-20 18:07:01 +00:00
Expect ( p . raw ) . To ( HaveLen ( int ( protocol . MaxPacketSize ) ) )
2018-01-03 19:19:49 +00:00
Expect ( p . frames [ 0 ] . ( * wire . StreamFrame ) . DataLenPresent ) . To ( BeFalse ( ) )
p , err = packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-20 18:07:01 +00:00
Expect ( p ) . To ( BeNil ( ) )
2017-12-12 02:51:45 +00:00
} )
2018-01-03 19:19:49 +00:00
It ( "packs multiple small STREAM frames into single packet" , func ( ) {
f1 := & wire . StreamFrame {
2018-01-20 18:07:01 +00:00
StreamID : 5 ,
Data : [ ] byte ( "frame 1" ) ,
DataLenPresent : true ,
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
f2 := & wire . StreamFrame {
2018-01-20 18:07:01 +00:00
StreamID : 5 ,
Data : [ ] byte ( "frame 2" ) ,
DataLenPresent : true ,
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
f3 := & wire . StreamFrame {
2018-01-20 18:07:01 +00:00
StreamID : 3 ,
Data : [ ] byte ( "frame 3" ) ,
DataLenPresent : true ,
2017-12-12 02:51:45 +00:00
}
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) ) . Return ( [ ] * wire . StreamFrame { f1 , f2 , f3 } )
2018-01-03 19:19:49 +00:00
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( p ) . ToNot ( BeNil ( ) )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( HaveLen ( 3 ) )
2018-01-20 18:07:01 +00:00
Expect ( p . frames [ 0 ] . ( * wire . StreamFrame ) . Data ) . To ( Equal ( [ ] byte ( "frame 1" ) ) )
Expect ( p . frames [ 1 ] . ( * wire . StreamFrame ) . Data ) . To ( Equal ( [ ] byte ( "frame 2" ) ) )
Expect ( p . frames [ 2 ] . ( * wire . StreamFrame ) . Data ) . To ( Equal ( [ ] byte ( "frame 3" ) ) )
2018-01-03 19:19:49 +00:00
Expect ( p . frames [ 0 ] . ( * wire . StreamFrame ) . DataLenPresent ) . To ( BeTrue ( ) )
Expect ( p . frames [ 1 ] . ( * wire . StreamFrame ) . DataLenPresent ) . To ( BeTrue ( ) )
Expect ( p . frames [ 2 ] . ( * wire . StreamFrame ) . DataLenPresent ) . To ( BeFalse ( ) )
2017-12-12 02:51:45 +00:00
} )
It ( "refuses to send unencrypted stream data on a data stream" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
// don't expect a call to mockStreamFramer.PopStreamFrames
2017-12-12 02:51:45 +00:00
packer . cryptoSetup . ( * mockCryptoSetup ) . encLevelSeal = protocol . EncryptionUnencrypted
2018-01-03 19:19:49 +00:00
p , err := packer . PackPacket ( )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
Expect ( p ) . To ( BeNil ( ) )
2017-12-12 02:51:45 +00:00
} )
2018-01-03 19:19:49 +00:00
It ( "sends non forward-secure data as the client" , func ( ) {
f := & wire . StreamFrame {
2017-12-12 02:51:45 +00:00
StreamID : 5 ,
Data : [ ] byte ( "foobar" ) ,
}
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) ) . Return ( [ ] * wire . StreamFrame { f } )
packer . perspective = protocol . PerspectiveClient
packer . cryptoSetup . ( * mockCryptoSetup ) . encLevelSeal = protocol . EncryptionSecure
2018-01-03 19:19:49 +00:00
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . encryptionLevel ) . To ( Equal ( protocol . EncryptionSecure ) )
2018-01-20 18:07:01 +00:00
Expect ( p . frames ) . To ( Equal ( [ ] wire . Frame { f } ) )
2017-12-12 02:51:45 +00:00
} )
2018-01-03 19:19:49 +00:00
It ( "does not send non forward-secure data as the server" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
// don't expect a call to mockStreamFramer.PopStreamFrames
2018-01-03 19:19:49 +00:00
packer . cryptoSetup . ( * mockCryptoSetup ) . encLevelSeal = protocol . EncryptionSecure
p , err := packer . PackPacket ( )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p ) . To ( BeNil ( ) )
} )
It ( "sends unencrypted stream data on the crypto stream" , func ( ) {
2018-01-20 18:07:01 +00:00
f := & wire . StreamFrame {
StreamID : packer . version . CryptoStreamID ( ) ,
Data : [ ] byte ( "foobar" ) ,
}
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( ) . Return ( true )
mockStreamFramer . EXPECT ( ) . PopCryptoStreamFrame ( gomock . Any ( ) ) . Return ( f )
2018-01-03 19:19:49 +00:00
packer . cryptoSetup . ( * mockCryptoSetup ) . encLevelSealCrypto = protocol . EncryptionUnencrypted
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-20 18:07:01 +00:00
Expect ( p . frames ) . To ( Equal ( [ ] wire . Frame { f } ) )
2017-12-12 02:51:45 +00:00
Expect ( p . encryptionLevel ) . To ( Equal ( protocol . EncryptionUnencrypted ) )
} )
It ( "sends encrypted stream data on the crypto stream" , func ( ) {
2018-01-20 18:07:01 +00:00
f := & wire . StreamFrame {
StreamID : packer . version . CryptoStreamID ( ) ,
Data : [ ] byte ( "foobar" ) ,
}
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( ) . Return ( true )
mockStreamFramer . EXPECT ( ) . PopCryptoStreamFrame ( gomock . Any ( ) ) . Return ( f )
2018-01-03 19:19:49 +00:00
packer . cryptoSetup . ( * mockCryptoSetup ) . encLevelSealCrypto = protocol . EncryptionSecure
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-20 18:07:01 +00:00
Expect ( p . frames ) . To ( Equal ( [ ] wire . Frame { f } ) )
2017-12-12 02:51:45 +00:00
Expect ( p . encryptionLevel ) . To ( Equal ( protocol . EncryptionSecure ) )
2018-01-03 19:19:49 +00:00
} )
2018-01-20 18:07:01 +00:00
It ( "does not pack STREAM frames if not allowed" , func ( ) {
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
// don't expect a call to mockStreamFramer.PopStreamFrames
2018-01-03 19:19:49 +00:00
packer . cryptoSetup . ( * mockCryptoSetup ) . encLevelSeal = protocol . EncryptionUnencrypted
2018-01-20 18:07:01 +00:00
ack := & wire . AckFrame { LargestAcked : 10 }
packer . QueueControlFrame ( ack )
2018-01-03 19:19:49 +00:00
p , err := packer . PackPacket ( )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-20 18:07:01 +00:00
Expect ( p . frames ) . To ( Equal ( [ ] wire . Frame { ack } ) )
2017-12-12 02:51:45 +00:00
} )
} )
It ( "packs a single ACK" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) )
2018-01-03 19:19:49 +00:00
ack := & wire . AckFrame { LargestAcked : 42 }
packer . QueueControlFrame ( ack )
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) )
Expect ( p ) . ToNot ( BeNil ( ) )
Expect ( p . frames [ 0 ] ) . To ( Equal ( ack ) )
} )
It ( "does not return nil if we only have a single ACK but request it to be sent" , func ( ) {
2018-01-20 18:07:01 +00:00
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( )
mockStreamFramer . EXPECT ( ) . PopStreamFrames ( gomock . Any ( ) )
2018-01-03 19:19:49 +00:00
ack := & wire . AckFrame { }
packer . QueueControlFrame ( ack )
p , err := packer . PackPacket ( )
2017-12-12 02:51:45 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) )
Expect ( p ) . ToNot ( BeNil ( ) )
} )
Context ( "retransmitting of handshake packets" , func ( ) {
2018-01-03 19:19:49 +00:00
swf := & wire . StopWaitingFrame { LeastUnacked : 1 }
sf := & wire . StreamFrame {
2017-12-12 02:51:45 +00:00
StreamID : 1 ,
Data : [ ] byte ( "foobar" ) ,
}
2018-01-03 19:19:49 +00:00
BeforeEach ( func ( ) {
packer . QueueControlFrame ( swf )
} )
2017-12-12 02:51:45 +00:00
It ( "packs a retransmission for a packet sent with no encryption" , func ( ) {
packet := & ackhandler . Packet {
EncryptionLevel : protocol . EncryptionUnencrypted ,
2018-01-03 19:19:49 +00:00
Frames : [ ] wire . Frame { sf } ,
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
p , err := packer . PackHandshakeRetransmission ( packet )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-20 18:07:01 +00:00
Expect ( p . frames ) . To ( Equal ( [ ] wire . Frame { swf , sf } ) )
Expect ( p . encryptionLevel ) . To ( Equal ( protocol . EncryptionUnencrypted ) )
} )
It ( "doesn't add a STOP_WAITING frame for IETF QUIC" , func ( ) {
packer . version = versionIETFFrames
packet := & ackhandler . Packet {
EncryptionLevel : protocol . EncryptionUnencrypted ,
Frames : [ ] wire . Frame { sf } ,
}
p , err := packer . PackHandshakeRetransmission ( packet )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( Equal ( [ ] wire . Frame { sf } ) )
2017-12-12 02:51:45 +00:00
Expect ( p . encryptionLevel ) . To ( Equal ( protocol . EncryptionUnencrypted ) )
} )
It ( "packs a retransmission for a packet sent with initial encryption" , func ( ) {
nonce := bytes . Repeat ( [ ] byte { 'e' } , 32 )
packer . cryptoSetup . ( * mockCryptoSetup ) . divNonce = nonce
packet := & ackhandler . Packet {
EncryptionLevel : protocol . EncryptionSecure ,
2018-01-03 19:19:49 +00:00
Frames : [ ] wire . Frame { sf } ,
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
p , err := packer . PackHandshakeRetransmission ( packet )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
2018-01-20 18:07:01 +00:00
Expect ( p . frames ) . To ( Equal ( [ ] wire . Frame { swf , sf } ) )
2017-12-12 02:51:45 +00:00
Expect ( p . encryptionLevel ) . To ( Equal ( protocol . EncryptionSecure ) )
// a packet sent by the server with initial encryption contains the SHLO
// it needs to have a diversification nonce
Expect ( p . raw ) . To ( ContainSubstring ( string ( nonce ) ) )
} )
It ( "includes the diversification nonce on packets sent with initial encryption" , func ( ) {
packet := & ackhandler . Packet {
EncryptionLevel : protocol . EncryptionSecure ,
2018-01-03 19:19:49 +00:00
Frames : [ ] wire . Frame { sf } ,
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
p , err := packer . PackHandshakeRetransmission ( packet )
2017-12-12 02:51:45 +00:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( p . encryptionLevel ) . To ( Equal ( protocol . EncryptionSecure ) )
} )
// this should never happen, since non forward-secure packets are limited to a size smaller than MaxPacketSize, such that it is always possible to retransmit them without splitting the StreamFrame
// (note that the retransmitted packet needs to have enough space for the StopWaitingFrame)
It ( "refuses to send a packet larger than MaxPacketSize" , func ( ) {
packet := & ackhandler . Packet {
EncryptionLevel : protocol . EncryptionSecure ,
2018-01-03 19:19:49 +00:00
Frames : [ ] wire . Frame {
& wire . StreamFrame {
2017-12-12 02:51:45 +00:00
StreamID : 1 ,
Data : bytes . Repeat ( [ ] byte { 'f' } , int ( protocol . MaxPacketSize - 5 ) ) ,
} ,
} ,
}
2018-01-03 19:19:49 +00:00
_ , err := packer . PackHandshakeRetransmission ( packet )
2017-12-12 02:51:45 +00:00
Expect ( err ) . To ( MatchError ( "PacketPacker BUG: packet too large" ) )
} )
2018-01-03 19:19:49 +00:00
It ( "pads Initial packets to the required minimum packet size" , func ( ) {
2018-01-20 18:07:01 +00:00
f := & wire . StreamFrame {
StreamID : packer . version . CryptoStreamID ( ) ,
Data : [ ] byte ( "foobar" ) ,
}
mockStreamFramer . EXPECT ( ) . HasCryptoStreamData ( ) . Return ( true )
mockStreamFramer . EXPECT ( ) . PopCryptoStreamFrame ( gomock . Any ( ) ) . Return ( f )
2018-01-03 19:19:49 +00:00
packer . version = protocol . VersionTLS
packer . hasSentPacket = false
packer . perspective = protocol . PerspectiveClient
packer . cryptoSetup . ( * mockCryptoSetup ) . encLevelSealCrypto = protocol . EncryptionUnencrypted
packet , err := packer . PackPacket ( )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
Expect ( packet . raw ) . To ( HaveLen ( protocol . MinInitialPacketSize ) )
Expect ( packet . frames ) . To ( HaveLen ( 1 ) )
sf := packet . frames [ 0 ] . ( * wire . StreamFrame )
Expect ( sf . Data ) . To ( Equal ( [ ] byte ( "foobar" ) ) )
Expect ( sf . DataLenPresent ) . To ( BeTrue ( ) )
} )
2017-12-12 02:51:45 +00:00
It ( "refuses to retransmit packets that were sent with forward-secure encryption" , func ( ) {
p := & ackhandler . Packet {
EncryptionLevel : protocol . EncryptionForwardSecure ,
}
2018-01-03 19:19:49 +00:00
_ , err := packer . PackHandshakeRetransmission ( p )
2017-12-12 02:51:45 +00:00
Expect ( err ) . To ( MatchError ( "PacketPacker BUG: forward-secure encrypted handshake packets don't need special treatment" ) )
} )
2018-01-03 19:19:49 +00:00
It ( "refuses to retransmit packets without a STOP_WAITING Frame" , func ( ) {
packer . stopWaiting = nil
_ , err := packer . PackHandshakeRetransmission ( & ackhandler . Packet {
2017-12-12 02:51:45 +00:00
EncryptionLevel : protocol . EncryptionSecure ,
2018-01-03 19:19:49 +00:00
} )
2018-01-20 18:07:01 +00:00
Expect ( err ) . To ( MatchError ( "PacketPacker BUG: Handshake retransmissions must contain a STOP_WAITING frame" ) )
2017-12-12 02:51:45 +00:00
} )
} )
2018-01-03 19:19:49 +00:00
Context ( "packing ACK packets" , func ( ) {
It ( "packs ACK packets" , func ( ) {
packer . QueueControlFrame ( & wire . AckFrame { } )
p , err := packer . PackAckPacket ( )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( Equal ( [ ] wire . Frame { & wire . AckFrame { DelayTime : math . MaxInt64 } } ) )
} )
2018-01-20 18:07:01 +00:00
It ( "packs ACK packets with STOP_WAITING frames" , func ( ) {
2018-01-03 19:19:49 +00:00
packer . QueueControlFrame ( & wire . AckFrame { } )
packer . QueueControlFrame ( & wire . StopWaitingFrame { } )
p , err := packer . PackAckPacket ( )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
Expect ( p . frames ) . To ( Equal ( [ ] wire . Frame {
& wire . AckFrame { DelayTime : math . MaxInt64 } ,
& wire . StopWaitingFrame { PacketNumber : 1 , PacketNumberLen : 2 } ,
} ) )
} )
} )
2017-12-12 02:51:45 +00:00
} )