[xiph-commits] r7659 - in icecast/branches/kh/icecast: conf doc src
karl at motherfish-iii.xiph.org
karl at motherfish-iii.xiph.org
Sun Aug 29 08:17:15 PDT 2004
Author: karl
Date: 2004-08-29 08:17:14 -0700 (Sun, 29 Aug 2004)
New Revision: 7659
Modified:
icecast/branches/kh/icecast/conf/icecast.xml.in
icecast/branches/kh/icecast/doc/icecast2_config_file.html
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/global.h
icecast/branches/kh/icecast/src/slave.c
icecast/branches/kh/icecast/src/slave.h
icecast/branches/kh/icecast/src/source.c
Log:
build the slave host list by using the connecting relay-authenticated master relays
instead of using the xml. Update docs and example xml
Modified: icecast/branches/kh/icecast/conf/icecast.xml.in
===================================================================
--- icecast/branches/kh/icecast/conf/icecast.xml.in 2004-08-28 20:42:10 UTC (rev 7658)
+++ icecast/branches/kh/icecast/conf/icecast.xml.in 2004-08-29 15:17:14 UTC (rev 7659)
@@ -58,19 +58,6 @@
</listen-socket>
-->
- <!-- when full, redirect listeners to the listed slaves -->
- <!--
- <slave-host>
- <server>somehost.com</server>
- <port>8000</port>
- </slave-host>
-
- <slave-host>
- <server>someotherhost.com</server>
- <port>8000</port>
- </slave-host>
- -->
-
<!--<relays-on-demand>1</relays-on-demand>-->
<!--<master-server>127.0.0.1</master-server>-->
<!--<master-server-port>8001</master-server-port>-->
@@ -78,6 +65,10 @@
<!--<master-password>hackme</master-password>-->
<!--<master-relay-auth>1</master-relay-auth>-->
+ <!-- Report <hostname> and this port to master server for redirecting
+ clients to this slave -->
+ <!--<master-redirect-port>8000</master-redirect-port>-->
+
<!-- Relays. State connection information, and by default
request inline metadata for mp3 streams if available.
An on-demand relay will only retrieve the stream if
Modified: icecast/branches/kh/icecast/doc/icecast2_config_file.html
===================================================================
--- icecast/branches/kh/icecast/doc/icecast2_config_file.html 2004-08-28 20:42:10 UTC (rev 7658)
+++ icecast/branches/kh/icecast/doc/icecast2_config_file.html 2004-08-29 15:17:14 UTC (rev 7659)
@@ -215,10 +215,23 @@
<div class=indentedbox>
The interval (in seconds) that the Relay Server will poll the Master Server for any new mountpoints to relay.
</div>
+<h4>master-username</h4>
+<div class=indentedbox>
+This is the username to authenticate with the master. The default is "relay". This is used to
+get hold of the streamlist and can be used to authenticate master relays. The master server
+will compare with the relay-user.
+</div>
<h4>master-password</h4>
<div class=indentedbox>
-This is the admin password on the Master server. It is used to query the server for a list of mountpoints to relay.
+As with master-username, this is the password to authenticate with the master server. The
+relay-password on the master server is used for comparison.
</div>
+<h4>master-redirect-port</h4>
+<div class=indentedbox>
+When a slave starts a master relay using authentication, then a host and port can also be sent to
+inform the master for the purposes of redirecting clients to the slave. The host is provided by
+the hostname setting and this specifies the port to redirect listeners to.
+</div>
<h4>relays-on-demand</h4>
<div class=indentedbox>
Changes the default on-demand setting, so a stream is only relayed if listeners are connected.
Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c 2004-08-28 20:42:10 UTC (rev 7658)
+++ icecast/branches/kh/icecast/src/cfgfile.c 2004-08-29 15:17:14 UTC (rev 7659)
@@ -77,7 +77,6 @@
static void _parse_security(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *c);
-static void _parse_slave_host(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
@@ -119,7 +118,6 @@
relay_server *relay, *nextrelay;
mount_proxy *mount, *nextmount;
aliases *alias, *nextalias;
- slave_host *slave;
int i;
config_options_t *option;
@@ -221,14 +219,6 @@
free(dirnode);
dirnode = nextdirnode;
}
- slave = c->slave_list;
- while (slave)
- {
- slave_host *to_go = slave;
- slave = slave->next;
- xmlFree (to_go->server);
- free (to_go);
- }
#ifdef HAVE_YP
i = 0;
while (i < c->num_yp_directories)
@@ -348,6 +338,7 @@
configuration->master_username = NULL;
configuration->master_password = NULL;
configuration->master_relay_auth = 0;
+ configuration->master_redirect_port = 0;
configuration->base_dir = CONFIG_DEFAULT_BASE_DIR;
configuration->log_dir = CONFIG_DEFAULT_LOG_DIR;
configuration->webroot_dir = CONFIG_DEFAULT_WEBROOT_DIR;
@@ -434,6 +425,10 @@
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->master_server_port = atoi(tmp);
xmlFree (tmp);
+ } else if (strcmp(node->name, "master-redirect-port") == 0) {
+ tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ configuration->master_redirect_port = atoi(tmp);
+ xmlFree (tmp);
} else if (strcmp(node->name, "master-update-interval") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->master_update_interval = atoi(tmp);
@@ -446,8 +441,6 @@
_parse_limits(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "relay") == 0) {
_parse_relay(doc, node->xmlChildrenNode, configuration);
- } else if (strcmp(node->name, "slave-host") == 0) {
- _parse_slave_host(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "mount") == 0) {
_parse_mount(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "directory") == 0) {
@@ -650,37 +643,7 @@
} while ((node = node->next));
}
-static void _parse_slave_host(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c)
-{
- slave_host *slave = calloc(1, sizeof(slave_host));
- xmlChar *tmp;
- slave->port = 8000;
-
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
-
- if (strcmp(node->name, "server") == 0) {
- slave->server = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (strcmp(node->name, "port") == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- slave->port = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- } while ((node = node->next));
- if (slave->server)
- {
- slave->next = c->slave_list;
- c->slave_list = slave;
- c->slaves_count++;
- return;
- }
- free (slave);
-}
-
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
Modified: icecast/branches/kh/icecast/src/cfgfile.h
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.h 2004-08-28 20:42:10 UTC (rev 7658)
+++ icecast/branches/kh/icecast/src/cfgfile.h 2004-08-29 15:17:14 UTC (rev 7659)
@@ -135,8 +135,8 @@
char *webroot_dir;
char *adminroot_dir;
aliases *aliases;
- slave_host *slave_list;
unsigned slaves_count;
+ int master_redirect_port;
char *access_log;
char *error_log;
Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c 2004-08-28 20:42:10 UTC (rev 7658)
+++ icecast/branches/kh/icecast/src/client.c 2004-08-29 15:17:14 UTC (rev 7659)
@@ -70,6 +70,9 @@
;
}
#endif
+ if (client->is_slave)
+ slave_host_remove (client);
+
connection_close(client->con);
httpp_destroy(client->parser);
@@ -198,3 +201,16 @@
refbuf_release (to_release);
}
+void client_as_slave (client_t *client)
+{
+ char *slave_redirect = httpp_getvar (client->parser, "ice-redirect");
+ INFO1 ("client connected as slave from %s", client->con->ip);
+ client->is_slave = 1;
+ if (slave_redirect)
+ {
+ /* this will be something like ip:port */
+ DEBUG1 ("header for auth slave is \"%s\"", slave_redirect);
+ slave_host_add (client, slave_redirect);
+ }
+}
+
Modified: icecast/branches/kh/icecast/src/client.h
===================================================================
--- icecast/branches/kh/icecast/src/client.h 2004-08-28 20:42:10 UTC (rev 7658)
+++ icecast/branches/kh/icecast/src/client.h 2004-08-29 15:17:14 UTC (rev 7659)
@@ -82,5 +82,6 @@
void client_send_302(client_t *client, char *location);
int client_send_bytes (client_t *client, const void *buf, unsigned len);
void client_set_queue (client_t *client, refbuf_t *refbuf);
+void client_as_slave (client_t *client);
#endif /* __CLIENT_H__ */
Modified: icecast/branches/kh/icecast/src/global.h
===================================================================
--- icecast/branches/kh/icecast/src/global.h 2004-08-28 20:42:10 UTC (rev 7658)
+++ icecast/branches/kh/icecast/src/global.h 2004-08-29 15:17:14 UTC (rev 7659)
@@ -42,6 +42,10 @@
/* relays retrieved from master */
struct _relay_server *master_relays;
+ /* slave relay list */
+ unsigned int slave_count;
+ struct _slave_host *slaves;
+
cond_t shutdown_cond;
} ice_global_t;
Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c 2004-08-28 20:42:10 UTC (rev 7658)
+++ icecast/branches/kh/icecast/src/slave.c 2004-08-29 15:17:14 UTC (rev 7659)
@@ -60,10 +60,13 @@
#define CATMODULE "slave"
static void *_slave_thread(void *arg);
-thread_type *_slave_thread_id;
+static void _add_slave_host (const char *server, int port);
+
+static thread_type *_slave_thread_id;
static int slave_running = 0;
static unsigned int max_interval = 0;
static int rescan_relays = 0;
+static rwlock_t slaves_lock;
relay_server *relay_free (relay_server *relay)
{
@@ -122,6 +125,7 @@
if (slave_running)
return;
+ thread_rwlock_create (&slaves_lock);
slave_running = 1;
_slave_thread_id = thread_create("Slave Thread", _slave_thread, NULL, THREAD_ATTACHED);
}
@@ -134,20 +138,21 @@
slave_running = 0;
DEBUG0 ("waiting for slave thread");
thread_join (_slave_thread_id);
+ thread_rwlock_destroy (&slaves_lock);
}
int slave_redirect (char *mountpoint, client_t *client)
{
slave_host *slave = NULL;
- ice_config_t *c = config_get_config();
+ DEBUG1 ("slave count is %d", global.slave_count);
+ thread_rwlock_rlock (&slaves_lock);
/* select slave entry */
- if (c->slaves_count)
+ if (global.slave_count)
{
- int which=(int) (((float)c->slaves_count)*rand()/(RAND_MAX+1.0));
- DEBUG1 ("which is %d", which);
- slave = c->slave_list;
+ int which=(int) (((float)global.slave_count)*rand()/(RAND_MAX+1.0));
+ slave = global.slaves;
while (slave && which)
{
slave = slave->next;
@@ -168,13 +173,13 @@
"at %s:%d", slave->server, slave->port);
snprintf (location, len, "http://%s:%d%s", slave->server,
slave->port, mountpoint);
- config_release_config();
+ thread_rwlock_unlock (&slaves_lock);
client_send_302 (client, location);
free (location);
return 1;
}
}
- config_release_config();
+ thread_rwlock_unlock (&slaves_lock);
return 0;
}
@@ -196,6 +201,7 @@
do
{
char *auth_header;
+ char *redirect_header;
streamsock = sock_connect_wto (relay->server, relay->port, 10);
if (streamsock == SOCK_ERROR)
@@ -210,6 +216,7 @@
{
char *esc_authorisation;
unsigned len = strlen(relay->username) + strlen(relay->password) + 2;
+ ice_config_t *config;
auth_header = malloc (len);
snprintf (auth_header, len, "%s:%s", relay->username, relay->password);
@@ -220,9 +227,23 @@
snprintf (auth_header, len,
"Authorization: Basic %s\r\n", esc_authorisation);
free(esc_authorisation);
+
+ /* header to use for participating in load sharing */
+ config = config_get_config ();
+ if (config->master_redirect_port)
+ {
+ len = strlen ("ice-redirect:") + strlen (config->hostname) + 10;
+ redirect_header = malloc (len);
+ snprintf (redirect_header, len, "ice-redirect: %s:%d\r\n",
+ config->hostname, config->master_redirect_port);
+ }
+ config_release_config ();
}
else
+ {
auth_header = strdup ("");
+ redirect_header = strdup ("");
+ }
/* At this point we may not know if we are relaying an mp3 or vorbis
* stream, but only send the icy-metadata header if the relay details
@@ -233,10 +254,14 @@
"User-Agent: " ICECAST_VERSION_STRING "\r\n"
"%s"
"%s"
+ "%s"
"\r\n",
- relay->mount, relay->mp3metadata?"Icy-MetaData: 1\r\n":"",
+ relay->mount,
+ relay->mp3metadata?"Icy-MetaData: 1\r\n":"",
+ redirect_header,
auth_header);
free (auth_header);
+ free (redirect_header);
memset (header, 0, sizeof(header));
if (util_read_header (con->sock, header, 4096) == 0)
{
@@ -540,11 +565,38 @@
}
+static void update_master_as_slave (ice_config_t *config)
+{
+ char *str;
+ slave_host *slave;
+
+ if (config->master_server == NULL || config->master_redirect_port == 0)
+ return;
+ str = strdup (config->master_server);
+ slave = calloc (1, sizeof(slave_host));
+ if (slave && str)
+ {
+ slave->server = str;
+ slave->port = config->master_server_port;
+ thread_rwlock_wlock (&slaves_lock);
+ _add_slave_host (config->master_server, config->master_server_port);
+ thread_rwlock_unlock (&slaves_lock);
+ return;
+ }
+ free (str);
+ free (slave);
+}
+
+
static void *_slave_thread(void *arg)
{
ice_config_t *config;
unsigned int interval = 0;
+ config = config_get_config();
+ update_master_as_slave (config);
+ config_release_config();
+
while (slave_running)
{
relay_server *cleanup_relays;
@@ -561,6 +613,7 @@
interval = 0;
max_interval = config->master_update_interval;
+ update_master_as_slave (config);
/* the connection could take some time, so the lock can drop */
if (update_from_master (config))
@@ -594,3 +647,102 @@
return NULL;
}
+
+/* remove this slave clients entry in the slave host list */
+void slave_host_remove (client_t *client)
+{
+ const char *var = httpp_getvar (client->parser, "ice-redirect");
+
+ if (var)
+ {
+ slave_host *slave, **trail;
+ char *server = strdup (var), *separator;
+ int port;
+
+ separator = strchr (server, ':');
+ if (separator == NULL)
+ {
+ free (server);
+ return;
+ }
+ *separator = '\0';
+ port = atoi (separator+1);
+ thread_rwlock_wlock (&slaves_lock);
+ slave = global.slaves;
+ trail = &global.slaves;
+ while (slave)
+ {
+ if (strcmp (slave->server, server) == 0 && slave->port == port)
+ {
+ slave->count--;
+ if (slave->count == 0)
+ {
+ INFO2 ("slave at %s:%d removed", slave->server, slave->port);
+ *trail = slave->next;
+ free (slave->server);
+ global.slave_count--;
+ }
+ break;
+ }
+ trail = &slave->next;
+ slave = slave->next;
+ }
+ thread_rwlock_unlock (&slaves_lock);
+ }
+}
+
+
+/* with the provided header (eg "localhost:8000") add a new slave host
+ * entry to so that clients can redirect to other sites when full
+ */
+void slave_host_add (client_t *client, const char *header)
+{
+ slave_host *slave;
+ char *server, *separator;
+ int port;
+
+ if (client == NULL || header == NULL)
+ return;
+
+ server = strdup (header);
+ separator = strchr (server, ':');
+ if (separator == NULL)
+ {
+ free (server);
+ return;
+ }
+ *separator = '\0';
+ port = atoi (separator+1);
+ thread_rwlock_wlock (&slaves_lock);
+ slave = global.slaves;
+ while (slave)
+ {
+ if (strcmp (slave->server, server) == 0 && slave->port == port)
+ {
+ slave->count++;
+ DEBUG0 ("already exists, increasing count");
+ break;
+ }
+ slave = slave->next;
+ }
+ if (slave == NULL)
+ _add_slave_host (server, port);
+ free (server);
+ thread_rwlock_unlock (&slaves_lock);
+}
+
+static void _add_slave_host (const char *server, int port)
+{
+ slave_host *slave = calloc (1, sizeof (slave_host));
+ if (slave == NULL)
+ return;
+ slave->server = strdup (server);
+ slave->port = port;
+ slave->count = 1;
+ slave->next = global.slaves;
+ global.slaves = slave;
+ global.slave_count++;
+ INFO3 ("slave (%d) at %s:%d added", global.slave_count,
+ slave->server, slave->port);
+}
+
Modified: icecast/branches/kh/icecast/src/slave.h
===================================================================
--- icecast/branches/kh/icecast/src/slave.h 2004-08-28 20:42:10 UTC (rev 7658)
+++ icecast/branches/kh/icecast/src/slave.h 2004-08-29 15:17:14 UTC (rev 7659)
@@ -36,6 +36,7 @@
{
char *server;
int port;
+ unsigned int count;
struct _slave_host *next;
} slave_host;
@@ -44,6 +45,8 @@
void slave_recheck (void);
void slave_rescan (void);
int slave_redirect (char *mountpoint, client_t *client);
+void slave_host_add (client_t *client, const char *header);
+void slave_host_remove (client_t *client);
relay_server *relay_free (relay_server *relay);
#endif /* __SLAVE_H__ */
Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c 2004-08-28 20:42:10 UTC (rev 7658)
+++ icecast/branches/kh/icecast/src/source.c 2004-08-29 15:17:14 UTC (rev 7659)
@@ -885,8 +885,8 @@
{
if (connection_check_relay_pass(client->parser))
{
+ client_as_slave (client);
INFO0 ("client connected as slave");
- client->is_slave = 1;
}
thread_mutex_lock (&move_clients_mutex);
avl_tree_rlock (global.source_tree);
More information about the commits
mailing list