mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-04 21:09:19 +08:00
171 lines
4.3 KiB
C++
171 lines
4.3 KiB
C++
#include "stdafx.h"
|
|
#include "service_main.h"
|
|
|
|
static ACL_AIO *__aio = NULL;
|
|
static ACL_HTABLE *__cache = NULL;
|
|
|
|
void ns_cache_init(ACL_AIO *aio)
|
|
{
|
|
const char *myname = "ns_cache_init";
|
|
|
|
if (__cache != NULL)
|
|
acl_msg_fatal("%s(%d): __cache != NULL", myname, __LINE__);
|
|
|
|
__aio = aio;
|
|
__cache = acl_htable_create(10000, 0);
|
|
}
|
|
|
|
static void ns_cache_timeout_fn(int event_type acl_unused,
|
|
ACL_EVENT *event acl_unused, void *context)
|
|
{
|
|
NS_CACHE_ENTRY *entry = (NS_CACHE_ENTRY*) context;
|
|
|
|
acl_htable_delete(__cache, entry->domain, NULL);
|
|
ns_cache_entry_free(entry);
|
|
}
|
|
|
|
void ns_cache_add(NS_CACHE_ENTRY *entry)
|
|
{
|
|
const char *myname = "ns_cache_add";
|
|
NS_CACHE_ENTRY *old_entry;
|
|
|
|
if (__cache == NULL)
|
|
acl_msg_fatal("%s(%d): ns_cache_init not called",
|
|
myname, __LINE__);
|
|
|
|
old_entry = (NS_CACHE_ENTRY*) acl_htable_find(__cache, entry->domain);
|
|
if (old_entry == NULL) {
|
|
acl_htable_enter(__cache, entry->domain, (char*) entry);
|
|
if (entry->ttl > 0)
|
|
acl_aio_request_timer(__aio, ns_cache_timeout_fn,
|
|
entry, entry->ttl, 0);
|
|
return;
|
|
}
|
|
|
|
if (entry->ttl > 0) {
|
|
acl_aio_cancel_timer(__aio, ns_cache_timeout_fn, old_entry);
|
|
acl_aio_request_timer(__aio, ns_cache_timeout_fn,
|
|
entry, entry->ttl, 0);
|
|
}
|
|
if (entry == old_entry)
|
|
return;
|
|
acl_htable_delete(__cache, old_entry->domain, NULL);
|
|
ns_cache_entry_free(old_entry);
|
|
acl_htable_enter(__cache, entry->domain, (char*) entry);
|
|
}
|
|
|
|
NS_CACHE_ENTRY *ns_cache_find(const char *domain)
|
|
{
|
|
const char *myname = "ns_cache_find";
|
|
NS_CACHE_ENTRY *entry;
|
|
char key[MAX_DOMAIN_LEN];
|
|
|
|
if (__cache == NULL)
|
|
acl_msg_fatal("%s(%d): ns_cache_init not called",
|
|
myname, __LINE__);
|
|
|
|
ACL_SAFE_STRNCPY(key, domain, sizeof(key));
|
|
acl_lowercase(key);
|
|
|
|
entry = (NS_CACHE_ENTRY*) acl_htable_find(__cache, key);
|
|
return (entry);
|
|
}
|
|
|
|
int ns_cache_delete(const char *domain)
|
|
{
|
|
const char *myname = "ns_cache_delete";
|
|
char key[MAX_DOMAIN_LEN];
|
|
|
|
if (__cache == NULL)
|
|
acl_msg_fatal("%s(%d): ns_cache_init not called",
|
|
myname, __LINE__);
|
|
|
|
ACL_SAFE_STRNCPY(key, domain, sizeof(key));
|
|
acl_lowercase(key);
|
|
|
|
return (acl_htable_delete(__cache, key,
|
|
(void (*)(void*))ns_cache_entry_free));
|
|
}
|
|
|
|
void ns_cache_entry_free(NS_CACHE_ENTRY *entry)
|
|
{
|
|
if (entry->ip_list)
|
|
acl_argv_free(entry->ip_list);
|
|
acl_myfree(entry);
|
|
}
|
|
|
|
NS_CACHE_ENTRY *ns_cache_entry_new(const char *domain, const ACL_ARGV *ip_list,
|
|
const char *cache_buf, int dlen, int ttl)
|
|
{
|
|
const char *myname = "ns_cache_entry_new";
|
|
NS_CACHE_ENTRY *entry;
|
|
int i;
|
|
|
|
if (ip_list == NULL && (cache_buf == NULL || dlen <= 0)) {
|
|
acl_msg_error("%s(%d): invalid input args", myname, __LINE__);
|
|
return (NULL);
|
|
}
|
|
if (ip_list != NULL && (cache_buf != NULL && dlen > 0)) {
|
|
acl_msg_error("%s(%d): ip_list != NULL and cache_buf != NULL",
|
|
myname, __LINE__);
|
|
return (NULL);
|
|
}
|
|
|
|
entry = (NS_CACHE_ENTRY*) acl_mycalloc(1, sizeof(NS_CACHE_ENTRY));
|
|
entry->idx = 0;
|
|
entry->ttl = ttl;
|
|
ACL_SAFE_STRNCPY(entry->domain, domain, sizeof(entry->domain));
|
|
acl_lowercase(entry->domain);
|
|
|
|
if (ip_list) {
|
|
entry->ip_list = acl_argv_alloc(10);
|
|
for (i = 0; i < ip_list->argc; i++) {
|
|
acl_argv_add(entry->ip_list, ip_list->argv[i], NULL);
|
|
}
|
|
entry->cache_dlen = 0;
|
|
} else if (cache_buf) {
|
|
memcpy(entry->cache_buf, cache_buf, dlen);
|
|
entry->cache_dlen = dlen;
|
|
}
|
|
|
|
return (entry);
|
|
}
|
|
|
|
static char __unknown_domain[MAX_DOMAIN_LEN];
|
|
static NS_CACHE_ENTRY *__unknown_cache_entry;
|
|
|
|
void ns_cache_add_unknown(const char *domain, const ACL_ARGV *ip_list)
|
|
{
|
|
__unknown_cache_entry = ns_cache_entry_new(domain, ip_list, NULL, 0, 0);
|
|
ACL_SAFE_STRNCPY(__unknown_domain, domain, sizeof(__unknown_domain));
|
|
}
|
|
|
|
NS_CACHE_ENTRY *ns_cache_unknown(void)
|
|
{
|
|
const char *myname = "ns_cache_unknown";
|
|
|
|
if (__unknown_cache_entry == NULL)
|
|
acl_msg_fatal("%s(%d): __unknown_cache_entry null",
|
|
myname, __LINE__);
|
|
return (__unknown_cache_entry);
|
|
}
|
|
|
|
ACL_ARGV *ns_cache_ip_list(NS_CACHE_ENTRY *cache_entry)
|
|
{
|
|
ACL_ARGV *argv = acl_argv_alloc(10);
|
|
ACL_ARGV *ip_list = cache_entry->ip_list;
|
|
int i, n;
|
|
|
|
n = ip_list->argc;
|
|
if (cache_entry->idx >= n)
|
|
cache_entry->idx = 0;
|
|
i = cache_entry->idx++;
|
|
while (n-- > 0) {
|
|
acl_argv_add(argv, ip_list->argv[i++], NULL);
|
|
if (i >= ip_list->argc)
|
|
i = 0;
|
|
}
|
|
|
|
return (argv);
|
|
}
|