inbound

package
v1.0.48 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: Apache-2.0 Imports: 32 Imported by: 0

Documentation

Overview

Package inbound is the loft client listener: SOCKS5, userspace TUN (ICMP/UDP/TCP), Darwin/Linux DNS and routes, optional overlay IPv6.

"Inbound" means where local traffic enters the client: apps either talk to the SOCKS5 proxy (socks5.go) or the system routes their packets into a TUN, a virtual network interface (this file). Both hand the traffic to a transport.Dialer, the live session to the loft node. The overlay is the private network the node gives its members, with addresses like 10.7.0.x.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AcceptTUNFD

func AcceptTUNFD(ln net.Listener) (int, string, error)

AcceptTUNFD closes ln and fails: there is no helper to receive an fd from.

func EnableLANReturn added in v1.0.33

func EnableLANReturn(tun, mode string) (func(), error)

EnableLANReturn installs the rule and the table for the route mode on the TUN named tun and returns the undo. The next hop is the current IPv4 default route of the container (the router's side of the veth).

Only for a dedicated gateway (a router's container): on a general Linux host with IP forwarding on, the rule would let overlay members route through this machine. That is why it runs only with listen.gateway: route.

mode is listen.gateway: "route" installs both rules, "nat" only the one for the container's own address.

func JoinDNS

func JoinDNS(ips []net.IP) string

JoinDNS is comma-separated IPv4 for STATUS and logs.

func ListenSOCKS5

func ListenSOCKS5(addr string, d transport.Dialer) (net.Listener, error)

ListenSOCKS5 accepts SOCKS5 CONNECT and UDP ASSOCIATE on addr.

func ListenTUNSock

func ListenTUNSock(path string) (net.Listener, error)

ListenTUNSock always fails here: fd passing exists only on macOS.

func OpenPacketPipe added in v1.0.31

func OpenPacketPipe(name string) (tunIO, error)

OpenPacketPipe is the Windows service pipe. Other systems use utun.

func OverlayCIDR

func OverlayCIDR(overlayIP, tunAddr string) string

OverlayCIDR is Status.IP with the prefix from tun_addr (default /24).

func PacketTUNFromFD

func PacketTUNFromFD(fd int, name string) io.ReadWriteCloser

PacketTUNFromFD returns a device whose every Read and Write fails, because a raw utun fd cannot exist on this system.

func ParseDNSList

func ParseDNSList(s string) []net.IP

ParseDNSList reads IPv4 addresses separated by comma, space, or semicolon.

func ResolveDNS

func ResolveDNS(ipcp []net.IP, peer net.IP, extra []net.IP, replace bool) []net.IP

ResolveDNS picks SSTP resolvers the way Windows RAS does: IPCP DNS if the server sent any, else the PPP gateway. extra appends to that list; extra with replace uses only extra.

func SocksOff added in v1.0.4

func SocksOff(addr string) bool

SocksOff is true when addr is empty, off, false, 0, or "-".

func WrapL3 added in v1.0.25

func WrapL3(d transport.Dialer) (transport.Dialer, error)

WrapL3 returns n wrapping d when d carries IP. d is returned unchanged otherwise.

Types

type Device

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

Device is a live TUN. Attach hooks ICMP on each new mux session (metro).

func AttachTUN added in v1.0.15

func AttachTUN(device, cidr string, d transport.Dialer) (*Device, error)

AttachTUN opens an existing TUN by name and runs the userspace stack on it. The kernel address, MTU, DNS, and routes stay with the caller (ConnMan, NetworkManager). Same packet path as StartTUN.

func StartRoutedTUN added in v1.0.33

func StartRoutedTUN(device, cidr string, d transport.Dialer) (*Device, error)

StartRoutedTUN opens a named TUN and the userspace stack, and does not install an address, a default route, a split default, or DNS. KeeneticOS owns the routing table: the device is opkgtunN and ndmc registers OpkgTunN. "auto" is refused so a desktop utun is never created by mistake.

func StartStack

func StartStack(rw io.ReadWriteCloser, name string, d transport.Dialer, overlayIP string) (*Device, error)

StartStack binds an IP packet pipe. Mux fronts get gVisor; l3 splices IP. overlayIP is Status (loft) or the synthetic VLESS address. No OS routes.

func StartTUN

func StartTUN(device, cidr string, killSwitch bool, d transport.Dialer, exclude []string) (*Device, error)

StartTUN brings up a real utun/tun, userspace stack, and optional kill-switch.

func StartTUNFromFD

func StartTUNFromFD(fd int, name string, _ transport.Dialer) (*Device, error)

StartTUNFromFD always fails here: fd passing exists only on macOS.

func StartTUNIO added in v1.0.31

func StartTUNIO(ifc tunIO, cidr string, d transport.Dialer) (*Device, error)

StartTUNIO runs the userspace stack on a device the caller already opened. Address, DNS, and routes stay with the caller. The Windows service uses this with a named pipe of IP packets in front of Wintun.

func (*Device) Attach

func (d *Device) Attach(dial transport.Dialer)

Attach hooks ICMP/UDP datagrams on the current mux session, or an L3 IP pump.

func (*Device) Close

func (d *Device) Close() error

Close undoes DNS/routes, stops the stack, and closes the TUN.

func (*Device) Name added in v1.0.33

func (d *Device) Name() string

Name is the kernel interface (opkgtun0, utun6). Empty after Close.

func (*Device) Readdress added in v1.0.33

func (d *Device) Readdress(ip string) error

Readdress moves the interface to a new overlay IP after a reconnect.

Why: the node can hand out another overlay address when the member reconnects (it restarted and lost its leases, the old address was taken, the client moved to another node). The kernel accepts a packet only when its destination is an address of the interface, so with the old address left in place every reply to the new one is dropped and the member stays cut off until the client restarts.

It keeps the prefix length the interface had and does nothing when the address is the same or not ours to change (see Device.addr).

type L3Net added in v1.0.25

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

L3Net is a Dialer that opens TCP/UDP on the L3 overlay IP.

func NewL3Net added in v1.0.25

func NewL3Net(d transport.Dialer, pump transport.IPPump) (*L3Net, error)

NewL3Net binds a gVisor IPv4 stack to pump and starts the packet pump.

func (*L3Net) AttachTUN added in v1.0.25

func (n *L3Net) AttachTUN(tun io.ReadWriteCloser)

AttachTUN splices kernel utun packets with the L3 pump.

func (*L3Net) Close added in v1.0.25

func (n *L3Net) Close() error

Close shuts L3Net down for good. Readers waiting for a new pump are woken so they see Done and exit.

Steps:

  1. Stop stackOut and the gVisor stack.
  2. Close the attached TUN, which also ends fromTUN.
  3. Drop the pump and wake everyone blocked on the old wait channel.
  4. Close the front's Dialer, then close Done.

func (*L3Net) ConnBytes added in v1.0.25

func (n *L3Net) ConnBytes() (uint64, uint64)

ConnBytes is the IP bytes sent (up) and received (down) through the pump.

func (*L3Net) Done added in v1.0.25

func (n *L3Net) Done() <-chan struct{}

Done is closed when L3Net is closed.

func (*L3Net) ListenUDP added in v1.0.25

func (n *L3Net) ListenUDP() (net.PacketConn, error)

ListenUDP binds one unconnected UDP socket on the overlay.

func (*L3Net) LookupIP4 added in v1.0.25

func (n *L3Net) LookupIP4(host string) (net.IP, error)

LookupIP4 resolves host through the host resolver (debug path).

func (*L3Net) Open added in v1.0.25

func (n *L3Net) Open(target string) (net.Conn, error)

Open dials TCP on the overlay toward target (host:port).

func (*L3Net) Session added in v1.0.25

func (n *L3Net) Session() *mux.Session

Session is nil: an L3 front carries IP, not a mux session.

func (*L3Net) Stats added in v1.0.33

func (n *L3Net) Stats() L3NetStats

Stats returns the counters since this L3Net started.

func (*L3Net) Swap added in v1.0.25

func (n *L3Net) Swap(d transport.Dialer, pump transport.IPPump)

Swap replaces the CONNECT pump. gVisor, SOCKS, and TUN stay.

type L3NetStats added in v1.0.33

type L3NetStats struct {
	Dropped, Orphan, Retransmits, Timeouts, FastRetransmits uint64
	// SendErrors are segments the stack could not hand to the link (a full
	// link queue); TLP and SpuriousRTO count tail-loss probes and timeouts
	// that turned out needless.
	SendErrors, TLP, SpuriousRTO uint64
}

L3NetStats are drop and retransmission counters of an L3Net, for debugging lost packets on the l3 front: Dropped is packets the gVisor stack threw away (mostly a full receive queue of a socket), Orphan packets from the tunnel that no socket owned, and Retransmits, Timeouts and FastRetransmits what the stack had to send again toward the node.

type SSTPNet

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

SSTPNet is a transport.Dialer that opens TCP/UDP on the SSTP overlay IP.

func NewSSTPNet

func NewSSTPNet(sess *sstp.Session) (*SSTPNet, error)

NewSSTPNet binds a gVisor IPv4 stack to sess and starts the packet pump.

func (*SSTPNet) ApplyDNS

func (n *SSTPNet) ApplyDNS(extra []net.IP, replace bool)

ApplyDNS sets resolvers: IPCP, else the PPP peer, plus extra. replace with a non-empty extra list skips IPCP and the gateway.

func (*SSTPNet) AttachTUN

func (n *SSTPNet) AttachTUN(tun io.ReadWriteCloser)

AttachTUN splices kernel utun packets with the SSTP session (L3).

func (*SSTPNet) Bytes

func (n *SSTPNet) Bytes() (up, down uint64)

Bytes is overlay IP octets written (up) and read (down) on the PPP session.

func (*SSTPNet) Close

func (n *SSTPNet) Close() error

Close stops the packet goroutines and the stack, closes the attached TUN, and closes Done. It is safe to call more than once.

func (*SSTPNet) DNS

func (n *SSTPNet) DNS() []net.IP

DNS is the resolver list SOCKS/TUN name lookup will use.

func (*SSTPNet) DialUDP

func (n *SSTPNet) DialUDP(addr string) (net.Conn, error)

DialUDP opens one connected UDP socket on the SSTP overlay (SOCKS UDP ASSOCIATE).

func (*SSTPNet) Done

func (n *SSTPNet) Done() <-chan struct{}

Done is closed when the SSTP session ends and the Dialer must be replaced.

func (*SSTPNet) ListenUDP

func (n *SSTPNet) ListenUDP() (net.PacketConn, error)

ListenUDP binds one unconnected UDP socket on the overlay (SOCKS UDP ASSOCIATE).

func (*SSTPNet) LookupIP4

func (n *SSTPNet) LookupIP4(host string) (net.IP, error)

LookupIP4 resolves host through the SSTP DNS servers.

func (*SSTPNet) Open

func (n *SSTPNet) Open(target string) (net.Conn, error)

Open makes a TCP connection to target ("host:port") from the SSTP address. A host name is resolved through the SSTP DNS servers first. Only IPv4 is supported. Each connection reserves a local port so incoming packets for it can be told apart from TUN traffic (see stackOwns). The dial gives up after 20 seconds.

func (*SSTPNet) OverlayIP

func (n *SSTPNet) OverlayIP() net.IP

OverlayIP is the SSTP-assigned IPv4.

func (*SSTPNet) Session

func (n *SSTPNet) Session() *mux.Session

Session is nil: SSTP carries plain IP, not a loft mux session.

func (*SSTPNet) SetLog

func (n *SSTPNet) SetLog(fn func(string, ...any))

SetLog prints stack/DNS/TCP traces (loft-front -v, loft-probe -v).

func (*SSTPNet) SetTap

func (n *SSTPNet) SetTap(fn func([]byte))

SetTap sees every inbound IP before demux (ICMP probes).

type SocksGate added in v1.0.4

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

SocksGate holds the current SOCKS5 listener. Set replaces it; a bind error leaves the previous listener running.

func NewSocksGate added in v1.0.4

func NewSocksGate(d transport.Dialer) *SocksGate

NewSocksGate serves SOCKS5 through d. No listen until Set.

func (*SocksGate) Addr added in v1.0.4

func (g *SocksGate) Addr() string

Addr is the current listen address, or empty.

func (*SocksGate) Close added in v1.0.4

func (g *SocksGate) Close() error

Close drops the listener. In-flight SOCKS clients keep the Dialer.

func (*SocksGate) Set added in v1.0.4

func (g *SocksGate) Set(addr string) (bound string, err error)

Set binds addr (host:port). Empty/off closes the listener. On bind failure the previous listen stays up.

Jump to

Keyboard shortcuts

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