"complete dns debug dump", /* Documentation string */
0 /* Method signature(s) */
};
-#endif
+
+#ifdef DNS_WATCHDOG_SUPPORT
+void dns_set_server_state_rpc(rpc_t* rpc, void* ctx);
+
+static const char* dns_set_server_state_doc[] = {
+ "sets the state of the DNS servers " \
+ "(0: all the servers are down, 1: at least one server is up)", /* Documentation string */
+ 0 /* Method signature(s) */
+};
+#endif /* DNS_WATCHDOG_SUPPORT */
+#endif /* USE_DNS_CACHE */
#ifdef USE_DST_BLACKLIST
void dst_blst_debug(rpc_t* rpc, void* ctx);
void dst_blst_mem_info(rpc_t* rpc, void* ctx);
{"dns.mem_info", dns_cache_mem_info, dns_cache_mem_info_doc, 0 },
{"dns.debug", dns_cache_debug, dns_cache_debug_doc, 0 },
{"dns.debug_all", dns_cache_debug_all, dns_cache_debug_all_doc, 0 },
+#ifdef DNS_WATCHDOG_SUPPORT
+ {"dns.set_server_state", dns_set_server_state_rpc, dns_set_server_state_doc, 0 },
+#endif
#endif
#ifdef USE_DST_BLACKLIST
{"dst_blacklist.mem_info", dst_blst_mem_info, dst_blst_mem_info_doc, 0 },
* 2007-06-14 dns iterate through A & AAAA records fix (andrei)
* 2007-06-15 srv rr weight based load balancing support (andrei)
* 2007-06-16 naptr support (andrei)
+ * 2008-07-18 DNS watchdog support -- can be used to inform the core
+ * that the DNS servers are down (Miklos)
*/
#ifdef USE_DNS_CACHE
static struct timer_ln* dns_timer_h=0;
+#ifdef DNS_WATCHDOG_SUPPORT
+static atomic_t *dns_servers_up = NULL;
+#endif
+
static const char* dns_str_errors[]={
static ticks_t dns_timer(ticks_t ticks, struct timer_ln* tl, void* data)
{
+#ifdef DNS_WATCHDOG_SUPPORT
+ /* do not clean the hash table if the servers are down */
+ if (atomic_get(dns_servers_up) == 0)
+ return (ticks_t)(-1);
+#endif
if (*dns_cache_mem_used>12*(dns_cache_max_mem/16)){ /* ~ 75% used */
dns_cache_free_mem(dns_cache_max_mem/2, 1);
}else{
timer_free(dns_timer_h);
dns_timer_h=0;
}
+#ifdef DNS_WATCHDOG_SUPPORT
+ if (dns_servers_up){
+ shm_free(dns_servers_up);
+ dns_servers_up=0;
+ }
+#endif
if (dns_hash_lock){
lock_destroy(dns_hash_lock);
lock_dealloc(dns_hash_lock);
ret=-1;
goto error;
}
+
+#ifdef DNS_WATCHDOG_SUPPORT
+ dns_servers_up=shm_malloc(sizeof(atomic_t));
+ if (dns_servers_up==0){
+ ret=E_OUT_OF_MEM;
+ goto error;
+ }
+ atomic_set(dns_servers_up, 1);
+#endif
/* fix options */
dns_cache_max_mem<<=10; /* Kb */ /* TODO: test with 0 */
ticks_t now;
int cname_chain;
str cname;
+#ifdef DNS_WATCHDOG_SUPPORT
+ int servers_up;
+
+ servers_up = atomic_get(dns_servers_up);
+#endif
cname_chain=0;
ret=0;
name->len, type, *h);
#endif
clist_foreach_safe(&dns_hash[*h], e, tmp, next){
- /* automatically remove expired elements */
- if ((s_ticks_t)(now-e->expire)>=0){
+ if (
+#ifdef DNS_WATCHDOG_SUPPORT
+ /* remove expired elements only when the dns servers are up */
+ servers_up &&
+#endif
+ /* automatically remove expired elements */
+ ((s_ticks_t)(now-e->expire)>=0)
+ ) {
_dns_hash_remove(e);
}else if ((e->type==type) && (e->name_len==name->len) &&
(strncasecmp(e->name, name->s, e->name_len)==0)){
goto end;/* we do not cache obvious stuff */
}
}
+#ifdef DNS_WATCHDOG_SUPPORT
+ if (atomic_get(dns_servers_up)==0)
+ goto end; /* the servers are down, needless to perform the query */
+#endif
if (name->len>=MAX_DNS_NAME){
LOG(L_ERR, "ERROR: dns_cache_do_request: name too long (%d chars)\n",
name->len);
struct dns_rr* rr;
int n;
int flags;
+#ifdef DNS_WATCHDOG_SUPPORT
+ int servers_up;
+
+ servers_up = atomic_get(dns_servers_up);
+#endif
flags=0;
for(rr=e->rr_lst, n=0;rr && (n<*no);rr=rr->next, n++);/* skip *no records*/
for(;rr;rr=rr->next){
- if ((s_ticks_t)(now-e->expire)>=0) /* expired entry */
+ if (
+#ifdef DNS_WATCHDOG_SUPPORT
+ /* check the expiration time only when the servers are up */
+ servers_up &&
+#endif
+ ((s_ticks_t)(now-rr->expire)>=0) /* expired rr */
+ )
continue;
if (rr->err_flags){ /* bad rr */
continue;
unsigned r_sum;
struct dns_rr* rr;
}r_sums[MAX_SRV_GRP_IDX];
+#ifdef DNS_WATCHDOG_SUPPORT
+ int servers_up;
+
+ servers_up = atomic_get(dns_servers_up);
+#endif
rand_w=0;
for(rr=e->rr_lst, n=0;rr && (n<*no);rr=rr->next, n++);/* skip *no records*/
found=0;
for (idx=0;rr && (prio==((struct srv_rdata*)rr->rdata)->priority) &&
(idx < MAX_SRV_GRP_IDX); idx++, rr=rr->next){
- if ( ((s_ticks_t)(now-rr->expire)>=0) /* expired entry */ ||
+ if ((
+#ifdef DNS_WATCHDOG_SUPPORT
+ /* check the expiration time only when the servers are up */
+ servers_up &&
+#endif
+ ((s_ticks_t)(now-rr->expire)>=0) /* expired entry */) ||
(rr->err_flags) /* bad rr */ ||
(srv_marked(tried, idx)) ) /* already tried */{
r_sums[idx].r_sum=0; /* 0 sum, to skip over it */
}
+#ifdef DNS_WATCHDOG_SUPPORT
+/* sets the state of the DNS servers:
+ * 1: at least one server is up
+ * 0: all the servers are down
+ */
+void dns_set_server_state(int state)
+{
+ atomic_set(dns_servers_up, state);
+}
+#endif /* DNS_WATCHDOG_SUPPORT */
/* rpc functions */
void dns_cache_mem_info(rpc_t* rpc, void* ctx)
UNLOCK_DNS_HASH();
}
+#ifdef DNS_WATCHDOG_SUPPORT
+/* sets the DNS server states */
+void dns_set_server_state_rpc(rpc_t* rpc, void* ctx)
+{
+ int state;
+
+ if (rpc->scan(ctx, "d", &state) < 1)
+ return;
+ dns_set_server_state(state);
+}
+#endif /* DNS_WATCHDOG_SUPPORT */
#endif