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) ...@@ -150,6 +150,17 @@ static void config_clear_mount (mount_proxy *mount)
free (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) void config_clear(ice_config_t *c)
{ {
...@@ -183,9 +194,6 @@ 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->access_log) xmlFree(c->access_log);
if (c->error_log) xmlFree(c->error_log); if (c->error_log) xmlFree(c->error_log);
if (c->shoutcast_mount) xmlFree(c->shoutcast_mount); 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_server) xmlFree(c->master_server);
if (c->master_username) xmlFree(c->master_username); if (c->master_username) xmlFree(c->master_username);
if (c->master_password) xmlFree(c->master_password); if (c->master_password) xmlFree(c->master_password);
...@@ -193,6 +201,9 @@ void config_clear(ice_config_t *c) ...@@ -193,6 +201,9 @@ void config_clear(ice_config_t *c)
if (c->group) xmlFree(c->group); if (c->group) xmlFree(c->group);
if (c->mimetypes_fn) xmlFree (c->mimetypes_fn); if (c->mimetypes_fn) xmlFree (c->mimetypes_fn);
while ((c->listen_sock = config_clear_listener (c->listen_sock)))
;
thread_mutex_lock(&(_locks.relay_lock)); thread_mutex_lock(&(_locks.relay_lock));
relay = c->relay; relay = c->relay;
while(relay) { while(relay) {
...@@ -342,10 +353,7 @@ static void _set_defaults(ice_config_t *configuration) ...@@ -342,10 +353,7 @@ static void _set_defaults(ice_config_t *configuration)
configuration->dir_list = NULL; configuration->dir_list = NULL;
configuration->hostname = (char *)xmlCharStrdup (CONFIG_DEFAULT_HOSTNAME); configuration->hostname = (char *)xmlCharStrdup (CONFIG_DEFAULT_HOSTNAME);
configuration->mimetypes_fn = (char *)xmlCharStrdup (MIMETYPESFILE); configuration->mimetypes_fn = (char *)xmlCharStrdup (MIMETYPESFILE);
configuration->port = 0; configuration->port = 8000;
configuration->listeners[0].port = 0;
configuration->listeners[0].bind_address = NULL;
configuration->listeners[0].shoutcast_compat = 0;
configuration->master_server = NULL; configuration->master_server = NULL;
configuration->master_server_port = 0; configuration->master_server_port = 0;
configuration->master_update_interval = CONFIG_MASTER_UPDATE_INTERVAL; configuration->master_update_interval = CONFIG_MASTER_UPDATE_INTERVAL;
...@@ -375,6 +383,10 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node, ...@@ -375,6 +383,10 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
{ {
char *tmp; char *tmp;
configuration->listen_sock = calloc (1, sizeof (*configuration->listen_sock));
configuration->listen_sock->port = 8000;
configuration->listen_sock_count = 1;
do { do {
if (node == NULL) break; if (node == NULL) break;
if (xmlIsBlankNode(node)) continue; if (xmlIsBlankNode(node)) continue;
...@@ -424,12 +436,12 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node, ...@@ -424,12 +436,12 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
} else if (xmlStrcmp (node->name, XMLSTR("port")) == 0) { } else if (xmlStrcmp (node->name, XMLSTR("port")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->port = atoi(tmp); configuration->port = atoi(tmp);
configuration->listeners[0].port = atoi(tmp); configuration->listen_sock->port = atoi(tmp);
if (tmp) xmlFree(tmp); if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("bind-address")) == 0) { } else if (xmlStrcmp (node->name, XMLSTR("bind-address")) == 0) {
if (configuration->listeners[0].bind_address) if (configuration->listen_sock->bind_address)
xmlFree(configuration->listeners[0].bind_address); xmlFree(configuration->listen_sock->bind_address);
configuration->listeners[0].bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); configuration->listen_sock->bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("master-server")) == 0) { } else if (xmlStrcmp (node->name, XMLSTR("master-server")) == 0) {
if (configuration->master_server) xmlFree(configuration->master_server); if (configuration->master_server) xmlFree(configuration->master_server);
configuration->master_server = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); configuration->master_server = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
...@@ -751,19 +763,13 @@ static void _parse_relay(xmlDocPtr doc, xmlNodePtr node, ...@@ -751,19 +763,13 @@ static void _parse_relay(xmlDocPtr doc, xmlNodePtr node,
static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node, static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration) ice_config_t *configuration)
{ {
listener_t *listener = NULL;
int i;
char *tmp; 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) if (listener == NULL)
return; return;
listener->port = 8000;
do { do {
if (node == NULL) break; if (node == NULL) break;
if (xmlIsBlankNode(node)) continue; if (xmlIsBlankNode(node)) continue;
...@@ -790,6 +796,10 @@ static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node, ...@@ -790,6 +796,10 @@ static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
node->xmlChildrenNode, 1); node->xmlChildrenNode, 1);
} }
} while ((node = node->next)); } 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, static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
...@@ -1068,3 +1078,29 @@ mount_proxy *config_find_mount (ice_config_t *config, const char *mount) ...@@ -1068,3 +1078,29 @@ mount_proxy *config_find_mount (ice_config_t *config, const char *mount)
return mountinfo; 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; ...@@ -26,6 +26,7 @@ struct _mount_proxy;
#include "avl/avl.h" #include "avl/avl.h"
#include "auth.h" #include "auth.h"
#include "global.h" #include "global.h"
#include "connection.h"
#define XMLSTR(str) ((xmlChar *)(str)) #define XMLSTR(str) ((xmlChar *)(str))
...@@ -97,7 +98,8 @@ typedef struct _aliases { ...@@ -97,7 +98,8 @@ typedef struct _aliases {
struct _aliases *next; struct _aliases *next;
}aliases; }aliases;
typedef struct { typedef struct _listener_t {
struct _listener_t *next;
int port; int port;
char *bind_address; char *bind_address;
int shoutcast_compat; int shoutcast_compat;
...@@ -137,7 +139,8 @@ typedef struct ice_config_tag ...@@ -137,7 +139,8 @@ typedef struct ice_config_tag
int port; int port;
char *mimetypes_fn; char *mimetypes_fn;
listener_t listeners[MAX_LISTEN_SOCKETS]; listener_t *listen_sock;
unsigned int listen_sock_count;
char *master_server; char *master_server;
int master_server_port; int master_server_port;
...@@ -187,8 +190,10 @@ int config_parse_file(const char *filename, ice_config_t *configuration); ...@@ -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_initial_parse_file(const char *filename);
int config_parse_cmdline(int arg, char **argv); int config_parse_cmdline(int arg, char **argv);
void config_set_config(ice_config_t *config); void config_set_config(ice_config_t *config);
listener_t *config_clear_listener (listener_t *listener);
void config_clear(ice_config_t *config); void config_clear(ice_config_t *config);
mount_proxy *config_find_mount (ice_config_t *config, const char *mount); 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); int config_rehash(void);
......
...@@ -592,8 +592,8 @@ void connection_accept_loop(void) ...@@ -592,8 +592,8 @@ void connection_accept_loop(void)
{ {
client_queue_t *node; client_queue_t *node;
ice_config_t *config; ice_config_t *config;
int i;
client_t *client = NULL; client_t *client = NULL;
listener_t *listener;
global_lock(); global_lock();
if (client_create (&client, con, NULL) < 0) if (client_create (&client, con, NULL) < 0)
...@@ -615,17 +615,15 @@ void connection_accept_loop(void) ...@@ -615,17 +615,15 @@ void connection_accept_loop(void)
} }
node->client = client; node->client = client;
/* Check for special shoutcast compatability processing */
config = config_get_config(); 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 (listener->shoutcast_compat)
{ node->shoutcast = 1;
if (config->listeners[i].shoutcast_compat) if (listener->ssl && ssl_ok)
node->shoutcast = 1; connection_uses_ssl (client->con);
if (config->listeners[i].ssl && ssl_ok)
connection_uses_ssl (client->con);
}
} }
config_release_config(); config_release_config();
...@@ -966,22 +964,22 @@ static void _handle_get_request (client_t *client, char *passed_uri) ...@@ -966,22 +964,22 @@ static void _handle_get_request (client_t *client, char *passed_uri)
{ {
int fileserve; int fileserve;
int port; int port;
int i;
char *serverhost = NULL; char *serverhost = NULL;
int serverport = 0; int serverport = 0;
aliases *alias; aliases *alias;
ice_config_t *config; ice_config_t *config;
char *uri = passed_uri; char *uri = passed_uri;
listener_t *listen_sock;
config = config_get_config(); config = config_get_config();
fileserve = config->fileserve; fileserve = config->fileserve;
port = config->port; port = config->port;
for(i = 0; i < global.server_sockets; i++) {
if(global.serversock[i] == client->con->serversock) { listen_sock = config_get_listen_sock (config, client->con);
serverhost = config->listeners[i].bind_address; if (listen_sock)
serverport = config->listeners[i].port; {
break; serverhost = listen_sock->bind_address;
} serverport = listen_sock->port;
} }
alias = config->aliases; alias = config->aliases;
...@@ -1211,6 +1209,80 @@ static void *_handle_connection(void *arg) ...@@ -1211,6 +1209,80 @@ static void *_handle_connection(void *arg)
return NULL; 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) void connection_close(connection_t *con)
{ {
sock_close(con->sock); sock_close(con->sock);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
struct _client_tag; struct _client_tag;
struct source_tag; struct source_tag;
struct ice_config_tag;
typedef struct connection_tag typedef struct connection_tag
{ {
...@@ -54,6 +55,7 @@ typedef struct connection_tag ...@@ -54,6 +55,7 @@ typedef struct connection_tag
void connection_initialize(void); void connection_initialize(void);
void connection_shutdown(void); void connection_shutdown(void);
void connection_accept_loop(void); void connection_accept_loop(void);
int connection_setup_sockets (struct ice_config_tag *config);
void connection_close(connection_t *con); void connection_close(connection_t *con);
connection_t *connection_create (sock_t sock, sock_t serversock, char *ip); connection_t *connection_create (sock_t sock, sock_t serversock, char *ip);
int connection_complete_source (struct source_tag *source, int response); int connection_complete_source (struct source_tag *source, int response);
......
...@@ -35,7 +35,6 @@ static mutex_t _global_mutex; ...@@ -35,7 +35,6 @@ static mutex_t _global_mutex;
void global_initialize(void) void global_initialize(void)
{ {
memset(global.serversock, 0, sizeof(int)*MAX_LISTEN_SOCKETS);
global.server_sockets = 0; global.server_sockets = 0;
global.relays = NULL; global.relays = NULL;
global.master_relays = NULL; global.master_relays = NULL;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
typedef struct ice_global_tag typedef struct ice_global_tag
{ {
int serversock[MAX_LISTEN_SOCKETS]; int *serversock;
int server_sockets; int server_sockets;
int running; int running;
......
...@@ -261,41 +261,6 @@ static int _start_logging(void) ...@@ -261,41 +261,6 @@ static int _start_logging(void)
return 0; 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) static int _start_listening(void)
{ {
...@@ -313,9 +278,9 @@ static int _start_listening(void) ...@@ -313,9 +278,9 @@ static int _start_listening(void)
/* bind the socket and start listening */ /* bind the socket and start listening */
static int _server_proc_init(void) 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; return 0;
if (!_start_listening()) { if (!_start_listening()) {
...@@ -323,7 +288,6 @@ static int _server_proc_init(void) ...@@ -323,7 +288,6 @@ static int _server_proc_init(void)
return 0; return 0;
} }
config = config_get_config_unlocked();
/* recreate the pid file */ /* recreate the pid file */
if (config->pidfile) if (config->pidfile)
{ {
...@@ -342,8 +306,6 @@ static int _server_proc_init(void) ...@@ -342,8 +306,6 @@ static int _server_proc_init(void)
/* this is the heart of the beast */ /* this is the heart of the beast */
static void _server_proc(void) static void _server_proc(void)
{ {
int i;
if (background) if (background)
{ {
fclose (stdin); fclose (stdin);
...@@ -352,8 +314,7 @@ static void _server_proc(void) ...@@ -352,8 +314,7 @@ static void _server_proc(void)
} }
connection_accept_loop(); connection_accept_loop();
for(i=0; i < MAX_LISTEN_SOCKETS; i++) connection_setup_sockets (NULL);
sock_close(global.serversock[i]);
} }
/* chroot the process. Watch out - we need to do this before starting other /* 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