mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-09-22 04:15:54 -04:00
Feature: immediate mode for <role>s
This allows a <role> represented by a auth_t to run in "immediate" mode. In this mode no thread is created for this <role>. This is a major speedup. Closes #2124
This commit is contained in:
parent
c5bd8ad281
commit
25f6c53929
73
src/auth.c
73
src/auth.c
@ -50,6 +50,7 @@ struct auth_stack_tag {
|
||||
};
|
||||
|
||||
/* code */
|
||||
static void __handle_auth_client (auth_t *auth, auth_client *auth_user);
|
||||
|
||||
static auth_client *auth_client_setup (client_t *client)
|
||||
{
|
||||
@ -114,13 +115,17 @@ static void queue_auth_client (auth_client *auth_user)
|
||||
return;
|
||||
}
|
||||
auth = auth_user->client->auth;
|
||||
thread_mutex_lock (&auth->lock);
|
||||
ICECAST_LOG_DEBUG("...refcount on auth_t %s is now %d", auth->mount, (int)auth->refcount);
|
||||
*auth->tailp = auth_user;
|
||||
auth->tailp = &auth_user->next;
|
||||
auth->pending_count++;
|
||||
ICECAST_LOG_INFO("auth on %s has %d pending", auth->mount, auth->pending_count);
|
||||
thread_mutex_unlock (&auth->lock);
|
||||
if (auth->immediate) {
|
||||
__handle_auth_client(auth, auth_user);
|
||||
} else {
|
||||
thread_mutex_lock (&auth->lock);
|
||||
*auth->tailp = auth_user;
|
||||
auth->tailp = &auth_user->next;
|
||||
auth->pending_count++;
|
||||
ICECAST_LOG_INFO("auth on %s has %d pending", auth->mount, auth->pending_count);
|
||||
thread_mutex_unlock (&auth->lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -240,12 +245,37 @@ static auth_result auth_remove_client(auth_t *auth, auth_client *auth_user)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __handle_auth_client (auth_t *auth, auth_client *auth_user) {
|
||||
auth_result result;
|
||||
|
||||
if (auth_user->process) {
|
||||
result = auth_user->process(auth, auth_user);
|
||||
} else {
|
||||
ICECAST_LOG_ERROR("client auth process not set");
|
||||
result = AUTH_FAILED;
|
||||
}
|
||||
|
||||
if (result == AUTH_OK) {
|
||||
if (auth_user->client->acl)
|
||||
acl_release(auth_user->client->acl);
|
||||
acl_addref(auth_user->client->acl = auth->acl);
|
||||
if (auth->role) /* TODO: Handle errors here */
|
||||
auth_user->client->role = strdup(auth->role);
|
||||
}
|
||||
|
||||
if (result == AUTH_NOMATCH && auth_user->on_no_match) {
|
||||
auth_user->on_no_match(auth_user->client, auth_user->on_result, auth_user->userdata);
|
||||
} else if (auth_user->on_result) {
|
||||
auth_user->on_result(auth_user->client, auth_user->userdata, result);
|
||||
}
|
||||
|
||||
auth_client_free (auth_user);
|
||||
}
|
||||
|
||||
/* The auth thread main loop. */
|
||||
static void *auth_run_thread (void *arg)
|
||||
{
|
||||
auth_t *auth = arg;
|
||||
auth_result result;
|
||||
|
||||
ICECAST_LOG_INFO("Authentication thread started");
|
||||
while (auth->running)
|
||||
@ -271,28 +301,7 @@ static void *auth_run_thread (void *arg)
|
||||
thread_mutex_unlock(&auth->lock);
|
||||
auth_user->next = NULL;
|
||||
|
||||
if (auth_user->process) {
|
||||
result = auth_user->process(auth, auth_user);
|
||||
} else {
|
||||
ICECAST_LOG_ERROR("client auth process not set");
|
||||
result = AUTH_FAILED;
|
||||
}
|
||||
|
||||
if (result == AUTH_OK) {
|
||||
if (auth_user->client->acl)
|
||||
acl_release(auth_user->client->acl);
|
||||
acl_addref(auth_user->client->acl = auth->acl);
|
||||
if (auth->role) /* TODO: Handle errors here */
|
||||
auth_user->client->role = strdup(auth->role);
|
||||
}
|
||||
|
||||
if (result == AUTH_NOMATCH && auth_user->on_no_match) {
|
||||
auth_user->on_no_match(auth_user->client, auth_user->on_result, auth_user->userdata);
|
||||
} else if (auth_user->on_result) {
|
||||
auth_user->on_result(auth_user->client, auth_user->userdata, result);
|
||||
}
|
||||
|
||||
auth_client_free (auth_user);
|
||||
__handle_auth_client(auth, auth_user);
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -511,8 +520,10 @@ auth_t *auth_get_authenticator(xmlNodePtr node)
|
||||
auth = NULL;
|
||||
} else {
|
||||
auth->tailp = &auth->head;
|
||||
auth->running = 1;
|
||||
auth->thread = thread_create("auth thread", auth_run_thread, auth, THREAD_ATTACHED);
|
||||
if (!auth->immediate) {
|
||||
auth->running = 1;
|
||||
auth->thread = thread_create("auth thread", auth_run_thread, auth, THREAD_ATTACHED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,11 @@ typedef struct auth_tag
|
||||
/* filters */
|
||||
int method[httpp_req_unknown+1];
|
||||
|
||||
/* whether authenticate_client() and release_client() will return immediate.
|
||||
* Setting this will result in no thread being started for this.
|
||||
*/
|
||||
int immediate;
|
||||
|
||||
/* Authenticate using the given username and password */
|
||||
auth_result (*authenticate_client)(auth_client *aclient);
|
||||
auth_result (*release_client)(auth_client *auth_user);
|
||||
|
@ -26,5 +26,6 @@ static auth_result anonymous_auth (auth_client *auth_user) {
|
||||
|
||||
int auth_get_anonymous_auth (auth_t *authenticator, config_options_t *options) {
|
||||
authenticator->authenticate_client = anonymous_auth;
|
||||
authenticator->immediate = 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -226,6 +226,7 @@ int auth_get_htpasswd_auth (auth_t *authenticator, config_options_t *options)
|
||||
authenticator->adduser = htpasswd_adduser;
|
||||
authenticator->deleteuser = htpasswd_deleteuser;
|
||||
authenticator->listuser = htpasswd_userlist;
|
||||
authenticator->immediate = 1;
|
||||
|
||||
state = calloc(1, sizeof(htpasswd_auth_state));
|
||||
|
||||
|
@ -77,6 +77,7 @@ int auth_get_static_auth (auth_t *authenticator, config_options_t *options) {
|
||||
authenticator->authenticate_client = static_auth;
|
||||
authenticator->free = clear_auth;
|
||||
authenticator->state = auth_info;
|
||||
authenticator->immediate = 1;
|
||||
|
||||
while (options) {
|
||||
if (strcmp(options->name, "username") == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user