github.com/metacubex/quic-go@v0.44.1-0.20240520163451-20b689a59136/internal/wire/new_connection_id_frame.go (about) 1 package wire 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 8 "github.com/metacubex/quic-go/internal/protocol" 9 "github.com/metacubex/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(b []byte, _ protocol.Version) (*NewConnectionIDFrame, int, error) { 21 startLen := len(b) 22 seq, l, err := quicvarint.Parse(b) 23 if err != nil { 24 return nil, 0, replaceUnexpectedEOF(err) 25 } 26 b = b[l:] 27 ret, l, err := quicvarint.Parse(b) 28 if err != nil { 29 return nil, 0, replaceUnexpectedEOF(err) 30 } 31 b = b[l:] 32 if ret > seq { 33 //nolint:stylecheck 34 return nil, 0, fmt.Errorf("Retire Prior To value (%d) larger than Sequence Number (%d)", ret, seq) 35 } 36 if len(b) == 0 { 37 return nil, 0, io.EOF 38 } 39 connIDLen := int(b[0]) 40 b = b[1:] 41 if connIDLen == 0 { 42 return nil, 0, errors.New("invalid zero-length connection ID") 43 } 44 if connIDLen > protocol.MaxConnIDLen { 45 return nil, 0, protocol.ErrInvalidConnectionIDLen 46 } 47 if len(b) < connIDLen { 48 return nil, 0, io.EOF 49 } 50 frame := &NewConnectionIDFrame{ 51 SequenceNumber: seq, 52 RetirePriorTo: ret, 53 ConnectionID: protocol.ParseConnectionID(b[:connIDLen]), 54 } 55 b = b[connIDLen:] 56 if len(b) < len(frame.StatelessResetToken) { 57 return nil, 0, io.EOF 58 } 59 copy(frame.StatelessResetToken[:], b) 60 return frame, startLen - len(b) + len(frame.StatelessResetToken), nil 61 } 62 63 func (f *NewConnectionIDFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { 64 b = append(b, newConnectionIDFrameType) 65 b = quicvarint.Append(b, f.SequenceNumber) 66 b = quicvarint.Append(b, f.RetirePriorTo) 67 connIDLen := f.ConnectionID.Len() 68 if connIDLen > protocol.MaxConnIDLen { 69 return nil, fmt.Errorf("invalid connection ID length: %d", connIDLen) 70 } 71 b = append(b, uint8(connIDLen)) 72 b = append(b, f.ConnectionID.Bytes()...) 73 b = append(b, f.StatelessResetToken[:]...) 74 return b, nil 75 } 76 77 // Length of a written frame 78 func (f *NewConnectionIDFrame) Length(protocol.Version) protocol.ByteCount { 79 return 1 + protocol.ByteCount(quicvarint.Len(f.SequenceNumber)+quicvarint.Len(f.RetirePriorTo)+1 /* connection ID length */ +f.ConnectionID.Len()) + 16 80 }