Skip to main content

Crate networkframework

Crate networkframework 

Source
Expand description

§networkframework-rs

Safe Rust bindings for Apple’s Network.framework, backed by a Swift bridge plus an opt-in raw FFI surface.

SDK coverage: 500 / 500 SDK symbols verified, macOS 26.2 SDK. See COVERAGE.md for the logical-area map and COVERAGE_AUDIT.md for the symbol-by-symbol audit.

§Why this crate

  • Broad transport coverage: TCP clients and listeners, UDP, TLS, QUIC, WebSocket, and Bonjour discovery/advertising all live in one safe crate.
  • More than sockets: endpoints, connection parameters, path monitoring, content contexts, framers, connection groups, privacy contexts, and resolver / proxy configuration are part of the public safe API.
  • Async where it helps: this is the Tier 1 crate with a native async/await story for Network.framework event streams.
  • Runtime-gated APIs handled for you: newer framework features stay safe, and unsupported runtime combinations surface as Rust errors instead of raw Objective-C / C state leaking upward.
  • Escape hatch available: enable raw-ffi when you need direct bridge access beyond the safe wrappers.

§Feature flags

  • Default: safe blocking + callback-oriented API.
  • async: enables networkframework::async_api stream wrappers.
  • raw-ffi: exposes networkframework::raw_ffi::*.

§Installation

[dependencies]
networkframework = "0.13.1"

Enable async support explicitly when you want awaitable event streams:

[dependencies]
networkframework = { version = "0.13.1", features = ["async"] }

§Async usage

The networkframework::async_api module turns callback-based Network.framework notifications into executor-agnostic Rust futures/streams. It does not lock you into Tokio, async-std, or any other runtime-specific public API. Instead, the crate uses doom-fish-utils async primitives (doom_fish_utils::completion helpers plus the stream-based next().await surface) so the same types compose with whatever executor your application already uses.

Today the async surface includes:

  • ConnectionStateStream
  • ConnectionViabilityStream
  • ConnectionBetterPathStream
  • ConnectionPathChangedStream
  • ListenerEventStream
  • PathUpdateStream
  • BrowserEventStream

A minimal async round trip can use an awaitable listener stream while keeping transport I/O on the same TcpClient / accepted-connection types as the sync API:

use networkframework::async_api::{ListenerEvent, ListenerEventStream};
use networkframework::{TcpClient, TcpListener};

async fn run() -> Result<(), networkframework::NetworkError> {
    let listener = TcpListener::bind(0)?;
    let port = listener.local_port();
    let events = ListenerEventStream::subscribe(&listener, 8);

    let client = TcpClient::connect("127.0.0.1", port)?;
    client.send(b"ping")?;

    while let Some(event) = events.next().await {
        match event {
            ListenerEvent::NewConnection(server) => {
                let request = server.receive(1024)?;
                assert_eq!(request, b"ping");
                server.send(b"pong")?;
                break;
            }
            ListenerEvent::State { .. } => {}
        }
    }

    let reply = client.receive(1024)?;
    assert_eq!(reply, b"pong");
    Ok(())
}

For tiny binaries, pollster::block_on(run()) is often enough. In larger applications, just await the same stream types from your existing runtime. The bundled 07_async_streams example shows PathUpdateStream and ConnectionStateStream in practice.

§Sync / callback usage

The original API remains small and direct for request / response flows. If you prefer a blocking round trip, the same TCP primitives work without any feature flags:

use networkframework::{TcpClient, TcpListener};

fn main() -> Result<(), networkframework::NetworkError> {
    let listener = TcpListener::bind(0)?;
    let port = listener.local_port();
    let server = std::thread::spawn(move || -> Result<(), networkframework::NetworkError> {
        let connection = listener.accept()?;
        let request = connection.receive(1024)?;
        assert_eq!(request, b"ping");
        connection.send(b"pong")?;
        Ok(())
    });

    let client = TcpClient::connect("127.0.0.1", port)?;
    client.send(b"ping")?;
    let reply = client.receive(1024)?;
    assert_eq!(reply, b"pong");

    server.join().expect("server thread")?;
    Ok(())
}

Callback-oriented APIs are still available for long-lived observers and framework-managed events. Common entry points include start_path_monitor, start_browser_with_descriptor, start_browser_results_with_descriptor, advertise_with_descriptor, and the various set_*_handler hooks on connection, group, and protocol types.

§Examples

The repository ships runnable examples across the main areas of the crate:

  • 01_get_example — local TCP listener/client round trip.
  • 02_tls_getConnectionParameters policy tuning and protocol stacking.
  • 03_udp_and_path — UDP parameters, endpoint construction, and path monitor snapshots.
  • 04_bonjour — Bonjour browse descriptors and browser events.
  • 05_websocket — WebSocket protocol definitions plus QUIC option inspection.
  • 06_bonjour_advertise — Bonjour advertising with TXT records.
  • 07_async_streams — async stream subscriptions for path and connection events (--features async).
  • framer_length_prefix — custom length-prefixed framer wiring.
  • interface_list — enumerating local network interfaces.
  • connection_group — multicast connection groups and state callbacks.
  • content_context_overview — content-context identifiers, priorities, and antecedents.
  • resolver_overview — DNS-over-HTTPS and DNS-over-TLS resolver configs.
  • privacy_context_overview — encrypted name resolution plus proxy policy.
  • quic_options — QUIC transport tuning and ALPN setup.

Run any example directly:

cargo run --example 01_get_example
cargo run --example 07_async_streams --features async

§Coverage and audit

  • COVERAGE.md — logical-area coverage map, example links, and test references.
  • COVERAGE_AUDIT.md — full audited SDK symbol table for the macOS 26.2 headers.

§Availability notes

Some Apple APIs are runtime-gated by the operating system:

  • Application-service browsing / advertising / parameters: macOS 13+
  • Relay and Oblivious HTTP proxy configuration: macOS 14+
  • Ultra-constrained path / parameter flags and link quality: newer SDK/runtime combinations

The safe wrappers return NetworkError::InvalidArgument when a requested API is unavailable at runtime.

§Validation

cargo build --all-features
cargo clippy --all-targets --all-features -- -D warnings

§Status

Actively developed. Targets macOS and tracks the audited Network.framework SDK surface closely.

§License

Licensed under either of:

at your option.


§API documentation

Re-exports§

pub use advertise_descriptor::advertise_with_descriptor;
pub use advertise_descriptor::AdvertiseDescriptor;
pub use advertise_descriptor::Advertiser;
pub use browser::advertise_bonjour_service;
pub use browser::start_browser;
pub use browser::start_browser_results_with_descriptor;
pub use browser::start_browser_with_descriptor;
pub use browser::BonjourAdvertiser;
pub use browser::BrowseDescriptor;
pub use browser::BrowseResult;
pub use browser::BrowseResultChange;
pub use browser::BrowseResultsBrowser;
pub use browser::Browser;
pub use browser::BrowserEvent;
pub use browser::BrowserState;
pub use browser::DiscoveredService;
pub use client::ContentContext;
pub use client::ReceivedContent;
pub use client::TcpClient;
pub use connection::Connection;
pub use connection_group::ConnectionGroup;
pub use connection_group::ConnectionGroupDescriptor;
pub use connection_group::ConnectionGroupMessage;
pub use connection_group::ConnectionGroupState;
pub use connection_report::DataTransferPathReport;
pub use connection_report::DataTransferReport;
pub use connection_report::DataTransferReportState;
pub use connection_report::EstablishmentProtocol;
pub use connection_report::EstablishmentReport;
pub use connection_report::ResolutionProtocol;
pub use connection_report::ResolutionReport;
pub use connection_report::ResolutionSource;
pub use connection_report::ResolutionStep;
pub use endpoint::Endpoint;
pub use endpoint::EndpointType;
pub use error::ErrorDomain;
pub use error::FrameworkError;
pub use error::NetworkError;
pub use ethernet_channel::EthernetChannel;
pub use ethernet_channel::EthernetChannelState;
pub use ethernet_channel::EthernetFrame;
pub use framer::Framer;
pub use framer::FramerContext;
pub use framer::FramerDefinition;
pub use framer::FramerMessage;
pub use framer::FramerMessageView;
pub use framer::FramerOptions;
pub use framer::FramerStart;
pub use group::Group;
pub use group::GroupDescriptor;
pub use group::GroupMessage;
pub use group::GroupState;
pub use interface::list_interfaces;
pub use interface::InterfaceType;
pub use interface::NetworkInterface;
pub use listener::TcpListener;
pub use parameters::ConnectionParameters;
pub use parameters::ParametersAttribution;
pub use path::LinkQuality;
pub use path::Path;
pub use path::PathStatus;
pub use path::PathUnsatisfiedReason;
pub use path_monitor::start_path_monitor;
pub use path_monitor::start_path_monitor_for_ethernet_channel;
pub use path_monitor::start_path_monitor_with_type;
pub use path_monitor::PathMonitor;
pub use path_monitor::PathUpdate;
pub use privacy::PrivacyContext;
pub use privacy::ProxyConfig;
pub use privacy::RelayHop;
pub use privacy::ResolverConfig;
pub use privacy::UrlSessionConfiguration;
pub use protocol::IpEcnFlag;
pub use protocol::IpLocalAddressPreference;
pub use protocol::IpVersion;
pub use protocol::ProtocolDefinition;
pub use protocol::ProtocolMetadata;
pub use protocol::ProtocolOptions;
pub use protocol::TcpMultipathVersion;
pub use quic::QuicConnection;
pub use quic::QuicOptions;
pub use txt_record::TxtRecord;
pub use txt_record::TxtRecordEntry;
pub use txt_record::TxtRecordFindResult;
pub use txt_record::TxtRecordLookup;
pub use udp::UdpClient;
pub use websocket::Opcode;
pub use websocket::WebSocket;
pub use websocket::WsCloseCode;
pub use websocket::WsMessage;
pub use websocket::WsRequest;
pub use websocket::WsResponse;
pub use websocket::WsResponseStatus;
pub use websocket::WsVersion;

Modules§

advertise_descriptor
Advertise-descriptor helpers.
async_apiasync
Async stream wrappers for Network.framework callback-based APIs.
browser
Browser — Bonjour and application-service discovery via nw_browser.
client
TcpClient — synchronous outbound TCP connection via Network.framework.
connection
Connection-oriented helpers and aliases.
connection_group
Connection groups built on nw_connection_group_*.
connection_report
Connection establishment and data-transfer reports.
content_context
Content-context aliases.
endpoint
Endpoint helpers backed by nw_endpoint_t.
error
Errors raised by networkframework.
ethernet_channel
Ethernet channel wrappers.
framer
Custom protocol framers built on nw_framer_*.
group
Connection-group aliases.
interface
Network interface enumeration helpers.
listener
TcpListener — synchronous TCP listener via Network.framework.
parameters
Configurable nw_parameters wrappers for advanced connections.
path
Path snapshots backed by nw_path_t.
path_monitor
PathMonitor — observe network reachability and interface changes via nw_path_monitor.
prelude
Common imports.
privacy
Privacy contexts, proxy configuration, and encrypted resolver settings.
privacy_context
Privacy-context aliases.
protocol
Protocol definitions and options.
proxy_config
Proxy-configuration aliases.
quic
QUIC helpers backed by Network.framework.
raw_ffiraw-ffi
Raw FFI ABI surface for advanced callers.
resolver
Resolver aliases.
txt_record
TXT-record helper APIs.
udp
UdpClient — connected-mode UDP via Network.framework.
websocket
WebSocket — RFC 6455 WebSocket client over Network.framework.

Structs§

ProtocolStack
Mutable wrapper around nw_protocol_stack_t.
QuicMetadata
QUIC protocol metadata attached to a connection or content context.
SecurityProtocolMetadata
Opaque sec_protocol_metadata_t extracted from QUIC metadata.
SecurityProtocolOptions
Opaque sec_protocol_options_t extracted from QUIC options.

Enums§

ExpiredDnsBehavior
Policy controlling whether expired DNS answers may be used.
InterfaceRadioType
Radio technology reported for an interface path sample.
MultipathService
Multipath policy applied to new connections.
QuicStreamType
QUIC stream direction or datagram mode.
ServiceClass
Connection service class applied to new paths.