mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-28 12:39:58 +00:00
TUN-4597: Add a QUIC server skeleton
- Added a QUIC server to accept streams - Unit test for this server also tests ALPN - Temporary echo capability for HTTP ConnectionType
This commit is contained in:
134
vendor/github.com/lucas-clemente/quic-go/quicvarint/varint.go
generated
vendored
Normal file
134
vendor/github.com/lucas-clemente/quic-go/quicvarint/varint.go
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
package quicvarint
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
)
|
||||
|
||||
// taken from the QUIC draft
|
||||
const (
|
||||
maxVarInt1 = 63
|
||||
maxVarInt2 = 16383
|
||||
maxVarInt4 = 1073741823
|
||||
maxVarInt8 = 4611686018427387903
|
||||
)
|
||||
|
||||
// Read reads a number in the QUIC varint format
|
||||
func Read(b io.ByteReader) (uint64, error) {
|
||||
firstByte, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// the first two bits of the first byte encode the length
|
||||
len := 1 << ((firstByte & 0xc0) >> 6)
|
||||
b1 := firstByte & (0xff - 0xc0)
|
||||
if len == 1 {
|
||||
return uint64(b1), nil
|
||||
}
|
||||
b2, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len == 2 {
|
||||
return uint64(b2) + uint64(b1)<<8, nil
|
||||
}
|
||||
b3, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
b4, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len == 4 {
|
||||
return uint64(b4) + uint64(b3)<<8 + uint64(b2)<<16 + uint64(b1)<<24, nil
|
||||
}
|
||||
b5, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
b6, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
b7, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
b8, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint64(b8) + uint64(b7)<<8 + uint64(b6)<<16 + uint64(b5)<<24 + uint64(b4)<<32 + uint64(b3)<<40 + uint64(b2)<<48 + uint64(b1)<<56, nil
|
||||
}
|
||||
|
||||
// Write writes a number in the QUIC varint format
|
||||
func Write(b *bytes.Buffer, i uint64) {
|
||||
if i <= maxVarInt1 {
|
||||
b.WriteByte(uint8(i))
|
||||
} else if i <= maxVarInt2 {
|
||||
b.Write([]byte{uint8(i>>8) | 0x40, uint8(i)})
|
||||
} else if i <= maxVarInt4 {
|
||||
b.Write([]byte{uint8(i>>24) | 0x80, uint8(i >> 16), uint8(i >> 8), uint8(i)})
|
||||
} else if i <= maxVarInt8 {
|
||||
b.Write([]byte{
|
||||
uint8(i>>56) | 0xc0, uint8(i >> 48), uint8(i >> 40), uint8(i >> 32),
|
||||
uint8(i >> 24), uint8(i >> 16), uint8(i >> 8), uint8(i),
|
||||
})
|
||||
} else {
|
||||
panic(fmt.Sprintf("%#x doesn't fit into 62 bits", i))
|
||||
}
|
||||
}
|
||||
|
||||
// WriteWithLen writes a number in the QUIC varint format, with the desired length.
|
||||
func WriteWithLen(b *bytes.Buffer, i uint64, length protocol.ByteCount) {
|
||||
if length != 1 && length != 2 && length != 4 && length != 8 {
|
||||
panic("invalid varint length")
|
||||
}
|
||||
l := Len(i)
|
||||
if l == length {
|
||||
Write(b, i)
|
||||
return
|
||||
}
|
||||
if l > length {
|
||||
panic(fmt.Sprintf("cannot encode %d in %d bytes", i, length))
|
||||
}
|
||||
if length == 2 {
|
||||
b.WriteByte(0b01000000)
|
||||
} else if length == 4 {
|
||||
b.WriteByte(0b10000000)
|
||||
} else if length == 8 {
|
||||
b.WriteByte(0b11000000)
|
||||
}
|
||||
for j := protocol.ByteCount(1); j < length-l; j++ {
|
||||
b.WriteByte(0)
|
||||
}
|
||||
for j := protocol.ByteCount(0); j < l; j++ {
|
||||
b.WriteByte(uint8(i >> (8 * (l - 1 - j))))
|
||||
}
|
||||
}
|
||||
|
||||
// Len determines the number of bytes that will be needed to write a number
|
||||
func Len(i uint64) protocol.ByteCount {
|
||||
if i <= maxVarInt1 {
|
||||
return 1
|
||||
}
|
||||
if i <= maxVarInt2 {
|
||||
return 2
|
||||
}
|
||||
if i <= maxVarInt4 {
|
||||
return 4
|
||||
}
|
||||
if i <= maxVarInt8 {
|
||||
return 8
|
||||
}
|
||||
// Don't use a fmt.Sprintf here to format the error message.
|
||||
// The function would then exceed the inlining budget.
|
||||
panic(struct {
|
||||
message string
|
||||
num uint64
|
||||
}{"value doesn't fit into 62 bits: ", i})
|
||||
}
|
Reference in New Issue
Block a user