mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-04-18 00:48:43 -04:00
Merge branch 'epirat-yp-listenurl-fix'
Good work. Thanks to ePirat.
This commit is contained in:
commit
987bdec373
189
src/cfgfile.c
189
src/cfgfile.c
@ -63,7 +63,6 @@
|
|||||||
#define CONFIG_DEFAULT_SHOUTCAST_MOUNT "/stream"
|
#define CONFIG_DEFAULT_SHOUTCAST_MOUNT "/stream"
|
||||||
#define CONFIG_DEFAULT_SHOUTCAST_USER "source"
|
#define CONFIG_DEFAULT_SHOUTCAST_USER "source"
|
||||||
#define CONFIG_DEFAULT_FILESERVE 1
|
#define CONFIG_DEFAULT_FILESERVE 1
|
||||||
#define CONFIG_DEFAULT_TOUCH_FREQ 5
|
|
||||||
#define CONFIG_DEFAULT_HOSTNAME "localhost"
|
#define CONFIG_DEFAULT_HOSTNAME "localhost"
|
||||||
#define CONFIG_DEFAULT_PLAYLIST_LOG NULL
|
#define CONFIG_DEFAULT_PLAYLIST_LOG NULL
|
||||||
#define CONFIG_DEFAULT_ACCESS_LOG "access.log"
|
#define CONFIG_DEFAULT_ACCESS_LOG "access.log"
|
||||||
@ -161,7 +160,8 @@ static ice_config_locks _locks;
|
|||||||
static void _set_defaults(ice_config_t *c);
|
static void _set_defaults(ice_config_t *c);
|
||||||
static void _parse_root(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
static void _parse_root(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
||||||
static void _parse_limits(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
static void _parse_limits(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
||||||
static void _parse_directory(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
static void _parse_oldstyle_directory(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
||||||
|
static void _parse_yp_directory(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
||||||
static void _parse_paths(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
static void _parse_paths(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
||||||
static void _parse_logging(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
static void _parse_logging(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
||||||
static void _parse_security(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
static void _parse_security(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
||||||
@ -178,7 +178,6 @@ static void _parse_listen_socket(xmlDocPtr doc,
|
|||||||
xmlNodePtr node,
|
xmlNodePtr node,
|
||||||
ice_config_t *c);
|
ice_config_t *c);
|
||||||
|
|
||||||
static void _add_server(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
|
||||||
static void _parse_events(event_registration_t **events, xmlNodePtr node);
|
static void _parse_events(event_registration_t **events, xmlNodePtr node);
|
||||||
|
|
||||||
static void merge_mounts(mount_proxy * dst, mount_proxy * src);
|
static void merge_mounts(mount_proxy * dst, mount_proxy * src);
|
||||||
@ -633,6 +632,19 @@ static void config_clear_resource(resource_t *resource)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void config_clear_yp_directories(yp_directory_t *yp_dir)
|
||||||
|
{
|
||||||
|
yp_directory_t *next_yp_dir;
|
||||||
|
|
||||||
|
while (yp_dir) {
|
||||||
|
next_yp_dir = yp_dir->next;
|
||||||
|
free(yp_dir->url);
|
||||||
|
free(yp_dir->listen_socket_id);
|
||||||
|
free(yp_dir);
|
||||||
|
yp_dir = next_yp_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
listener_t *config_clear_listener(listener_t *listener)
|
listener_t *config_clear_listener(listener_t *listener)
|
||||||
{
|
{
|
||||||
listener_t *next = NULL;
|
listener_t *next = NULL;
|
||||||
@ -651,8 +663,6 @@ listener_t *config_clear_listener(listener_t *listener)
|
|||||||
|
|
||||||
void config_clear(ice_config_t *c)
|
void config_clear(ice_config_t *c)
|
||||||
{
|
{
|
||||||
ice_config_dir_t *dirnode,
|
|
||||||
*nextdirnode;
|
|
||||||
mount_proxy *mount,
|
mount_proxy *mount,
|
||||||
*nextmount;
|
*nextmount;
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -708,17 +718,8 @@ void config_clear(ice_config_t *c)
|
|||||||
|
|
||||||
config_clear_resource(c->resources);
|
config_clear_resource(c->resources);
|
||||||
|
|
||||||
dirnode = c->dir_list;
|
|
||||||
while (dirnode) {
|
|
||||||
nextdirnode = dirnode->next;
|
|
||||||
xmlFree(dirnode->host);
|
|
||||||
free(dirnode);
|
|
||||||
dirnode = nextdirnode;
|
|
||||||
}
|
|
||||||
#ifdef USE_YP
|
#ifdef USE_YP
|
||||||
for (i = 0; i < c->num_yp_directories; i++) {
|
config_clear_yp_directories(c->yp_directories);
|
||||||
xmlFree(c->yp_url[i]);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
config_clear_http_header(c->http_headers);
|
config_clear_http_header(c->http_headers);
|
||||||
@ -877,12 +878,8 @@ static void _set_defaults(ice_config_t *configuration)
|
|||||||
->shoutcast_user = (char *) xmlCharStrdup(CONFIG_DEFAULT_SHOUTCAST_USER);
|
->shoutcast_user = (char *) xmlCharStrdup(CONFIG_DEFAULT_SHOUTCAST_USER);
|
||||||
configuration
|
configuration
|
||||||
->fileserve = CONFIG_DEFAULT_FILESERVE;
|
->fileserve = CONFIG_DEFAULT_FILESERVE;
|
||||||
configuration
|
|
||||||
->touch_interval = CONFIG_DEFAULT_TOUCH_FREQ;
|
|
||||||
configuration
|
configuration
|
||||||
->on_demand = 0;
|
->on_demand = 0;
|
||||||
configuration
|
|
||||||
->dir_list = NULL;
|
|
||||||
configuration
|
configuration
|
||||||
->hostname = (char *) xmlCharStrdup(CONFIG_DEFAULT_HOSTNAME);
|
->hostname = (char *) xmlCharStrdup(CONFIG_DEFAULT_HOSTNAME);
|
||||||
configuration
|
configuration
|
||||||
@ -923,8 +920,6 @@ static void _set_defaults(ice_config_t *configuration)
|
|||||||
->user = NULL;
|
->user = NULL;
|
||||||
configuration
|
configuration
|
||||||
->group = NULL;
|
->group = NULL;
|
||||||
configuration
|
|
||||||
->num_yp_directories = 0;
|
|
||||||
/* default to a typical prebuffer size used by clients */
|
/* default to a typical prebuffer size used by clients */
|
||||||
configuration
|
configuration
|
||||||
->burst_size = CONFIG_DEFAULT_BURST_SIZE;
|
->burst_size = CONFIG_DEFAULT_BURST_SIZE;
|
||||||
@ -1094,7 +1089,9 @@ static void _parse_root(xmlDocPtr doc,
|
|||||||
} else if (xmlStrcmp(node->name, XMLSTR("mount")) == 0) {
|
} else if (xmlStrcmp(node->name, XMLSTR("mount")) == 0) {
|
||||||
_parse_mount(doc, node, configuration);
|
_parse_mount(doc, node, configuration);
|
||||||
} else if (xmlStrcmp(node->name, XMLSTR("directory")) == 0) {
|
} else if (xmlStrcmp(node->name, XMLSTR("directory")) == 0) {
|
||||||
_parse_directory(doc, node->xmlChildrenNode, configuration);
|
_parse_oldstyle_directory(doc, node->xmlChildrenNode, configuration);
|
||||||
|
} else if (xmlStrcmp(node->name, XMLSTR("yp-directory")) == 0) {
|
||||||
|
_parse_yp_directory(doc, node, configuration);
|
||||||
} else if (xmlStrcmp(node->name, XMLSTR("paths")) == 0) {
|
} else if (xmlStrcmp(node->name, XMLSTR("paths")) == 0) {
|
||||||
_parse_paths(doc, node->xmlChildrenNode, configuration);
|
_parse_paths(doc, node->xmlChildrenNode, configuration);
|
||||||
} else if (xmlStrcmp(node->name, XMLSTR("logging")) == 0) {
|
} else if (xmlStrcmp(node->name, XMLSTR("logging")) == 0) {
|
||||||
@ -2048,14 +2045,19 @@ static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
|
|||||||
configuration->authstack = old_style;
|
configuration->authstack = old_style;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _parse_directory(xmlDocPtr doc,
|
static void _parse_oldstyle_directory(xmlDocPtr doc,
|
||||||
xmlNodePtr node,
|
xmlNodePtr node,
|
||||||
ice_config_t *configuration)
|
ice_config_t *configuration)
|
||||||
{
|
{
|
||||||
if (configuration->num_yp_directories >= MAX_YP_DIRECTORIES) {
|
yp_directory_t *yp_dir,
|
||||||
ICECAST_LOG_ERROR("Maximum number of yp directories exceeded!");
|
*current, *last;
|
||||||
|
|
||||||
|
yp_dir = calloc(1, sizeof(*yp_dir));
|
||||||
|
if (yp_dir == NULL) {
|
||||||
|
ICECAST_LOG_ERROR("Can not allocate memory for YP directory entry.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
break;
|
break;
|
||||||
@ -2063,21 +2065,93 @@ static void _parse_directory(xmlDocPtr doc,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (xmlStrcmp(node->name, XMLSTR("yp-url")) == 0) {
|
if (xmlStrcmp(node->name, XMLSTR("yp-url")) == 0) {
|
||||||
if (configuration->yp_url[configuration->num_yp_directories])
|
if (yp_dir->url)
|
||||||
xmlFree(configuration->yp_url[configuration->num_yp_directories]);
|
xmlFree(yp_dir->url);
|
||||||
configuration->yp_url[configuration->num_yp_directories] =
|
yp_dir->url = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||||
(char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
|
||||||
} else if (xmlStrcmp(node->name, XMLSTR("yp-url-timeout")) == 0) {
|
} else if (xmlStrcmp(node->name, XMLSTR("yp-url-timeout")) == 0) {
|
||||||
__read_int(doc, node, &configuration->yp_url_timeout[configuration->num_yp_directories], "<yp-url-timeout> must not be empty.");
|
__read_int(doc, node, &yp_dir->timeout, "<yp-url-timeout> must not be empty.");
|
||||||
} else if (xmlStrcmp(node->name, XMLSTR("server")) == 0) {
|
|
||||||
_add_server(doc, node->xmlChildrenNode, configuration);
|
|
||||||
} else if (xmlStrcmp(node->name, XMLSTR("touch-interval")) == 0) {
|
} else if (xmlStrcmp(node->name, XMLSTR("touch-interval")) == 0) {
|
||||||
__read_int(doc, node, &configuration->yp_touch_interval[configuration->num_yp_directories], "<touch-interval> must not be empty.");
|
__read_int(doc, node, &yp_dir->touch_interval, "<touch-interval> must not be empty.");
|
||||||
}
|
}
|
||||||
} while ((node = node->next));
|
} while ((node = node->next));
|
||||||
if (configuration->yp_url[configuration->num_yp_directories] == NULL)
|
|
||||||
|
if (yp_dir->url == NULL)
|
||||||
return;
|
return;
|
||||||
configuration->num_yp_directories++;
|
|
||||||
|
/* Append YP directory entry to the global list */
|
||||||
|
current = configuration->yp_directories;
|
||||||
|
last = NULL;
|
||||||
|
while (current) {
|
||||||
|
last = current;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
if (last) {
|
||||||
|
last->next = yp_dir;
|
||||||
|
} else {
|
||||||
|
configuration->yp_directories = yp_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _parse_yp_directory(xmlDocPtr doc,
|
||||||
|
xmlNodePtr node,
|
||||||
|
ice_config_t *configuration)
|
||||||
|
{
|
||||||
|
char *url;
|
||||||
|
config_options_t *options;
|
||||||
|
yp_directory_t *yp_dir,
|
||||||
|
*current, *last;
|
||||||
|
|
||||||
|
url = (char *)xmlGetProp(node, XMLSTR("url"));
|
||||||
|
if (url == NULL) {
|
||||||
|
ICECAST_LOG_ERROR("Missing mandatory attribute 'url' for <yp-directory>.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
yp_dir = calloc(1, sizeof(*yp_dir));
|
||||||
|
if (yp_dir == NULL) {
|
||||||
|
ICECAST_LOG_ERROR("Can not allocate memory for YP directory entry.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
yp_dir->url = url;
|
||||||
|
|
||||||
|
options = config_parse_options(node);
|
||||||
|
for (config_options_t *opt = options; opt; opt = opt->next) {
|
||||||
|
if (!opt->name || !opt->value) {
|
||||||
|
ICECAST_LOG_WARN("Invalid <option>, missing 'name' and 'value' attributes.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(opt->name, "timeout") == 0) {
|
||||||
|
yp_dir->timeout = util_str_to_int(opt->value, yp_dir->timeout);
|
||||||
|
} else if (strcmp(opt->name, "touch-interval") == 0) {
|
||||||
|
yp_dir->touch_interval = util_str_to_int(opt->value, yp_dir->touch_interval);
|
||||||
|
} else if (strcmp(opt->name, "listen-socket") == 0) {
|
||||||
|
if (yp_dir->listen_socket_id) {
|
||||||
|
ICECAST_LOG_ERROR(
|
||||||
|
"Multiple 'listen-socket' in <yp-directory> currently unsupported. "
|
||||||
|
"Only the last one will be used.");
|
||||||
|
free(yp_dir->listen_socket_id);
|
||||||
|
}
|
||||||
|
yp_dir->listen_socket_id = config_href_to_id(opt->value);
|
||||||
|
} else {
|
||||||
|
ICECAST_LOG_WARN("Invalid YP <option> with unknown 'name' attribute.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_clear_options(options);
|
||||||
|
|
||||||
|
/* Append YP directory entry to the global list */
|
||||||
|
current = configuration->yp_directories;
|
||||||
|
last = NULL;
|
||||||
|
while (current) {
|
||||||
|
last = current;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
if (last) {
|
||||||
|
last->next = yp_dir;
|
||||||
|
} else {
|
||||||
|
configuration->yp_directories = yp_dir;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _parse_resource(xmlDocPtr doc,
|
static void _parse_resource(xmlDocPtr doc,
|
||||||
@ -2416,51 +2490,6 @@ static void _parse_security(xmlDocPtr doc,
|
|||||||
} while ((node = node->next));
|
} while ((node = node->next));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _add_server(xmlDocPtr doc,
|
|
||||||
xmlNodePtr node,
|
|
||||||
ice_config_t *configuration)
|
|
||||||
{
|
|
||||||
ice_config_dir_t *dirnode,
|
|
||||||
*server;
|
|
||||||
int addnode;
|
|
||||||
|
|
||||||
server = (ice_config_dir_t *)malloc(sizeof(ice_config_dir_t));
|
|
||||||
server->touch_interval = configuration->touch_interval;
|
|
||||||
server->host = NULL;
|
|
||||||
addnode = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (node == NULL)
|
|
||||||
break;
|
|
||||||
if (xmlIsBlankNode(node))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (xmlStrcmp(node->name, XMLSTR("host")) == 0) {
|
|
||||||
server->host = (char *) xmlNodeListGetString(doc,
|
|
||||||
node->xmlChildrenNode, 1);
|
|
||||||
addnode = 1;
|
|
||||||
} else if (xmlStrcmp(node->name, XMLSTR("touch-interval")) == 0) {
|
|
||||||
__read_int(doc, node, &server->touch_interval, "<touch-interval> must not be empty.");
|
|
||||||
}
|
|
||||||
server->next = NULL;
|
|
||||||
} while ((node = node->next));
|
|
||||||
|
|
||||||
if (addnode) {
|
|
||||||
dirnode = configuration->dir_list;
|
|
||||||
if (dirnode == NULL) {
|
|
||||||
configuration->dir_list = server;
|
|
||||||
} else {
|
|
||||||
while (dirnode->next) dirnode = dirnode->next;
|
|
||||||
dirnode->next = server;
|
|
||||||
}
|
|
||||||
|
|
||||||
server = NULL;
|
|
||||||
addnode = 0;
|
|
||||||
} else {
|
|
||||||
free (server);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _parse_events(event_registration_t **events, xmlNodePtr node)
|
static void _parse_events(event_registration_t **events, xmlNodePtr node)
|
||||||
{
|
{
|
||||||
while (node) {
|
while (node) {
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
#define CONFIG_EBADROOT -3
|
#define CONFIG_EBADROOT -3
|
||||||
#define CONFIG_EPARSE -4
|
#define CONFIG_EPARSE -4
|
||||||
|
|
||||||
#define MAX_YP_DIRECTORIES 25
|
|
||||||
|
|
||||||
#include <libxml/tree.h>
|
#include <libxml/tree.h>
|
||||||
#include "common/thread/thread.h"
|
#include "common/thread/thread.h"
|
||||||
#include "common/avl/avl.h"
|
#include "common/avl/avl.h"
|
||||||
@ -52,12 +50,6 @@ typedef struct ice_config_http_header_tag {
|
|||||||
struct ice_config_http_header_tag *next;
|
struct ice_config_http_header_tag *next;
|
||||||
} ice_config_http_header_t;
|
} ice_config_http_header_t;
|
||||||
|
|
||||||
typedef struct ice_config_dir_tag {
|
|
||||||
char *host;
|
|
||||||
int touch_interval;
|
|
||||||
struct ice_config_dir_tag *next;
|
|
||||||
} ice_config_dir_t;
|
|
||||||
|
|
||||||
struct _config_options {
|
struct _config_options {
|
||||||
char *type;
|
char *type;
|
||||||
char *name;
|
char *name;
|
||||||
@ -150,6 +142,14 @@ typedef struct _resource {
|
|||||||
struct _resource *next;
|
struct _resource *next;
|
||||||
} resource_t;
|
} resource_t;
|
||||||
|
|
||||||
|
typedef struct _yp_directory {
|
||||||
|
char *url;
|
||||||
|
int timeout;
|
||||||
|
int touch_interval;
|
||||||
|
char *listen_socket_id;
|
||||||
|
struct _yp_directory *next;
|
||||||
|
} yp_directory_t;
|
||||||
|
|
||||||
typedef enum _listener_type_tag {
|
typedef enum _listener_type_tag {
|
||||||
LISTENER_TYPE_ERROR,
|
LISTENER_TYPE_ERROR,
|
||||||
LISTENER_TYPE_NORMAL,
|
LISTENER_TYPE_NORMAL,
|
||||||
@ -219,9 +219,6 @@ struct ice_config_tag {
|
|||||||
|
|
||||||
struct event_registration_tag *event;
|
struct event_registration_tag *event;
|
||||||
|
|
||||||
int touch_interval;
|
|
||||||
ice_config_dir_t *dir_list;
|
|
||||||
|
|
||||||
char *hostname;
|
char *hostname;
|
||||||
int sane_hostname;
|
int sane_hostname;
|
||||||
int port;
|
int port;
|
||||||
@ -271,10 +268,8 @@ struct ice_config_tag {
|
|||||||
int chuid;
|
int chuid;
|
||||||
char *user;
|
char *user;
|
||||||
char *group;
|
char *group;
|
||||||
char *yp_url[MAX_YP_DIRECTORIES];
|
|
||||||
int yp_url_timeout[MAX_YP_DIRECTORIES];
|
yp_directory_t *yp_directories;
|
||||||
int yp_touch_interval[MAX_YP_DIRECTORIES];
|
|
||||||
size_t num_yp_directories;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -39,8 +39,6 @@ int main(void)
|
|||||||
|
|
||||||
void _dump_config(ice_config_t *config)
|
void _dump_config(ice_config_t *config)
|
||||||
{
|
{
|
||||||
ice_config_dir_t *node;
|
|
||||||
|
|
||||||
printf("-----\n");
|
printf("-----\n");
|
||||||
printf("location = %s\n", config->location);
|
printf("location = %s\n", config->location);
|
||||||
printf("admin = %s\n", config->admin);
|
printf("admin = %s\n", config->admin);
|
||||||
@ -49,16 +47,6 @@ void _dump_config(ice_config_t *config)
|
|||||||
printf("threadpool_size = %d\n", config->threadpool_size);
|
printf("threadpool_size = %d\n", config->threadpool_size);
|
||||||
printf("client_timeout = %d\n", config->client_timeout);
|
printf("client_timeout = %d\n", config->client_timeout);
|
||||||
printf("source_password = %s\n", config->source_password);
|
printf("source_password = %s\n", config->source_password);
|
||||||
printf("touch_interval = %d\n", config->touch_interval);
|
|
||||||
|
|
||||||
node = config->dir_list;
|
|
||||||
while (node) {
|
|
||||||
printf("directory.touch_interval = %d\n", node->touch_interval);
|
|
||||||
printf("directory.host = %s\n", node->host);
|
|
||||||
|
|
||||||
node = node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("hostname = %s\n", config->hostname);
|
printf("hostname = %s\n", config->hostname);
|
||||||
printf("port = %d\n", config->port);
|
printf("port = %d\n", config->port);
|
||||||
printf("bind_address = %s\n", config->bind_address);
|
printf("bind_address = %s\n", config->bind_address);
|
||||||
|
@ -53,7 +53,6 @@ struct listensocket_tag {
|
|||||||
sock_t sock;
|
sock_t sock;
|
||||||
};
|
};
|
||||||
|
|
||||||
static listensocket_t * listensocket_container_get_by_id(listensocket_container_t *self, const char *id);
|
|
||||||
static int listensocket_container_configure__unlocked(listensocket_container_t *self, const ice_config_t *config);
|
static int listensocket_container_configure__unlocked(listensocket_container_t *self, const ice_config_t *config);
|
||||||
static int listensocket_container_setup__unlocked(listensocket_container_t *self);
|
static int listensocket_container_setup__unlocked(listensocket_container_t *self);
|
||||||
static ssize_t listensocket_container_sockcount__unlocked(listensocket_container_t *self);
|
static ssize_t listensocket_container_sockcount__unlocked(listensocket_container_t *self);
|
||||||
@ -484,7 +483,7 @@ static ssize_t listensocket_container_sockcount__unlocked(listensocket_container
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static listensocket_t * listensocket_container_get_by_id(listensocket_container_t *self, const char *id)
|
listensocket_t * listensocket_container_get_by_id(listensocket_container_t *self, const char *id)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
const listener_t *listener;
|
const listener_t *listener;
|
||||||
|
@ -22,6 +22,7 @@ int listensocket_container_setup(listensocket_container_
|
|||||||
connection_t * listensocket_container_accept(listensocket_container_t *self, int timeout);
|
connection_t * listensocket_container_accept(listensocket_container_t *self, int timeout);
|
||||||
int listensocket_container_set_sockcount_cb(listensocket_container_t *self, void (*cb)(size_t count, void *userdata), void *userdata);
|
int listensocket_container_set_sockcount_cb(listensocket_container_t *self, void (*cb)(size_t count, void *userdata), void *userdata);
|
||||||
ssize_t listensocket_container_sockcount(listensocket_container_t *self);
|
ssize_t listensocket_container_sockcount(listensocket_container_t *self);
|
||||||
|
listensocket_t * listensocket_container_get_by_id(listensocket_container_t *self, const char *id);
|
||||||
|
|
||||||
REFOBJECT_FORWARD_TYPE(listensocket_t);
|
REFOBJECT_FORWARD_TYPE(listensocket_t);
|
||||||
|
|
||||||
|
64
src/yp.c
64
src/yp.c
@ -29,6 +29,7 @@
|
|||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "cfgfile.h"
|
#include "cfgfile.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
|
#include "listensocket.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
@ -43,6 +44,7 @@ struct yp_server
|
|||||||
unsigned url_timeout;
|
unsigned url_timeout;
|
||||||
unsigned touch_interval;
|
unsigned touch_interval;
|
||||||
int remove;
|
int remove;
|
||||||
|
char *listen_socket_id;
|
||||||
|
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
struct ypdata_tag *mounts, *pending_mounts;
|
struct ypdata_tag *mounts, *pending_mounts;
|
||||||
@ -217,7 +219,6 @@ static ypdata_t *find_yp_mount (ypdata_t *mounts, const char *mount)
|
|||||||
|
|
||||||
void yp_recheck_config (ice_config_t *config)
|
void yp_recheck_config (ice_config_t *config)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
struct yp_server *server;
|
struct yp_server *server;
|
||||||
|
|
||||||
ICECAST_LOG_DEBUG("Updating YP configuration");
|
ICECAST_LOG_DEBUG("Updating YP configuration");
|
||||||
@ -234,9 +235,9 @@ void yp_recheck_config (ice_config_t *config)
|
|||||||
server_version = strdup (config->server_id);
|
server_version = strdup (config->server_id);
|
||||||
/* for each yp url in config, check to see if one exists
|
/* for each yp url in config, check to see if one exists
|
||||||
if not, then add it. */
|
if not, then add it. */
|
||||||
for (i=0 ; i < config->num_yp_directories; i++)
|
for (yp_directory_t *yp = config->yp_directories; yp; yp = yp->next)
|
||||||
{
|
{
|
||||||
server = find_yp_server (config->yp_url[i]);
|
server = find_yp_server (yp->url);
|
||||||
if (server == NULL)
|
if (server == NULL)
|
||||||
{
|
{
|
||||||
server = calloc (1, sizeof (struct yp_server));
|
server = calloc (1, sizeof (struct yp_server));
|
||||||
@ -247,9 +248,10 @@ void yp_recheck_config (ice_config_t *config)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
server->server_id = strdup ((char *)server_version);
|
server->server_id = strdup ((char *)server_version);
|
||||||
server->url = strdup (config->yp_url[i]);
|
server->url = strdup (yp->url);
|
||||||
server->url_timeout = config->yp_url_timeout[i];
|
server->url_timeout = yp->timeout;
|
||||||
server->touch_interval = config->yp_touch_interval[i];
|
server->touch_interval = yp->touch_interval;
|
||||||
|
server->listen_socket_id = yp->listen_socket_id;
|
||||||
server->curl = icecast_curl_new(server->url, &(server->curl_error[0]));
|
server->curl = icecast_curl_new(server->url, &(server->curl_error[0]));
|
||||||
if (server->curl == NULL)
|
if (server->curl == NULL)
|
||||||
{
|
{
|
||||||
@ -563,16 +565,19 @@ static void yp_process_server (struct yp_server *server)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static ypdata_t *create_yp_entry (const char *mount)
|
static ypdata_t *create_yp_entry (struct yp_server *server, const char *mount)
|
||||||
{
|
{
|
||||||
ypdata_t *yp;
|
ypdata_t *yp;
|
||||||
char *s;
|
|
||||||
|
if (!server)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
yp = calloc (1, sizeof (ypdata_t));
|
yp = calloc (1, sizeof (ypdata_t));
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
listensocket_t *listen_socket = NULL;
|
||||||
unsigned len = 512;
|
unsigned len = 512;
|
||||||
int ret;
|
ssize_t ret;
|
||||||
char *url;
|
char *url;
|
||||||
mount_proxy *mountproxy = NULL;
|
mount_proxy *mountproxy = NULL;
|
||||||
ice_config_t *config;
|
ice_config_t *config;
|
||||||
@ -595,15 +600,33 @@ static ypdata_t *create_yp_entry (const char *mount)
|
|||||||
url = malloc (len);
|
url = malloc (len);
|
||||||
if (url == NULL)
|
if (url == NULL)
|
||||||
break;
|
break;
|
||||||
config = config_get_config();
|
|
||||||
ret = snprintf (url, len, "http://%s:%d%s", config->hostname, config->port, mount);
|
|
||||||
if (ret >= (signed)len)
|
|
||||||
{
|
|
||||||
s = realloc (url, ++ret);
|
|
||||||
if (s) url = s;
|
|
||||||
snprintf (url, ret, "http://%s:%d%s", config->hostname, config->port, mount);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (server->listen_socket_id) {
|
||||||
|
listen_socket = listensocket_container_get_by_id(global.listensockets,
|
||||||
|
server->listen_socket_id);
|
||||||
|
if (!listen_socket)
|
||||||
|
ICECAST_LOG_ERROR("Failure to find listen socket with ID %#H, using default.",
|
||||||
|
server->listen_socket_id);
|
||||||
|
}
|
||||||
|
ret = client_get_baseurl(NULL, listen_socket, url, len, NULL, NULL, NULL, mount, NULL);
|
||||||
|
if (ret >= len) {
|
||||||
|
// Buffer was too small, allocate a big enough one
|
||||||
|
char *s = realloc (url, ret + 1);
|
||||||
|
if (!s) {
|
||||||
|
refobject_unref(listen_socket);
|
||||||
|
free(url);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
url = s;
|
||||||
|
|
||||||
|
ret = client_get_baseurl(NULL, listen_socket, url, len, NULL, NULL, NULL, mount, NULL);
|
||||||
|
}
|
||||||
|
refobject_unref(listen_socket);
|
||||||
|
|
||||||
|
if (ret < 0 || ret >= len)
|
||||||
|
break;
|
||||||
|
|
||||||
|
config = config_get_config();
|
||||||
mountproxy = config_find_mount (config, mount, MOUNT_TYPE_NORMAL);
|
mountproxy = config_find_mount (config, mount, MOUNT_TYPE_NORMAL);
|
||||||
if (mountproxy && mountproxy->cluster_password)
|
if (mountproxy && mountproxy->cluster_password)
|
||||||
add_yp_info (yp, mountproxy->cluster_password, YP_CLUSTER_PASSWORD);
|
add_yp_info (yp, mountproxy->cluster_password, YP_CLUSTER_PASSWORD);
|
||||||
@ -633,7 +656,7 @@ static void check_servers (void)
|
|||||||
if (server->remove)
|
if (server->remove)
|
||||||
{
|
{
|
||||||
struct yp_server *to_go = server;
|
struct yp_server *to_go = server;
|
||||||
ICECAST_LOG_DEBUG("YP server \"%s\"removed", server->url);
|
ICECAST_LOG_DEBUG("YP server \"%s\" removed", server->url);
|
||||||
*server_p = server->next;
|
*server_p = server->next;
|
||||||
server = server->next;
|
server = server->next;
|
||||||
destroy_yp_server(to_go);
|
destroy_yp_server(to_go);
|
||||||
@ -662,10 +685,9 @@ static void check_servers (void)
|
|||||||
ypdata_t *yp;
|
ypdata_t *yp;
|
||||||
|
|
||||||
source_t *source = node->key;
|
source_t *source = node->key;
|
||||||
if (source->yp_public && (yp = create_yp_entry (source->mount)) != NULL)
|
if (source->yp_public && (yp = create_yp_entry (server, source->mount)) != NULL)
|
||||||
{
|
{
|
||||||
ICECAST_LOG_DEBUG("Adding existing mount %s", source->mount);
|
ICECAST_LOG_DEBUG("Adding existing mount %s", source->mount);
|
||||||
yp->server = server;
|
|
||||||
yp->touch_interval = server->touch_interval;
|
yp->touch_interval = server->touch_interval;
|
||||||
yp->next = server->mounts;
|
yp->next = server->mounts;
|
||||||
server->mounts = yp;
|
server->mounts = yp;
|
||||||
@ -901,7 +923,7 @@ void yp_add (const char *mount)
|
|||||||
if (yp == NULL)
|
if (yp == NULL)
|
||||||
{
|
{
|
||||||
/* add new ypdata to each servers pending yp */
|
/* add new ypdata to each servers pending yp */
|
||||||
yp = create_yp_entry (mount);
|
yp = create_yp_entry (server, mount);
|
||||||
if (yp)
|
if (yp)
|
||||||
{
|
{
|
||||||
ICECAST_LOG_DEBUG("Adding %s to %s", mount, server->url);
|
ICECAST_LOG_DEBUG("Adding %s to %s", mount, server->url);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user