📄 dns_cash.c.svn-base
字号:
*/
if (!t_matched)
{
qname = r->rdata;
goto restart_cname;
}
} /* for loop */
/*
* Return number of RRs we found. If we found CNAMEs but didn't find
* appropriate RRs at the new name, pretend we found nothing at all.
*/
if (n_rrs > 0 && rrs[n_rrs-1]->type == DNS_T_CNAME &&
!dns_t_match(qtype, DNS_T_CNAME))
return 0;
else
return n_rrs;
}
/*------------------------------------------------------------------------
* dns_cache_rrs()
* Purpose: Routine to add all the RRs in a message to the cache.
* Returns status code.
* Parameters:
* Input:
* Output:
* returns :
*------------------------------------------------------------------------
*/
enum dns_error dns_cache_rrs
(unsigned char *msg, /* Message containing RRs to cache */
unsigned msg_len, /* Length of message */
struct dns_header *hdr, /* Decoded DNS header */
struct dns_rr rrs[], /* Parsed RRs from msg */
unsigned n_rrs) /* Length of rrs[] */
{
struct dns_rr *r , *head = 0;
UI32_T minttl;
unsigned rdcount;
enum dns_error err;
int i, j, n;
if (msg == 0 || hdr == 0 || rrs == 0)
return DNS_ERROR_BAD_ARGS;
if ((minttl = DNSR_Get_Max_TTL()) > DNS_MAX_TTL)
minttl = DNS_MAX_TTL;
/*
* Build a struct dns_rr for each RR we're going to cache,
* and add it to the chain.
*/
n = hdr->qdcount + hdr->ancount;
/* marked by Victor to cache only answers*/
if ((unsigned) n > n_rrs)
return DNS_ERROR_TRUNCATED;
for (i = hdr->qdcount; i < n; ++i)
{
/*
* Compute lengths of portions of this RR that might be compressed.
*/
if ((err = dns_uncompress_rdata(0, &rrs[i], msg, msg_len,
&rdcount)) != DNS_ERROR_OK)
return err;
if ((j = dns_uncompress_name(0, rrs[i].name, msg, msg_len)) == 0)
return DNS_ERROR_BAD_NAME;
/*
* Allocate a single block of memory big enough for the whole RR,
* and copy the RR, uncompressing as necessary. If this RR has a
* lower TTL than any other we've seen so far, remember the TTL.
* Add the RR to the list we're building.
*/
if (dns_cache_count < MAX_DNS_CACHE_RR)
{
dns_cache_count++;
/* structure of dns_rr + name size + rdata size*/
r = (struct dns_rr *)
OS_mem_alloc(sizeof(struct dns_rr) + j + rdcount);
if (r == 0)
return DNS_ERROR_ALLOCATION_FAILURE;
memset(r,0,sizeof(struct dns_rr));
*r = rrs[i];
r->name = ((unsigned char *) r) + sizeof(struct dns_rr);
r->rdcount = (UI16_T )rdcount;
r->rdata = r->name + j;
if (dns_uncompress_name(r->name, rrs[i].name, msg, msg_len) != j)
return DNS_ERROR_IMPOSSIBLE;
if ((err = dns_uncompress_rdata(r->rdata, &rrs[i], msg, msg_len,
&rdcount)) != DNS_ERROR_OK)
return err;
if (r->rdcount != rdcount)
return DNS_ERROR_IMPOSSIBLE;
if (minttl > r->ttl)
minttl = r->ttl;
r->next = head;
head = r;
};/* end of if dns_cache_count<MAX_DNS_CACHE_RR */
} /* for loop */
/*
* Insert these RRs into the cache, adjusting TTLs as we go.
*/
while ((r = head) != 0)
{
if (r->ttl > minttl)
r->ttl = minttl;
i = dns_hash(r->name);
head = r->next;
DNSR_Lock();
r->next = dns_cache[i];
dns_cache[i] = r;
DNSR_UnLock();
}
return DNS_ERROR_OK;
}
/*
* Routines to garbage collect the cache.
*
* dns_gc_mark() runs through the cache zeroing the TTLs of any RR that's
* timed out or associated (via ring pointers) with an RR that's timed out.
* This routine can be called at any time without risk of memory
* corruption, although calling it concurrently with dns_lookup() will
* confuse the bleep out of the latter. dns_gc_mark() must be called
* often enough to catch timed-out RRs before the clock wraps too far.
*
* dns_gc_sweep() reclaims space occupied by timed-out RRs. This
* should not be run when any pointers into the cache might exist.
* Skipping a call to dns_gc_sweep() will not affect the correct
* operation of the code, although it will cost you in memory usage
* and performance.
*
* dns_gc_nuke() relaims all space occupied by cached RRs, whether
* or not they have timed out. It can be called at any time that
* it would be ok to call dns_gc_sweep().
*/
/*------------------------------------------------------------------------
* dns_gc_mark()
* Purpose:
*
* Parameters:
* Input:
* Output:
* returns :
*------------------------------------------------------------------------
*/
void dns_gc_mark(void)
{
struct dns_rr *p;
UI32_T now = GLUE_NOW();
int i;
/*
* Find and mark every RR in the cache which is too old,
* or which is chained to an RR which is too old.
*
* Anything which has arrived since the start of the oldest query
* should be safe, since its birthdate alone should make it ok even
* if its TTL is zero. Similarly, since all chained RRs should
* have the same birthdate, they should all be safe if they were
* received after the oldest query was started.
*/
for (i = 0; i < DNS_CACHE_SIZE; ++i)
for (p = dns_cache[i]; p != 0; p = p->next)
if (!dns_ttl_valid(p, now))
{
p->expired = TRUE;
}
else
{
};
}
void dns_gc_sweep(void)
{
struct dns_rr **pp, *p;
int i;
for (i = 0; i < DNS_CACHE_SIZE; ++i)
{
pp = &dns_cache[i];
while ((p = *pp) != 0)
{
DNSR_Lock();
if (p->expired)
{
*pp = p->next;
#if DNSR_DEBUG
DBG_L3_Printf("OS_mem_free(cache): p=%x\n", p);
#endif
OS_mem_free((void *)p);
dns_cache_count--;
}
else
{
pp = &p->next;
}
DNSR_UnLock();
} /* for loop */
} /* while loop */
}
void dns_gc_nuke()
{
struct dns_rr *p;
int i;
dns_gc_mark_time = GLUE_NOW();
dns_gc_sweep_time = GLUE_NOW();
DNSR_Lock();
dns_cache_count = 0;
for (i = 0; i < DNS_CACHE_SIZE; ++i)
{
while ((p = dns_cache[i]) != 0)
{
dns_cache[i] = p->next;
OS_mem_free((void *)p);
}
}
DNSR_UnLock();
}
/*------------------------------------------------------------------------
* UI32_T dns_check_cache()
* Purpose: check dns cache
*
* Parameters:
* Input:
* Output:
* returns :
*------------------------------------------------------------------------
*/
UI32_T dns_check_cache(void)
{
UI32_T mark_time ,sweep_time ;
/* cache status is disabled, do nothing */
if (DNSR_Get_Cache_Status() == FALSE)
return 0xffffffff;
/* check the cache expiration time */
if (GLUE_NOW() - dns_gc_mark_time > DNS_CACHE_MARK_PERIOD)
{
dns_gc_mark();
dns_gc_mark_time = GLUE_NOW();
mark_time = DNS_CACHE_MARK_PERIOD;
}
else
mark_time = DNS_CACHE_MARK_PERIOD - (GLUE_NOW() - dns_gc_mark_time);
if (GLUE_NOW() - dns_gc_sweep_time > DNS_CACHE_SWEEP_PERIOD)
{
dns_gc_sweep();
dns_gc_sweep_time = GLUE_NOW();
sweep_time = DNS_CACHE_SWEEP_PERIOD;
}
else
sweep_time = DNS_CACHE_SWEEP_PERIOD - (GLUE_NOW() - dns_gc_sweep_time);
return ((mark_time <sweep_time)? mark_time : sweep_time);
}
/*------------------------------------------------------------------------
* void dns_gc_init()
* Purpose: initialize dns cache
*
* Parameters:
* Input:
* Output:
* returns :
*------------------------------------------------------------------------
*/
void dns_gc_init(void)
{
int i;
dns_gc_mark_time = 0;
dns_gc_sweep_time =0;
dns_cache_count =0;
for (i = 0 ; i <DNS_CACHE_SIZE ;i++)
dns_cache[i] = 0;
}
/*------------------------------------------------------------------------
* void dns_gc_count()
* Purpose: return total cache
*
* Parameters:
* Input:
* Output:
* returns :
*------------------------------------------------------------------------
*/
int dns_gc_count(void)
{
return dns_cache_count;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -