#include "includes.h"
#define CONNCACHE_ADDR 1
#define CONNCACHE_NAME 2
struct failed_connection_cache {
fstring domain_name;
fstring controller;
time_t lookup_time;
NTSTATUS nt_status;
struct failed_connection_cache *prev, *next;
};
static struct failed_connection_cache *failed_connection_cache;
NTSTATUS check_negative_conn_cache_timeout( const char *domain, const char *server, unsigned int failed_cache_timeout )
{
struct failed_connection_cache *fcc;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
if ( !domain || !server )
return NT_STATUS_OK;
for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
if (!(strequal(domain, fcc->domain_name) && strequal(server, fcc->controller))) {
continue;
}
if (failed_cache_timeout != (unsigned int)-1) {
if (failed_cache_timeout == 0 ||
(time(NULL) - fcc->lookup_time) > (time_t)failed_cache_timeout) {
DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n",
domain, server ));
DLIST_REMOVE(failed_connection_cache, fcc);
SAFE_FREE(fcc);
return NT_STATUS_OK;
}
}
DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n",
domain, server ));
result = fcc->nt_status;
return result;
}
return NT_STATUS_OK;
}
NTSTATUS check_negative_conn_cache( const char *domain, const char *server)
{
return check_negative_conn_cache_timeout(domain, server, FAILED_CONNECTION_CACHE_TIMEOUT);
}
void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result)
{
struct failed_connection_cache *fcc;
SMB_ASSERT(!NT_STATUS_IS_OK(result));
for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) ) {
DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n",
domain, server ));
fcc->lookup_time = time(NULL);
return;
}
}
if ( !(fcc = SMB_MALLOC_P(struct failed_connection_cache)) ) {
DEBUG(0, ("malloc failed in add_failed_connection_entry!\n"));
return;
}
ZERO_STRUCTP(fcc);
fstrcpy( fcc->domain_name, domain );
fstrcpy( fcc->controller, server );
fcc->lookup_time = time(NULL);
fcc->nt_status = result;
DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n",
domain, server ));
DLIST_ADD(failed_connection_cache, fcc);
}
void flush_negative_conn_cache( void )
{
struct failed_connection_cache *fcc;
fcc = failed_connection_cache;
while (fcc) {
struct failed_connection_cache *fcc_next;
fcc_next = fcc->next;
DLIST_REMOVE(failed_connection_cache, fcc);
free(fcc);
fcc = fcc_next;
}
}
void flush_negative_conn_cache_for_domain(const char *domain)
{
struct failed_connection_cache *fcc;
fcc = failed_connection_cache;
while (fcc) {
struct failed_connection_cache *fcc_next;
fcc_next = fcc->next;
if (strequal(fcc->domain_name, domain)) {
DEBUG(10,("flush_negative_conn_cache_for_domain: removed server %s "
" from failed cache for domain %s\n",
fcc->controller, domain));
DLIST_REMOVE(failed_connection_cache, fcc);
free(fcc);
}
fcc = fcc_next;
}
}