forked from quic-go/quic-go
add public header parser
This commit is contained in:
84
public_header.go
Normal file
84
public_header.go
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package quic
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
// The PublicHeader of a QUIC packet
|
||||||
|
type PublicHeader struct {
|
||||||
|
VersionFlag bool
|
||||||
|
ResetFlag bool
|
||||||
|
|
||||||
|
ConnectionIDLength uint8
|
||||||
|
ConnectionID uint64
|
||||||
|
|
||||||
|
QuicVersion uint32
|
||||||
|
|
||||||
|
PacketNumberLength uint8
|
||||||
|
PacketNumber uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParsePublicHeader parses a QUIC packet's public header
|
||||||
|
func ParsePublicHeader(b io.ByteReader) (*PublicHeader, error) {
|
||||||
|
header := &PublicHeader{}
|
||||||
|
|
||||||
|
// First byte
|
||||||
|
publicFlagByte, err := b.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
header.VersionFlag = publicFlagByte&0x01 > 0
|
||||||
|
header.ResetFlag = publicFlagByte&0x02 > 0
|
||||||
|
switch publicFlagByte & 0x0C {
|
||||||
|
case 0x0C:
|
||||||
|
header.ConnectionIDLength = 8
|
||||||
|
case 0x08:
|
||||||
|
header.ConnectionIDLength = 4
|
||||||
|
case 0x04:
|
||||||
|
header.ConnectionIDLength = 1
|
||||||
|
}
|
||||||
|
switch publicFlagByte & 0x30 {
|
||||||
|
case 0x30:
|
||||||
|
header.PacketNumberLength = 6
|
||||||
|
case 0x20:
|
||||||
|
header.PacketNumberLength = 4
|
||||||
|
case 0x10:
|
||||||
|
header.PacketNumberLength = 2
|
||||||
|
case 0x00:
|
||||||
|
header.PacketNumberLength = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection ID
|
||||||
|
header.ConnectionID, err = readUint64(b, header.ConnectionIDLength)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version (optional)
|
||||||
|
if header.VersionFlag {
|
||||||
|
var v uint64
|
||||||
|
v, err = readUint64(b, 4)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
header.QuicVersion = uint32(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packet number
|
||||||
|
header.PacketNumber, err = readUint64(b, header.PacketNumberLength)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return header, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readUint64(b io.ByteReader, length uint8) (uint64, error) {
|
||||||
|
var res uint64
|
||||||
|
for i := uint8(0); i < length; i++ {
|
||||||
|
bt, err := b.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
res = res<<8 + uint64(bt)
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
23
public_header_test.go
Normal file
23
public_header_test.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package quic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Public Header", func() {
|
||||||
|
It("parses intial client header", func() {
|
||||||
|
b := bytes.NewReader([]byte{0xd, 0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c, 0x51, 0x30, 0x33, 0x30, 0x1})
|
||||||
|
publicHeader, err := ParsePublicHeader(b)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(publicHeader.VersionFlag).To(BeTrue())
|
||||||
|
Expect(publicHeader.ResetFlag).To(BeFalse())
|
||||||
|
Expect(publicHeader.ConnectionIDLength).To(Equal(uint8(8)))
|
||||||
|
Expect(publicHeader.ConnectionID).ToNot(BeZero())
|
||||||
|
Expect(publicHeader.QuicVersion).To(Equal(uint32(0x51303330)))
|
||||||
|
Expect(publicHeader.PacketNumberLength).To(Equal(uint8(1)))
|
||||||
|
Expect(publicHeader.PacketNumber).To(Equal(uint64(1)))
|
||||||
|
})
|
||||||
|
})
|
||||||
13
quic_suite_test.go
Normal file
13
quic_suite_test.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package quic
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestQuicGo(t *testing.T) {
|
||||||
|
RegisterFailHandler(Fail)
|
||||||
|
RunSpecs(t, "QUIC Suite")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user