1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-09-29 04:25:55 -04:00

various merges from trunk due to rc1 testing. slave relay user/pass checked

no matter if listener auth set. small memory leaks fixed.

svn path=/icecast/branches/kh/icecast/; revision=9856
This commit is contained in:
Karl Heyes 2005-08-27 00:32:46 +00:00
parent 787f86116e
commit d786d8d2e4
15 changed files with 95 additions and 65 deletions

View File

@ -381,7 +381,7 @@ If you are relaying a Shoutcast stream, you need to specify this indicator to al
<username>othersource</username>
<password>hackmemore</password>
<max-listeners>1</max-listeners>
<listening-duration>3600</listening-duration>
<max-listener-duration>3600</max-listener-duration>
<dump-file>/tmp/dump-example1.ogg</dump-file>
<intro>/intro.ogg</intro>
<fallback-mount>/example2.ogg</fallback-mount>
@ -480,9 +480,9 @@ listening clients back from the fallback mount.
</div>
<h4>fallback-when-full</h4>
<div class="indentedbox">
<p>When set to 1, this will cause new listeners (when the max listener has been reached)
to move to the fallback mount if there is one specified.
</p>
<p>When set to 1, this will cause new listeners, when the max listener count for the
mountpoint has been reached, to move to the fallback mount if there is one specified.
</p>
</div>
<h4>no-yp</h4>
<div class="indentedbox">

View File

@ -311,9 +311,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);
@ -359,11 +362,17 @@ int auth_postprocess_client (auth_client *auth_user)
void add_client (const char *mount, client_t *client)
{
mount_proxy *mountinfo;
ice_config_t *config = config_get_config();
ice_config_t *config;
/* we don't need any more data from the listener, just setup for writing */
client->refbuf->len = PER_CLIENT_REFBUF_SIZE;
if (connection_check_relay_pass(client->parser))
{
client_as_slave (client);
INFO0 ("client connected as slave");
}
config = config_get_config();
mountinfo = config_find_mount (config, mount);
if (mountinfo && mountinfo->no_mount)
{
@ -390,12 +399,6 @@ void add_client (const char *mount, client_t *client)
client_send_401 (client);
return;
}
/* config lock taken in here */
if (connection_check_relay_pass(client->parser))
{
client_as_slave (client);
INFO0 ("client connected as slave");
}
auth_user = calloc (1, sizeof (auth_client));
if (auth_user == NULL)
{

View File

@ -191,6 +191,8 @@ void config_clear(ice_config_t *c)
xmlFree(c->webroot_dir);
if (c->adminroot_dir && c->adminroot_dir != CONFIG_DEFAULT_ADMINROOT_DIR)
xmlFree(c->adminroot_dir);
if (c->cert_file)
xmlFree(c->cert_file);
if (c->pidfile)
xmlFree(c->pidfile);
if (c->playlist_log && c->playlist_log != CONFIG_DEFAULT_PLAYLIST_LOG)

View File

@ -37,18 +37,22 @@
#include "client.h"
#include "logging.h"
#undef CATMODULE
#define CATMODULE "client"
#ifdef HAVE_AIO
#include <errno.h>
#endif
#ifdef WIN32
#ifdef _WIN32
#define snprintf _snprintf
#endif
/* should be called with global lock held */
#undef CATMODULE
#define CATMODULE "client"
/* 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;
@ -56,7 +60,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 ();
@ -71,6 +75,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;

View File

@ -105,9 +105,9 @@ static volatile client_queue_t *_req_queue = NULL, **_req_queue_tail = &_req_que
static volatile client_queue_t *_con_queue = NULL, **_con_queue_tail = &_con_queue;
static mutex_t _con_queue_mutex;
static mutex_t _req_queue_mutex;
static int ssl_ok;
#ifdef HAVE_OPENSSL
static SSL_CTX *ssl_ctx;
static int ssl_ok;
#endif
rwlock_t _source_shutdown_rwlock;
@ -131,6 +131,7 @@ void connection_initialize(void)
static void get_ssl_certificate ()
{
ssl_ok = 0;
#ifdef HAVE_OPENSSL
SSL_METHOD *method;
ice_config_t *config;
@ -141,7 +142,6 @@ static void get_ssl_certificate ()
method = SSLv23_server_method();
ssl_ctx = SSL_CTX_new (method);
ssl_ok = 0;
config = config_get_config ();
do
{
@ -280,11 +280,13 @@ connection_t *connection_create (sock_t sock, sock_t serversock, char *ip)
*/
void connection_uses_ssl (connection_t *con)
{
#ifdef HAVE_OPENSSL
con->read = connection_read_ssl;
con->send = connection_send_ssl;
con->ssl = SSL_new (ssl_ctx);
SSL_set_accept_state (con->ssl);
SSL_set_fd (con->ssl, con->sock);
#endif
}
@ -561,9 +563,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)
@ -611,7 +611,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, connection_t *con, http_parser_t *in_parser)
int connection_complete_source (source_t *source, connection_t *con, http_parser_t *in_parser, int response)
{
ice_config_t *config = config_get_config();
@ -638,8 +638,11 @@ int connection_complete_source (source_t *source, connection_t *con, http_parser
{
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;
}
@ -655,27 +658,15 @@ int connection_complete_source (source_t *source, connection_t *con, http_parser
{
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, con, parser) < 0)
{
config_release_config();
global_unlock();
return -1;
}
}
global.sources++;
stats_event_args (NULL, "sources", "%d", global.sources);
global_unlock();
@ -698,8 +689,11 @@ int connection_complete_source (source_t *source, connection_t *con, http_parser
global_unlock();
config_release_config();
if (source->client)
if (response)
{
client_send_404 (source->client, "too many sources connected");
source->client = NULL;
}
return -1;
}
@ -885,9 +879,8 @@ static void _handle_source_request (client_t *client, char *uri, int auth_style)
source->shoutcast_compat = 1;
}
source->client = client;
if (connection_complete_source (source, NULL, NULL) < 0)
if (connection_complete_source (source, NULL, NULL, 1) < 0)
{
source->client = NULL;
source_free_source (source);
}
else

View File

@ -56,7 +56,7 @@ 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, connection_t *con,
http_parser_t *parser);
http_parser_t *parser, int response);
int connection_check_source_pass(http_parser_t *parser, const char *mount);
int connection_check_relay_pass(http_parser_t *parser);

View File

@ -160,7 +160,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;

View File

@ -409,8 +409,7 @@ static void format_mp3_free_plugin (format_plugin_t *plugin)
free (format_mp3->url_artist);
free (format_mp3->url_title);
refbuf_release (format_mp3->metadata);
if (format_mp3->read_data)
refbuf_release (format_mp3->read_data);
refbuf_release (format_mp3->read_data);
free(format_mp3);
free(plugin);
}

View File

@ -32,6 +32,7 @@
#ifdef _WIN32
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#endif
/* the global log descriptors */

View File

@ -313,6 +313,7 @@ static int _server_proc_init(void)
_fatal_error("Failed trying to listen on server socket");
return 0;
}
config = config_get_config_unlocked();
/* recreate the pid file */
if (config->pidfile)

View File

@ -66,6 +66,8 @@ void refbuf_addref(refbuf_t *self)
void refbuf_release(refbuf_t *self)
{
if (self == NULL)
return;
self->_count--;
if (self->_count == 0) {
while (self->associated)

View File

@ -309,7 +309,18 @@ static void *start_relay_stream (void *arg)
ERROR1("Error from relay request: %s", httpp_getvar(parser, HTTPP_VAR_ERROR_MESSAGE));
break;
}
if (connection_complete_source (src, con, parser) < 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, con, parser, 0) < 0)
{
DEBUG0("Failed to complete source initialisation");
break;
@ -325,6 +336,7 @@ static void *start_relay_stream (void *arg)
yp_remove (relay->localmount);
relay->source->yp_public = -1;
}
/* initiate an immediate relay cleanup run */
relay->cleanup = 1;
rescan_relays = 1;
@ -745,11 +757,12 @@ static void *streamlist_thread (void *arg)
static void update_from_master (ice_config_t *config)
{
#ifdef HAVE_CURL
struct master_conn_details *details = calloc (1, sizeof (*details));
struct master_conn_details *details;
if (config->master_password == NULL || config->master_server == NULL ||
config->master_server_port == 0)
return;
details = calloc (1, sizeof (*details));
details->server = strdup (config->master_server);
details->port = config->master_server_port;
details->ssl_port = config->master_ssl_port;

View File

@ -356,7 +356,7 @@ void source_move_clients (source_t *source, source_t *dest)
{
client_set_queue (client, NULL);
client->check_buffer = format_check_file_buffer;
if (source->client && source->client->con == NULL)
if (source->client == NULL)
client->intro_offset = -1;
}
@ -415,7 +415,7 @@ static void get_next_buffer (source_t *source)
thread_mutex_unlock (&source->lock);
if (source->client->con)
if (source->client)
fds = util_timed_wait_for_fd (source->client->con->sock, delay);
else
{
@ -687,11 +687,14 @@ static void source_init (source_t *source)
source->fast_clients_p = &source->active_clients;
source->audio_info = util_dict_new();
str = httpp_getvar(source->client->parser, "ice-audio-info");
if (str)
if (source->client)
{
_parse_audio_info (source, str);
stats_event (source->mount, "audio_info", str);
str = httpp_getvar(source->client->parser, "ice-audio-info");
if (str)
{
_parse_audio_info (source, str);
stats_event (source->mount, "audio_info", str);
}
}
thread_mutex_unlock (&source->lock);
@ -1119,7 +1122,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)
{
stats_event_hidden (source->mount, NULL, 1);
return;
@ -1203,8 +1206,8 @@ void source_client_callback (client_t *client, void *arg)
global_lock();
global.sources--;
global_unlock();
source_clear_source (source);
source_free_source (source);
client_destroy (client);
return;
}
client->refbuf = old_data->associated;
@ -1237,7 +1240,7 @@ static void source_run_script (char *command, char *mountpoint)
break;
case 0: /* child */
DEBUG1 ("Starting command %s", command);
execl (command, command, mountpoint, NULL);
execl (command, command, mountpoint, (char*)NULL);
ERROR2 ("Unable to run command %s (%s)", command, strerror (errno));
exit(0);
default: /* parent */
@ -1304,9 +1307,10 @@ static void *source_fallback_file (void *arg)
source->intro_file = file;
file = NULL;
if (connection_complete_source (source, NULL, parser) < 0)
if (connection_complete_source (source, NULL, parser, 0) < 0)
break;
source_client_thread (source);
httpp_destroy (parser);
} while (0);
if (file)
fclose (file);

View File

@ -722,12 +722,18 @@ long rate_avg (struct rate_calc *calc)
void rate_free (struct rate_calc *calc)
{
int i = calc->seconds;
struct rate_calc_node *endoflist;
for (; i; i--)
if (calc == NULL)
return;
endoflist = calc->current;
while (calc->current)
{
struct rate_calc_node *to_go = calc->current;
calc->current = to_go->next;
if (to_go->next == endoflist)
calc->current = NULL;
else
calc->current = to_go->next;
free (to_go);
}
free (calc);

View File

@ -602,7 +602,7 @@ static void check_servers ()
source_t *source = node->key;
thread_mutex_lock (&source->lock);
if ((yp = create_yp_entry (source->mount)) != NULL)
if (source->yp_public && (yp = create_yp_entry (source->mount)) != NULL)
{
DEBUG1 ("Adding existing mount %s", source->mount);
yp->server = server;