netstack2

package
v1.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 3, 2026 License: AGPL-3.0 Imports: 41 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AccessLogger added in v1.11.0

type AccessLogger struct {
	// contains filtered or unexported fields
}

AccessLogger tracks access sessions for resources and periodically flushes completed sessions to the server via a configurable SendFunc.

func NewAccessLogger added in v1.11.0

func NewAccessLogger(udpTimeout time.Duration) *AccessLogger

NewAccessLogger creates a new access logger. udpTimeout controls how long a UDP session is kept alive without traffic before being ended.

func (*AccessLogger) Close added in v1.11.0

func (al *AccessLogger) Close()

Close shuts down the background loop, ends all active sessions, and performs one final flush to send everything to the server.

func (*AccessLogger) EndTCPSession added in v1.11.0

func (al *AccessLogger) EndTCPSession(sessionID string)

EndTCPSession logs the end of a TCP session and queues it for sending.

func (*AccessLogger) EndUDPSession added in v1.11.0

func (al *AccessLogger) EndUDPSession(sessionID string)

EndUDPSession ends a UDP session and queues it for sending.

func (*AccessLogger) SetSendFunc added in v1.11.0

func (al *AccessLogger) SetSendFunc(fn SendFunc)

SetSendFunc sets the callback used to send compressed access log batches to the server. This can be called after construction once the websocket client is available.

func (*AccessLogger) StartTCPSession added in v1.11.0

func (al *AccessLogger) StartTCPSession(resourceID int, srcAddr, dstAddr string) string

StartTCPSession logs the start of a TCP session and returns a session ID.

func (*AccessLogger) TrackUDPSession added in v1.11.0

func (al *AccessLogger) TrackUDPSession(resourceID int, srcAddr, dstAddr string) string

TrackUDPSession starts or returns an existing UDP session. Returns the session ID.

type AccessSession added in v1.11.0

type AccessSession struct {
	SessionID       string    `json:"sessionId"`
	ResourceID      int       `json:"resourceId"`
	SourceAddr      string    `json:"sourceAddr"`
	DestAddr        string    `json:"destAddr"`
	Protocol        string    `json:"protocol"`
	StartedAt       time.Time `json:"startedAt"`
	EndedAt         time.Time `json:"endedAt,omitempty"`
	BytesTx         int64     `json:"bytesTx"`
	BytesRx         int64     `json:"bytesRx"`
	ConnectionCount int       `json:"connectionCount,omitempty"` // number of raw connections merged into this session (0 or 1 = single)
}

AccessSession represents a tracked access session through the proxy

type ICMPHandler

type ICMPHandler struct {
	// contains filtered or unexported fields
}

ICMPHandler handles ICMP packets from netstack

func NewICMPHandler

func NewICMPHandler(s *stack.Stack, ph *ProxyHandler) *ICMPHandler

NewICMPHandler creates a new ICMP handler

func (*ICMPHandler) InstallICMPHandler

func (h *ICMPHandler) InstallICMPHandler() error

InstallICMPHandler installs the ICMP handler on the stack

type Net

type Net netTun

func CreateNetTUN

func CreateNetTUN(localAddresses, dnsServers []netip.Addr, mtu int) (tun.Device, *Net, error)

CreateNetTUN creates a new TUN device with netstack without proxying

func CreateNetTUNWithOptions

func CreateNetTUNWithOptions(localAddresses, dnsServers []netip.Addr, mtu int, options NetTunOptions) (tun.Device, *Net, error)

CreateNetTUNWithOptions creates a new TUN device with netstack and optional TCP/UDP proxying

func (*Net) AddProxySubnetRule

func (net *Net) AddProxySubnetRule(sourcePrefix, destPrefix netip.Prefix, rewriteTo string, portRanges []PortRange, disableIcmp bool, resourceId int)

AddProxySubnetRule adds a subnet rule to the proxy handler If portRanges is nil or empty, all ports are allowed for this subnet rewriteTo can be either an IP/CIDR (e.g., "192.168.1.1/32") or a domain name (e.g., "example.com")

func (*Net) Dial

func (tnet *Net) Dial(network, address string) (net.Conn, error)

func (*Net) DialContext

func (tnet *Net) DialContext(ctx context.Context, network, address string) (net.Conn, error)

func (*Net) DialContextTCP

func (net *Net) DialContextTCP(ctx context.Context, addr *net.TCPAddr) (*gonet.TCPConn, error)

func (*Net) DialContextTCPAddrPort

func (net *Net) DialContextTCPAddrPort(ctx context.Context, addr netip.AddrPort) (*gonet.TCPConn, error)

func (*Net) DialPing

func (net *Net) DialPing(laddr, raddr *PingAddr) (*PingConn, error)

func (*Net) DialPingAddr

func (net *Net) DialPingAddr(laddr, raddr netip.Addr) (*PingConn, error)

func (*Net) DialTCP

func (net *Net) DialTCP(addr *net.TCPAddr) (*gonet.TCPConn, error)

func (*Net) DialTCPAddrPort

func (net *Net) DialTCPAddrPort(addr netip.AddrPort) (*gonet.TCPConn, error)

func (*Net) DialUDP

func (net *Net) DialUDP(laddr, raddr *net.UDPAddr) (*gonet.UDPConn, error)

func (*Net) DialUDPAddrPort

func (net *Net) DialUDPAddrPort(laddr, raddr netip.AddrPort) (*gonet.UDPConn, error)

func (*Net) GetProxyHandler

func (net *Net) GetProxyHandler() *ProxyHandler

GetProxyHandler returns the proxy handler (for advanced use cases) Returns nil if proxy is not enabled

func (*Net) GetProxySubnetRules added in v1.11.0

func (net *Net) GetProxySubnetRules() []SubnetRule

GetProxySubnetRules returns all subnet rules from the proxy handler

func (*Net) ListenPing

func (net *Net) ListenPing(laddr *PingAddr) (*PingConn, error)

func (*Net) ListenPingAddr

func (net *Net) ListenPingAddr(laddr netip.Addr) (*PingConn, error)

func (*Net) ListenTCP

func (net *Net) ListenTCP(addr *net.TCPAddr) (*gonet.TCPListener, error)

func (*Net) ListenTCPAddrPort

func (net *Net) ListenTCPAddrPort(addr netip.AddrPort) (*gonet.TCPListener, error)

func (*Net) ListenUDP

func (net *Net) ListenUDP(laddr *net.UDPAddr) (*gonet.UDPConn, error)

func (*Net) ListenUDPAddrPort

func (net *Net) ListenUDPAddrPort(laddr netip.AddrPort) (*gonet.UDPConn, error)

func (*Net) LookupContextHost

func (tnet *Net) LookupContextHost(ctx context.Context, host string) ([]string, error)

func (*Net) LookupHost

func (net *Net) LookupHost(host string) (addrs []string, err error)

func (*Net) RemoveProxySubnetRule

func (net *Net) RemoveProxySubnetRule(sourcePrefix, destPrefix netip.Prefix)

RemoveProxySubnetRule removes a subnet rule from the proxy handler

func (*Net) SetAccessLogSender added in v1.11.0

func (net *Net) SetAccessLogSender(fn SendFunc)

SetAccessLogSender configures the function used to send compressed access log batches to the server. This should be called once the websocket client is available.

type NetTunOptions

type NetTunOptions struct {
	EnableTCPProxy  bool
	EnableUDPProxy  bool
	EnableICMPProxy bool
}

NetTunOptions contains options for creating a NetTUN device

type PingAddr

type PingAddr struct {
	// contains filtered or unexported fields
}

func PingAddrFromAddr

func PingAddrFromAddr(addr netip.Addr) *PingAddr

func (PingAddr) Addr

func (ia PingAddr) Addr() netip.Addr

func (PingAddr) Network

func (ia PingAddr) Network() string

func (PingAddr) String

func (ia PingAddr) String() string

type PingConn

type PingConn struct {
	// contains filtered or unexported fields
}

func (*PingConn) Close

func (pc *PingConn) Close() error

func (*PingConn) LocalAddr

func (pc *PingConn) LocalAddr() net.Addr

func (*PingConn) Read

func (pc *PingConn) Read(p []byte) (n int, err error)

func (*PingConn) ReadFrom

func (pc *PingConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)

func (*PingConn) RemoteAddr

func (pc *PingConn) RemoteAddr() net.Addr

func (*PingConn) SetDeadline

func (pc *PingConn) SetDeadline(t time.Time) error

func (*PingConn) SetReadDeadline

func (pc *PingConn) SetReadDeadline(t time.Time) error

func (*PingConn) SetWriteDeadline

func (pc *PingConn) SetWriteDeadline(t time.Time) error

func (*PingConn) Write

func (pc *PingConn) Write(p []byte) (n int, err error)

func (*PingConn) WriteTo

func (pc *PingConn) WriteTo(p []byte, addr net.Addr) (n int, err error)

type PortRange

type PortRange struct {
	Min      uint16
	Max      uint16
	Protocol string // "tcp", "udp", or "" for both
}

PortRange represents an allowed range of ports (inclusive) with optional protocol filtering Protocol can be "tcp", "udp", or "" (empty string means both protocols)

type ProxyHandler

type ProxyHandler struct {
	// contains filtered or unexported fields
}

ProxyHandler handles packet injection and extraction for promiscuous mode

func NewProxyHandler

func NewProxyHandler(options ProxyHandlerOptions) (*ProxyHandler, error)

NewProxyHandler creates a new proxy handler for promiscuous mode

func (*ProxyHandler) AddSubnetRule

func (p *ProxyHandler) AddSubnetRule(sourcePrefix, destPrefix netip.Prefix, rewriteTo string, portRanges []PortRange, disableIcmp bool, resourceId int)

AddSubnetRule adds a subnet with optional port restrictions to the proxy handler sourcePrefix: The IP prefix of the peer sending the data destPrefix: The IP prefix of the destination rewriteTo: Optional address to rewrite destination to - can be IP/CIDR or domain name If portRanges is nil or empty, all ports are allowed for this subnet

func (*ProxyHandler) Close

func (p *ProxyHandler) Close() error

Close cleans up the proxy handler resources

func (*ProxyHandler) GetAccessLogger added in v1.11.0

func (p *ProxyHandler) GetAccessLogger() *AccessLogger

GetAccessLogger returns the access logger for session tracking

func (*ProxyHandler) GetAllRules added in v1.11.0

func (p *ProxyHandler) GetAllRules() []SubnetRule

GetAllRules returns all subnet rules from the proxy handler

func (*ProxyHandler) HandleIncomingPacket

func (p *ProxyHandler) HandleIncomingPacket(packet []byte) bool

HandleIncomingPacket processes incoming packets and determines if they should be injected into the proxy stack

func (*ProxyHandler) Initialize

func (p *ProxyHandler) Initialize(notifiable channel.Notification) error

Initialize sets up the promiscuous NIC with the netTun's notification system

func (*ProxyHandler) LookupDestinationRewrite

func (p *ProxyHandler) LookupDestinationRewrite(srcIP, dstIP string, dstPort uint16, proto uint8) (netip.Addr, bool)

LookupDestinationRewrite looks up the rewritten destination for a connection This is used by TCP/UDP handlers to find the actual target address

func (*ProxyHandler) LookupResourceId added in v1.11.0

func (p *ProxyHandler) LookupResourceId(srcIP, dstIP string, dstPort uint16, proto uint8) int

LookupResourceId looks up the resource ID for a connection Returns 0 if no resource ID is associated with this connection

func (*ProxyHandler) QueueICMPReply

func (p *ProxyHandler) QueueICMPReply(packet []byte) bool

QueueICMPReply queues an ICMP reply packet to be sent back through the tunnel

func (*ProxyHandler) ReadOutgoingPacket

func (p *ProxyHandler) ReadOutgoingPacket() *buffer.View

ReadOutgoingPacket reads packets from the proxy stack that need to be sent back through the tunnel

func (*ProxyHandler) RemoveSubnetRule

func (p *ProxyHandler) RemoveSubnetRule(sourcePrefix, destPrefix netip.Prefix)

RemoveSubnetRule removes a subnet from the proxy handler

func (*ProxyHandler) SetAccessLogSender added in v1.11.0

func (p *ProxyHandler) SetAccessLogSender(fn SendFunc)

SetAccessLogSender configures the function used to send compressed access log batches to the server. This should be called once the websocket client is available.

type ProxyHandlerOptions

type ProxyHandlerOptions struct {
	EnableTCP  bool
	EnableUDP  bool
	EnableICMP bool
	MTU        int
}

ProxyHandlerOptions configures the proxy handler

type SendFunc added in v1.11.0

type SendFunc func(data string) error

SendFunc is a callback that sends compressed access log data to the server. The data is a base64-encoded zlib-compressed JSON array of AccessSession objects.

type SubnetLookup

type SubnetLookup struct {
	// contains filtered or unexported fields
}

SubnetLookup provides fast IP subnet and port matching using BART (Binary Aggregated Range Tree) This uses BART Table for O(log n) prefix matching with Supernets() for efficient lookups

Architecture: - Two-level BART structure for matching both source AND destination prefixes - Level 1: Source prefix -> Level 2 (destination prefix -> rules) - This reduces search space: only check destination prefixes for matching source prefixes

func NewSubnetLookup

func NewSubnetLookup() *SubnetLookup

NewSubnetLookup creates a new subnet lookup table using BART

func (*SubnetLookup) AddSubnet

func (sl *SubnetLookup) AddSubnet(sourcePrefix, destPrefix netip.Prefix, rewriteTo string, portRanges []PortRange, disableIcmp bool, resourceId int)

AddSubnet adds a subnet rule with source and destination prefixes and optional port restrictions If portRanges is nil or empty, all ports are allowed for this subnet rewriteTo can be either an IP/CIDR (e.g., "192.168.1.1/32") or a domain name (e.g., "example.com")

func (*SubnetLookup) GetAllRules added in v1.11.0

func (sl *SubnetLookup) GetAllRules() []SubnetRule

GetAllRules returns a copy of all subnet rules

func (*SubnetLookup) Match

func (sl *SubnetLookup) Match(srcIP, dstIP netip.Addr, port uint16, proto tcpip.TransportProtocolNumber) *SubnetRule

Match checks if a source IP, destination IP, port, and protocol match any subnet rule Returns the matched rule if ALL of these conditions are met:

  • The source IP is in the rule's source prefix
  • The destination IP is in the rule's destination prefix
  • The port is in an allowed range (or no port restrictions exist)
  • The protocol matches (or the port range allows both protocols)

proto should be header.TCPProtocolNumber, header.UDPProtocolNumber, or header.ICMPv4ProtocolNumber Returns nil if no rule matches This uses BART's Supernets() for O(log n) prefix matching instead of O(n) iteration

func (*SubnetLookup) RemoveSubnet

func (sl *SubnetLookup) RemoveSubnet(sourcePrefix, destPrefix netip.Prefix)

RemoveSubnet removes a subnet rule from the lookup table

type SubnetRule

type SubnetRule struct {
	SourcePrefix netip.Prefix // Source IP prefix (who is sending)
	DestPrefix   netip.Prefix // Destination IP prefix (where it's going)
	DisableIcmp  bool         // If true, ICMP traffic is blocked for this subnet
	RewriteTo    string       // Optional rewrite address for DNAT - can be IP/CIDR or domain name
	PortRanges   []PortRange  // empty slice means all ports allowed
	ResourceId   int          // Optional resource ID from the server for access logging
}

SubnetRule represents a subnet with optional port restrictions and source address When RewriteTo is set, DNAT (Destination Network Address Translation) is performed:

  • Incoming packets: destination IP is rewritten to the resolved RewriteTo address
  • Outgoing packets: source IP is rewritten back to the original destination

RewriteTo can be either:

  • An IP address with CIDR notation (e.g., "192.168.1.1/32")
  • A domain name (e.g., "example.com") which will be resolved at request time

This allows transparent proxying where traffic appears to come from the rewritten address

type TCPHandler

type TCPHandler struct {
	// contains filtered or unexported fields
}

TCPHandler handles TCP connections from netstack

func NewTCPHandler

func NewTCPHandler(s *stack.Stack, ph *ProxyHandler) *TCPHandler

NewTCPHandler creates a new TCP handler

func (*TCPHandler) InstallTCPHandler

func (h *TCPHandler) InstallTCPHandler() error

InstallTCPHandler installs the TCP forwarder on the stack

type UDPHandler

type UDPHandler struct {
	// contains filtered or unexported fields
}

UDPHandler handles UDP connections from netstack

func NewUDPHandler

func NewUDPHandler(s *stack.Stack, ph *ProxyHandler) *UDPHandler

NewUDPHandler creates a new UDP handler

func (*UDPHandler) InstallUDPHandler

func (h *UDPHandler) InstallUDPHandler() error

InstallUDPHandler installs the UDP forwarder on the stack

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL