github.com/quic-go/quic-go@v0.44.0/internal/wire/connection_close_frame.go (about) 1 package wire 2 3 import ( 4 "io" 5 6 "github.com/quic-go/quic-go/internal/protocol" 7 "github.com/quic-go/quic-go/quicvarint" 8 ) 9 10 // A ConnectionCloseFrame is a CONNECTION_CLOSE frame 11 type ConnectionCloseFrame struct { 12 IsApplicationError bool 13 ErrorCode uint64 14 FrameType uint64 15 ReasonPhrase string 16 } 17 18 func parseConnectionCloseFrame(b []byte, typ uint64, _ protocol.Version) (*ConnectionCloseFrame, int, error) { 19 startLen := len(b) 20 f := &ConnectionCloseFrame{IsApplicationError: typ == applicationCloseFrameType} 21 ec, l, err := quicvarint.Parse(b) 22 if err != nil { 23 return nil, 0, replaceUnexpectedEOF(err) 24 } 25 b = b[l:] 26 f.ErrorCode = ec 27 // read the Frame Type, if this is not an application error 28 if !f.IsApplicationError { 29 ft, l, err := quicvarint.Parse(b) 30 if err != nil { 31 return nil, 0, replaceUnexpectedEOF(err) 32 } 33 b = b[l:] 34 f.FrameType = ft 35 } 36 var reasonPhraseLen uint64 37 reasonPhraseLen, l, err = quicvarint.Parse(b) 38 if err != nil { 39 return nil, 0, replaceUnexpectedEOF(err) 40 } 41 b = b[l:] 42 if int(reasonPhraseLen) > len(b) { 43 return nil, 0, io.EOF 44 } 45 46 reasonPhrase := make([]byte, reasonPhraseLen) 47 copy(reasonPhrase, b) 48 f.ReasonPhrase = string(reasonPhrase) 49 return f, startLen - len(b) + int(reasonPhraseLen), nil 50 } 51 52 // Length of a written frame 53 func (f *ConnectionCloseFrame) Length(protocol.Version) protocol.ByteCount { 54 length := 1 + protocol.ByteCount(quicvarint.Len(f.ErrorCode)+quicvarint.Len(uint64(len(f.ReasonPhrase)))) + protocol.ByteCount(len(f.ReasonPhrase)) 55 if !f.IsApplicationError { 56 length += protocol.ByteCount(quicvarint.Len(f.FrameType)) // for the frame type 57 } 58 return length 59 } 60 61 func (f *ConnectionCloseFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { 62 if f.IsApplicationError { 63 b = append(b, applicationCloseFrameType) 64 } else { 65 b = append(b, connectionCloseFrameType) 66 } 67 68 b = quicvarint.Append(b, f.ErrorCode) 69 if !f.IsApplicationError { 70 b = quicvarint.Append(b, f.FrameType) 71 } 72 b = quicvarint.Append(b, uint64(len(f.ReasonPhrase))) 73 b = append(b, []byte(f.ReasonPhrase)...) 74 return b, nil 75 }