dns.cc dns.hh \
dns_random.hh \
dnscrypt.cc dnscrypt.hh \
+ dnsdist-actions.hh \
dnsdist-async.cc dnsdist-async.hh \
dnsdist-backend.cc dnsdist-backend.hh \
dnsdist-backoff.hh \
--- /dev/null
+/*
+ * 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
+
+/* so what could you do:
+ drop,
+ fake up nxdomain,
+ provide actual answer,
+ allow & and stop processing,
+ continue processing,
+ modify header: (servfail|refused|notimp), set TC=1,
+ send to pool */
+
+struct DNSQuestion;
+struct DNSResponse;
+
+class DNSAction
+{
+public:
+ enum class Action : uint8_t
+ {
+ Drop,
+ Nxdomain,
+ Refused,
+ Spoof,
+ Allow,
+ HeaderModify,
+ Pool,
+ Delay,
+ Truncate,
+ ServFail,
+ None,
+ NoOp,
+ NoRecurse,
+ SpoofRaw,
+ SpoofPacket,
+ SetTag,
+ };
+ static std::string typeToString(const Action& action)
+ {
+ switch (action) {
+ case Action::Drop:
+ return "Drop";
+ case Action::Nxdomain:
+ return "Send NXDomain";
+ case Action::Refused:
+ return "Send Refused";
+ case Action::Spoof:
+ return "Spoof an answer";
+ case Action::SpoofPacket:
+ return "Spoof a raw answer from bytes";
+ case Action::SpoofRaw:
+ return "Spoof an answer from raw bytes";
+ case Action::Allow:
+ return "Allow";
+ case Action::HeaderModify:
+ return "Modify the header";
+ case Action::Pool:
+ return "Route to a pool";
+ case Action::Delay:
+ return "Delay";
+ case Action::Truncate:
+ return "Truncate over UDP";
+ case Action::ServFail:
+ return "Send ServFail";
+ case Action::SetTag:
+ return "Set Tag";
+ case Action::None:
+ case Action::NoOp:
+ return "Do nothing";
+ case Action::NoRecurse:
+ return "Set rd=0";
+ }
+
+ return "Unknown";
+ }
+
+ virtual Action operator()(DNSQuestion*, std::string* ruleresult) const = 0;
+ virtual ~DNSAction() = default;
+ virtual std::string toString() const = 0;
+ virtual std::map<std::string, double> getStats() const
+ {
+ return {{}};
+ }
+ virtual void reload()
+ {
+ }
+};
+
+class DNSResponseAction
+{
+public:
+ enum class Action : uint8_t
+ {
+ Allow,
+ Delay,
+ Drop,
+ HeaderModify,
+ ServFail,
+ Truncate,
+ None
+ };
+ virtual Action operator()(DNSResponse*, std::string* ruleresult) const = 0;
+ virtual ~DNSResponseAction() = default;
+ virtual std::string toString() const = 0;
+ virtual void reload()
+ {
+ }
+};
#include "dnsdist-async.hh"
#include "dnsdist-internal-queries.hh"
#include "dolog.hh"
+#include "mplexer.hh"
#include "threadname.hh"
namespace dnsdist
uint16_t d_queryID;
};
- typedef multi_index_container<
+ using content_t = multi_index_container<
Entry,
indexed_by<
ordered_unique<tag<IDTag>,
member<Entry, uint16_t, &Entry::d_queryID>,
member<Entry, uint16_t, &Entry::d_asyncID>>>,
ordered_non_unique<tag<TTDTag>,
- member<Entry, struct timeval, &Entry::d_ttd>>>>
- content_t;
+ member<Entry, struct timeval, &Entry::d_ttd>>>>;
static void pickupExpired(content_t&, const struct timeval& now, std::list<std::pair<uint16_t, std::unique_ptr<CrossProtocolQuery>>>& expiredEvents);
static struct timeval getNextTTD(const content_t&);
#endif
#include "dnsdist-carbon.hh"
+#include "dnsdist-cache.hh"
#include "dnsdist.hh"
#include "dnsdist-backoff.hh"
#include "dnsdist-configuration.hh"
#include "config.h"
#include "credentials.hh"
+#include "dnsdist-actions.hh"
#include "dnsdist-carbon.hh"
#include "dnsdist-query-count.hh"
#include "dnsdist-rule-chains.hh"
#include "iputils.hh"
-/* so what could you do:
- drop,
- fake up nxdomain,
- provide actual answer,
- allow & and stop processing,
- continue processing,
- modify header: (servfail|refused|notimp), set TC=1,
- send to pool */
-
-struct DNSQuestion;
-struct DNSResponse;
-
-class DNSAction
-{
-public:
- enum class Action : uint8_t
- {
- Drop,
- Nxdomain,
- Refused,
- Spoof,
- Allow,
- HeaderModify,
- Pool,
- Delay,
- Truncate,
- ServFail,
- None,
- NoOp,
- NoRecurse,
- SpoofRaw,
- SpoofPacket,
- SetTag,
- };
- static std::string typeToString(const Action& action)
- {
- switch (action) {
- case Action::Drop:
- return "Drop";
- case Action::Nxdomain:
- return "Send NXDomain";
- case Action::Refused:
- return "Send Refused";
- case Action::Spoof:
- return "Spoof an answer";
- case Action::SpoofPacket:
- return "Spoof a raw answer from bytes";
- case Action::SpoofRaw:
- return "Spoof an answer from raw bytes";
- case Action::Allow:
- return "Allow";
- case Action::HeaderModify:
- return "Modify the header";
- case Action::Pool:
- return "Route to a pool";
- case Action::Delay:
- return "Delay";
- case Action::Truncate:
- return "Truncate over UDP";
- case Action::ServFail:
- return "Send ServFail";
- case Action::SetTag:
- return "Set Tag";
- case Action::None:
- case Action::NoOp:
- return "Do nothing";
- case Action::NoRecurse:
- return "Set rd=0";
- }
-
- return "Unknown";
- }
-
- virtual Action operator()(DNSQuestion*, std::string* ruleresult) const = 0;
- virtual ~DNSAction() = default;
- virtual std::string toString() const = 0;
- virtual std::map<std::string, double> getStats() const
- {
- return {{}};
- }
- virtual void reload()
- {
- }
-};
-
-class DNSResponseAction
-{
-public:
- enum class Action : uint8_t
- {
- Allow,
- Delay,
- Drop,
- HeaderModify,
- ServFail,
- Truncate,
- None
- };
- virtual Action operator()(DNSResponse*, std::string* ruleresult) const = 0;
- virtual ~DNSResponseAction() = default;
- virtual std::string toString() const = 0;
- virtual void reload()
- {
- }
-};
-
class ServerPolicy;
struct ServerPool;
struct DownstreamState;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "dnsdist.hh"
+#include "dnsdist-configuration.hh"
#include "dnsdist-dnsparser.hh"
std::string DNSQuestion::getTrailingData() const
SMTBlockParameters& d_blockParameters;
};
+struct DynBlock
+{
+ DynBlock()
+ {
+ until.tv_sec = 0;
+ until.tv_nsec = 0;
+ }
+
+ DynBlock(const std::string& reason_, const struct timespec& until_, const DNSName& domain_, DNSAction::Action action_) :
+ reason(reason_), domain(domain_), until(until_), action(action_)
+ {
+ }
+
+ DynBlock(const DynBlock& rhs) :
+ reason(rhs.reason), domain(rhs.domain), until(rhs.until), tagSettings(rhs.tagSettings), action(rhs.action), warning(rhs.warning), bpf(rhs.bpf)
+ {
+ blocks.store(rhs.blocks);
+ }
+
+ DynBlock(DynBlock&& rhs) :
+ reason(std::move(rhs.reason)), domain(std::move(rhs.domain)), until(rhs.until), tagSettings(std::move(rhs.tagSettings)), action(rhs.action), warning(rhs.warning), bpf(rhs.bpf)
+ {
+ blocks.store(rhs.blocks);
+ }
+
+ DynBlock& operator=(const DynBlock& rhs)
+ {
+ reason = rhs.reason;
+ until = rhs.until;
+ domain = rhs.domain;
+ action = rhs.action;
+ blocks.store(rhs.blocks);
+ warning = rhs.warning;
+ bpf = rhs.bpf;
+ tagSettings = rhs.tagSettings;
+ return *this;
+ }
+
+ DynBlock& operator=(DynBlock&& rhs)
+ {
+ reason = std::move(rhs.reason);
+ until = rhs.until;
+ domain = std::move(rhs.domain);
+ action = rhs.action;
+ blocks.store(rhs.blocks);
+ warning = rhs.warning;
+ bpf = rhs.bpf;
+ tagSettings = std::move(rhs.tagSettings);
+ return *this;
+ }
+
+ struct TagSettings
+ {
+ std::string d_name;
+ std::string d_value;
+ };
+
+ string reason;
+ DNSName domain;
+ timespec until{};
+ std::shared_ptr<TagSettings> tagSettings{nullptr};
+ mutable std::atomic<uint32_t> blocks{0};
+ DNSAction::Action action{DNSAction::Action::None};
+ bool warning{false};
+ bool bpf{false};
+};
+
using dnsdist_ffi_dynamic_block_inserted_hook = std::function<void(uint8_t type, const char* key, const char* reason, uint8_t action, uint64_t duration, bool warning)>;
using ClientAddressDynamicRules = NetmaskTree<DynBlock, AddressAndPortRange>;
using SuffixDynamicRules = SuffixMatchTree<DynBlock>;
*/
#include "dnsdist-dynbpf.hh"
+std::vector<std::shared_ptr<DynBPFFilter>> g_dynBPFFilters;
+
bool DynBPFFilter::block(const ComboAddress& addr, const struct timespec& until)
{
bool inserted = false;
};
LockGuarded<Data> d_data;
};
+
+extern std::vector<std::shared_ptr<DynBPFFilter>> g_dynBPFFilters;
#include "dnsdist-frontend.hh"
#include "dnsdist.hh"
+#include "dnsdist-configuration.hh"
namespace dnsdist
{
struct dnsdist_ffi_server_t;
struct dnsdist_ffi_dnsquestion_t;
+struct DNSQuestion;
struct DownstreamState;
struct PerThreadPoliciesState;
#include "config.h"
#include "dnsdist.hh"
+#include "dnsdist-cache.hh"
#include "dnsdist-lua.hh"
#include <boost/lexical_cast.hpp>
#include "config.h"
#include "dnsdist.hh"
#include "dnsdist-async.hh"
+#include "dnsdist-dynblocks.hh"
+#include "dnsdist-dynbpf.hh"
#include "dnsdist-frontend.hh"
#include "dnsdist-lua.hh"
#include "dnsdist-resolver.hh"
luaCtx.registerFunction<bool (ComboAddress::*)() const>("isIPv6", [](const ComboAddress& addr) { return addr.sin4.sin_family == AF_INET6; });
luaCtx.registerFunction<bool (ComboAddress::*)() const>("isMappedIPv4", [](const ComboAddress& addr) { return addr.isMappedIPv4(); });
luaCtx.registerFunction<ComboAddress (ComboAddress::*)() const>("mapToIPv4", [](const ComboAddress& addr) { return addr.mapToIPv4(); });
- luaCtx.registerFunction<bool (nmts_t::*)(const ComboAddress&)>("match", [](nmts_t& set, const ComboAddress& addr) { return set.match(addr); });
+#ifndef DISABLE_DYNBLOCKS
+ luaCtx.registerFunction<bool (ClientAddressDynamicRules::*)(const ComboAddress&) const>("match", [](const ClientAddressDynamicRules& set, const ComboAddress& addr) { return set.match(addr); });
+#endif /* DISABLE_DYNBLOCKS */
#endif /* DISABLE_COMBO_ADDR_BINDINGS */
#ifndef DISABLE_DNSNAME_BINDINGS
*/
#include "dnsdist-async.hh"
+#include "dnsdist-cache.hh"
#include "dnsdist-dnsparser.hh"
#include "dnsdist-dynblocks.hh"
#include "dnsdist-ecs.hh"
#include "dnsdist.hh"
#include "dnsdist-backend.hh"
+#include "dnsdist-cache.hh"
#include "dnsdist-carbon.hh"
#include "dnsdist-concurrent-connections.hh"
#include "dnsdist-configuration.hh"
#include "dnsdist-console.hh"
#include "dnsdist-crypto.hh"
#include "dnsdist-dynblocks.hh"
+#include "dnsdist-dynbpf.hh"
#include "dnsdist-discovery.hh"
#include "dnsdist-ecs.hh"
#include "dnsdist-frontend.hh"
using LuaTypeOrArrayOf = boost::variant<T, LuaArray<T>>;
using luaruleparams_t = LuaAssociativeTable<std::string>;
-using nmts_t = NetmaskTree<DynBlock, AddressAndPortRange>;
using luadnsrule_t = boost::variant<string, LuaArray<std::string>, std::shared_ptr<DNSRule>, DNSName, LuaArray<DNSName>>;
std::shared_ptr<DNSRule> makeRule(const luadnsrule_t& var, const std::string& calledFrom);
#include "base64.hh"
#include "connection-management.hh"
#include "dnsdist.hh"
+#include "dnsdist-cache.hh"
#include "dnsdist-configuration.hh"
#include "dnsdist-dynblocks.hh"
+#include "dnsdist-dynbpf.hh"
#include "dnsdist-frontend.hh"
#include "dnsdist-healthchecks.hh"
#include "dnsdist-metrics.hh"
string g_outputBuffer;
shared_ptr<BPFFilter> g_defaultBPFFilter{nullptr};
-std::vector<std::shared_ptr<DynBPFFilter>> g_dynBPFFilters;
/* UDP: the grand design. Per socket we listen on for incoming queries there is one thread.
Then we have a bunch of connected sockets for talking to downstream servers.
#include <unistd.h>
#include <unordered_map>
-#include <boost/variant.hpp>
-
+#include "bpf-filter.hh"
#include "circular_buffer.hh"
-#include "dnscrypt.hh"
-#include "dnsdist-cache.hh"
-#include "dnsdist-dynbpf.hh"
#include "dnsdist-idstate.hh"
#include "dnsdist-lbpolicies.hh"
#include "dnsdist-protocols.hh"
#include "misc.hh"
#include "mplexer.hh"
#include "noinitvector.hh"
-#include "tcpiohandler.hh"
#include "uuid-utils.hh"
#include "proxy-protocol.hh"
#include "stat_t.hh"
const std::shared_ptr<DownstreamState>& d_downstream;
};
-struct DynBlock
-{
- DynBlock()
- {
- until.tv_sec = 0;
- until.tv_nsec = 0;
- }
-
- DynBlock(const std::string& reason_, const struct timespec& until_, const DNSName& domain_, DNSAction::Action action_) :
- reason(reason_), domain(domain_), until(until_), action(action_)
- {
- }
-
- DynBlock(const DynBlock& rhs) :
- reason(rhs.reason), domain(rhs.domain), until(rhs.until), tagSettings(rhs.tagSettings), action(rhs.action), warning(rhs.warning), bpf(rhs.bpf)
- {
- blocks.store(rhs.blocks);
- }
-
- DynBlock(DynBlock&& rhs) :
- reason(std::move(rhs.reason)), domain(std::move(rhs.domain)), until(rhs.until), tagSettings(std::move(rhs.tagSettings)), action(rhs.action), warning(rhs.warning), bpf(rhs.bpf)
- {
- blocks.store(rhs.blocks);
- }
-
- DynBlock& operator=(const DynBlock& rhs)
- {
- reason = rhs.reason;
- until = rhs.until;
- domain = rhs.domain;
- action = rhs.action;
- blocks.store(rhs.blocks);
- warning = rhs.warning;
- bpf = rhs.bpf;
- tagSettings = rhs.tagSettings;
- return *this;
- }
-
- DynBlock& operator=(DynBlock&& rhs)
- {
- reason = std::move(rhs.reason);
- until = rhs.until;
- domain = std::move(rhs.domain);
- action = rhs.action;
- blocks.store(rhs.blocks);
- warning = rhs.warning;
- bpf = rhs.bpf;
- tagSettings = std::move(rhs.tagSettings);
- return *this;
- }
-
- struct TagSettings
- {
- std::string d_name;
- std::string d_value;
- };
-
- string reason;
- DNSName domain;
- timespec until{};
- std::shared_ptr<TagSettings> tagSettings{nullptr};
- mutable std::atomic<uint32_t> blocks{0};
- DNSAction::Action action{DNSAction::Action::None};
- bool warning{false};
- bool bpf{false};
-};
-
using pdns::stat_t;
class BasicQPSLimiter
class XskSocket;
class XskWorker;
+class DNSCryptContext;
+
struct ClientState
{
ClientState(const ComboAddress& local_, bool isTCP_, bool doReusePort, int fastOpenQueue, const std::string& itfName, const std::set<int>& cpus_, bool enableProxyProtocol) :
};
struct CrossProtocolQuery;
+class FDMultiplexer;
struct DownstreamState : public std::enable_shared_from_this<DownstreamState>
{
extern RecursiveLockGuarded<LuaContext> g_lua;
extern std::string g_outputBuffer; // locking for this is ok, as locked by g_luamutex
+class DNSDistPacketCache;
+
class DNSRule
{
public:
};
extern shared_ptr<BPFFilter> g_defaultBPFFilter;
-extern std::vector<std::shared_ptr<DynBPFFilter>> g_dynBPFFilters;
void tcpAcceptorThread(const std::vector<ClientState*>& states);
bool checkQueryHeaders(const struct dnsheader& dnsHeader, ClientState& clientState);
+class DNSCryptQuery;
+
bool handleDNSCryptQuery(PacketBuffer& packet, DNSCryptQuery& query, bool tcp, time_t now, PacketBuffer& response);
bool checkDNSCryptQuery(const ClientState& clientState, PacketBuffer& query, std::unique_ptr<DNSCryptQuery>& dnsCryptQuery, time_t now, bool tcp);
Asynchronous
};
+#include "dnsdist-actions.hh"
#include "dnsdist-rule-chains.hh"
ProcessQueryResult processQuery(DNSQuestion& dnsQuestion, std::shared_ptr<DownstreamState>& selectedBackend);
#include <boost/test/unit_test.hpp>
#include "dnsdist-lua-ffi.hh"
+#include "dnsdist-cache.hh"
+#include "dnsdist-configuration.hh"
#include "dnsdist-rings.hh"
#include "dnsdist-web.hh"
#include "dnsparser.hh"