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

appnet

package
v1.3.104 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: AGPL-3.0 Imports: 21 Imported by: 1

Documentation

Overview

Package appnet pkg/app/appnet/addr.go c2-vis-appsvc

Package appnet pkg/app/appnet/dial_fallback.go c2-vis-appsvc

Package appnet pkg/app/appnet/dmsg_networker.go c2-vis-appsvc

Package appnet pkg/app/appnet/doc.go c2-vis-appsvc from skywire apps.

Package appnet pkg/app/appnet/errors.go c2-vis-appsvc

Package appnet pkg/app/appnet/forwarding.go c2-vis-appsvc

Package appnet pkg/app/appnet/local_service.go c2-vis-appsvc

Local services: in-process handlers that an app on THIS visor reaches over the data plane it already holds, with no localhost port and no network hop. A dial to the visor's own PK on a registered port is served over net.Pipe.

The resolving proxies are the motivating case. An app wanting to hand a `<pk>.skynet` name to the resolver had only one way in: the resolver's SOCKS5 listener on 127.0.0.1, which means a second proxy hop and a port the operator has to configure on both sides.

This is deliberately NOT pkg/visor's ServiceRegistry. That map is the one handleServerConn dispatches INCOMING peer connections from, on the sky forwarding ports, where the CALLER names the port it wants — so membership there is mesh reachability, and the registry path returns before the per-port PK whitelist below it. A resolving proxy must never be reachable that way: a peer would be resolving this visor's alias table through its MITM CA and leaving through its exit. A local service has no port on the forwarding server, so a peer has nothing to name.

Package appnet pkg/app/appnet/networker.go c2-vis-appsvc

Package appnet pkg/app/appnet/skywire_conn.go c2-vis-appsvc

Package appnet pkg/app/appnet/skywire_networker.go c2-vis-appsvc

Package appnet pkg/app/appnet/type.go c2-vis-appsvc

Package appnet pkg/app/appnet/wrapped_conn.go c2-vis-appsvc

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrPortAlreadyBound is being returned when the desired port is already bound to.
	ErrPortAlreadyBound = errors.New("port already bound")
	// ErrClosedConn is being returned when we are listening on a closed connection.
	// Wraps net.ErrClosed so generic accept loops that check the standard
	// sentinel (e.g. dmsgctrl.ServeListener) recognize this as terminal
	// instead of spin-logging on shutdown.
	ErrClosedConn = fmt.Errorf("listening on closed connection: %w", net.ErrClosed)
)
View Source
var ErrNoLocalService = errors.New("no local service registered on that address")

ErrNoLocalService is returned by DialLocalService for an address with no handler registered on it.

View Source
var (
	// ErrNoSuchNetworker is being returned when there's no suitable networker.
	ErrNoSuchNetworker = errors.New("no such networker")
)
View Source
var ErrPacketNetworkerNotSupported = errors.New("appnet: networker does not support packet dialing")

ErrPacketNetworkerNotSupported is returned by DialPacket when the resolved Networker for addr.Net does not implement PacketNetworker. Stage 5 ships the API; implementations land in the route-setup-integration follow-up.

View Source
var (
	// ErrUnknownAddrType is returned when trying to convert the
	// unknown addr type.
	ErrUnknownAddrType = errors.New("addr type is unknown")
)

Functions

func AddNetworker

func AddNetworker(t Type, n Networker) error

AddNetworker associates Networker with the `network`.

func AddRawTCPForwarding

func AddRawTCPForwarding(fwd *RawTCPForwardConn)

AddRawTCPForwarding adds RawTCPForwardConn with its ID

func AppNameFromContext

func AppNameFromContext(ctx context.Context) string

AppNameFromContext returns the app name stored on ctx by WithAppName, or "" if none.

func ClearLocalServices added in v1.3.99

func ClearLocalServices()

ClearLocalServices removes every registration. Mirrors ClearNetworkers, for tests.

func ClearNetworkers

func ClearNetworkers()

ClearNetworkers removes all the stored networkers.

func Dial

func Dial(addr Addr) (net.Conn, error)

Dial dials the remote `addr`.

func DialContext

func DialContext(ctx context.Context, addr Addr) (net.Conn, error)

DialContext dials the remote `addr` with the context.

func DialLocalService added in v1.3.99

func DialLocalService(addr Addr) (net.Conn, error)

DialLocalService serves addr in-process over net.Pipe: the handler runs on its own goroutine with the server end, and the client end is returned. No transport, no route, no listener.

func ErrServiceOffline

func ErrServiceOffline(port uint16) error

ErrServiceOffline is used to get a verbose error of GetListenerError

func GetAllRawTCPForwardConns

func GetAllRawTCPForwardConns() map[uuid.UUID]*RawTCPForwardConn

GetAllRawTCPForwardConns gets all RawTCPForwardConns

func HasLocalService added in v1.3.99

func HasLocalService(addr Addr) bool

HasLocalService reports whether addr names a registered local service.

func IsCarrierDial

func IsCarrierDial(ctx context.Context) bool

IsCarrierDial reports whether ctx was marked by WithCarrierDial.

func Listen

func Listen(addr Addr) (net.Listener, error)

Listen starts listening on the local `addr`.

func ListenContext

func ListenContext(ctx context.Context, addr Addr) (net.Listener, error)

ListenContext starts listening on the local `addr` with the context.

func Ping

func Ping(pk cipher.PubKey, addr Addr) (net.Conn, error)

Ping dials the remote `addr`.

func PingContext

func PingContext(ctx context.Context, pk cipher.PubKey, addr Addr) (net.Conn, error)

PingContext dials the remote `addr` with the context.

func PingContextWithMinHops

func PingContextWithMinHops(ctx context.Context, pk cipher.PubKey, addr Addr, minHops int) (net.Conn, error)

PingContextWithMinHops dials the remote `addr` constrained to paths of at least `minHops` hops. Used by mux-bw's --min-hops flag to force non-direct routing even when a direct transport exists. Falls back to plain PingContext when the resolved networker isn't a SkywireNetworker (DMSG, etc).

func PingContextWithRoute

func PingContextWithRoute(ctx context.Context, pk cipher.PubKey, addr Addr, forwardHops, reverseHops []RouteHopInfo) (net.Conn, error)

PingContextWithRoute dials the remote `addr` using a specific route. This skips route calculation and uses the provided forward/reverse hops. Only works with TypeSkynet networker.

func PingContextWithTransport

func PingContextWithTransport(ctx context.Context, pk cipher.PubKey, addr Addr, transportID string) (net.Conn, error)

PingContextWithTransport dials the remote `addr` using a specific transport. This skips route calculation and uses the provided transport directly. Only works with TypeSkynet networker.

func RegisterLocalService added in v1.3.99

func RegisterLocalService(pk cipher.PubKey, svc LocalService, handler LocalHandler)

RegisterLocalService makes handler reachable to apps on this visor that dial pk:svc.Port, where pk is this visor's own public key. Overwrites any handler on the same address — matching AddNetworker's last-writer-wins semantics, which a restarted resolver relies on.

func RemoveRawTCPForwardConn

func RemoveRawTCPForwardConn(id uuid.UUID)

RemoveRawTCPForwardConn removes a RawTCPForwardConn by ID

func UnregisterLocalService added in v1.3.99

func UnregisterLocalService(pk cipher.PubKey, port routing.Port)

UnregisterLocalService removes the handler on pk:port. No-op if none.

func WithAppName

func WithAppName(ctx context.Context, appName string) context.Context

WithAppName returns a derived context that carries the given app name. SkywireNetworker reads it via AppNameFromContext.

func WithCarrierDial

func WithCarrierDial(ctx context.Context) context.Context

WithCarrierDial marks ctx as a session-carrier dial, which exempts it from the visor-global min_hops.

min_hops exists so an intermediate cannot learn the true source and destination of this visor's TRAFFIC — with enough hops it only ever sees its neighbors. A carrier dial is not traffic. Its destination IS the peer that will carry the session, chosen by this visor, and that peer terminates the session and therefore knows exactly whose it is. Extra hops hide nothing from the only party in a position to learn anything, so min_hops buys no privacy on this dial.

What it costs is the bootstrap. min_hops >= 2 makes the carrier dial ineligible for the 0-hop AppDirectMux shortcut, so it falls through to route setup — which reaches the route finder and the setup node over dmsg, the very thing the carrier is replacing. hasDirectTransportTo deliberately refuses a multi-hop route for exactly this reason, but it cannot see that min_hops has already forced one: holding a direct transport does not make a dial one hop when the config forbids one hop. So on a visor configured for privacy, dmsg-over-skynet silently could not converge — and failed into the circular path rather than cleanly.

Traffic dials are untouched: this marks only the carrier, and only the visor sets it.

func WrapConn

func WrapConn(conn net.Conn) (net.Conn, error)

WrapConn wraps passed `conn`. Handles `net.Addr` type assertion.

Types

type Addr

type Addr struct {
	Net    Type
	PubKey cipher.PubKey
	Port   routing.Port
}

Addr implements net.Addr for network addresses.

func ConvertAddr

func ConvertAddr(addr net.Addr) (Addr, error)

ConvertAddr asserts type of the passed `net.Addr` and converts it to `Addr` if possible. Accepts:

  • dmsg.Addr — pre-skynet legacy address; mapped to TypeDmsg.
  • routing.Addr — emitted by route-group conns (PingRoute path).
  • appnet.Addr — already in this package's type; emitted by directConn (AppDirect VStream conns). Passed through unchanged so listeners that call WrapConn on a conn from the AppDirect dispatch loop accept it instead of erroring with ErrUnknownAddrType.

Pre-fix: any listener calling WrapConn on a direct-dial conn (most notably the ping listener at init_services.go) hit the default branch, returned ErrUnknownAddrType, logged "Failed to wrap ping conn" and closed the stream. The client then saw the close on its first write and surfaced "write size: use of closed network connection" — a confusing failure mode that masked the underlying type-assertion gap.

func (Addr) Network

func (a Addr) Network() string

Network returns network type.

func (Addr) PK

func (a Addr) PK() cipher.PubKey

PK returns public key of visor.

func (Addr) String

func (a Addr) String() string

String returns public key and port of visor split by colon.

type ConnDialer

type ConnDialer func(ctx context.Context, addr Addr) (net.Conn, error)

ConnDialer dials a single appnet Addr and returns the resulting conn or an error. It abstracts over the concrete dial primitive a caller uses (the RPC app.Client, the in-visor appnet.DialContext, a raw dmsg client, …) so the ordered-try logic below can be shared regardless of how each network dials.

type DatagramPacketConn

type DatagramPacketConn interface {
	net.PacketConn

	// MaxPayload is the largest plaintext datagram WriteTo accepts.
	MaxPayload() int

	// InboundDropped is the count of inbound datagrams dropped
	// since conn construction due to a full receive queue.
	InboundDropped() uint64

	// AEADAuthFailures is the count of inbound datagrams dropped
	// since conn construction due to AEAD authentication failure.
	AEADAuthFailures() uint64
}

DatagramPacketConn extends net.PacketConn with the operations apps need to use UDP-over-skywire without surprises:

  • MaxPayload returns the largest plaintext datagram WriteTo will accept. App code that consults this before sending never sees the opaque EMSGSIZE behavior plain net.UDPConn presents (where the OS-level MTU is invisible until a send fails). Reflects the Stage 3 AEAD overhead — 24 bytes subtracted from the raw wire cap.

  • InboundDropped surfaces the count of inbound datagrams the conn dropped because its receive queue was full (slow- consumer signal). Apps that care about packet loss can poll this to distinguish "lost in transit" from "delivered but dropped at our end."

  • AEADAuthFailures surfaces the count of inbound datagrams that failed authentication (forgery / replay / corrupted). A rising counter under normal traffic is an attack signal.

func DialPacket

func DialPacket(addr Addr) (DatagramPacketConn, error)

DialPacket opens a UDP-shaped conn to addr using a background context.

func DialPacketContext

func DialPacketContext(ctx context.Context, addr Addr) (DatagramPacketConn, error)

DialPacketContext opens a UDP-shaped conn to addr. The networker for addr.Net must implement PacketNetworker; otherwise ErrPacketNetworkerNotSupported is returned.

On success the returned conn is loss-tolerant, possibly- unordered, no head-of-line blocking on reorder. Each datagram is independently encrypted + authenticated + replay-protected (per-datagram ChaCha20-Poly1305-IETF + RFC 6479 sliding window; see pkg/router/datagram_crypto.go).

type DmsgNetworker

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

DmsgNetworker implements `Networker` for dmsg network.

func (*DmsgNetworker) Dial

func (n *DmsgNetworker) Dial(addr Addr) (net.Conn, error)

Dial dials remote `addr` via dmsg network.

func (*DmsgNetworker) DialContext

func (n *DmsgNetworker) DialContext(ctx context.Context, addr Addr) (net.Conn, error)

DialContext dials remote `addr` via dmsg network with context.

func (*DmsgNetworker) Listen

func (n *DmsgNetworker) Listen(addr Addr) (net.Listener, error)

Listen starts listening on local `addr` in the dmsg network.

func (*DmsgNetworker) ListenContext

func (n *DmsgNetworker) ListenContext(_ context.Context, addr Addr) (net.Listener, error)

ListenContext starts listening on local `addr` in the dmsg network with context.

func (*DmsgNetworker) Ping

func (n *DmsgNetworker) Ping(_ cipher.PubKey, _ Addr) (net.Conn, error)

Ping dials remote `addr` via dmsg network.

func (*DmsgNetworker) PingContext

func (n *DmsgNetworker) PingContext(_ context.Context, _ cipher.PubKey, _ Addr) (net.Conn, error)

PingContext dials remote `addr` via dmsg network with context.

type LocalHandler added in v1.3.99

type LocalHandler func(conn net.Conn)

LocalHandler serves one connection and owns it for its lifetime: it reads requests, writes responses, and closes the conn when done.

type LocalService added in v1.3.99

type LocalService struct {
	// Port is the routing port an app dials on its own visor's PK. The
	// resolving proxies use their own SOCKS5 port number, which
	// ValidateResolvers already keeps unique across resolvers.
	Port routing.Port
	// Label names the service in logs ("skynet_web", "dmsg_web").
	Label string
	// Suffixes are the hostname suffixes this service answers for, where it
	// answers for names at all: ".skynet", ".dmsg". Empty means the app has to
	// know what the service is for by its label.
	Suffixes []string
}

LocalService describes one in-process service that apps on this visor may dial. It is what an app asking the visor what it can reach gets back, so an app matches on what a service answers for instead of hard-coding a port.

func LocalServiceFor added in v1.3.99

func LocalServiceFor(addr Addr) (LocalService, bool)

LocalServiceFor returns the service registered on addr, and whether addr names one at all.

func LocalServices added in v1.3.99

func LocalServices(pk cipher.PubKey) []LocalService

LocalServices lists what an app on the visor owning pk can reach in-process, ordered by port so the answer is stable.

type MockNetworker

type MockNetworker struct {
	mock.Mock
}

MockNetworker is an autogenerated mock type for the Networker type

func NewMockNetworker

func NewMockNetworker(t interface {
	mock.TestingT
	Cleanup(func())
}) *MockNetworker

NewMockNetworker creates a new instance of MockNetworker. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. The first argument is typically a *testing.T value.

func (*MockNetworker) Dial

func (_m *MockNetworker) Dial(addr Addr) (net.Conn, error)

Dial provides a mock function with given fields: addr

func (*MockNetworker) DialContext

func (_m *MockNetworker) DialContext(ctx context.Context, addr Addr) (net.Conn, error)

DialContext provides a mock function with given fields: ctx, addr

func (*MockNetworker) Listen

func (_m *MockNetworker) Listen(addr Addr) (net.Listener, error)

Listen provides a mock function with given fields: addr

func (*MockNetworker) ListenContext

func (_m *MockNetworker) ListenContext(ctx context.Context, addr Addr) (net.Listener, error)

ListenContext provides a mock function with given fields: ctx, addr

func (*MockNetworker) Ping

func (_m *MockNetworker) Ping(pk cipher.PubKey, addr Addr) (net.Conn, error)

Ping provides a mock function with given fields: pk, addr

func (*MockNetworker) PingContext

func (_m *MockNetworker) PingContext(ctx context.Context, pk cipher.PubKey, addr Addr) (net.Conn, error)

PingContext provides a mock function with given fields: ctx, pk, addr

type Networker

type Networker interface {
	Dial(addr Addr) (net.Conn, error)
	Ping(pk cipher.PubKey, addr Addr) (net.Conn, error)
	PingContext(ctx context.Context, pk cipher.PubKey, addr Addr) (net.Conn, error)
	DialContext(ctx context.Context, addr Addr) (net.Conn, error)
	Listen(addr Addr) (net.Listener, error)
	ListenContext(ctx context.Context, addr Addr) (net.Listener, error)
}

Networker defines basic network operations, such as Dial/Listen.

func NewDMSGNetworker

func NewDMSGNetworker(dmsgC *dmsg.Client) Networker

NewDMSGNetworker constructs new `DMSGNetworker`.

func NewSkywireNetworker

func NewSkywireNetworker(l logrus.FieldLogger, r router.Router) Networker

NewSkywireNetworker constructs skywire networker.

func ResolveNetworker

func ResolveNetworker(t Type) (Networker, error)

ResolveNetworker resolves Networker by `network`.

type PacketNetworker

type PacketNetworker interface {
	// DialPacketContext opens a datagram conn to addr. Canceling
	// ctx during the dial returns ctx.Err. The returned conn is
	// safe for concurrent use by multiple goroutines.
	DialPacketContext(ctx context.Context, addr Addr) (DatagramPacketConn, error)
}

PacketNetworker is the opt-in interface a Networker implements when it supports datagram-shaped dialing. Separate from the core Networker contract so implementations that don't yet support datagrams stay valid — callers get ErrPacketNetworkerNotSupported when they hit one of those.

type RawTCPForwardConn

type RawTCPForwardConn struct {
	ID         uuid.UUID `json:"id"`
	Network    string    `json:"network"`
	LocalPort  int       `json:"local_port"`
	RemotePort int       `json:"remote_port"`
	// contains filtered or unexported fields
}

RawTCPForwardConn handles raw TCP port forwarding over skywire. Network identifies the underlying transport ("skynet" or "dmsg") so the listing surfaces it back to clients; empty is treated as skynet for back-compat with older entries.

func GetRawTCPForwardConn

func GetRawTCPForwardConn(id uuid.UUID) *RawTCPForwardConn

GetRawTCPForwardConn gets a RawTCPForwardConn by ID

func NewRawTCPForwardConn

func NewRawTCPForwardConn(log *logging.Logger, network string, remoteConn net.Conn, remotePort, localPort int) (*RawTCPForwardConn, error)

NewRawTCPForwardConn creates a new raw TCP forwarding connection. network labels the underlying transport ("skynet" or "dmsg") so the listing surfaces it; empty defaults to "skynet" for callers that don't pass it.

func (*RawTCPForwardConn) Close

func (f *RawTCPForwardConn) Close() (err error)

Close closes the listener and remote connection

func (*RawTCPForwardConn) Serve

func (f *RawTCPForwardConn) Serve()

Serve starts accepting local connections and forwarding them to the remote skywire connection

type RouteHopInfo

type RouteHopInfo struct {
	TpID   string
	From   string
	To     string
	TpType string
}

RouteHopInfo contains detailed information about a single hop in a route.

type SkywireConn

type SkywireConn struct {
	net.Conn
	// contains filtered or unexported fields
}

SkywireConn is a connection wrapper for skynet.

nrg is nil for connections established via the direct-transport app-dial path (no route group, no setup-node). Direct conns expose the same net.Conn surface but the metric / status accessors return zero values since the route-group bookkeeping that backs them doesn't exist for raw vstreams.

func (*SkywireConn) BandwidthReceived

func (c *SkywireConn) BandwidthReceived() uint64

BandwidthReceived returns amount of bandwidth received (bytes).

func (*SkywireConn) BandwidthSent

func (c *SkywireConn) BandwidthSent() uint64

BandwidthSent returns amount of bandwidth sent (bytes).

func (*SkywireConn) Close

func (c *SkywireConn) Close() error

Close closes connection.

func (*SkywireConn) DownloadSpeed

func (c *SkywireConn) DownloadSpeed() uint32

DownloadSpeed returns download speed (bytes/s).

func (*SkywireConn) GetError

func (c *SkywireConn) GetError() error

GetError gets the close error.

func (*SkywireConn) IsAlive

func (c *SkywireConn) IsAlive() bool

IsAlive checks whether connection is alive.

func (*SkywireConn) Latency

func (c *SkywireConn) Latency() time.Duration

Latency returns latency till remote (ms).

func (*SkywireConn) RouteHopDetails

func (c *SkywireConn) RouteHopDetails() []router.RouteHopInfo

RouteHopDetails returns detailed information about each hop in the route.

func (*SkywireConn) RouteHops

func (c *SkywireConn) RouteHops() []cipher.PubKey

RouteHops returns the list of visor public keys that form the route path.

func (*SkywireConn) SetError

func (c *SkywireConn) SetError(err error)

SetError sets the close error.

func (*SkywireConn) SetForwardHops

func (c *SkywireConn) SetForwardHops(hops []routing.Hop)

SetForwardHops sets the complete forward route hops.

func (*SkywireConn) UploadSpeed

func (c *SkywireConn) UploadSpeed() uint32

UploadSpeed returns upload speed (bytes/s).

type SkywireNetworker

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

SkywireNetworker implements `Networker` for skynet.

func (*SkywireNetworker) Dial

func (r *SkywireNetworker) Dial(addr Addr) (net.Conn, error)

Dial dials remote `addr` via `skynet`.

func (*SkywireNetworker) DialContext

func (r *SkywireNetworker) DialContext(ctx context.Context, addr Addr) (conn net.Conn, err error)

DialContext dials remote `addr` via `skynet` with context.

func (*SkywireNetworker) DialContextWithOptions

func (r *SkywireNetworker) DialContextWithOptions(ctx context.Context, addr Addr, opts *router.DialOptions) (conn net.Conn, err error)

DialContextWithOptions dials remote `addr` via `skynet` with context and custom dial options.

Tries the direct-transport path first when the visor has an AppDirectMux configured: opens a vstream over an existing direct transport to addr.PubKey and writes a 2-byte port header to the remote's accept loop. No setup-node, no rule installation, no handshake-await — just the transport's own framing. Falls back to the legacy route-setup-mediated DialRoutes path when there's no direct transport, or when the direct dial fails (e.g. remote doesn't expose the mux yet — older build).

func (*SkywireNetworker) DialPacketContext

func (r *SkywireNetworker) DialPacketContext(ctx context.Context, addr Addr) (_ DatagramPacketConn, err error)

DialPacketContext implements PacketNetworker — it opens a faithful-UDP (#2607) datagram conn to addr. The dial goes through route setup with Datagram intent, which builds a DatagramRouteGroup sibling over the reliable route; the returned conn wraps that sibling and keeps the reliable route alive (closing the packet conn tears the route down and frees the local port).

The remote port must also be in datagram mode (the accept side must have called RegisterDatagramPort) or the dial fails — both ends opt in locally, there is no wire negotiation.

func (*SkywireNetworker) Listen

func (r *SkywireNetworker) Listen(addr Addr) (net.Listener, error)

Listen starts listening on local `addr` in the skynet.

func (*SkywireNetworker) ListenContext

func (r *SkywireNetworker) ListenContext(ctx context.Context, addr Addr) (net.Listener, error)

ListenContext starts listening on local `addr` in the skynet with context.

func (*SkywireNetworker) Ping

func (r *SkywireNetworker) Ping(pk cipher.PubKey, addr Addr) (net.Conn, error)

Ping dials remote `addr` via `skynet`.

func (*SkywireNetworker) PingContext

func (r *SkywireNetworker) PingContext(ctx context.Context, pk cipher.PubKey, addr Addr) (net.Conn, error)

PingContext dials remote `addr` via `skynet` with context.

func (*SkywireNetworker) PingContextWithOpts

func (r *SkywireNetworker) PingContextWithOpts(ctx context.Context, pk cipher.PubKey, addr Addr, opts *router.DialOptions) (net.Conn, error)

PingContextWithOpts dials remote `addr` via `skynet` with context and custom dial options.

Direct-transport bypass: when an AppDirectMux is configured and either (a) opts.TransportID names a transport to the peer or (b) any non-DMSG transport to the peer exists, try a vstream over that transport BEFORE falling back to the RSN-mediated PingRoute. Same mechanism that DialContextWithOptions uses for regular app dials. Cuts ping setup time from ~1-7s (RSN round-trip over dmsg) down to ~10ms (transport handshake only) — the difference shows up directly in `ping tree`'s setup-phase column when the operator and peer are both direct-transport reachable. Falls back transparently on no-direct-transport, no-mux, or older-peer-doesn't-support-AppDirect.

func (*SkywireNetworker) Router

func (r *SkywireNetworker) Router() router.Router

Router returns the router this networker dials through. Exposed for the app-server ingress paths that must reach the router for something other than a dial — reporting an app-decided tunnel event onto the router's mux-event ring — which resolve the networker exactly the way dialWithMuxRoutes does.

func (*SkywireNetworker) SetAppDirectMux

func (r *SkywireNetworker) SetAppDirectMux(mux *transport.VStreamMux)

SetAppDirectMux installs the visor's AppDirectMux on this networker and starts the accept loop that dispatches inbound direct-dial streams to listeners by destination port. Safe to call once at visor init; repeated calls are no-ops after the loop is running.

type Type

type Type string

Type represents the network type.

const (
	// TypeDmsg is a network type for dmsg communication.
	TypeDmsg Type = "dmsg"
	// TypeSkynet is a network type for skywire communication.
	TypeSkynet Type = "skynet"
	// TypeTCPDirect is a network type for noise-XK over raw TCP —
	// point-to-point with known endpoints, no dmsg-disc, no visor
	// routing. Apps use this as a reliability floor for
	// agent-to-agent comms that survives visor restarts and dmsg
	// infrastructure blips. See pkg/dmsg/tcpnoise + #2706.
	TypeTCPDirect Type = "tcp-direct"
)

func DialWithFallback

func DialWithFallback(ctx context.Context, dial ConnDialer, pk cipher.PubKey, port routing.Port, nets ...Type) (net.Conn, Type, error)

DialWithFallback dials pk:port over each network in nets IN ORDER, returning the first successful conn and the network that carried it. This is the single shared "try skynet, then dmsg" primitive — replacing the per-app copies of the same ordered-try loop (skychat filexfer, skysocks-client, …). dmsg is the natural last entry: it relays through a dmsg server, so it's the always-available baseline when a direct/route network can't reach the peer.

Networks are tried sequentially (not raced): the first is the preferred path, later ones are fallbacks tried only after the preferred one fails. Empty net entries are skipped. If every dial fails, the last error is returned (wrapped); if nets is empty, a descriptive error is returned.

func OtherNet

func OtherNet(n Type) Type

OtherNet returns the alternate of the two first-class app networks (skynet↔dmsg), or "" for any other/unknown value. Small shared helper for the "dial the OTHER network" fallback pattern.

func (Type) IsValid

func (n Type) IsValid() bool

IsValid checks whether the network contains valid value for the type.

type WrappedConn

type WrappedConn struct {
	net.Conn
	// contains filtered or unexported fields
}

WrappedConn wraps `net.Conn` to support address conversion between specific `net.Addr` implementations and `Addr`.

func (*WrappedConn) LocalAddr

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

LocalAddr returns local address.

func (*WrappedConn) RemoteAddr

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

RemoteAddr returns remote address.

Jump to

Keyboard shortcuts

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