github.com/ooni/psiphon/tunnel-core@v0.0.0-20230105123940-fe12a24c96ee/oovendor/quic-go/internal/protocol/connection_id.go (about) 1 package protocol 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "fmt" 7 "io" 8 ) 9 10 // A ConnectionID in QUIC 11 type ConnectionID []byte 12 13 const maxConnectionIDLen = 20 14 15 // GenerateConnectionID generates a connection ID using cryptographic random 16 func GenerateConnectionID(len int) (ConnectionID, error) { 17 b := make([]byte, len) 18 if _, err := rand.Read(b); err != nil { 19 return nil, err 20 } 21 return ConnectionID(b), nil 22 } 23 24 // GenerateConnectionIDForInitial generates a connection ID for the Initial packet. 25 // It uses a length randomly chosen between 8 and 20 bytes. 26 func GenerateConnectionIDForInitial() (ConnectionID, error) { 27 r := make([]byte, 1) 28 if _, err := rand.Read(r); err != nil { 29 return nil, err 30 } 31 len := MinConnectionIDLenInitial + int(r[0])%(maxConnectionIDLen-MinConnectionIDLenInitial+1) 32 return GenerateConnectionID(len) 33 } 34 35 // ReadConnectionID reads a connection ID of length len from the given io.Reader. 36 // It returns io.EOF if there are not enough bytes to read. 37 func ReadConnectionID(r io.Reader, len int) (ConnectionID, error) { 38 if len == 0 { 39 return nil, nil 40 } 41 c := make(ConnectionID, len) 42 _, err := io.ReadFull(r, c) 43 if err == io.ErrUnexpectedEOF { 44 return nil, io.EOF 45 } 46 return c, err 47 } 48 49 // Equal says if two connection IDs are equal 50 func (c ConnectionID) Equal(other ConnectionID) bool { 51 return bytes.Equal(c, other) 52 } 53 54 // Len returns the length of the connection ID in bytes 55 func (c ConnectionID) Len() int { 56 return len(c) 57 } 58 59 // Bytes returns the byte representation 60 func (c ConnectionID) Bytes() []byte { 61 return []byte(c) 62 } 63 64 func (c ConnectionID) String() string { 65 if c.Len() == 0 { 66 return "(empty)" 67 } 68 return fmt.Sprintf("%x", c.Bytes()) 69 }