package relayprotoimport// errVarintEnd is returned when a buffer is too short to hold a varint.var errVarintEnd = errors.New("relayproto: unexpected end decoding varint")// QUIC variable-length integers per RFC 9000 §16: the two most-significant bits// of the first byte select a 1/2/4/8-byte length (prefixes 0b00/01/10/11).// varintLen returns the number of bytes needed to encode v as a QUIC varint.func varintLen( uint64) int {switch {case < 1<<6:return1case < 1<<14:return2case < 1<<30:return4case < 1<<62:return8default:panic("relayproto: varint too large") }}// appendVarint appends v to dst as a QUIC varint.func appendVarint( []byte, uint64) []byte {switchvarintLen() {case1:returnappend(, byte())case2:returnappend(, byte(>>8)|0x40, byte())case4:returnappend(,byte(>>24)|0x80, byte(>>16), byte(>>8), byte())default: // 8returnappend(,byte(>>56)|0xc0, byte(>>48), byte(>>40), byte(>>32),byte(>>24), byte(>>16), byte(>>8), byte()) }}// readVarint reads a QUIC varint from the front of buf, returning the value and// the remaining bytes.func readVarint( []byte) (uint64, []byte, error) {iflen() == 0 {return0, nil, errVarintEnd } := [0] >> 6 := 1 << // 1, 2, 4, or 8 bytesiflen() < {return0, nil, errVarintEnd } := uint64([0] & 0x3f)for := 1; < ; ++ { = <<8 | uint64([]) }return , [:], nil}// postcard uses LEB128 (unsigned little-endian base-128) varints for lengths and// integers, which is a different encoding from the QUIC varints above. The relay// datagram framing uses QUIC varints (for frame types); the handshake frame// bodies are postcard, so their length prefixes use these.// appendPostcardVarint appends v to dst as a postcard/LEB128 varint.func appendPostcardVarint( []byte, uint64) []byte {for >= 0x80 { = append(, byte()|0x80) >>= 7 }returnappend(, byte())}// readPostcardVarint reads a postcard/LEB128 varint from the front of buf.func readPostcardVarint( []byte) (uint64, []byte, error) {varuint64for := 0; < len(); ++ { := [] |= uint64(&0x7f) << (7 * )if < 0x80 {return , [+1:], nil }if >= 9 {break } }return0, nil, errVarintEnd}// EcnCodepoint is the QUIC explicit-congestion-notification codepoint carried in// a relayed datagram (RFC 9000 §13.4 / IP ECN field values).typeEcnCodepointuint8const (// EcnEct1 is ECT(1).EcnEct1EcnCodepoint = 1// EcnEct0 is ECT(0).EcnEct0EcnCodepoint = 2// EcnCe is CE (congestion experienced).EcnCeEcnCodepoint = 3)// ecnFromBits returns the EcnCodepoint for the low two bits of b, or (0, false)// for Not-ECT.func ecnFromBits( uint8) (EcnCodepoint, bool) {switch & 0b11 {case1:returnEcnEct1, truecase2:returnEcnEct0, truecase3:returnEcnCe, truedefault:return0, false }}
The pages are generated with Goldsv0.8.4. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.