mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
wip: InitialSpec (2/n)
- Added QUICFrame to describe QUIC Frame found in an Initial Packet, including PADDING, PING, and CRYPTO. - Added QUICSpec to describe the QUIC Header and QUIC Frames' order/length/offset.
This commit is contained in:
parent
20e2a487b8
commit
95f3eaaa66
4 changed files with 332 additions and 8 deletions
7
go.mod
7
go.mod
|
@ -6,12 +6,12 @@ replace github.com/refraction-networking/utls => ../utls
|
|||
|
||||
require (
|
||||
github.com/francoispqt/gojay v1.2.13
|
||||
github.com/gaukas/clienthellod v0.4.0
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/onsi/ginkgo/v2 v2.9.5
|
||||
github.com/onsi/gomega v1.27.6
|
||||
github.com/quic-go/qpack v0.4.0
|
||||
github.com/quic-go/qtls-go1-20 v0.3.0
|
||||
github.com/refraction-networking/utls v0.0.0-00010101000000-000000000000
|
||||
github.com/refraction-networking/utls v1.3.2
|
||||
golang.org/x/crypto v0.10.0
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db
|
||||
golang.org/x/net v0.11.0
|
||||
|
@ -21,10 +21,11 @@ require (
|
|||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/gaukas/godicttls v0.0.3 // indirect
|
||||
github.com/gaukas/godicttls v0.0.4 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/gopacket v1.1.19 // indirect
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
||||
github.com/klauspost/compress v1.16.6 // indirect
|
||||
golang.org/x/mod v0.10.0 // indirect
|
||||
|
|
15
go.sum
15
go.sum
|
@ -27,8 +27,10 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI
|
|||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gaukas/godicttls v0.0.3 h1:YNDIf0d9adcxOijiLrEzpfZGAkNwLRzPaG6OjU7EITk=
|
||||
github.com/gaukas/godicttls v0.0.3/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
|
||||
github.com/gaukas/clienthellod v0.4.0 h1:DySeZT4c3Xw6OGMzHRlAuOHx9q1P7vQNjA7YkyHrqac=
|
||||
github.com/gaukas/clienthellod v0.4.0/go.mod h1:gjt7a7cNNzZV4yTe0jKcXtj0a7u6RL2KQvijxFOvcZE=
|
||||
github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
|
||||
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
|
@ -52,6 +54,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
|||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
|
@ -96,8 +100,6 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q
|
|||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.0 h1:NrCXmDl8BddZwO67vlvEpBTwT89bJfKYygxv4HQvuDk=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.0/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||
|
@ -147,6 +149,8 @@ golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZ
|
|||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
||||
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
|
@ -202,6 +206,7 @@ golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
|
||||
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||
|
@ -224,7 +229,7 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE
|
|||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
200
u_quic_spec.go
Normal file
200
u_quic_spec.go
Normal file
|
@ -0,0 +1,200 @@
|
|||
package quic
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
|
||||
"github.com/gaukas/clienthellod"
|
||||
"github.com/quic-go/quic-go/quicvarint"
|
||||
)
|
||||
|
||||
type QUICSpec struct {
|
||||
// SrcConnIDLength specifies how many bytes should the SrcConnID be
|
||||
SrcConnIDLength int
|
||||
|
||||
// DestConnIDLength specifies how many bytes should the DestConnID be
|
||||
DstConnIDLength int
|
||||
|
||||
// InitPacketNumberLength specifies how many bytes should the InitPacketNumber
|
||||
// be interpreted as. It is usually 1 or 2 bytes. If unset, UQUIC will use the
|
||||
// default algorithm to compute the length which is at least 2 bytes.
|
||||
InitPacketNumberLength PacketNumberLen
|
||||
|
||||
// InitPacketNumber is the packet number of the first Initial packet. Following
|
||||
// Initial packets, if any, will increment the Packet Number accordingly.
|
||||
InitPacketNumber uint64 // [UQUIC]
|
||||
|
||||
// TokenStore is used to store and retrieve tokens. If set, will override the
|
||||
// one set in the Config.
|
||||
TokenStore TokenStore
|
||||
|
||||
// If ClientTokenLength is set when TokenStore is not set, a dummy TokenStore
|
||||
// will be created to randomly generate tokens of the specified length for
|
||||
// Pop() calls with any key and silently drop any Put() calls.
|
||||
//
|
||||
// However, the tokens will not be stored anywhere and are expected to be
|
||||
// invalid since not assigned by the server.
|
||||
ClientTokenLength int
|
||||
|
||||
// QUICFrames specifies a list of QUIC frames to be sent in the first Initial
|
||||
// packet.
|
||||
//
|
||||
// If nil, it will be treated as a list with only a single QUICFrameCrypto.
|
||||
QUICFrames []QUICFrame
|
||||
}
|
||||
|
||||
func (s *QUICSpec) getTokenStore() TokenStore {
|
||||
if s.TokenStore != nil {
|
||||
return s.TokenStore
|
||||
}
|
||||
|
||||
if s.ClientTokenLength > 0 {
|
||||
return &dummyTokenStore{
|
||||
tokenLength: s.ClientTokenLength,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type dummyTokenStore struct {
|
||||
tokenLength int
|
||||
}
|
||||
|
||||
func (d *dummyTokenStore) Pop(key string) (token *ClientToken) {
|
||||
var data []byte = make([]byte, d.tokenLength)
|
||||
rand.Read(data)
|
||||
|
||||
return &ClientToken{
|
||||
data: data,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *dummyTokenStore) Put(_ string, _ *ClientToken) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
type QUICFrames []QUICFrame
|
||||
|
||||
func (qfs QUICFrames) MarshalWithCryptoData(cryptoData []byte) (payload []byte, err error) {
|
||||
if len(qfs) == 0 { // If no frames specified, send a single crypto frame
|
||||
payload = make([]byte, len(cryptoData)+1)
|
||||
}
|
||||
|
||||
for _, frame := range qfs {
|
||||
var frameBytes []byte
|
||||
if offset, length, cryptoOK := frame.CryptoFrameInfo(); cryptoOK {
|
||||
if length == 0 {
|
||||
// calculate length: from offset to the end of cryptoData
|
||||
length = len(cryptoData) - offset
|
||||
}
|
||||
frameBytes = []byte{0x06} // CRYPTO frame type
|
||||
frameBytes = quicvarint.Append(frameBytes, uint64(offset))
|
||||
frameBytes = quicvarint.Append(frameBytes, uint64(length))
|
||||
frameCryptoData := make([]byte, length)
|
||||
copy(frameCryptoData, cryptoData[offset:]) // copy at most length bytes
|
||||
frameBytes = append(frameBytes, frameCryptoData...)
|
||||
} else { // Handle none crypto frames: read and append to payload
|
||||
frameBytes, err = frame.Read()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
payload = append(payload, frameBytes...)
|
||||
}
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
func (qfs QUICFrames) MarshalWithFrames(frames []byte) (payload []byte, err error) {
|
||||
// parse frames
|
||||
r := bytes.NewReader(frames)
|
||||
qchframes, err := clienthellod.ReadAllFrames(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// parse crypto data
|
||||
cryptoData, err := clienthellod.ReassembleCRYPTOFrames(qchframes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// marshal
|
||||
return qfs.MarshalWithCryptoData(cryptoData)
|
||||
}
|
||||
|
||||
type QUICFrame interface {
|
||||
// None crypto frames should return false for cryptoOK
|
||||
CryptoFrameInfo() (offset, length int, cryptoOK bool)
|
||||
|
||||
// None crypto frames should return the byte representation of the frame.
|
||||
// Crypto frames' behavior is undefined and unused.
|
||||
Read() ([]byte, error)
|
||||
}
|
||||
|
||||
// QUICFrameCrypto is used to specify the crypto frames containing the TLS ClientHello
|
||||
// to be sent in the first Initial packet.
|
||||
type QUICFrameCrypto struct {
|
||||
// Offset is used to specify the starting offset of the crypto frame.
|
||||
// Used when sending multiple crypto frames in a single packet.
|
||||
//
|
||||
// Multiple crypto frames in a single packet must not overlap and must
|
||||
// make up an entire crypto stream continuously.
|
||||
Offset int
|
||||
|
||||
// Length is used to specify the length of the crypto frame.
|
||||
//
|
||||
// Must be set if it is NOT the last crypto frame in a packet.
|
||||
Length int
|
||||
}
|
||||
|
||||
// CryptoFrameInfo() implements the QUICFrame interface.
|
||||
//
|
||||
// Crypto frames are later replaced by the crypto message using the information
|
||||
// returned by this function.
|
||||
func (q QUICFrameCrypto) CryptoFrameInfo() (offset, length int, cryptoOK bool) {
|
||||
return q.Offset, q.Length, true
|
||||
}
|
||||
|
||||
// Read() implements the QUICFrame interface.
|
||||
//
|
||||
// Crypto frames are later replaced by the crypto message, so they are not Read()-able.
|
||||
func (q QUICFrameCrypto) Read() ([]byte, error) {
|
||||
return nil, errors.New("crypto frames are not Read()-able")
|
||||
}
|
||||
|
||||
// QUICFramePadding is used to specify the padding frames to be sent in the first Initial
|
||||
// packet.
|
||||
type QUICFramePadding struct {
|
||||
// Length is used to specify the length of the padding frame.
|
||||
Length int
|
||||
}
|
||||
|
||||
// CryptoFrameInfo() implements the QUICFrame interface.
|
||||
func (q QUICFramePadding) CryptoFrameInfo() (offset, length int, cryptoOK bool) {
|
||||
return 0, 0, false
|
||||
}
|
||||
|
||||
// Read() implements the QUICFrame interface.
|
||||
//
|
||||
// Padding simply returns a slice of bytes of the specified length filled with 0.
|
||||
func (q QUICFramePadding) Read() ([]byte, error) {
|
||||
return make([]byte, q.Length), nil
|
||||
}
|
||||
|
||||
// QUICFramePing is used to specify the ping frames to be sent in the first Initial
|
||||
// packet.
|
||||
type QUICFramePing struct{}
|
||||
|
||||
// CryptoFrameInfo() implements the QUICFrame interface.
|
||||
func (q QUICFramePing) CryptoFrameInfo() (offset, length int, cryptoOK bool) {
|
||||
return 0, 0, false
|
||||
}
|
||||
|
||||
// Read() implements the QUICFrame interface.
|
||||
//
|
||||
// Ping simply returns a slice of bytes of size 1 with value 0x01(PING).
|
||||
func (q QUICFramePing) Read() ([]byte, error) {
|
||||
return []byte{0x01}, nil
|
||||
}
|
118
u_quic_spec_test.go
Normal file
118
u_quic_spec_test.go
Normal file
|
@ -0,0 +1,118 @@
|
|||
package quic
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/gaukas/clienthellod"
|
||||
)
|
||||
|
||||
func TestQUICFramesMarshalWithCryptoData(t *testing.T) {
|
||||
resultQUICPayload, err := testQUICFrames.MarshalWithCryptoData(testCryptoFrameBytes)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to marshal QUIC frames: %v", err)
|
||||
}
|
||||
|
||||
if len(resultQUICPayload) != len(truthQUICPayload) {
|
||||
t.Fatalf("QUIC payload length mismatch: got %d, want %d. \n%x", len(resultQUICPayload), len(truthQUICPayload), resultQUICPayload)
|
||||
}
|
||||
|
||||
// verify that the crypto frames would actually assemble the original crypto data
|
||||
r := bytes.NewReader(resultQUICPayload)
|
||||
qchframes, err := clienthellod.ReadAllFrames(r)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read QUIC frames: %v", err)
|
||||
}
|
||||
|
||||
reassembledCryptoData, err := clienthellod.ReassembleCRYPTOFrames(qchframes)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to reassemble crypto data: %v", err)
|
||||
}
|
||||
if !bytes.Equal(reassembledCryptoData, testCryptoFrameBytes) {
|
||||
t.Fatalf("Reassembled crypto data mismatch: \n%x", reassembledCryptoData)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
testCryptoFrameBytes = []byte{
|
||||
0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13,
|
||||
0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b,
|
||||
0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23,
|
||||
0x24, 0x25, 0x26, 0x27,
|
||||
0x28, 0x29, 0x2a, 0x2b,
|
||||
0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33,
|
||||
0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x3a, 0x3b,
|
||||
0x3c, 0x3d, 0x3e, 0x3f,
|
||||
} // 64 bytes
|
||||
|
||||
testQUICFrames = QUICFrames{
|
||||
// first 64 bytes: 01 + 63 bytes of padding
|
||||
&QUICFramePing{},
|
||||
&QUICFramePadding{Length: 63},
|
||||
// second 64 bytes: last 32 bytes of crypto frame + 29 bytes of padding
|
||||
&QUICFrameCrypto{
|
||||
Offset: 32,
|
||||
Length: 0,
|
||||
},
|
||||
&QUICFramePadding{Length: 29},
|
||||
// third 64 bytes: first 16 bytes of crypto frame + 45 bytes of padding
|
||||
&QUICFrameCrypto{
|
||||
Offset: 0,
|
||||
Length: 16,
|
||||
},
|
||||
&QUICFramePadding{Length: 45},
|
||||
// fourth 64 bytes: second 16 bytes of crypto frame + 45 bytes of padding
|
||||
&QUICFrameCrypto{
|
||||
Offset: 16,
|
||||
Length: 16,
|
||||
},
|
||||
&QUICFramePadding{Length: 45},
|
||||
}
|
||||
|
||||
truthQUICPayload = []byte{
|
||||
0x01, // ping
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 63 bytes of padding
|
||||
0x06, 0x20, 0x20, // 3 bytes header
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // 32 bytes of crypto frame
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, // 29 bytes of padding
|
||||
0x06, 0x00, 0x10, // 3 bytes header
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // 16 bytes of crypto frame
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, // 45 bytes of padding
|
||||
0x06, 0x10, 0x10, // 3 bytes header
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, // 16 bytes of crypto frame
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, // 45 bytes of padding
|
||||
}
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue