[xiph-cvs] cvs commit: icecast/src config.c config.h connection.c global.c global.h main.c

Michael Smith msmith at xiph.org
Sun Mar 9 03:27:06 PST 2003



msmith      03/03/09 06:27:06

  Modified:    .        News
               conf     icecast.xml
               src      config.c config.h connection.c global.c global.h
                        main.c
  Log:
  Support listening on multiple sockets.

Revision  Changes    Path
1.4       +3 -0      icecast/News

Index: News
===================================================================
RCS file: /usr/local/cvsroot/icecast/News,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- News	8 Mar 2003 04:57:02 -0000	1.3
+++ News	9 Mar 2003 11:27:05 -0000	1.4
@@ -1,4 +1,7 @@
 2003-03-09
+    Support listening on multiple sockets.
+
+2003-03-08
     Support for shoutcast source protocol added.
 
 2003-03-08

<p><p>1.20      +14 -1     icecast/conf/icecast.xml

Index: icecast.xml
===================================================================
RCS file: /usr/local/cvsroot/icecast/conf/icecast.xml,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- icecast.xml	4 Mar 2003 08:31:49 -0000	1.19
+++ icecast.xml	9 Mar 2003 11:27:05 -0000	1.20
@@ -31,9 +31,22 @@
      -->
 
         <hostname>localhost</hostname>
-	<port>8000</port>
 
+    <!-- You can use these two if you only want a single listener -->
+	<!--<port>8000</port> -->
         <!--<bind-address>127.0.0.1</bind-address>-->
+
+    <!-- You may have multiple <listener> elements -->
+    <listen-socket>
+        <port>8000</port>
+        <!-- <bind-address>127.0.0.1</bind-address> -->
+    </listen-socket>
+    <!--
+    <listen-socket>
+        <port>8001</port>
+    </listen-socket>
+    -->
+
         <!--<master-server>127.0.0.1</master-server>-->
         <!--<master-server-port>8001</master-server-port>-->
         <!--<master-update-interval>120</master-update-interval>-->

<p><p>1.30      +50 -9     icecast/src/config.c

Index: config.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/config.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- config.c	5 Mar 2003 13:03:35 -0000	1.29
+++ config.c	9 Mar 2003 11:27:06 -0000	1.30
@@ -26,7 +26,6 @@
 #define CONFIG_DEFAULT_FILESERVE 1
 #define CONFIG_DEFAULT_TOUCH_FREQ 5
 #define CONFIG_DEFAULT_HOSTNAME "localhost"
-#define CONFIG_DEFAULT_PORT 8888
 #define CONFIG_DEFAULT_ACCESS_LOG "access.log"
 #define CONFIG_DEFAULT_ERROR_LOG "error.log"
 #define CONFIG_DEFAULT_LOG_LEVEL 4
@@ -61,6 +60,8 @@
         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, 
+        ice_config_t *c);
 static void _add_server(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
 
 static void create_locks() {
@@ -97,6 +98,7 @@
         ice_config_dir_t *dirnode, *nextdirnode;
     relay_server *relay, *nextrelay;
     mount_proxy *mount, *nextmount;
+    int i;
 
     if (c->config_filename)
         free(c->config_filename);
@@ -125,7 +127,9 @@
         xmlFree(c->access_log);
         if (c->error_log && c->error_log != CONFIG_DEFAULT_ERROR_LOG) 
         xmlFree(c->error_log);
-    if (c->bind_address) xmlFree(c->bind_address);
+    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_password) xmlFree(c->master_password);
     if (c->user) xmlFree(c->user);
@@ -262,10 +266,11 @@
         configuration->touch_interval = CONFIG_DEFAULT_TOUCH_FREQ;
         configuration->dir_list = NULL;
         configuration->hostname = CONFIG_DEFAULT_HOSTNAME;
-	configuration->port = CONFIG_DEFAULT_PORT;
-	configuration->bind_address = NULL;
+    configuration->port = 0;
+	configuration->listeners[0].port = 0;
+	configuration->listeners[0].bind_address = NULL;
         configuration->master_server = NULL;
-	configuration->master_server_port = CONFIG_DEFAULT_PORT;
+	configuration->master_server_port = 0;
     configuration->master_update_interval = CONFIG_MASTER_UPDATE_INTERVAL;
         configuration->master_password = NULL;
         configuration->base_dir = CONFIG_DEFAULT_BASE_DIR;
@@ -324,13 +329,17 @@
                 } else if (strcmp(node->name, "hostname") == 0) {
                         if (configuration->hostname && configuration->hostname != CONFIG_DEFAULT_HOSTNAME) xmlFree(configuration->hostname);
                         configuration->hostname = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-		} else if (strcmp(node->name, "port") == 0) {
+		} else if (strcmp(node->name, "listen-socket") == 0) {
+            _parse_listen_socket(doc, node->xmlChildrenNode, configuration);
+        } else if (strcmp(node->name, "port") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			configuration->port = atoi(tmp);
+            configuration->port = atoi(tmp);
+			configuration->listeners[0].port = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 } else if (strcmp(node->name, "bind-address") == 0) {
-			if (configuration->bind_address) xmlFree(configuration->bind_address);
-			configuration->bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->listeners[0].bind_address) 
+                xmlFree(configuration->listeners[0].bind_address);
+			configuration->listeners[0].bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "master-server") == 0) {
                         if (configuration->master_server) xmlFree(configuration->master_server);
                         configuration->master_server = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
@@ -497,6 +506,38 @@
             tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
             relay->mp3metadata = atoi(tmp);
             if(tmp) xmlFree(tmp);
+        }
+	} while ((node = node->next));
+}
+
+static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
+        ice_config_t *configuration)
+{
+    listener_t *listener = NULL;
+    int i;
+    char *tmp;
+
+    for(i=0; i < MAX_LISTEN_SOCKETS; i++) {
+        if(configuration->listeners[i].port <= 0) {
+            listener = &(configuration->listeners[i]);
+            break;
+        }
+    }
+
+	do {
+		if (node == NULL) break;
+		if (xmlIsBlankNode(node)) continue;
+
+		if (strcmp(node->name, "port") == 0) {
+            tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+            if(configuration->port == 0)
+                configuration->port = atoi(tmp);
+            listener->port = atoi(tmp);
+            if(tmp) xmlFree(tmp);
+        }
+        else if (strcmp(node->name, "bind-address") == 0) {
+            listener->bind_address = (char *)xmlNodeListGetString(doc, 
+                    node->xmlChildrenNode, 1);
         }
         } while ((node = node->next));
 }

<p><p>1.18      +12 -2     icecast/src/config.h

Index: config.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/config.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- config.h	5 Mar 2003 13:03:35 -0000	1.17
+++ config.h	9 Mar 2003 11:27:06 -0000	1.18
@@ -8,7 +8,10 @@
 
 #define MAX_YP_DIRECTORIES 25
 
+
 #include "thread/thread.h"
+#include "avl/avl.h"
+#include "global.h"
 
 typedef struct ice_config_dir_tag
 {
@@ -40,6 +43,11 @@
     struct _mount_proxy *next;
 } mount_proxy;
 
+typedef struct {
+    int port;
+    char *bind_address;
+} listener_t;
+
 typedef struct ice_config_tag
 {
     char *config_filename;
@@ -66,8 +74,10 @@
         ice_config_dir_t *dir_list;
 
         char *hostname;
-	int port;
-	char *bind_address;
+    int port;
+
+    listener_t listeners[MAX_LISTEN_SOCKETS];
+
         char *master_server;
         int master_server_port;
     int master_update_interval;

<p><p>1.63      +71 -4     icecast/src/connection.c

Index: connection.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/connection.c,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -r1.62 -r1.63
--- connection.c	8 Mar 2003 05:38:52 -0000	1.62
+++ connection.c	9 Mar 2003 11:27:06 -0000	1.63
@@ -4,6 +4,9 @@
 #include <time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifdef HAVE_POLL
+#include <sys/poll.h>
+#endif
 
 #ifndef _WIN32
 #include <sys/time.h>
@@ -121,20 +124,84 @@
         return con;
 }
 
+static int wait_for_serversock(int timeout)
+{
+#ifdef HAVE_POLL
+    struct pollfd ufds[MAX_LISTEN_SOCKETS];
+    int i, ret;
+
+    for(i=0; i < global.server_sockets; i++) {
+        ufds[i].fd = global.serversock[i];
+        ufds[i].events = POLLIN;
+        ufds[i].revents = 0;
+    }
+
+    ret = poll(ufds, global.server_sockets, timeout);
+    if(ret < 0) {
+        return -2;
+    }
+    else if(ret == 0) {
+        return -1;
+    }
+    else {
+        for(i=0; i < global.server_sockets; i++) {
+            if(ufds[i].revents == POLLIN)
+                return ufds[i].fd;
+        }
+        return -1; /* Shouldn't happen */
+    }
+#else
+    fd_set rfds;
+    struct timeval tv, *p=NULL;
+    int i, ret;
+    int max = -1;
+
+    FD_ZERO(&rfds);
+
+    for(i=0; i < global.server_sockets; i++) {
+        FD_SET(global.serversock[i], &rfds);
+        if(global.serversock[i] > max)
+            max = global.serversock[i];
+    }
+
+    if(timeout >= 0) {
+        tv.tv_sec = timeout/1000;
+        tv.tv_usec = (timeout % 1000)/1000;
+        p = &tv;
+    }
+
+    ret = select(max+1, &rfds, NULL, NULL, p);
+    if(ret < 0) {
+        return -2;
+    }
+    else if(ret == 0) {
+        return -1;
+    }
+    else {
+        for(i=0; i < global.server_sockets; i++) {
+            if(FD_ISSET(global.serversock[i], &rfds))
+                return global.serversock[i];
+        }
+        return -1; /* Should be impossible, stop compiler warnings */
+    }
+#endif
+}
+
 static connection_t *_accept_connection(void)
 {
         int sock;
         connection_t *con;
         char *ip;
+    int serversock; 
 
-    if (util_timed_wait_for_fd(global.serversock, 100) <= 0) {
-		return NULL;
-	}
+    serversock = wait_for_serversock(100);
+    if(serversock < 0)
+        return NULL;
 
         /* malloc enough room for a full IP address (including ipv6) */
         ip = (char *)malloc(MAX_ADDR_LEN);
 
-	sock = sock_accept(global.serversock, ip, MAX_ADDR_LEN);
+	sock = sock_accept(serversock, ip, MAX_ADDR_LEN);
         if (sock >= 0) {
                 con = create_connection(sock, ip);
 

<p><p>1.6       +4 -1      icecast/src/global.c

Index: global.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/global.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- global.c	2 Feb 2003 14:31:34 -0000	1.5
+++ global.c	9 Mar 2003 11:27:06 -0000	1.6
@@ -1,3 +1,5 @@
+#include <string.h>
+
 #include "thread.h"
 #include "avl.h"
 
@@ -17,7 +19,8 @@
 
 void global_initialize(void)
 {
-	global.serversock = -1;
+    memset(global.serversock, 0, sizeof(int)*MAX_LISTEN_SOCKETS);
+	global.server_sockets = 0;
         global.running = 0;
         global.clients = 0;
         global.sources = 0;

<p><p>1.6       +4 -1      icecast/src/global.h

Index: global.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/global.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- global.h	11 Feb 2003 14:23:34 -0000	1.5
+++ global.h	9 Mar 2003 11:27:06 -0000	1.6
@@ -8,11 +8,14 @@
 
 #define ICECAST_VERSION_STRING "Icecast 2.0-alpha2/cvs"
 
+#define MAX_LISTEN_SOCKETS 10
+
 #include "thread/thread.h"
 
 typedef struct ice_global_tag
 {
-	int serversock;
+	int serversock[MAX_LISTEN_SOCKETS];
+    int server_sockets;
 
         int running;
 

<p><p>1.23      +34 -13    icecast/src/main.c

Index: main.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/main.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- main.c	5 Mar 2003 13:03:35 -0000	1.22
+++ main.c	9 Mar 2003 11:27:06 -0000	1.23
@@ -153,26 +153,47 @@
         return 0;
 }
 
-static int _setup_socket(void)
+static int _setup_sockets(void)
 {
         ice_config_t *config;
+    int i = 0;
+    int ret = 0;
+    int successful = 0;
 
         config = config_get_config_unlocked();
 
-	global.serversock = sock_get_server_socket(config->port, config->bind_address);
+    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) {
+		    fprintf(stderr, "Could not create listener socket on port %d\n", 
+                    config->listeners[i].port);
+            return 0;
+        }
+        else {
+            ret = 1;
+            successful++;
+        }
+    }
 
-	if (global.serversock == SOCK_ERROR)
-		return 0;
+    global.server_sockets = successful;
         
-	return 1;
+	return ret;
 }
 
 static int _start_listening(void)
 {
-	if (sock_listen(global.serversock, ICE_LISTEN_QUEUE) == SOCK_ERROR)
-		return 0;
+    int i;
+    for(i=0; i < global.server_sockets; i++) {
+    	if (sock_listen(global.serversock[i], ICE_LISTEN_QUEUE) == SOCK_ERROR)
+	    	return 0;
 
-	sock_set_blocking(global.serversock, SOCK_NONBLOCK);
+	    sock_set_blocking(global.serversock[i], SOCK_NONBLOCK);
+    }
 
         return 1;
 }
@@ -180,11 +201,8 @@
 /* bind the socket and start listening */
 static int _server_proc_init(void)
 {
-	if (!_setup_socket()) {
-		fprintf(stderr, "Could not create listener socket on port %d\n", 
-                config_get_config_unlocked()->port);
+	if (!_setup_sockets())
                 return 0;
-	}
 
         if (!_start_listening()) {
                 fprintf(stderr, "Failed trying to listen on server socket\n");
@@ -197,9 +215,12 @@
 /* this is the heart of the beast */
 static void _server_proc(void)
 {
+    int i;
+
         connection_accept_loop();
 
-	sock_close(global.serversock);
+    for(i=0; i < MAX_LISTEN_SOCKETS; i++)
+    	sock_close(global.serversock[i]);
 }
 
 /* chroot the process. Watch out - we need to do this before starting other

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list