mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Make source client connections reserve the source mountpoint and get rid
of the unused source setup code. svn path=/trunk/icecast/; revision=5846
This commit is contained in:
parent
ae825afd3e
commit
466a5cb60c
127
src/connection.c
127
src/connection.c
@ -520,98 +520,6 @@ int connection_complete_source (source_t *source)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int connection_create_source(client_t *client, connection_t *con, http_parser_t *parser, char *mount) {
|
|
||||||
source_t *source;
|
|
||||||
char *contenttype;
|
|
||||||
mount_proxy *mountproxy, *mountinfo = NULL;
|
|
||||||
int source_limit;
|
|
||||||
ice_config_t *config;
|
|
||||||
|
|
||||||
config = config_get_config();
|
|
||||||
source_limit = config->source_limit;
|
|
||||||
config_release_config();
|
|
||||||
|
|
||||||
/* check to make sure this source wouldn't
|
|
||||||
** be over the limit
|
|
||||||
*/
|
|
||||||
global_lock();
|
|
||||||
if (global.sources >= source_limit) {
|
|
||||||
INFO1("Source (%s) logged in, but there are too many sources", mount);
|
|
||||||
global_unlock();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
global.sources++;
|
|
||||||
global_unlock();
|
|
||||||
|
|
||||||
stats_event_inc(NULL, "sources");
|
|
||||||
|
|
||||||
config = config_get_config();
|
|
||||||
mountproxy = config->mounts;
|
|
||||||
thread_mutex_lock(&(config_locks()->mounts_lock));
|
|
||||||
|
|
||||||
while(mountproxy) {
|
|
||||||
if(!strcmp(mountproxy->mountname, mount)) {
|
|
||||||
mountinfo = mountproxy;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mountproxy = mountproxy->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
contenttype = httpp_getvar(parser, "content-type");
|
|
||||||
|
|
||||||
if (contenttype != NULL) {
|
|
||||||
format_type_t format = format_get_type(contenttype);
|
|
||||||
if (format == FORMAT_ERROR) {
|
|
||||||
WARN1("Content-type \"%s\" not supported, dropping source", contenttype);
|
|
||||||
thread_mutex_unlock(&(config_locks()->mounts_lock));
|
|
||||||
config_release_config();
|
|
||||||
goto fail;
|
|
||||||
} else {
|
|
||||||
source = source_create(client, con, parser, mount,
|
|
||||||
format, mountinfo);
|
|
||||||
thread_mutex_unlock(&(config_locks()->mounts_lock));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
format_type_t format = FORMAT_TYPE_MP3;
|
|
||||||
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, mountinfo);
|
|
||||||
thread_mutex_unlock(&(config_locks()->mounts_lock));
|
|
||||||
}
|
|
||||||
config_release_config();
|
|
||||||
|
|
||||||
/* we need to add this source into the tree but fail if this mountpoint
|
|
||||||
* already exists
|
|
||||||
*/
|
|
||||||
avl_tree_wlock(global.source_tree);
|
|
||||||
if (source_find_mount_raw (mount) != NULL)
|
|
||||||
{
|
|
||||||
avl_tree_unlock(global.source_tree);
|
|
||||||
global_lock();
|
|
||||||
global.sources--;
|
|
||||||
global_unlock();
|
|
||||||
stats_event_dec(NULL, "sources");
|
|
||||||
INFO1("source \"%s\" already in use", mount);
|
|
||||||
client_send_404 (client, "Mountpoint in use");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
avl_insert(global.source_tree, (void *)source);
|
|
||||||
avl_tree_unlock(global.source_tree);
|
|
||||||
|
|
||||||
source->send_return = 1;
|
|
||||||
source->shutdown_rwlock = &_source_shutdown_rwlock;
|
|
||||||
sock_set_blocking(con->sock, SOCK_NONBLOCK);
|
|
||||||
thread_create("Source Thread", source_client_thread, (void *)source, THREAD_DETACHED);
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
global_lock();
|
|
||||||
global.sources--;
|
|
||||||
global_unlock();
|
|
||||||
|
|
||||||
stats_event_dec(NULL, "sources");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _check_pass_http(http_parser_t *parser,
|
static int _check_pass_http(http_parser_t *parser,
|
||||||
char *correctuser, char *correctpass)
|
char *correctuser, char *correctpass)
|
||||||
{
|
{
|
||||||
@ -761,10 +669,12 @@ int connection_check_source_pass(http_parser_t *parser, char *mount)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _handle_source_request(connection_t *con,
|
static void _handle_source_request(connection_t *con,
|
||||||
http_parser_t *parser, char *uri)
|
http_parser_t *parser, char *uri)
|
||||||
{
|
{
|
||||||
client_t *client;
|
client_t *client;
|
||||||
|
source_t *source;
|
||||||
|
|
||||||
client = client_create(con, parser);
|
client = client_create(con, parser);
|
||||||
|
|
||||||
@ -780,23 +690,28 @@ static void _handle_source_request(connection_t *con,
|
|||||||
client_send_401(client);
|
client_send_401(client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
source = source_reserve (uri);
|
||||||
/* check to make sure this source has
|
if (source)
|
||||||
** a unique mountpoint
|
{
|
||||||
*/
|
source->client = client;
|
||||||
|
source->parser = parser;
|
||||||
avl_tree_rlock(global.source_tree);
|
source->con = con;
|
||||||
if (source_find_mount_raw(uri) != NULL) {
|
if (connection_complete_source (source) < 0)
|
||||||
avl_tree_unlock(global.source_tree);
|
{
|
||||||
INFO1("Source tried to log in as %s, but mountpoint is already used", uri);
|
source->client = NULL;
|
||||||
client_send_404(client, "Mountpoint in use");
|
source_free_source (source);
|
||||||
return;
|
}
|
||||||
|
else
|
||||||
|
thread_create ("Source Thread", source_client_thread,
|
||||||
|
source, THREAD_DETACHED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
client_send_404 (client, "Mountpoint in use");
|
||||||
}
|
}
|
||||||
avl_tree_unlock(global.source_tree);
|
|
||||||
|
|
||||||
connection_create_source(client, con, parser, uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _handle_stats_request(connection_t *con,
|
static void _handle_stats_request(connection_t *con,
|
||||||
http_parser_t *parser, char *uri)
|
http_parser_t *parser, char *uri)
|
||||||
{
|
{
|
||||||
|
@ -48,8 +48,6 @@ void connection_shutdown(void);
|
|||||||
void connection_accept_loop(void);
|
void connection_accept_loop(void);
|
||||||
void connection_close(connection_t *con);
|
void connection_close(connection_t *con);
|
||||||
connection_t *create_connection(sock_t sock, sock_t serversock, char *ip);
|
connection_t *create_connection(sock_t sock, sock_t serversock, char *ip);
|
||||||
int connection_create_source(struct _client_tag *client, connection_t *con,
|
|
||||||
http_parser_t *parser, char *mount);
|
|
||||||
int connection_complete_source (struct source_tag *source);
|
int connection_complete_source (struct source_tag *source);
|
||||||
|
|
||||||
void connection_inject_event(int eventnum, void *event_data);
|
void connection_inject_event(int eventnum, void *event_data);
|
||||||
|
62
src/source.c
62
src/source.c
@ -101,58 +101,6 @@ source_t *source_reserve (const char *mount)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
source_t *source_create(client_t *client, connection_t *con,
|
|
||||||
http_parser_t *parser, const char *mount, format_type_t type,
|
|
||||||
mount_proxy *mountinfo)
|
|
||||||
{
|
|
||||||
source_t *src;
|
|
||||||
|
|
||||||
src = (source_t *)malloc(sizeof(source_t));
|
|
||||||
src->client = client;
|
|
||||||
src->mount = (char *)strdup(mount);
|
|
||||||
src->fallback_mount = NULL;
|
|
||||||
src->format = format_get_plugin(type, src->mount, parser);
|
|
||||||
src->con = con;
|
|
||||||
src->parser = parser;
|
|
||||||
src->client_tree = avl_tree_new(_compare_clients, NULL);
|
|
||||||
src->pending_tree = avl_tree_new(_compare_clients, NULL);
|
|
||||||
src->running = 1;
|
|
||||||
src->num_yp_directories = 0;
|
|
||||||
src->listeners = 0;
|
|
||||||
src->max_listeners = -1;
|
|
||||||
src->send_return = 0;
|
|
||||||
src->dumpfilename = NULL;
|
|
||||||
src->dumpfile = NULL;
|
|
||||||
src->audio_info = util_dict_new();
|
|
||||||
src->yp_public = 0;
|
|
||||||
src->fallback_override = 0;
|
|
||||||
src->no_mount = 0;
|
|
||||||
src->authenticator = NULL;
|
|
||||||
|
|
||||||
if(mountinfo != NULL) {
|
|
||||||
if (mountinfo->fallback_mount != NULL)
|
|
||||||
src->fallback_mount = strdup (mountinfo->fallback_mount);
|
|
||||||
src->max_listeners = mountinfo->max_listeners;
|
|
||||||
if (mountinfo->dumpfile != NULL)
|
|
||||||
src->dumpfilename = strdup (mountinfo->dumpfile);
|
|
||||||
if(mountinfo->auth_type != NULL)
|
|
||||||
src->authenticator = auth_get_authenticator(
|
|
||||||
mountinfo->auth_type, mountinfo->auth_options);
|
|
||||||
src->fallback_override = mountinfo->fallback_override;
|
|
||||||
src->no_mount = mountinfo->no_mount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(src->dumpfilename != NULL) {
|
|
||||||
src->dumpfile = fopen(src->dumpfilename, "ab");
|
|
||||||
if(src->dumpfile == NULL) {
|
|
||||||
WARN2("Cannot open dump file \"%s\" for appending: %s, disabling.",
|
|
||||||
src->dumpfilename, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find a mount with this raw name - ignoring fallbacks. You should have the
|
/* Find a mount with this raw name - ignoring fallbacks. You should have the
|
||||||
* global source tree locked to call this.
|
* global source tree locked to call this.
|
||||||
*/
|
*/
|
||||||
@ -562,6 +510,16 @@ void *source_main(void *arg)
|
|||||||
if (listenurl) {
|
if (listenurl) {
|
||||||
free(listenurl);
|
free(listenurl);
|
||||||
}
|
}
|
||||||
|
if (source->dumpfilename != NULL)
|
||||||
|
{
|
||||||
|
source->dumpfile = fopen (source->dumpfilename, "ab");
|
||||||
|
if (source->dumpfile == NULL)
|
||||||
|
{
|
||||||
|
WARN2("Cannot open dump file \"%s\" for appending: %s, disabling.",
|
||||||
|
source->dumpfilename, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DEBUG0("Source creation complete");
|
DEBUG0("Source creation complete");
|
||||||
source->running = 1;
|
source->running = 1;
|
||||||
|
@ -59,9 +59,6 @@ typedef struct source_tag
|
|||||||
int no_mount;
|
int no_mount;
|
||||||
} source_t;
|
} source_t;
|
||||||
|
|
||||||
source_t *source_create(client_t *client, connection_t *con,
|
|
||||||
http_parser_t *parser, const char *mount, format_type_t type,
|
|
||||||
mount_proxy *mountinfo);
|
|
||||||
source_t *source_reserve (const char *mount);
|
source_t *source_reserve (const char *mount);
|
||||||
void *source_client_thread (void *arg);
|
void *source_client_thread (void *arg);
|
||||||
void source_apply_mount (source_t *source, mount_proxy *mountinfo);
|
void source_apply_mount (source_t *source, mount_proxy *mountinfo);
|
||||||
|
Loading…
Reference in New Issue
Block a user