[xiph-commits] r17364 - in icecast/branches/kh/icecast: . src win32

karl at svn.xiph.org karl at svn.xiph.org
Mon Aug 16 17:26:27 PDT 2010


Author: karl
Date: 2010-08-16 17:26:27 -0700 (Mon, 16 Aug 2010)
New Revision: 17364

Modified:
   icecast/branches/kh/icecast/NEWS
   icecast/branches/kh/icecast/config.h.vc6
   icecast/branches/kh/icecast/configure.in
   icecast/branches/kh/icecast/src/auth.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_mp3.c
   icecast/branches/kh/icecast/src/fserve.c
   icecast/branches/kh/icecast/src/slave.c
   icecast/branches/kh/icecast/src/stats.c
   icecast/branches/kh/icecast/win32/icecast2.iss
Log:
kh26 update. The 2 main issues are :- 

possible corruption with short-send of non-ogg metadata, specifically the
write merged block.
the slave stream listing was not honouring non-hidden attributes or auth

The smaller parts are mainly code re-organisation, a backward compatibility
option and options for IP handling.


Modified: icecast/branches/kh/icecast/NEWS
===================================================================
--- icecast/branches/kh/icecast/NEWS	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/NEWS	2010-08-17 00:26:27 UTC (rev 17364)
@@ -1,5 +1,6 @@
 Feature differences from SVN trunk
 
+. FLV wrapping for mp3/aac listeners requesting it with ?type=.flv
 . define a fixed number of worker threads (default 1) for processing clients
 . allow for wildcards (*[] expansion) in mount-name and ban/allow files
 . can limit mountpoint by outgoing bandwidth as well as a max listeners count
@@ -16,6 +17,17 @@
 any extra tags are show in the conf/icecast.xml.dist file
 
 
+2.3.2-kh26
+. fix possible content corruption on shoutcast metadata inserted streams if a short
+  send occurs during metadata sending.
+. do not list non-hidden streams in /admin/stream[list|streams] and make sure auth
+  applies to /admin/streams.
+. allow for the so-sndbuf option per-mount as well as on all connections.
+. old style bind-address setting (not listen-socket) was not working
+. allow a negative ban-client value to use the internal deny block of IPs to prevent
+  more than 1 IP connecting at the same time.
+. small code changes for main worker thread
+
 2.3.2-kh25
 . FLV clients could skip frames on a truncated write, leading to playback problems.
 . various client scheduling tunings, allows quicker reschedule when only some data

Modified: icecast/branches/kh/icecast/config.h.vc6
===================================================================
--- icecast/branches/kh/icecast/config.h.vc6	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/config.h.vc6	2010-08-17 00:26:27 UTC (rev 17364)
@@ -95,7 +95,7 @@
 #define PACKAGE_NAME "Icecast"
 
 /* Version number of package */
-#define VERSION "2.3.2-kh25"
+#define VERSION "2.3.2-kh26"
 
 /* Define to the version of this package. */
 #define PACKAGE_VERSION VERSION

Modified: icecast/branches/kh/icecast/configure.in
===================================================================
--- icecast/branches/kh/icecast/configure.in	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/configure.in	2010-08-17 00:26:27 UTC (rev 17364)
@@ -1,4 +1,4 @@
-AC_INIT([Icecast], [2.3.2-kh25], [karl at xiph.org])
+AC_INIT([Icecast], [2.3.2-kh26], [karl at xiph.org])
 
 LT_INIT
 AC_PREREQ(2.59)

Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/src/auth.c	2010-08-17 00:26:27 UTC (rev 17364)
@@ -412,6 +412,10 @@
 
     client->flags |= CLIENT_AUTHENTICATED;
 
+    /* some win32 setups do not do TCP win scaling well, so allow an override */
+    if (mountinfo && mountinfo->so_sndbuf > 0)
+        sock_set_send_buffer (client->connection.sock, mountinfo->so_sndbuf);
+
     /* check whether we are processing a streamlist request for slaves */
     if (strcmp (mount, "/admin/streams") == 0)
     {
@@ -534,10 +538,15 @@
     {
         if (mountinfo->skip_accesslog)
             client->flags |= CLIENT_SKIP_ACCESSLOG;
-        if (mountinfo->ban_client || mountinfo->no_mount)
+        if (mountinfo->ban_client)
         {
-            if (mountinfo->ban_client)
-                connection_add_banned_ip (client->connection.ip, mountinfo->ban_client);
+            DEBUG1 ("ban client value is %d", mountinfo->ban_client);
+            if (mountinfo->ban_client < 0)
+                client->flags |= CLIENT_IP_BAN_LIFT;
+            connection_add_banned_ip (client->connection.ip, mountinfo->ban_client);
+        }
+        if (mountinfo->no_mount)
+        {
             config_release_config ();
             client_send_403 (client, "mountpoint unavailable");
             return;
@@ -562,7 +571,10 @@
     }
     else
     {
-        add_authenticated_listener (mount, mountinfo, client);
+        if (client->flags & CLIENT_AUTHENTICATED)
+            add_authenticated_listener (mount, mountinfo, client);
+        else
+            client_send_403 (client, "Forbidden");
     }
     config_release_config ();
 }

Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/src/cfgfile.c	2010-08-17 00:26:27 UTC (rev 17364)
@@ -792,6 +792,7 @@
                                 config_get_bool,    &mount->url_ogg_meta },
         { "no-mount",           config_get_bool,    &mount->no_mount },
         { "ban-client",         config_get_int,     &mount->ban_client },
+        { "so-sndbuf",          config_get_int,     &mount->so_sndbuf },
         { "hidden",             config_get_bool,    &mount->hidden },
         { "authentication",     auth_get_authenticator, &mount->auth },
         { "on-connect",         config_get_str,     &mount->on_connect },
@@ -842,7 +843,9 @@
     if (mount->url_ogg_meta)
         mount->ogg_passthrough = 0;
     if (mount->queue_block_size < 100)
-        mount->queue_block_size = 2900;
+        mount->queue_block_size = 1400;
+    if (mount->ban_client < 0)
+        mount->no_mount = 0;
 
     mount->next = config->mounts;
     config->mounts = mount;
@@ -1061,6 +1064,7 @@
 
 static int _parse_root (xmlNodePtr node, ice_config_t *config)
 {
+    char *bindaddress = NULL;
     struct cfg_tag icecast_tags[] =
     {
         { "location",           config_get_str,     &config->location },
@@ -1070,6 +1074,7 @@
         { "source-password",    config_get_str,     &config->source_password },
         { "hostname",           config_get_str,     &config->hostname },
         { "port",               config_get_int,     &config->port },
+        { "bind-address",       config_get_str,     &bindaddress },
         { "fileserve",          config_get_bool,    &config->fileserve },
         { "relays-on-demand",   config_get_bool,    &config->on_demand },
         { "master-server",      config_get_str,     &config->master_server },
@@ -1104,8 +1109,22 @@
         config->max_redirects = 1;
     if (config->listen_sock_count == 0)
     {
-        WARN0 ("No listen-socket defintions");
-        return -1;
+        if (config->port)
+        {
+            listener_t *listener = calloc (1, sizeof(listener_t));
+            listener->refcount = 1;
+            listener->port = config->port;
+            listener->qlen = ICE_LISTEN_QUEUE;
+            listener->bind_address = (char*)xmlStrdup (XMLSTR(bindaddress));
+            listener->next = config->listen_sock;
+            config->listen_sock = listener;
+            config->listen_sock_count++;
+        }
+        else
+        {
+            WARN0 ("No listen-socket defintions");
+            return -1;
+        }
     }
     return 0;
 }

Modified: icecast/branches/kh/icecast/src/cfgfile.h
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.h	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/src/cfgfile.h	2010-08-17 00:26:27 UTC (rev 17364)
@@ -101,6 +101,7 @@
     int ban_client;     /* do we add a client on this to the ban list automatically */
     int no_mount; /* Do we permit direct requests of this mountpoint? (or only
                      indirect, through fallbacks) */
+    int so_sndbuf;      /* TCP send buffer size for new clients */
     int burst_size; /* amount to send to a new client if possible, -1 take
                      * from global setting */
     unsigned int queue_size_limit;

Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/src/client.c	2010-08-17 00:26:27 UTC (rev 17364)
@@ -101,6 +101,13 @@
     if (client->respcode > 0 && client->parser)
         logging_access(client);
 
+    if (client->flags & CLIENT_IP_BAN_LIFT)
+    {
+        INFO1 ("lifting IP ban on client at %s", client->connection.ip);
+        connection_release_banned_ip (client->connection.ip);
+        client->flags &= ~CLIENT_IP_BAN_LIFT;
+    }
+
     connection_close (&client->connection);
     if (client->parser)
         httpp_destroy (client->parser);
@@ -372,6 +379,7 @@
     worker_wakeup (handler);
 }
 
+
 #ifdef _WIN32
 #define pipe_create         sock_create_pipe_emulation
 #define pipe_write(A, B, C) send(A, B, C, 0)
@@ -382,27 +390,7 @@
 #define pipe_read read
 #endif
 
-static void worker_move_clients (worker_t *from)
-{
-    client_t *client = from->clients;
 
-    if (workers == NULL || from == NULL || workers->running == 0)
-        return;
-    while (client)
-    {
-        client->worker = workers;
-        client = client->next_on_worker;
-    }
-    thread_spin_lock (&workers->lock);
-    *workers->pending_clients_tail = from->clients;
-    workers->pending_clients_tail = from->last_p;
-    workers->pending_count += from->count;
-    thread_spin_unlock (&workers->lock);
-    from->count = 0;
-    from->clients = NULL;
-    from->last_p = &from->clients;
-}
-
 static void worker_add_pending_clients (worker_t *worker)
 {
     if (worker && worker->pending_clients)
@@ -440,87 +428,113 @@
     worker_add_pending_clients (worker);
 
     worker->time_ms = timing_get_time();
-    worker->current_time.tv_sec = worker->time_ms/1000;
+    worker->current_time.tv_sec = (time_t)(worker->time_ms/1000);
     worker->current_time.tv_nsec = worker->current_time.tv_sec - (worker->time_ms*1000);
     worker->wakeup_ms = worker->time_ms + 60000;
 }
 
 
+static void worker_relocate_clients (worker_t *worker)
+{
+    if (workers == NULL)
+        return;
+    while (worker->count || worker->pending_count)
+    {
+        client_t *client = worker->clients, **prevp = &worker->clients;
+
+        worker->wakeup_ms = worker->time_ms + 150;
+        while (client)
+        {
+            if (client->flags & CLIENT_ACTIVE)
+            {
+                client->worker = workers;
+                prevp = &client->next_on_worker;
+            }
+            else
+            {
+                *prevp = client->next_on_worker;
+                worker_add_client (worker, client);
+                worker->count--;
+            }
+            client = *prevp;
+        }
+        if (worker->clients)
+        {
+            thread_spin_lock (&workers->lock);
+            *workers->pending_clients_tail = worker->clients;
+            workers->pending_clients_tail = prevp;
+            workers->pending_count += worker->count;
+            thread_spin_unlock (&workers->lock);
+            worker_wakeup (workers);
+            worker->clients = NULL;
+            worker->last_p = &worker->clients;
+            worker->count = 0;
+        }
+        worker_wait (worker);
+    }
+}
+
 void *worker (void *arg)
 {
-    worker_t *handler = arg;
-    client_t *client, **prevp;
+    worker_t *worker = arg;
     long prev_count = -1;
 
-    handler->running = 1;
-    handler->wakeup_ms = (int64_t)0;
-    prevp = &handler->clients;
+    worker->running = 1;
+    worker->wakeup_ms = (int64_t)0;
+
     while (1)
     {
-        if (handler->running == 0)
+        client_t *client = worker->clients, **prevp = &worker->clients;
+
+        if (prev_count != worker->count)
         {
-            handler->wakeup_ms = handler->time_ms + 50;
-            worker_add_pending_clients (handler);
-            if (handler->count == 0)
-                break;
-            worker_move_clients (handler);
+            DEBUG2 ("%p now has %d clients", worker, worker->count);
+            prev_count = worker->count;
         }
-        if (prev_count != handler->count)
-        {
-            DEBUG2 ("%p now has %d clients", handler, handler->count);
-            prev_count = handler->count;
-        }
-
-        worker_wait (handler);
-        client = handler->clients;
-        prevp = &handler->clients;
         while (client)
         {
-            if (client->worker != handler)
-                abort();
+            if (client->worker != worker) abort();
             /* process client details but skip those that are not ready yet */
             if (client->flags & CLIENT_ACTIVE)
             {
-                if (client->schedule_ms <= handler->time_ms+10)
+                int ret = 0;
+                client_t *nx = client->next_on_worker;
+
+                if (client->schedule_ms <= worker->time_ms+10)
                 {
-                    int ret;
-                    client_t *nx = client->next_on_worker;
-
-                    client->schedule_ms = handler->time_ms;
+                    client->schedule_ms = worker->time_ms;
                     ret = client->ops->process (client);
-
-                    /* special handler, client has moved away to another worker */
-                    if (ret > 0)
-                    {
-                        handler->count--;
-                        if (nx == NULL) /* moved last client */
-                            handler->last_p = prevp;
-                        *prevp = nx;
-                        client = nx;
-                        continue;
-                    }
                     if (ret < 0)
                     {
-                        client_t *to_go = client;
-                        *prevp = to_go->next_on_worker;
-                        client->next_on_worker = NULL;
                         client->worker = NULL;
-                        handler->count--;
                         if (client->ops->release)
                             client->ops->release (client);
-                        client = *prevp;
-                        if (client == NULL)
-                            handler->last_p = prevp;
+                    }
+                    if (ret)
+                    {
+                        worker->count--;
+                        if (nx == NULL) /* is this the last client */
+                            worker->last_p = prevp;
+                        client = *prevp = nx;
                         continue;
                     }
                 }
-                if (client->schedule_ms < handler->wakeup_ms)
-                    handler->wakeup_ms = client->schedule_ms;
+                if (client->schedule_ms < worker->wakeup_ms)
+                    worker->wakeup_ms = client->schedule_ms;
             }
             prevp = &client->next_on_worker;
             client = *prevp;
         }
+        if (worker->running == 0)
+        {
+            if (global.running == ICE_RUNNING)
+                break;
+            if (worker->count == 0 && worker->pending_count == 0)
+                break;
+        }
+        worker_wait (worker);
     }
+    worker_relocate_clients (worker);
     INFO0 ("shutting down");
     return NULL;
 }

Modified: icecast/branches/kh/icecast/src/client.h
===================================================================
--- icecast/branches/kh/icecast/src/client.h	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/src/client.h	2010-08-17 00:26:27 UTC (rev 17364)
@@ -149,6 +149,7 @@
 #define CLIENT_HAS_INTRO_CONTENT    (040)
 #define CLIENT_SKIP_ACCESSLOG       (0100)
 #define CLIENT_HAS_MOVED            (0200)
+#define CLIENT_IP_BAN_LIFT          (0400)
 #define CLIENT_FORMAT_BIT           (01000)
 
 #endif  /* __CLIENT_H__ */

Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/src/connection.c	2010-08-17 00:26:27 UTC (rev 17364)
@@ -356,7 +356,7 @@
 
 void connection_add_banned_ip (const char *ip, int duration)
 {
-    time_t timeout = -1;
+    time_t timeout = 0;
     if (duration > 0)
         timeout = time(NULL) + duration;
 
@@ -368,6 +368,16 @@
     }
 }
 
+void connection_release_banned_ip (const char *ip)
+{
+    if (banned_ip.contents)
+    {
+        global_lock();
+        avl_delete (banned_ip.contents, (void*)ip, free_filtered_line);
+        global_unlock();
+    }
+}
+
 void connection_stats (void)
 {
     if (banned_ip.contents)

Modified: icecast/branches/kh/icecast/src/connection.h
===================================================================
--- icecast/branches/kh/icecast/src/connection.h	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/src/connection.h	2010-08-17 00:26:27 UTC (rev 17364)
@@ -61,6 +61,7 @@
 int  connection_complete_source (struct source_tag *source);
 void connection_uses_ssl (connection_t *con);
 void connection_add_banned_ip (const char *ip, int duration);
+void connection_release_banned_ip (const char *ip);
 void connection_stats (void);
 #ifdef HAVE_OPENSSL
 int  connection_read_ssl (connection_t *con, void *buf, size_t len);

Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/src/format_mp3.c	2010-08-17 00:26:27 UTC (rev 17364)
@@ -342,31 +342,43 @@
     /* If there is a change in metadata then send it else
      * send a single zero value byte in its place
      */
-    if (associated && associated != client_mp3->associated)
+    if (client->flags & CLIENT_IN_METADATA)
     {
-        metadata = associated->data + client_mp3->metadata_offset;
-        meta_len = associated->len - client_mp3->metadata_offset;
-        client->flags &= ~CLIENT_USING_BLANK_META;
-        refbuf_release (client_mp3->associated);
-        refbuf_addref (associated);
-        client_mp3->associated = associated;
+        /* rare but possible case of resuming a send part way through a metadata block */
+        metadata = client_mp3->associated->data + client_mp3->metadata_offset;
+        meta_len = client_mp3->associated->len - client_mp3->metadata_offset;
     }
     else
     {
-        if (associated || ((client->flags & CLIENT_USING_BLANK_META) &&
-                    client_mp3->metadata_offset == 0))
+        if (associated && associated != client_mp3->associated)
         {
-            metadata = "\0";
-            meta_len = 1;
+            /* change of metadata found, but we do not release the blank one as that
+             * could race against the source client use of it. */
+            metadata = associated->data;
+            meta_len = associated->len;
+            if (client->flags & CLIENT_USING_BLANK_META)
+                client->flags &= ~CLIENT_USING_BLANK_META;
+            else
+                refbuf_release (client_mp3->associated);
+            refbuf_addref (associated);
+            client_mp3->associated = associated;
         }
         else
         {
-            char *meta = blank_meta.data;
-            metadata = meta + client_mp3->metadata_offset;
-            meta_len = blank_meta.len - client_mp3->metadata_offset;
-            client->flags |= CLIENT_USING_BLANK_META;
-            refbuf_release (client_mp3->associated);
-            client_mp3->associated = NULL;
+            if (associated) /* previously sent metadata does not need to be sent again */
+            {
+                metadata = "\0";
+                meta_len = 1;
+            }
+            else
+            {
+                char *meta = blank_meta.data;
+                metadata = meta + client_mp3->metadata_offset;
+                meta_len = blank_meta.len - client_mp3->metadata_offset;
+                client->flags |= CLIENT_USING_BLANK_META;
+                refbuf_release (client_mp3->associated);
+                client_mp3->associated = &blank_meta;
+            }
         }
     }
     /* if there is normal stream data to send as well as metadata then try
@@ -389,6 +401,8 @@
                 client->flags |= CLIENT_IN_METADATA;
                 client->schedule_ms += 200;
             }
+            else
+                client->flags &= ~CLIENT_IN_METADATA;
             client_mp3->since_meta_block = 0;
             client->pos += remaining;
             client->queue_pos += remaining;
@@ -401,6 +415,7 @@
             client->pos += ret;
             client->queue_pos += ret;
         }
+        client->flags |= CLIENT_IN_METADATA;
         return ret > 0 ? ret : 0;
     }
     ret = client_send_bytes (client, metadata, meta_len);
@@ -434,15 +449,6 @@
 
     do
     {
-        /* send any unwritten metadata to the client */
-        if (client->flags & CLIENT_IN_METADATA)
-        {
-            ret = send_stream_metadata (client, refbuf, 0);
-
-            if (client->flags & CLIENT_IN_METADATA)
-                break;
-            written += ret;
-        }
         /* see if we need to send the current metadata to the client */
         if (client_mp3->interval)
         {
@@ -459,6 +465,7 @@
                 len -= remaining;
                 if (ret <= (int)remaining || len > client_mp3->interval)
                     break;
+                written += ret;
             }
         }
         /* write any mp3, maybe after the metadata block */

Modified: icecast/branches/kh/icecast/src/fserve.c
===================================================================
--- icecast/branches/kh/icecast/src/fserve.c	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/src/fserve.c	2010-08-17 00:26:27 UTC (rev 17364)
@@ -677,6 +677,7 @@
 {
     refbuf_t *refbuf = client->refbuf;
     int loop = 6, bytes, written = 0;
+    worker_t *worker = client->worker;
 
     while (loop)
     {
@@ -733,15 +734,15 @@
             bytes = client->check_buffer (client);
         if (bytes < 0)
         {
-            client->schedule_ms = client->worker->time_ms + 300;
+            client->schedule_ms = worker->time_ms + 300;
             return 0;
         }
         written += bytes;
-        global_add_bitrates (global.out_bitrate, bytes, client->worker->time_ms);
+        global_add_bitrates (global.out_bitrate, bytes, worker->time_ms);
         if (written > 30000)
             break;
     }
-    client->schedule_ms = client->worker->time_ms + 100;
+    client->schedule_ms = worker->time_ms + 100;
     return 0;
 }
 
@@ -774,9 +775,11 @@
     refbuf_t *refbuf = client->refbuf;
     int loop = 6, bytes, written = 0, ret = 0;
     fh_node *fh = client->shared_data;
-    time_t now = client->worker->current_time.tv_sec;
+    worker_t *worker = client->worker;
+    time_t now;
 
-    client->schedule_ms = client->worker->time_ms;
+    client->schedule_ms = worker->time_ms;
+    now = worker->current_time.tv_sec;
     /* slowdown if max bandwidth is exceeded, but allow for short-lived connections to avoid 
      * this, eg admin requests */
     if (throttle_sends > 1 && now - client->connection.con_time > 1)
@@ -816,13 +819,17 @@
     refbuf_t *refbuf = client->refbuf;
     int  bytes;
     fh_node *fh = client->shared_data;
-    time_t now = client->worker->current_time.tv_sec;
-    unsigned long secs = now - client->timer_start; 
-    unsigned int  rate = secs ? ((client->counter+1400)/secs) : 0;
+    time_t now;
+    worker_t *worker = client->worker;
+    unsigned long secs; 
+    unsigned int  rate = 0;
     unsigned int limit = fh->finfo.limit;
 
     if (fserve_running == 0 || client->connection.error)
         return -1;
+    now = worker->current_time.tv_sec;
+    secs = now - client->timer_start; 
+    client->schedule_ms = worker->time_ms;
     if (client->connection.discon_time && now >= client->connection.discon_time)
         return -1;
     if (fh->finfo.fallback)
@@ -830,15 +837,17 @@
         fserve_move_listener (client);
         return 0;
     }
-    thread_mutex_lock (&fh->lock);
     if (client->flags & CLIENT_WANTS_FLV) /* increase limit for flv clients as wrapping takes more space */
         limit = (unsigned long)(limit * 1.02);
+    if (secs)
+        rate = (client->counter+1400)/secs;
+    thread_mutex_lock (&fh->lock);
     if (rate > limit)
     {
-        client->schedule_ms = client->worker->time_ms + (1000*(rate - fh->finfo.limit))/fh->finfo.limit;
-        rate_add (fh->format->out_bitrate, 0, client->worker->time_ms);
+        client->schedule_ms += (1000*(rate - limit))/limit;
+        rate_add (fh->format->out_bitrate, 0, worker->time_ms);
         thread_mutex_unlock (&fh->lock);
-        global_add_bitrates (global.out_bitrate, 0, client->worker->time_ms);
+        global_add_bitrates (global.out_bitrate, 0, worker->time_ms);
         return 0;
     }
     if (fh->stats_update <= now)
@@ -855,7 +864,7 @@
             thread_mutex_unlock (&fh->lock);
             client->intro_offset = 0;
             client->pos = refbuf->len = 0;
-            client->schedule_ms = client->worker->time_ms + 150;
+            client->schedule_ms += 150;
             return 0;
         }
         client->pos = 0;
@@ -863,11 +872,11 @@
     bytes = client->check_buffer (client);
     if (bytes < 0)
         bytes = 0;
-    rate_add (fh->format->out_bitrate, bytes, client->worker->time_ms);
+    rate_add (fh->format->out_bitrate, bytes, worker->time_ms);
     thread_mutex_unlock (&fh->lock);
-    global_add_bitrates (global.out_bitrate, bytes, client->worker->time_ms);
+    global_add_bitrates (global.out_bitrate, bytes, worker->time_ms);
     client->counter += bytes;
-    client->schedule_ms = client->worker->time_ms + (1000/(fh->finfo.limit/1400*2));
+    client->schedule_ms += (1000/(limit/1400*2));
 
     /* progessive slowdown if max bandwidth is exceeded. */
     if (throttle_sends > 1)

Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/src/slave.c	2010-08-17 00:26:27 UTC (rev 17364)
@@ -1345,6 +1345,7 @@
 static int relay_startup (client_t *client)
 {
     relay_server *relay = get_relay_details (client);
+    worker_t *worker = client->worker;
 
     if (relay->cleanup)
     {
@@ -1356,7 +1357,7 @@
     }
     if (global.running != ICE_RUNNING)
         return 0; /* wait for cleanup */
-    if (relay->running == 0 || relay->start > client->worker->current_time.tv_sec)
+    if (relay->running == 0 || relay->start > worker->current_time.tv_sec)
     {
         client->schedule_ms = client->worker->time_ms + 1000;
         return 0;
@@ -1368,7 +1369,7 @@
         int start_relay = src->listeners; // 0 or non-zero
 
         src->flags |= SOURCE_ON_DEMAND;
-        if (client->worker->current_time.tv_sec % 10 == 0)
+        if (worker->current_time.tv_sec % 10 == 0)
         {
             mount_proxy * mountinfo = config_find_mount (config_get_config(), src->mount);
             if (mountinfo && mountinfo->fallback_mount)

Modified: icecast/branches/kh/icecast/src/stats.c
===================================================================
--- icecast/branches/kh/icecast/src/stats.c	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/src/stats.c	2010-08-17 00:26:27 UTC (rev 17364)
@@ -1103,7 +1103,7 @@
         int ret;
         stats_source_t *source = (stats_source_t *)node->key;
 
-        if (source->flags & STATS_SLAVE)
+        if ((source->flags & STATS_HIDDEN) == 0)
         {
             if (remaining <= strlen (source->source) + prelen + 3)
             {

Modified: icecast/branches/kh/icecast/win32/icecast2.iss
===================================================================
--- icecast/branches/kh/icecast/win32/icecast2.iss	2010-08-17 00:18:22 UTC (rev 17363)
+++ icecast/branches/kh/icecast/win32/icecast2.iss	2010-08-17 00:26:27 UTC (rev 17364)
@@ -3,7 +3,7 @@
 
 [Setup]
 AppName=Icecast2-KH
-AppVerName=Icecast v2.3.2-kh25
+AppVerName=Icecast v2.3.2-kh26
 AppPublisherURL=http://www.icecast.org
 AppSupportURL=http://www.icecast.org
 AppUpdatesURL=http://www.icecast.org
@@ -13,7 +13,7 @@
 LicenseFile=..\COPYING
 InfoAfterFile=..\README
 OutputDir=.
-OutputBaseFilename=icecast2_win32_v2.3.2-kh25_setup
+OutputBaseFilename=icecast2_win32_v2.3.2-kh26
 WizardImageFile=icecast2logo2.bmp
 WizardImageStretch=no
 VersionInfoVersion=2.3.2
@@ -68,4 +68,3 @@
 [UninstallRun]
 Filename: "{app}\icecastService.exe"; Parameters: "remove"
 
-



More information about the commits mailing list