struct opm_lookup
{
rb_dlink_list scans; /* List of scans */
+ bool in_progress;
};
struct opm_proxy
return NULL;
}
+/* This is called when an open proxy connects to us */
static void
read_opm_reply(rb_fde_t *F, void *data)
{
char readbuf[OPM_READSIZE];
ssize_t len;
- if(auth == NULL || (lookup = auth->data[PROVIDER_OPM]) == NULL)
- {
- rb_close(F);
- return;
- }
+ lrb_assert(auth != NULL);
+ lookup = get_provider_data(auth, PROVIDER_OPM);
+ lrb_assert(lookup != NULL);
if((len = rb_read(F, readbuf, sizeof(readbuf))) < 0 && rb_ignore_errno(errno))
{
uint8_t *c = sendbuf;
ssize_t ret;
- if(scan == NULL || (auth = scan->auth) == NULL || (lookup = auth->data[PROVIDER_OPM]) == NULL)
- return;
-
if(error || !opm_enable)
goto end;
+ lrb_assert(scan != NULL);
+
+ auth = scan->auth;
+ lookup = get_provider_data(auth, PROVIDER_OPM);
+
memcpy(c, "\x04\x01", 2); c += 2; /* Socks version 4, connect command */
switch(GET_SS_FAMILY(&auth->c_addr))
uint8_t *c = sendbuf;
ssize_t ret;
- if(scan == NULL || (auth = scan->auth) == NULL || (lookup = auth->data[PROVIDER_OPM]) == NULL)
- return;
-
if(error || !opm_enable)
goto end;
+ lrb_assert(scan != NULL);
+
+ auth = scan->auth;
+ lookup = get_provider_data(auth, PROVIDER_OPM);
+
/* Build the version header and socks request
* version header (3 bytes): version, number of auth methods, auth type (0 for none)
* connect req (3 bytes): version, command (1 = connect), reserved (0)
char *c = sendbuf;
ssize_t ret;
- if(scan == NULL || (auth = scan->auth) == NULL || (lookup = auth->data[PROVIDER_OPM]) == NULL)
- return;
-
if(error || !opm_enable)
goto end;
+ lrb_assert(scan != NULL);
+
+ auth = scan->auth;
+ lookup = get_provider_data(auth, PROVIDER_OPM);
+
switch(GET_SS_FAMILY(&auth->c_addr))
{
case AF_INET:
static inline void
establish_connection(struct auth_client *auth, struct opm_proxy *proxy)
{
- struct opm_lookup *lookup = auth->data[PROVIDER_OPM];
+ struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM);
struct opm_listener *listener;
struct opm_scan *scan = rb_malloc(sizeof(struct opm_scan));
struct rb_sockaddr_storage c_a, l_a;
int opt = 1;
CNCB *callback;
+ lrb_assert(lookup != NULL);
+
switch(proxy->proto)
{
case PROTO_SOCKS4:
scan->proxy = proxy;
if((scan->F = rb_socket(GET_SS_FAMILY(&auth->c_addr), SOCK_STREAM, 0, proxy->note)) == NULL)
{
- warn_opers(L_CRIT, "OPM: could not create OPM socket (proto %s): %s", proxy->note, strerror(errno));
+ warn_opers(L_WARN, "OPM: could not create OPM socket (proto %s): %s", proxy->note, strerror(errno));
rb_free(scan);
return;
}
exit(EX_PROVIDER_ERROR);
}
+ SET_SS_PORT(&addr, htons(port));
+
#ifdef RB_IPV6
if(GET_SS_FAMILY(&addr) == AF_INET6)
{
exit(EX_PROVIDER_ERROR);
}
- /* Set up ports for binding */
-#ifdef RB_IPV6
- if(GET_SS_FAMILY(&addr) == AF_INET6)
- ((struct sockaddr_in6 *)&addr)->sin6_port = htons(port);
- else
-#endif
- ((struct sockaddr_in *)&addr)->sin_port = htons(port);
-
if(bind(rb_get_fd(F), (struct sockaddr *)&addr, GET_SS_LEN(&addr)))
{
/* Shit happens, let's not cripple authd over /this/ since it could be user error */
return true;
}
-
static void
-opm_destroy(void)
+opm_scan(struct auth_client *auth)
{
- struct auth_client *auth;
- rb_dictionary_iter iter;
+ rb_dlink_node *ptr;
+ struct opm_lookup *lookup;
- /* Nuke all opm lookups */
- RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
+ lrb_assert(auth != NULL);
+
+ lookup = get_provider_data(auth, PROVIDER_OPM);
+ set_provider_timeout_relative(auth, PROVIDER_OPM, opm_timeout);
+
+ lookup->in_progress = true;
+
+ RB_DLINK_FOREACH(ptr, proxy_scanners.head)
{
- opm_cancel(auth);
+ struct opm_proxy *proxy = ptr->data;
+ establish_connection(auth, proxy);
}
+
+ notice_client(auth->cid, "*** Scanning for open proxies...");
+}
+
+/* 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)
+{
+ struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM);
+
+ lrb_assert(provider != PROVIDER_OPM);
+ lrb_assert(!is_provider_done(auth, PROVIDER_OPM));
+ lrb_assert(rb_dlink_list_length(&proxy_scanners) > 0);
+
+ if(lookup == NULL || lookup->in_progress)
+ /* 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 */
+ return;
+ else
+ opm_scan(auth);
}
static bool
opm_start(struct auth_client *auth)
{
- rb_dlink_node *ptr;
- struct opm_lookup *lookup = rb_malloc(sizeof(struct opm_lookup));
+ lrb_assert(get_provider_data(auth, PROVIDER_OPM) == NULL);
- if(!opm_enable || !rb_dlink_list_length(&proxy_scanners))
+ if(!opm_enable || rb_dlink_list_length(&proxy_scanners) == 0)
{
+ /* Nothing to do... */
notice_client(auth->cid, "*** Proxy scanning disabled, not scanning");
return true;
}
- auth->data[PROVIDER_OPM] = lookup = rb_malloc(sizeof(struct opm_lookup));
- auth->timeout[PROVIDER_OPM] = rb_current_time() + opm_timeout;
+ set_provider_data(auth, PROVIDER_BLACKLIST, rb_malloc(sizeof(struct opm_lookup)));
- RB_DLINK_FOREACH(ptr, proxy_scanners.head)
- {
- struct opm_proxy *proxy = ptr->data;
- establish_connection(auth, proxy);
- }
-
- notice_client(auth->cid, "*** Scanning for open proxies...");
- set_provider_on(auth, PROVIDER_OPM);
+ 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 */
+ opm_scan(auth);
+ set_provider_on(auth, PROVIDER_BLACKLIST);
return true;
}
static void
opm_cancel(struct auth_client *auth)
{
- struct opm_lookup *lookup = auth->data[PROVIDER_OPM];
+ struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM);
if(lookup != NULL)
{
}
rb_free(lookup);
+
+ set_provider_data(auth, PROVIDER_OPM, NULL);
+ set_provider_timeout_absolute(auth, PROVIDER_OPM, 0);
provider_done(auth, PROVIDER_OPM);
}
}
+static void
+opm_destroy(void)
+{
+ struct auth_client *auth;
+ rb_dictionary_iter iter;
+
+ /* Nuke all opm lookups */
+ RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
+ {
+ opm_cancel(auth);
+ }
+}
+
+
static void
add_conf_opm_timeout(const char *key __unused, int parc __unused, const char **parv)
{
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
{
rb_dlink_node *ptr;
- struct opm_lookup *lookup = auth->data[PROVIDER_OPM];
+ struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM);
if(lookup == NULL)
continue;
rb_dlinkDelete(&scan->node, &lookup->scans);
rb_free(scan);
- if(!rb_dlink_list_length(&lookup->scans))
+ if(rb_dlink_list_length(&lookup->scans) == 0)
opm_cancel(auth);
break;
rb_dlinkDelete(&proxy->node, &proxy_scanners);
rb_free(proxy);
+
+ if(rb_dlink_list_length(&proxy_scanners) == 0)
+ opm_enable = false;
}
static void
{
opm_cancel(auth);
}
+
+ opm_enable = false;
}