mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
fixes for client handling, these are all related to the handling of max clients.
I've taken out the client_create out of the connection_complete_source and put it in slave, that way we can control the cleanup of the memory/socket better, the change also meant fallback to file tests were slghtly different. svn path=/icecast/trunk/icecast/; revision=9847
This commit is contained in:
parent
c519afa812
commit
d07723c997
@ -322,9 +322,12 @@ static int add_authenticated_client (const char *mount, mount_proxy *mountinfo,
|
||||
avl_tree_unlock (global.source_tree);
|
||||
return -1;
|
||||
}
|
||||
/* set a per-mount disconnect time if auth hasn't set one already */
|
||||
if (mountinfo->max_listener_duration && client->con->discon_time == 0)
|
||||
client->con->discon_time = time(NULL) + mountinfo->max_listener_duration;
|
||||
if (mountinfo)
|
||||
{
|
||||
/* set a per-mount disconnect time if auth hasn't set one already */
|
||||
if (mountinfo->max_listener_duration && client->con->discon_time == 0)
|
||||
client->con->discon_time = time(NULL) + mountinfo->max_listener_duration;
|
||||
}
|
||||
|
||||
ret = add_client_to_source (source, client);
|
||||
avl_tree_unlock (global.source_tree);
|
||||
|
10
src/client.c
10
src/client.c
@ -44,7 +44,11 @@
|
||||
#undef CATMODULE
|
||||
#define CATMODULE "client"
|
||||
|
||||
/* should be called with global lock held */
|
||||
/* create a client_t with the provided connection and parser details. Return
|
||||
* 0 on success, -1 if server limit has been reached. In either case a
|
||||
* client_t is returned just in case a message needs to be returned. Should
|
||||
* be called with global lock held.
|
||||
*/
|
||||
int client_create (client_t **c_ptr, connection_t *con, http_parser_t *parser)
|
||||
{
|
||||
ice_config_t *config;
|
||||
@ -52,7 +56,7 @@ int client_create (client_t **c_ptr, connection_t *con, http_parser_t *parser)
|
||||
int ret = -1;
|
||||
|
||||
if (client == NULL)
|
||||
return -1;
|
||||
abort();
|
||||
|
||||
config = config_get_config ();
|
||||
|
||||
@ -67,6 +71,8 @@ int client_create (client_t **c_ptr, connection_t *con, http_parser_t *parser)
|
||||
stats_event_args (NULL, "clients", "%d", global.clients);
|
||||
client->con = con;
|
||||
client->parser = parser;
|
||||
client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
|
||||
client->refbuf->len = 0; /* force reader code to ignore buffer contents */
|
||||
client->pos = 0;
|
||||
client->write_to_client = format_generic_write_to_client;
|
||||
*c_ptr = client;
|
||||
|
@ -434,9 +434,7 @@ void connection_accept_loop(void)
|
||||
global_unlock();
|
||||
|
||||
/* setup client for reading incoming http */
|
||||
client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
|
||||
client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000';
|
||||
client->refbuf->len = 0; /* force reader code to ignore buffer */
|
||||
|
||||
node = calloc (1, sizeof (client_queue_t));
|
||||
if (node == NULL)
|
||||
@ -482,7 +480,7 @@ void connection_accept_loop(void)
|
||||
/* Called when activating a source. Verifies that the source count is not
|
||||
* exceeded and applies any initial parameters.
|
||||
*/
|
||||
int connection_complete_source (source_t *source)
|
||||
int connection_complete_source (source_t *source, int response)
|
||||
{
|
||||
ice_config_t *config = config_get_config();
|
||||
|
||||
@ -505,8 +503,11 @@ int connection_complete_source (source_t *source)
|
||||
{
|
||||
global_unlock();
|
||||
config_release_config();
|
||||
if (source->client)
|
||||
if (response)
|
||||
{
|
||||
client_send_404 (source->client, "Content-type not supported");
|
||||
source->client = NULL;
|
||||
}
|
||||
WARN1("Content-type \"%s\" not supported, dropping source", contenttype);
|
||||
return -1;
|
||||
}
|
||||
@ -522,31 +523,15 @@ int connection_complete_source (source_t *source)
|
||||
{
|
||||
global_unlock();
|
||||
config_release_config();
|
||||
if (source->client)
|
||||
if (response)
|
||||
{
|
||||
client_send_404 (source->client, "internal format allocation problem");
|
||||
source->client = NULL;
|
||||
}
|
||||
WARN1 ("plugin format failed for \"%s\"", source->mount);
|
||||
source->client = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* for relays, we don't yet have a client, however we do require one
|
||||
* to retrieve the stream from. This is created here, quite late,
|
||||
* because we can't use this client to return an error code/message,
|
||||
* so we only do this once we know we're going to accept the source.
|
||||
*/
|
||||
if (source->client == NULL)
|
||||
{
|
||||
if (client_create (&source->client, source->con, source->parser) < 0)
|
||||
{
|
||||
config_release_config();
|
||||
global_unlock();
|
||||
connection_close (source->con);
|
||||
source->con = NULL;
|
||||
httpp_destroy (source->parser);
|
||||
source->parser = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
global.sources++;
|
||||
stats_event_args (NULL, "sources", "%d", global.sources);
|
||||
global_unlock();
|
||||
@ -569,8 +554,11 @@ int connection_complete_source (source_t *source)
|
||||
global_unlock();
|
||||
config_release_config();
|
||||
|
||||
if (source->client)
|
||||
if (response)
|
||||
{
|
||||
client_send_404 (source->client, "too many sources connected");
|
||||
source->client = NULL;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -758,9 +746,8 @@ static void _handle_source_request (client_t *client, char *uri, int auth_style)
|
||||
source->client = client;
|
||||
source->parser = client->parser;
|
||||
source->con = client->con;
|
||||
if (connection_complete_source (source) < 0)
|
||||
if (connection_complete_source (source, 1) < 0)
|
||||
{
|
||||
source->client = NULL;
|
||||
source_free_source (source);
|
||||
}
|
||||
else
|
||||
|
@ -45,7 +45,7 @@ void connection_shutdown(void);
|
||||
void connection_accept_loop(void);
|
||||
void connection_close(connection_t *con);
|
||||
connection_t *connection_create (sock_t sock, sock_t serversock, char *ip);
|
||||
int connection_complete_source (struct source_tag *source);
|
||||
int connection_complete_source (struct source_tag *source, int response);
|
||||
|
||||
int connection_check_source_pass(http_parser_t *parser, const char *mount);
|
||||
int connection_check_relay_pass(http_parser_t *parser);
|
||||
|
@ -150,7 +150,7 @@ int format_check_file_buffer (source_t *source, client_t *client)
|
||||
if (refbuf == NULL)
|
||||
{
|
||||
/* client refers to no data, must be from a move */
|
||||
if (source->client->con)
|
||||
if (source->client)
|
||||
{
|
||||
find_client_start (source, client);
|
||||
return -1;
|
||||
|
13
src/slave.c
13
src/slave.c
@ -237,7 +237,18 @@ static void *start_relay_stream (void *arg)
|
||||
}
|
||||
src->parser = parser;
|
||||
src->con = con;
|
||||
if (connection_complete_source (src) < 0)
|
||||
|
||||
if (client_create (&src->client, con, parser) < 0)
|
||||
{
|
||||
/* make sure only the client_destory frees these */
|
||||
con = NULL;
|
||||
parser = NULL;
|
||||
streamsock = SOCK_ERROR;
|
||||
break;
|
||||
}
|
||||
client_set_queue (src->client, NULL);
|
||||
|
||||
if (connection_complete_source (src, 0) < 0)
|
||||
{
|
||||
DEBUG0("Failed to complete source initialisation");
|
||||
break;
|
||||
|
@ -442,7 +442,7 @@ static refbuf_t *get_next_buffer (source_t *source)
|
||||
int fds = 0;
|
||||
time_t current = time (NULL);
|
||||
|
||||
if (source->client->con)
|
||||
if (source->client)
|
||||
fds = util_timed_wait_for_fd (source->con->sock, delay);
|
||||
else
|
||||
{
|
||||
@ -1132,7 +1132,7 @@ static void source_apply_mount (source_t *source, mount_proxy *mountinfo)
|
||||
void source_update_settings (ice_config_t *config, source_t *source, mount_proxy *mountinfo)
|
||||
{
|
||||
/* skip if source is a fallback to file */
|
||||
if (source->running && source->client->con == NULL)
|
||||
if (source->running && source->client == NULL)
|
||||
return;
|
||||
/* set global settings first */
|
||||
source->queue_size_limit = config->queue_size_limit;
|
||||
@ -1312,7 +1312,7 @@ static void *source_fallback_file (void *arg)
|
||||
source->parser = parser;
|
||||
file = NULL;
|
||||
|
||||
if (connection_complete_source (source) < 0)
|
||||
if (connection_complete_source (source, 0) < 0)
|
||||
break;
|
||||
source_client_thread (source);
|
||||
} while (0);
|
||||
|
Loading…
Reference in New Issue
Block a user