diff --git a/net/packet/header.go b/net/packet/header.go index 54f67704e..ed7306f3a 100644 --- a/net/packet/header.go +++ b/net/packet/header.go @@ -16,27 +16,34 @@ const tcpHeaderLength = 20 const maxPacketLength = math.MaxUint16 var ( + // errSmallBuffer is returned when Marshal receives a buffer + // too small to contain the header to marshal. errSmallBuffer = errors.New("buffer too small") + // errLargePacket is returned when Marshal receives a payload + // larger than the maximum representable size in header + // fields. errLargePacket = errors.New("packet too large") ) -// Header is a packet header capable of marshaling itself into a byte buffer. +// Header is a packet header capable of marshaling itself into a byte +// buffer. type Header interface { - // Len returns the length of the header after marshaling. + // Len returns the length of the marshaled packet. Len() int - // Marshal serializes the header into buf in wire format. - // It clobbers the header region, which is the first h.Length() bytes of buf. - // It explicitly initializes every byte of the header region, - // so pre-zeroing it on reuse is not required. It does not allocate memory. - // It fails if and only if len(buf) < Length(). + // Marshal serializes the header into buf, which must be at + // least Len() bytes long. Implementations of Marshal assume + // that bytes after the first Len() are payload bytes for the + // purpose of computing length and checksum fields. Marshal + // implementations must not allocate memory. Marshal(buf []byte) error // ToResponse transforms the header into one for a response packet. // For instance, this swaps the source and destination IPs. ToResponse() } -// Generate generates a new packet with the given header and payload. -// Unlike Header.Marshal, this does allocate memory. +// Generate generates a new packet with the given Header and +// payload. This function allocates memory, see Header.Marshal for an +// allocation-free option. func Generate(h Header, payload []byte) []byte { hlen := h.Len() buf := make([]byte, hlen+len(payload)) diff --git a/net/packet/udp4.go b/net/packet/udp4.go index 6ae0cf4b6..a633bf072 100644 --- a/net/packet/udp4.go +++ b/net/packet/udp4.go @@ -14,17 +14,17 @@ type UDP4Header struct { } const ( + // udpHeaderLength is the size of the UDP packet header, not + // including the outer IP header. udpHeaderLength = 8 - // udpTotalHeaderLength is the length of all headers in a UDP packet. - udpTotalHeaderLength = ip4HeaderLength + udpHeaderLength ) func (UDP4Header) Len() int { - return udpTotalHeaderLength + return ip4HeaderLength + udpHeaderLength } func (h UDP4Header) Marshal(buf []byte) error { - if len(buf) < udpTotalHeaderLength { + if len(buf) < h.Len() { return errSmallBuffer } if len(buf) > maxPacketLength { @@ -39,9 +39,8 @@ func (h UDP4Header) Marshal(buf []byte) error { binary.BigEndian.PutUint16(buf[24:26], uint16(length)) binary.BigEndian.PutUint16(buf[26:28], 0) // blank checksum - h.IP4Header.MarshalPseudo(buf) - // UDP checksum with IP pseudo header. + h.IP4Header.MarshalPseudo(buf) binary.BigEndian.PutUint16(buf[26:28], ipChecksum(buf[8:])) h.IP4Header.Marshal(buf)