mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
Don't impose a limit on the number of listening sockets allowed in the xml
svn path=/icecast/trunk/icecast/; revision=13995
This commit is contained in:
parent
e065acb7f1
commit
ba438dd7b5
@ -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);
|
||||
|
||||
|
106
src/connection.c
106
src/connection.c
@ -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;
|
||||
|
45
src/main.c
45
src/main.c
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user