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

📄 dnscache.c

📁 快速开发
💻 C
字号:
#include "stx.h"#include "common.h"/***************************************** * Basic types definitions */typedef struct _stx_dns_data {    struct in_addr *addrs;    int num_addrs;    int cur;    time_t expires;} stx_dns_data_t;#define MAX_HOST_ADDRS 1024static struct in_addr addr_list[MAX_HOST_ADDRS];stx_cache_t *_stx_dns_cache = NULL;extern int _stx_dns_ttl;extern int _stx_dns_getaddrlist(const char *hostname, struct in_addr *addrs,				int *num_addrs, st_utime_t timeout);static unsigned long hash_hostname(const void *key){    const char *name = (const char *)key;    unsigned long hash = 0;    while (*name)	hash = (hash << 4) - hash + *name++; /* hash = hash * 15 + *name++ */    return hash;}static void cleanup_entry(void *key, void *data){    if (key)	free(key);    if (data) {	if (((stx_dns_data_t *)data)->addrs)	    free(((stx_dns_data_t *)data)->addrs);	free(data);    }}static int lookup_entry(const char *host, struct in_addr *addrs,			int *num_addrs, int rotate){    stx_cache_entry_t *entry;    stx_dns_data_t *data;    int n;    entry = stx_cache_entry_lookup(_stx_dns_cache, host);    if (entry) {	data = (stx_dns_data_t *)stx_cache_entry_getdata(entry);	if (st_time() <= data->expires) {	    if (*num_addrs == 1) {		if (rotate) {		    *addrs = data->addrs[data->cur++];		    if (data->cur >= data->num_addrs)			data->cur = 0;		} else {		    *addrs = data->addrs[0];		}	    } else {		n = STX_MIN(*num_addrs, data->num_addrs);		memcpy(addrs, data->addrs, n * sizeof(*addrs));		*num_addrs = n;	    }	    stx_cache_entry_release(_stx_dns_cache, entry);	    return 1;	}	/*	 * Cache entry expired: decrement its refcount and purge it from cache.	 */	stx_cache_entry_release(_stx_dns_cache, entry);	stx_cache_entry_delete(_stx_dns_cache, entry);    }    return 0;}static void insert_entry(const char *host, struct in_addr *addrs, int count){    stx_cache_entry_t *entry;    stx_dns_data_t *data;    char *key;    size_t n;    if (_stx_dns_ttl > 0) {	key = strdup(host);	data = (stx_dns_data_t *)malloc(sizeof(stx_dns_data_t));	n = count * sizeof(*addrs);	if (data) {	    data->addrs = (struct in_addr *)malloc(n);	    if (data->addrs)		memcpy(data->addrs, addrs, n);	    data->num_addrs = count;	    data->cur = 0;	    data->expires = st_time() + _stx_dns_ttl;	}	entry = stx_cache_entry_create(key, data, strlen(host) + 1 +				       sizeof(stx_dns_data_t) + n +				       stx_cache_entry_sizeof());	if (key && data && data->addrs && entry &&	    stx_cache_entry_insert(_stx_dns_cache, entry) == 0) {	    stx_cache_entry_release(_stx_dns_cache, entry);	    return;	}	if (entry)	    stx_cache_entry_delete(_stx_dns_cache, entry);	else	    cleanup_entry(key, data);    }}int _stx_dns_cache_getaddrlist(const char *hostname, struct in_addr *addrs,			       int *num_addrs, st_utime_t timeout,			       int rotate){    char host[128];    int n, count;    if (!_stx_dns_cache)	return _stx_dns_getaddrlist(hostname, addrs, num_addrs, timeout);    for (n = 0; n < sizeof(host) - 1 && hostname[n]; n++) {	host[n] = tolower(hostname[n]);    }    host[n] = '\0';    if (lookup_entry(host, addrs, num_addrs, rotate))	return 0;    count = MAX_HOST_ADDRS;    if (_stx_dns_getaddrlist(host, addr_list, &count, timeout) < 0)	return -1;    n = STX_MIN(*num_addrs, count);    memcpy(addrs, addr_list, n * sizeof(*addrs));    *num_addrs = n;    insert_entry(host, addr_list, count);    return 0;}int stx_dns_cache_init(size_t max_size, size_t max_bytes, size_t hash_size){    _stx_dns_cache = stx_cache_create(max_size, max_bytes, hash_size,				  hash_hostname,				  (long (*)(const void *, const void *))strcmp,				  cleanup_entry);    if (!_stx_dns_cache)	return -1;    return 0;}void stx_dns_cache_getinfo(stx_cache_info_t *info){    if (_stx_dns_cache)	stx_cache_getinfo(_stx_dns_cache, info);    else	memset(info, 0, sizeof(stx_cache_info_t));}	int stx_dns_getaddrlist(const char *hostname, struct in_addr *addrs,			int *num_addrs, st_utime_t timeout){    return _stx_dns_cache_getaddrlist(hostname, addrs, num_addrs, timeout, 0);}int stx_dns_getaddr(const char *hostname, struct in_addr *addr,		    st_utime_t timeout){    int n = 1;    return _stx_dns_cache_getaddrlist(hostname, addr, &n, timeout, 1);}

⌨️ 快捷键说明

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