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§
Sourceasync fn start(&mut self) -> Result<(), NetworkError>
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.
Sourceasync fn stop(&mut self) -> Result<(), NetworkError>
async fn stop(&mut self) -> Result<(), NetworkError>
Stop the network provider and clean up all resources.
Sourcefn local_identity(&self) -> NodeIdentity
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.
Sourcefn local_addr(&self) -> PeerAddr
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.
Sourcefn peer_events(&self) -> Receiver<NetworkPeerEvent>
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.
Sourceasync fn peers(&self) -> Vec<NetworkPeer>
async fn peers(&self) -> Vec<NetworkPeer>
Snapshot of all currently known peers.
Sourceasync fn dial_tcp(
&self,
addr: &str,
port: u16,
) -> Result<TcpStream, NetworkError>
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.
Sourceasync fn listen_tcp(
&self,
port: u16,
) -> Result<NetworkTcpListener, NetworkError>
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.
Sourceasync fn unlisten_tcp(&self, port: u16) -> Result<(), NetworkError>
async fn unlisten_tcp(&self, port: u16) -> Result<(), NetworkError>
Stop listening on a previously opened port.
Sourceasync fn bind_udp(&self, port: u16) -> Result<NetworkUdpSocket, NetworkError>
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.
Sourceasync fn ping(&self, addr: &str) -> Result<PingResult, NetworkError>
async fn ping(&self, addr: &str) -> Result<PingResult, NetworkError>
Ping a peer via the network layer (Tailscale TSMP).
Sourceasync fn health(&self) -> HealthInfo
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.