summaryrefslogtreecommitdiffstats
path: root/dns.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 21:11:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 21:11:59 +0000
commit3cd01b932e1c85394272ae64fae67ebeda92fb00 (patch)
treec5a3115d710afc1879ddea5349362a2bc651733c /dns.cc
parentInitial commit. (diff)
downloaddnsdist-3cd01b932e1c85394272ae64fae67ebeda92fb00.tar.xz
dnsdist-3cd01b932e1c85394272ae64fae67ebeda92fb00.zip
Adding upstream version 1.8.3.upstream/1.8.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dns.cc')
-rw-r--r--dns.cc126
1 files changed, 126 insertions, 0 deletions
diff --git a/dns.cc b/dns.cc
new file mode 100644
index 0000000..d9fb509
--- /dev/null
+++ b/dns.cc
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "dns.hh"
+#include "misc.hh"
+#include <stdexcept>
+#include <iostream>
+#include <boost/algorithm/string.hpp>
+#include <boost/assign/list_of.hpp>
+#include "dnsparser.hh"
+
+const std::array<std::string, 24> RCode::rcodes_s = {
+ "No Error",
+ "Form Error",
+ "Server Failure",
+ "Non-Existent domain",
+ "Not Implemented",
+ "Query Refused",
+ "Name Exists when it should not",
+ "RR Set Exists when it should not",
+ "RR Set that should exist does not",
+ "Server Not Authoritative for zone / Not Authorized",
+ "Name not contained in zone",
+ "Err#11",
+ "Err#12",
+ "Err#13",
+ "Err#14",
+ "Err#15", // Last non-extended RCode
+ "Bad OPT Version / TSIG Signature Failure",
+ "Key not recognized",
+ "Signature out of time window",
+ "Bad TKEY Mode",
+ "Duplicate key name",
+ "Algorithm not supported",
+ "Bad Truncation",
+ "Bad/missing Server Cookie"
+};
+
+static const std::array<std::string, 10> rcodes_short_s = {
+ "noerror",
+ "formerr",
+ "servfail",
+ "nxdomain",
+ "notimp",
+ "refused",
+ "yxdomain",
+ "yxrrset",
+ "nxrrset",
+ "notauth",
+};
+
+std::string RCode::to_s(uint8_t rcode) {
+ if (rcode > 0xF)
+ return std::string("ErrOutOfRange");
+ return ERCode::to_s(rcode);
+}
+
+std::string RCode::to_short_s(uint8_t rcode) {
+ if (rcode >= rcodes_short_s.size()) {
+ return "rcode" + std::to_string(rcode);
+ }
+ return rcodes_short_s.at(rcode);
+}
+
+std::string ERCode::to_s(uint8_t rcode) {
+ if (rcode > RCode::rcodes_s.size()-1)
+ return std::string("Err#")+std::to_string(rcode);
+ return RCode::rcodes_s.at(rcode);
+}
+
+std::string Opcode::to_s(uint8_t opcode) {
+ static const std::array<std::string, 6> s_opcodes = { "Query", "IQuery", "Status", "3", "Notify", "Update" };
+
+ if (opcode >= s_opcodes.size()) {
+ return std::to_string(opcode);
+ }
+
+ return s_opcodes.at(opcode);
+}
+
+// goal is to hash based purely on the question name, and turn error into 'default'
+uint32_t hashQuestion(const uint8_t* packet, uint16_t packet_len, uint32_t init, bool& ok)
+{
+ if (packet_len < sizeof(dnsheader)) {
+ ok = false;
+ return init;
+ }
+ // C++ 17 does not have std::u8string_view
+ std::basic_string_view<uint8_t> name(packet + sizeof(dnsheader), packet_len - sizeof(dnsheader));
+ std::basic_string_view<uint8_t>::size_type len = 0;
+
+ while (len < name.length()) {
+ uint8_t labellen = name[len++];
+ if (labellen == 0) {
+ ok = true;
+ // len is name.length() at max as it was < before the increment
+ return burtleCI(name.data(), len, init);
+ }
+ len += labellen;
+ }
+ // We've encountered a label that is too long
+ ok = false;
+ return init;
+}
+