Skip to main content

NetworkProvider

Trait NetworkProvider 

Source
pub trait NetworkProvider: Send + Sync {
    // Required methods
    async fn start(&mut self) -> Result<(), NetworkError>;
    async fn stop(&mut self) -> Result<(), NetworkError>;
    fn local_identity(&self) -> NodeIdentity;
    fn local_addr(&self) -> PeerAddr;
    fn peer_events(&self) -> Receiver<NetworkPeerEvent>;
    async fn peers(&self) -> Vec<NetworkPeer>;
    async fn dial_tcp(
        &self,
        addr: &str,
        port: u16,
    ) -> Result<TcpStream, NetworkError>;
    async fn listen_tcp(
        &self,
        port: u16,
    ) -> Result<NetworkTcpListener, NetworkError>;
    async fn unlisten_tcp(&self, port: u16) -> Result<(), NetworkError>;
    async fn bind_udp(
        &self,
        port: u16,
    ) -> Result<NetworkUdpSocket, NetworkError>;
    async fn ping(&self, addr: &str) -> Result<PingResult, NetworkError>;
    async fn health(&self) -> HealthInfo;
}
Expand description

Provides network-level peer discovery and raw connectivity.

The primary implementation is TailscaleProvider which uses tsnet via a Go sidecar. The trait is designed to be swappable — future providers could use mDNS (LAN), STUN/TURN (internet), or Bluetooth.

§Layer rules

  • Layer 3 does NOT know about WebSocket, QUIC, or any Layer 4 protocol
  • Layer 3 does NOT know about envelopes, namespaces, or messages
  • Layer 3 provides raw TcpStream — not framed connections
  • peer_events() is the ONLY source of peer events — no polling, no announce

Required Methods§

Source

async fn start(&mut self) -> Result<(), NetworkError>

Start the network provider.

This spawns child processes, binds ports, and performs authentication. If authentication is required (e.g., Tailscale browser auth), the provider emits NetworkPeerEvent::AuthRequired { url } via peer_events() and keeps waiting until auth completes or the timeout is reached.

Callers should subscribe to peer_events() BEFORE calling start() to receive auth URLs and display them to the user.

Returns Ok(()) when the provider is fully online, or Err if auth times out or a fatal error occurs.

Source

async fn stop(&mut self) -> Result<(), NetworkError>

Stop the network provider and clean up all resources.

Source

fn local_identity(&self) -> NodeIdentity

Local node’s identity (stable ID, hostname, display name).

Returns a clone of the current cached identity. The identity is populated after start() completes and may be updated when the sidecar reports tsnet:status.

Source

fn local_addr(&self) -> PeerAddr

Local node’s network address.

Returns a clone of the current cached address. The address is populated after start() completes and may be updated when the sidecar reports tsnet:status.

Source

fn peer_events(&self) -> Receiver<NetworkPeerEvent>

Subscribe to peer events. Fires immediately when peers join/leave/update.

Uses WatchIPNBus for real-time notifications instead of polling.

Source

async fn peers(&self) -> Vec<NetworkPeer>

Snapshot of all currently known peers.

Source

async fn dial_tcp( &self, addr: &str, port: u16, ) -> Result<TcpStream, NetworkError>

Dial a TCP connection to a peer via the encrypted Tailscale tunnel.

Returns a plain TcpStream — all bridge internals (pending_dials, session token, binary headers) are hidden inside the provider.

Source

async fn listen_tcp( &self, port: u16, ) -> Result<NetworkTcpListener, NetworkError>

Listen for incoming TCP connections on a port via the Tailscale tunnel.

The returned receiver yields TcpStreams for each accepted connection.

Source

async fn unlisten_tcp(&self, port: u16) -> Result<(), NetworkError>

Stop listening on a previously opened port.

Source

async fn bind_udp(&self, port: u16) -> Result<NetworkUdpSocket, NetworkError>

Bind a UDP socket on a port via the network tunnel.

Returns a NetworkUdpSocket that transparently relays datagrams through the network provider. The socket supports send_to / recv_from with full remote address information.

Not all providers support UDP. Returns NetworkError::Internal if the provider has not implemented UDP transport yet.

Source

async fn ping(&self, addr: &str) -> Result<PingResult, NetworkError>

Ping a peer via the network layer (Tailscale TSMP).

Source

async fn health(&self) -> HealthInfo

Node health info (key expiry, connection quality, warnings).

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§