Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: incorporate Go reference document changes for Alpha release #41

Merged
merged 10 commits into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions network/delegate_packet_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ import (
"sync/atomic"
)

// DelegatePacketProxy is a PacketProxy that forwards calls (like NewSession) to another PacketProxy. To create a
// DelegatePacketProxy with the default PacketProxy, use NewDelegatePacketProxy. To change the underlying PacketProxy,
// use SetProxy.
// DelegatePacketProxy is a [PacketProxy] that forwards calls (like NewSession) to another [PacketProxy],
// so that the caller can replace the underlying [PacketProxy] without changing the original reference.
// To create a DelegatePacketProxy with the default PacketProxy, use [NewDelegatePacketProxy]. To change
// the underlying [PacketProxy], use SetProxy.
//
// Note: After changing the underlying PacketProxy, only new NewSession calls will be routed to the new PacketProxy.
// Existing sessions will not be affected.
// Note: After the underlying [PacketProxy] is changed, only new NewSession calls will be routed to the new
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// [PacketProxy]. Existing sessions will not be affected.
//
// Multiple goroutines may invoke methods on a DelegatePacketProxy simultaneously.
// Multiple goroutines can simultaneously invoke methods on a DelegatePacketProxy.
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
type DelegatePacketProxy interface {
PacketProxy

Expand Down
8 changes: 4 additions & 4 deletions network/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ import (
)

var (
// ErrMsgSize is the error returned by a Write on a network device that the size of the message to be sent is bigger
// than the maximum message size the device can process.
// ErrMsgSize is the error returned by a Write on a network device. It means that the size of the message to be
// sent is bigger than the maximum message size the device can process.
ErrMsgSize = fmt.Errorf("packet size is too big: %w", syscall.EMSGSIZE)
)

// IPDevice is a generic network device that reads and writes IP packets. It extends the [io.ReadWriteCloser]
// interface. For better memory efficiency, we also recommend implementing the [io.ReaderFrom] and
// [io.WriterTo] interfaces if possible.
// interface. For better memory efficiency, we also recommend that you implement the [io.ReaderFrom] and [io.WriterTo]
// interfaces if possible.
//
// Some examples of IPDevices are a virtual network adapter or a local IP proxy.
type IPDevice interface {
Expand Down
8 changes: 4 additions & 4 deletions network/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

/*
The network package defines interfaces and provides utilities for network layer (OSI layer 3) functionalities. For
example, the [IPDevice] interface can be used to read and write IP packets from a physical or virtual network device.
example, you can use the [IPDevice] interface to read and write IP packets from a physical or virtual network device.

In addition, user-space network stack implementations are also included in the sub-packages (such as
network/lwip2transport) that can translate raw IP packets into TCP/UDP flows. You can implement a [PacketProxy]
to handle UDP traffic, and a [transport.StreamDialer] to handle TCP traffic.
In addition, the sub-packages include user-space network stack implementations (such as network/lwip2transport) that
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
can translate raw IP packets into TCP/UDP flows. You can implement a [PacketProxy] to handle UDP traffic, and a
[transport.StreamDialer] to handle TCP traffic.
*/
package network
6 changes: 3 additions & 3 deletions network/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ import (

// Portable analogs of some common errors.
//
// Errors returned from this package and all sub-packages may be tested against these errors with [errors.Is].
// Errors returned from this package and all sub-packages can be tested against these errors using [errors.Is].
var (
// ErrClosed is the error returned by an I/O call on a network device or proxy that has already been closed, or that is
// closed by another goroutine before the I/O is completed. This may be wrapped in another error, and should normally
// closed by another goroutine before the I/O is completed. This can be wrapped in another error, and should normally
// be tested using errors.Is(err, network.ErrClosed).
ErrClosed = errors.New("network device already closed")

// ErrPortUnreachable is an error that indicates a remote server's port cannot be reached. This may be wrapped in
// ErrPortUnreachable is an error that indicates a remote server's port cannot be reached. This can be wrapped in
// another error, and should normally be tested using errors.Is(err, network.ErrPortUnreachable).
ErrPortUnreachable = errors.New("port is not reachable")
)
24 changes: 12 additions & 12 deletions network/packet_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
// PacketProxy handles UDP traffic from the upstream network stack. The upstream network stack uses the NewSession
// function to create a new UDP session that can send or receive UDP packets from PacketProxy.
//
// Multiple goroutines may invoke methods on a PacketProxy simultaneously.
// Multiple goroutines can simultaneously invoke methods on a PacketProxy.
type PacketProxy interface {
// NewSession function tells the PacketProxy that a new UDP socket session has been started (using socket as an
// example, a session will be started by calling the bind() function). The PacketProxy then creates a
Expand All @@ -34,14 +34,14 @@ type PacketProxy interface {
}

// PacketRequestSender sends UDP request packets to the [PacketProxy]. It should be implemented by the [PacketProxy],
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// who must implement the WriteTo method to process the request packets. PacketRequestSender is typically called by an
// upstream component (such as a network stack). Once the Close method is called, there will be no more requests sent
// to the sender, and all resources can be freed.
// which must implement the WriteTo method to process the request packets. PacketRequestSender is typically called by
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// an upstream component (such as a network stack). After the Close method is called, there will be no more requests
// sent to the sender, and all resources can be freed.
//
// Multiple goroutines may invoke methods on a PacketRequestSender simultaneously.
// Multiple goroutines can simultaneously invoke methods on a PacketRequestSender.
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
type PacketRequestSender interface {
// WriteTo sends a UDP request packet to the [PacketProxy]. The packet is destined for the remote server identified
// by `destination`; and the payload of the packet is stored in `p`. If `p` is empty, the request packet will be
// by `destination` and the payload of the packet is stored in `p`. If `p` is empty, the request packet will be
// ignored. WriteTo returns the number of bytes written from `p` and any error encountered that caused the function
// to stop early.
//
Expand All @@ -53,13 +53,13 @@ type PacketRequestSender interface {
Close() error
}

// PacketResponseReceiver receives UDP response packets from the [PacketProxy]. It is usually implemented by the
// upstream component (such as a network stack). When creating a new UDP session, a valid instance
// PacketResponseReceiver is passed to the PacketProxy.NewSession function. Then the [PacketProxy] must use this
// instance to send UDP responses all the time; and it must call the Close function to indicate there will be no more
// responses send to this receiver.
// PacketResponseReceiver receives UDP response packets from the [PacketProxy]. It is usually implemented by an
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// upstream component (such as a network stack). When a new UDP session is created, a valid instance of
// PacketResponseReceiver is passed to the PacketProxy.NewSession function. The [PacketProxy] must then use this
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// instance to send UDP responses. It must then call the Close function to indicate that there will be no more
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// responses sent to this receiver.
//
// Multiple goroutines may invoke methods on a PacketResponseReceiver simultaneously.
// Multiple goroutines can simultaneously invoke methods on a PacketResponseReceiver.
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
type PacketResponseReceiver interface {
// WriteFrom is a callback function that is called by a PacketProxy when a UDP response packet is received. The
// `source` identifies the remote server that sent the packet; and the `p` contains the packet payload. WriteFrom
Expand Down
10 changes: 5 additions & 5 deletions transport/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ func (a *domainAddr) String() string {
var _ net.Addr = (*domainAddr)(nil)

// MakeNetAddr returns a [net.Addr] based on the network and address.
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// This is a helper for code that need to return or provide a net.Addr
// The address must be in host:port format, with the host being a domain name, IPv4 or IPv6.
// Network must be "tcp" or "udp".
// This is a helper for code that needs to return or provide a [net.Addr].
// The address must be in "host:port" format with the host being a domain name, IPv4 or IPv6.
// The network must be "tcp" or "udp".
// For IP hosts, the returned address will be of type [*net.TCPAddr] or [*net.UDPAddr], based on the network argument.
// This is important because some of the standard library functions inspect the type of the address and may return an
// "invalid argument" error if the type is not the right one.
// This is important because some of the standard library functions inspect the type of the address and might return an
// "invalid argument" error if the type is not the correct one.
func MakeNetAddr(network, address string) (net.Addr, error) {
host, port, err := net.SplitHostPort(address)
if err != nil {
Expand Down
18 changes: 9 additions & 9 deletions transport/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ type PacketEndpoint interface {
Connect(ctx context.Context) (net.Conn, error)
}

// UDPEndpoint is a [PacketEndpoint] that connects to the given address via UDP
// UDPEndpoint is a [PacketEndpoint] that connects to the specified address using UDP
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
type UDPEndpoint struct {
// The Dialer used to create the net.Conn on Connect().
Dialer net.Dialer
// The endpoint address (host:port) to pass to Dial.
// The endpoint address ("host:port") to pass to Dial.
// If the host is a domain name, consider pre-resolving it to avoid resolution calls.
Address string
}
Expand All @@ -42,7 +42,7 @@ func (e UDPEndpoint) Connect(ctx context.Context) (net.Conn, error) {
return e.Dialer.DialContext(ctx, "udp", e.Address)
}

// PacketDialerEndpoint is a [PacketEndpoint] that connects to the given address using the given [PacketDialer].
// PacketDialerEndpoint is a [PacketEndpoint] that connects to the given address using the specified [PacketDialer].
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
type PacketDialerEndpoint struct {
Dialer PacketDialer
Address string
Expand All @@ -57,8 +57,8 @@ func (e *PacketDialerEndpoint) Connect(ctx context.Context) (net.Conn, error) {

// PacketDialer provides a way to dial a destination and establish datagram connections.
type PacketDialer interface {
// Dial connects to `raddr`.
// `raddr` has the form `host:port`, where `host` can be a domain name or IP address.
// Dial connects to `addr`.
// `addr` has the form "host:port", where "host" can be a domain name or IP address.
Dial(ctx context.Context, addr string) (net.Conn, error)
}

Expand Down Expand Up @@ -91,9 +91,9 @@ type boundPacketConn struct {
var _ net.Conn = (*boundPacketConn)(nil)

// Dial implements [PacketDialer].Dial.
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// The address is a host:port and the host must be a full IP address (not [::]) or a domain
// The address must be supported by the WriteTo call of the PacketConn
// returned by the PacketListener. For instance, a [net.UDPConn] only supports IP addresses, not domain names.
// The address is in "host:port" format and the host must be either a full IP address (not "[::]") or a domain.
// The address must be supported by the WriteTo call of the [net.PacketConn] returned by the [PacketListener].
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// For example, a [net.UDPConn] only supports IP addresses, not domain names.
// If the host is a domain name, consider pre-resolving it to avoid resolution calls.
func (e PacketListenerDialer) Dial(ctx context.Context, address string) (net.Conn, error) {
packetConn, err := e.Listener.ListenPacket(ctx)
Expand Down Expand Up @@ -138,7 +138,7 @@ func (c *boundPacketConn) RemoteAddr() net.Addr {

// PacketListener provides a way to create a local unbound packet connection to send packets to different destinations.
type PacketListener interface {
// ListenPacket creates a PacketConn that can be used to relay packets (such as UDP) through some proxy.
// ListenPacket creates a PacketConn that can be used to relay packets (such as UDP) through a proxy.
ListenPacket(ctx context.Context) (net.PacketConn, error)
}

Expand Down
19 changes: 10 additions & 9 deletions transport/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,13 @@ import (
"net"
)

// StreamConn is a net.Conn that allows for closing only the reader or writer end of
// it, supporting half-open state.
// StreamConn is a [net.Conn] that allows for closing only the reader or writer end of it, supporting half-open state.
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
type StreamConn interface {
net.Conn
// Closes the Read end of the connection, allowing for the release of resources.
// No more reads should happen.
CloseRead() error
// Closes the Write end of the connection. An EOF or FIN signal may be
// Closes the Write end of the connection. An EOF or FIN signal can be
// sent to the connection target.
CloseWrite() error
}
Expand Down Expand Up @@ -59,8 +58,8 @@ func (dc *duplexConnAdaptor) CloseWrite() error {
return dc.StreamConn.CloseWrite()
}

// WrapDuplexConn wraps an existing [StreamConn] with new Reader and Writer, but
// preserving the original [StreamConn.CloseRead] and [StreamConn.CloseWrite].
// WrapConn wraps an existing [StreamConn] with a new [io.Reader] and [io.Writer], but preserves the original
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// [StreamConn].CloseRead and [StreamConn].CloseWrite.
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
func WrapConn(c StreamConn, r io.Reader, w io.Writer) StreamConn {
conn := c
// We special-case duplexConnAdaptor to avoid multiple levels of nesting.
Expand All @@ -70,13 +69,14 @@ func WrapConn(c StreamConn, r io.Reader, w io.Writer) StreamConn {
return &duplexConnAdaptor{StreamConn: conn, r: r, w: w}
}

// StreamEndpoint represents an endpoint that can be used to established stream connections (like TCP) to a fixed destination.
// StreamEndpoint represents an endpoint that can be used to establish stream connections (like TCP) to a fixed
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// destination.
type StreamEndpoint interface {
// Connect establishes a connection with the endpoint, returning the connection.
Connect(ctx context.Context) (StreamConn, error)
}

// TCPEndpoint is a [StreamEndpoint] that connects to the given address using the given [StreamDialer].
// TCPEndpoint is a [StreamEndpoint] that connects to the specified address using the specified [StreamDialer].
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
type TCPEndpoint struct {
// The Dialer used to create the net.Conn on Connect().
Dialer net.Dialer
Expand All @@ -96,7 +96,8 @@ func (e *TCPEndpoint) Connect(ctx context.Context) (StreamConn, error) {
return conn.(*net.TCPConn), nil
}

// StreamDialerEndpoint is a [StreamEndpoint] that connects to the given address using the given [StreamDialer].
// StreamDialerEndpoint is a [StreamEndpoint] that connects to the specified address using the specified
jyyi1 marked this conversation as resolved.
Show resolved Hide resolved
// [StreamDialer].
type StreamDialerEndpoint struct {
Dialer StreamDialer
Address string
Expand All @@ -112,7 +113,7 @@ func (e *StreamDialerEndpoint) Connect(ctx context.Context) (StreamConn, error)
// StreamDialer provides a way to dial a destination and establish stream connections.
type StreamDialer interface {
// Dial connects to `raddr`.
// `raddr` has the form `host:port`, where `host` can be a domain name or IP address.
// `raddr` has the form "host:port", where "host" can be a domain name or IP address.
Dial(ctx context.Context, raddr string) (StreamConn, error)
}

Expand Down