[xiph-commits] r7329 - in icecast/branches/kh/icecast: conf src

karl at dactyl.lonelymoon.com karl
Sun Jul 25 09:38:01 PDT 2004


Author: karl
Date: Sun Jul 25 09:38:01 2004
New Revision: 7329

Modified:
icecast/branches/kh/icecast/conf/icecast.xml.in
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/slave.c
icecast/branches/kh/icecast/src/slave.h
icecast/branches/kh/icecast/src/source.c
Log:
enabled clients to be redirected to a randomly selected slave when
max clients has been reached. This uses the HTTP 302 code


Modified: icecast/branches/kh/icecast/conf/icecast.xml.in
===================================================================
--- icecast/branches/kh/icecast/conf/icecast.xml.in	2004-07-25 15:27:29 UTC (rev 7328)
+++ icecast/branches/kh/icecast/conf/icecast.xml.in	2004-07-25 16:38:00 UTC (rev 7329)
@@ -51,6 +51,19 @@
</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>-->

Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c	2004-07-25 15:27:29 UTC (rev 7328)
+++ icecast/branches/kh/icecast/src/cfgfile.c	2004-07-25 16:38:00 UTC (rev 7329)
@@ -77,6 +77,7 @@
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,
@@ -118,6 +119,7 @@
relay_server *relay, *nextrelay;
mount_proxy *mount, *nextmount;
aliases *alias, *nextalias;
+    slave_host *slave;
int i;
config_options_t *option;

@@ -219,6 +221,14 @@
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)
@@ -344,6 +354,7 @@
configuration->user = CONFIG_DEFAULT_USER;
configuration->group = CONFIG_DEFAULT_GROUP;
configuration->num_yp_directories = 0;
+    configuration->slaves_count = 0;
configuration->relay_username = NULL;
configuration->relay_password = NULL;
}
@@ -423,6 +434,8 @@
_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) {
@@ -617,6 +630,37 @@
} 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-07-25 15:27:29 UTC (rev 7328)
+++ icecast/branches/kh/icecast/src/cfgfile.h	2004-07-25 16:38:00 UTC (rev 7329)
@@ -24,6 +24,7 @@
#include "thread/thread.h"
#include "avl/avl.h"
#include "global.h"
+#include "slave.h"

typedef struct ice_config_dir_tag
{
@@ -131,6 +132,8 @@
char *webroot_dir;
char *adminroot_dir;
aliases *aliases;
+    slave_host *slave_list;
+    unsigned slaves_count;

char *access_log;
char *error_log;

Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c	2004-07-25 15:27:29 UTC (rev 7328)
+++ icecast/branches/kh/icecast/src/client.c	2004-07-25 16:38:00 UTC (rev 7329)
@@ -81,6 +81,18 @@
free(client);
}

+void client_send_302(client_t *client, char *location) {
+    int bytes;
+    bytes = sock_write(client->con->sock, "HTTP/1.0 302 Temporarily Moved\r\n"
+            "Content-Type: text/html\r\n"
+            "Location: %s\r\n\r\n"
+            "<a href=\"%s\">%s</a>", location, location, location);
+    if(bytes > 0) client->con->sent_bytes = bytes;
+    client->respcode = 302;
+    client_destroy(client);
+}
+
+
void client_send_400(client_t *client, char *message) {
int bytes;
bytes = sock_write(client->con->sock, "HTTP/1.0 400 Bad Request\r\n"

Modified: icecast/branches/kh/icecast/src/client.h
===================================================================
--- icecast/branches/kh/icecast/src/client.h	2004-07-25 15:27:29 UTC (rev 7328)
+++ icecast/branches/kh/icecast/src/client.h	2004-07-25 16:38:00 UTC (rev 7329)
@@ -76,6 +76,7 @@
void client_send_404(client_t *client, char *message);
void client_send_401(client_t *client);
void client_send_400(client_t *client, char *message);
+void client_send_302(client_t *client, char *location);
int client_send_bytes (client_t *client, const void *buf, unsigned len);

#endif  /* __CLIENT_H__ */

Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c	2004-07-25 15:27:29 UTC (rev 7328)
+++ icecast/branches/kh/icecast/src/connection.c	2004-07-25 16:38:00 UTC (rev 7329)
@@ -889,8 +889,11 @@
if (global.clients >= client_limit)
{
global_unlock();
-        client_send_404(client,
-                "The server is already full. Try again later.");
+        if (slave_redirect (uri, client) == 0)
+        {
+            client_send_404(client,
+                    "The server is already full. Try again later.");
+        }
if (uri != passed_uri) free (uri);
return;
}

Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c	2004-07-25 15:27:29 UTC (rev 7328)
+++ icecast/branches/kh/icecast/src/slave.c	2004-07-25 16:38:00 UTC (rev 7329)
@@ -153,6 +153,48 @@
}


+int slave_redirect (char *mountpoint, client_t *client)
+{
+    slave_host *slave = NULL;
+    ice_config_t *c = config_get_config();
+
+    /* select slave entry */
+    if (c->slaves_count)
+    {
+        int which=(int) (((float)c->slaves_count)*rand()/(RAND_MAX+1.0));
+        DEBUG1 ("which is %d", which);
+        slave = c->slave_list;
+        while (slave && which)
+        {
+            slave = slave->next;
+            which--;
+        }
+        DEBUG2 ("selected %s:%d", slave->server,slave->port);
+    }
+    if (slave)
+    {
+        char *location = NULL;
+        /* add 13 for "http://" the port ':' and nul */
+        int len = strlen(mountpoint) + strlen (slave->server) + 13;
+
+        location = malloc (len);
+        if (location)
+        {
+            INFO2 ("redirecting client to slave server"
+                    "at %s:%d", slave->server, slave->port);
+            snprintf (location, len, "http://%s:%d%s", slave->server,
+                    slave->port, mountpoint);
+            config_release_config();
+            client_send_302 (client, location);
+            free (location);
+            return 1;
+        }
+    }
+    config_release_config();
+    return 0;
+}
+
+
/* This does the actual connection for a relay. A thread is
* started off if a connection can be acquired
*/

Modified: icecast/branches/kh/icecast/src/slave.h
===================================================================
--- icecast/branches/kh/icecast/src/slave.h	2004-07-25 15:27:29 UTC (rev 7328)
+++ icecast/branches/kh/icecast/src/slave.h	2004-07-25 16:38:00 UTC (rev 7329)
@@ -13,6 +13,8 @@
#ifndef __SLAVE_H__
#define __SLAVE_H__

+#include <client.h>
+
typedef struct _relay_server {
char *server;
int port;
@@ -28,10 +30,17 @@
struct _relay_server *next;
} relay_server;

+typedef struct _slave_host
+{
+    char *server;
+    int port;
+    struct _slave_host *next;
+} slave_host;

void slave_initialize(void);
void slave_shutdown(void);
void slave_recheck (void);
+int slave_redirect (char *mountpoint, 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-07-25 15:27:29 UTC (rev 7328)
+++ icecast/branches/kh/icecast/src/source.c	2004-07-25 16:38:00 UTC (rev 7329)
@@ -904,7 +904,11 @@
switch (added)
{
case -1:
-        client_send_404 (client, "Too many clients on this mountpoint. Try again later.");
+        /* 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:



More information about the commits mailing list