summaryrefslogtreecommitdiffstats
path: root/doq-common.hh
diff options
context:
space:
mode:
Diffstat (limited to 'doq-common.hh')
-rw-r--r--doq-common.hh102
1 files changed, 102 insertions, 0 deletions
diff --git a/doq-common.hh b/doq-common.hh
new file mode 100644
index 0000000..d2222c6
--- /dev/null
+++ b/doq-common.hh
@@ -0,0 +1,102 @@
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#pragma once
+
+#include <map>
+#include <memory>
+
+#include "config.h"
+
+#if defined(HAVE_DNS_OVER_QUIC) || defined(HAVE_DNS_OVER_HTTP3)
+
+#include <quiche.h>
+
+#include "dolog.hh"
+#include "noinitvector.hh"
+#include "sstuff.hh"
+#include "libssl.hh"
+#include "dnsdist-crypto.hh"
+
+namespace dnsdist::doq
+{
+
+static const std::map<const std::string, int> s_available_cc_algorithms = {
+ {"reno", QUICHE_CC_RENO},
+ {"cubic", QUICHE_CC_CUBIC},
+ {"bbr", QUICHE_CC_BBR},
+};
+
+using QuicheConnection = std::unique_ptr<quiche_conn, decltype(&quiche_conn_free)>;
+using QuicheHTTP3Connection = std::unique_ptr<quiche_h3_conn, decltype(&quiche_h3_conn_free)>;
+using QuicheConfig = std::shared_ptr<quiche_config>;
+using QuicheHTTP3Config = std::unique_ptr<quiche_h3_config, decltype(&quiche_h3_config_free)>;
+
+struct QuicheParams
+{
+ TLSConfig d_tlsConfig;
+ std::string d_keyLogFile;
+ uint64_t d_idleTimeout{5};
+ uint64_t d_maxInFlight{65535};
+ std::string d_ccAlgo{"reno"};
+ std::string d_alpn;
+};
+
+/* from rfc9250 section-4.3 */
+enum class DOQ_Error_Codes : uint64_t
+{
+ DOQ_NO_ERROR = 0,
+ DOQ_INTERNAL_ERROR = 1,
+ DOQ_PROTOCOL_ERROR = 2,
+ DOQ_REQUEST_CANCELLED = 3,
+ DOQ_EXCESSIVE_LOAD = 4,
+ DOQ_UNSPECIFIED_ERROR = 5
+};
+
+/* Quiche type values do not match rfc9000 */
+enum class DOQ_Packet_Types : uint8_t
+{
+ QUIC_PACKET_TYPE_INITIAL = 1,
+ QUIC_PACKET_TYPE_RETRY = 2,
+ QUIC_PACKET_TYPE_HANDSHAKE = 3,
+ QUIC_PACKET_TYPE_ZERO_RTT = 4,
+ QUIC_PACKET_TYPE_SHORT = 5,
+ QUIC_PACKET_TYPE_VERSION_NEGOTIATION = 6
+};
+
+static constexpr size_t MAX_TOKEN_LEN = dnsdist::crypto::authenticated::getEncryptedSize(std::tuple_size<decltype(dnsdist::crypto::authenticated::Nonce::value)>{} /* nonce */ + sizeof(uint64_t) /* TTD */ + 16 /* IPv6 */ + QUICHE_MAX_CONN_ID_LEN);
+static constexpr size_t MAX_DATAGRAM_SIZE = 1200;
+static constexpr size_t LOCAL_CONN_ID_LEN = 16;
+static constexpr std::array<uint8_t, 4> DOQ_ALPN{'\x03', 'd', 'o', 'q'};
+static constexpr std::array<uint8_t, 3> DOH3_ALPN{'\x02', 'h', '3'};
+
+void fillRandom(PacketBuffer& buffer, size_t size);
+std::optional<PacketBuffer> getCID();
+PacketBuffer mintToken(const PacketBuffer& dcid, const ComboAddress& peer);
+std::optional<PacketBuffer> validateToken(const PacketBuffer& token, const ComboAddress& peer);
+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, bool isHTTP);
+
+};
+
+#endif