github.com/MerlinKodo/quic-go@v0.39.2/internal/wire/datagram_frame.go (about) 1 package wire 2 3 import ( 4 "bytes" 5 "io" 6 7 "github.com/MerlinKodo/quic-go/internal/protocol" 8 "github.com/MerlinKodo/quic-go/quicvarint" 9 ) 10 11 // A DatagramFrame is a DATAGRAM frame 12 type DatagramFrame struct { 13 DataLenPresent bool 14 Data []byte 15 } 16 17 func parseDatagramFrame(r *bytes.Reader, typ uint64, _ protocol.VersionNumber) (*DatagramFrame, error) { 18 f := &DatagramFrame{} 19 f.DataLenPresent = typ&0x1 > 0 20 21 var length uint64 22 if f.DataLenPresent { 23 var err error 24 len, err := quicvarint.Read(r) 25 if err != nil { 26 return nil, err 27 } 28 if len > uint64(r.Len()) { 29 return nil, io.EOF 30 } 31 length = len 32 } else { 33 length = uint64(r.Len()) 34 } 35 f.Data = make([]byte, length) 36 if _, err := io.ReadFull(r, f.Data); err != nil { 37 return nil, err 38 } 39 return f, nil 40 } 41 42 func (f *DatagramFrame) Append(b []byte, _ protocol.VersionNumber) ([]byte, error) { 43 typ := uint8(0x30) 44 if f.DataLenPresent { 45 typ ^= 0b1 46 } 47 b = append(b, typ) 48 if f.DataLenPresent { 49 b = quicvarint.Append(b, uint64(len(f.Data))) 50 } 51 b = append(b, f.Data...) 52 return b, nil 53 } 54 55 // MaxDataLen returns the maximum data length 56 func (f *DatagramFrame) MaxDataLen(maxSize protocol.ByteCount, version protocol.VersionNumber) protocol.ByteCount { 57 headerLen := protocol.ByteCount(1) 58 if f.DataLenPresent { 59 // pretend that the data size will be 1 bytes 60 // if it turns out that varint encoding the length will consume 2 bytes, we need to adjust the data length afterwards 61 headerLen++ 62 } 63 if headerLen > maxSize { 64 return 0 65 } 66 maxDataLen := maxSize - headerLen 67 if f.DataLenPresent && quicvarint.Len(uint64(maxDataLen)) != 1 { 68 maxDataLen-- 69 } 70 return maxDataLen 71 } 72 73 // Length of a written frame 74 func (f *DatagramFrame) Length(_ protocol.VersionNumber) protocol.ByteCount { 75 length := 1 + protocol.ByteCount(len(f.Data)) 76 if f.DataLenPresent { 77 length += quicvarint.Len(uint64(len(f.Data))) 78 } 79 return length 80 }