vtun

package
v0.8.1 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: MIT Imports: 36 Imported by: 0

Documentation

Overview

Package vtun provides a virtual tunnel implementation built on gVisor's netstack. It creates userspace network interfaces that support TCP, UDP, and ICMP, with built-in DNS resolution. TCP name dials use a dual-stack connection race so an unavailable address family does not block a usable address from the other family.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Opts

type Opts struct {
	// EndpointCh specifies the size of the endpoint channel buffer. Defaults to 1024.
	EndpointCh int
	// EventCh specifies the size of the event channel buffer. Defaults to 10.
	EventCh int

	// LocalAddrs contains the local IP addresses to assign to the tunnel.
	// If not provided, a random address from rarely used subnets will be generated.
	LocalAddrs []netip.Addr
	// SourceRoutes selects a local source address from the remote destination.
	// Routes are independent for IPv4 and IPv6, and the longest prefix wins.
	// A family with source routes has no implicit default route.
	SourceRoutes []SourceRoute
	// DnsServers contains the DNS servers to use for name resolution.
	// Default: 8.8.8.8, 8.8.4.4, 1.1.1.1, 1.0.0.1, 9.9.9.9
	DnsServers []netip.Addr
	// Lookup provides a custom DNS lookup function.
	// If not set, uses the built-in simple DNS resolver.
	Lookup gonnect.LookupIP
	// TCPFallbackDelay is the time that Dial and DialTCP wait before they
	// start the next resolved TCP candidate. The default is 250 ms. A negative
	// value disables timed fallback, but a definitive failure still starts the
	// next candidate immediately.
	TCPFallbackDelay time.Duration

	// Name specifies the name of the tunnel interface. Default: "vtun".
	Name string

	// NoLoopbackAddr prevents adding loopback addresses (127.0.0.1 and ::1) to the
	// local addresses. This is useful when using the spoofer to prevent "martian
	// packet" errors when the stack chooses a loopback address as the source.
	NoLoopbackAddr bool

	// NetStackOpts provides additional netstack configuration options.
	NetStackOpts *helpers.Opts

	MWO, MRO int
}

Opts contains configuration options for creating a VTun virtual tunnel.

func (*Opts) Build

func (o *Opts) Build() (*VTun, error)

Build creates and initializes a new VTun virtual tunnel with the configured options. It sets up the network stack, creates a NIC, adds protocol addresses, and sets up routing for IPv4 and/or IPv6. Returns the initialized VTun instance or an error.

type PingAddr

type PingAddr struct {
	netip.Addr
}

PingAddr represents an ICMP ping address.

func (PingAddr) Network

func (ia PingAddr) Network() string

Network returns the network type for the ping address (ping4 or ping6).

func (PingAddr) String

func (ia PingAddr) String() string

String returns the string representation of the ping address.

type PingConn

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

PingConn sends ICMP Echo Request messages and reads Echo Reply payloads.

func (*PingConn) Close

func (pc *PingConn) Close() error

Close closes the ping connection.

func (*PingConn) LocalAddr

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

LocalAddr returns the local address of the ping connection.

func (*PingConn) Read

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

Read reads an ICMP Echo Reply payload.

func (*PingConn) ReadFrom

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

ReadFrom reads an ICMP Echo Reply payload and returns the remote address.

func (*PingConn) RemoteAddr

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

RemoteAddr returns the remote address of the ping connection.

func (*PingConn) SetDeadline

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

SetDeadline sets both read and write deadlines for the ping connection.

func (*PingConn) SetReadDeadline

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

SetReadDeadline sets the read deadline for the ping connection.

func (*PingConn) SetWriteDeadline

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

SetWriteDeadline sets the write deadline for the ping connection (unimplemented).

func (*PingConn) Write

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

Write sends p as the payload of an ICMP Echo Request to the remote address.

func (*PingConn) WriteTo

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

WriteTo sends p as the payload of an ICMP Echo Request to addr.

type SourceRoute added in v0.6.0

type SourceRoute struct {
	// Destination is the remote prefix that selects Source. VTun masks this
	// prefix before it compares or installs the route.
	Destination netip.Prefix
	// Source is an address from Opts.LocalAddrs.
	Source netip.Addr
}

SourceRoute selects a preferred local source address for a destination prefix. VTun uses the route with the longest matching destination prefix.

Example (DualStack)
package main

import (
	"fmt"
	"net/netip"

	"github.com/asciimoth/gonnect-netstack/vtun"
)

func main() {
	options := vtun.Opts{
		LocalAddrs: []netip.Addr{
			netip.MustParseAddr("10.0.0.2"),
			netip.MustParseAddr("2001:db8::2"),
		},
		SourceRoutes: []vtun.SourceRoute{
			{Destination: netip.MustParsePrefix("0.0.0.0/0"), Source: netip.MustParseAddr("10.0.0.2")},
			{Destination: netip.MustParsePrefix("::/0"), Source: netip.MustParseAddr("2001:db8::2")},
		},
	}
	fmt.Println(len(options.SourceRoutes))
}
Output:
2

type VTun

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

VTun represents a virtual tunnel network interface built on gVisor's netstack. It provides TCP/UDP dialing and listening capabilities, DNS resolution, ICMP ping support, and implements the gonnect Network and Resolver interfaces. It was originally borrowed from wireguard-go and then significantly modified to fit the gonnect ecosystem.

func (*VTun) BatchSize

func (vt *VTun) BatchSize() int

BatchSize returns the preferred number of packets that can be read or written in a single call. For netTun, this is always 1.

func (*VTun) Close

func (vt *VTun) Close() error

Close closes the netTun device by removing the NIC, closing the stack, removing notifications, closing the endpoint, and closing the channels.

func (*VTun) Dial

func (vt *VTun) Dial(
	ctx context.Context,
	network, address string,
) (net.Conn, error)

Dial connects to address through the VTun. TCP names use the same dual-stack connection race as DialTCP. UDP behavior is unchanged.

func (*VTun) DialPing

func (vt *VTun) DialPing(laddr, raddr *PingAddr) (*PingConn, error)

DialPing creates an ICMP ping connection with the specified local and remote PingAddr.

func (*VTun) DialPingAddr

func (vt *VTun) DialPingAddr(laddr, raddr netip.Addr) (*PingConn, error)

DialPingAddr creates an ICMP ping connection with the specified local and remote addresses. Writes send Echo Request messages. Reads return Echo Reply payloads.

func (*VTun) DialTCP

func (vt *VTun) DialTCP(
	ctx context.Context,
	network, laddr, raddr string,
) (gonnect.TCPConn, error)

DialTCP establishes a TCP connection. For a name with addresses from both IP families, it races the resolved candidates and returns the first connection that completes its TCP handshake. It starts the next candidate after TCPFallbackDelay, or immediately after a definitive failure. The caller context is the time limit for the complete race.

The tcp4 and tcp6 networks use only the requested family. An IP literal is dialed once without a DNS lookup. A specific laddr overrides the source route selected for the remote destination and also restricts the race to the local address family.

func (*VTun) DialTCPAddrPort

func (vt *VTun) DialTCPAddrPort(ctx context.Context, addr netip.AddrPort) (*gonet.TCPConn, error)

DialTCPAddrPort starts a TCP connection to a numeric address. This low-level method returns the endpoint after gVisor starts the connect operation. Use DialTCP when success must mean that the TCP handshake is complete. When a source policy is active, the destination selects the local address.

func (*VTun) DialUDP

func (vt *VTun) DialUDP(
	ctx context.Context,
	network, laddr, raddr string,
) (conn gonnect.UDPConn, err error)

func (*VTun) DialUDPAddrPort

func (vt *VTun) DialUDPAddrPort(laddr, raddr netip.AddrPort) (*gonet.UDPConn, error)

DialUDPAddrPort establishes a UDP connection with the specified local and remote addresses and ports. The connection can be used for sending and receiving UDP packets through the VTun's network stack.

func (*VTun) Down

func (vt *VTun) Down() error

func (*VTun) Events

func (vt *VTun) Events() <-chan tun.Event

Events returns the channel through which device events are communicated.

func (*VTun) File

func (vt *VTun) File() *os.File

File returns nil as the netTun device does not have an associated file descriptor.

func (*VTun) GetDnsServers

func (vt *VTun) GetDnsServers() []netip.Addr

GetDnsServers returns the list of configured DNS servers.

func (*VTun) InterfaceAddrs

func (vt *VTun) InterfaceAddrs() ([]net.Addr, error)

func (*VTun) InterfaceMulticastAddrs added in v0.4.15

func (vt *VTun) InterfaceMulticastAddrs() ([]net.Addr, error)

func (*VTun) Interfaces

func (vt *VTun) Interfaces() ([]gonnect.NetworkInterface, error)

func (*VTun) InterfacesByIndex

func (vt *VTun) InterfacesByIndex(index int) ([]gonnect.NetworkInterface, error)

func (*VTun) InterfacesByName

func (vt *VTun) InterfacesByName(name string) ([]gonnect.NetworkInterface, error)

func (*VTun) IsNative added in v0.3.9

func (vt *VTun) IsNative() bool

func (*VTun) IsUp

func (vt *VTun) IsUp() (bool, error)

IsUp returns true if the VTun is up and operational.

func (*VTun) Listen

func (vt *VTun) Listen(
	ctx context.Context,
	network, address string,
) (net.Listener, error)

func (*VTun) ListenMulticastUDP added in v0.4.15

func (vt *VTun) ListenMulticastUDP(
	ctx context.Context,
	network, address string,
	opts gonnect.MulticastOptions,
) (gonnect.MulticastPacketConn, error)

func (*VTun) ListenPacket

func (vt *VTun) ListenPacket(
	ctx context.Context,
	network, address string,
) (gonnect.PacketConn, error)

func (*VTun) ListenPacketConfig added in v0.4.15

func (vt *VTun) ListenPacketConfig(
	ctx context.Context,
	lc *gonnect.ListenConfig,
	network, address string,
) (gonnect.PacketConn, error)

func (*VTun) ListenPing

func (vt *VTun) ListenPing(laddr *PingAddr) (*PingConn, error)

ListenPing creates an ICMP ping listener bound to the specified local PingAddr.

func (*VTun) ListenPingAddr

func (vt *VTun) ListenPingAddr(laddr netip.Addr) (*PingConn, error)

ListenPingAddr creates an ICMP ping connection bound to the specified local address.

func (*VTun) ListenTCP

func (vt *VTun) ListenTCP(
	ctx context.Context,
	network, laddr string,
) (listener gonnect.TCPListener, err error)

func (*VTun) ListenTCPAddrPort

func (vt *VTun) ListenTCPAddrPort(addr netip.AddrPort) (*gonet.TCPListener, error)

ListenTCPAddrPort listens for incoming TCP connections on the specified address and port. Supports wildcard binding:

  • 0.0.0.0:port or :port binds to first local IPv4 address
  • [::]:port binds to first local IPv6 address

func (*VTun) ListenUDP

func (vt *VTun) ListenUDP(
	ctx context.Context,
	network, laddr string,
) (conn gonnect.UDPConn, err error)

func (*VTun) ListenUDPAddrPort

func (vt *VTun) ListenUDPAddrPort(laddr netip.AddrPort) (*gonet.UDPConn, error)

ListenUDPAddrPort listens for incoming UDP packets on the specified local address and port. Supports wildcard binding:

  • 0.0.0.0:port or :port binds to first local IPv4 address
  • [::]:port binds to first local IPv6 address
  • Port-only addresses (e.g., netip.AddrPortFrom(netip.IPv4Unspecified(), 53)) bind to first local address

func (*VTun) ListenUDPConfig added in v0.4.15

func (vt *VTun) ListenUDPConfig(
	ctx context.Context,
	lc *gonnect.ListenConfig,
	network, laddr string,
) (gonnect.UDPConn, error)

func (*VTun) LocalAddrs

func (vt *VTun) LocalAddrs() []netip.Addr

LocalAddrs returns a copy of the local addresses configured on this VTun. This is useful for dial operations where you need to know the VTun's address instead of using hardcoded constants.

func (*VTun) LookupAddr

func (vt *VTun) LookupAddr(ctx context.Context, addr string) (names []string, err error)

func (*VTun) LookupCNAME

func (vt *VTun) LookupCNAME(ctx context.Context, host string) (cname string, err error)

func (*VTun) LookupHost

func (vt *VTun) LookupHost(ctx context.Context, host string) ([]string, error)

LookupHost performs a DNS lookup for host and returns the addresses that the VTun protocol configuration supports. It resolves A and AAAA records in parallel when both families are enabled. The result order is not a carrier reachability decision. Dial and DialTCP schedule and race TCP candidates.

func (*VTun) LookupIP

func (vt *VTun) LookupIP(
	ctx context.Context, network, address string,
) ([]net.IP, error)

func (*VTun) LookupIPAddr

func (vt *VTun) LookupIPAddr(ctx context.Context, host string) ([]net.IPAddr, error)

func (*VTun) LookupMX

func (vt *VTun) LookupMX(
	ctx context.Context,
	name string,
) ([]*net.MX, error)

func (*VTun) LookupNS

func (vt *VTun) LookupNS(ctx context.Context, name string) ([]*net.NS, error)

func (*VTun) LookupNetIP

func (vt *VTun) LookupNetIP(
	ctx context.Context, network, host string,
) ([]netip.Addr, error)

func (*VTun) LookupPort

func (vt *VTun) LookupPort(
	ctx context.Context,
	network, service string,
) (port int, err error)

func (*VTun) LookupSRV

func (vt *VTun) LookupSRV(
	ctx context.Context,
	service, proto, name string,
) (string, []*net.SRV, error)

func (*VTun) LookupTXT

func (vt *VTun) LookupTXT(
	ctx context.Context,
	name string,
) ([]string, error)

func (*VTun) MRO added in v0.3.4

func (vt *VTun) MRO() int

func (*VTun) MTU

func (vt *VTun) MTU() (int, error)

MTU returns the maximum transmission unit of the device.

func (*VTun) MWO added in v0.3.4

func (vt *VTun) MWO() int

func (*VTun) Name

func (vt *VTun) Name() (string, error)

Name returns the name of the tun device.

func (*VTun) PacketDial added in v0.3.3

func (vt *VTun) PacketDial(
	ctx context.Context,
	network, raddr string,
) (conn gonnect.PacketConn, err error)

func (*VTun) Read

func (vt *VTun) Read(buf [][]byte, sizes []int, offset int) (int, error)

Read reads a single packet from the incomingPacket channel and writes it to the first buffer. It returns 1 for one packet read and the size of the packet.

func (*VTun) SetDnsServers

func (vt *VTun) SetDnsServers(servers []netip.Addr)

SetDnsServers configures the DNS servers to use for name resolution.

func (*VTun) SetLookup

func (vt *VTun) SetLookup(fn gonnect.LookupIP)

SetLookup sets a custom DNS lookup function for the VTun.

func (*VTun) SetMTU added in v0.6.2

func (vt *VTun) SetMTU(mtu int) error

SetMTU changes the netstack NIC MTU without replacing the VTun. It updates the value reported by MTU and emits EventMTUUpdate after a material change.

func (*VTun) SetSourceRoutes added in v0.6.0

func (vt *VTun) SetSourceRoutes(routes []SourceRoute) error

SetSourceRoutes replaces the source-route table for new flows. The method validates the complete new table before it changes the active table. Existing TCP, connected UDP, and connected ICMP flows keep their selected sources.

func (*VTun) SourceRoutes added in v0.6.0

func (vt *VTun) SourceRoutes() []SourceRoute

SourceRoutes returns a copy of the active, normalized source-route table.

func (*VTun) Up

func (vt *VTun) Up() error

func (*VTun) Write

func (vt *VTun) Write(buf [][]byte, offset int) (int, error)

Write writes packets to the device endpoint. It determines the IP version from the first nibble of each packet and injects it as an inbound packet to the appropriate protocol handler.

func (*VTun) WriteNotify

func (vt *VTun) WriteNotify()

WriteNotify is called when the endpoint has data available. It reads a packet from the endpoint and sends it to the incomingPacket channel.

Jump to

Keyboard shortcuts

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