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  }