[xiph-commits] r8244 - in icecast/branches/kh/icecast: . doc src

karl at motherfish-iii.xiph.org karl at motherfish-iii.xiph.org
Mon Nov 22 09:09:43 PST 2004


Author: karl
Date: 2004-11-22 09:09:42 -0800 (Mon, 22 Nov 2004)
New Revision: 8244

Modified:
   icecast/branches/kh/icecast/configure.in
   icecast/branches/kh/icecast/doc/icecast2_config_file.html
   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/cfgfile.c
   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/format_mp3.c
   icecast/branches/kh/icecast/src/fserve.c
   icecast/branches/kh/icecast/src/fserve.h
   icecast/branches/kh/icecast/src/md5.c
   icecast/branches/kh/icecast/src/source.c
   icecast/branches/kh/icecast/src/source.h
   icecast/branches/kh/icecast/src/stats.c
Log:
various cleanups, small resync and some functions moved to help further
merging.


Modified: icecast/branches/kh/icecast/configure.in
===================================================================
--- icecast/branches/kh/icecast/configure.in	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/configure.in	2004-11-22 17:09:42 UTC (rev 8244)
@@ -101,10 +101,10 @@
         enable_curl="yes"
         XIPH_VAR_APPEND([XIPH_CPPFLAGS],[$CURL_CFLAGS])
         XIPH_VAR_PREPEND([XIPH_LIBS],[$CURL_LIBS])
-        ], [ AC_MSG_NOTICE([Your curl dev files are too old (7.10 or above required)])
+        ], [ AC_MSG_NOTICE([Your curl dev files are too old (7.10 or above required), YP disabled])
         ], [#include <curl/curl.h>
         ])
-    ],[ AC_MSG_NOTICE([libcurl not found])
+    ],[ AC_MSG_NOTICE([libcurl not found, YP disabled])
     ])
 dnl -- YP support --
 AC_ARG_ENABLE([yp],

Modified: icecast/branches/kh/icecast/doc/icecast2_config_file.html
===================================================================
--- icecast/branches/kh/icecast/doc/icecast2_config_file.html	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/doc/icecast2_config_file.html	2004-11-22 17:09:42 UTC (rev 8244)
@@ -349,6 +349,7 @@
         &lt;intro&gt;/path/to/intro.ogg&lt;/intro&gt;
         &lt;fallback-mount&gt;/example2.ogg&lt;/fallback-mount&gt;
         &lt;fallback-override&gt;1&lt;/fallback-override&gt;
+        &lt;no-yp&gt;1&lt;/no-yp&gt;
         &lt;burst-size&gt;65536&lt;/burst-size&gt;
         &lt;mp3-metadata-interval&gt;8192&lt;/mp3-metadata-interval&gt;
         &lt;authentication type="htpasswd"&gt;
@@ -403,6 +404,12 @@
 When enabled, this allows a connecting source client or relay on this mountpoint to move
 listening clients back from the fallback mount.
 </div>
+<h4>no-yp</h4>
+<div class="indentedbox">
+Setting this option prevents this mountpoint from advertising on YP.  The default is 0 so YP
+advertising occurs however you may want to prevent it here if you intend listeners to connect
+to a local relay instead
+</div>
 <h4>burst-size</h4>
 <div class="indentedbox">
 This optional setting allows for providing a burst size which overrides the default burst size

Modified: icecast/branches/kh/icecast/src/admin.c
===================================================================
--- icecast/branches/kh/icecast/src/admin.c	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/admin.c	2004-11-22 17:09:42 UTC (rev 8244)
@@ -194,7 +194,10 @@
         int response, char *xslt_template);
 static void html_write(client_t *client, char *fmt, ...);
 
-xmlDocPtr admin_build_sourcelist(char *current_source)
+/* build an XML doc containing information about currently running sources.
+ * If a mountpoint is passed then that source will not be added to the XML
+ * doc even if the source is running */
+xmlDocPtr admin_build_sourcelist (const char *mount)
 {
     avl_node *node;
     source_t *source;
@@ -207,16 +210,16 @@
     xmlnode = xmlNewDocNode(doc, NULL, "icestats", NULL);
     xmlDocSetRootElement(doc, xmlnode);
 
-    if (current_source) {
-        xmlNewChild(xmlnode, NULL, "current_source", current_source);
+    if (mount) {
+        xmlNewChild(xmlnode, NULL, "current_source", mount);
     }
 
     node = avl_get_first(global.source_tree);
     while(node) {
         source = (source_t *)node->key;
-        if (current_source && strcmp (current_source, source->mount) == 0)
+        if (mount && strcmp (mount, source->mount) == 0)
         {
-            node = avl_get_next(node);
+            node = avl_get_next (node);
             continue;
         }
 
@@ -229,7 +232,7 @@
             xmlNewChild (srcnode, NULL, "fallback", 
                     (source->fallback_mount != NULL)?
                     source->fallback_mount:"");
-            snprintf (buf, sizeof(buf), "%ld", source->listeners);
+            snprintf (buf, sizeof(buf), "%u", source->listeners);
             xmlNewChild (srcnode, NULL, "listeners", buf);
             if (source->running)
             {
@@ -664,12 +667,11 @@
     int response)
 {
     xmlDocPtr doc;
-    xmlNodePtr node, srcnode;
+    xmlNodePtr node, srcnode, listenernode;
+    client_t *current;
+    char buf[22];
     char *userAgent = NULL;
-    xmlNodePtr listenernode;
-    client_t *current;
     time_t now = time(NULL);
-    char buf[22];
 
     doc = xmlNewDoc("1.0");
     node = xmlNewDocNode(doc, NULL, "icestats", NULL);
@@ -681,7 +683,7 @@
     xmlDocSetRootElement(doc, node);
 
     memset(buf, '\000', sizeof(buf));
-    snprintf(buf, sizeof(buf)-1, "%ld", source->listeners);
+    snprintf(buf, sizeof(buf)-1, "%u", source->listeners);
     xmlNewChild(srcnode, NULL, "Listeners", buf);
 
     current = source->active_clients;
@@ -812,7 +814,6 @@
     client_destroy(client);
 }
 
-
 static void command_kill_source(client_t *client, source_t *source,
         int response)
 {
@@ -912,9 +913,9 @@
     COMMAND_OPTIONAL(client, "title", title);
     COMMAND_OPTIONAL(client, "artist", artist);
 
-    if (strcmp(action, "updinfo") != 0)
+    if (strcmp (action, "updinfo") != 0)
     {
-        client_send_400(client, "No such action");
+        client_send_400 (client, "No such action");
         return;
     }
 
@@ -990,7 +991,6 @@
     }
 }
 
-
 static void command_stats(client_t *client, int response) {
     xmlDocPtr doc;
 

Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/auth.c	2004-11-22 17:09:42 UTC (rev 8244)
@@ -30,6 +30,7 @@
 #include "source.h"
 #include "client.h"
 #include "cfgfile.h"
+#include "stats.h"
 #include "httpp/httpp.h"
 #include "md5.h"
 
@@ -185,3 +186,173 @@
         client_send_401 (client);
 }
 
+
+/* Check whether this client is currently on this mount, the client may be
+ * on either the active or pending lists.
+ * return 1 if ok to add or 0 to prevent
+ */
+static int check_duplicate_logins (source_t *source, client_t *client)
+{
+    auth_t *auth = source->authenticator;
+
+    /* allow multiple authenticated relays */
+    if (client->username == NULL || client->is_slave)
+        return 1;
+
+    if (auth && auth->allow_duplicate_users == 0)
+    {
+        client_t *existing;
+
+        existing = source->active_clients;
+        while (existing)
+        {
+            if (existing->username && strcmp (existing->username, client->username) == 0)
+                return 0;
+            existing = existing->next;
+        }
+        existing = source->pending_clients;
+        while (existing)
+        {
+            if (existing->username && strcmp (existing->username, client->username) == 0)
+                return 0;
+            existing = existing->next;
+        }
+    }
+    return 1;
+}
+
+
+/* The actual add client routine, this requires the source to be locked.
+ * if 0 is returned then the client should not be touched, however if -1
+ * is returned then the caller is responsible for handling the client
+ */
+int add_authenticated_client (source_t *source, client_t *client)
+{
+    if (source->authenticator && check_duplicate_logins (source, client) == 0)
+        return -1;
+    /* lets add the client to the pending list */
+    client->next = source->pending_clients;
+    source->pending_clients = client;
+
+    client->write_to_client = format_http_write_to_client;
+    client->refbuf = refbuf_new (4096);
+
+    sock_set_blocking (client->con->sock, SOCK_NONBLOCK);
+    sock_set_nodelay (client->con->sock);
+    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;
+        slave_rescan();
+    }
+    DEBUG1 ("Added client to pending on %s", source->mount);
+    stats_event_inc (NULL, "clients");
+    return 0;
+}
+
+
+/* try to add client to a pending list.  return
+ *  0 for success
+ *  -1 too many clients
+ *  -2 mount needs authentication
+ *  -3 mount is unavailable
+ */
+static int _add_client (char *passed_mount, client_t *client, int initial_connection)
+{
+    source_t *source;
+    char *mount = passed_mount;
+    
+    while (1)
+    {
+        source = source_find_mount (mount);
+        if (passed_mount != mount) 
+            free (mount);
+        if (source == NULL)
+            return -3;
+        if (initial_connection && source->no_mount
+                && strcmp (source->mount, passed_mount) == 0)
+            return -3;
+        thread_mutex_lock (&source->lock);
+
+        if (source->running || source->on_demand)
+        {
+            DEBUG2 ("max on %s is %d", source->mount, source->max_listeners);
+            DEBUG2 ("pending %d, current %d", source->new_listeners, source->listeners);
+            if (source->max_listeners == -1)
+                break;
+            if (client->is_slave)
+                break;
+            if (source->new_listeners + source->listeners < (unsigned int)source->max_listeners)
+                break;
+
+            INFO2 ("max listeners (%d) reached on %s", source->max_listeners, source->mount);
+            if (source->fallback_when_full == 0 || source->fallback_mount == NULL)
+            {
+                thread_mutex_unlock (&source->lock);
+                return -1;
+            }
+            if (source->fallback_mount)
+                mount = strdup (source->fallback_mount);
+            else
+                mount = NULL;
+        }
+
+        thread_mutex_unlock (&source->lock);
+    }
+
+    if (auth_check_client (source, client) != AUTH_OK)
+    {
+        thread_mutex_unlock (&source->lock);
+        INFO0 ("listener failed to authenticate");
+        return -2;
+    }
+    source->new_listeners++;
+
+    thread_mutex_unlock (&source->lock);
+    return 0;
+}
+
+
+void add_client (char *mount, client_t *client)
+{
+    int added = -3;
+
+    if (mount)
+    {
+        if (connection_check_relay_pass(client->parser))
+        {
+            client_as_slave (client);
+            INFO0 ("client connected as slave");
+        }
+        thread_mutex_lock (&move_clients_mutex);
+        avl_tree_rlock (global.source_tree);
+        added = _add_client (mount, client, 1);
+        avl_tree_unlock (global.source_tree);
+        thread_mutex_unlock (&move_clients_mutex);
+    }
+    switch (added)
+    {
+    case -1: 
+        /* there may be slaves we can re-direct to */
+        if (slave_redirect (mount, client))
+            break;
+        client_send_404 (client,
+                "Too many clients on this mountpoint. Try again later.");
+        DEBUG1 ("max clients on %s", mount);
+        break;
+    case -2:
+        client_send_401 (client);
+        break;
+    case -3:
+        client_send_404 (client, "The file you requested could not be found");
+        break;
+    default:
+        return;
+    }
+    /* failed client, drop global count */
+    global_lock();
+    global.clients--;
+    global_unlock();
+}
+

Modified: icecast/branches/kh/icecast/src/auth.h
===================================================================
--- icecast/branches/kh/icecast/src/auth.h	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/auth.h	2004-11-22 17:09:42 UTC (rev 8244)
@@ -13,12 +13,13 @@
 #ifndef __AUTH_H__
 #define __AUTH_H__
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <libxml/xmlmemory.h>
 #include <libxml/parser.h>
 #include <libxml/tree.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
 #include "source.h"
 #include "client.h"
 
@@ -54,6 +55,8 @@
 void auth_clear(auth_t *authenticator);
 int auth_postprocess_client (const char *mount, client_t *client);
 void auth_close_client (client_t *client);
+int add_authenticated_client (source_t *source, client_t *client);
+void add_client (char *mount, client_t *client);
 
 #endif
 

Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/cfgfile.c	2004-11-22 17:09:42 UTC (rev 8244)
@@ -158,7 +158,7 @@
         xmlFree(c->access_log);
     if (c->error_log && c->error_log != CONFIG_DEFAULT_ERROR_LOG) 
         xmlFree(c->error_log);
-    if (c->shoutcast_mount && c->shoutcast_mount != CONFIG_DEFAULT_SHOUTCAST_MOUNT) 
+    if (c->shoutcast_mount && c->shoutcast_mount != CONFIG_DEFAULT_SHOUTCAST_MOUNT)
         xmlFree(c->shoutcast_mount);
     for(i=0; i < MAX_LISTEN_SOCKETS; i++) {
         if (c->listeners[i].bind_address) xmlFree(c->listeners[i].bind_address);

Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/client.c	2004-11-22 17:09:42 UTC (rev 8244)
@@ -150,9 +150,8 @@
 /* helper function for sending the data to a client */
 int client_send_bytes (client_t *client, const void *buf, unsigned len)
 {
-    int ret;
 #ifdef HAVE_AIO
-    int err;
+    int ret, err;
     struct aiocb *aiocbp = &client->aio;
 
     if (client->pending_io == 0)
@@ -175,16 +174,13 @@
     client->pending_io = 0;
 
 #else
-    ret = sock_write_bytes (client->con->sock, buf, len);
+    int ret = sock_write_bytes (client->con->sock, buf, len);
 #endif
 
-    if (ret < 0)
+    if (ret < 0 && !sock_recoverable (sock_error()))
     {
-        if (! sock_recoverable (sock_error()))
-        {
-            DEBUG0 ("Client connection died");
-            client->con->error = 1;
-        }
+        DEBUG0 ("Client connection died");
+        client->con->error = 1;
     }
     if (ret > 0)
         client->con->sent_bytes += ret;

Modified: icecast/branches/kh/icecast/src/client.h
===================================================================
--- icecast/branches/kh/icecast/src/client.h	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/client.h	2004-11-22 17:09:42 UTC (rev 8244)
@@ -24,6 +24,7 @@
 
 #include "connection.h"
 #include "refbuf.h"
+#include "httpp/httpp.h"
 
 struct source_tag;
 

Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/connection.c	2004-11-22 17:09:42 UTC (rev 8244)
@@ -50,6 +50,7 @@
 #include "refbuf.h"
 #include "client.h"
 #include "stats.h"
+#include "auth.h"
 #include "logging.h"
 #include "xslt.h"
 #include "fserve.h"

Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/format_mp3.c	2004-11-22 17:09:42 UTC (rev 8244)
@@ -580,7 +580,7 @@
 }
 
 
-static int format_mp3_create_client_data(source_t *source, client_t *client) 
+static int format_mp3_create_client_data(source_t *source, client_t *client)
 {
     mp3_client_data *client_mp3 = calloc(1,sizeof(mp3_client_data));
     mp3_state *source_mp3 = source->format->_state;

Modified: icecast/branches/kh/icecast/src/fserve.c
===================================================================
--- icecast/branches/kh/icecast/src/fserve.c	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/fserve.c	2004-11-22 17:09:42 UTC (rev 8244)
@@ -46,6 +46,7 @@
 #include "logging.h"
 #include "cfgfile.h"
 #include "util.h"
+#include "compat.h"
 
 #include "fserve.h"
 

Modified: icecast/branches/kh/icecast/src/fserve.h
===================================================================
--- icecast/branches/kh/icecast/src/fserve.h	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/fserve.h	2004-11-22 17:09:42 UTC (rev 8244)
@@ -14,6 +14,7 @@
 #define __FSERVE_H__
 
 #include <stdio.h>
+#include "compat.h"
 
 typedef struct _fserve_t
 {

Modified: icecast/branches/kh/icecast/src/md5.c
===================================================================
--- icecast/branches/kh/icecast/src/md5.c	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/md5.c	2004-11-22 17:09:42 UTC (rev 8244)
@@ -187,7 +187,7 @@
 # define F4(x, y, z) (y ^ (x | ~z))
 
 /* This is the central step in the MD5 algorithm. */
-# define MD5STEP(f, w, x, y, z, data, s) do { w += f(x, y, z) + data;  w = (w<<s) | (w>>(32-s));  w += x; }while (0)
+# define MD5STEP(f, w, x, y, z, data, s) do { w += f(x, y, z) + data;  w = (w<<s) | (w>>(32-s));  w += x; }while(0)
 
 /*
  * The core of the MD5 algorithm, this alters an existing MD5 hash to

Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/source.c	2004-11-22 17:09:42 UTC (rev 8244)
@@ -62,6 +62,7 @@
 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);
 #ifdef _WIN32
 #define source_run_script(x,y)  WARN0("on [dis]connect scripts disabled");
 #else
@@ -260,6 +261,7 @@
     source->shoutcast_compat = 0;
     source->max_listeners = -1;
     source->yp_public = 0;
+    source->yp_prevent = 0;
     util_dict_free (source->audio_info);
     source->audio_info = NULL;
 
@@ -412,7 +414,6 @@
         INFO2 ("passing %d listeners to \"%s\"", count, dest->mount);
 
         dest->new_listeners += count;
-        dest->check_pending = 1;
         source->listeners = 0;
         source->new_listeners = 0;
         stats_event (source->mount, "listeners", "0");
@@ -449,7 +450,118 @@
     }
 }
 
+/* get some data from the source. The stream data is placed in a refbuf
+ * and sent back, however NULL is also valid as in the case of a short
+ * timeout and there's no data pending.
+ */
+static void get_next_buffer (source_t *source)
+{
+    refbuf_t *refbuf = NULL;
+    int no_delay_count = 0;
 
+    while (global.running == ICE_RUNNING && source->running)
+    {
+        int fds = 0;
+        time_t current = time(NULL);
+        int delay = 200;
+
+        /* service fast clients but jump out once in a while to check on
+         * normal clients */
+        if (no_delay_count < 10)
+        {
+            if (source->active_clients != source->first_normal_client)
+            {
+                delay = 0;
+                no_delay_count++;
+            }
+        }
+        else
+            return;
+
+        thread_mutex_unlock (&source->lock);
+
+        if (source->con)
+            fds = util_timed_wait_for_fd (source->con->sock, delay);
+        else
+        {
+            thread_sleep (delay*1000);
+            source->last_read = current;
+        }
+
+        /* take the lock */
+        thread_mutex_lock (&source->lock);
+
+        if (source->recheck_settings)
+        {
+            ice_config_t *config = config_get_config();
+            source_update_settings (config, source);
+            config_release_config ();
+        }
+        if (fds < 0)
+        {
+            if (! sock_recoverable (sock_error()))
+            {
+                WARN0 ("Error while waiting on socket, Disconnecting source");
+                source->running = 0;
+            }
+            continue;
+        }
+
+        if (fds == 0)
+        {
+            if (source->last_read + (time_t)source->timeout < current)
+            {
+                WARN0 ("Disconnecting source due to socket timeout");
+                source->running = 0;
+                break;
+            }
+            if (delay == 0)
+            {
+                process_listeners (source, 1, 0);
+                continue;
+            }
+            break;
+        }
+        source->last_read = current;
+        refbuf = source->format->get_buffer (source);
+        if (refbuf)
+        {
+            /* append buffer to the in-flight data queue,  */
+            if (source->stream_data == NULL)
+            {
+                source->stream_data = refbuf;
+                source->burst_point = refbuf;
+                source->burst_offset = 0;
+            }
+            if (source->stream_data_tail)
+                source->stream_data_tail->next = refbuf;
+            source->stream_data_tail = refbuf;
+            source->queue_size += refbuf->len;
+            refbuf_addref (refbuf);
+
+            /* move the starting point for new listeners */
+            source->burst_offset += refbuf->len;
+            if (source->burst_offset > source->burst_size)
+            {
+                if (source->burst_point->next)
+                {
+                    refbuf_t *to_go = source->burst_point;
+
+                    source->burst_offset -= source->burst_point->len;
+                    source->burst_point = source->burst_point->next;
+                    refbuf_release (to_go);
+                }
+            }
+
+            /* save stream to file */
+            if (source->dumpfile && source->format->write_buf_to_file)
+                source->format->write_buf_to_file (source, refbuf);
+        }
+        break;
+    }
+}
+
+
 /* 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
@@ -572,114 +684,48 @@
 }
 
 
-/* get some data from the source. The stream data is placed in a refbuf
- * and sent back, however NULL is also valid as in the case of a short
- * timeout and there's no data pending.
- */
-static void get_next_buffer (source_t *source)
+static void process_pending_clients (source_t *source)
 {
-    refbuf_t *refbuf = NULL;
-    int no_delay_count = 0;
+    unsigned count = 0;
+    client_t *client = source->pending_clients;
 
-    while (global.running == ICE_RUNNING && source->running)
+    while (client)
     {
-        int fds = 0;
-        time_t current = time(NULL);
-        int delay = 200;
+        client_t *to_go = client;
 
-        /* service fast clients but jump out once in a while to check on
-         * normal clients */
-        if (no_delay_count < 10)
+        client = client->next;
+        /*  trap from when clients have been moved */
+        if (to_go->write_to_client == NULL)
         {
-            if (source->active_clients != source->first_normal_client)
+            /* trap for client moved to fallback file */
+            if (source->file_only)
             {
-                delay = 0;
-                no_delay_count++;
+                to_go->write_to_client = format_intro_write_to_client;
+                client_set_queue (to_go, refbuf_new(4096));
+                to_go->intro_offset = 0;
+                to_go->pos = 4096;
             }
-        }
-        else
-            return;
-
-        thread_mutex_unlock (&source->lock);
-
-        if (source->con)
-            fds = util_timed_wait_for_fd (source->con->sock, delay);
-        else
-        {
-            thread_sleep (delay*1000);
-            source->last_read = current;
-        }
-
-        /* take the lock */
-        thread_mutex_lock (&source->lock);
-
-        if (source->recheck_settings)
-        {
-            ice_config_t *config = config_get_config();
-            source_update_settings (config, source);
-            config_release_config ();
-        }
-        if (fds < 0)
-        {
-            if (! sock_recoverable (sock_error()))
+            else
             {
-                WARN0 ("Problem while waiting on socket, Disconnecting source");
-                source->running = 0;
+                to_go->write_to_client = source->format->write_buf_to_client;
+                client_set_queue (to_go, source->stream_data_tail);
             }
-            continue;
         }
 
-        if (fds == 0)
-        {
-            if (source->last_read + (time_t)source->timeout < current)
-            {
-                WARN0 ("Disconnecting source due to socket timeout");
-                source->running = 0;
-                break;
-            }
-            if (delay == 0)
-            {
-                process_listeners (source, 1, 0);
-                continue;
-            }
-            break;
-        }
-        source->last_read = current;
-        refbuf = source->format->get_buffer (source);
-        if (refbuf)
-        {
-            /* append buffer to the in-flight data queue,  */
-            if (source->stream_data == NULL)
-            {
-                source->stream_data = refbuf;
-                source->burst_point = refbuf;
-                source->burst_offset = 0;
-            }
-            if (source->stream_data_tail)
-                source->stream_data_tail->next = refbuf;
-            source->stream_data_tail = refbuf;
-            source->queue_size += refbuf->len;
-            refbuf_addref (refbuf);
+        to_go->next = source->active_clients;
+        source->active_clients = to_go;
 
-            /* move the starting point for new listeners */
-            source->burst_offset += refbuf->len;
-            if (source->burst_offset > source->burst_size)
-            {
-                if (source->burst_point->next)
-                {
-                    refbuf_t *to_go = source->burst_point;
+        count++;
+        source->new_listeners--;
+    }
+    source->pending_clients = NULL;
+    source->pending_clients_tail = &source->pending_clients;
 
-                    source->burst_offset -= source->burst_point->len;
-                    source->burst_point = source->burst_point->next;
-                    refbuf_release (to_go);
-                }
-            }
-
-            /* save stream to file */
-            if (source->dumpfile && source->format->write_buf_to_file)
-                source->format->write_buf_to_file (source, refbuf);
-        }
-        break;
+    if (count)
+    {
+        DEBUG1("Adding %d client(s)", count);
+        source->listeners += count;
+        stats_event_args (source->mount, "listeners", "%d", source->listeners);
     }
 }
 
@@ -785,226 +831,9 @@
 }
 
 
-/* Check whether this client is currently on this mount, the client may be
- * on either the active or pending lists.
- * return 1 if ok to add or 0 to prevent
- */
-static int check_duplicate_logins (source_t *source, client_t *client)
-{
-    auth_t *auth = source->authenticator;
 
-    /* allow multiple authenticated relays */
-    if (client->username == NULL || client->is_slave)
-        return 1;
-
-    if (auth && auth->allow_duplicate_users == 0)
-    {
-        client_t *existing;
-
-        existing = source->active_clients;
-        while (existing)
-        {
-            if (existing->username && strcmp (existing->username, client->username) == 0)
-                return 0;
-            existing = existing->next;
-        }
-        existing = source->pending_clients;
-        while (existing)
-        {
-            if (existing->username && strcmp (existing->username, client->username) == 0)
-                return 0;
-            existing = existing->next;
-        }
-    }
-    return 1;
-}
-
-
-/* The actual add client routine, this requires the source to be locked.
- * if 0 is returned then the client should not be touched, however if -1
- * is returned then the caller is responsible for handling the client
- */
-int add_authenticated_client (source_t *source, client_t *client)
+void source_main (source_t *source)
 {
-    if (source->authenticator && check_duplicate_logins (source, client) == 0)
-        return -1;
-    /* lets add the client to the pending list */
-    client->next = source->pending_clients;
-    source->pending_clients = client;
-
-    client->write_to_client = format_http_write_to_client;
-    client->refbuf = refbuf_new (4096);
-
-    sock_set_blocking (client->con->sock, SOCK_NONBLOCK);
-    sock_set_nodelay (client->con->sock);
-    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;
-        slave_rescan();
-    }
-    DEBUG1 ("Added client to pending on %s", source->mount);
-    source->check_pending = 1;
-    stats_event_inc (NULL, "clients");
-    return 0;
-}
-
-
-/* try to add client to a pending list.  return
- *  0 for success
- *  -1 too many clients
- *  -2 mount needs authentication
- *  -3 mount is unavailable
- */
-static int _add_client (char *passed_mount, client_t *client, int initial_connection)
-{
-    source_t *source;
-    char *mount = passed_mount;
-
-    while (1)
-    {
-        source = source_find_mount (mount);
-        if (passed_mount != mount)
-            free (mount);
-        if (source == NULL)
-            return -3;
-        if (initial_connection && source->no_mount
-                && strcmp (source->mount, passed_mount) == 0)
-            return -3;
-        thread_mutex_lock (&source->lock);
-
-        if (source->running || source->on_demand)
-        {
-            DEBUG2 ("max on %s is %d", source->mount, source->max_listeners);
-            DEBUG2 ("pending %d, current %d", source->new_listeners, source->listeners);
-            if (source->max_listeners == -1)
-                break;
-            if (client->is_slave)
-                break;
-            if (source->new_listeners + source->listeners < source->max_listeners)
-                break;
-
-            INFO2 ("max listeners (%d) reached on %s", source->max_listeners, source->mount);
-            if (source->fallback_when_full == 0 || source->fallback_mount == NULL)
-            {
-                thread_mutex_unlock (&source->lock);
-                return -1;
-            }
-            if (source->fallback_mount)
-                mount = strdup (source->fallback_mount);
-            else
-                mount = NULL;
-        }
-
-        thread_mutex_unlock (&source->lock);
-    }
-
-    if (auth_check_client (source, client) != AUTH_OK)
-    {
-        thread_mutex_unlock (&source->lock);
-        INFO0 ("listener failed to authenticate");
-        return -2;
-    }
-    source->new_listeners++;
-
-    thread_mutex_unlock (&source->lock);
-    return 0;
-}
-
-
-void add_client (char *mount, client_t *client)
-{
-    int added = -3;
-
-    if (mount)
-    {
-        if (connection_check_relay_pass(client->parser))
-        {
-            client_as_slave (client);
-            INFO0 ("client connected as slave");
-        }
-        thread_mutex_lock (&move_clients_mutex);
-        avl_tree_rlock (global.source_tree);
-        added = _add_client (mount, client, 1);
-        avl_tree_unlock (global.source_tree);
-        thread_mutex_unlock (&move_clients_mutex);
-    }
-    switch (added)
-    {
-    case -1: 
-        /* there may be slaves we can re-direct to */
-        if (slave_redirect (mount, client))
-            break;
-        client_send_404 (client,
-                "Too many clients on this mountpoint. Try again later.");
-        DEBUG1 ("max clients on %s", mount);
-        break;
-    case -2:
-        client_send_401 (client);
-        break;
-    case -3:
-        client_send_404 (client, "The file you requested could not be found");
-        break;
-    default:
-        return;
-    }
-    /* failed client, drop global count */
-    global_lock();
-    global.clients--;
-    global_unlock();
-}
-
-
-static void process_pending_clients (source_t *source)
-{
-    unsigned count = 0;
-    client_t *client = source->pending_clients;
-
-    while (client)
-    {
-        client_t *to_go = client;
-
-        client = client->next;
-        /*  trap from when clients have been moved */
-        if (to_go->write_to_client == NULL)
-        {
-            /* trap for client moved to fallback file */
-            if (source->file_only)
-            {
-                to_go->write_to_client = format_intro_write_to_client;
-                client_set_queue (to_go, refbuf_new(4096));
-                to_go->intro_offset = 0;
-                to_go->pos = 4096;
-            }
-            else
-            {
-                to_go->write_to_client = source->format->write_buf_to_client;
-                client_set_queue (to_go, source->stream_data_tail);
-            }
-        }
-
-        to_go->next = source->active_clients;
-        source->active_clients = to_go;
-
-        count++;
-        source->new_listeners--;
-    }
-    source->pending_clients = NULL;
-    source->pending_clients_tail = &source->pending_clients;
-    source->check_pending = 0;
-
-    if (count)
-    {
-        DEBUG1("Adding %d client(s)", count);
-        source->listeners += count;
-        stats_event_args (source->mount, "listeners", "%d", source->listeners);
-    }
-}
-
-
-void source_main(source_t *source)
-{
     source_init (source);
 
     while (global.running == ICE_RUNNING && source->running)
@@ -1021,7 +850,7 @@
             remove_from_q = 1;
 
         /* add pending clients */
-        if (source->check_pending)
+        if (source->pending_clients)
             process_pending_clients (source);
 
         process_listeners (source, 0, remove_from_q);

Modified: icecast/branches/kh/icecast/src/source.h
===================================================================
--- icecast/branches/kh/icecast/src/source.h	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/source.h	2004-11-22 17:09:42 UTC (rev 8244)
@@ -42,10 +42,9 @@
     client_t *active_clients;
     client_t *first_normal_client;
 
-    int check_pending;
     client_t *pending_clients;
     client_t **pending_clients_tail;
-    long new_listeners;
+    unsigned int new_listeners;
 
     rwlock_t *shutdown_rwlock;
     util_dict *audio_info;
@@ -53,7 +52,7 @@
     char *dumpfilename; /* Name of a file to dump incoming stream to */
     FILE *dumpfile;
 
-    long listeners;
+    unsigned int listeners;
     long max_listeners;
     int yp_public;
     int yp_prevent;
@@ -104,8 +103,6 @@
 void source_move_clients (source_t *source, source_t *dest);
 int source_remove_client(void *key);
 void source_main(source_t *source);
-void add_client (char *mount, client_t *client);
-int add_authenticated_client (source_t *source, client_t *client);
 int source_free_client (source_t *source, client_t *client);
 void source_recheck_mounts (void);
 

Modified: icecast/branches/kh/icecast/src/stats.c
===================================================================
--- icecast/branches/kh/icecast/src/stats.c	2004-11-21 21:43:56 UTC (rev 8243)
+++ icecast/branches/kh/icecast/src/stats.c	2004-11-22 17:09:42 UTC (rev 8244)
@@ -239,10 +239,12 @@
     va_end(val);
 
     if (ret < 0 || (unsigned int)ret >= sizeof (buf))
+    {
         WARN2 ("problem with formatting %s stat %s",
                 source==NULL ? "global" : source, name);
-    else
-        stats_event(source, name, buf);
+        return;
+    }
+    stats_event(source, name, buf);
 }
 
 static char *_get_stats(char *source, char *name)



More information about the commits mailing list