mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-11-07 10:47:48 -05:00
70 lines
1.6 KiB
Go
70 lines
1.6 KiB
Go
package protocol
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/rand"
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// A ConnectionID in QUIC
|
|
type ConnectionID []byte
|
|
|
|
const maxConnectionIDLen = 18
|
|
|
|
// GenerateConnectionID generates a connection ID using cryptographic random
|
|
func GenerateConnectionID(len int) (ConnectionID, error) {
|
|
b := make([]byte, len)
|
|
if _, err := rand.Read(b); err != nil {
|
|
return nil, err
|
|
}
|
|
return ConnectionID(b), nil
|
|
}
|
|
|
|
// GenerateConnectionIDForInitial generates a connection ID for the Initial packet.
|
|
// It uses a length randomly chosen between 8 and 18 bytes.
|
|
func GenerateConnectionIDForInitial() (ConnectionID, error) {
|
|
r := make([]byte, 1)
|
|
if _, err := rand.Read(r); err != nil {
|
|
return nil, err
|
|
}
|
|
len := MinConnectionIDLenInitial + int(r[0])%(maxConnectionIDLen-MinConnectionIDLenInitial+1)
|
|
return GenerateConnectionID(len)
|
|
}
|
|
|
|
// ReadConnectionID reads a connection ID of length len from the given io.Reader.
|
|
// It returns io.EOF if there are not enough bytes to read.
|
|
func ReadConnectionID(r io.Reader, len int) (ConnectionID, error) {
|
|
if len == 0 {
|
|
return nil, nil
|
|
}
|
|
c := make(ConnectionID, len)
|
|
_, err := io.ReadFull(r, c)
|
|
if err == io.ErrUnexpectedEOF {
|
|
return nil, io.EOF
|
|
}
|
|
return c, err
|
|
}
|
|
|
|
// Equal says if two connection IDs are equal
|
|
func (c ConnectionID) Equal(other ConnectionID) bool {
|
|
return bytes.Equal(c, other)
|
|
}
|
|
|
|
// Len returns the length of the connection ID in bytes
|
|
func (c ConnectionID) Len() int {
|
|
return len(c)
|
|
}
|
|
|
|
// Bytes returns the byte representation
|
|
func (c ConnectionID) Bytes() []byte {
|
|
return []byte(c)
|
|
}
|
|
|
|
func (c ConnectionID) String() string {
|
|
if c.Len() == 0 {
|
|
return "(empty)"
|
|
}
|
|
return fmt.Sprintf("%#x", c.Bytes())
|
|
}
|