Skip to content

Commit

Permalink
doc: incorporate Go reference document changes for Alpha release (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
jyyi1 authored Aug 17, 2023
1 parent 40c8132 commit 484adab
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 58 deletions.
15 changes: 8 additions & 7 deletions network/delegate_packet_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,19 @@ 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
// [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.
type DelegatePacketProxy interface {
PacketProxy

// SetProxy updates the underlying PacketProxy to `proxy`. And `proxy` must not be nil. After this function
// SetProxy updates the underlying PacketProxy to `proxy`; `proxy` must not be nil. After this function
// returns, all new PacketProxy calls will be forwarded to the `proxy`. Existing sessions will not be affected.
SetProxy(proxy PacketProxy) error
}
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
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")
)
30 changes: 15 additions & 15 deletions network/packet_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,26 @@ 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
// PacketRequestSender object to handle requests from this session, and it also uses the PacketResponseReceiver
// to send responses back to the upstream network stack.
//
// Note that, it is possible for a session to receive UDP packets without sending any requests.
// Note that it is possible for a session to receive UDP packets without sending any requests.
NewSession(PacketResponseReceiver) (PacketRequestSender, error)
}

// PacketRequestSender sends UDP request packets to the [PacketProxy]. It should be implemented by the [PacketProxy],
// 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
// 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.
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
// 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
// ignored. WriteTo returns the number of bytes written from `p` and any error encountered that caused the function
// to stop early.
//
Expand All @@ -53,16 +53,16 @@ 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
// 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
// instance to send UDP responses. It must then call the Close function to indicate that there will be no more
// responses sent to this receiver.
//
// Multiple goroutines may invoke methods on a PacketResponseReceiver simultaneously.
// Multiple goroutines can simultaneously invoke methods on a PacketResponseReceiver.
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
// `source` identifies the remote server that sent the packet and the `p` contains the packet payload. WriteFrom
// returns the number of bytes written from `p` and any error encountered that caused the function to stop early.
//
// `p` must not be modified, and it must not be referenced after WriteFrom returns.
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.
// 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
22 changes: 11 additions & 11 deletions transport/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ import (
"net"
)

// PacketEndpoint represents an endpoint that can be used to established packet connections (like UDP) to a fixed destination.
// PacketEndpoint represents an endpoint that can be used to establish packet connections (like UDP) to a fixed destination.
type PacketEndpoint interface {
// Connect creates a connection bound to an endpoint, returning the connection.
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.
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].
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 All @@ -75,7 +75,7 @@ func (d *UDPPacketDialer) Dial(ctx context.Context, addr string) (net.Conn, erro
return d.Dialer.DialContext(ctx, "udp", addr)
}

// PacketListenerDialer is a [PacketDialer] that connects to the destination using the given [PacketListener].
// PacketListenerDialer is a [PacketDialer] that connects to the destination using the specified [PacketListener].
type PacketListenerDialer struct {
// The PacketListener that is used to create the net.PacketConn to bind on Dial. Must be non nil.
Listener PacketListener
Expand All @@ -91,9 +91,9 @@ type boundPacketConn struct {
var _ net.Conn = (*boundPacketConn)(nil)

// Dial implements [PacketDialer].Dial.
// 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].
// 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.
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
// [StreamConn].CloseRead and [StreamConn].CloseWrite.
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
// 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].
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
// [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

0 comments on commit 484adab

Please sign in to comment.