Networking
Connecting to and exposing network services.
Networking in Selium is capability-driven. Guests access the host network stack through selium_userland::net, but only when you grant the relevant Net* capabilities. The goal is to make network I/O feel straightforward without granting hidden authority.
Supported protocols:
NetProtocol::Quic(QUIC over UDP with TLS 1.3)NetProtocol::Http(HTTP/1.1 over TCP)NetProtocol::Https(HTTP/1.1 over TLS 1.3)- many more in development
TLS configuration is explicit. You register configs with TlsServerConfig::register and TlsClientConfig::register (gated by NetTlsServerConfig and NetTlsClientConfig capabilities):
const TLS_CERT_PEM: &[u8] = include_bytes!("../server-cert.pem");
const TLS_KEY_PEM: &[u8] = include_bytes!("../server-key.pem");
let tls_bundle = TlsServerBundle {
cert_chain_pem: TLS_CERT_PEM.to_vec(),
private_key_pem: TLS_KEY_PEM.to_vec(),
client_ca_pem: None,
alpn: Some(vec!["http/1.1".to_string()]), // http/2 requires more boilerplate r/n
require_client_auth: false,
};
let tls_config = TlsServerConfig::register(tls_bundle).await?;
let listener = HttpsListener::bind_with_tls(domain, port, &tls_config).await?;Selium is still early here. Expect improvements and higher-level helpers over time.
HTTP payloads
HTTP connections surface complete request/response payloads as raw bytes. When you read or write frames, you are responsible for parsing or formatting HTTP messages yourself. (Chunked transfer encoding is not supported yet.)
Again, Selium is very early here, so you can expect this to improve dramatically over time.
Channels
Network connections are not channels, but they intentionally feel similar, behaving like Stream/Sink pairs. If you want to integrate them into your channel-based architecture, you can bridge them explicitly:
For example (from the load-balancer example):
let lb: Fanout<Connection> = Fanout::create(&switchboard).await?;
let listener = HttpListener::bind(domain, port).await?;
listener
.incoming()
.and_then(|mut conn| async move {
conn.prepare_for_transfer().await?; // must be called first
Ok(conn)
})
.map_err(SwitchboardError::Driver)
.forward(lb)
.await?;