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

📄 dns_relay_cache.c

📁 DNS 的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        else {                             /* in the middle of the list */            ce->c_prev->c_next = ce->c_next;            ce->c_next->c_prev = ce->c_prev;            cache_entry_clear(head, ce->c_next, match, data);            free_cache_element(ce);            return;        }    }    cache_entry_clear(head, ce->c_next, match, data);}   /* end cache_entry_clear() *//* * get_cache_element() * * this routine will loop through the array of cache entries and return * a pointer to the first unsed one. * * return:  pointer to an element, or *          NULL to indicate none available. */static Cache_t *get_cache_element(){    int  i;    for ( i = 0; i < DNS_CACHE_POOLSIZE; i++ ) {        if ( !cache_list[i].used ) {            cache_list[i].used = 1;            ce_inuse++;            return &cache_list[i];        }    }    return NULL;}   /* end get_cache_element() *//* * dns_cache_insert() * * this routine will attempt to insert an entry into the cache.  the routine * will verify some aspects of the reply.  note that the time out, tout, is * used as a make time for this cached element. * * return:  0 to indicate successfully cached, or *         -1 indicates an error. */intdns_cache_insert(DnsQuestion *q, void *reply, unsigned long tout, int rsize){    Cache_t   *entry;    /* see if this entry is already cached. if so, just return */    if ((entry = relay_cache_search(q)) != NULL)         return 0;    if ( rsize > DNSMAX ) {        TRACE(TRACE_WARN, "DNS relay cache error! DNS reply to be cached larger than 512!");        return -1;    }        if(tout == 0)       return 0;// With TTL=0, it's meant for temproary transactions, so don't cache!    /* get an entry for the new reply, if we can't get one, drop it */    if ((entry = get_relay_cache_element()) == NULL)         return 0;    entry->question.q_type = q->q_type;    entry->question.q_class = q->q_class;    strcpy(entry->question.q_name, q->q_name);    memcpy(entry->dnsreply, reply, rsize);    entry->rsize = rsize;    entry->created = timer_secs();    entry->timeout = tout;    insert_cache_entry(entry);    return 0;}   /* end dns_cache_insert() *//* * get_relay_cache_element() * * this routine will attempt to acquire a new cache element.  if none are * initially available, we attempt to time out entries, then we also clear * any entries that haven't been hit or hit recently. * * return:  pointer to a cache element or *          NULL if none are available. */static Cache_t *get_relay_cache_element(){    Cache_t *cache;    /*      * attempt to find an unused element.  if there are none, then attempt to     * time out entries and try again.  if there are still none, try clearing     * any seldom used entries or entries that haven't been used for some     * time.     */    if ((cache = get_cache_element()) == NULL) {        dns_relay_cache_entry_timeout();        if ((cache = get_cache_element()) == NULL)             dns_relay_cache_nohit_entry_clear(DNS_RELAY_CACHE_NOHIT_PERIOD);        else            return cache;        return get_cache_element();    }    return cache;}   /* end get_relay_cache_element() *//* * insert_cache_entry() * * this routine will just insert the cache entry into our cache.  no memory * is allocated and the structure is expected to be set up. */static voidinsert_cache_entry(Cache_t *entry){#ifndef DNS_RELAY_LL_CACHE    unsigned long  index;    Cache_t        *next;    char           tmp[256+1];    lowercase_copy(tmp, entry->question.q_name);    index = cache_string_hash((const unsigned char *)tmp);    if ( relay_cache[index] == NULL )         relay_cache[index] = entry;    else {        next = relay_cache[index];        while ( next->c_next )             next = next->c_next;        next->c_next = entry;        entry->c_prev = next;    }#else    Cache_t  *current;    if ( cache_head == NULL )         cache_head = entry;    else {        current = cache_head;        while ( current->c_next )            current = current->c_next;        current->c_next = entry;        entry->c_prev = current;    }#endif}   /* end insert_cache_entry() *//* * dns_cache_search() * * this routine will search the cache for a match to the question.  if * found then the entire saved dns replay is copied to dnsbuffer.  note * that it is assumed there is enough space. * * if a matching entry is located we increment the number of hits for that  * entry and update a time for last access of that entry.  this information  * is used when elimating entries when the cache is full. * * return:  number of bytes in the copied DNS reply, or *          0 which indicates no cache hit. */intdns_cache_search(DnsQuestion *q, void *dnsbuffer){    Cache_t        *entry;    unsigned char  *buffer = (unsigned char *)dnsbuffer;    if ((entry = relay_cache_search(q)) != NULL) {        memcpy(buffer + 2, entry->dnsreply + 2, (entry->rsize - 2));        entry->hits++;        entry->lasthit = timer_secs();        cache_hit++;        return entry->rsize;    }    cache_miss++;    return 0;       }   /* end dns_cache_search() */        /* * relay_cache_search() * * this routine will attempt to locate a cache entry bases on the information * of the DNS question.  the routine loops through each entry to compare the * passed in question with the question that is part of the cache entry.  if * * return:  a pointer to the matching entry if found, or *          NULL if no match. */static Cache_t *relay_cache_search(DnsQuestion *q){#ifndef DNS_RELAY_LL_CACHE    unsigned long  index;    Cache_t        *entry;    char           tmp[256+1];    /* hash the domain name in the question */    lowercase_copy(tmp, q->q_name);    index = cache_string_hash((const unsigned char *)tmp);    /* if the hashed bucket is empty, then there's no match */    if ((entry = relay_cache[index]) == NULL)        return NULL;    /*     * the bucket is a list, we loop through each element and     * compare the question to see if we have a match.      */    while ( entry != NULL ) {        if ( dns_question_compare(q, &entry->question) )         {            U32 now=timer_secs();            if(timeout_match(entry, &now) == FALSE)		return entry;            else                break;        }               entry = entry->c_next;    }    return NULL;   /* if we get here there wasn't a match */#else    Cache_t   *entry = cache_head;    /*     * the cache is a list, we loop through all the entries until     * either we find a match, or we run out of entries.       */    while ( entry != NULL ) {        if ( dns_question_compare(q, &entry->question) )             return entry;                entry = entry->c_next;    }    return NULL;   /* no match */#endif}   /* end relay_cache_search() */#ifndef DNS_RELAY_LL_CACHE/* * cache_string_hash() * * this is the hash routine for the cache.  note that it is pretty simply. * that's on purpose, this routine appears to have reasonable distribution * compared with more complex functions, but there's less computation. note * that its likely you can find a better hash function. */static unsigned long  cache_string_hash(const unsigned char *str){    unsigned long h = 0;    int           i;    for ( i = 0; *str; i++ )        h += *str++ + i;    return h % DNS_RELAY_CACHE;}   /* end cache_string_hash() */#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -