Documentation
¶
Overview ¶
Package forward implements host-to-VM port forwarding for Slicer.
Each accepted local TCP/Unix connection opens a per-connection WebSocket to the daemon at /vm/{hostname}/forward with an X-Inlets-Upstream header that tells the daemon what host:port (or unix:/path) to dial inside the guest. The WebSocket carries raw bytes both directions as binary frames. No subprotocol framing, no multiplexing — one local connection per WebSocket.
Usage:
fwd, err := forward.Start(ctx, forward.Options{
BaseURL: "http://127.0.0.1:8080",
Token: os.Getenv("SLICER_TOKEN"),
VMName: "sbox-1",
Specs: []string{"127.0.0.1:8080:127.0.0.1:80"},
})
if err != nil { log.Fatal(err) }
defer fwd.Close()
// listeners are bound and serving; issue your host-side requests now.
resp, _ := http.Get("http://127.0.0.1:8080/")
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AddressMapping ¶
type AddressMapping struct {
// RawSpec is the original string supplied by the caller.
RawSpec string
// ListenAddr is the TCP bind address (e.g. "127.0.0.1" or "0.0.0.0").
// Empty when listening on a Unix socket.
ListenAddr string
// ListenPort is the TCP listen port. Zero for random; ignored for Unix.
ListenPort int
// ListenUnixPath is set when listening on a Unix socket instead of TCP.
ListenUnixPath string
// RemoteHost is the guest-side TCP host to dial. Empty when targeting
// a guest Unix socket.
RemoteHost string
// RemotePort is the guest-side TCP port.
RemotePort int
// RemoteUnixPath is set when dialing a Unix socket inside the guest.
RemoteUnixPath string
}
AddressMapping describes one -L-style forward: a local listener on the host plus the upstream target to dial inside the VM.
func ParseAddressMapping ¶
func ParseAddressMapping(spec string) (*AddressMapping, error)
ParseAddressMapping parses a -L-style spec. Supported formats:
127.0.0.1:9000 TCP, listen and forward same host:port 9001:127.0.0.1:9000 TCP, listen 0.0.0.0:9001 → 127.0.0.1:9000 0:127.0.0.1:9000 TCP, random listen port → 127.0.0.1:9000 0.0.0.0:9000:127.0.0.1:9000 TCP, fully explicit 127.0.0.1:9000:/var/run/docker.sock TCP listen, Unix socket forward 9000:/var/run/docker.sock TCP listen 0.0.0.0:9000, Unix socket forward /tmp/docker.sock:/var/run/docker.sock Unix-to-Unix ./docker.sock:/var/run/docker.sock Unix-to-Unix with relative local path
func (*AddressMapping) ListenAddress ¶
func (m *AddressMapping) ListenAddress() string
ListenAddress renders a human-readable form of the local side.
func (*AddressMapping) ListenUnix ¶
func (m *AddressMapping) ListenUnix() bool
ListenUnix reports whether the local listener is a Unix socket.
func (*AddressMapping) RemoteTarget ¶
func (m *AddressMapping) RemoteTarget() string
RemoteTarget renders the X-Inlets-Upstream header value.
TCP: "host:port" Unix: "unix:/path/to/socket"
func (*AddressMapping) RemoteUnix ¶
func (m *AddressMapping) RemoteUnix() bool
RemoteUnix reports whether the upstream target is a Unix socket.
type Forwarder ¶
type Forwarder struct {
// contains filtered or unexported fields
}
Forwarder holds bound listeners and the per-connection tunnel machinery. A Forwarder is safe to close from any goroutine; Close is idempotent.
func Start ¶
Start parses specs, binds all local listeners, begins accepting, and returns a Forwarder. If binding any listener fails the partial state is cleaned up before returning the error.
ctx governs the lifetime of accept loops. Cancelling it is equivalent to calling Close.
func (*Forwarder) Close ¶
Close tears down all listeners and in-flight tunnel sockets. Safe to call multiple times.
type Listener ¶
type Listener struct {
// Spec is the original -L string that created this listener.
Spec string
// Local is a human-readable form of the local address (e.g.
// "127.0.0.1:50306" or "/tmp/docker.sock").
Local string
// Remote is the upstream target inside the VM as sent in X-Inlets-Upstream.
Remote string
// Port is the resolved local TCP port. Useful when the caller asked for 0.
// Zero for Unix-socket listeners.
Port int
}
Listener describes one bound local listener.
type Options ¶
type Options struct {
// BaseURL is the Slicer API URL: `http(s)://host[:port]` or an absolute
// Unix socket path (`/path/to/slicer.sock` or `unix:///path`).
BaseURL string
// Token is the bearer token for the Slicer API. Optional for unix sockets
// with no auth configured.
Token string
// VMName is the hostname of the VM to forward into.
VMName string
// Specs are -L-style mappings. See ParseAddressMapping for the accepted
// formats.
Specs []string
// ClientID identifies this client to the daemon via the
// X-Inlets-Client-ID header. Defaults to os.Hostname().
ClientID string
// UserAgent overrides the HTTP User-Agent header on the upgrade request.
UserAgent string
// DialTimeout bounds the initial WebSocket handshake. Default 10s.
DialTimeout time.Duration
// Logger receives short progress strings. If nil, events are discarded.
Logger *log.Logger
}
Options configures a Forwarder.