[xiph-commits] r13995 - icecast/trunk/icecast/src

karl at svn.xiph.org karl at svn.xiph.org
Mon Oct 15 18:53:07 PDT 2007


Author: karl
Date: 2007-10-15 18:53:06 -0700 (Mon, 15 Oct 2007)
New Revision: 13995

Modified:
   icecast/trunk/icecast/src/cfgfile.c
   icecast/trunk/icecast/src/cfgfile.h
   icecast/trunk/icecast/src/connection.c
   icecast/trunk/icecast/src/connection.h
   icecast/trunk/icecast/src/global.c
   icecast/trunk/icecast/src/global.h
   icecast/trunk/icecast/src/main.c
Log:
Don't impose a limit on the number of listening sockets allowed in the xml


Modified: icecast/trunk/icecast/src/cfgfile.c
===================================================================
--- icecast/trunk/icecast/src/cfgfile.c	2007-10-15 23:25:15 UTC (rev 13994)
+++ icecast/trunk/icecast/src/cfgfile.c	2007-10-16 01:53:06 UTC (rev 13995)
@@ -150,6 +150,17 @@
     free (mount);
 }
 
+listener_t *config_clear_listener (listener_t *listener)
+{
+    listener_t *next = NULL;
+    if (listener)
+    {
+        next = listener->next;
+        if (listener->bind_address)     xmlFree (listener->bind_address);
+        free (listener);
+    }
+    return next;
+}
 
 void config_clear(ice_config_t *c)
 {
@@ -183,9 +194,6 @@
     if (c->access_log) xmlFree(c->access_log);
     if (c->error_log) xmlFree(c->error_log);
     if (c->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);
-    }
     if (c->master_server) xmlFree(c->master_server);
     if (c->master_username) xmlFree(c->master_username);
     if (c->master_password) xmlFree(c->master_password);
@@ -193,6 +201,9 @@
     if (c->group) xmlFree(c->group);
     if (c->mimetypes_fn) xmlFree (c->mimetypes_fn);
 
+    while ((c->listen_sock = config_clear_listener (c->listen_sock)))
+        ;
+
     thread_mutex_lock(&(_locks.relay_lock));
     relay = c->relay;
     while(relay) {
@@ -342,10 +353,7 @@
     configuration->dir_list = NULL;
     configuration->hostname = (char *)xmlCharStrdup (CONFIG_DEFAULT_HOSTNAME);
     configuration->mimetypes_fn = (char *)xmlCharStrdup (MIMETYPESFILE);
-    configuration->port = 0;
-    configuration->listeners[0].port = 0;
-    configuration->listeners[0].bind_address = NULL;
-    configuration->listeners[0].shoutcast_compat = 0;
+    configuration->port = 8000;
     configuration->master_server = NULL;
     configuration->master_server_port = 0;
     configuration->master_update_interval = CONFIG_MASTER_UPDATE_INTERVAL;
@@ -375,6 +383,10 @@
 {
     char *tmp;
 
+    configuration->listen_sock = calloc (1, sizeof (*configuration->listen_sock));
+    configuration->listen_sock->port = 8000;
+    configuration->listen_sock_count = 1;
+
     do {
         if (node == NULL) break;
         if (xmlIsBlankNode(node)) continue;
@@ -424,12 +436,12 @@
         } else if (xmlStrcmp (node->name, XMLSTR("port")) == 0) {
             tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
             configuration->port = atoi(tmp);
-            configuration->listeners[0].port = atoi(tmp);
+            configuration->listen_sock->port = atoi(tmp);
             if (tmp) xmlFree(tmp);
         } else if (xmlStrcmp (node->name, XMLSTR("bind-address")) == 0) {
-            if (configuration->listeners[0].bind_address) 
-                xmlFree(configuration->listeners[0].bind_address);
-            configuration->listeners[0].bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+            if (configuration->listen_sock->bind_address) 
+                xmlFree(configuration->listen_sock->bind_address);
+            configuration->listen_sock->bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
         } else if (xmlStrcmp (node->name, XMLSTR("master-server")) == 0) {
             if (configuration->master_server) xmlFree(configuration->master_server);
             configuration->master_server = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
@@ -751,19 +763,13 @@
 static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
         ice_config_t *configuration)
 {
-    listener_t *listener = NULL;
-    int i;
     char *tmp;
+    listener_t *listener = calloc (1, sizeof(listener_t));
 
-    for(i=0; i < MAX_LISTEN_SOCKETS; i++) {
-        if(configuration->listeners[i].port <= 0) {
-            listener = &(configuration->listeners[i]);
-            break;
-        }
-    }
-
     if (listener == NULL)
         return;
+    listener->port = 8000;
+
     do {
         if (node == NULL) break;
         if (xmlIsBlankNode(node)) continue;
@@ -790,6 +796,10 @@
                     node->xmlChildrenNode, 1);
         }
     } while ((node = node->next));
+
+    listener->next = configuration->listen_sock;
+    configuration->listen_sock = listener;
+    configuration->listen_sock_count++;
 }
 
 static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
@@ -1068,3 +1078,29 @@
     return mountinfo;
 }
 
+/* Helper function to locate the configuration details of the listening 
+ * socket
+ */
+listener_t *config_get_listen_sock (ice_config_t *config, connection_t *con)
+{
+    listener_t *listener;
+    int i = 0;
+
+    listener = config->listen_sock;
+    global_lock();
+    while (listener)
+    {
+        if (i < global.server_sockets)
+            listener = NULL;
+        else
+        {
+            if (global.serversock[i] == con->serversock)
+                break;
+            listener = listener->next;
+            i++;
+        }
+    }
+    global_unlock();
+    return listener;
+}
+

Modified: icecast/trunk/icecast/src/cfgfile.h
===================================================================
--- icecast/trunk/icecast/src/cfgfile.h	2007-10-15 23:25:15 UTC (rev 13994)
+++ icecast/trunk/icecast/src/cfgfile.h	2007-10-16 01:53:06 UTC (rev 13995)
@@ -26,6 +26,7 @@
 #include "avl/avl.h"
 #include "auth.h"
 #include "global.h"
+#include "connection.h"
 
 #define XMLSTR(str) ((xmlChar *)(str)) 
 
@@ -97,7 +98,8 @@
     struct _aliases *next;
 }aliases;
 
-typedef struct {
+typedef struct _listener_t {
+    struct _listener_t *next;
     int port;
     char *bind_address;
     int shoutcast_compat;
@@ -137,7 +139,8 @@
     int port;
     char *mimetypes_fn;
 
-    listener_t listeners[MAX_LISTEN_SOCKETS];
+    listener_t *listen_sock;
+    unsigned int listen_sock_count;
 
     char *master_server;
     int master_server_port;
@@ -187,8 +190,10 @@
 int config_initial_parse_file(const char *filename);
 int config_parse_cmdline(int arg, char **argv);
 void config_set_config(ice_config_t *config);
+listener_t *config_clear_listener (listener_t *listener);
 void config_clear(ice_config_t *config);
 mount_proxy *config_find_mount (ice_config_t *config, const char *mount);
+listener_t *config_get_listen_sock (ice_config_t *config, connection_t *con);
 
 int config_rehash(void);
 

Modified: icecast/trunk/icecast/src/connection.c
===================================================================
--- icecast/trunk/icecast/src/connection.c	2007-10-15 23:25:15 UTC (rev 13994)
+++ icecast/trunk/icecast/src/connection.c	2007-10-16 01:53:06 UTC (rev 13995)
@@ -592,8 +592,8 @@
         {
             client_queue_t *node;
             ice_config_t *config;
-            int i;
             client_t *client = NULL;
+            listener_t *listener;
 
             global_lock();
             if (client_create (&client, con, NULL) < 0)
@@ -615,17 +615,15 @@
             }
             node->client = client;
 
-            /* Check for special shoutcast compatability processing */
             config = config_get_config();
-            for (i = 0; i < global.server_sockets; i++)
+            listener = config_get_listen_sock (config, client->con);
+
+            if (listener)
             {
-                if (global.serversock[i] == con->serversock)
-                {
-                    if (config->listeners[i].shoutcast_compat)
-                        node->shoutcast = 1;
-                    if (config->listeners[i].ssl && ssl_ok)
-                        connection_uses_ssl (client->con);
-                }
+                if (listener->shoutcast_compat)
+                    node->shoutcast = 1;
+                if (listener->ssl && ssl_ok)
+                    connection_uses_ssl (client->con);
             }
             config_release_config();
 
@@ -966,22 +964,22 @@
 {
     int fileserve;
     int port;
-    int i;
     char *serverhost = NULL;
     int serverport = 0;
     aliases *alias;
     ice_config_t *config;
     char *uri = passed_uri;
+    listener_t *listen_sock;
 
     config = config_get_config();
     fileserve = config->fileserve;
     port = config->port;
-    for(i = 0; i < global.server_sockets; i++) {
-        if(global.serversock[i] == client->con->serversock) {
-            serverhost = config->listeners[i].bind_address;
-            serverport = config->listeners[i].port;
-            break;
-        }
+
+    listen_sock = config_get_listen_sock (config, client->con);
+    if (listen_sock)
+    {
+        serverhost = listen_sock->bind_address;
+        serverport = listen_sock->port;
     }
     alias = config->aliases;
 
@@ -1211,6 +1209,80 @@
     return NULL;
 }
 
+
+/* called when listening thread is not checking for incoming connections */
+int connection_setup_sockets (ice_config_t *config)
+{
+    int count = 0;
+    listener_t *listener, **prev;
+
+    global_lock();
+    if (global.serversock)
+    {
+        for (; count < global.server_sockets; count++)
+            sock_close (global.serversock [count]);
+        free (global.serversock);
+        global.serversock = NULL;
+    }
+    if (config == NULL)
+    {
+        global_unlock();
+        return 0;
+    }
+
+    count = 0;
+    global.serversock = calloc (config->listen_sock_count, sizeof (sock_t));
+
+    listener = config->listen_sock; 
+    prev = &config->listen_sock;
+    while (listener)
+    {
+        int successful = 0;
+
+        do
+        {
+            sock_t sock = sock_get_server_socket (listener->port, listener->bind_address);
+            if (sock == SOCK_ERROR)
+                break;
+            if (sock_listen (sock, ICE_LISTEN_QUEUE) == SOCK_ERROR)
+            {
+                sock_close (sock);
+                break;
+            }
+            sock_set_blocking (sock, SOCK_NONBLOCK);
+            successful = 1;
+            global.serversock [count] = sock;
+            count++;
+        } while(0);
+        if (successful == 0)
+        {
+            if (listener->bind_address)
+                ERROR2 ("Could not create listener socket on port %d bind %s",
+                        listener->port, listener->bind_address);
+            else
+                ERROR1 ("Could not create listener socket on port %d", listener->port);
+            /* remove failed connection */
+            *prev = config_clear_listener (listener);
+            listener = *prev;
+            continue;
+        }
+        if (listener->bind_address)
+            INFO2 ("listener socket on port %d address %s", listener->port, listener->bind_address);
+        else
+            INFO1 ("listener socket on port %d", listener->port);
+        prev = &listener->next;
+        listener = listener->next;
+    }
+    global.server_sockets = count;
+    global_unlock();
+
+    if (count == 0)
+        ERROR0 ("No listening sockets established");
+
+    return count;
+}
+
+
 void connection_close(connection_t *con)
 {
     sock_close(con->sock);

Modified: icecast/trunk/icecast/src/connection.h
===================================================================
--- icecast/trunk/icecast/src/connection.h	2007-10-15 23:25:15 UTC (rev 13994)
+++ icecast/trunk/icecast/src/connection.h	2007-10-16 01:53:06 UTC (rev 13995)
@@ -27,6 +27,7 @@
 
 struct _client_tag;
 struct source_tag;
+struct ice_config_tag;
 
 typedef struct connection_tag
 {
@@ -54,6 +55,7 @@
 void connection_initialize(void);
 void connection_shutdown(void);
 void connection_accept_loop(void);
+int  connection_setup_sockets (struct ice_config_tag *config);
 void connection_close(connection_t *con);
 connection_t *connection_create (sock_t sock, sock_t serversock, char *ip);
 int connection_complete_source (struct source_tag *source, int response);

Modified: icecast/trunk/icecast/src/global.c
===================================================================
--- icecast/trunk/icecast/src/global.c	2007-10-15 23:25:15 UTC (rev 13994)
+++ icecast/trunk/icecast/src/global.c	2007-10-16 01:53:06 UTC (rev 13995)
@@ -35,7 +35,6 @@
 
 void global_initialize(void)
 {
-    memset(global.serversock, 0, sizeof(int)*MAX_LISTEN_SOCKETS);
     global.server_sockets = 0;
     global.relays = NULL;
     global.master_relays = NULL;

Modified: icecast/trunk/icecast/src/global.h
===================================================================
--- icecast/trunk/icecast/src/global.h	2007-10-15 23:25:15 UTC (rev 13994)
+++ icecast/trunk/icecast/src/global.h	2007-10-16 01:53:06 UTC (rev 13995)
@@ -27,7 +27,7 @@
 
 typedef struct ice_global_tag
 {
-    int serversock[MAX_LISTEN_SOCKETS];
+    int *serversock;
     int server_sockets;
 
     int running;

Modified: icecast/trunk/icecast/src/main.c
===================================================================
--- icecast/trunk/icecast/src/main.c	2007-10-15 23:25:15 UTC (rev 13994)
+++ icecast/trunk/icecast/src/main.c	2007-10-16 01:53:06 UTC (rev 13995)
@@ -261,42 +261,7 @@
     return 0;
 }
 
-static int _setup_sockets(void)
-{
-    ice_config_t *config;
-    int i = 0;
-    int ret = 0;
-    int successful = 0;
-    char pbuf[1024];
 
-    config = config_get_config_unlocked();
-
-    for(i = 0; i < MAX_LISTEN_SOCKETS; i++) {
-        if(config->listeners[i].port <= 0)
-            break;
-
-        global.serversock[i] = sock_get_server_socket(
-                config->listeners[i].port, config->listeners[i].bind_address);
-
-        if (global.serversock[i] == SOCK_ERROR) {
-            memset(pbuf, '\000', sizeof(pbuf));
-            snprintf(pbuf, sizeof(pbuf)-1, 
-                "Could not create listener socket on port %d", 
-                config->listeners[i].port);
-            _fatal_error(pbuf);
-            return 0;
-        }
-        else {
-            ret = 1;
-            successful++;
-        }
-    }
-
-    global.server_sockets = successful;
-    
-    return ret;
-}
-
 static int _start_listening(void)
 {
     int i;
@@ -313,9 +278,9 @@
 /* bind the socket and start listening */
 static int _server_proc_init(void)
 {
-    ice_config_t *config;
+    ice_config_t *config = config_get_config_unlocked();
 
-    if (!_setup_sockets())
+    if (connection_setup_sockets (config) < 1)
         return 0;
 
     if (!_start_listening()) {
@@ -323,7 +288,6 @@
         return 0;
     }
 
-    config = config_get_config_unlocked();
     /* recreate the pid file */
     if (config->pidfile)
     {
@@ -342,8 +306,6 @@
 /* this is the heart of the beast */
 static void _server_proc(void)
 {
-    int i;
-
     if (background)
     {
         fclose (stdin);
@@ -352,8 +314,7 @@
     }
     connection_accept_loop();
 
-    for(i=0; i < MAX_LISTEN_SOCKETS; i++)
-        sock_close(global.serversock[i]);
+    connection_setup_sockets (NULL);
 }
 
 /* chroot the process. Watch out - we need to do this before starting other



More information about the commits mailing list