github.com/MerlinKodo/quic-go@v0.39.2/internal/wire/new_connection_id_frame.go (about)

     1  package wire
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  
     8  	"github.com/MerlinKodo/quic-go/internal/protocol"
     9  	"github.com/MerlinKodo/quic-go/quicvarint"
    10  )
    11  
    12  // A NewConnectionIDFrame is a NEW_CONNECTION_ID frame
    13  type NewConnectionIDFrame struct {
    14  	SequenceNumber      uint64
    15  	RetirePriorTo       uint64
    16  	ConnectionID        protocol.ConnectionID
    17  	StatelessResetToken protocol.StatelessResetToken
    18  }
    19  
    20  func parseNewConnectionIDFrame(r *bytes.Reader, _ protocol.VersionNumber) (*NewConnectionIDFrame, error) {
    21  	seq, err := quicvarint.Read(r)
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  	ret, err := quicvarint.Read(r)
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  	if ret > seq {
    30  		//nolint:stylecheck
    31  		return nil, fmt.Errorf("Retire Prior To value (%d) larger than Sequence Number (%d)", ret, seq)
    32  	}
    33  	connIDLen, err := r.ReadByte()
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  	connID, err := protocol.ReadConnectionID(r, int(connIDLen))
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	frame := &NewConnectionIDFrame{
    42  		SequenceNumber: seq,
    43  		RetirePriorTo:  ret,
    44  		ConnectionID:   connID,
    45  	}
    46  	if _, err := io.ReadFull(r, frame.StatelessResetToken[:]); err != nil {
    47  		if err == io.ErrUnexpectedEOF {
    48  			return nil, io.EOF
    49  		}
    50  		return nil, err
    51  	}
    52  
    53  	return frame, nil
    54  }
    55  
    56  func (f *NewConnectionIDFrame) Append(b []byte, _ protocol.VersionNumber) ([]byte, error) {
    57  	b = append(b, newConnectionIDFrameType)
    58  	b = quicvarint.Append(b, f.SequenceNumber)
    59  	b = quicvarint.Append(b, f.RetirePriorTo)
    60  	connIDLen := f.ConnectionID.Len()
    61  	if connIDLen > protocol.MaxConnIDLen {
    62  		return nil, fmt.Errorf("invalid connection ID length: %d", connIDLen)
    63  	}
    64  	b = append(b, uint8(connIDLen))
    65  	b = append(b, f.ConnectionID.Bytes()...)
    66  	b = append(b, f.StatelessResetToken[:]...)
    67  	return b, nil
    68  }
    69  
    70  // Length of a written frame
    71  func (f *NewConnectionIDFrame) Length(protocol.VersionNumber) protocol.ByteCount {
    72  	return 1 + quicvarint.Len(f.SequenceNumber) + quicvarint.Len(f.RetirePriorTo) + 1 /* connection ID length */ + protocol.ByteCount(f.ConnectionID.Len()) + 16
    73  }