Skip to content

proposal: x/net/ipv4: add wrappers for Write/WriteToIP and Read/ReadFromIP #66461

@Einsfier

Description

@Einsfier

Brief for proposal

Add four wrapper function on ipv4.RawConn with detailed documentation.
Current doc is inferred from embed field, it is misleading even wrong in the context of ipv4.RawConn.

Described as below.

// Write writes a raw IPv4 datagram to the underlying socket.
// It will NOT prepend IPv4 header to the datagram, and it is caller's
// responsibility to provide correct IPv4 header on the wire per platform bias.
// See "x/net/ipv4/header.go" for details.
func (c *RawConn) Write(b []byte) (int, error) {
	// wrapper fn act same as before
}

// WriteToIP acts like Write but takes a *net.IPAddr as target for writing.
// It will NOT prepend IPv4 header to the datagram, and it is caller's
// responsibility to provide correct IPv4 header on the wire per platform bias.
// See "x/net/ipv4/header.go" for details.
func (c *RawConn) WriteToIP(b []byte, addr *net.IPAddr) (int, error) {
	// wrapper fn act same as before
}

// Read reads a raw IPv4 datagram into b, including IPv4 header, 
// returns the length read or an error.
// It's callers responsibility to parse IPv4 header per platform bias.
// See "x/net/ipv4/header.go" for details.
func (c *RawConn) Read(b []byte) (int, error) {
	// wrapper fn act same as before
}

// ReadFromIP reads an IPv4 datagram and write its payload into b,
// returns the length of payload and remote IPAddr.
func (c *RawConn) ReadFromIP(b []byte) (int, *net.IPAddr, error) {
	// wrapper fn act same as before
}

Proposal detail

Currently, functions on ipv4.RawConn are mostly provided by anonymous embed field, so with its doc.
I am confused with similar function names, but things they do completely different.

For example:
Read, ReadFrom and ReadFromIP.
Write, WriteTo and WriteToIP.
I just list fn signature and its doc below for quick reference.

Here is WHAT I HAVE OBSERVED

Read/Write is provided by *net.conn embed in field "packetHandler.IPConn"
ReadFrom/WriteTo is directly provided by embed field "packetHandler"
ReadFromIP/WriteToIP is provided by *net.IPConn embed in field "packetHandler"

The doc for ReadFromIP is not correct in the context of ipv4.RawConn, also the doc for Read is not very useful, and does not warn user that the wire format of IPv4 header may vary between platforms.
This is also true for Write*** situations.

eg: Some BSD-like systme including macOS have the ip_len and ip_off fields converted to host byte order after packets recived, and expcting host byte order for ip_len and ip_off fields while sending packets.
Those cases are already handled in x/net/ipv4/header.go, but we also should warn users about the differences while manipulating raw IPv4 datagrams.

type RawConn struct {
	genericOpt
	dgramOpt
	packetHandler
}

// Read implements the Conn Read method.
func (c *conn) Read(b []byte) (int, error)

// ReadFrom reads an IPv4 datagram from the endpoint c, copying the
// datagram into b. It returns the received datagram as the IPv4
// header h, the payload p and the control message cm.
func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error)

// ReadFromIP acts like ReadFrom but returns an IPAddr.
func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error)

// Write implements the Conn Write method.
func (c *conn) Write(b []byte) (int, error)

// WriteTo writes an IPv4 datagram through the endpoint c, copying the
// datagram from the IPv4 header h and the payload p. The control
// message cm allows the datagram path and the outgoing interface to be
// specified.  Currently only Darwin and Linux support this. The cm
// may be nil if control of the outgoing datagram is not required.
//
// The IPv4 header h must contain appropriate fields that include:
//
//	Version       = <must be specified>
//	Len           = <must be specified>
//	TOS           = <must be specified>
//	TotalLen      = <must be specified>
//	ID            = platform sets an appropriate value if ID is zero
//	FragOff       = <must be specified>
//	TTL           = <must be specified>
//	Protocol      = <must be specified>
//	Checksum      = platform sets an appropriate value if Checksum is zero
//	Src           = platform sets an appropriate value if Src is nil
//	Dst           = <must be specified>
//	Options       = optional
func (c *packetHandler) WriteTo(h *Header, p []byte, cm *ControlMessage) error

// WriteToIP acts like [IPConn.WriteTo] but takes an [IPAddr].
func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Incoming

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions