tunnel

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: May 22, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package tunnel reconnect machinery: exponential-backoff loop that retries Start on transient SSH failures (EOF, connection reset, handshake timeouts) while letting permanent failures (host-key mismatch, unsupported options, no usable auth) surface immediately.

Package tunnel opens a single SSH tunnel using golang.org/x/crypto/ssh and forwards a local port through it.

Phase 1 supports only local forwards; remote and dynamic land in Phase 2.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BackoffOptions

type BackoffOptions struct {
	// InitialDelay is the wait before the first reconnect attempt.
	// Defaults to 1s.
	InitialDelay time.Duration
	// MaxDelay caps the exponential growth. Defaults to 60s.
	MaxDelay time.Duration
	// Multiplier scales the previous delay each step. Defaults to 2.0.
	Multiplier float64
	// Jitter is the fractional bound on per-call randomisation
	// (e.g. 0.1 means +/-10%). Zero disables jitter entirely.
	Jitter float64
	// MaxAttempts is the maximum number of Start calls before giving up.
	// Defaults to 10.
	MaxAttempts int
}

BackoffOptions configures the reconnect backoff schedule. Zero values receive sane defaults via applyDefaults, with one deliberate exception: Jitter==0 means "no jitter" rather than "use default jitter" so tests can run deterministically. Production call sites (StartWithReconnect via newBackoff) inject the 10% default themselves when the field is untouched at the manager level.

type Options

type Options struct {
	// HostKeyCallback is required. In production use
	// ssh.InsecureIgnoreHostKey() is forbidden; supply
	// knownhosts.New or ssh.FixedHostKey.
	HostKeyCallback ssh.HostKeyCallback

	// DialTimeout is the maximum time for the initial TCP+SSH handshake.
	// If zero, defaults to 10s.
	DialTimeout time.Duration

	// Reconnect enables auto-reconnect with exponential backoff: when
	// Start returns due to a transient SSH error, StartWithReconnect
	// will retry up to Backoff.MaxAttempts times.
	Reconnect bool

	// Backoff configures the reconnect schedule. Zero-value receives
	// sane defaults (1s..60s, 10% jitter, 10 attempts).
	Backoff BackoffOptions
}

Options carries cross-cutting settings shared across tunnels.

type Status

type Status int

Status describes a tunnel's current state.

const (
	StatusDown Status = iota
	StatusConnecting
	StatusUp
	StatusStopping
)

Status values reported by a Tunnel as it progresses through its lifecycle.

func (Status) String

func (s Status) String() string

type Tunnel

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

Tunnel represents a single configured tunnel. Construct with New, then call Start to bring it up.

func New

func New(rt config.ResolvedTunnel, opts Options) *Tunnel

New constructs a Tunnel. It does not connect.

func (*Tunnel) LocalAddr

func (t *Tunnel) LocalAddr() string

LocalAddr returns the actual listen address ("host:port") once Start has succeeded. Empty before then.

func (*Tunnel) Metrics

func (t *Tunnel) Metrics() *metrics.Tracker

Metrics returns the per-tunnel metrics tracker. Non-nil after New.

func (*Tunnel) Name

func (t *Tunnel) Name() string

Name returns the configured name of this tunnel.

func (*Tunnel) Start

func (t *Tunnel) Start(ctx context.Context, started chan<- struct{}) error

Start dials the SSH server, opens the local listener, and forwards connections. It blocks until ctx is cancelled or a fatal error occurs. The `started` channel is closed once the listener is accepting connections (use to gate on "tunnel is up" in tests and CLI mode).

func (*Tunnel) StartWithReconnect

func (t *Tunnel) StartWithReconnect(ctx context.Context, started chan<- struct{}) error

StartWithReconnect wraps Start with an exponential-backoff retry loop. Transient SSH errors (EOF, connection reset, handshake failures, timeouts) trigger a retry; permanent errors (host-key mismatch, unsupported config options, no usable auth) short-circuit and surface immediately.

The first attempt receives the supplied started channel; subsequent attempts pass nil so callers see exactly one "up" signal across the reconnect lifecycle.

When t.opts.Reconnect is false this is a thin pass-through to Start.

func (*Tunnel) Status

func (t *Tunnel) Status() Status

Status returns the current tunnel state.

Jump to

Keyboard shortcuts

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