github.com/tumi8/quic-go@v0.37.4-tum/noninternal/wire/datagram_frame.go (about)

     1  package wire
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  
     7  	"github.com/tumi8/quic-go/noninternal/protocol"
     8  	"github.com/tumi8/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  }