authd/providers: add timeout callback system.
This means that each provider no longer has to keep its own event; it can set a timeout and have a callbackinstead.
This commit is contained in:
parent
a20190d5ea
commit
15c49abbb3
5 changed files with 47 additions and 98 deletions
|
@ -52,11 +52,15 @@
|
|||
#include "provider.h"
|
||||
#include "notice.h"
|
||||
|
||||
static EVH provider_timeout_event;
|
||||
|
||||
rb_dlink_list auth_providers;
|
||||
|
||||
/* Clients waiting */
|
||||
rb_dictionary *auth_clients;
|
||||
|
||||
static struct ev_entry *timeout_ev;
|
||||
|
||||
/* Load a provider */
|
||||
void
|
||||
load_provider(struct auth_provider *provider)
|
||||
|
@ -105,6 +109,7 @@ void
|
|||
init_providers(void)
|
||||
{
|
||||
auth_clients = rb_dictionary_create("pending auth clients", rb_uint32cmp);
|
||||
timeout_ev = rb_event_addish("provider_timeout_event", provider_timeout_event, NULL, 1);
|
||||
load_provider(&rdns_provider);
|
||||
load_provider(&ident_provider);
|
||||
load_provider(&blacklist_provider);
|
||||
|
@ -345,3 +350,28 @@ handle_cancel_connection(int parc, char *parv[])
|
|||
|
||||
cancel_providers(auth);
|
||||
}
|
||||
|
||||
static void
|
||||
provider_timeout_event(void *notused __unused)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
const time_t curtime = rb_current_time();
|
||||
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, auth_providers.head)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
const time_t timeout = auth->timeout[provider->id];
|
||||
|
||||
if(is_provider_on(auth, provider->id) && provider->timeout != NULL &&
|
||||
timeout && timeout < curtime)
|
||||
{
|
||||
provider->timeout(auth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ typedef enum
|
|||
PROVIDER_RDNS,
|
||||
PROVIDER_IDENT,
|
||||
PROVIDER_BLACKLIST,
|
||||
PROVIDER_OPM,
|
||||
} provider_t;
|
||||
|
||||
struct auth_client
|
||||
|
@ -56,6 +57,7 @@ struct auth_client
|
|||
bool providers_starting; /* Providers are still warming up */
|
||||
|
||||
void *data[MAX_PROVIDERS]; /* Provider-specific data slots */
|
||||
time_t timeout[MAX_PROVIDERS]; /* When to call timeout callback */
|
||||
};
|
||||
|
||||
typedef bool (*provider_init_t)(void);
|
||||
|
@ -63,6 +65,7 @@ typedef void (*provider_destroy_t)(void);
|
|||
|
||||
typedef bool (*provider_start_t)(struct auth_client *);
|
||||
typedef void (*provider_cancel_t)(struct auth_client *);
|
||||
typedef void (*provider_timeout_t)(struct auth_client *);
|
||||
typedef void (*provider_complete_t)(struct auth_client *, provider_t);
|
||||
|
||||
struct auth_stats_handler
|
||||
|
@ -82,6 +85,7 @@ struct auth_provider
|
|||
|
||||
provider_start_t start; /* Perform authentication */
|
||||
provider_cancel_t cancel; /* Authentication cancelled */
|
||||
provider_timeout_t timeout; /* Timeout callback */
|
||||
provider_complete_t completed; /* Callback for when other performers complete (think dependency chains) */
|
||||
|
||||
struct auth_stats_handler stats_handler;
|
||||
|
|
|
@ -91,11 +91,9 @@ struct blacklist_filter
|
|||
struct blacklist_user
|
||||
{
|
||||
rb_dlink_list queries; /* Blacklist queries in flight */
|
||||
time_t timeout; /* When this times out */
|
||||
};
|
||||
|
||||
/* public interfaces */
|
||||
static bool blacklists_init(void);
|
||||
static void blacklists_destroy(void);
|
||||
|
||||
static bool blacklists_start(struct auth_client *);
|
||||
|
@ -108,11 +106,9 @@ static struct blacklist *find_blacklist(const char *);
|
|||
static bool blacklist_check_reply(struct blacklist_lookup *, const char *);
|
||||
static void blacklist_dns_callback(const char *, bool, query_type, void *);
|
||||
static void initiate_blacklist_dnsquery(struct blacklist *, struct auth_client *);
|
||||
static void timeout_blacklist_queries_event(void *);
|
||||
|
||||
/* Variables */
|
||||
static rb_dlink_list blacklist_list = { NULL, NULL, 0 };
|
||||
static struct ev_entry *timeout_ev;
|
||||
static int blacklist_timeout = 15;
|
||||
|
||||
/* private interfaces */
|
||||
|
@ -265,6 +261,7 @@ blacklist_dns_callback(const char *result, bool status, query_type type, void *d
|
|||
rb_dlink_list_length(&blacklist_list) > 1 ? "s" : "");
|
||||
rb_free(bluser);
|
||||
auth->data[PROVIDER_BLACKLIST] = NULL;
|
||||
auth->timeout[PROVIDER_BLACKLIST] = 0;
|
||||
provider_done(auth, PROVIDER_BLACKLIST);
|
||||
}
|
||||
}
|
||||
|
@ -294,25 +291,6 @@ initiate_blacklist_dnsquery(struct blacklist *bl, struct auth_client *auth)
|
|||
bl->refcount++;
|
||||
}
|
||||
|
||||
/* Timeout outstanding queries */
|
||||
static void
|
||||
timeout_blacklist_queries_event(void *notused)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
|
||||
|
||||
if(bluser != NULL && bluser->timeout < rb_current_time())
|
||||
{
|
||||
blacklists_cancel(auth);
|
||||
provider_done(auth, PROVIDER_BLACKLIST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
lookup_all_blacklists(struct auth_client *auth)
|
||||
{
|
||||
|
@ -330,7 +308,7 @@ lookup_all_blacklists(struct auth_client *auth)
|
|||
initiate_blacklist_dnsquery(bl, auth);
|
||||
}
|
||||
|
||||
bluser->timeout = rb_current_time() + blacklist_timeout;
|
||||
auth->timeout[PROVIDER_BLACKLIST] = rb_current_time() + blacklist_timeout;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -427,13 +405,8 @@ blacklists_cancel(struct auth_client *auth)
|
|||
|
||||
rb_free(bluser);
|
||||
auth->data[PROVIDER_BLACKLIST] = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
blacklists_init(void)
|
||||
{
|
||||
timeout_ev = rb_event_addish("timeout_blacklist_queries_event", timeout_blacklist_queries_event, NULL, 1);
|
||||
return (timeout_ev != NULL);
|
||||
auth->timeout[PROVIDER_BLACKLIST] = 0;
|
||||
provider_done(auth, PROVIDER_BLACKLIST);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -448,7 +421,6 @@ blacklists_destroy(void)
|
|||
}
|
||||
|
||||
delete_all_blacklists();
|
||||
rb_event_delete(timeout_ev);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -576,10 +548,10 @@ struct auth_opts_handler blacklist_options[] =
|
|||
struct auth_provider blacklist_provider =
|
||||
{
|
||||
.id = PROVIDER_BLACKLIST,
|
||||
.init = blacklists_init,
|
||||
.destroy = blacklists_destroy,
|
||||
.start = blacklists_start,
|
||||
.cancel = blacklists_cancel,
|
||||
.timeout = blacklists_cancel,
|
||||
.completed = blacklists_initiate,
|
||||
.opt_handlers = blacklist_options,
|
||||
/* .stats_handler = { 'B', blacklist_stats }, */
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
|
||||
struct ident_query
|
||||
{
|
||||
time_t timeout; /* Timeout interval */
|
||||
rb_fde_t *F; /* Our FD */
|
||||
};
|
||||
|
||||
|
@ -58,7 +57,6 @@ typedef enum
|
|||
REPORT_DISABLED,
|
||||
} ident_message;
|
||||
|
||||
static EVH timeout_ident_queries_event;
|
||||
static CNCB ident_connected;
|
||||
static PF read_ident_reply;
|
||||
|
||||
|
@ -66,27 +64,10 @@ static void client_fail(struct auth_client *auth, ident_message message);
|
|||
static void client_success(struct auth_client *auth);
|
||||
static char * get_valid_ident(char *buf);
|
||||
|
||||
static struct ev_entry *timeout_ev;
|
||||
static int ident_timeout = 5;
|
||||
static bool ident_enable = true;
|
||||
|
||||
|
||||
/* Timeout outstanding queries */
|
||||
static void
|
||||
timeout_ident_queries_event(void *notused __unused)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct ident_query *query = auth->data[PROVIDER_IDENT];
|
||||
|
||||
if(query != NULL && query->timeout < rb_current_time())
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ident_connected() - deal with the result of rb_connect_tcp()
|
||||
*
|
||||
|
@ -209,6 +190,7 @@ client_fail(struct auth_client *auth, ident_message report)
|
|||
|
||||
rb_free(query);
|
||||
auth->data[PROVIDER_IDENT] = NULL;
|
||||
auth->timeout[PROVIDER_IDENT] = 0;
|
||||
|
||||
notice_client(auth->cid, messages[report]);
|
||||
provider_done(auth, PROVIDER_IDENT);
|
||||
|
@ -227,6 +209,7 @@ client_success(struct auth_client *auth)
|
|||
|
||||
rb_free(query);
|
||||
auth->data[PROVIDER_IDENT] = NULL;
|
||||
auth->timeout[PROVIDER_IDENT] = 0;
|
||||
|
||||
notice_client(auth->cid, messages[REPORT_FOUND]);
|
||||
provider_done(auth, PROVIDER_IDENT);
|
||||
|
@ -296,13 +279,6 @@ get_valid_ident(char *buf)
|
|||
return (colon3Ptr);
|
||||
}
|
||||
|
||||
static bool
|
||||
ident_init(void)
|
||||
{
|
||||
timeout_ev = rb_event_addish("timeout_ident_queries_event", timeout_ident_queries_event, NULL, 1);
|
||||
return (timeout_ev != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
ident_destroy(void)
|
||||
{
|
||||
|
@ -338,7 +314,7 @@ static bool ident_start(struct auth_client *auth)
|
|||
notice_client(auth->cid, messages[REPORT_LOOKUP]);
|
||||
|
||||
auth->data[PROVIDER_IDENT] = query;
|
||||
query->timeout = rb_current_time() + ident_timeout;
|
||||
auth->timeout[PROVIDER_IDENT] = rb_current_time() + ident_timeout;
|
||||
|
||||
if((query->F = rb_socket(family, SOCK_STREAM, 0, "ident")) == NULL)
|
||||
{
|
||||
|
@ -416,10 +392,8 @@ struct auth_opts_handler ident_options[] =
|
|||
struct auth_provider ident_provider =
|
||||
{
|
||||
.id = PROVIDER_IDENT,
|
||||
.init = ident_init,
|
||||
.destroy = ident_destroy,
|
||||
.start = ident_start,
|
||||
.cancel = ident_cancel,
|
||||
.completed = NULL,
|
||||
.timeout = ident_cancel,
|
||||
.opt_handlers = ident_options,
|
||||
};
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
struct user_query
|
||||
{
|
||||
struct dns_query *query; /* Pending DNS query */
|
||||
time_t timeout; /* When the request times out */
|
||||
};
|
||||
|
||||
/* Goinked from old s_auth.c --Elizabeth */
|
||||
|
@ -53,8 +52,6 @@ static void client_fail(struct auth_client *auth, dns_message message);
|
|||
static void client_success(struct auth_client *auth);
|
||||
static void dns_answer_callback(const char *res, bool status, query_type type, void *data);
|
||||
|
||||
static struct ev_entry *timeout_ev;
|
||||
static EVH timeout_dns_queries_event;
|
||||
static int rdns_timeout = 15;
|
||||
|
||||
static void
|
||||
|
@ -74,25 +71,6 @@ dns_answer_callback(const char *res, bool status, query_type type, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
/* Timeout outstanding queries */
|
||||
static void
|
||||
timeout_dns_queries_event(void *notused)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct user_query *query = auth->data[PROVIDER_RDNS];
|
||||
|
||||
if(query != NULL && query->timeout < rb_current_time())
|
||||
{
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
client_fail(struct auth_client *auth, dns_message report)
|
||||
{
|
||||
|
@ -108,6 +86,7 @@ client_fail(struct auth_client *auth, dns_message report)
|
|||
|
||||
rb_free(query);
|
||||
auth->data[PROVIDER_RDNS] = NULL;
|
||||
auth->timeout[PROVIDER_RDNS] = 0;
|
||||
|
||||
provider_done(auth, PROVIDER_RDNS);
|
||||
}
|
||||
|
@ -122,17 +101,11 @@ client_success(struct auth_client *auth)
|
|||
|
||||
rb_free(query);
|
||||
auth->data[PROVIDER_RDNS] = NULL;
|
||||
auth->timeout[PROVIDER_RDNS] = 0;
|
||||
|
||||
provider_done(auth, PROVIDER_RDNS);
|
||||
}
|
||||
|
||||
static bool
|
||||
rdns_init(void)
|
||||
{
|
||||
timeout_ev = rb_event_addish("timeout_dns_queries_event", timeout_dns_queries_event, NULL, 1);
|
||||
return (timeout_ev != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
rdns_destroy(void)
|
||||
{
|
||||
|
@ -144,8 +117,6 @@ rdns_destroy(void)
|
|||
if(auth->data[PROVIDER_RDNS] != NULL)
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
}
|
||||
|
||||
rb_event_delete(timeout_ev);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -153,9 +124,8 @@ rdns_start(struct auth_client *auth)
|
|||
{
|
||||
struct user_query *query = rb_malloc(sizeof(struct user_query));
|
||||
|
||||
query->timeout = rb_current_time() + rdns_timeout;
|
||||
|
||||
auth->data[PROVIDER_RDNS] = query;
|
||||
auth->timeout[PROVIDER_RDNS] = rb_current_time() + rdns_timeout;
|
||||
|
||||
query->query = lookup_hostname(auth->c_ip, dns_answer_callback, auth);
|
||||
|
||||
|
@ -196,10 +166,9 @@ struct auth_opts_handler rdns_options[] =
|
|||
struct auth_provider rdns_provider =
|
||||
{
|
||||
.id = PROVIDER_RDNS,
|
||||
.init = rdns_init,
|
||||
.destroy = rdns_destroy,
|
||||
.start = rdns_start,
|
||||
.cancel = rdns_cancel,
|
||||
.completed = NULL,
|
||||
.timeout = rdns_cancel,
|
||||
.opt_handlers = rdns_options,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue