From: Remi Gacogne Date: Mon, 8 Jan 2024 16:03:17 +0000 (+0100) Subject: dnsdist: Grant unidirectional HTTP/3 streams for DoH3 X-Git-Tag: auth-4.9.0-alpha1~12^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e7989f54bf076e7946d58c8917ef3a94bf7ad08;p=thirdparty%2Fpdns.git dnsdist: Grant unidirectional HTTP/3 streams for DoH3 While unidirectional streams are not needed for DNS over QUIC, they are required by the HTTP/3 RFC and thus needed for DNS over HTTP/3. This change makes curl and Firefix happy with dnsdist's DoH3 implementation. --- diff --git a/pdns/dnsdistdist/doh3.cc b/pdns/dnsdistdist/doh3.cc index 713e379f1b..4861e058dd 100644 --- a/pdns/dnsdistdist/doh3.cc +++ b/pdns/dnsdistdist/doh3.cc @@ -367,7 +367,7 @@ void DOH3Frontend::setup() auto config = QuicheConfig(quiche_config_new(QUICHE_PROTOCOL_VERSION), quiche_config_free); d_quicheParams.d_alpn = std::string(DOH3_ALPN.begin(), DOH3_ALPN.end()); - configureQuiche(config, d_quicheParams); + configureQuiche(config, d_quicheParams, true); // quiche_h3_config_new auto http3config = QuicheHTTP3Config(quiche_h3_config_new(), quiche_h3_config_free); diff --git a/pdns/dnsdistdist/doq-common.cc b/pdns/dnsdistdist/doq-common.cc index 46dfa0c7c0..c81193fc0a 100644 --- a/pdns/dnsdistdist/doq-common.cc +++ b/pdns/dnsdistdist/doq-common.cc @@ -188,7 +188,7 @@ void flushEgress(Socket& sock, QuicheConnection& conn, const ComboAddress& peer, } } -void configureQuiche(QuicheConfig& config, const QuicheParams& params) +void configureQuiche(QuicheConfig& config, const QuicheParams& params, bool isHTTP) { for (const auto& pair : params.d_tlsConfig.d_certKeyPairs) { auto res = quiche_config_load_cert_chain_from_pem_file(config.get(), pair.d_cert.c_str()); @@ -227,6 +227,18 @@ void configureQuiche(QuicheConfig& config, const QuicheParams& params) quiche_config_set_initial_max_stream_data_bidi_local(config.get(), 8192); quiche_config_set_initial_max_stream_data_bidi_remote(config.get(), 8192); + if (isHTTP) { + /* see rfc9114 section 6.2. Unidirectional Streams: + Each endpoint needs to create at least one unidirectional stream for the HTTP control stream. + QPACK requires two additional unidirectional streams, and other extensions might require further streams. + Therefore, the transport parameters sent by both clients and servers MUST allow the peer to create at least three + unidirectional streams. + These transport parameters SHOULD also provide at least 1,024 bytes of flow-control credit to each unidirectional stream. + */ + quiche_config_set_initial_max_streams_uni(config.get(), 3U); + quiche_config_set_initial_max_stream_data_uni(config.get(), 1024U); + } + // The number of total bytes of incoming stream data to be buffered for the whole connection // https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_data quiche_config_set_initial_max_data(config.get(), 8192 * params.d_maxInFlight); diff --git a/pdns/dnsdistdist/doq-common.hh b/pdns/dnsdistdist/doq-common.hh index efcb877829..bd3dfc0887 100644 --- a/pdns/dnsdistdist/doq-common.hh +++ b/pdns/dnsdistdist/doq-common.hh @@ -84,7 +84,7 @@ std::optional validateToken(const PacketBuffer& token, const Combo void handleStatelessRetry(Socket& sock, const PacketBuffer& clientConnID, const PacketBuffer& serverConnID, const ComboAddress& peer, uint32_t version, PacketBuffer& buffer); void handleVersionNegociation(Socket& sock, const PacketBuffer& clientConnID, const PacketBuffer& serverConnID, const ComboAddress& peer, PacketBuffer& buffer); void flushEgress(Socket& sock, QuicheConnection& conn, const ComboAddress& peer, PacketBuffer& buffer); -void configureQuiche(QuicheConfig& config, const QuicheParams& params); +void configureQuiche(QuicheConfig& config, const QuicheParams& params, bool isHTTP); }; diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 4431f6e4f0..30572192ac 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -300,7 +300,7 @@ void DOQFrontend::setup() { auto config = QuicheConfig(quiche_config_new(QUICHE_PROTOCOL_VERSION), quiche_config_free); d_quicheParams.d_alpn = std::string(DOQ_ALPN.begin(), DOQ_ALPN.end()); - configureQuiche(config, d_quicheParams); + configureQuiche(config, d_quicheParams, false); d_server_config = std::make_unique(std::move(config), d_internalPipeBufferSize); }