Documentation ¶
Overview ¶
The network package defines interfaces and provides utilities for network layer (OSI layer 3) functionalities. For example, you can use the IPDevice interface to read and write IP packets from a physical or virtual network device.
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.
Index ¶
Constants ¶
This section is empty.
Variables ¶
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 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 can be wrapped in // another error, and should normally be tested using errors.Is(err, network.ErrPortUnreachable). ErrPortUnreachable = errors.New("port is not reachable") )
Portable analogs of some common errors.
Errors returned from this package and all sub-packages can be tested against these errors using errors.Is.
var ( // 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) )
Functions ¶
func WithPacketListenerWriteIdleTimeout ¶
func WithPacketListenerWriteIdleTimeout(timeout time.Duration) func(*PacketListenerProxy) error
WithPacketListenerWriteIdleTimeout sets the write idle timeout of the PacketListenerProxy. This means that if there are no WriteTo operations on the UDP session created by NewSession for the specified amount of time, the proxy will end this session.
This should be used together with the [NewPacketProxyFromPacketListenerWithOptions] function.
Types ¶
type DelegatePacketProxy ¶
type DelegatePacketProxy interface { PacketProxy // 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 }
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 the underlying PacketProxy is changed, only new NewSession calls will be routed to the new PacketProxy. Existing sessions will not be affected.
Multiple goroutines can simultaneously invoke methods on a DelegatePacketProxy.
func NewDelegatePacketProxy ¶
func NewDelegatePacketProxy(proxy PacketProxy) (DelegatePacketProxy, error)
NewDelegatePacketProxy creates a new DelegatePacketProxy that forwards calls to the `proxy` PacketProxy. The `proxy` must not be nil.
type IPDevice ¶
type IPDevice interface { // Close closes this device. Any future Read will return io.EOF and Write will return ErrClosed. Close() error // Read reads an IP packet from this device into p, returning the number of bytes read. It blocks until a full IP // packet has been received. Note that an IP packet might be fragmented, and we will not reassemble it. Instead, we // will simply return the fragmented packets to the caller. // // If len(p) is smaller than the incoming IP packet, only len(p) bytes will be copied to p, the excess bytes are // discarded (this aligns with the socket recvfrom function), and nil error will be returned. You can Use MTU to get // the maximum size of the packets. // // If the returned error is nil, it means that Read has completed successfully and that an IP packet has been copied // into p. Read(p []byte) (int, error) // Write writes an IP packet p to this device and returns the number of bytes written. Similar to Read, large IP // packets must be fragmented by the caller, and len(p) must not exceed the maximum buffer size returned by MTU. // // Write will return (0, ErrMsgSize) if len(p) > MTU(). This aligns with the socket sendto function. // // If the returned error is nil, it means that Write has completed successfully and that the entire packet has been // written to the destination. // // If only a portion of the packet has been written, Write will return a non-nil error as well as the number of bytes // written (< len(p)). Write(b []byte) (int, error) // MTU returns the size of the Maximum Transmission Unit for this device, which is the maximum size of a single IP // packet that can be received/sent. MTU() int }
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 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 PacketListenerProxy ¶
type PacketListenerProxy struct {
// contains filtered or unexported fields
}
func NewPacketProxyFromPacketListener ¶
func NewPacketProxyFromPacketListener(pl transport.PacketListener, options ...func(*PacketListenerProxy) error) (*PacketListenerProxy, error)
NewPacketProxyFromPacketListener creates a new PacketProxy that uses the existing transport.PacketListener to create connections to a proxy. You can also specify additional options. This function is useful if you already have an implementation of transport.PacketListener and you want to use it with one of the network stacks (for example, network/lwip2transport) as a UDP traffic handler.
func (*PacketListenerProxy) NewSession ¶
func (proxy *PacketListenerProxy) NewSession(respWriter PacketResponseReceiver) (PacketRequestSender, error)
NewSession implements PacketProxy.NewSession function. It uses transport.PacketListener.ListenPacket to create a net.PacketConn, and constructs a new PacketRequestSender that is based on this net.PacketConn.
type 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. NewSession(PacketResponseReceiver) (PacketRequestSender, error) }
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 can simultaneously invoke methods on a PacketProxy.
type 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 // ignored. WriteTo 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 WriteTo returns. WriteTo(p []byte, destination netip.AddrPort) (int, error) // Close indicates that the sender is no longer accepting new requests. Any future attempts to call WriteTo on the // sender will fail with ErrClosed. Close() error }
PacketRequestSender sends UDP request packets to the PacketProxy. It should be implemented by the PacketProxy, 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 can simultaneously invoke methods on a PacketRequestSender.
type 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 // 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. WriteFrom(p []byte, source net.Addr) (int, error) // Close indicates that the receiver is no longer accepting new responses. Any future attempts to call WriteFrom on // the receiver will fail with ErrClosed. Close() error }
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 can simultaneously invoke methods on a PacketResponseReceiver.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package dnstruncate functions as an alternative implementation that handles DNS requests if the remote server doesn't support UDP traffic.
|
Package dnstruncate functions as an alternative implementation that handles DNS requests if the remote server doesn't support UDP traffic. |
The network/lwip2transport package translates between IP packets and TCP/UDP protocols.
|
The network/lwip2transport package translates between IP packets and TCP/UDP protocols. |