mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Fix a serious bug with source creation in relays when local-mount != mount,
and fix a series of locking bugs in source creation. svn path=/trunk/icecast/; revision=4352
This commit is contained in:
parent
8f0aefb2be
commit
76fc62810e
@ -290,6 +290,9 @@ static connection_t *_get_connection(void)
|
||||
return con;
|
||||
}
|
||||
|
||||
/* TODO: Make this return an appropriate error code so that we can use HTTP
|
||||
* codes where appropriate
|
||||
*/
|
||||
int connection_create_source(client_t *client, connection_t *con, http_parser_t *parser, char *mount) {
|
||||
source_t *source;
|
||||
char *contenttype;
|
||||
@ -306,7 +309,7 @@ int connection_create_source(client_t *client, connection_t *con, http_parser_t
|
||||
}
|
||||
global.sources++;
|
||||
global_unlock();
|
||||
|
||||
|
||||
stats_event_inc(NULL, "sources");
|
||||
|
||||
contenttype = httpp_getvar(parser, "content-type");
|
||||
@ -324,6 +327,21 @@ int connection_create_source(client_t *client, connection_t *con, http_parser_t
|
||||
ERROR0("No content-type header, falling back to backwards compatibility mode for icecast 1.x relays. Assuming content is mp3.");
|
||||
source = source_create(client, con, parser, mount, format);
|
||||
}
|
||||
|
||||
/* We did a preliminary check earlier, to catch the common case before
|
||||
* we do any unneccesary processing. Now, we do a check that must be
|
||||
* correct - so we have to take a write lock out, since we need to
|
||||
* add this source if it doesn't already exist.
|
||||
*/
|
||||
avl_tree_wlock(global.source_tree);
|
||||
if (source_find_mount(mount) != NULL) {
|
||||
INFO1("Source tried to log in as %s, but mountpoint is already used",
|
||||
mount);
|
||||
avl_tree_unlock(global.source_tree);
|
||||
goto fail;
|
||||
}
|
||||
/* Keep the tree locked - it gets unlocked in source_main */
|
||||
|
||||
client->respcode = 200;
|
||||
bytes = sock_write(client->con->sock,
|
||||
"HTTP/1.0 200 OK\r\n\r\n");
|
||||
@ -569,15 +587,15 @@ static void _handle_source_request(connection_t *con,
|
||||
|
||||
avl_tree_rlock(global.source_tree);
|
||||
if (source_find_mount(uri) != NULL) {
|
||||
avl_tree_unlock(global.source_tree);
|
||||
INFO1("Source tried to log in as %s, but mountpoint is already used", uri);
|
||||
client_send_404(client, "Mountpoint in use");
|
||||
avl_tree_unlock(global.source_tree);
|
||||
return;
|
||||
}
|
||||
avl_tree_unlock(global.source_tree);
|
||||
|
||||
if (!connection_create_source(client, con, parser, uri)) {
|
||||
client_destroy(client);
|
||||
client_send_404(client, "Mountpoint in use");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ static void *_slave_thread(void *arg) {
|
||||
relay = config_get_config()->relay;
|
||||
while(relay) {
|
||||
avl_tree_rlock(global.source_tree);
|
||||
if(!source_find_mount(relay->mount)) {
|
||||
if(!source_find_mount(relay->localmount)) {
|
||||
avl_tree_unlock(global.source_tree);
|
||||
|
||||
create_relay_stream(relay->server, relay->port, relay->mount,
|
||||
|
@ -48,7 +48,7 @@ source_t *source_create(client_t *client, connection_t *con, http_parser_t *pars
|
||||
src->client = client;
|
||||
src->mount = (char *)strdup(mount);
|
||||
src->fallback_mount = NULL;
|
||||
src->format = format_get_plugin(type, src->mount);
|
||||
src->format = format_get_plugin(type, src->mount, parser);
|
||||
src->con = con;
|
||||
src->parser = parser;
|
||||
src->client_tree = avl_tree_new(_compare_clients, NULL);
|
||||
@ -129,6 +129,9 @@ int source_free_source(void *key)
|
||||
}
|
||||
|
||||
|
||||
/* The caller MUST have a current write lock on global.source_tree when calling
|
||||
* this
|
||||
*/
|
||||
void *source_main(void *arg)
|
||||
{
|
||||
source_t *source = (source_t *)arg;
|
||||
@ -154,8 +157,8 @@ void *source_main(void *arg)
|
||||
/* grab a read lock, to make sure we get a chance to cleanup */
|
||||
thread_rwlock_rlock(source->shutdown_rwlock);
|
||||
|
||||
/* get a write lock on the global source tree */
|
||||
avl_tree_wlock(global.source_tree);
|
||||
/* The caller has ensured we have a write lock on the tree... */
|
||||
|
||||
/* insert source onto source tree */
|
||||
avl_insert(global.source_tree, (void *)source);
|
||||
/* release write lock on global source tree */
|
||||
|
Loading…
Reference in New Issue
Block a user