The feature is desabled by default, enable it with -DDNS_WATCHDOG_SUPPORT (required DNS cache enabled)
... | ... |
@@ -60,6 +60,7 @@ |
60 | 60 |
# 2007-05-26 changed darwin module link flags (instead of -bundle_loader ser |
61 | 61 |
# -flat_namespace -undefined suppress) (andrei) |
62 | 62 |
# 2007-07-07 added HAVE_SCHED_SETSCHEDULER for linux (andrei) |
63 |
+# 2007-07-18 added DNS_WATCHDOG_SUPPORT (Miklos) |
|
63 | 64 |
|
64 | 65 |
# check if already included/exported |
65 | 66 |
|
... | ... |
@@ -403,6 +404,11 @@ endif |
403 | 404 |
# unsafe) |
404 | 405 |
# -DUSE_NAPTR |
405 | 406 |
# turns on naptr support (but must be also enabled from the config) |
407 |
+# -DDNS_WATCHDOG_SUPPORT |
|
408 |
+# turns on DNS watchdog support which can be used to inform the |
|
409 |
+# core that the DNS servers are down. No DNS query is performed |
|
410 |
+# when the servers are unreachable, and even expired resource |
|
411 |
+# records are used from the cache. (requires external watchdog) |
|
406 | 412 |
|
407 | 413 |
# Sometimes is needes correct non-quoted $OS. HACK: gcc translates known OS to number ('linux'), so there is added underscore |
408 | 414 |
|
... | ... |
@@ -423,6 +429,7 @@ DEFS+= $(extra_defs) \ |
423 | 429 |
-DUSE_DNS_FAILOVER \ |
424 | 430 |
-DUSE_DST_BLACKLIST \ |
425 | 431 |
-DUSE_NAPTR \ |
432 |
+ #-DDNS_WATCHDOG_SUPPORT \ |
|
426 | 433 |
#-DLL_MALLOC \ |
427 | 434 |
#-DSF_MALLOC \ |
428 | 435 |
#-DDL_MALLOC \ |
... | ... |
@@ -57,7 +57,17 @@ static const char* dns_cache_debug_all_doc[] = { |
57 | 57 |
"complete dns debug dump", /* Documentation string */ |
58 | 58 |
0 /* Method signature(s) */ |
59 | 59 |
}; |
60 |
-#endif |
|
60 |
+ |
|
61 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
62 |
+void dns_set_server_state_rpc(rpc_t* rpc, void* ctx); |
|
63 |
+ |
|
64 |
+static const char* dns_set_server_state_doc[] = { |
|
65 |
+ "sets the state of the DNS servers " \ |
|
66 |
+ "(0: all the servers are down, 1: at least one server is up)", /* Documentation string */ |
|
67 |
+ 0 /* Method signature(s) */ |
|
68 |
+}; |
|
69 |
+#endif /* DNS_WATCHDOG_SUPPORT */ |
|
70 |
+#endif /* USE_DNS_CACHE */ |
|
61 | 71 |
#ifdef USE_DST_BLACKLIST |
62 | 72 |
void dst_blst_debug(rpc_t* rpc, void* ctx); |
63 | 73 |
void dst_blst_mem_info(rpc_t* rpc, void* ctx); |
... | ... |
@@ -469,6 +479,9 @@ rpc_export_t core_rpc_methods[] = { |
469 | 479 |
{"dns.mem_info", dns_cache_mem_info, dns_cache_mem_info_doc, 0 }, |
470 | 480 |
{"dns.debug", dns_cache_debug, dns_cache_debug_doc, 0 }, |
471 | 481 |
{"dns.debug_all", dns_cache_debug_all, dns_cache_debug_all_doc, 0 }, |
482 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
483 |
+ {"dns.set_server_state", dns_set_server_state_rpc, dns_set_server_state_doc, 0 }, |
|
484 |
+#endif |
|
472 | 485 |
#endif |
473 | 486 |
#ifdef USE_DST_BLACKLIST |
474 | 487 |
{"dst_blacklist.mem_info", dst_blst_mem_info, dst_blst_mem_info_doc, 0 }, |
... | ... |
@@ -33,6 +33,8 @@ |
33 | 33 |
* 2007-06-14 dns iterate through A & AAAA records fix (andrei) |
34 | 34 |
* 2007-06-15 srv rr weight based load balancing support (andrei) |
35 | 35 |
* 2007-06-16 naptr support (andrei) |
36 |
+ * 2008-07-18 DNS watchdog support -- can be used to inform the core |
|
37 |
+ * that the DNS servers are down (Miklos) |
|
36 | 38 |
*/ |
37 | 39 |
|
38 | 40 |
#ifdef USE_DNS_CACHE |
... | ... |
@@ -112,6 +114,10 @@ static struct dns_hash_head* dns_hash=0; |
112 | 114 |
|
113 | 115 |
static struct timer_ln* dns_timer_h=0; |
114 | 116 |
|
117 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
118 |
+static atomic_t *dns_servers_up = NULL; |
|
119 |
+#endif |
|
120 |
+ |
|
115 | 121 |
|
116 | 122 |
|
117 | 123 |
static const char* dns_str_errors[]={ |
... | ... |
@@ -192,6 +198,11 @@ inline static int dns_cache_free_mem(unsigned int target, int expired_only); |
192 | 198 |
|
193 | 199 |
static ticks_t dns_timer(ticks_t ticks, struct timer_ln* tl, void* data) |
194 | 200 |
{ |
201 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
202 |
+ /* do not clean the hash table if the servers are down */ |
|
203 |
+ if (atomic_get(dns_servers_up) == 0) |
|
204 |
+ return (ticks_t)(-1); |
|
205 |
+#endif |
|
195 | 206 |
if (*dns_cache_mem_used>12*(dns_cache_max_mem/16)){ /* ~ 75% used */ |
196 | 207 |
dns_cache_free_mem(dns_cache_max_mem/2, 1); |
197 | 208 |
}else{ |
... | ... |
@@ -210,6 +221,12 @@ void destroy_dns_cache() |
210 | 221 |
timer_free(dns_timer_h); |
211 | 222 |
dns_timer_h=0; |
212 | 223 |
} |
224 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
225 |
+ if (dns_servers_up){ |
|
226 |
+ shm_free(dns_servers_up); |
|
227 |
+ dns_servers_up=0; |
|
228 |
+ } |
|
229 |
+#endif |
|
213 | 230 |
if (dns_hash_lock){ |
214 | 231 |
lock_destroy(dns_hash_lock); |
215 | 232 |
lock_dealloc(dns_hash_lock); |
... | ... |
@@ -277,6 +294,15 @@ int init_dns_cache() |
277 | 294 |
ret=-1; |
278 | 295 |
goto error; |
279 | 296 |
} |
297 |
+ |
|
298 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
299 |
+ dns_servers_up=shm_malloc(sizeof(atomic_t)); |
|
300 |
+ if (dns_servers_up==0){ |
|
301 |
+ ret=E_OUT_OF_MEM; |
|
302 |
+ goto error; |
|
303 |
+ } |
|
304 |
+ atomic_set(dns_servers_up, 1); |
|
305 |
+#endif |
|
280 | 306 |
|
281 | 307 |
/* fix options */ |
282 | 308 |
dns_cache_max_mem<<=10; /* Kb */ /* TODO: test with 0 */ |
... | ... |
@@ -413,6 +439,11 @@ inline static struct dns_hash_entry* _dns_hash_find(str* name, int type, |
413 | 439 |
ticks_t now; |
414 | 440 |
int cname_chain; |
415 | 441 |
str cname; |
442 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
443 |
+ int servers_up; |
|
444 |
+ |
|
445 |
+ servers_up = atomic_get(dns_servers_up); |
|
446 |
+#endif |
|
416 | 447 |
|
417 | 448 |
cname_chain=0; |
418 | 449 |
ret=0; |
... | ... |
@@ -425,8 +456,14 @@ again: |
425 | 456 |
name->len, type, *h); |
426 | 457 |
#endif |
427 | 458 |
clist_foreach_safe(&dns_hash[*h], e, tmp, next){ |
428 |
- /* automatically remove expired elements */ |
|
429 |
- if ((s_ticks_t)(now-e->expire)>=0){ |
|
459 |
+ if ( |
|
460 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
461 |
+ /* remove expired elements only when the dns servers are up */ |
|
462 |
+ servers_up && |
|
463 |
+#endif |
|
464 |
+ /* automatically remove expired elements */ |
|
465 |
+ ((s_ticks_t)(now-e->expire)>=0) |
|
466 |
+ ) { |
|
430 | 467 |
_dns_hash_remove(e); |
431 | 468 |
}else if ((e->type==type) && (e->name_len==name->len) && |
432 | 469 |
(strncasecmp(e->name, name->s, e->name_len)==0)){ |
... | ... |
@@ -1476,6 +1513,10 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type) |
1476 | 1513 |
goto end;/* we do not cache obvious stuff */ |
1477 | 1514 |
} |
1478 | 1515 |
} |
1516 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
1517 |
+ if (atomic_get(dns_servers_up)==0) |
|
1518 |
+ goto end; /* the servers are down, needless to perform the query */ |
|
1519 |
+#endif |
|
1479 | 1520 |
if (name->len>=MAX_DNS_NAME){ |
1480 | 1521 |
LOG(L_ERR, "ERROR: dns_cache_do_request: name too long (%d chars)\n", |
1481 | 1522 |
name->len); |
... | ... |
@@ -1660,11 +1701,22 @@ inline static struct dns_rr* dns_entry_get_rr( struct dns_hash_entry* e, |
1660 | 1701 |
struct dns_rr* rr; |
1661 | 1702 |
int n; |
1662 | 1703 |
int flags; |
1704 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
1705 |
+ int servers_up; |
|
1706 |
+ |
|
1707 |
+ servers_up = atomic_get(dns_servers_up); |
|
1708 |
+#endif |
|
1663 | 1709 |
|
1664 | 1710 |
flags=0; |
1665 | 1711 |
for(rr=e->rr_lst, n=0;rr && (n<*no);rr=rr->next, n++);/* skip *no records*/ |
1666 | 1712 |
for(;rr;rr=rr->next){ |
1667 |
- if ((s_ticks_t)(now-e->expire)>=0) /* expired entry */ |
|
1713 |
+ if ( |
|
1714 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
1715 |
+ /* check the expiration time only when the servers are up */ |
|
1716 |
+ servers_up && |
|
1717 |
+#endif |
|
1718 |
+ ((s_ticks_t)(now-rr->expire)>=0) /* expired rr */ |
|
1719 |
+ ) |
|
1668 | 1720 |
continue; |
1669 | 1721 |
if (rr->err_flags){ /* bad rr */ |
1670 | 1722 |
continue; |
... | ... |
@@ -1741,6 +1793,11 @@ inline static struct dns_rr* dns_srv_get_nxt_rr(struct dns_hash_entry* e, |
1741 | 1793 |
unsigned r_sum; |
1742 | 1794 |
struct dns_rr* rr; |
1743 | 1795 |
}r_sums[MAX_SRV_GRP_IDX]; |
1796 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
1797 |
+ int servers_up; |
|
1798 |
+ |
|
1799 |
+ servers_up = atomic_get(dns_servers_up); |
|
1800 |
+#endif |
|
1744 | 1801 |
|
1745 | 1802 |
rand_w=0; |
1746 | 1803 |
for(rr=e->rr_lst, n=0;rr && (n<*no);rr=rr->next, n++);/* skip *no records*/ |
... | ... |
@@ -1755,7 +1812,12 @@ retry: |
1755 | 1812 |
found=0; |
1756 | 1813 |
for (idx=0;rr && (prio==((struct srv_rdata*)rr->rdata)->priority) && |
1757 | 1814 |
(idx < MAX_SRV_GRP_IDX); idx++, rr=rr->next){ |
1758 |
- if ( ((s_ticks_t)(now-rr->expire)>=0) /* expired entry */ || |
|
1815 |
+ if (( |
|
1816 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
1817 |
+ /* check the expiration time only when the servers are up */ |
|
1818 |
+ servers_up && |
|
1819 |
+#endif |
|
1820 |
+ ((s_ticks_t)(now-rr->expire)>=0) /* expired entry */) || |
|
1759 | 1821 |
(rr->err_flags) /* bad rr */ || |
1760 | 1822 |
(srv_marked(tried, idx)) ) /* already tried */{ |
1761 | 1823 |
r_sums[idx].r_sum=0; /* 0 sum, to skip over it */ |
... | ... |
@@ -2939,6 +3001,16 @@ int dns_srv_get_ip(str* name, struct ip_addr* ip, unsigned short* port, |
2939 | 3001 |
} |
2940 | 3002 |
|
2941 | 3003 |
|
3004 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
3005 |
+/* sets the state of the DNS servers: |
|
3006 |
+ * 1: at least one server is up |
|
3007 |
+ * 0: all the servers are down |
|
3008 |
+ */ |
|
3009 |
+void dns_set_server_state(int state) |
|
3010 |
+{ |
|
3011 |
+ atomic_set(dns_servers_up, state); |
|
3012 |
+} |
|
3013 |
+#endif /* DNS_WATCHDOG_SUPPORT */ |
|
2942 | 3014 |
|
2943 | 3015 |
/* rpc functions */ |
2944 | 3016 |
void dns_cache_mem_info(rpc_t* rpc, void* ctx) |
... | ... |
@@ -3026,5 +3098,16 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx) |
3026 | 3098 |
UNLOCK_DNS_HASH(); |
3027 | 3099 |
} |
3028 | 3100 |
|
3101 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
3102 |
+/* sets the DNS server states */ |
|
3103 |
+void dns_set_server_state_rpc(rpc_t* rpc, void* ctx) |
|
3104 |
+{ |
|
3105 |
+ int state; |
|
3106 |
+ |
|
3107 |
+ if (rpc->scan(ctx, "d", &state) < 1) |
|
3108 |
+ return; |
|
3109 |
+ dns_set_server_state(state); |
|
3110 |
+} |
|
3111 |
+#endif /* DNS_WATCHDOG_SUPPORT */ |
|
3029 | 3112 |
|
3030 | 3113 |
#endif |
... | ... |
@@ -48,6 +48,10 @@ |
48 | 48 |
#error "DNS FAILOVER requires DNS CACHE support (define USE_DNS_CACHE)" |
49 | 49 |
#endif |
50 | 50 |
|
51 |
+#if defined(DNS_WATCHDOG_SUPPORT) && !defined(USE_DNS_CACHE) |
|
52 |
+#error "DNS WATCHDOG requires DNS CACHE support (define USE_DNS_CACHE)" |
|
53 |
+#endif |
|
54 |
+ |
|
51 | 55 |
/* uncomment the define below for SRV weight based load balancing */ |
52 | 56 |
#define DNS_SRV_LB |
53 | 57 |
|
... | ... |
@@ -308,4 +312,13 @@ inline static int dns_sip_resolve2su(struct dns_srv_handle* h, |
308 | 312 |
init_su(su, &ip, port); |
309 | 313 |
return ret; |
310 | 314 |
} |
315 |
+ |
|
316 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
317 |
+/* sets the state of the DNS servers: |
|
318 |
+ * 1: at least one server is up |
|
319 |
+ * 0: all the servers are down |
|
320 |
+ */ |
|
321 |
+void dns_set_server_state(int state); |
|
322 |
+#endif /* DNS_WATCHDOG_SUPPORT */ |
|
323 |
+ |
|
311 | 324 |
#endif |
... | ... |
@@ -260,6 +260,12 @@ |
260 | 260 |
#define USE_DNS_FAILOVER_STR "" |
261 | 261 |
#endif |
262 | 262 |
|
263 |
+#ifdef DNS_WATCHDOG_SUPPORT |
|
264 |
+#define DNS_WATCHDOG_SUPPORT_STR ", DNS_WATCHDOG_SUPPORT" |
|
265 |
+#else |
|
266 |
+#define DNS_WATCHDOG_SUPPORT_STR "" |
|
267 |
+#endif |
|
268 |
+ |
|
263 | 269 |
#ifdef USE_NAPTR |
264 | 270 |
#define USE_NAPTR_STR ", USE_NAPTR" |
265 | 271 |
#else |
... | ... |
@@ -297,7 +303,7 @@ |
297 | 303 |
USE_FUTEX_STR \ |
298 | 304 |
FAST_LOCK_STR NOSMP_STR USE_PTHREAD_MUTEX_STR USE_POSIX_SEM_STR \ |
299 | 305 |
USE_SYSV_SEM_STR USE_COMP_STR USE_DNS_CACHE_STR USE_DNS_FAILOVER_STR \ |
300 |
- USE_NAPTR_STR USE_DST_BLACKLIST_STR |
|
306 |
+ DNS_WATCHDOG_SUPPORT_STR USE_NAPTR_STR USE_DST_BLACKLIST_STR |
|
301 | 307 |
|
302 | 308 |
|
303 | 309 |
#endif |