[xiph-commits] r16154 - in icecast/branches/kh/icecast: . src
karl at svn.xiph.org
karl at svn.xiph.org
Sun Jun 21 18:06:57 PDT 2009
Author: karl
Date: 2009-06-21 18:06:57 -0700 (Sun, 21 Jun 2009)
New Revision: 16154
Modified:
icecast/branches/kh/icecast/configure.in
icecast/branches/kh/icecast/src/admin.c
icecast/branches/kh/icecast/src/auth.c
icecast/branches/kh/icecast/src/auth.h
icecast/branches/kh/icecast/src/auth_cmd.c
icecast/branches/kh/icecast/src/auth_htpasswd.c
icecast/branches/kh/icecast/src/auth_url.c
icecast/branches/kh/icecast/src/cfgfile.c
icecast/branches/kh/icecast/src/cfgfile.h
icecast/branches/kh/icecast/src/client.c
icecast/branches/kh/icecast/src/client.h
icecast/branches/kh/icecast/src/connection.c
icecast/branches/kh/icecast/src/connection.h
icecast/branches/kh/icecast/src/format.c
icecast/branches/kh/icecast/src/format.h
icecast/branches/kh/icecast/src/format_kate.c
icecast/branches/kh/icecast/src/format_mp3.c
icecast/branches/kh/icecast/src/global.c
icecast/branches/kh/icecast/src/global.h
icecast/branches/kh/icecast/src/refbuf.h
icecast/branches/kh/icecast/src/slave.c
icecast/branches/kh/icecast/src/slave.h
icecast/branches/kh/icecast/src/source.c
icecast/branches/kh/icecast/src/source.h
icecast/branches/kh/icecast/src/stats.c
icecast/branches/kh/icecast/src/yp.c
Log:
Various small updates collected. Most are down to code cleanups or shuffling functions
around. Mainly to check in things not related to the thread update for kh10.
Modified: icecast/branches/kh/icecast/configure.in
===================================================================
--- icecast/branches/kh/icecast/configure.in 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/configure.in 2009-06-22 01:06:57 UTC (rev 16154)
@@ -1,4 +1,4 @@
-AC_INIT([Icecast], [2.3.2-kh9], [karl at xiph.org])
+AC_INIT([Icecast], [2.3.2-kh9b], [karl at xiph.org])
AC_PREREQ(2.59)
AC_CONFIG_SRCDIR(src/main.c)
Modified: icecast/branches/kh/icecast/src/admin.c
===================================================================
--- icecast/branches/kh/icecast/src/admin.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/admin.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -34,6 +34,7 @@
#include "xslt.h"
#include "fserve.h"
#include "admin.h"
+#include "slave.h"
#include "format.h"
@@ -157,7 +158,7 @@
}
thread_mutex_lock (&source->lock);
- if (source->running || source->on_demand)
+ if (source_available (source))
{
ice_config_t *config;
mount_proxy *mountinfo;
@@ -446,8 +447,8 @@
source_t *dest;
xmlDocPtr doc;
xmlNodePtr node;
+ int parameters_passed = 0;
char buf[255];
- int parameters_passed = 0;
if((COMMAND_OPTIONAL(client, "destination", dest_source))) {
parameters_passed = 1;
Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/auth.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -38,6 +38,13 @@
#include "logging.h"
#define CATMODULE "auth"
+struct _auth_thread_t
+{
+ thread_type *thread;
+ void *data;
+ unsigned int id;
+ struct auth_tag *auth;
+};
static volatile int thread_id;
@@ -161,8 +168,8 @@
}
free (authenticator->handles);
- if (authenticator->free)
- authenticator->free (authenticator);
+ if (authenticator->release)
+ authenticator->release (authenticator);
xmlFree (authenticator->type);
xmlFree (authenticator->realm);
thread_mutex_unlock (&authenticator->lock);
@@ -233,7 +240,7 @@
}
}
if (auth_postprocess_listener (auth_user) < 0)
- INFO1 ("client %lu failed", client->con->id);
+ INFO0 ("listener connection failed");
}
@@ -346,189 +353,6 @@
}
-/* Check whether this listener is on this source. This is only called when
- * there is auth. This may flag an existing listener to terminate.
- * return 1 if ok to add or 0 to prevent
- */
-static int check_duplicate_logins (source_t *source, client_t *client, auth_t *auth)
-{
- client_t *existing;
-
- if (auth == NULL || auth->allow_duplicate_users)
- return 1;
-
- /* allow multiple authenticated relays */
- if (client->username == NULL || client->is_slave)
- return 1;
-
- existing = source->active_clients;
- while (existing)
- {
- if (existing->con->error == 0 && existing->username &&
- strcmp (existing->username, client->username) == 0)
- {
- if (auth->drop_existing_listener)
- {
- existing->con->error = 1;
- return 1;
- }
- else
- return 0;
- }
- existing = existing->next;
- }
- return 1;
-}
-
-
-/* Add client to source if it finds one. If a 0 is returned then the client should not be
- * touched, if the return value is -1 then it failed to add and should not be touched.
- * If it's a -2 value then the client is still around for any further processing.
- */
-static int add_listener_to_source (const char *mount, mount_proxy *mountinfo, client_t *client)
-{
- int loop = 10;
- int within_limits;
- source_t *source;
- mount_proxy *minfo = mountinfo;
- const char *passed_mount = mount;
- ice_config_t *config = config_get_config_unlocked();
-
- do
- {
- int64_t stream_bitrate = 0;
-
- do
- {
- source = source_find_mount_raw (mount);
- if (loop == 0)
- {
- WARN0 ("preventing a fallback loop");
- client_send_403 (client, "Fallback through too many mountpoints");
- return -1;
- }
- if (source)
- {
- thread_mutex_lock (&source->lock);
- if (source->running || source->on_demand)
- break;
- thread_mutex_unlock (&source->lock);
- }
- if (minfo == NULL || minfo->fallback_mount == NULL)
- return -2;
- mount = minfo->fallback_mount;
- minfo = config_find_mount (config_get_config_unlocked(), mount);
- loop--;
- } while (1);
-
- /* ok, we found a source and it is locked */
- if (client->is_slave)
- {
- if (source->client == NULL && source->on_demand == 0)
- {
- client_send_403 (client, "Slave relay reading from time unregulated stream");
- return -1;
- }
- INFO0 ("client is from a slave, bypassing limits");
- break;
- }
- if (source->format)
- {
- stream_bitrate = 8 * rate_avg (source->format->in_bitrate);
-
- if (config->max_bandwidth)
- {
- int64_t global_rate = (int64_t)8 * global_getrate_avg (global.out_bitrate);
-
- DEBUG1 ("server outgoing bitrate is %" PRId64, global_rate);
- if (global_rate + stream_bitrate > config->max_bandwidth)
- {
- thread_mutex_unlock (&source->lock);
- INFO0 ("server-wide outgoing bandwidth limit reached");
- client_send_403redirect (client, passed_mount, "server bandwidth reached");
- return -1;
- }
- }
- }
-
- if (mountinfo == NULL)
- break; /* allow adding listeners, no mount limits imposed */
-
- if (check_duplicate_logins (source, client, mountinfo->auth) == 0)
- {
- thread_mutex_unlock (&source->lock);
- client_send_403 (client, "Account already in use");
- 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;
-
- INFO3 ("max on %s is %ld (cur %lu)", source->mount,
- mountinfo->max_listeners, source->listeners);
-
- within_limits = 1;
- if (mountinfo->max_bandwidth > -1 && stream_bitrate)
- {
- DEBUG3 ("checking bandwidth limits for %s (%" PRId64 ", %" PRId64 ")",
- mountinfo->mountname, stream_bitrate, mountinfo->max_bandwidth);
- if ((source->listeners+1) * stream_bitrate > mountinfo->max_bandwidth)
- {
- INFO1 ("bandwidth limit reached on %s", source->mount);
- within_limits = 0;
- }
- }
- if (within_limits)
- {
- if (mountinfo->max_listeners == -1)
- break;
-
- if (source->listeners < (unsigned long)mountinfo->max_listeners)
- break;
- INFO1 ("max listener count reached on %s", source->mount);
- }
-
- /* minfo starts off as mountinfo put cascades through fallbacks */
- if (minfo && minfo->fallback_when_full && minfo->fallback_mount)
- {
- thread_mutex_unlock (&source->lock);
- mount = minfo->fallback_mount;
- INFO1 ("stream full trying %s", mount);
- loop--;
- continue;
- }
-
- /* now we fail the client */
- thread_mutex_unlock (&source->lock);
- client_send_403redirect (client, passed_mount, "max listeners reached");
- return -1;
-
- } while (1);
-
- client->write_to_client = format_generic_write_to_client;
- client->check_buffer = format_check_http_buffer;
- client->refbuf->len = PER_CLIENT_REFBUF_SIZE;
- memset (client->refbuf->data, 0, PER_CLIENT_REFBUF_SIZE);
-
- /* lets add the client to the active list */
- client->next = source->active_clients;
- source->active_clients = client;
- source->listeners++;
-
- thread_mutex_unlock (&source->lock);
-
- if (source->running == 0 && source->on_demand)
- {
- /* enable on-demand relay to start, wake up the slave thread */
- DEBUG0("kicking off on-demand relay");
- source->on_demand_req = 1;
- }
- DEBUG1 ("Added client to %s", source->mount);
- return 0;
-}
-
-
/* Add listener to the pending lists of either the source or fserve thread. This can be run
* from the connection or auth thread context. return -1 to indicate that client has been
* terminated, 0 for receiving content.
@@ -568,7 +392,7 @@
}
avl_tree_rlock (global.source_tree);
- ret = add_listener_to_source (mount, mountinfo, client);
+ ret = source_add_listener (mount, mountinfo, client);
avl_tree_unlock (global.source_tree);
if (ret == -2)
@@ -611,7 +435,6 @@
mountinfo = config_find_mount (config, mount);
ret = add_authenticated_listener (mount, mountinfo, client);
config_release_config();
-
auth_user->client = NULL;
return ret;
Modified: icecast/branches/kh/icecast/src/auth.h
===================================================================
--- icecast/branches/kh/icecast/src/auth.h 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/auth.h 2009-06-22 01:06:57 UTC (rev 16154)
@@ -19,11 +19,11 @@
struct source_tag;
struct auth_tag;
+typedef struct _auth_thread_t auth_thread_t;
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
-#include "cfgfile.h"
#include "client.h"
#include "thread/thread.h"
@@ -52,14 +52,6 @@
} auth_client;
-typedef struct _auth_thread_t
-{
- thread_type *thread;
- void *data;
- unsigned int id;
- struct auth_tag *auth;
-} auth_thread_t;
-
typedef struct auth_tag
{
char *mount;
@@ -78,7 +70,7 @@
void (*stream_end)(auth_client *auth_user);
/* auth state-specific free call */
- void (*free)(struct auth_tag *self);
+ void (*release)(struct auth_tag *self);
/* call to allocate any per auth thread data */
void *(*alloc_thread_data)(struct auth_tag *self);
Modified: icecast/branches/kh/icecast/src/auth_cmd.c
===================================================================
--- icecast/branches/kh/icecast/src/auth_cmd.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/auth_cmd.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -123,7 +123,7 @@
auth_cmd *state;
authenticator->authenticate = auth_cmd_client;
- authenticator->free = cmd_clear;
+ authenticator->release = cmd_clear;
authenticator->adduser = auth_cmd_adduser;
authenticator->deleteuser = auth_cmd_deleteuser;
authenticator->listuser = auth_cmd_listuser;
Modified: icecast/branches/kh/icecast/src/auth_htpasswd.c
===================================================================
--- icecast/branches/kh/icecast/src/auth_htpasswd.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/auth_htpasswd.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -181,8 +181,25 @@
htpasswd_user entry;
void *result;
- if (client->username == NULL || client->password == NULL)
+ do {
+ const char *val;
+
+ if (client->username && client->password)
+ break;
+ free (client->username);
+ val = httpp_get_query_param (client->parser, "user");
+ if (val)
+ {
+ client->username = strdup (val);
+ val = httpp_get_query_param (client->parser, "pass");
+ if (val)
+ {
+ client->password = strdup (val);
+ break;
+ }
+ }
return AUTH_FAILED;
+ } while (0);
htpasswd_recheckfile (htpasswd);
@@ -216,7 +233,7 @@
htpasswd_auth_state *state;
authenticator->authenticate = htpasswd_auth;
- authenticator->free = htpasswd_clear;
+ authenticator->release = htpasswd_clear;
authenticator->adduser = htpasswd_adduser;
authenticator->deleteuser = htpasswd_deleteuser;
authenticator->listuser = htpasswd_userlist;
Modified: icecast/branches/kh/icecast/src/auth_url.c
===================================================================
--- icecast/branches/kh/icecast/src/auth_url.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/auth_url.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -381,7 +381,7 @@
if (res)
{
WARN2 ("auth to server %s failed with %s", url->addurl, atd->errormsg);
- client_send_403 (client, "Unable to contact auth server");
+ client_send_403 (client, "Authentication not possible");
auth_user->client = NULL;
return AUTH_FAILED;
}
@@ -586,7 +586,7 @@
{
auth_url *url_info;
- authenticator->free = auth_url_clear;
+ authenticator->release = auth_url_clear;
authenticator->adduser = auth_url_adduser;
authenticator->deleteuser = auth_url_deleteuser;
authenticator->listuser = auth_url_listuser;
Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/cfgfile.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -975,6 +975,7 @@
{ "shoutcast-compat", config_get_bool, &listener->shoutcast_compat },
{ "bind-address", config_get_str, &listener->bind_address },
{ "queue-len", config_get_int, &listener->qlen },
+ { "so-sndbuf", config_get_int, &listener->so_sndbuf },
{ "ssl", config_get_bool, &listener->ssl },
{ "shoutcast-mount", config_get_str, &listener->shoutcast_mount },
{ NULL, NULL, NULL },
Modified: icecast/branches/kh/icecast/src/cfgfile.h
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.h 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/cfgfile.h 2009-06-22 01:06:57 UTC (rev 16154)
@@ -26,11 +26,9 @@
struct ice_config_tag;
typedef struct _listener_t listener_t;
-#include "thread/thread.h"
#include "avl/avl.h"
#include "auth.h"
#include "global.h"
-#include "connection.h"
typedef struct ice_config_dir_tag
{
@@ -131,8 +129,37 @@
int qlen;
int shoutcast_compat;
int ssl;
+ int so_sndbuf;
};
+typedef struct _relay_server_master
+{
+ struct _relay_server_master *next;
+ char *ip;
+ char *bind;
+ char *mount;
+ int port;
+} relay_server_master;
+
+typedef struct _relay_server
+{
+ relay_server_master *masters;
+ char *username;
+ char *password;
+ char *localmount;
+ struct source_tag *source;
+ int interval;
+ int mp3metadata;
+ int on_demand;
+ int running;
+ int cleanup;
+ int enable;
+ time_t start;
+ thread_type *thread;
+ struct _relay_server *next;
+} relay_server;
+
+
typedef struct
{
char *hostname;
@@ -264,7 +291,6 @@
listener_t *config_clear_listener (listener_t *listener);
void config_clear(ice_config_t *config);
mount_proxy *config_find_mount (ice_config_t *config, const char *mount);
-listener_t *config_get_listen_sock (ice_config_t *config, sock_t serversock);
int config_rehash(void);
Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/client.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -36,11 +36,8 @@
#include "client.h"
#include "logging.h"
+#include "slave.h"
-#ifdef HAVE_AIO
-#include <errno.h>
-#endif
-
#undef CATMODULE
#define CATMODULE "client"
@@ -210,10 +207,10 @@
{
if (redirect_client (mount, client))
return;
- DEBUG0 ("dropping client");
client_send_403 (client, reason);
}
+
void client_send_404(client_t *client, const char *message)
{
if (client->respcode)
Modified: icecast/branches/kh/icecast/src/client.h
===================================================================
--- icecast/branches/kh/icecast/src/client.h 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/client.h 2009-06-22 01:06:57 UTC (rev 16154)
@@ -18,13 +18,10 @@
#ifndef __CLIENT_H__
#define __CLIENT_H__
-#ifdef HAVE_AIO
-#include <aio.h>
-#endif
-
struct source_tag;
typedef struct _client_tag client_t;
+#include "cfgfile.h"
#include "connection.h"
#include "refbuf.h"
#include "httpp/httpp.h"
Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/connection.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -51,6 +51,7 @@
#include "xslt.h"
#include "fserve.h"
#include "sighandler.h"
+#include "slave.h"
#include "yp.h"
#include "source.h"
@@ -85,10 +86,6 @@
struct client_queue_tag *next;
} client_queue_t;
-typedef struct _thread_queue_tag {
- thread_type *thread_id;
- struct _thread_queue_tag *next;
-} thread_queue_t;
typedef struct
{
@@ -1031,7 +1028,6 @@
static void _handle_source_request (client_t *client, const char *uri)
{
INFO1("Source logging in at mountpoint \"%s\"", uri);
-
if (uri[0] != '/')
{
WARN0 ("source mountpoint not starting with /");
@@ -1369,6 +1365,9 @@
sock_close (sock);
break;
}
+ /* some win32 setups do not do TCP win scaling well, so allow an override */
+ if (listener->so_sndbuf)
+ sock_set_send_buffer (sock, listener->so_sndbuf);
sock_set_blocking (sock, 0);
successful = 1;
global.serversock [count] = sock;
@@ -1416,3 +1415,4 @@
#endif
free(con);
}
+
Modified: icecast/branches/kh/icecast/src/connection.h
===================================================================
--- icecast/branches/kh/icecast/src/connection.h 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/connection.h 2009-06-22 01:06:57 UTC (rev 16154)
@@ -26,7 +26,6 @@
#include "cfgfile.h"
#include "compat.h"
#include "httpp/httpp.h"
-#include "thread/thread.h"
#include "net/sock.h"
struct connection_tag
Modified: icecast/branches/kh/icecast/src/format.c
===================================================================
--- icecast/branches/kh/icecast/src/format.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/format.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -44,9 +44,7 @@
#include "stats.h"
#define CATMODULE "format"
-static int format_prepare_headers (source_t *source, client_t *client);
-
format_type_t format_get_type(const char *contenttype)
{
if(strcmp(contenttype, "application/x-ogg") == 0)
@@ -94,146 +92,25 @@
}
-/* clients need to be start from somewhere in the queue so we will look for
- * a refbuf which has been previously marked as a sync point.
- */
-static void find_client_start (source_t *source, client_t *client)
+int format_file_read (client_t *client, FILE *intro)
{
- refbuf_t *refbuf = source->burst_point;
-
- /* we only want to attempt a burst at connection time, not midstream
- * however streams like theora may not have the most recent page marked as
- * a starting point, so look for one from the burst point */
- if (client->intro_offset == -1 && source->stream_data_tail
- && source->stream_data_tail->sync_point)
- {
- refbuf = source->stream_data_tail;
- client->lag = refbuf->len;
- }
- else
- {
- size_t size = client->intro_offset;
- refbuf = source->burst_point;
- client->lag = source->burst_offset;
- while (size > 0 && refbuf && refbuf->next)
- {
- size -= refbuf->len;
- client->lag -= refbuf->len;
- refbuf = refbuf->next;
- }
- }
-
- while (refbuf)
- {
- if (refbuf->sync_point)
- {
- client_set_queue (client, refbuf);
- client->check_buffer = format_advance_queue;
- client->write_to_client = source->format->write_buf_to_client;
- client->intro_offset = -1;
- break;
- }
- refbuf = refbuf->next;
- }
-}
-
-
-static int get_file_data (FILE *intro, client_t *client)
-{
refbuf_t *refbuf = client->refbuf;
- size_t bytes;
- if (intro == NULL || fseek (intro, client->intro_offset, SEEK_SET) < 0)
- return 0;
- bytes = fread (refbuf->data, 1, 4096, intro);
- if (bytes == 0)
- return 0;
-
- refbuf->len = bytes;
- return 1;
-}
-
-
-/* call to check the buffer contents for file reading. move the client
- * to right place in the queue at end of file else repeat file if queue
- * is not ready yet.
- */
-int format_check_file_buffer (source_t *source, client_t *client)
-{
- refbuf_t *refbuf = client->refbuf;
-
- if (refbuf == NULL)
- {
- /* client refers to no data, must be from a move */
- if (source->client)
- {
- find_client_start (source, client);
- return -1;
- }
- /* source -> file fallback, need a refbuf for data */
- refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
- client->refbuf = refbuf;
- client->pos = refbuf->len;
- client->intro_offset = 0;
- client->lag = 0;
- }
+ if (intro == NULL)
+ return -1;
if (client->pos == refbuf->len)
{
- if (get_file_data (source->intro_file, client))
- {
- client->pos = 0;
- client->intro_offset += refbuf->len;
- }
- else
- {
- if (source->stream_data_tail)
- {
- /* better find the right place in queue for this client */
- client_set_queue (client, NULL);
- find_client_start (source, client);
- }
- else
- client->intro_offset = 0; /* replay intro file */
- return -1;
- }
- }
- return 0;
-}
+ size_t bytes;
-
-/* call this to verify that the HTTP data has been sent and if so setup
- * callbacks to the appropriate format functions
- */
-int format_check_http_buffer (source_t *source, client_t *client)
-{
- refbuf_t *refbuf = client->refbuf;
-
- if (refbuf == NULL)
- return -1;
-
- if (client->respcode == 0)
- {
- DEBUG0("processing pending client headers");
-
- if (format_prepare_headers (source, client) < 0)
- {
- ERROR0 ("internal problem, dropping client");
- client->con->error = 1;
+ if (fseek (intro, client->intro_offset, SEEK_SET) < 0)
return -1;
- }
- client->respcode = 200;
- stats_event_inc (NULL, "listeners");
- stats_event_inc (NULL, "listener_connections");
- stats_event_inc (source->mount, "listener_connections");
- }
+ bytes = fread (refbuf->data, 1, PER_CLIENT_REFBUF_SIZE, intro);
+ if (bytes == 0)
+ return -1;
- if (client->pos == refbuf->len)
- {
- client->write_to_client = source->format->write_buf_to_client;
- client->check_buffer = format_check_file_buffer;
- client->intro_offset = 0;
- client->pos = refbuf->len = 4096;
- return -1;
+ client->intro_offset += bytes;
+ refbuf->len = bytes;
+ client->pos = 0;
}
return 0;
}
@@ -246,6 +123,8 @@
const char *buf = refbuf->data + client->pos;
unsigned int len = refbuf->len - client->pos;
+ if (len > 4096) /* make sure we don't send huge amounts in one go */
+ len = 4096;
ret = client_send_bytes (client, buf, len);
if (ret > 0)
@@ -279,7 +158,7 @@
}
-static int format_prepare_headers (source_t *source, client_t *client)
+int format_prepare_headers (source_t *source, client_t *client)
{
unsigned remaining;
char *ptr;
@@ -288,6 +167,7 @@
avl_node *node;
ice_config_t *config;
+ DEBUG0 ("processing listener headers");
remaining = client->refbuf->len;
ptr = client->refbuf->data;
client->respcode = 200;
@@ -374,7 +254,7 @@
client->refbuf->len -= remaining;
if (source->format->create_client_data)
if (source->format->create_client_data (source, client) < 0)
- return -1;
- return 0;
+ bytes = -1;
+ return bytes;
}
Modified: icecast/branches/kh/icecast/src/format.h
===================================================================
--- icecast/branches/kh/icecast/src/format.h 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/format.h 2009-06-22 01:06:57 UTC (rev 16154)
@@ -20,7 +20,6 @@
#include "client.h"
#include "refbuf.h"
-#include "httpp/httpp.h"
struct source_tag;
struct _mount_proxy;
@@ -64,9 +63,10 @@
int format_generic_write_to_client (client_t *client);
int format_advance_queue (struct source_tag *source, client_t *client);
-int format_check_http_buffer (struct source_tag *source, client_t *client);
-int format_check_file_buffer (struct source_tag *source, client_t *client);
+int format_file_read (client_t *client, FILE *fp);
+int format_prepare_headers (struct source_tag *source, client_t *client);
+
void format_send_general_headers(format_plugin_t *format,
struct source_tag *source, client_t *client);
Modified: icecast/branches/kh/icecast/src/format_kate.c
===================================================================
--- icecast/branches/kh/icecast/src/format_kate.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/format_kate.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -152,25 +152,6 @@
refbuf = make_refbuf_with_page (codec, page);
/* DEBUG3 ("refbuf %p has pageno %ld, %llu", refbuf, ogg_page_pageno (page), (uint64_t)granulepos); */
- if (codec->possible_start)
- {
- /* we don't bother trying to know where we can start, we'll just
- start whenever we have to, video's more important and in the majority
- of the cases it's ok if we lose an event we're seeking in the middle
- of, as we won't have display artifacts as we'd have with video */
- codec->possible_start->sync_point = 1;
- refbuf_release (codec->possible_start);
- codec->possible_start = NULL;
- }
- if (granulepos != kate->prev_granulepos || granulepos == 0)
- {
- if (codec->possible_start)
- refbuf_release (codec->possible_start);
- refbuf_addref (refbuf);
- codec->possible_start = refbuf;
- }
- kate->prev_granulepos = granulepos;
-
return refbuf;
}
Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/format_mp3.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -206,14 +206,14 @@
if (mount)
{
- if (mount->mp3_meta_interval > 0)
+ if (mount->mp3_meta_interval >= 0)
source_mp3->interval = mount->mp3_meta_interval;
if (mount->charset)
format->charset = strdup (mount->charset);
if (mount->queue_block_size)
source_mp3->queue_block_size = mount->queue_block_size;
}
- if (source_mp3->interval <= 0)
+ if (source_mp3->interval < 0)
{
const char *metadata = httpp_getvar (client->parser, "icy-metaint");
source_mp3->interval = ICY_METADATA_INTERVAL;
@@ -467,7 +467,7 @@
if (ret > 0)
written += ret;
- return written;
+ return written == 0 ? -1 : written;
}
static void format_mp3_free_plugin (format_plugin_t *plugin)
@@ -505,7 +505,6 @@
source_mp3->read_count = 0;
}
buf = source_mp3->read_data->data + source_mp3->read_count;
-
if (source_mp3->read_count < source_mp3->queue_block_size)
{
bytes = client_read_bytes (source->client, buf, source_mp3->queue_block_size-source_mp3->read_count);
Modified: icecast/branches/kh/icecast/src/global.c
===================================================================
--- icecast/branches/kh/icecast/src/global.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/global.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -19,7 +19,7 @@
#include "thread/thread.h"
#include "avl/avl.h"
-#include "httpp/httpp.h"
+#include "timing/timing.h"
#include "connection.h"
#include "refbuf.h"
Modified: icecast/branches/kh/icecast/src/global.h
===================================================================
--- icecast/branches/kh/icecast/src/global.h 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/global.h 2009-06-22 01:06:57 UTC (rev 16154)
@@ -23,8 +23,6 @@
#define ICECAST_VERSION_STRING "Icecast " PACKAGE_VERSION
#include "thread/thread.h"
-#include "slave.h"
-#include "timing/timing.h"
#include "net/sock.h"
typedef struct ice_global_tag
Modified: icecast/branches/kh/icecast/src/refbuf.h
===================================================================
--- icecast/branches/kh/icecast/src/refbuf.h 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/refbuf.h 2009-06-22 01:06:57 UTC (rev 16154)
@@ -19,7 +19,6 @@
#define __REFBUF_H__
#include <sys/types.h>
-#include "compat.h"
typedef struct _refbuf_tag
{
Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/slave.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -309,14 +309,14 @@
bind = master->bind;
if (bind)
- INFO3 ("connecting to %s:%d, bound to %s", server, port, bind);
+ INFO4 ("connecting to %s:%d for %s, bound to %s", server, port, relay->localmount, bind);
else
- INFO2 ("connecting to %s:%d", server, port);
+ INFO3 ("connecting to %s:%d for %s", server, port, relay->localmount);
streamsock = sock_connect_wto_bind (server, port, bind, 10);
if (streamsock == SOCK_ERROR)
{
- WARN2 ("Failed to connect to %s:%d", server, port);
+ WARN3 ("Failed to connect to %s:%d for %s", server, port, relay->localmount);
break;
}
con = connection_create (streamsock, SOCK_ERROR, strdup (server));
Modified: icecast/branches/kh/icecast/src/slave.h
===================================================================
--- icecast/branches/kh/icecast/src/slave.h 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/slave.h 2009-06-22 01:06:57 UTC (rev 16154)
@@ -13,43 +13,15 @@
#ifndef __SLAVE_H__
#define __SLAVE_H__
-#include "thread/thread.h"
+#include "client.h"
-struct _client_tag;
-
-typedef struct _relay_server_master {
- struct _relay_server_master *next;
- char *ip;
- char *bind;
- char *mount;
- int port;
-} relay_server_master;
-
-typedef struct _relay_server {
- relay_server_master *masters;
- char *username;
- char *password;
- char *localmount;
- struct source_tag *source;
- int interval;
- int mp3metadata;
- int on_demand;
- int running;
- int cleanup;
- int enable;
- time_t start;
- thread_type *thread;
- struct _relay_server *next;
-} relay_server;
-
-
void slave_initialize(void);
void slave_shutdown(void);
void slave_restart (void);
void slave_update_all_mounts (void);
void slave_rebuild_mounts (void);
relay_server *slave_find_relay (relay_server *relays, const char *mount);
-int redirect_client (const char *mountpoint, struct _client_tag *client);
+int redirect_client (const char *mountpoint, struct _client_tag *client);
void redirector_update (struct _client_tag *client);
relay_server *relay_free (relay_server *relay);
Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/source.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -27,7 +27,6 @@
#ifndef _WIN32
#include <unistd.h>
-#include <sys/time.h>
#include <sys/socket.h>
#include <sys/wait.h>
#else
@@ -36,6 +35,7 @@
#endif
#include "thread/thread.h"
+#include "timing/timing.h"
#include "avl/avl.h"
#include "httpp/httpp.h"
#include "net/sock.h"
@@ -53,6 +53,7 @@
#include "fserve.h"
#include "auth.h"
#include "compat.h"
+#include "slave.h"
#undef CATMODULE
#define CATMODULE "source"
@@ -62,10 +63,15 @@
mutex_t move_clients_mutex;
/* avl tree helper */
-static int _compare_clients(void *compare_arg, void *a, void *b);
+static int _compare_clients(void *compare_arg, void *a, void *b);
static void _parse_audio_info (source_t *source, const char *s);
static void source_shutdown (source_t *source);
static void process_listeners (source_t *source, int fast_clients_only, int deletion_expected);
+
+static int http_source_listener (source_t *source, client_t *client);
+static int http_source_intro (source_t *source, client_t *client);
+static int locate_start_on_queue (source_t *source, client_t *client);
+
#ifdef _WIN32
#define source_run_script(x,y) WARN0("on [dis]connect scripts disabled");
#else
@@ -127,7 +133,7 @@
while (node) {
source = (source_t *)node->key;
- cmp = strcmp(mount, source->mount);
+ cmp = strcmp (mount, source->mount);
if (cmp < 0)
node = node->left;
else if (cmp > 0)
@@ -155,11 +161,11 @@
config = config_get_config();
while (mount && depth < MAX_FALLBACK_DEPTH)
{
- source = source_find_mount_raw(mount);
+ source = source_find_mount_raw (mount);
if (source)
{
- if (source->running || source->on_demand)
+ if (source_available (source))
break;
}
@@ -231,7 +237,6 @@
auth_release_listener (client, source->mount, mountinfo);
}
config_release_config ();
-
if (i)
stats_event_sub (NULL, "listeners", i);
@@ -331,7 +336,6 @@
break;
client = client->next;
}
-
return client;
}
@@ -399,10 +403,10 @@
* refbuf it's referring to, if it's http headers then we need
* to write them so don't release it.
*/
- if (client->check_buffer != format_check_http_buffer)
+ if (client->check_buffer != http_source_listener)
{
client_set_queue (client, NULL);
- client->check_buffer = format_check_file_buffer;
+ client->check_buffer = http_source_intro;
if (source->client == NULL)
client->intro_offset = -1;
}
@@ -632,6 +636,126 @@
}
+static int locate_start_on_queue (source_t *source, client_t *client)
+{
+ refbuf_t *refbuf;
+ long lag = 0;
+ int ret = -1;
+
+ /* we only want to attempt a burst at connection time, not midstream
+ * however streams like theora may not have the most recent page marked as
+ * a starting point, so look for one from the burst point */
+ if (source->stream_data_tail == NULL)
+ return -1;
+ refbuf = source->stream_data_tail;
+ DEBUG0 ("in here");
+ if (client->intro_offset == -1 && refbuf->sync_point)
+ {
+ refbuf = source->stream_data_tail;
+ lag = refbuf->len;
+ }
+ else
+ {
+ size_t size = client->intro_offset;
+ refbuf = source->burst_point;
+ lag = source->burst_offset;
+ while (size > 0 && refbuf && refbuf->next)
+ {
+ size -= refbuf->len;
+ lag -= refbuf->len;
+ refbuf = refbuf->next;
+ }
+ if (lag < 0)
+ ERROR1 ("Odd, lag is negative", lag);
+ }
+
+ while (refbuf)
+ {
+ if (refbuf->sync_point)
+ {
+ client_set_queue (client, refbuf);
+ client->check_buffer = format_advance_queue;
+ client->write_to_client = source->format->write_buf_to_client;
+ client->intro_offset = -1;
+ client->lag = lag;
+ ret = 0;
+ break;
+ }
+ lag -= refbuf->len;
+ refbuf = refbuf->next;
+ }
+ return ret;
+}
+
+
+static int http_source_intro (source_t *source, client_t *client)
+{
+ refbuf_t *refbuf = client->refbuf;
+
+ if (refbuf == NULL)
+ {
+ /* client refers to no data, must be from a move */
+ if (source->client)
+ {
+ locate_start_on_queue (source, client);
+ return -1;
+ }
+ /* source -> file fallback, need a refbuf for data */
+ refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
+ client->refbuf = refbuf;
+ client->pos = refbuf->len;
+ client->intro_offset = 0;
+ client->lag = 0;
+ }
+ if (format_file_read (client, source->intro_file) < 0)
+ {
+ if (source->stream_data_tail)
+ {
+ /* better find the right place in queue for this client */
+ client_set_queue (client, NULL);
+ return locate_start_on_queue (source, client);
+ }
+ client->intro_offset = 0; /* replay intro file */
+ return -1;
+ }
+ return 0;
+}
+
+
+static int http_source_listener (source_t *source, client_t *client)
+{
+ refbuf_t *refbuf = client->refbuf;
+
+ if (refbuf == NULL)
+ return -1;
+
+ if (client->respcode == 0)
+ {
+ DEBUG0("processing pending listener headers");
+
+ if (format_prepare_headers (source, client) < 0)
+ {
+ ERROR0 ("internal problem, dropping client");
+ client->con->error = 1;
+ return -1;
+ }
+ client->respcode = 200;
+ stats_event_inc (NULL, "listeners");
+ stats_event_inc (NULL, "listener_connections");
+ stats_event_inc (source->mount, "listener_connections");
+ }
+ if (client->pos == refbuf->len)
+ {
+ client->write_to_client = source->format->write_buf_to_client;
+ client->check_buffer = http_source_intro;
+ client->intro_offset = 0;
+ client->pos = refbuf->len = 4096;
+ return -1;
+ }
+ return 0;
+}
+
+
/* general send routine per listener. The deletion_expected tells us whether
* the last in the queue is about to disappear, so if this client is still
* referring to it after writing then drop the client as it's fallen too far
@@ -643,7 +767,7 @@
static int send_to_listener (source_t *source, client_t *client, int deletion_expected)
{
int bytes;
- int loop = 10; /* max number of iterations in one go */
+ int loop = 8; /* max number of iterations in one go */
long total_written = 0;
int ret = 0;
@@ -748,7 +872,7 @@
continue;
}
listener_count++;
- if (fast_client && client->check_buffer != format_check_file_buffer)
+ if (fast_client && client->check_buffer != http_source_intro)
{
client_t *to_move = client;
@@ -827,7 +951,6 @@
stats_event_hidden (source->mount, "total_bytes_sent", "0", STATS_COUNTERS);
stats_event_hidden (source->mount, "total_bytes_read", "0", STATS_COUNTERS);
- DEBUG0("Source creation complete");
source->last_read = time(NULL);
source->prev_listeners = -1;
source->bytes_sent_since_update = 0;
@@ -886,6 +1009,7 @@
source->format->in_bitrate = rate_setup (source->avg_bitrate_duration+1, 1);
source->format->out_bitrate = rate_setup (120, 1000);
+ INFO1 ("Source %s initialised", source->mount);
source->running = 1;
}
@@ -1280,6 +1404,9 @@
if (mountinfo && mountinfo->burst_size >= 0)
source->burst_size = (unsigned int)mountinfo->burst_size;
+ if (source->burst_size > source->queue_size_limit - 50000)
+ source->queue_size_limit = source->burst_size + 50000;
+
source->wait_time = 0;
if (mountinfo && mountinfo->wait_time)
source->wait_time = (time_t)mountinfo->wait_time;
@@ -1577,6 +1704,186 @@
}
+/* Check whether this listener is on this source. This is only called when
+ * there is auth. This may flag an existing listener to terminate.
+ * return 1 if ok to add or 0 to prevent
+ */
+static int check_duplicate_logins (source_t *source, client_t *client, auth_t *auth)
+{
+ client_t *existing;
+
+ if (auth == NULL || auth->allow_duplicate_users)
+ return 1;
+
+ /* allow multiple authenticated relays */
+ if (client->username == NULL || client->is_slave)
+ return 1;
+
+ existing = source->active_clients;
+ while (existing)
+ {
+ if (existing->con->error == 0 && existing->username &&
+ strcmp (existing->username, client->username) == 0)
+ {
+ if (auth->drop_existing_listener)
+ {
+ existing->con->error = 1;
+ return 1;
+ }
+ else
+ return 0;
+ }
+ existing = existing->next;
+ }
+ return 1;
+}
+
+
+/* Add client to source if it finds one. If a 0 is returned then the client should not be
+ * touched, if the return value is -1 then it failed to add and should not be touched.
+ * If it's a -2 value then the client is still around for any further processing.
+ */
+int source_add_listener (const char *mount, mount_proxy *mountinfo, client_t *client)
+{
+ int loop = 10;
+ int within_limits;
+ source_t *source;
+ mount_proxy *minfo = mountinfo;
+ const char *passed_mount = mount;
+ ice_config_t *config = config_get_config_unlocked();
+
+ do
+ {
+ int64_t stream_bitrate = 0;
+
+ do
+ {
+ source = source_find_mount_raw (mount);
+ if (loop == 0)
+ {
+ WARN0 ("preventing a fallback loop");
+ client_send_403 (client, "Fallback through too many mountpoints");
+ return -1;
+ }
+ if (source)
+ {
+ thread_mutex_lock (&source->lock);
+ if (source_available (source))
+ break;
+ thread_mutex_unlock (&source->lock);
+ }
+ if (minfo == NULL || minfo->fallback_mount == NULL)
+ return -2;
+ mount = minfo->fallback_mount;
+ minfo = config_find_mount (config_get_config_unlocked(), mount);
+ loop--;
+ } while (1);
+
+ /* ok, we found a source and it is locked */
+ if (client->is_slave)
+ {
+ if (source->client == NULL && source->on_demand == 0)
+ {
+ client_send_403 (client, "Slave relay reading from time unregulated stream");
+ return -1;
+ }
+ INFO0 ("client is from a slave, bypassing limits");
+ break;
+ }
+ if (source->format)
+ {
+ stream_bitrate = 8 * rate_avg (source->format->in_bitrate);
+
+ if (config->max_bandwidth)
+ {
+ int64_t global_rate = (int64_t)8 * global_getrate_avg (global.out_bitrate);
+
+ DEBUG1 ("server outgoing bitrate is %" PRId64, global_rate);
+ if (global_rate + stream_bitrate > config->max_bandwidth)
+ {
+ thread_mutex_unlock (&source->lock);
+ INFO0 ("server-wide outgoing bandwidth limit reached");
+ client_send_403redirect (client, passed_mount, "server bandwidth reached");
+ return -1;
+ }
+ }
+ }
+
+ if (mountinfo == NULL)
+ break; /* allow adding listeners, no mount limits imposed */
+
+ if (check_duplicate_logins (source, client, mountinfo->auth) == 0)
+ {
+ thread_mutex_unlock (&source->lock);
+ client_send_403 (client, "Account already in use");
+ 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;
+
+ INFO3 ("max on %s is %ld (cur %lu)", source->mount,
+ mountinfo->max_listeners, source->listeners);
+ within_limits = 1;
+ if (mountinfo->max_bandwidth > -1 && stream_bitrate)
+ {
+ DEBUG3 ("checking bandwidth limits for %s (%" PRId64 ", %" PRId64 ")",
+ mountinfo->mountname, stream_bitrate, mountinfo->max_bandwidth);
+ if ((source->listeners+1) * stream_bitrate > mountinfo->max_bandwidth)
+ {
+ INFO1 ("bandwidth limit reached on %s", source->mount);
+ within_limits = 0;
+ }
+ }
+ if (within_limits)
+ {
+ if (mountinfo->max_listeners == -1)
+ break;
+
+ if (source->listeners < (unsigned long)mountinfo->max_listeners)
+ break;
+ INFO1 ("max listener count reached on %s", source->mount);
+ }
+ /* minfo starts off as mountinfo put cascades through fallbacks */
+ if (minfo && minfo->fallback_when_full && minfo->fallback_mount)
+ {
+ thread_mutex_unlock (&source->lock);
+ mount = minfo->fallback_mount;
+ INFO1 ("stream full trying %s", mount);
+ loop--;
+ continue;
+ }
+
+ /* now we fail the client */
+ thread_mutex_unlock (&source->lock);
+ client_send_403redirect (client, passed_mount, "max listeners reached");
+ return -1;
+
+ } while (1);
+
+ client->con->sent_bytes = 0;
+ client->write_to_client = format_generic_write_to_client;
+ client->check_buffer = http_source_listener;
+ client->refbuf->len = PER_CLIENT_REFBUF_SIZE;
+ memset (client->refbuf->data, 0, PER_CLIENT_REFBUF_SIZE);
+
+ /* lets add the client to the active list */
+ client->next = source->active_clients;
+ source->active_clients = client;
+ source->listeners++;
+ thread_mutex_unlock (&source->lock);
+
+ if (source->running == 0 && source->on_demand)
+ {
+ /* enable on-demand relay to start, wake up the slave thread */
+ DEBUG0("kicking off on-demand relay");
+ source->on_demand_req = 1;
+ }
+ return 0;
+}
+
+
void source_startup (client_t *client, const char *uri)
{
source_t *source;
Modified: icecast/branches/kh/icecast/src/source.h
===================================================================
--- icecast/branches/kh/icecast/src/source.h 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/source.h 2009-06-22 01:06:57 UTC (rev 16154)
@@ -86,6 +86,8 @@
} source_t;
+#define source_available(x) ((x)->running || (x)->on_demand)
+
source_t *source_reserve (const char *mount);
void *source_client_thread (void *arg);
void source_startup (client_t *client, const char *uri);
@@ -101,6 +103,7 @@
int source_remove_client(void *key);
void source_main(source_t *source);
void source_recheck_mounts (int update_all);
+int source_add_listener (const char *mount, mount_proxy *mountinfo, client_t *client);
extern mutex_t move_clients_mutex;
Modified: icecast/branches/kh/icecast/src/stats.c
===================================================================
--- icecast/branches/kh/icecast/src/stats.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/stats.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -511,7 +511,6 @@
node->hidden = event->hidden;
if (snode->hidden & STATS_HIDDEN)
node->hidden |= STATS_HIDDEN;
-
stats_listener_send (node->hidden, "EVENT %s %s %s\n", event->source, event->name, event->value);
avl_insert(snode->stats_tree, (void *)node);
}
@@ -525,6 +524,7 @@
return;
}
modify_node_event (node, event);
+ stats_listener_send (node->hidden, "EVENT %s %s %s\n", event->source, node->name, node->value);
return;
}
/* change source hidden status */
@@ -561,11 +561,7 @@
return;
}
if (event->action == STATS_EVENT_REMOVE)
- {
- DEBUG1 ("delete source node %s", event->source);
- stats_listener_send (snode->hidden, "DELETE %s\n", event->source);
avl_delete(_stats.source_tree, (void *)snode, _free_source_stats);
- }
}
@@ -698,6 +694,8 @@
va_list vl;
va_copy (vl, ap);
+ if (len <= 0)
+ return -1;
ret = vsnprintf (buf, len, fmt, vl);
if (ret < 0 || ret >= len)
return -1;
@@ -719,9 +717,12 @@
static void _add_node_to_stats_client (event_listener_t *listener, refbuf_t *refbuf)
{
- *listener->queue_recent_p = refbuf;
- listener->queue_recent_p = &refbuf->next;
- listener->content_len += refbuf->len;
+ if (refbuf->len)
+ {
+ *listener->queue_recent_p = refbuf;
+ listener->queue_recent_p = &refbuf->next;
+ listener->content_len += refbuf->len;
+ }
}
@@ -803,69 +804,61 @@
stats_count.action = STATS_EVENT_INC;
process_event_unlocked (&stats_count);
- while (size < 50000) /* use a large limit */
+ /* first we fill our queue with the current stats */
+ refbuf = refbuf_new (size);
+ refbuf->len = 0;
+
+ /* the global stats */
+ node = avl_get_first(_stats.global_tree);
+ while (node)
{
- /* first we fill our queue with the current stats */
- refbuf = refbuf_new (size);
- refbuf->len = 0;
+ stats_node_t *stat = node->key;
- /* starts with the http response header */
- if (_append_to_buffer (refbuf, size, "HTTP/1.0 200 OK\r\ncapability: streamlist\r\n\r\n") < 0)
+ if (stat->hidden & listener->hidden_level)
{
- refbuf_release (refbuf);
- break;
- }
- /* now the global stats */
- node = avl_get_first(_stats.global_tree);
- while (node)
- {
- stats_node_t *stat = node->key;
-
- node = avl_get_next(node);
- if ((stat->hidden & listener->hidden_level) == 0)
- continue;
if (_append_to_buffer (refbuf, size, "EVENT global %s %s\n", stat->name, stat->value) < 0)
{
- size += 8192;
- refbuf_release (refbuf);
- break;
+ _add_node_to_stats_client (listener, refbuf);
+ refbuf = refbuf_new (size);
+ refbuf->len = 0;
+ continue;
}
}
- if (node) continue; /* catch buffer full case */
-
- /* now the stats for each source */
- node = avl_get_first(_stats.source_tree);
- while (node)
+ node = avl_get_next(node);
+ }
+ /* now the stats for each source */
+ node = avl_get_first(_stats.source_tree);
+ while (node)
+ {
+ avl_node *node2;
+ stats_source_t *snode = (stats_source_t *)node->key;
+ if (snode->hidden & listener->hidden_level)
{
- avl_node *node2;
- stats_source_t *snode = (stats_source_t *)node->key;
- node = avl_get_next(node);
- if ((snode->hidden & listener->hidden_level) == 0)
- continue;
if (_append_to_buffer (refbuf, size, "NEW %s\n", snode->source) < 0)
{
- size += 8192;
- refbuf_release (refbuf);
- break;
+ _add_node_to_stats_client (listener, refbuf);
+ refbuf = refbuf_new (size);
+ refbuf->len = 0;
+ continue;
}
- node2 = avl_get_first(snode->stats_tree);
- while (node2)
+ }
+ node = avl_get_next(node);
+ node2 = avl_get_first(snode->stats_tree);
+ while (node2)
+ {
+ stats_node_t *stat = node2->key;
+ if (stat->hidden & listener->hidden_level)
{
- stats_node_t *stat = node2->key;
- node2 = avl_get_next(node2);
-
- if ((stat->hidden & listener->hidden_level) == 0)
- continue;
if (_append_to_buffer (refbuf, size, "EVENT %s %s %s\n", snode->source, stat->name, stat->value) < 0)
{
- size += 8192;
- refbuf_release (refbuf);
- break;
+ _add_node_to_stats_client (listener, refbuf);
+ refbuf = refbuf_new (size);
+ refbuf->len = 0;
+ continue;
}
}
+ node2 = avl_get_next (node2);
}
- if (node) continue; /* catch buffer full case */
- break;
}
client_set_queue (listener->client, refbuf);
@@ -896,7 +889,9 @@
listener->queue_recent_p = &listener->queue;
client->respcode = 200;
- snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
+ client_set_queue (client, NULL);
+ client->refbuf = refbuf_new (100);
+ snprintf (client->refbuf->data, 100,
"HTTP/1.0 200 OK\r\ncapability: streamlist\r\n\r\n");
client->refbuf->len = strlen (client->refbuf->data);
fserve_add_client_callback (client, stats_callback, listener);
@@ -971,6 +966,8 @@
static int _free_source_stats(void *key)
{
stats_source_t *node = (stats_source_t *)key;
+ stats_listener_send (node->hidden, "DELETE %s\n", node->source);
+ DEBUG1 ("delete source node %s", node->source);
avl_tree_free(node->stats_tree, _free_stats);
free(node->source);
free(node);
@@ -1049,7 +1046,6 @@
{
/* no source_t is reserved so remove them now */
snode = avl_get_next (snode);
- DEBUG1 ("releasing %s stats", src->source);
avl_delete (_stats.source_tree, src, _free_source_stats);
continue;
}
Modified: icecast/branches/kh/icecast/src/yp.c
===================================================================
--- icecast/branches/kh/icecast/src/yp.c 2009-06-21 17:28:50 UTC (rev 16153)
+++ icecast/branches/kh/icecast/src/yp.c 2009-06-22 01:06:57 UTC (rev 16154)
@@ -296,7 +296,7 @@
if (curlcode)
{
yp->process = do_yp_add;
- yp->next_update += 1200;
+ yp->next_update = now + 1200;
ERROR2 ("connection to %s failed with \"%s\"", server->url, server->curl_error);
return -2;
}
@@ -307,7 +307,7 @@
if (yp->process == do_yp_add)
{
ERROR3 ("YP %s on %s failed: %s", cmd, server->url, yp->error_msg);
- yp->next_update += 7200;
+ yp->next_update = now + 7200;
}
if (yp->process == do_yp_touch)
{
@@ -318,9 +318,9 @@
* cases as a firewall block or incorrect listenurl.
*/
if (yp->touch_interval < 1200)
- yp->next_update += 1200;
+ yp->next_update = now + 1200;
else
- yp->next_update += yp->touch_interval;
+ yp->next_update = now + yp->touch_interval;
INFO3 ("YP %s on %s failed: %s", cmd, server->url, yp->error_msg);
}
yp->process = do_yp_add;
@@ -408,7 +408,7 @@
{
yp->process = do_yp_touch;
/* force first touch in 5 secs */
- yp->next_update = time(NULL) + 5;
+ yp->next_update = now + 5;
}
return ret;
}
More information about the commits
mailing list