- DNS failure cache: do several attempts before blacklisting
This commit is contained in:
parent
6859b0b9b3
commit
f81e32fe73
@ -1,5 +1,6 @@
|
|||||||
0.6.1
|
0.6.1
|
||||||
=====
|
=====
|
||||||
|
20-Dec-2007: - DNS failure cache: do several attempts before blacklisting
|
||||||
28-Nov-2007: - Fix: Detach from controlling TTY if daemonized
|
28-Nov-2007: - Fix: Detach from controlling TTY if daemonized
|
||||||
22-Nov-2007: - Working on code that that will allow siproxd to use
|
22-Nov-2007: - Working on code that that will allow siproxd to use
|
||||||
separate interfaces in its "in front of NAT routes" setup.
|
separate interfaces in its "in front of NAT routes" setup.
|
||||||
|
|||||||
@ -261,6 +261,8 @@ int sip_message_set_body(osip_message_t * sip, const char *buf, size_t len);
|
|||||||
#define URL_STRING_SIZE 128 /* max size of an URL/URI string */
|
#define URL_STRING_SIZE 128 /* max size of an URL/URI string */
|
||||||
#define STATUSCODE_SIZE 5 /* size of string representation of status */
|
#define STATUSCODE_SIZE 5 /* size of string representation of status */
|
||||||
#define DNS_CACHE_SIZE 256 /* number of entries in internal DNS cache */
|
#define DNS_CACHE_SIZE 256 /* number of entries in internal DNS cache */
|
||||||
|
#define DNS_ATTEMPTS 3 /* number of attempts to resolve a name
|
||||||
|
before it is marked as bad */
|
||||||
#define DNS_GOOD_AGE 60 /* maximum age of a good cache entry (sec) */
|
#define DNS_GOOD_AGE 60 /* maximum age of a good cache entry (sec) */
|
||||||
#define DNS_BAD_AGE 600 /* maximum age of a bad cache entry (sec) */
|
#define DNS_BAD_AGE 600 /* maximum age of a bad cache entry (sec) */
|
||||||
#define IFADR_CACHE_SIZE 32 /* number of entries in internal IFADR cache */
|
#define IFADR_CACHE_SIZE 32 /* number of entries in internal IFADR cache */
|
||||||
|
|||||||
90
src/utils.c
90
src/utils.c
@ -63,7 +63,7 @@ extern int h_errno;
|
|||||||
* STS_FAILURE on failure
|
* STS_FAILURE on failure
|
||||||
*/
|
*/
|
||||||
int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
||||||
int i, j, k;
|
int i, j, k, idx;
|
||||||
time_t t1, t2;
|
time_t t1, t2;
|
||||||
struct hostent *hostentry;
|
struct hostent *hostentry;
|
||||||
#if defined(HAVE_GETHOSTBYNAME_R)
|
#if defined(HAVE_GETHOSTBYNAME_R)
|
||||||
@ -74,6 +74,7 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
|||||||
static struct {
|
static struct {
|
||||||
time_t expires_timestamp; /* time of expiration */
|
time_t expires_timestamp; /* time of expiration */
|
||||||
struct in_addr addr; /* IP address or 0.0.0.0 if a bad entry */
|
struct in_addr addr; /* IP address or 0.0.0.0 if a bad entry */
|
||||||
|
char error_count; /* counts failed resolution attempts */
|
||||||
char bad_entry; /* != 0 if resolving failed */
|
char bad_entry; /* != 0 if resolving failed */
|
||||||
char hostname[HOSTNAME_SIZE+1];
|
char hostname[HOSTNAME_SIZE+1];
|
||||||
} dns_cache[DNS_CACHE_SIZE];
|
} dns_cache[DNS_CACHE_SIZE];
|
||||||
@ -109,15 +110,22 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
|||||||
/*
|
/*
|
||||||
* search requested entry in cache
|
* search requested entry in cache
|
||||||
*/
|
*/
|
||||||
|
idx=0;
|
||||||
for (i=0; i<DNS_CACHE_SIZE; i++) {
|
for (i=0; i<DNS_CACHE_SIZE; i++) {
|
||||||
if (dns_cache[i].hostname[0]=='\0') continue; /* empty */
|
if (dns_cache[i].hostname[0]=='\0') continue; /* empty */
|
||||||
if (strcasecmp(hostname, dns_cache[i].hostname) == 0) { /* match */
|
if (strcasecmp(hostname, dns_cache[i].hostname) == 0) { /* match */
|
||||||
memcpy(addr, &dns_cache[i].addr, sizeof(struct in_addr));
|
memcpy(addr, &dns_cache[i].addr, sizeof(struct in_addr));
|
||||||
if (dns_cache[i].bad_entry) {
|
if (dns_cache[i].bad_entry) {
|
||||||
DEBUGC(DBCLASS_DNS, "DNS lookup - bad entry from cache: %s",
|
DEBUGC(DBCLASS_DNS, "DNS lookup - blacklisted from cache: %s",
|
||||||
hostname);
|
hostname);
|
||||||
return STS_FAILURE;
|
return STS_FAILURE;
|
||||||
}
|
}
|
||||||
|
if (dns_cache[i].error_count > 0) {
|
||||||
|
DEBUGC(DBCLASS_DNS, "DNS lookup - previous resolution failed: %s"
|
||||||
|
", attempt %i", hostname, dns_cache[i].error_count);
|
||||||
|
idx=i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
DEBUGC(DBCLASS_DNS, "DNS lookup - from cache: %s -> %s",
|
DEBUGC(DBCLASS_DNS, "DNS lookup - from cache: %s -> %s",
|
||||||
hostname, utils_inet_ntoa(*addr));
|
hostname, utils_inet_ntoa(*addr));
|
||||||
return STS_SUCCESS;
|
return STS_SUCCESS;
|
||||||
@ -203,47 +211,59 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
|||||||
hostname, utils_inet_ntoa(*addr));
|
hostname, utils_inet_ntoa(*addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* if we already have the entry, skip finding a new empty one */
|
||||||
* find an empty slot in the cache
|
if (idx == 0) {
|
||||||
*/
|
/*
|
||||||
j=0;
|
* find an empty slot in the cache
|
||||||
k=0;
|
*/
|
||||||
t1=INT_MAX;
|
j=0;
|
||||||
t2=INT_MAX;
|
k=0;
|
||||||
for (i=0; i<DNS_CACHE_SIZE; i++) {
|
t1=INT_MAX;
|
||||||
if (dns_cache[i].hostname[0]=='\0') break;
|
t2=INT_MAX;
|
||||||
if ((dns_cache[i].expires_timestamp < t1) &&
|
for (i=0; i<DNS_CACHE_SIZE; i++) {
|
||||||
(dns_cache[i].bad_entry == 0)) {
|
if (dns_cache[i].hostname[0]=='\0') break;
|
||||||
/* remember oldest good entry */
|
if ((dns_cache[i].expires_timestamp < t1) &&
|
||||||
t1=dns_cache[i].expires_timestamp;
|
(dns_cache[i].bad_entry == 0)) {
|
||||||
j=i;
|
/* remember oldest good entry */
|
||||||
} else
|
t1=dns_cache[i].expires_timestamp;
|
||||||
if (dns_cache[i].expires_timestamp < t2) {
|
j=i;
|
||||||
/* remember oldest bad entry */
|
} else
|
||||||
t2=dns_cache[i].expires_timestamp;
|
if (dns_cache[i].expires_timestamp < t2) {
|
||||||
k=i;
|
/* remember oldest bad entry */
|
||||||
|
t2=dns_cache[i].expires_timestamp;
|
||||||
|
k=i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
/* if no empty slot found, victimize oldest one.
|
||||||
/* if no empty slot found, victimize oldest one.
|
* Give preference to the oldest "bad" entry if
|
||||||
* Give preference to the oldest "bad" entry if
|
* one exists */
|
||||||
* one exists */
|
if (i >= DNS_CACHE_SIZE) {
|
||||||
if (i >= DNS_CACHE_SIZE) {
|
if (k > 0) i=k;
|
||||||
if (k > 0) i=k;
|
else i=j;
|
||||||
else i=j;
|
}
|
||||||
|
idx=i;
|
||||||
|
memset(&dns_cache[idx], 0, sizeof(dns_cache[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* store the result in the cache
|
* store the result in the cache
|
||||||
*/
|
*/
|
||||||
DEBUGC(DBCLASS_DNS, "DNS lookup - store into cache, entry %i)", i);
|
DEBUGC(DBCLASS_DNS, "DNS lookup - store into cache, entry %i)", idx);
|
||||||
memset(&dns_cache[i], 0, sizeof(dns_cache[0]));
|
strncpy(dns_cache[idx].hostname, hostname, HOSTNAME_SIZE);
|
||||||
strncpy(dns_cache[i].hostname, hostname, HOSTNAME_SIZE);
|
dns_cache[idx].expires_timestamp = time(NULL) + DNS_GOOD_AGE;
|
||||||
if (hostentry) {
|
if (hostentry) {
|
||||||
dns_cache[i].expires_timestamp = time(NULL) + DNS_GOOD_AGE;
|
memcpy(&dns_cache[idx].addr, addr, sizeof(struct in_addr));
|
||||||
memcpy(&dns_cache[i].addr, addr, sizeof(struct in_addr));
|
dns_cache[idx].error_count = 0;
|
||||||
|
dns_cache[idx].bad_entry = 0;
|
||||||
} else {
|
} else {
|
||||||
dns_cache[i].expires_timestamp = time(NULL) + DNS_BAD_AGE;
|
dns_cache[idx].error_count++;
|
||||||
dns_cache[i].bad_entry = 1;
|
DEBUGC(DBCLASS_DNS, "DNS lookup - errcnt=%i", dns_cache[idx].error_count);
|
||||||
|
if (dns_cache[idx].error_count >= DNS_ATTEMPTS) {
|
||||||
|
DEBUGC(DBCLASS_DNS, "DNS lookup - blacklisting entry");
|
||||||
|
dns_cache[idx].expires_timestamp = time(NULL) + DNS_BAD_AGE;
|
||||||
|
dns_cache[idx].bad_entry = 1;
|
||||||
|
}
|
||||||
|
return STS_FAILURE;
|
||||||
}
|
}
|
||||||
return STS_SUCCESS;
|
return STS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user