Using TLS Server Connections
An accepted TLS server starts with a transferable TCP request and becomes an application byte stream only after it has authenticated client Finished. This page shows how to share connection capacity across listeners, limit incomplete handshakes separately, select immutable identities by exact SNI, inspect ClientHello policy, and shut down without truncating TLS.
Registering Default and Exact Identities
Load protected server identities once during application startup and register complete TLS configurations under labels. The default label is required; exact SNI mappings may select other labels:
auto defaultTls = cryptology::TlsConfiguration{};
defaultTls.setServerIdentity(loadIdentity("default-chain.pem"_el, "default-key.pem"_el));
core::application().cryptologyConfiguration().setTlsConfiguration(
"tls/server"_el, std::move(defaultTls));
auto apiTls = cryptology::TlsConfiguration{};
apiTls.setServerIdentity(loadIdentity("api-chain.pem"_el, "api-key.pem"_el));
core::application().cryptologyConfiguration().setTlsConfiguration(
"tls/server/api"_el, std::move(apiTls));
accept() resolves and captures every configured label before consuming the TCP request.
Replacing a registry entry therefore affects later accepts without changing an in-progress handshake.
SNI names use canonical HostName equality, so Unicode and IDNA ASCII spellings select the same exact entry.
An absent or unmatched SNI selects the required default identity.
An exact identity that cannot use any offered signature scheme fails the handshake instead of falling back.
Accepting TLS and Inspecting ClientHello
Create one TLS source for each emitted TCP request. The ClientHello checkpoint runs after bounded parsing and exact identity, ALPN, cipher, and signature selection, but before the server creates secrets or emits its flight:
publicListener->events().onConnection(
[events, handshakeQuota](network::TcpConnectionRequestPtr request) {
auto connection = events->get<network::Network>().createTlsServerConnection();
connection->events()
.onTransportConnected([]() {
// TCP is connected; TLS is not authenticated.
})
.onClientHello([connection]() {
inspect(
connection->serverName(),
connection->offeredAlpn(),
connection->requestedConfigurationLabel(),
connection->matchedConfigurationLabel());
})
.onHandshakeCompleted([connection]() {
beginApplicationProtocol(connection);
});
auto options = network::TlsServerAcceptOptions{handshakeQuota};
options.setIdentityMappings({
{network::HostName::fromStringOrThrow("api.example.test"_el), "tls/server/api"_el}})
.setAlpnProtocols({"http/1.1"_el});
connection->accept(std::move(request), std::move(options));
});
Calling abort() in onTransportConnected or onClientHello prevents the next transition and emits no server
flight.
A full handshake quota rejects the request and reports ResourceLimitExceeded in the Accepting phase on the TLS
source.
Back-Pressure and Graceful Shutdown
Application sends begin only in Active and accept at most 16 KiB atomically.
Keep a rejected block and retry it from onWritable.
pauseReceiving() stops application delivery and propagates the pause through TLS into TCP while all retained bytes
remain within the configured TLS and transport limits.
close() sends close_notify and waits for the peer notification before closing TCP.
If the peer starts closure, the source replies before finalizing.
A bare TCP EOF is reported as TLS truncation.
Successful closure calls onClosed with the first closure origin and then calls onFinal exactly once; failure
calls onError followed by onFinal.