Commit ba438dd7 authored by Karl Heyes's avatar Karl Heyes

Don't impose a limit on the number of listening sockets allowed in the xml

svn path=/icecast/trunk/icecast/; revision=13995
parent e065acb7
......@@ -150,6 +150,17 @@ static void config_clear_mount (mount_proxy *mount)
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 @@ void config_clear(ice_config_t *c)
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 @@ void config_clear(ice_config_t *c)
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 @@ static void _set_defaults(ice_config_t *configuration)
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 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
{
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 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
} 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_relay(xmlDocPtr doc, xmlNodePtr node,
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;
}
}
listener_t *listener = calloc (1, sizeof(listener_t));
if (listener == NULL)
return;
listener->port = 8000;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
......@@ -790,6 +796,10 @@ static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
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 @@ mount_proxy *config_find_mount (ice_config_t *config, const char *mount)
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;
}
......@@ -26,6 +26,7 @@ struct _mount_proxy;
#include "avl/avl.h"
#include "auth.h"
#include "global.h"
#include "connection.h"
#define XMLSTR(str) ((xmlChar *)(str))
......@@ -97,7 +98,8 @@ typedef struct _aliases {
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 @@ typedef struct ice_config_tag
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_parse_file(const char *filename, ice_config_t *configuration);
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);
......
......@@ -592,8 +592,8 @@ void connection_accept_loop(void)
{
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 @@ void connection_accept_loop(void)
}
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 @@ static void _handle_get_request (client_t *client, char *passed_uri)
{
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 @@ static void *_handle_connection(void *arg)
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);
......
......@@ -27,6 +27,7 @@
struct _client_tag;
struct source_tag;
struct ice_config_tag;
typedef struct connection_tag
{
......@@ -54,6 +55,7 @@ typedef struct connection_tag
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);
......
......@@ -35,7 +35,6 @@ static mutex_t _global_mutex;
void global_initialize(void)
{
memset(global.serversock, 0, sizeof(int)*MAX_LISTEN_SOCKETS);
global.server_sockets = 0;
global.relays = NULL;
global.master_relays = NULL;
......
......@@ -27,7 +27,7 @@
typedef struct ice_global_tag
{
int serversock[MAX_LISTEN_SOCKETS];
int *serversock;
int server_sockets;
int running;
......
......@@ -261,41 +261,6 @@ static int _start_logging(void)
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)
{
......@@ -313,9 +278,9 @@ static int _start_listening(void)
/* 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 @@ static int _server_proc_init(void)
return 0;
}
config = config_get_config_unlocked();
/* recreate the pid file */
if (config->pidfile)
{
......@@ -342,8 +306,6 @@ static int _server_proc_init(void)
/* this is the heart of the beast */
static void _server_proc(void)
{
int i;
if (background)
{
fclose (stdin);
......@@ -352,8 +314,7 @@ static void _server_proc(void)
}
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment