g_servFailOnNoPolicy = servfail;
});
+ g_lua.writeFunction("setRoundRobinFailOnNoServer", [](bool fail) {
+ setLuaSideEffect();
+ g_roundrobinFailOnNoServer = fail;
+ });
+
g_lua.writeFunction("setRingBuffersSize", [](size_t capacity, boost::optional<size_t> numberOfShards) {
setLuaSideEffect();
if (g_configurationDone) {
bool g_truncateTC{false};
bool g_fixupCase{false};
bool g_preserveTrailingData{false};
+bool g_roundrobinFailOnNoServer{false};
static void truncateTC(char* packet, uint16_t* len, size_t responseSize, unsigned int consumed)
try
}
const auto *res=&poss;
- if(poss.empty())
+ if(poss.empty() && !g_roundrobinFailOnNoServer)
res = &servers;
if(res->empty())
extern size_t g_udpVectorSize;
extern bool g_preserveTrailingData;
extern bool g_allowEmptyResponse;
+extern bool g_roundrobinFailOnNoServer;
#ifdef HAVE_EBPF
extern shared_ptr<BPFFilter> g_defaultBPFFilter;
~~~~~~~~~~~~~~
The last available policy is ``roundrobin``, which indiscriminately sends each query to the next server that is up.
+If all servers are down, the policy will still select one server by default. Setting :func:`setRoundRobinFailOnNoServer` to ``true`` will change this behavior.
Lua server policies
-------------------
If set, return a ServFail when no servers are available, instead of the default behaviour of dropping the query.
- :param bool value:
+ :param bool value: whether to return a servfail instead of dropping the query
.. function:: setPoolServerPolicy(policy, pool)
:param string function: name of the function
:param string pool: Name of the pool
+.. function:: setRoundRobinFailOnNoServer(value)
+
+ .. versionadded:: 1.4.0
+
+ By default the roundrobin load-balancing policy will still try to select a backend even if all backends are currently down. Setting this to true will make the policy fail and return that no server is available instead.
+
+ :param bool value: whether to fail when all servers are down
+
.. function:: showPoolServerPolicy(pool)
Print server selection policy for ``pool``.
self.assertEquals(total, numberOfQueries * 2)
+class TestRoutingRoundRobinLBAllDown(DNSDistTest):
+
+ _testServer2Port = 5351
+ _config_params = ['_testServerPort', '_testServer2Port']
+ _config_template = """
+ setServerPolicy(roundrobin)
+ setRoundRobinFailOnNoServer(true)
+ s1 = newServer{address="127.0.0.1:%s"}
+ s1:setDown()
+ s2 = newServer{address="127.0.0.1:%s"}
+ s2:setDown()
+ """
+
+ def testRRWithAllDown(self):
+ """
+ Routing: Round Robin with all servers down
+ """
+ numberOfQueries = 10
+ name = 'alldown.rr.routing.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'A', 'IN')
+ response = dns.message.make_response(query)
+ rrset = dns.rrset.from_text(name,
+ 60,
+ dns.rdataclass.IN,
+ dns.rdatatype.A,
+ '192.0.2.1')
+ response.answer.append(rrset)
+
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (_, receivedResponse) = sender(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, None)
+
class TestRoutingOrder(DNSDistTest):
_testServer2Port = 5351