diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 21:11:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 21:11:59 +0000 |
commit | 3cd01b932e1c85394272ae64fae67ebeda92fb00 (patch) | |
tree | c5a3115d710afc1879ddea5349362a2bc651733c /dns.cc | |
parent | Initial commit. (diff) | |
download | dnsdist-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.cc | 126 |
1 files changed, 126 insertions, 0 deletions
@@ -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; +} + |