diff --git a/src/auth.c b/src/auth.c index ab22e0de..a66635c6 100644 --- a/src/auth.c +++ b/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 mutex_t _auth_lock; /* protects _current_id */ static volatile unsigned long _current_id = 0; @@ -127,13 +128,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); + } } @@ -255,12 +260,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) @@ -286,28 +316,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; } @@ -528,8 +537,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); + } } } diff --git a/src/auth.h b/src/auth.h index bc8de0ff..3a4e724d 100644 --- a/src/auth.h +++ b/src/auth.h @@ -79,6 +79,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); diff --git a/src/auth_anonymous.c b/src/auth_anonymous.c index fb856d47..8cc45126 100644 --- a/src/auth_anonymous.c +++ b/src/auth_anonymous.c @@ -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; } diff --git a/src/auth_htpasswd.c b/src/auth_htpasswd.c index 0b16c9da..679668e4 100644 --- a/src/auth_htpasswd.c +++ b/src/auth_htpasswd.c @@ -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)); diff --git a/src/auth_static.c b/src/auth_static.c index 6dff225e..640a527b 100644 --- a/src/auth_static.c +++ b/src/auth_static.c @@ -89,6 +89,7 @@ int auth_get_static_auth (auth_t *authenticator, config_options_t *options) { authenticator->listuser = static_userlist; authenticator->free = clear_auth; authenticator->state = auth_info; + authenticator->immediate = 1; while (options) { if (strcmp(options->name, "username") == 0) {