📄 dns_relay_cache.c
字号:
/* ############################################################################ (c) Copyright Virata Limited 2002## Virata Limited Confidential and Proprietary## The following software source code ("Software") is strictly confidential and# is proprietary to Virata Limited ("Virata"). It may only be read, used,# copied, adapted, modified or otherwise dealt with by you if you have# entered into a confidentiality agreement with Virata and then subject to the# terms of that confidentiality agreement and any other applicable agreement# between you and Virata. If you are in any doubt as to whether you are # entitled to access, read, use, copy, adapt, modify or otherwise deal with# the Software or whether you are entitled to disclose the Software to any# other person you should contact Virata. If you have not entered into a# confidentiality agreement with Virata granting access to this Software you# should forthwith return all media, copies and printed listings containing# the Software to Virata. ## Virata reserves the right to take legal action against you should you breach# the above provisions.## If you are unsure, or to report violations, please contact # support@virata.com# ##########################################################################*/#include <stdio.h>#include <stdlib.h>#include "dns_trace.h"#include "dns_relay_chdr.h"/* * the cache is set up so that it can be compiled to represent the cache * as either a hash table with linked lists for its buckets or a linked * list. */#ifndef DNS_RELAY_LL_CACHEstatic Cache_t *relay_cache[DNS_RELAY_CACHE];#elsestatic Cache_t *cache_head = NULL;#endifstatic Cache_t *cache_list = NULL;static int ce_inuse = 0;static unsigned long cache_hit = 0;static unsigned long cache_miss = 0;static ATMOS_MESSAGE dctomsg;#define free_cache_element(x) memset((x), 0, sizeof(Cache_t)); ce_inuse--static void cache_entry_clear(Cache_t **, Cache_t *, ce_func, void *);static Cache_t *get_cache_element(void);static Cache_t *get_relay_cache_element(void);static void insert_cache_entry(Cache_t *);static Cache_t *relay_cache_search(DnsQuestion *);#ifndef DNS_RELAY_LL_CACHEstatic unsigned long cache_string_hash(const unsigned char *);#endif/* * dns_relay_cache_init() * * this routine will allocate a chunk of Cache_ts. These are later individually * allocated for use by setting the unsed flag. * * return: ESUCCESS, or ENOMEM. */intdns_relay_cache_init(){ if ((cache_list = (Cache_t *)calloc(DNS_CACHE_POOLSIZE, sizeof(Cache_t))) == NULL) { TRACE(TRACE_WARN, "DNS relay error! No memory for cache!"); return -1; } return 0;} /* end dns_relay_cache_init() *//* * dns_relay_cache_free() * * This routine will free a chunk of Cache_ts. */voiddns_relay_cache_free(void){ free(cache_list);}#ifdef PLATFORM_ATMOS/* * dns_relay_timeout() * * this routine will send the message that we use for our time out notification. * see "ATMOS Core Reference", DO-007073-TC issue 4, section 9 for how the ATMOS * timer stuff works. basically we make a call to timer_ms_timeout() and after * some time around the time we ask for a message is sent to our process that * returns the ATMOS message we sent. that's our notification of the elapsed * time. this routine is just a wrapper around that call so that we can keep * the OS dependent stuff out of the relay engine. that and it keeps the message * out of the engine also. */voiddns_relay_timeout(){ timer_ms_timeout(&dctomsg, MS2SEC(DNS_CACHE_TIMEOUT));}#endif#ifdef DEBUG/* * dns_relay_dump_cache_resources() * * this routine will print each cache element indicating whether or not * it is currently in use or not. note that this could be a long list * depending on how many elements are available. */voiddns_relay_dump_cache_resources(){ int i; printf("\nlisting cache elements from resources.\n"); for ( i = 0; i < DNS_CACHE_POOLSIZE; i++ ) { printf("cache_pool[%d] = %s.\n", i, cache_list[i].used ? "used" : "unused"); }} /* end dns_relay_dump_cache_resources() *//* * dns_relay_cache_statistics() * * this routine just prints out some information about the cache. prints the * number of elements in use, how many hits the cache has had and how many * misses. */voiddns_relay_cache_statistics(){ printf("\nDNS Relay Cache Statistics:\n"); printf("Number of cache elements in use: %d\n", ce_inuse); printf("Number of cache hits: %d\n", cache_hit); printf("Number of cache misses: %d\n\n", cache_miss);} /* end dns_relay_cache_statistics() */#endif /* * dns_relay_cache_entry_timeout() * * this routine gets the current time and goes through each element in the * cache to determine if it has expired. the recursive routine cache_entry_clear() * does the actual work. */voiddns_relay_cache_entry_timeout(){ unsigned long ct; /* current time */#ifndef DNS_RELAY_LL_CACHE int i;#endif ct = timer_secs();#ifndef DNS_RELAY_LL_CACHE for ( i = 0; i < DNS_RELAY_CACHE; i++ ) { if ( relay_cache[i] != NULL ) cache_entry_clear(&relay_cache[i], relay_cache[i], timeout_match, (void *)&ct); }#else cache_entry_clear(&cache_head, cache_head, timeout_match, (void *)&ct);#endif} /* end dns_relay_cache_entry_timeout() *//* * dns_relay_cache_nohit_entry_clear() * * this routine will attempt to find entries that have not been used * frequently. we do this by looking to see if the entry has been used * and how long ago it may have been used. if not used when we're looking * at the entry its flagged from removal or if it has been accessed but * it has been longer ago than DNS_RELAY_CACHE_NOHIT_PERIOD then it is * also flagged to be removed. */voiddns_relay_cache_nohit_entry_clear(unsigned long period){ HTime_t htime;#ifndef DNS_RELAY_LL_CACHE int i;#endif htime.t_now = timer_secs(); htime.t_period = period;#ifndef DNS_RELAY_LL_CACHE for ( i = 0; i < DNS_RELAY_CACHE; i++ ) { if ( relay_cache[i] != NULL ) cache_entry_clear(&relay_cache[i], relay_cache[i], nohit_match, (void *)&htime); }#else cache_entry_clear(&cache_head, cache_head, nohit_match, (void *)&htime);#endif} /* end dns_relay_cache_nohit_entry_clear() *//* * dns_relay_flush_cache() * * this routine will flush the entire cache. all the elements are freed, * which just means they are returned to the pool. */voiddns_relay_flush_cache(){#ifndef DNS_RELAY_LL_CACHE int i; Cache_t *entry, *tmp; /* * loop through each bucket of the cache and if there's * something there, we loop through the (possible) list * and free each element. */ for ( i = 0; i < DNS_RELAY_CACHE; i++ ) { if ((entry = relay_cache[i]) == NULL) /* bucket empty, skip */ continue; while ( entry != NULL ) { tmp = entry; entry = entry->c_next; free_cache_element(tmp); } relay_cache[i] = NULL; }#else Cache_t *entry, *tmp; /* * starting at the head of the list loop through and free each * element. */ entry = cache_head; while ( entry != NULL ){ tmp = entry; entry = entry->c_next; free_cache_element(tmp); } cache_head = NULL;#endif} /* end dns_relay_flush_cache() *//* * cache_entry_clear() * * this routine will recursively go through a list and delete entries that * match with the match() routine. the ending criteria is the next pointer * being null. */static voidcache_entry_clear(Cache_t **head, Cache_t *ce, ce_func match, void *data){ if ( ce == NULL ) return; if ( match(ce, data) ) { if ( ce == *head ) { /* start of the list */ *head = ce->c_next; if ( ce->c_next != NULL ) { ce->c_next->c_prev = NULL; cache_entry_clear(head, ce->c_next, match, data); } free_cache_element(ce); return; } else if ( ce->c_next == NULL ) { /* end of the list */ ce->c_prev->c_next = NULL; free_cache_element(ce); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -