func (s *packetNumberSpace) encryptPacket(b []byte, p *packet) {
	payload := s.sealer.encryptPayload(b, p.packetNumber, p.payloadLen)
	if len(payload) != p.payloadLen {
		panic("encrypted payload length not expected")
	}
	pnOffset := len(b) - p.payloadLen - packetNumberLen(p.packetNumber)
	s.sealer.encryptHeader(b, pnOffset)
	s.encryptedPackets++
	if s.encryptedPackets > s.maxEncryptedPackets && s.keyUpdatePermitted {
		s.updateKey()
	}
}
length of b and payloadLen must include overhead.
package transport
import (
	"fmt"
	"time"
)
type packetSpace uint8
const (
	packetSpaceInitial packetSpace = iota
	packetSpaceHandshake
	packetSpaceApplication
	packetSpaceCount
)
var packetSpaceNames = [...]string{
	packetSpaceInitial:     "initial",
	packetSpaceHandshake:   "handshake",
	packetSpaceApplication: "application_data",
	packetSpaceCount:       "",
}
func (s packetSpace) String() string {
	return packetSpaceNames[s]
}
type packetType uint8
const (
	packetTypeInitial packetType = iota
	packetTypeZeroRTT
	packetTypeHandshake
	packetTypeRetry
	packetTypeVersionNegotiation
	packetTypeOneRTT
)
var packetTypeNames = [...]string{
	packetTypeInitial:            "initial",
	packetTypeZeroRTT:            "0rtt",
	packetTypeHandshake:          "handshake",
	packetTypeRetry:              "retry",
	packetTypeVersionNegotiation: "version_negotiation",
	packetTypeOneRTT:             "1rtt",
}
func (s packetType) String() string {
	return packetTypeNames[s]
}
const (
	maxPacketNumberLength  = 4
	minPacketPayloadLength = 4
)
func isLongHeader(b byte) bool {
	return b&0x80 != 0
}
func packetTypeFromLongHeader(b uint8) packetType {
	switch (b >> 4) & 0x3 {
	case 0:
		return packetTypeInitial
	case 1:
		return packetTypeZeroRTT
	case 2:
		return packetTypeHandshake
	case 3:
		return packetTypeRetry
	default:
		panic("unreachable")
	}
}
func packetTypeFromSpace(space packetSpace) packetType {
	switch space {
	case packetSpaceInitial:
		return packetTypeInitial
	case packetSpaceHandshake:
		return packetTypeHandshake
	case packetSpaceApplication:
		return packetTypeOneRTT
	default:
		panic("unsupported packet space")
	}
}
func packetTypeHeaderFlag(typ packetType) uint8 {
	switch typ {
	case packetTypeInitial:
		return 0xc0
	case packetTypeZeroRTT:
		return 0xd0
	case packetTypeHandshake:
		return 0xe0
	case packetTypeRetry:
		return 0xf0
	case packetTypeVersionNegotiation:
		return 0xc0
	case packetTypeOneRTT:
		return 0x40
	default:
		return 0
	}
}
func packetNumberLenFromHeader(b uint8) int {
	return int(b&0x03) + 1
}
func packetNumberLenHeaderFlag(n int) uint8 {
	return uint8(n - 1)
}
func keyPhaseFromHeader(b uint8) uint8 {
	if b&0x04 == 0 {
		return 0
	}
	return 1
}
func keyPhaseHeaderFlag(n uint8) uint8 {
	if n == 0 {
		return 0
	}
	return 0x04
}
type packetHeader struct {
	flags   uint8
	version uint32
	dcid    []byte
	scid    []byte
	dcil uint8  
}
func (s *packetHeader) encodedLen() int {
	if isLongHeader(s.flags) {
		return s.encodedLenLong()
	}
	return s.encodedLenShort()
}
func (s *packetHeader) encodedLenLong() int {
	return 7 + len(s.dcid) + len(s.scid)
}
func (s *packetHeader) encodedLenShort() int {
	return 1 + len(s.dcid)
}
func (s *packetHeader) encode(b []byte) (int, error) {
	if len(s.dcid) > MaxCIDLength || len(s.scid) > MaxCIDLength {
		return 0, errInvalidPacket
	}
	enc := newCodec(b)
	ok := enc.writeByte(s.flags)
	if !ok {
		return 0, errShortBuffer
	}
	if isLongHeader(s.flags) {
		ok = enc.writeUint32(s.version) &&
			enc.writeByte(uint8(len(s.dcid))) &&
			enc.write(s.dcid) &&
			enc.writeByte(uint8(len(s.scid))) &&
			enc.write(s.scid)
	} else {
		ok = enc.write(s.dcid)
	}
	if !ok {
		return 0, errShortBuffer
	}
	return enc.offset(), nil
}
func (s *packetHeader) decode(b []byte) (int, error) {
	dec := newCodec(b)
	if !dec.readByte(&s.flags) {
		return 0, errInvalidPacket
	}
	if isLongHeader(s.flags) {
		if !dec.readUint32(&s.version) {
			return 0, errInvalidPacket
		}
		var length uint8
		ok := dec.readByte(&length) && dec.read(&s.dcid, int(length))
		if !ok || length > MaxCIDLength {
			return 0, errInvalidPacket
		}
		ok = dec.readByte(&length) && dec.read(&s.scid, int(length))
		if !ok || length > MaxCIDLength {
			return 0, errInvalidPacket
		}
	} else {
		if !dec.read(&s.dcid, int(s.dcil)) {
			return 0, errInvalidPacket
		}
	}
	return dec.offset(), nil
}
func (s *packetHeader) String() string {
	return fmt.Sprintf("packet_type=%s version=%d dcid=%x scid=%x", s.packetType(), s.version, s.dcid, s.scid)
}
func (s *packetHeader) packetType() packetType {
	if isLongHeader(s.flags) {
		if s.version == 0 {
			return packetTypeVersionNegotiation
		}
		return packetTypeFromLongHeader(s.flags)
	}
	return packetTypeOneRTT
}
type packet struct {
	typ       packetType
	header    packetHeader
	headerLen int  
	supportedVersions []uint32  
	token             []byte    
	packetNumber uint64
	packetSize   int
	payloadLen   int
}
func (s *packet) setType(typ packetType) {
	s.typ = typ
	s.header.flags = packetTypeHeaderFlag(typ)
}
func (s *packet) setPacketNumber(packetNumber uint64) {
	s.packetNumber = packetNumber
	switch s.typ {
	case packetTypeInitial:
		s.header.flags |= packetNumberLenHeaderFlag(packetNumberLen(packetNumber))
	case packetTypeZeroRTT:
		s.header.flags |= packetNumberLenHeaderFlag(packetNumberLen(packetNumber))
	case packetTypeHandshake:
		s.header.flags |= packetNumberLenHeaderFlag(packetNumberLen(packetNumber))
	case packetTypeOneRTT:
		s.header.flags |= packetNumberLenHeaderFlag(packetNumberLen(packetNumber))
	}
}
func (s *packet) setKeyPhase(n uint8) {
	switch s.typ {
	case packetTypeOneRTT:
		s.header.flags |= keyPhaseHeaderFlag(n)
	}
}
func (s *packet) keyPhase() uint8 {
	switch s.typ {
	case packetTypeOneRTT:
		return keyPhaseFromHeader(s.header.flags)
	default:
		return 0
	}
}
func (s *packet) encodedLen() int {
	switch s.typ {
	case packetTypeInitial:
		return s.encodedLenInitial()
	case packetTypeZeroRTT, packetTypeHandshake:
		return s.encodedLenLong()
	case packetTypeRetry:
		return s.encodedLenRetry()
	case packetTypeVersionNegotiation:
		return s.encodedLenVersionNegotiation()
	case packetTypeOneRTT:
		return s.encodedLenShort()
	default:
		panic("unreachable")
	}
}
func (s *packet) encode(b []byte) (int, error) {
	n, err := s.header.encode(b)
	if err != nil {
		return 0, err
	}
	b = b[n:]
	var m int
	switch s.typ {
	case packetTypeInitial:
		m, err = s.encodeInitial(b)
	case packetTypeZeroRTT, packetTypeHandshake:
		m, err = s.encodeLong(b)
	case packetTypeRetry:
		m, err = s.encodeRetry(b)
	case packetTypeVersionNegotiation:
		m, err = s.encodeVersionNegotiation(b)
	case packetTypeOneRTT:
		m, err = s.encodeShort(b)
	default:
		panic("unreachable")
	}
	if err != nil {
		return 0, err
	}
	return n + m, nil
}
func (s *packet) decodeHeader(b []byte) (int, error) {
	n, err := s.header.decode(b)
	if err != nil {
		return 0, err
	}
	s.headerLen = n
	s.typ = s.header.packetType()
	return n, nil
}
func (s *packet) decodeBody(b []byte) (int, error) {
	b = b[s.headerLen:]
	switch s.typ {
	case packetTypeInitial:
		return s.decodeInitial(b)
	case packetTypeZeroRTT, packetTypeHandshake:
		return s.decodeLong(b)
	case packetTypeRetry:
		return s.decodeRetry(b)
	case packetTypeVersionNegotiation:
		return s.decodeVersionNegotiation(b)
	case packetTypeOneRTT:
		return s.decodeShort(b)
	default:
		panic("unreachable")
	}
}
func (s *packet) packetNumberOffset(b []byte) (int, error) {
	if s.typ == packetTypeOneRTT {
		return s.headerLen, nil
	}
	var length uint64
	dec := newCodec(b[s.headerLen:])
	if s.typ == packetTypeInitial {
		ok := dec.readVarint(&length) && dec.skip(int(length))
		if !ok {
			return 0, errInvalidPacket
		}
	}
	if !dec.readVarint(&length) {
		return 0, errInvalidPacket
	}
	return s.headerLen + dec.offset(), nil
}
func (s *packet) log(b []byte) []byte {
	b = appendField(b, "packet_type", s.typ.String())
	if s.typ == packetTypeOneRTT {
		if len(s.header.dcid) > 0 {
			b = appendField(b, "dcid", s.header.dcid)
		}
	} else {
		if s.header.version > 0 {
			b = appendField(b, "version", s.header.version)
		}
		if len(s.header.dcid) > 0 {
			b = appendField(b, "dcid", s.header.dcid)
		}
		if len(s.header.scid) > 0 {
			b = appendField(b, "scid", s.header.scid)
		}
		if len(s.supportedVersions) > 0 {
			b = appendField(b, "supported_versions", s.supportedVersions)
		}
		if len(s.token) > 0 {
			b = appendField(b, "token", s.token)
		}
	}
	b = appendField(b, "packet_number", s.packetNumber)
	if s.packetSize > 0 {
		b = appendField(b, "packet_size", s.packetSize)
	}
	if s.payloadLen > 0 {
		b = appendField(b, "payload_length", s.payloadLen)
	}
	return b
}
func (s *packet) String() string {
	switch s.typ {
	case packetTypeInitial, packetTypeRetry:
		return fmt.Sprintf("packet_type=%s version=%d dcid=%x scid=%x token=%x packet_number=%d",
			s.typ, s.header.version, s.header.dcid, s.header.scid, s.token, s.packetNumber)
	case packetTypeOneRTT:
		return fmt.Sprintf("packet_type=%s dcid=%x packet_number=%d",
			s.typ, s.header.dcid, s.packetNumber)
	default:
		return fmt.Sprintf("packet_type=%s version=%d dcid=%x scid=%x packet_number=%d",
			s.typ, s.header.version, s.header.dcid, s.header.scid, s.packetNumber)
	}
}
type Header struct {
	Type    string
	DCID    []byte
	SCID    []byte  
	Token   []byte  
	Version uint32  
}
func (s *Header) Decode(b []byte, dcil int) (int, error) {
	h := packetHeader{
		dcil: uint8(dcil),
	}
	n, err := h.decode(b)
	if err != nil {
		return 0, err
	}
	typ := h.packetType()
	s.Type = typ.String()
	s.Version = h.version
	s.DCID = h.dcid
	s.SCID = h.scid
	dec := newCodec(b[n:])
	switch typ {
	case packetTypeInitial:
		var length uint64
		ok := dec.readVarint(&length) && dec.read(&s.Token, int(length))
		if !ok {
			return 0, errInvalidPacket
		}
	case packetTypeRetry:
		length := dec.len() - retryIntegrityTagLen
		if length < 0 || !dec.read(&s.Token, length) {
			return 0, errInvalidPacket
		}
	}
	return n + dec.offset(), nil
}
func (s *Header) String() string {
	switch s.Type {
	case packetTypeNames[packetTypeInitial], packetTypeNames[packetTypeRetry]:
		return fmt.Sprintf("packet_type=%s version=%d dcid=%x scid=%x token=%x",
			s.Type, s.Version, s.DCID, s.SCID, s.Token)
	case packetTypeNames[packetTypeOneRTT]:
		return fmt.Sprintf("packet_type=%s dcid=%x", s.Type, s.DCID)
	default:
		return fmt.Sprintf("packet_type=%s version=%d dcid=%x scid=%x",
			s.Type, s.Version, s.DCID, s.SCID)
	}
}
func (s *packet) encodedLenVersionNegotiation() int {
	return s.header.encodedLenLong() + 4*len(s.supportedVersions)
}
func (s *packet) encodeVersionNegotiation(b []byte) (int, error) {
	if len(s.supportedVersions) == 0 {
		return 0, errInvalidPacket
	}
	enc := newCodec(b)
	for _, v := range s.supportedVersions {
		if !enc.writeUint32(v) {
			return 0, errShortBuffer
		}
	}
	return enc.offset(), nil
}
func (s *packet) decodeVersionNegotiation(b []byte) (int, error) {
	dec := newCodec(b)
	var vers uint32
	if !dec.readUint32(&vers) {
		return 0, errInvalidPacket
	}
	s.supportedVersions = make([]uint32, 0, 1+dec.len()/4)
	s.supportedVersions = append(s.supportedVersions, vers)
	for dec.len() > 0 {
		if !dec.readUint32(&vers) {
			return dec.offset(), errInvalidPacket
		}
		s.supportedVersions = append(s.supportedVersions, vers)
	}
	return dec.offset(), nil
}
func NegotiateVersion(b, dcid, scid []byte) (int, error) {
	if len(dcid) > MaxCIDLength || len(scid) > MaxCIDLength {
		return 0, newError(ProtocolViolation, "cid too long")
	}
	p := packet{
		header: packetHeader{
			dcid: dcid,
			scid: scid,
		},
		supportedVersions: supportedVersions[:],
	}
	p.setType(packetTypeVersionNegotiation)
	return p.encode(b)
}
func (s *packet) encodedLenInitial() int {
	return s.encodedLenLong() +
		varintLen(uint64(len(s.token))) +
		len(s.token)
}
func (s *packet) encodeInitial(b []byte) (int, error) {
	pnLen := packetNumberLenFromHeader(s.header.flags)
	enc := newCodec(b)
	ok := enc.writeVarint(uint64(len(s.token))) &&
		enc.write(s.token) &&
		enc.writeVarint(uint64(pnLen+s.payloadLen)) &&
		enc.writePacketNumber(s.packetNumber, pnLen)
	if !ok {
		return 0, errShortBuffer
	}
	return enc.offset(), nil
}
func (s *packet) decodeInitial(b []byte) (int, error) {
	dec := newCodec(b)
	var length uint64
	ok := dec.readVarint(&length) &&
		dec.read(&s.token, int(length))
	if !ok {
		return 0, errInvalidPacket
	}
	pnLen := packetNumberLenFromHeader(s.header.flags)
	ok = dec.readVarint(&length) &&
		dec.readPacketNumber(&s.packetNumber, pnLen)
	if !ok || int(length) < pnLen {
		return 0, errInvalidPacket
	}
	s.payloadLen = int(length) - pnLen
	if s.payloadLen < 0 || dec.len() < s.payloadLen {
		return 0, errInvalidPacket
	}
	return dec.offset(), nil
}
func (s *packet) encodedLenLong() int {
	pnLen := packetNumberLen(s.packetNumber)
	return s.header.encodedLenLong() +
		varintLen(uint64(pnLen+s.payloadLen)) +
		pnLen +
		s.payloadLen
}
func (s *packet) encodeLong(b []byte) (int, error) {
	pnLen := packetNumberLenFromHeader(s.header.flags)
	enc := newCodec(b)
	ok := enc.writeVarint(uint64(pnLen+s.payloadLen)) &&
		enc.writePacketNumber(s.packetNumber, pnLen)
	if !ok {
		return 0, errShortBuffer
	}
	return enc.offset(), nil
}
func (s *packet) decodeLong(b []byte) (int, error) {
	dec := newCodec(b)
	var length uint64
	pnLen := packetNumberLenFromHeader(s.header.flags)
	ok := dec.readVarint(&length) &&
		dec.readPacketNumber(&s.packetNumber, pnLen)
	if !ok || int(length) < pnLen {
		return 0, errInvalidPacket
	}
	s.payloadLen = int(length) - pnLen
	if s.payloadLen < 0 || dec.len() < s.payloadLen {
		return 0, errInvalidPacket
	}
	return dec.offset(), nil
}
func (s *packet) encodedLenRetry() int {
	return s.header.encodedLenLong() +
		len(s.token) + retryIntegrityTagLen
}
func (s *packet) encodeRetry(b []byte) (int, error) {
	enc := newCodec(b)
	if !enc.write(s.token) {
		return 0, errShortBuffer
	}
	return enc.offset(), nil
}
func (s *packet) decodeRetry(b []byte) (int, error) {
	dec := newCodec(b)
	length := dec.len() - retryIntegrityTagLen
	if length < 0 || !dec.read(&s.token, length) {
		return 0, errInvalidPacket
	}
	return dec.offset(), nil
}
func Retry(b, dcid, scid, odcid, token []byte) (int, error) {
	if len(dcid) > MaxCIDLength || len(scid) > MaxCIDLength || len(odcid) > MaxCIDLength {
		return 0, newError(ProtocolViolation, "cid too long")
	}
	enc := newCodec(b)
	ok := enc.writeByte(uint8(len(odcid))) && enc.write(odcid)
	if !ok {
		return 0, errShortBuffer
	}
	offset := enc.offset()
	p := packet{
		header: packetHeader{
			version: supportedVersions[0],
			dcid:    dcid,
			scid:    scid,
		},
		token: token,
	}
	p.setType(packetTypeRetry)
	n, err := p.encode(b[offset:])
	if err != nil {
		return 0, err
	}
	out, err := computeRetryIntegrity(b[:offset+n])
	if err != nil {
		return 0, err
	}
	if len(out) != offset+n+retryIntegrityTagLen {
		panic("invalid length of integrity tag generated")
	}
	n = copy(b, out[offset:])
	return n, nil
}
func (s *packet) encodedLenShort() int {
	return s.header.encodedLenShort() +
		packetNumberLen(s.packetNumber) +
		s.payloadLen
}
func (s *packet) encodeShort(b []byte) (int, error) {
	pnLen := packetNumberLenFromHeader(s.header.flags)
	enc := newCodec(b)
	if !enc.writePacketNumber(s.packetNumber, pnLen) {
		return 0, errShortBuffer
	}
	return enc.offset(), nil
}
func (s *packet) decodeShort(b []byte) (int, error) {
	pnLen := packetNumberLenFromHeader(s.header.flags)
	dec := newCodec(b)
	dec.readPacketNumber(&s.packetNumber, pnLen)
	s.payloadLen = dec.len()
	return dec.offset(), nil
}
type packetNumberWindow struct {
	lower  uint64  
	window uint64  
}
func (s *packetNumberWindow) push(n uint64) {
	if n < s.lower {
		return
	}
	if n > s.upper() {
		diff := n - s.upper()
		s.lower += diff
		s.window <<= diff
	}
	mask := uint64(1) << (s.upper() - n)
	s.window |= mask
}
func (s *packetNumberWindow) contains(n uint64) bool {
	if n < s.lower {
		return true
	}
	if n > s.upper() {
		return false
	}
	mask := uint64(1) << (s.upper() - n)
	return s.window&mask != 0
}
func (s *packetNumberWindow) upper() uint64 {
	return s.lower + 63
}
func (s *packetNumberWindow) String() string {
	return fmt.Sprintf("%d+0x%x", s.lower, s.window)
}
type packetNumberSpace struct {
	largestRecvPacketNumber uint64
	largestRecvPacketTime   time.Time
	nextPacketNumber uint64
	recvPacketNeedAck rangeSet
	recvAckRanges rangeSet
	recvPacketNumbers packetNumberWindow
	opener packetProtection
	sealer packetProtection
	prevOpener *packetProtection
	encryptedPackets    uint64  
	maxEncryptedPackets uint64  
	cryptoStream Stream
	keyPhase           uint8
	keyUpdatePermitted bool
	ackElicited bool
}
func newPacketNumberSpace() *packetNumberSpace {
	s := &packetNumberSpace{}
	s.init()
	return s
}
func (s *packetNumberSpace) init() {
	s.cryptoStream.init(true, true)
	s.cryptoStream.flow.init(cryptoMaxData, cryptoMaxData)
	s.maxEncryptedPackets = maxEncryptedPackets
}
func (s *packetNumberSpace) reset() {
	s.cryptoStream = Stream{}
	s.init()
	s.ackElicited = false
}
func (s *packetNumberSpace) canEncrypt() bool {
	return s.sealer.aead != nil
}