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
|
||||
}
|
||||
Reference in New Issue
Block a user