* `showServerPolicy()`: show name of currently operational server selection policy
* `newServerPolicy(name, function)`: create a policy object from a Lua function
* `setServFailWhenNoServer(bool)`: if set, return a ServFail when no servers are available, instead of the default behaviour of dropping the query
+ * `setPoolServerPolicy(policy, pool)`: set the server selection policy for this pool to that policy
+ * `setPoolServerPolicyLua(name, function, poool)`: set the server selection policy for this pool to one named 'name' and provided by 'function'
+ * `showPoolServerPolicy()`: show server selection policy for this pool
* Available policies:
* `firstAvailable`: Pick first server that has not exceeded its QPS limit, ordered by the server 'order' parameter
* `whashed`: Weighted hashed ('sticky') distribution over available servers, based on the server 'weight' parameter
{ "setMaxTCPQueriesPerConnection", true, "n", "set the maximum number of queries in an incoming TCP connection. 0 means unlimited" },
{ "setMaxTCPQueuedConnections", true, "n", "set the maximum number of TCP connections queued (waiting to be picked up by a client thread)" },
{ "setMaxUDPOutstanding", true, "n", "set the maximum number of outstanding UDP queries to a given backend server. This can only be set at configuration time and defaults to 10240" },
+ { "setPoolServerPolicy", true, "policy, pool", "set the server selection policy for this pool to that policy" },
+ { "setPoolServerPolicy", true, "name, func, pool", "set the server selection policy for this pool to one named 'name' and provided by 'function'" },
{ "setQueryCount", true, "bool", "set whether queries should be counted" },
{ "setQueryCountFilter", true, "func", "filter queries that would be counted, where `func` is a function with parameter `dq` which decides whether a query should and how it should be counted" },
{ "setRingBuffersSize", true, "n", "set the capacity of the ringbuffers used for live traffic inspection to `n`" },
{ "showCacheHitResponseRules", true, "", "show all defined cache hit response rules" },
{ "showDNSCryptBinds", true, "", "display the currently configured DNSCrypt binds" },
{ "showDynBlocks", true, "", "show dynamic blocks in force" },
+ { "showPoolServerPolicy", true, "pool", "show server selection policy for this pool" },
{ "showResponseLatency", true, "", "show a plot of the response time latency distribution" },
{ "showResponseRules", true, "", "show all defined response rules" },
{ "showRules", true, "", "show all defined rules" },
}
#endif /* HAVE_NET_SNMP */
});
+
+ g_lua.writeFunction("setPoolServerPolicy", [](ServerPolicy policy, string pool) {
+ setLuaSideEffect();
+ auto localPools = g_pools.getCopy();
+ setPoolPolicy(localPools, pool, std::make_shared<ServerPolicy>(policy));
+ });
+
+ g_lua.writeFunction("setPoolServerPolicyLua", [](string name, policyfunc_t policy, string pool) {
+ setLuaSideEffect();
+ auto localPools = g_pools.getCopy();
+ setPoolPolicy(localPools, pool, std::make_shared<ServerPolicy>(ServerPolicy{name, policy}));
+ });
+
+ g_lua.writeFunction("showPoolServerPolicy", [](string pool) {
+ setLuaSideEffect();
+ auto localPools = g_pools.getCopy();
+ auto poolObj = getPool(localPools, pool);
+ if (poolObj->policy == NULL) {
+ g_outputBuffer=g_policy.getLocal()->name+"\n";
+ } else {
+ g_outputBuffer=poolObj->policy->name+"\n";
+ }
+ });
}
std::shared_ptr<ServerPool> serverPool = getPool(*localPools, poolname);
std::shared_ptr<DNSDistPacketCache> packetCache = nullptr;
- {
- std::lock_guard<std::mutex> lock(g_luamutex);
- ds = localPolicy->policy(serverPool->servers, &dq);
- packetCache = serverPool->packetCache;
- }
+ auto policy = localPolicy->policy;
+ if (serverPool->policy != NULL) {
+ policy = serverPool->policy->policy;
+ }
+ {
+ std::lock_guard<std::mutex> lock(g_luamutex);
+ ds = policy(serverPool->servers, &dq);
+ packetCache = serverPool->packetCache;
+ }
if (dq.useECS && ds && ds->useECS) {
uint16_t newLen = dq.len;
if (!poolName.empty())
vinfolog("Creating pool %s", poolName);
pool = std::make_shared<ServerPool>();
+ pool->policy = NULL;
pools.insert(std::pair<std::string,std::shared_ptr<ServerPool> >(poolName, pool));
}
return pool;
}
+void setPoolPolicy(pools_t& pools, const string& poolName, std::shared_ptr<ServerPolicy> policy)
+{
+ std::shared_ptr<ServerPool> pool = createPoolIfNotExists(pools, poolName);
+ if (!poolName.empty()) {
+ vinfolog("Setting pool %s server selection policy to %s", poolName, policy->name);
+ } else {
+ vinfolog("Setting default pool server selection policy to %s", policy->name);
+ }
+ pool->policy = policy;
+}
+
void addServerToPool(pools_t& pools, const string& poolName, std::shared_ptr<DownstreamState> server)
{
std::shared_ptr<ServerPool> pool = createPoolIfNotExists(pools, poolName);
DownstreamState* ss = nullptr;
std::shared_ptr<ServerPool> serverPool = getPool(*localPools, poolname);
std::shared_ptr<DNSDistPacketCache> packetCache = nullptr;
- auto policy=localPolicy->policy;
+ auto policy = localPolicy->policy;
+ if (serverPool->policy != NULL) {
+ policy = serverPool->policy->policy;
+ }
{
- std::lock_guard<std::mutex> lock(g_luamutex);
- ss = policy(serverPool->servers, &dq).get();
- packetCache = serverPool->packetCache;
+ std::lock_guard<std::mutex> lock(g_luamutex);
+ ss = policy(serverPool->servers, &dq).get();
+ packetCache = serverPool->packetCache;
}
bool ednsAdded = false;
NumberedVector<shared_ptr<DownstreamState>> servers;
std::shared_ptr<DNSDistPacketCache> packetCache{nullptr};
+ std::shared_ptr<ServerPolicy> policy;
};
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);