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 ¶
- Variables
- func AddNetworker(t Type, n Networker) error
- func AddRawTCPForwarding(fwd *RawTCPForwardConn)
- func AppNameFromContext(ctx context.Context) string
- func ClearLocalServices()
- func ClearNetworkers()
- func Dial(addr Addr) (net.Conn, error)
- func DialContext(ctx context.Context, addr Addr) (net.Conn, error)
- func DialLocalService(addr Addr) (net.Conn, error)
- func ErrServiceOffline(port uint16) error
- func GetAllRawTCPForwardConns() map[uuid.UUID]*RawTCPForwardConn
- func HasLocalService(addr Addr) bool
- func IsCarrierDial(ctx context.Context) bool
- func Listen(addr Addr) (net.Listener, error)
- func ListenContext(ctx context.Context, addr Addr) (net.Listener, error)
- func Ping(pk cipher.PubKey, addr Addr) (net.Conn, error)
- func PingContext(ctx context.Context, pk cipher.PubKey, addr Addr) (net.Conn, error)
- func PingContextWithMinHops(ctx context.Context, pk cipher.PubKey, addr Addr, minHops int) (net.Conn, error)
- func PingContextWithRoute(ctx context.Context, pk cipher.PubKey, addr Addr, ...) (net.Conn, error)
- func PingContextWithTransport(ctx context.Context, pk cipher.PubKey, addr Addr, transportID string) (net.Conn, error)
- func RegisterLocalService(pk cipher.PubKey, svc LocalService, handler LocalHandler)
- func RemoveRawTCPForwardConn(id uuid.UUID)
- func UnregisterLocalService(pk cipher.PubKey, port routing.Port)
- func WithAppName(ctx context.Context, appName string) context.Context
- func WithCarrierDial(ctx context.Context) context.Context
- func WrapConn(conn net.Conn) (net.Conn, error)
- type Addr
- type ConnDialer
- type DatagramPacketConn
- type DmsgNetworker
- func (n *DmsgNetworker) Dial(addr Addr) (net.Conn, error)
- func (n *DmsgNetworker) DialContext(ctx context.Context, addr Addr) (net.Conn, error)
- func (n *DmsgNetworker) Listen(addr Addr) (net.Listener, error)
- func (n *DmsgNetworker) ListenContext(_ context.Context, addr Addr) (net.Listener, error)
- func (n *DmsgNetworker) Ping(_ cipher.PubKey, _ Addr) (net.Conn, error)
- func (n *DmsgNetworker) PingContext(_ context.Context, _ cipher.PubKey, _ Addr) (net.Conn, error)
- type LocalHandler
- type LocalService
- type MockNetworker
- func (_m *MockNetworker) Dial(addr Addr) (net.Conn, error)
- func (_m *MockNetworker) DialContext(ctx context.Context, addr Addr) (net.Conn, error)
- func (_m *MockNetworker) Listen(addr Addr) (net.Listener, error)
- func (_m *MockNetworker) ListenContext(ctx context.Context, addr Addr) (net.Listener, error)
- func (_m *MockNetworker) Ping(pk cipher.PubKey, addr Addr) (net.Conn, error)
- func (_m *MockNetworker) PingContext(ctx context.Context, pk cipher.PubKey, addr Addr) (net.Conn, error)
- type Networker
- type PacketNetworker
- type RawTCPForwardConn
- type RouteHopInfo
- type SkywireConn
- func (c *SkywireConn) BandwidthReceived() uint64
- func (c *SkywireConn) BandwidthSent() uint64
- func (c *SkywireConn) Close() error
- func (c *SkywireConn) DownloadSpeed() uint32
- func (c *SkywireConn) GetError() error
- func (c *SkywireConn) IsAlive() bool
- func (c *SkywireConn) Latency() time.Duration
- func (c *SkywireConn) RouteHopDetails() []router.RouteHopInfo
- func (c *SkywireConn) RouteHops() []cipher.PubKey
- func (c *SkywireConn) SetError(err error)
- func (c *SkywireConn) SetForwardHops(hops []routing.Hop)
- func (c *SkywireConn) UploadSpeed() uint32
- type SkywireNetworker
- func (r *SkywireNetworker) Dial(addr Addr) (net.Conn, error)
- func (r *SkywireNetworker) DialContext(ctx context.Context, addr Addr) (conn net.Conn, err error)
- func (r *SkywireNetworker) DialContextWithOptions(ctx context.Context, addr Addr, opts *router.DialOptions) (conn net.Conn, err error)
- func (r *SkywireNetworker) DialPacketContext(ctx context.Context, addr Addr) (_ DatagramPacketConn, err error)
- func (r *SkywireNetworker) Listen(addr Addr) (net.Listener, error)
- func (r *SkywireNetworker) ListenContext(ctx context.Context, addr Addr) (net.Listener, error)
- func (r *SkywireNetworker) Ping(pk cipher.PubKey, addr Addr) (net.Conn, error)
- func (r *SkywireNetworker) PingContext(ctx context.Context, pk cipher.PubKey, addr Addr) (net.Conn, error)
- func (r *SkywireNetworker) PingContextWithOpts(ctx context.Context, pk cipher.PubKey, addr Addr, opts *router.DialOptions) (net.Conn, error)
- func (r *SkywireNetworker) Router() router.Router
- func (r *SkywireNetworker) SetAppDirectMux(mux *transport.VStreamMux)
- type Type
- type WrappedConn
Constants ¶
This section is empty.
Variables ¶
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) )
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.
var ( // ErrNoSuchNetworker is being returned when there's no suitable networker. ErrNoSuchNetworker = errors.New("no such networker") )
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.
var ( // ErrUnknownAddrType is returned when trying to convert the // unknown addr type. ErrUnknownAddrType = errors.New("addr type is unknown") )
Functions ¶
func AddNetworker ¶
AddNetworker associates Networker with the `network`.
func AddRawTCPForwarding ¶
func AddRawTCPForwarding(fwd *RawTCPForwardConn)
AddRawTCPForwarding adds RawTCPForwardConn with its ID
func AppNameFromContext ¶
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 DialContext ¶
DialContext dials the remote `addr` with the context.
func DialLocalService ¶ added in v1.3.99
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 ¶
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
HasLocalService reports whether addr names a registered local service.
func IsCarrierDial ¶
IsCarrierDial reports whether ctx was marked by WithCarrierDial.
func ListenContext ¶
ListenContext starts listening on the local `addr` with the context.
func PingContext ¶
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 ¶
RemoveRawTCPForwardConn removes a RawTCPForwardConn by ID
func UnregisterLocalService ¶ added in v1.3.99
UnregisterLocalService removes the handler on pk:port. No-op if none.
func WithAppName ¶
WithAppName returns a derived context that carries the given app name. SkywireNetworker reads it via AppNameFromContext.
func WithCarrierDial ¶
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.
Types ¶
type Addr ¶
Addr implements net.Addr for network addresses.
func ConvertAddr ¶
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.
type ConnDialer ¶
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 ¶
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 ¶
ListenContext starts listening on local `addr` in the dmsg network with context.
type LocalHandler ¶ added in v1.3.99
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 ¶
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 ¶
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 ¶
ListenContext provides a mock function with given fields: ctx, 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 ¶
NewDMSGNetworker constructs new `DMSGNetworker`.
func NewSkywireNetworker ¶
func NewSkywireNetworker(l logrus.FieldLogger, r router.Router) Networker
NewSkywireNetworker constructs skywire networker.
func ResolveNetworker ¶
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 ¶
RouteHopInfo contains detailed information about a single hop in a route.
type SkywireConn ¶
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) 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 ¶
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 ¶
ListenContext starts listening on local `addr` in the skynet with context.
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.
type WrappedConn ¶
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.