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