]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Grant unidirectional HTTP/3 streams for DoH3 13678/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 8 Jan 2024 16:03:17 +0000 (17:03 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 8 Jan 2024 16:03:17 +0000 (17:03 +0100)
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.

pdns/dnsdistdist/doh3.cc
pdns/dnsdistdist/doq-common.cc
pdns/dnsdistdist/doq-common.hh
pdns/dnsdistdist/doq.cc

index 713e379f1b2cb34d2d0fb03c13e5ec6588dbbba9..4861e058ddf9efc7aade6d409d94ab317daff571 100644 (file)
@@ -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);
index 46dfa0c7c0df4ab6861ba844f26e8bec944a23dd..c81193fc0acd35ea2efef522e8aa552245993a7e 100644 (file)
@@ -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);
index efcb8778290166f14db33c9b9a0eaee41aa9b28e..bd3dfc08870f69a8275d89ce92e476be5ec0b255 100644 (file)
@@ -84,7 +84,7 @@ std::optional<PacketBuffer> 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);
 
 };
 
index 4431f6e4f0ef391c201345e97cd77758cc5835c7..30572192ac83d45ac422e2edf92ad9c95d25f495 100644 (file)
@@ -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<DOQServerConfig>(std::move(config), d_internalPipeBufferSize);
 }