Handshake and observability knobs
Four server options that do not change what a connection carries, only how it gets there and what gets logged alongside it: session-ticket resumption, RFC 9000 8.1.2 Retry, the congestion controller, and qlog/NSS key log output.
Code
#define WIRED_MAIN#include "wired.h"
static int on_request( void* ctx, const wired_h3reqdrive_req* req, u64 offset, wired_obuf* body_out, const char** content_type, int* more, u64* total_size) { (void)ctx; (void)req; (void)offset; (void)more; (void)total_size; wired_log_str("request /\n"); *content_type = "text/plain"; wired_obuf_printf(body_out, "ok"); return 1;}
int wired_main(int argc, char** argv) { /* The same fixed demo identity as the HTTP/3 hello page. */ static wired_srvboot_demo_keys keys; wired_srvboot_id id; wired_srvboot_demo(&id, &keys, 0x50, "guide-h3"); /* Non-0 enables session-ticket resumption/0-RTT (RFC 8446 4.6.1): the * SDK's per-process ticket seed; the sealing side and this id derive the * same rotating ticket keys from it. */ id.ticket_key = wired_srvloop_ticket_key();
wired_srvrun_opt opt = {0}; opt.incoming_cpu = -1; /* RFC 9000 8.1.2: answer every Initial with a stateless Retry first, * only accepting one that carries a valid Retry token. */ opt.force_retry = 1;
wired_srvrun_obs obs = { "demo.qlog", /* RFC 9002-shaped packet_sent/packet_received events */ "demo.keylog", /* SSLKEYLOGFILE, decrypts a capture in Wireshark */ 0, 0, 1, /* CC_ALGO_CUBIC (see transport/recovery/congestion/cc/cc.h); * 0 = NewReno, 2 = BBR */ };
u16 port = (u16)wired_cliargs_int(argc, argv, "--port", 4433); wired_srvrun_handler h = {.cb = on_request}; return wired_server_run_opt(port, &id, h, obs, &opt) ? 0 : 1;}Output
$ ./ops-handshake-knobs --port 4433request /conn closed by peer (CONNECTION_CLOSE)$ probe h3get 127.0.0.1:4433 /GET / status=200 content-type=text/plain body="ok"How it works
Section titled “How it works”id.ticket_key = wired_srvloop_ticket_key()enables session-ticket resumption (RFC 8446 4.6.1, 0-RTT’s prerequisite). The ticket key is derived from the SDK’s per-process seed and rotates every two hours: the current key seals new tickets, and the current or previous key opens presented ones. A ticket older than that is ignored and the client gets a full handshake.opt.force_retry = 1makes every Initial without a valid Retry token get a stateless Retry first (RFC 9000 8.1.2) – the quic-interop-runner’s retry testcase’s server mode. A real client handles this transparently; the handshake still completes, just with one extra round trip.obs.cc_algopicks the congestion controller for fresh connections (CC_ALGO_NEWRENO0,CC_ALGO_CUBIC1,CC_ALGO_BBR2, seetransport/recovery/congestion/cc/cc.h);0with no build override means Cubic (WIRED_CC_ALGO_DEFAULTin srvrun.c), since an explicit runtime NewReno request is itself0and indistinguishable from “unset” – a build wanting NewReno by default overrides-DWIRED_CC_ALGO_DEFAULT=0instead.obs.qlog_path/obs.keylog_pathwrite a qlog (RFC 9002-shapedpacket_sent/packet_receivedevents) and an NSS key log (SSLKEYLOGFILEformat) a tool like Wireshark reads to decrypt a capture – both 0 by default.