TLS
Introduction
xpp::net::TlsConfig and TlsContext provide RAII TLS configuration. Pass a TlsContext to TcpStream::connect() to enable TLS — the handshake is transparent.
Example — .await()
#include <xpp/net/tls.h>
xpp::EventLoop loop;
xpp::WaitScope scope(loop);
xpp::net::TlsContext ctx(xpp::net::TlsConfig::client());
auto conn = xpp::net::TcpStream::connect("example.com:443", ctx).await();
Example — co_await (C++20)
xpp::net::TlsContext ctx(xpp::net::TlsConfig::client());
auto conn = co_await xpp::net::TcpStream::connect("example.com:443", ctx);
API Reference
TlsConfig
| Method | Returns | Description |
|---|---|---|
client() | TlsConfig | Client defaults (system CA, verify on) |
client_insecure() | TlsConfig | Client that skips peer verification |
server(cert, key) | TlsConfig | Server config with cert + key paths |
server(cert, key, ca) | TlsConfig | Server config with CA (for mTLS) |
with_cert(path) | TlsConfig& | Builder: set cert path |
with_key(path) | TlsConfig& | Builder: set key path |
with_ca(path) | TlsConfig& | Builder: set CA path |
with_key_password(pw) | TlsConfig& | Builder: set key password |
with_alpn(protocols) | TlsConfig& | Builder: set ALPN list |
with_skip_verify(bool) | TlsConfig& | Builder: toggle verification |
raw() | const xTlsConf* | Underlying libx config |
Each with_* builder has two overloads, selected by ref-qualifier:
with_*(...) &→ returnsTlsConfig&, modifies in-place (lvalue chain)with_*(...) &&→ returnsTlsConfig&&, enables move (rvalue chain)
// Rvalue chain: temporary factory → && overloads → move at end
auto conf = TlsConfig::client().with_cert(...).with_key(...);
// Lvalue chain: named variable → & overloads → modify in-place
TlsConfig conf = TlsConfig::client();
conf.with_ca("/custom/ca.pem").with_alpn({"h2", "http/1.1"});
TlsContext
| Method | Returns | Description |
|---|---|---|
TlsContext(conf) | TlsContext | Create context from TlsConfig |
TlsContext(xTlsConf*) | TlsContext | Create from raw libx config |
reload(conf) | int | Hot-reload certificates (0 = success) |
raw() | xTlsCtx | Underlying libx context |
is_valid() | bool | Construction succeeded |
operator bool() | bool | Same as is_valid() |
How it works
TlsConfig is a builder that owns the string storage (cert path, key path, CA path, key password, ALPN protocols). It wraps xTlsConf (a POD of pointers).
TlsContext calls xTlsCtxCreate in its constructor and xTlsCtxDestroy in its destructor. The mode (client or server) is determined automatically by libx: if both cert and key are set, server mode; otherwise client mode.
When passed to TcpStream::connect(), the xTlsCtx handle is set in xTcpConnectConf::tls_ctx. libx's xTcpConnect does the TLS handshake transparently.
Usage Examples
Client with system CA — .await()
xpp::net::TlsContext tls(xpp::net::TlsConfig::client());
auto conn = xpp::net::TcpStream::connect("example.com:443", tls).await();
conn.write("GET / HTTP/1.0\r\n\r\n", 18).await();
Client with system CA — co_await (C++20)
xpp::Promise<void> https_fetch() {
xpp::net::TlsContext tls(xpp::net::TlsConfig::client());
auto conn = co_await xpp::net::TcpStream::connect("example.com:443", tls);
co_await conn.write("GET / HTTP/1.0\r\nHost: example.com\r\n\r\n", 40);
char buf[4096];
ssize_t n = co_await conn.read(buf, sizeof(buf));
printf("%.*s\n", (int)n, buf);
}
Server with certificate
xpp::net::TlsContext tls(xpp::net::TlsConfig::server("cert.pem", "key.pem"));
Builder pattern
xpp::net::TlsConfig conf = xpp::net::TlsConfig::client()
.with_ca("/custom/ca.pem")
.with_alpn({"h2", "http/1.1"});
xpp::net::TlsContext ctx(conf);
mTLS (mutual TLS)
xpp::net::TlsContext server_tls(
xpp::net::TlsConfig::server("server.pem", "server.key", "ca.pem"));
xpp::net::TlsConfig client_conf = xpp::net::TlsConfig::client()
.with_cert("client.pem").with_key("client.key");
xpp::net::TlsContext client_tls(client_conf);
Connect with error handling — .await()
xpp::net::TlsContext tls(xpp::net::TlsConfig::client());
auto conn = xpp::net::TcpStream::connect("example.com:443", tls).await();
if (!conn.is_open()) { /* handle failure */ }
conn.write("hello", 5).await();
Connect with error handling — co_await (C++20)
xpp::Promise<void> connect_or_fallback() {
xpp::net::TlsContext tls(xpp::net::TlsConfig::client());
auto conn = co_await xpp::net::TcpStream::connect("example.com:443", tls);
if (!conn.is_open()) { co_return; }
co_await conn.write("hello", 5);
}