pub struct QuicDialOptions {
pub skip_cert_verification: bool,
pub ca_certs: Vec<Vec<u8>>,
pub alpn: Vec<Vec<u8>>,
pub wt_protocols: Vec<Vec<u8>>,
pub on_peer_certificates: Option<CertificateHook>,
pub cipher_suites: Option<Vec<u16>>,
}Expand description
How a QUIC dial is configured, independent of any draft.
alpn is a list because ALPN is: one handshake offers several protocols and
the server picks, which is how a caller that does not know a peer’s draft
finds out without dialling once per candidate.
Fields§
§skip_cert_verification: boolSkip TLS certificate verification. Testing only.
ca_certs: Vec<Vec<u8>>Additional CA certificates to trust, DER-encoded, on top of the bundled Mozilla roots every dial starts from, on either transport.
alpn: Vec<Vec<u8>>ALPN protocols to offer, in preference order.
dial_quic returns the one the server selected. An empty list offers
nothing and is refused by any peer that requires ALPN, which every MoQT
relay does.
A WebTransport dial ignores this field: that session is HTTP/3 by
definition and offers h3 alone, so the protocol name a WebTransport
session negotiates is WT-Available-Protocols and not this. See
wt_protocols. Everything else here applies to
both transports.
wt_protocols: Vec<Vec<u8>>MOQT protocol identifiers to offer in the WT-Available-Protocols
header of a WebTransport dial, in preference order.
WebTransport’s answer to ALPN, and the reason a MoQT draft can be
negotiated over it at all. Drafts 15 and later state it in one sentence:
“MOQT uses ALPN in QUIC and WT-Available-Protocols in WebTransport
([WebTransport], Section 3.3) to perform version negotiation” —
draft-15 cites Section 3.4 of the same document and is otherwise
word-for-word. Drafts 18 through 20 add the client’s half of it: “The
client includes MOQT protocol identifiers in the WT-Available-Protocols
header”. The identifiers are the ALPN names: moqt-15 … moqt-20.
Empty for drafts 07 through 14, which predate the header and settle their version in CLIENT_SETUP instead. Empty is not the same as absent by accident: a server that implements the negotiation and receives no offer has nothing to select, and may reject the session outright. imquic does, in as many words — “No WebTransport protocol offered”.
Ignored by a QUIC dial, where alpn carries the same
names.
§Reading the answer needs a patched wtransport
A server names its choice in a WT-Protocol response header, and
upstream wtransport 0.7 drops the CONNECT response once it has judged
the status code. Transport::wt_protocol reads it — spelled as code
because it exists only behind this crate’s wt-protocol feature, and a
link to it would be broken in every build without that feature. The
feature requires the patch in moqtap/vendor/wtransport and does not
build without it.
Without that feature an accepted session says only that the server took one of the offers or ignored the header, and only a rejected one is conclusive — conclusive, then, about every identifier offered.
on_peer_certificates: Option<CertificateHook>Called with the peer’s certificate chain during the handshake, before
it is judged — so it runs even for a chain that is about to be
rejected, which is the case it exists for. See CertificateHook.
cipher_suites: Option<Vec<u16>>Restrict the TLS 1.3 cipher suites offered, by IANA codepoint.
None offers the crypto provider’s full set, which is what an ordinary
client does and what every caller but a measuring one wants.
Some exists because the negotiated suite cannot be read back.
quinn’s HandshakeData carries the ALPN and the server name and nothing
else, and rustls does not surface the suite through it — so the only way
to learn which suite a peer accepts is to offer exactly one and see
whether the handshake completes. A successful dial is the measurement.
Codepoints rather than a rustls enum so that a rustls upgrade cannot
change this crate’s public API. The three TLS 1.3 suites are 0x1301
AES-128-GCM-SHA256, 0x1302 AES-256-GCM-SHA384 and 0x1303
CHACHA20-POLY1305-SHA256. A codepoint the provider does not have is
DialError::TlsConfig rather than a silent omission, because silently
offering fewer suites than asked would make every answer a false
negative.
Excluding 0x1301 is allowed, and is the interesting case. QUIC’s
Initial packets must use AES-128-GCM and normally that makes such an
offer unbuildable; the initial keys are taken from the default provider
separately so that only the traffic suites are restricted.
Not honoured by webtransport::dial_webtransport_to, which reaches
wtransport’s builder and cannot supply a separate initial suite
through it. Spelled as code and not as a link on purpose: that module is
behind the webtransport feature, and just doc-check builds these
docs with the feature off.
Implementations§
Source§impl QuicDialOptions
impl QuicDialOptions
Sourcepub fn new(alpn: Vec<Vec<u8>>) -> Self
pub fn new(alpn: Vec<Vec<u8>>) -> Self
Options offering alpn, verifying certificates against the bundled
Mozilla roots, observing nothing.
A constructor and not a Default because there is no sensible default
ALPN: an empty list is refused by every MoQT relay, so a
QuicDialOptions::default() would be a value whose only outcome is TLS
alert 120 — which in a conformance report reads as a defect in the
relay rather than in the caller. Naming the offer is the one thing a
dial cannot do without.
It is also the base for functional update, which is how the fields below stay additive:
QuicDialOptions { skip_cert_verification: true, ..QuicDialOptions::new(alpn) }Sourcepub fn insecure(self, yes: bool) -> Self
pub fn insecure(self, yes: bool) -> Self
Accept any certificate. Testing only — see
skip_cert_verification.
Sourcepub fn ca_certs(self, certs: Vec<Vec<u8>>) -> Self
pub fn ca_certs(self, certs: Vec<Vec<u8>>) -> Self
Trust these DER-encoded CAs on top of the bundled roots.
Sourcepub fn observing(self, hook: CertificateHook) -> Self
pub fn observing(self, hook: CertificateHook) -> Self
Observe the peer’s certificate chain, accepted or not.
CertificateLog is the collector most callers want:
let log = CertificateLog::new();
let result = dial_quic_to(&target, &QuicDialOptions::new(alpn).observing(log.hook())).await;
let chain = log.chain();Sourcepub fn offering_cipher_suites(self, suites: Vec<u16>) -> Self
pub fn offering_cipher_suites(self, suites: Vec<u16>) -> Self
Offer only these cipher suites, by IANA codepoint. See
cipher_suites.
Sourcepub fn offering_wt_protocols(self, protocols: Vec<Vec<u8>>) -> Self
pub fn offering_wt_protocols(self, protocols: Vec<Vec<u8>>) -> Self
Offer these MOQT protocol identifiers to a WebTransport dial. See
wt_protocols.