Bug in handling fallback-override clients + patch
Mart van Santen <[email protected]>
| Newsgroups | gmane.comp.audio.icecast.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello,
I noticed a bug in the fallback-override handling in icecast 2.3.3. The
bug is as follows:
We use icecast for distributing a continuous radio stream, let's call
this stream "live", with mountpoint "/live"
In our usecase we have a second audio stream, called "event". This
stream is only online when there is a special event. This is on
mountpoint "/event".
Because we want the "event" stream also to be available, also when there
is no event, we've defined an fallback for the 'event' stream to 'live',
as follows:
<mount>
<mount-name>/event</mount-name>
<fallback-mount>/live</fallback-mount>
<fallback-override>1</fallback-override>
</mount>
The expected behavior, when a user is listening to /event, it will
stream /live, and once the event stream is up, the user will be moved to
the special 'event' stream.
This is working fine.
The problem is, icecast is moving 'all' users on '/live' to '/event',
once the event stream get's up.
Also the users who started on '/live' and not to the special '/event'
stream.
The bug is that icecast should not move back users who started on the
'/live' stream, but only users who started listing to the '/event' stream.
I've attached a patch to this e-mail to solve this bug. Unforunally my C
is not very well developed, so I hope I didn't make any pointer or
buffer-overflow errors.
They idea is to store the original requested mountpoint in the client's
structure. Once a fallback-override happens, we check with a strcmp if
the client should be moved back. If not, we leave the client on the
current stream.
I tested this code for correct behavior with 6 clients on two streams.
This works all fine, with starting/stopping the source stream "event"
and opening/closing streams.
I hope you can patch this upstream as well.
Kind regards,
Mart van Santen
--
Mart van Santen
Greenhost
E: [email protected]
T: +31204890444
A: Weesperstraat 3, Amsterdam, Netherlands
A PGP signature can be attached to this e-mail,
you need PGP software to verify it.
My public key is available in keyserver(s)
see: http://tinyurl.com/openpgp-manual
PGP Fingerprint: CA85 EB11 2B70 042D AF66 B29A 6437 01A1 10A3 D3A5
_______________________________________________
Icecast-dev mailing list
[email protected]
http://lists.xiph.org/mailman/listinfo/icecast-dev
fallback-override-org-stream-only.patch
(text/x-patch, 6.4 KB)
diff -u -r icecast-2.3.3.org/src/admin.c icecast-2.3.3/src/admin.c
--- icecast-2.3.3.org/src/admin.c 2012-06-11 18:45:20.000000000 +0200
+++ icecast-2.3.3/src/admin.c 2013-06-14 06:54:16.046904972 +0200
@@ -622,7 +622,7 @@
node = xmlNewDocNode(doc, NULL, XMLSTR("iceresponse"), NULL);
xmlDocSetRootElement(doc, node);
- source_move_clients (source, dest);
+ source_move_clients (source, dest, 0);
memset(buf, '\000', sizeof(buf));
snprintf (buf, sizeof(buf), "Clients moved from %s to %s",
diff -u -r icecast-2.3.3.org/src/auth.c icecast-2.3.3/src/auth.c
--- icecast-2.3.3.org/src/auth.c 2012-06-11 18:45:20.000000000 +0200
+++ icecast-2.3.3/src/auth.c 2013-06-14 11:24:45.448146436 +0200
@@ -447,6 +449,10 @@
return 0;
}
+ /* Save requested mountpoint in client pointer. We use this to know how
+ to handle failover-override to back users back to original
+ audiostream */
+ client->mountpoint = strdup (mount);
avl_tree_rlock (global.source_tree);
source = source_find_mount (mount);
diff -u -r icecast-2.3.3.org/src/client.h icecast-2.3.3/src/client.h
--- icecast-2.3.3.org/src/client.h 2012-06-11 18:45:20.000000000 +0200
+++ icecast-2.3.3/src/client.h 2013-06-14 06:46:24.863767986 +0200
@@ -47,6 +47,9 @@
/* auth used for this client */
struct auth_tag *auth;
+ /* Client's original mountpoint */
+ char *mountpoint;
+
/* Client username, if authenticated */
char *username;
diff -u -r icecast-2.3.3.org/src/slave.c icecast-2.3.3/src/slave.c
--- icecast-2.3.3.org/src/slave.c 2012-06-11 18:45:20.000000000 +0200
+++ icecast-2.3.3/src/slave.c 2013-06-14 06:54:29.731000202 +0200
@@ -361,7 +361,7 @@
fallback_source = source_find_mount (relay->source->fallback_mount);
if (fallback_source != NULL)
- source_move_clients (relay->source, fallback_source);
+ source_move_clients (relay->source, fallback_source,0);
avl_tree_unlock (global.source_tree);
}
diff -u -r icecast-2.3.3.org/src/source.c icecast-2.3.3/src/source.c
--- icecast-2.3.3.org/src/source.c 2012-06-11 18:45:20.000000000 +0200
+++ icecast-2.3.3/src/source.c 2013-06-14 10:24:12.922495076 +0200
@@ -338,7 +338,7 @@
* The only lock that should be held when this is called is the
* source tree lock
*/
-void source_move_clients (source_t *source, source_t *dest)
+void source_move_clients (source_t *source, source_t *dest, int override)
{
unsigned long count = 0;
if (strcmp (source->mount, dest->mount) == 0)
@@ -382,13 +382,38 @@
break;
}
}
-
+
while (1)
{
+ /* Get first node in tree */
avl_node *node = avl_get_first (source->pending_tree);
if (node == NULL)
break;
client = (client_t *)(node->key);
+
+
+ /* override flag: set when return to original source getting back */
+ if (override == 1) {
+
+ /* check original mountpoint */
+ while (strcmp(client->mountpoint, dest->mount) != 0) {
+ WARN2("client came not form this source, so not moving (client mountpoint: %s and fallback mountmout: %s)", client->mountpoint, dest->mount);
+ /* get next node */
+ node = avl_get_next(node);
+
+ if (node == NULL)
+ break;
+
+ client = (client_t *)(node->key);
+ }
+ }
+
+
+ if (node == NULL)
+ break;
+
+
+
avl_delete (source->pending_tree, client, NULL);
/* when switching a client to a different queue, be wary of the
@@ -402,7 +427,6 @@
if (source->con == NULL)
client->intro_offset = -1;
}
-
avl_insert (dest->pending_tree, (void *)client);
count++;
}
@@ -412,8 +436,28 @@
avl_node *node = avl_get_first (source->client_tree);
if (node == NULL)
break;
-
client = (client_t *)(node->key);
+
+ /* override flag: set when return to original source getting back */
+ if (override == 1) {
+
+ /* check original mountpoint */
+ while (strcmp(client->mountpoint, dest->mount) != 0) {
+ WARN2("client came not form this source, so not moving (client mountpoint: %s and fallback mountmout: %s)", client->mountpoint, dest->mount);
+ /* get next node */
+ node = avl_get_next(node);
+
+ if (node == NULL)
+ break;
+
+ client = (client_t *)(node->key);
+ }
+ }
+
+
+ if (node == NULL)
+ break;
+
avl_delete (source->client_tree, client, NULL);
/* when switching a client to a different queue, be wary of the
@@ -427,12 +471,13 @@
if (source->con == NULL)
client->intro_offset = -1;
}
+
avl_insert (dest->pending_tree, (void *)client);
count++;
}
INFO2 ("passing %lu listeners to \"%s\"", count, dest->mount);
- source->listeners = 0;
+ source->listeners = source->listeners - count;
stats_event (source->mount, "listeners", "0");
} while (0);
@@ -659,7 +704,7 @@
fallback_source = source_find_mount(source->fallback_mount);
if (fallback_source)
- source_move_clients (fallback_source, source);
+ source_move_clients (fallback_source, source, 1);
avl_tree_unlock(global.source_tree);
}
@@ -861,7 +906,7 @@
fallback_source = source_find_mount (source->fallback_mount);
if (fallback_source != NULL)
- source_move_clients (source, fallback_source);
+ source_move_clients (source, fallback_source, 0);
avl_tree_unlock (global.source_tree);
}
diff -u -r icecast-2.3.3.org/src/source.h icecast-2.3.3/src/source.h
--- icecast-2.3.3.org/src/source.h 2012-06-11 18:45:20.000000000 +0200
+++ icecast-2.3.3/src/source.h 2013-06-14 06:55:04.363238171 +0200
@@ -89,7 +89,7 @@
client_t *source_find_client(source_t *source, int id);
int source_compare_sources(void *arg, void *a, void *b);
void source_free_source(source_t *source);
-void source_move_clients (source_t *source, source_t *dest);
+void source_move_clients (source_t *source, source_t *dest, int override);
int source_remove_client(void *key);
void source_main(source_t *source);
void source_recheck_mounts (int update_all);
signature.asc
(application/pgp-signature, 555 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJRuu2mAAoJEGQ3AaEQo9Ol2msH/1u+jO00ArHT01YbNar3fu/n JSbqYSLqdoIYQfZhrYEugQqQJvFqWwc+NgTtTdDUur12yFPW48OweIeQbENinsK0 XpS+A+nHGNeEVW+oBnT7p6R22w8JyOmcxLmvDuyhai+YPs+8aKjvAWEacxzw9wDn lRgw/ko2RHnkzOUEFs3nlnVb4O60Kc8/2Lwt6y/tAFcqCuhzHzfk5iiAOMfit9Vy Zug20Ps7FWOQyZ548MzQsH2mszLvBW4laekNguSj9iDEtQHjGRkUvK6xWLMhIP0+ Is84OKDJGKDttYRJAdmX74bJAyPGLY0rD2CDttJT2Fmw4BkCg7GliXcX2+hgeqY= =aUoT -----END PGP SIGNATURE-----