1
0
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:
Philipp Schafft 2014-12-19 17:27:54 +00:00
parent c5bd8ad281
commit 25f6c53929
5 changed files with 50 additions and 31 deletions

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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));

View File

@ -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) {