⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dns_cash.c.svn-base

📁 域名解析器的实现
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
        */
        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 + -