*/
#include "authd.h"
+#include "defaults.h"
#include "provider.h"
#include "notice.h"
#include "stdinc.h"
#include "dns.h"
+#define SELF_PID (blacklist_provider.id)
+
typedef enum filter_t
{
FILTER_ALL = 1,
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 *);
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;
+static int blacklist_timeout = BLACKLIST_TIMEOUT_DEFAULT;
/* private interfaces */
struct blacklist *bl;
struct auth_client *auth;
- if (bllookup == NULL || bllookup->auth == NULL)
- return;
+ lrb_assert(bllookup != NULL);
+ lrb_assert(bllookup->auth != NULL);
bl = bllookup->bl;
auth = bllookup->auth;
- bluser = auth->data[PROVIDER_BLACKLIST];
- if(bluser == NULL)
+
+ if((bluser = get_provider_data(auth, SELF_PID)) == NULL)
return;
if (result != NULL && status && blacklist_check_reply(bllookup, result))
/* Match found, so proceed no further */
bl->hits++;
blacklists_cancel(auth);
- reject_client(auth, PROVIDER_BLACKLIST, bl->host, bl->reason);
+ reject_client(auth, SELF_PID, bl->host, bl->reason);
return;
}
{
/* Done here */
notice_client(auth->cid, "*** IP not found in DNS blacklist%s",
- rb_dlink_list_length(&blacklist_list) > 1 : "s" : "");
+ rb_dlink_list_length(&blacklist_list) > 1 ? "s" : "");
rb_free(bluser);
- auth->data[PROVIDER_BLACKLIST] = NULL;
- provider_done(auth, PROVIDER_BLACKLIST);
+ set_provider_data(auth, SELF_PID, NULL);
+ set_provider_timeout_absolute(auth, SELF_PID, 0);
+ provider_done(auth, SELF_PID);
}
}
initiate_blacklist_dnsquery(struct blacklist *bl, struct auth_client *auth)
{
struct blacklist_lookup *bllookup = rb_malloc(sizeof(struct blacklist_lookup));
- struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
+ struct blacklist_user *bluser = get_provider_data(auth, SELF_PID);
char buf[IRCD_RES_HOSTLEN + 1];
int aftype;
if((aftype == AF_INET && (bl->iptype & IPTYPE_IPV4) == 0) ||
(aftype == AF_INET6 && (bl->iptype & IPTYPE_IPV6) == 0))
/* Incorrect blacklist type for this IP... */
+ {
+ rb_free(bllookup);
return;
+ }
build_rdns(buf, sizeof(buf), &auth->c_addr, bl->host);
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)
{
- struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
+ struct blacklist_user *bluser = get_provider_data(auth, SELF_PID);
rb_dlink_node *ptr;
notice_client(auth->cid, "*** Checking your IP against DNS blacklist%s",
initiate_blacklist_dnsquery(bl, auth);
}
- bluser->timeout = rb_current_time() + blacklist_timeout;
+ set_provider_timeout_relative(auth, SELF_PID, blacklist_timeout);
}
static inline void
static bool
blacklists_start(struct auth_client *auth)
{
- if(auth->data[PROVIDER_BLACKLIST] != NULL)
- return true;
+ uint32_t rdns_pid, ident_pid;
+
+ lrb_assert(get_provider_data(auth, SELF_PID) == NULL);
if(!rb_dlink_list_length(&blacklist_list))
- {
/* Nothing to do... */
- notice_client(auth->cid, "*** No DNS blacklists configured, not checking your IP");
return true;
- }
- auth->data[PROVIDER_BLACKLIST] = rb_malloc(sizeof(struct blacklist_user));
+ set_provider_data(auth, SELF_PID, rb_malloc(sizeof(struct blacklist_user)));
- if(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT))
- /* This probably can't happen but let's handle this case anyway */
+ if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) &&
+ (!get_provider_id("ident", &ident_pid) || is_provider_done(auth, ident_pid)))
+ {
+ /* Start the lookup if ident and rdns are finished, or not loaded. */
lookup_all_blacklists(auth);
+ }
- set_provider_on(auth, PROVIDER_BLACKLIST);
+ set_provider_running(auth, SELF_PID);
return true;
}
/* This is called every time a provider is completed as long as we are marked not done */
static void
-blacklists_initiate(struct auth_client *auth, provider_t provider)
+blacklists_initiate(struct auth_client *auth, uint32_t provider)
{
- struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
+ struct blacklist_user *bluser = get_provider_data(auth, SELF_PID);
+ uint32_t rdns_pid, ident_pid;
- lrb_assert(provider != PROVIDER_BLACKLIST);
- lrb_assert(!is_provider_done(auth, PROVIDER_BLACKLIST));
+ lrb_assert(provider != SELF_PID);
+ lrb_assert(!is_provider_done(auth, SELF_PID));
lrb_assert(rb_dlink_list_length(&blacklist_list) > 0);
if(bluser == NULL || rb_dlink_list_length(&bluser->queries))
/* Nothing to do */
return;
- else if(!(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT)))
- /* Don't start until we've completed these */
+ else if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) &&
+ (!get_provider_id("ident", &ident_pid) || is_provider_done(auth, ident_pid)))
+ /* Don't start until ident and rdns are finished (or not loaded) */
return;
else
lookup_all_blacklists(auth);
blacklists_cancel(struct auth_client *auth)
{
rb_dlink_node *ptr, *nptr;
- struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
+ struct blacklist_user *bluser = get_provider_data(auth, SELF_PID);
if(bluser == NULL)
return;
}
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);
+ set_provider_data(auth, SELF_PID, NULL);
+ set_provider_timeout_absolute(auth, SELF_PID, 0);
+ provider_done(auth, SELF_PID);
}
static void
}
delete_all_blacklists();
- rb_event_delete(timeout_ev);
}
static void
struct auth_provider blacklist_provider =
{
- .id = PROVIDER_BLACKLIST,
- .init = blacklists_init,
+ .name = "blacklist",
+ .letter = 'B',
.destroy = blacklists_destroy,
.start = blacklists_start,
.cancel = blacklists_cancel,
+ .timeout = blacklists_cancel,
.completed = blacklists_initiate,
.opt_handlers = blacklist_options,
/* .stats_handler = { 'B', blacklist_stats }, */