#include <boost/variant.hpp>
-#include "bpf-filter.hh"
#include "capabilities.hh"
#include "circular_buffer.hh"
#include "dnscrypt.hh"
#include "dnsdist-cache.hh"
#include "dnsdist-dynbpf.hh"
+#include "dnsdist-lbpolicies.hh"
#include "dnsname.hh"
#include "doh.hh"
#include "ednsoptions.hh"
#include "sholder.hh"
#include "tcpiohandler.hh"
#include "uuid-utils.hh"
+#include "proxy-protocol.hh"
void carbonDumpThread();
uint64_t uptimeOfProcess(const std::string& str);
DNSQuestion& operator=(const DNSQuestion&) = delete;
DNSQuestion(DNSQuestion&&) = default;
+ std::string getTrailingData() const;
+ bool setTrailingData(const std::string&);
+
#ifdef HAVE_PROTOBUF
boost::optional<boost::uuids::uuid> uniqueId;
#endif
const ComboAddress* local{nullptr};
const ComboAddress* remote{nullptr};
std::shared_ptr<QTag> qTag{nullptr};
+ std::unique_ptr<std::vector<ProxyProtocolValue>> proxyProtocolValues{nullptr};
std::shared_ptr<std::map<uint16_t, EDNSOptionView> > ednsOptions;
std::shared_ptr<DNSCryptQuery> dnsCryptQuery{nullptr};
std::shared_ptr<DNSDistPacketCache> packetCache{nullptr};
stat_t cacheMisses{0};
stat_t latency0_1{0}, latency1_10{0}, latency10_50{0}, latency50_100{0}, latency100_1000{0}, latencySlow{0}, latencySum{0};
stat_t securityStatus{0};
+ stat_t dohQueryPipeFull{0};
+ stat_t dohResponsePipeFull{0};
double latencyAvg100{0}, latencyAvg1000{0}, latencyAvg10000{0}, latencyAvg1000000{0};
typedef std::function<uint64_t(const std::string&)> statfunction_t;
{"dyn-blocked", &dynBlocked},
{"dyn-block-nmg-size", [](const std::string&) { return g_dynblockNMG.getLocal()->size(); }},
{"security-status", &securityStatus},
+ {"doh-query-pipe-full", &dohQueryPipeFull},
+ {"doh-response-pipe-full", &dohResponsePipeFull},
// Latency histogram
{"latency-sum", &latencySum},
{"latency-count", getLatencyCount},
struct QueryCount {
QueryCount()
{
- pthread_rwlock_init(&queryLock, nullptr);
}
~QueryCount()
{
- pthread_rwlock_destroy(&queryLock);
}
QueryCountRecords records;
QueryCountFilter filter;
- pthread_rwlock_t queryLock;
+ ReadWriteLock queryLock;
bool enabled{false};
};
std::atomic<double> tcpAvgConnectionDuration{0.0};
int udpFD{-1};
int tcpFD{-1};
+ int tcpListenQueueSize{SOMAXCONN};
int fastOpenQueueSize{0};
bool muted{false};
bool tcp;
fd = -1;
}
}
- pthread_rwlock_destroy(&d_lock);
}
boost::uuids::uuid id;
- std::set<unsigned int> hashes;
- mutable pthread_rwlock_t d_lock;
+ std::vector<unsigned int> hashes;
+ mutable ReadWriteLock d_lock;
std::vector<int> sockets;
const std::string sourceItfName;
std::mutex socketsLock;
std::atomic<double> tcpAvgQueriesPerConnection{0.0};
/* in ms */
std::atomic<double> tcpAvgConnectionDuration{0.0};
- string name;
size_t socketsOffset{0};
double queryLoad{0.0};
double dropRate{0.0};
bool mustResolve{false};
bool upStatus{false};
bool useECS{false};
+ bool useProxyProtocol{false};
bool setCD{false};
bool disableZeroScope{false};
std::atomic<bool> connected{false};
void setUp() { availability = Availability::Up; }
void setDown() { availability = Availability::Down; }
void setAuto() { availability = Availability::Auto; }
- string getName() const {
- if (name.empty()) {
- return remote.toStringWithPort();
- }
+ const string& getName() const {
return name;
}
- string getNameWithAddr() const {
- if (name.empty()) {
- return remote.toStringWithPort();
- }
- return name + " (" + remote.toStringWithPort()+ ")";
+ const string& getNameWithAddr() const {
+ return nameWithAddr;
+ }
+ void setName(const std::string& newName)
+ {
+ name = newName;
+ nameWithAddr = newName.empty() ? remote.toStringWithPort() : (name + " (" + remote.toStringWithPort()+ ")");
}
+
string getStatus() const
{
string status;
tcpAvgQueriesPerConnection = (99.0 * tcpAvgQueriesPerConnection / 100.0) + (nbQueries / 100.0);
tcpAvgConnectionDuration = (99.0 * tcpAvgConnectionDuration / 100.0) + (durationMs / 100.0);
}
+private:
+ std::string name;
+ std::string nameWithAddr;
};
using servers_t =vector<std::shared_ptr<DownstreamState>>;
-template <class T> using NumberedVector = std::vector<std::pair<unsigned int, T> >;
-
void responderThread(std::shared_ptr<DownstreamState> state);
extern std::mutex g_luamutex;
extern LuaContext g_lua;
mutable std::atomic<uint64_t> d_matches{0};
};
-using NumberedServerVector = NumberedVector<shared_ptr<DownstreamState>>;
-typedef std::function<shared_ptr<DownstreamState>(const NumberedServerVector& servers, const DNSQuestion*)> policyfunc_t;
-
-struct ServerPolicy
-{
- string name;
- policyfunc_t policy;
- bool isLua;
- std::string toString() const {
- return string("ServerPolicy") + (isLua ? " (Lua)" : "") + " \"" + name + "\"";
- }
-};
-
struct ServerPool
{
ServerPool()
{
- pthread_rwlock_init(&d_lock, nullptr);
}
~ServerPool()
{
- pthread_rwlock_destroy(&d_lock);
}
const std::shared_ptr<DNSDistPacketCache> getCache() const { return packetCache; };
return count;
}
- NumberedVector<shared_ptr<DownstreamState>> getServers()
+ ServerPolicy::NumberedServerVector getServers()
{
- NumberedVector<shared_ptr<DownstreamState>> result;
+ ServerPolicy::NumberedServerVector result;
{
ReadLock rl(&d_lock);
result = d_servers;
}
private:
- NumberedVector<shared_ptr<DownstreamState>> d_servers;
- pthread_rwlock_t d_lock;
+ ServerPolicy::NumberedServerVector d_servers;
+ ReadWriteLock d_lock;
bool d_useECS{false};
};
-using pools_t=map<std::string,std::shared_ptr<ServerPool>>;
-void setPoolPolicy(pools_t& pools, const string& poolName, std::shared_ptr<ServerPolicy> policy);
-void addServerToPool(pools_t& pools, const string& poolName, std::shared_ptr<DownstreamState> server);
-void removeServerFromPool(pools_t& pools, const string& poolName, std::shared_ptr<DownstreamState> server);
struct CarbonConfig
{
extern ComboAddress g_serverControl; // not changed during runtime
-extern std::vector<std::tuple<ComboAddress, bool, bool, int, std::string, std::set<int>>> g_locals; // not changed at runtime (we hope XXX)
extern std::vector<shared_ptr<TLSFrontend>> g_tlslocals;
extern std::vector<shared_ptr<DOHFrontend>> g_dohlocals;
extern std::vector<std::unique_ptr<ClientState>> g_frontends;
extern bool g_apiReadWrite;
extern std::string g_apiConfigDirectory;
extern bool g_servFailOnNoPolicy;
-extern uint32_t g_hashperturb;
extern bool g_useTCPSinglePipe;
extern uint16_t g_downstreamTCPCleanupInterval;
extern size_t g_udpVectorSize;
extern bool g_preserveTrailingData;
extern bool g_allowEmptyResponse;
-extern bool g_roundrobinFailOnNoServer;
-extern double g_consistentHashBalancingFactor;
#ifdef HAVE_EBPF
extern shared_ptr<BPFFilter> g_defaultBPFFilter;
struct dnsheader;
-void controlThread(int fd, ComboAddress local);
-std::shared_ptr<ServerPool> getPool(const pools_t& pools, const std::string& poolName);
-std::shared_ptr<ServerPool> createPoolIfNotExists(pools_t& pools, const string& poolName);
-NumberedServerVector getDownstreamCandidates(const pools_t& pools, const std::string& poolName);
-
-std::shared_ptr<DownstreamState> firstAvailable(const NumberedServerVector& servers, const DNSQuestion* dq);
-
-std::shared_ptr<DownstreamState> leastOutstanding(const NumberedServerVector& servers, const DNSQuestion* dq);
-std::shared_ptr<DownstreamState> wrandom(const NumberedServerVector& servers, const DNSQuestion* dq);
-std::shared_ptr<DownstreamState> whashed(const NumberedServerVector& servers, const DNSQuestion* dq);
-std::shared_ptr<DownstreamState> chashed(const NumberedServerVector& servers, const DNSQuestion* dq);
-std::shared_ptr<DownstreamState> roundrobin(const NumberedServerVector& servers, const DNSQuestion* dq);
-
-struct WebserverConfig
-{
- std::string password;
- std::string apiKey;
- boost::optional<std::map<std::string, std::string> > customHeaders;
- std::mutex lock;
-};
-
-void setWebserverAPIKey(const boost::optional<std::string> apiKey);
-void setWebserverPassword(const std::string& password);
-void setWebserverCustomHeaders(const boost::optional<std::map<std::string, std::string> > customHeaders);
+vector<std::function<void(void)>> setupLua(bool client, const std::string& config);
-void dnsdistWebserverThread(int sock, const ComboAddress& local);
void tcpAcceptorThread(void* p);
#ifdef HAVE_DNS_OVER_HTTPS
void dohThread(ClientState* cs);