[xiph-commits] r14114 - icecast/trunk/icecast/src
karl at svn.xiph.org
karl at svn.xiph.org
Thu Nov 8 11:52:52 PST 2007
Author: karl
Date: 2007-11-08 11:52:51 -0800 (Thu, 08 Nov 2007)
New Revision: 14114
Modified:
icecast/trunk/icecast/src/auth.c
icecast/trunk/icecast/src/auth.h
Log:
auth sync up. Fix longstanding race bug and make stream start/stop triggers work again.
Modified: icecast/trunk/icecast/src/auth.c
===================================================================
--- icecast/trunk/icecast/src/auth.c 2007-11-08 13:57:27 UTC (rev 14113)
+++ icecast/trunk/icecast/src/auth.c 2007-11-08 19:52:51 UTC (rev 14114)
@@ -40,12 +40,13 @@
static mutex_t auth_lock;
-static void auth_client_setup (mount_proxy *mountinfo, client_t *client)
+static auth_client *auth_client_setup (const char *mount, client_t *client)
{
/* This will look something like "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" */
const char *header = httpp_getvar(client->parser, "authorization");
char *userpass, *tmp;
char *username, *password;
+ auth_client *auth_user;
do
{
@@ -81,23 +82,35 @@
} while (0);
- thread_mutex_lock (&mountinfo->auth->lock);
- client->auth = mountinfo->auth;
- client->auth->refcount++;
- DEBUG2 ("...refcount on auth_t %s is %d", client->auth->mount, client->auth->refcount);
- thread_mutex_unlock (&mountinfo->auth->lock);
+ auth_user = calloc (1, sizeof(auth_client));
+ auth_user->mount = strdup (mount);
+ auth_user->client = client;
+ return auth_user;
}
-static void queue_auth_client (auth_client *auth_user)
+static void queue_auth_client (auth_client *auth_user, mount_proxy *mountinfo)
{
auth_t *auth;
- if (auth_user == NULL)
+ if (auth_user == NULL || (mountinfo == NULL && auth_user->client
+ && auth_user->client->auth == NULL))
return;
- auth = auth_user->client->auth;
- thread_mutex_lock (&auth->lock);
auth_user->next = NULL;
+ if (mountinfo)
+ {
+ auth = mountinfo->auth;
+ thread_mutex_lock (&auth->lock);
+ if (auth_user->client)
+ auth_user->client->auth = auth;
+ auth->refcount++;
+ }
+ else
+ {
+ auth = auth_user->client->auth;
+ thread_mutex_lock (&auth->lock);
+ }
+ DEBUG2 ("...refcount on auth_t %s is now %d", auth->mount, auth->refcount);
*auth->tailp = auth_user;
auth->tailp = &auth_user->next;
auth->pending_count++;
@@ -172,7 +185,7 @@
/* wrapper function for auth thread to authenticate new listener
* connection details
*/
-static void auth_new_listener (auth_client *auth_user)
+static void auth_new_listener (auth_t *auth, auth_client *auth_user)
{
client_t *client = auth_user->client;
@@ -184,9 +197,9 @@
client->respcode = 400;
return;
}
- if (client->auth->authenticate)
+ if (auth->authenticate)
{
- if (client->auth->authenticate (auth_user) != AUTH_OK)
+ if (auth->authenticate (auth_user) != AUTH_OK)
return;
}
if (auth_postprocess_listener (auth_user) < 0)
@@ -196,7 +209,7 @@
/* wrapper function for auth thread to drop listener connections
*/
-static void auth_remove_listener (auth_client *auth_user)
+static void auth_remove_listener (auth_t *auth, auth_client *auth_user)
{
client_t *client = auth_user->client;
@@ -212,24 +225,22 @@
/* Callback from auth thread to handle a stream start event, this applies
* to both source clients and relays.
*/
-static void stream_start_callback (auth_client *auth_user)
+static void stream_start_callback (auth_t *auth, auth_client *auth_user)
{
- auth_t *auth = auth_user->client->auth;
-
if (auth->stream_start)
auth->stream_start (auth_user);
+ auth_release (auth);
}
/* Callback from auth thread to handle a stream start event, this applies
* to both source clients and relays.
*/
-static void stream_end_callback (auth_client *auth_user)
+static void stream_end_callback (auth_t *auth, auth_client *auth_user)
{
- auth_t *auth = auth_user->client->auth;
-
if (auth->stream_end)
auth->stream_end (auth_user);
+ auth_release (auth);
}
@@ -263,7 +274,7 @@
auth_user->next = NULL;
if (auth_user->process)
- auth_user->process (auth_user);
+ auth_user->process (auth, auth_user);
else
ERROR0 ("client auth process not set");
@@ -282,10 +293,8 @@
* on either the active or pending lists.
* return 1 if ok to add or 0 to prevent
*/
-static int check_duplicate_logins (source_t *source, client_t *client)
+static int check_duplicate_logins (source_t *source, client_t *client, auth_t *auth)
{
- auth_t *auth = client->auth;
-
/* allow multiple authenticated relays */
if (client->username == NULL)
return 1;
@@ -391,6 +400,8 @@
int ret = 0;
source_t *source = NULL;
+ client->authenticated = 1;
+
/* Here we are parsing the URI request to see if the extension is .xsl, if
* so, then process this request as an XSLT request
*/
@@ -407,7 +418,7 @@
if (source)
{
- if (client->auth && check_duplicate_logins (source, client) == 0)
+ if (check_duplicate_logins (source, client, mountinfo->auth) == 0)
{
avl_tree_unlock (global.source_tree);
return -1;
@@ -440,7 +451,6 @@
ice_config_t *config = config_get_config();
mount_proxy *mountinfo = config_find_mount (config, auth_user->mount);
- client->authenticated = 1;
ret = add_authenticated_listener (auth_user->mount, mountinfo, client);
config_release_config();
@@ -468,7 +478,7 @@
client_send_403 (client, "mountpoint unavailable");
return;
}
- if (mountinfo && mountinfo->auth)
+ if (mountinfo && mountinfo->auth && mountinfo->auth->authenticate)
{
auth_client *auth_user;
@@ -479,21 +489,11 @@
client_send_403 (client, "busy, please try again later");
return;
}
- auth_client_setup (mountinfo, client);
- config_release_config ();
-
- auth_user = calloc (1, sizeof (auth_client));
- if (auth_user == NULL)
- {
- client_send_401 (client);
- return;
- }
- auth_user->mount = strdup (mount);
+ auth_user = auth_client_setup (mount, client);
auth_user->process = auth_new_listener;
- auth_user->client = client;
-
INFO0 ("adding client for authentication");
- queue_auth_client (auth_user);
+ queue_auth_client (auth_user, mountinfo);
+ config_release_config ();
}
else
{
@@ -510,18 +510,22 @@
*/
int auth_release_listener (client_t *client)
{
- if (client->auth)
+ if (client->authenticated)
{
- auth_client *auth_user = calloc (1, sizeof (auth_client));
- if (auth_user == NULL)
- return 0;
+ const char *mount = httpp_getvar (client->parser, HTTPP_VAR_URI);
- auth_user->mount = strdup (httpp_getvar (client->parser, HTTPP_VAR_URI));
- auth_user->process = auth_remove_listener;
- auth_user->client = client;
+ /* drop any queue reference here, we do not want a race between the source thread
+ * and the auth/fserve thread */
+ client_set_queue (client, NULL);
- queue_auth_client (auth_user);
- return 1;
+ if (mount && client->auth && client->auth->release_listener)
+ {
+ auth_client *auth_user = auth_client_setup (mount, client);
+ auth_user->process = auth_remove_listener;
+ queue_auth_client (auth_user, NULL);
+ return 1;
+ }
+ client->authenticated = 0;
}
return 0;
}
@@ -648,7 +652,7 @@
auth_user->mount = strdup (mount);
auth_user->process = stream_start_callback;
- queue_auth_client (auth_user);
+ queue_auth_client (auth_user, mountinfo);
}
}
}
@@ -667,7 +671,7 @@
auth_user->mount = strdup (mount);
auth_user->process = stream_end_callback;
- queue_auth_client (auth_user);
+ queue_auth_client (auth_user, mountinfo);
}
}
}
Modified: icecast/trunk/icecast/src/auth.h
===================================================================
--- icecast/trunk/icecast/src/auth.h 2007-11-08 13:57:27 UTC (rev 14113)
+++ icecast/trunk/icecast/src/auth.h 2007-11-08 19:52:51 UTC (rev 14114)
@@ -42,7 +42,7 @@
{
char *mount;
client_t *client;
- void (*process)(struct auth_client_tag *auth_user);
+ void (*process)(struct auth_tag *auth, struct auth_client_tag *auth_user);
struct auth_client_tag *next;
} auth_client;
More information about the commits
mailing list