Help us shape the future of Go! Take the 2026 Go Developer Survey

app

package
v1.3.103 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: AGPL-3.0 Imports: 18 Imported by: 2

Documentation

Overview

Package app pkg/app/client.go c2-vis-appsvc

Package app pkg/app/conn.go c2-vis-appsvc

Package app pkg/app/dial_errors.go c2-vis-appsvc

Package app pkg/app/doc.go c2-vis-appsvc between a visor and a skywire application. Intended to replace the original `app` module.

Package app pkg/app/listener.go c2-vis-appsvc

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsNoDisjointFirstHop

func IsNoDisjointFirstHop(err error) bool

IsNoDisjointFirstHop reports whether a failed app dial failed because the router had no disjoint first hop left to offer — the settled answer a RequireDisjointFirstHop dial gets once every route to the destination leaves over a first hop a sibling route group already holds.

A caller growing a pool of sibling tunnels uses it to tell "the topology has another disjoint route" from "it has none left", and must STOP on true. It is not a transient failure and re-dialing against it is the setup-node storm of #4325.

The substring check is not belt-and-braces, it is the load-bearing half: an app dial crosses a net/rpc boundary to the visor, which flattens every error to its text (appserver.RPCErr), so errors.Is alone can only ever match in-process callers.

Types

type Client

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

Client is used by skywire apps.

func NewClient

func NewClient(eventSubs *appevent.Subscriber) *Client

NewClient creates a new Client, panicking on any error.

func NewClientFromConfig

func NewClientFromConfig(log logrus.FieldLogger, conf appcommon.ProcConfig, subs *appevent.Subscriber) (*Client, error)

NewClientFromConfig creates a new client from a given proc config.

func (*Client) AppSettings

func (c *Client) AppSettings(applied, opsApplied uint64) (map[string]int64, map[string]string, []appserver.AppOp, uint64, error)

AppSettings polls the visor for this app's live tuning knobs, reporting the version the app currently has installed so a steady-state poll costs an empty round-trip. Returns the full intended set and the version it carries; a knob absent from the set is at its compiled default.

This is the only visor->app VALUE channel: the ingress gateway is ingress only (the app is the RPC client), so a running app is reconfigured by asking, not by being told. See pkg/app/appserver/app_settings.go. The list knobs travel in their own map (text) and the edge-triggered ops beside both; opsApplied is the highest op sequence this app has carried out, which is how an op leaves the visor's queue.

func (*Client) Close

func (c *Client) Close()

Close closes client/server communication entirely. It closes all open listeners and connections.

func (*Client) Config

func (c *Client) Config() appcommon.ProcConfig

Config returns the underlying proc config.

func (*Client) Dial

func (c *Client) Dial(remote appnet.Addr) (net.Conn, error)

Dial dials the remote visor using `remote`.

func (*Client) DialWithOptions

func (c *Client) DialWithOptions(remote appnet.Addr, opts appserver.DialOptionsReq) (net.Conn, error)

DialWithOptions dials remote with the per-call dial options opts carries — mux route counts (symmetric and per-direction), min-hops (symmetric and per-direction), the `--direct` transport-only shortcut, multi-tunnel diversification and its disjoint requirement, and the tunnel role label. See appserver.DialOptionsReq for what each field means to the router.

An opts with nothing explicit set is semantically equivalent to Dial. Apps requesting these dial shapes (skynet-client's --routes / --min-hops / --forward-mux …, skysocks-client's tunnels) call this instead of Dial; non-mux callers keep using Dial unchanged.

opts.Addr is filled in from remote, so a caller never has to state the destination twice.

func (*Client) GrowMuxFromPool

func (c *Client) GrowMuxFromPool(localPort routing.Port, legs, minHops int) (int, error)

GrowMuxFromPool asks the visor to widen the tunnel this app dialed from localPort by legs packet-level mux legs, built on the routes of this app's own STANDBY tunnels to the same exit rather than discovered from scratch. minHops floors the hop count of a leg the pool cannot cover and the route-finder has to plan (0 = the visor's own floor). Returns how many legs were actually added — fewer than asked is normal and not an error: the topology may simply not offer that many disjoint first hops.

The division of knowledge is the same one NoteMuxEvent rests on: the app knows which tunnel it wants wider and how many of its tunnels are parked, and only the visor knows the routes behind them.

func (*Client) Listen

func (c *Client) Listen(n appnet.Type, port routing.Port) (net.Listener, error)

Listen listens on the specified `port` for the incoming connections.

func (*Client) LocalServices added in v1.3.99

func (c *Client) LocalServices() ([]appnet.LocalService, error)

LocalServices lists the in-process services this app can reach on its own visor, each with the hostname suffixes it answers for — the resolving proxies. Dialing one is an ordinary Dial to the visor's own PK on the service's port, which the visor serves over a pipe instead of a route, so an app hands a .skynet or .dmsg name to the resolver without a second SOCKS hop on localhost.

A nil receiver (an app running standalone, with no visor) reports nothing rather than failing, so a caller can treat "no visor" and "no resolvers" the same way.

func (*Client) Log

func (c *Client) Log() logrus.FieldLogger

Log returns the client's logger for apps to use for logging.

func (*Client) NoteMuxEvent

func (c *Client) NoteMuxEvent(localPort routing.Port, event, reason, role string) error

NoteMuxEvent records a TUNNEL event this app decided — a standby tunnel promoted into the active set, an active one parked back into standby, a dead one retired — on the route group the app dialed from localPort, and re-labels that group's tunnel role ("active" / "standby"; "" leaves it alone).

The app is the only end that knows which of its tunnels carries streams, and the router is the only end that knows the route behind one and owns the event ring `visor state --select diag` reads. localPort — the port handed back by the dial — is the one name both ends share.

func (*Client) Notify

func (c *Client) Notify(n appserver.NotifyReq) error

Notify publishes a user-facing notification to the visor's notification hub, which decides which sink can actually reach the user (an attached UI, a subscribed host app such as the Android service, the host-OS notification center, or nowhere at all on a headless visor).

The app decides *whether* to notify — it alone knows what is muted or already on screen; the visor decides *where*. The visor stamps the App field from the calling proc's identity, so callers leave it empty.

func (*Client) NotifyOrLog

func (c *Client) NotifyOrLog(title, body, tag string)

NotifyOrLog publishes a notification, logging (without the body — it is routinely untrusted peer text) if the visor can't be reached. Best-effort and nil-safe like SetStatusOrLog, so apps that can run standalone don't have to guard each call site.

func (*Client) ProxyStatus

func (c *Client) ProxyStatus() (proxystatus.Snapshot, error)

ProxyStatus fetches the visor-built rich read-only status snapshot for this app (per-leg mux telemetry, recent logs, route/transport events). An app that serves its own reserved status host (skysocks-client's status.skysocks) renders this so the page shows the same rich view as the visor-side resolving proxies. An empty snapshot (no error) means the visor had no data; the caller then falls back to its own local view.

func (*Client) SetAppPort

func (c *Client) SetAppPort(appPort routing.Port) error

SetAppPort sets app port within the visor.

func (*Client) SetAppPortOrLog

func (c *Client) SetAppPortOrLog(port routing.Port)

SetAppPortOrLog sets the routing port and logs the error if any. Best-effort and nil-safe like SetStatusOrLog. Replaces the setAppPort helper that every app previously defined locally.

func (*Client) SetConnectionDuration

func (c *Client) SetConnectionDuration(dur int64) error

SetConnectionDuration sets the detailed app connection duration within the visor.

func (*Client) SetDetailedStatus

func (c *Client) SetDetailedStatus(status string) error

SetDetailedStatus sets detailed app status within the visor.

func (*Client) SetError

func (c *Client) SetError(appErr string) error

SetError sets app error within the visor.

func (*Client) SetErrorOrLog

func (c *Client) SetErrorOrLog(appErr error)

SetErrorOrLog records an app error in the visor and logs the failure to record (not the original error — that's already in appErr). Best-effort and nil-safe like SetStatusOrLog. Replaces the setAppError helper that every app previously defined locally.

func (*Client) SetOTP

func (c *Client) SetOTP(otp string) error

SetOTP publishes the app's current one-time code within the visor, where it surfaces on the (auth-gated) hypervisor app list. Apps that gate their own web UI use this so an operator can read the code out-of-band instead of the app needing a password of its own.

func (*Client) SetOTPOrLog

func (c *Client) SetOTPOrLog(otp string)

SetOTPOrLog publishes the app's one-time code, logging (without the code itself) if the visor can't be reached. Best-effort and nil-safe like SetStatusOrLog, so apps running standalone don't have to guard call sites.

func (*Client) SetStatusOrLog

func (c *Client) SetStatusOrLog(status appserver.AppDetailedStatus)

SetStatusOrLog sets the detailed status and logs the error if any. Status transitions are best-effort — the app keeps running even if the visor can't be notified, so callers don't have to handle the error path. A nil receiver is a no-op so apps that can run in standalone mode (skychat) don't have to guard each call site. Replaces the setAppStatus helper that every app previously defined locally.

type Conn

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

Conn is a connection from app client to the server. Implements `net.Conn`.

func (*Conn) Close

func (c *Conn) Close() error

Close closes connection.

func (*Conn) LocalAddr

func (c *Conn) LocalAddr() net.Addr

LocalAddr returns local address of connection.

func (*Conn) Read

func (c *Conn) Read(b []byte) (int, error)

Read reads from connection.

func (*Conn) RemoteAddr

func (c *Conn) RemoteAddr() net.Addr

RemoteAddr returns remote address of connection.

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time) error

SetDeadline sets read and write deadlines for connection.

func (*Conn) SetReadDeadline

func (c *Conn) SetReadDeadline(t time.Time) error

SetReadDeadline sets read deadline for connection.

func (*Conn) SetWriteDeadline

func (c *Conn) SetWriteDeadline(t time.Time) error

SetWriteDeadline sets write deadline for connection.

func (*Conn) Write

func (c *Conn) Write(b []byte) (int, error)

Write writes to connection.

type Listener

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

Listener is a listener for app server connections. Implements `net.Listener`.

func (*Listener) Accept

func (l *Listener) Accept() (net.Conn, error)

Accept accepts a connection from listener.

func (*Listener) Addr

func (l *Listener) Addr() net.Addr

Addr returns address listener listens on.

func (*Listener) Close

func (l *Listener) Close() error

Close closes listener.

Directories

Path Synopsis
Package appcommon pkg/app/appcommon/doc.go c2-vis-appsvc
Package appcommon pkg/app/appcommon/doc.go c2-vis-appsvc
Package appdisc pkg/app/appdisc/discovery_manager.go c2-vis-appsvc
Package appdisc pkg/app/appdisc/discovery_manager.go c2-vis-appsvc
Package appevent pkg/app/appevent/broadcaster.go c2-vis-appsvc
Package appevent pkg/app/appevent/broadcaster.go c2-vis-appsvc
Package appnet pkg/app/appnet/addr.go c2-vis-appsvc
Package appnet pkg/app/appnet/addr.go c2-vis-appsvc
Package appserver pkg/app/appserver/app_settings.go
Package appserver pkg/app/appserver/app_settings.go
spec
Package spec pkg/app/appserver/spec/spec.go c2-vis-appsvc Holds the AppConfig wire-format type that pkg/visor/visorconfig.V1's Launcher.Apps field embeds.
Package spec pkg/app/appserver/spec/spec.go c2-vis-appsvc Holds the AppConfig wire-format type that pkg/visor/visorconfig.V1's Launcher.Apps field embeds.
Package idmanager pkg/app/idmanager/delta_informer.go c2-vis-appsvc
Package idmanager pkg/app/idmanager/delta_informer.go c2-vis-appsvc
Package launcher pkg/app/launcher/launcher.go c2-vis-appsvc
Package launcher pkg/app/launcher/launcher.go c2-vis-appsvc

Jump to

Keyboard shortcuts

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