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 ¶
- func AcceptTUNFD(ln net.Listener) (int, string, error)
- func EnableLANReturn(tun, mode string) (func(), error)
- func JoinDNS(ips []net.IP) string
- func ListenSOCKS5(addr string, d transport.Dialer) (net.Listener, error)
- func ListenTUNSock(path string) (net.Listener, error)
- func OpenPacketPipe(name string) (tunIO, error)
- func OverlayCIDR(overlayIP, tunAddr string) string
- func PacketTUNFromFD(fd int, name string) io.ReadWriteCloser
- func ParseDNSList(s string) []net.IP
- func ResolveDNS(ipcp []net.IP, peer net.IP, extra []net.IP, replace bool) []net.IP
- func SocksOff(addr string) bool
- func WrapL3(d transport.Dialer) (transport.Dialer, error)
- type Device
- func AttachTUN(device, cidr string, d transport.Dialer) (*Device, error)
- func StartRoutedTUN(device, cidr string, d transport.Dialer) (*Device, error)
- func StartStack(rw io.ReadWriteCloser, name string, d transport.Dialer, overlayIP string) (*Device, error)
- func StartTUN(device, cidr string, killSwitch bool, d transport.Dialer, exclude []string) (*Device, error)
- func StartTUNFromFD(fd int, name string, _ transport.Dialer) (*Device, error)
- func StartTUNIO(ifc tunIO, cidr string, d transport.Dialer) (*Device, error)
- type L3Net
- func (n *L3Net) AttachTUN(tun io.ReadWriteCloser)
- func (n *L3Net) Close() error
- func (n *L3Net) ConnBytes() (uint64, uint64)
- func (n *L3Net) Done() <-chan struct{}
- func (n *L3Net) ListenUDP() (net.PacketConn, error)
- func (n *L3Net) LookupIP4(host string) (net.IP, error)
- func (n *L3Net) Open(target string) (net.Conn, error)
- func (n *L3Net) Session() *mux.Session
- func (n *L3Net) Stats() L3NetStats
- func (n *L3Net) Swap(d transport.Dialer, pump transport.IPPump)
- type L3NetStats
- type SSTPNet
- func (n *SSTPNet) ApplyDNS(extra []net.IP, replace bool)
- func (n *SSTPNet) AttachTUN(tun io.ReadWriteCloser)
- func (n *SSTPNet) Bytes() (up, down uint64)
- func (n *SSTPNet) Close() error
- func (n *SSTPNet) DNS() []net.IP
- func (n *SSTPNet) DialUDP(addr string) (net.Conn, error)
- func (n *SSTPNet) Done() <-chan struct{}
- func (n *SSTPNet) ListenUDP() (net.PacketConn, error)
- func (n *SSTPNet) LookupIP4(host string) (net.IP, error)
- func (n *SSTPNet) Open(target string) (net.Conn, error)
- func (n *SSTPNet) OverlayIP() net.IP
- func (n *SSTPNet) Session() *mux.Session
- func (n *SSTPNet) SetLog(fn func(string, ...any))
- func (n *SSTPNet) SetTap(fn func([]byte))
- type SocksGate
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AcceptTUNFD ¶
AcceptTUNFD closes ln and fails: there is no helper to receive an fd from.
func EnableLANReturn ¶ added in v1.0.33
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 ListenSOCKS5 ¶
ListenSOCKS5 accepts SOCKS5 CONNECT and UDP ASSOCIATE on addr.
func ListenTUNSock ¶
ListenTUNSock always fails here: fd passing exists only on macOS.
func OpenPacketPipe ¶ added in v1.0.31
OpenPacketPipe is the Windows service pipe. Other systems use utun.
func OverlayCIDR ¶
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 ¶
ParseDNSList reads IPv4 addresses separated by comma, space, or semicolon.
func ResolveDNS ¶
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.
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
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
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 ¶
StartTUNFromFD always fails here: fd passing exists only on macOS.
func StartTUNIO ¶ added in v1.0.31
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 ¶
Attach hooks ICMP/UDP datagrams on the current mux session, or an L3 IP pump.
func (*Device) Name ¶ added in v1.0.33
Name is the kernel interface (opkgtun0, utun6). Empty after Close.
func (*Device) Readdress ¶ added in v1.0.33
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
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
Close shuts L3Net down for good. Readers waiting for a new pump are woken so they see Done and exit.
Steps:
- Stop stackOut and the gVisor stack.
- Close the attached TUN, which also ends fromTUN.
- Drop the pump and wake everyone blocked on the old wait channel.
- Close the front's Dialer, then close Done.
func (*L3Net) ConnBytes ¶ added in v1.0.25
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
LookupIP4 resolves host through the host resolver (debug path).
func (*L3Net) Stats ¶ added in v1.0.33
func (n *L3Net) Stats() L3NetStats
Stats returns the counters since this L3Net started.
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 ¶
NewSSTPNet binds a gVisor IPv4 stack to sess and starts the packet pump.
func (*SSTPNet) ApplyDNS ¶
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) Close ¶
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) DialUDP ¶
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) Open ¶
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.
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
NewSocksGate serves SOCKS5 through d. No listen until Set.