mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-01 19:17:36 +03:00
* build(deps): bump github.com/quic-go/quic-go from 0.40.1 to 0.42.0 Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.40.1 to 0.42.0. - [Release notes](https://github.com/quic-go/quic-go/releases) - [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md) - [Commits](https://github.com/quic-go/quic-go/compare/v0.40.1...v0.42.0) --- updated-dependencies: - dependency-name: github.com/quic-go/quic-go dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> * update: remove dependency of quic-go We now vendor the quicvarint submodule from quic-go for a minimal dependency tree. This also updates the minimal Go version requirement to Go 1.21, given uTLS promised to support 2 most recent minor versions of Go. Signed-off-by: Gaukas Wang <i@gaukas.wang> --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Gaukas Wang <i@gaukas.wang> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gaukas Wang <i@gaukas.wang>
146 lines
3.4 KiB
Go
146 lines
3.4 KiB
Go
// Copyright 2024 The quic-go Authors. All rights reserved.
|
|
// Use of this source code is governed by a MIT-style
|
|
// license that can be found in the LICENSE file of
|
|
// the quic-go repository.
|
|
|
|
package quicvarint
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/refraction-networking/utls/internal/quicvarint/protocol"
|
|
)
|
|
|
|
// taken from the QUIC draft
|
|
const (
|
|
// Min is the minimum value allowed for a QUIC varint.
|
|
Min = 0
|
|
|
|
// Max is the maximum allowed value for a QUIC varint (2^62-1).
|
|
Max = maxVarInt8
|
|
|
|
maxVarInt1 = 63
|
|
maxVarInt2 = 16383
|
|
maxVarInt4 = 1073741823
|
|
maxVarInt8 = 4611686018427387903
|
|
)
|
|
|
|
// Read reads a number in the QUIC varint format from r.
|
|
func Read(r io.ByteReader) (uint64, error) {
|
|
firstByte, err := r.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 := r.ReadByte()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if len == 2 {
|
|
return uint64(b2) + uint64(b1)<<8, nil
|
|
}
|
|
b3, err := r.ReadByte()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
b4, err := r.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 := r.ReadByte()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
b6, err := r.ReadByte()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
b7, err := r.ReadByte()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
b8, err := r.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
|
|
}
|
|
|
|
// Append appends i in the QUIC varint format.
|
|
func Append(b []byte, i uint64) []byte {
|
|
if i <= maxVarInt1 {
|
|
return append(b, uint8(i))
|
|
}
|
|
if i <= maxVarInt2 {
|
|
return append(b, []byte{uint8(i>>8) | 0x40, uint8(i)}...)
|
|
}
|
|
if i <= maxVarInt4 {
|
|
return append(b, []byte{uint8(i>>24) | 0x80, uint8(i >> 16), uint8(i >> 8), uint8(i)}...)
|
|
}
|
|
if i <= maxVarInt8 {
|
|
return append(b, []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),
|
|
}...)
|
|
}
|
|
panic(fmt.Sprintf("%#x doesn't fit into 62 bits", i))
|
|
}
|
|
|
|
// AppendWithLen append i in the QUIC varint format with the desired length.
|
|
func AppendWithLen(b []byte, i uint64, length protocol.ByteCount) []byte {
|
|
if length != 1 && length != 2 && length != 4 && length != 8 {
|
|
panic("invalid varint length")
|
|
}
|
|
l := Len(i)
|
|
if l == length {
|
|
return Append(b, i)
|
|
}
|
|
if l > length {
|
|
panic(fmt.Sprintf("cannot encode %d in %d bytes", i, length))
|
|
}
|
|
if length == 2 {
|
|
b = append(b, 0b01000000)
|
|
} else if length == 4 {
|
|
b = append(b, 0b10000000)
|
|
} else if length == 8 {
|
|
b = append(b, 0b11000000)
|
|
}
|
|
for j := protocol.ByteCount(1); j < length-l; j++ {
|
|
b = append(b, 0)
|
|
}
|
|
for j := protocol.ByteCount(0); j < l; j++ {
|
|
b = append(b, uint8(i>>(8*(l-1-j))))
|
|
}
|
|
return b
|
|
}
|
|
|
|
// Len determines the number of bytes that will be needed to write the number i.
|
|
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})
|
|
}
|