mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Rearrange some relaying code.
Add ability to configure individual relays as well (i.e. single stream, rather than all the streams from a server). svn path=/trunk/icecast/; revision=4327
This commit is contained in:
parent
9e168dc870
commit
e3bb942ed9
@ -37,6 +37,13 @@
|
|||||||
<!--<master-server-port>8001</master-server-port>-->
|
<!--<master-server-port>8001</master-server-port>-->
|
||||||
<!--<master-update-interval>120</master-update-interval>-->
|
<!--<master-update-interval>120</master-update-interval>-->
|
||||||
<!--<master-password>hackme</master-password>-->
|
<!--<master-password>hackme</master-password>-->
|
||||||
|
<!--
|
||||||
|
<relay>
|
||||||
|
<server>127.0.0.1</server>
|
||||||
|
<port>8001</port>
|
||||||
|
<mount>/example.ogg</mount>
|
||||||
|
</relay>
|
||||||
|
-->
|
||||||
|
|
||||||
<fileserve>1</fileserve>
|
<fileserve>1</fileserve>
|
||||||
|
|
||||||
|
40
src/config.c
40
src/config.c
@ -55,6 +55,7 @@ static void _parse_paths(xmlDocPtr doc, xmlNodePtr node);
|
|||||||
static void _parse_logging(xmlDocPtr doc, xmlNodePtr node);
|
static void _parse_logging(xmlDocPtr doc, xmlNodePtr node);
|
||||||
static void _parse_security(xmlDocPtr doc, xmlNodePtr node);
|
static void _parse_security(xmlDocPtr doc, xmlNodePtr node);
|
||||||
static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node);
|
static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node);
|
||||||
|
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node);
|
||||||
static void _add_server(xmlDocPtr doc, xmlNodePtr node);
|
static void _add_server(xmlDocPtr doc, xmlNodePtr node);
|
||||||
|
|
||||||
void config_initialize(void)
|
void config_initialize(void)
|
||||||
@ -257,6 +258,8 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node)
|
|||||||
_configuration.master_update_interval = atoi(tmp);
|
_configuration.master_update_interval = atoi(tmp);
|
||||||
} else if (strcmp(node->name, "limits") == 0) {
|
} else if (strcmp(node->name, "limits") == 0) {
|
||||||
_parse_limits(doc, node->xmlChildrenNode);
|
_parse_limits(doc, node->xmlChildrenNode);
|
||||||
|
} else if (strcmp(node->name, "relay") == 0) {
|
||||||
|
_parse_relay(doc, node->xmlChildrenNode);
|
||||||
} else if (strcmp(node->name, "directory") == 0) {
|
} else if (strcmp(node->name, "directory") == 0) {
|
||||||
_parse_directory(doc, node->xmlChildrenNode);
|
_parse_directory(doc, node->xmlChildrenNode);
|
||||||
} else if (strcmp(node->name, "paths") == 0) {
|
} else if (strcmp(node->name, "paths") == 0) {
|
||||||
@ -305,6 +308,43 @@ static void _parse_limits(xmlDocPtr doc, xmlNodePtr node)
|
|||||||
} while ((node = node->next));
|
} while ((node = node->next));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
relay_server *relay = calloc(1, sizeof(relay_server));
|
||||||
|
relay_server *current = _configuration.relay;
|
||||||
|
relay_server *last=NULL;
|
||||||
|
|
||||||
|
while(current) {
|
||||||
|
last = current;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(last)
|
||||||
|
last->next = relay;
|
||||||
|
else
|
||||||
|
_configuration.relay = relay;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (node == NULL) break;
|
||||||
|
if (xmlIsBlankNode(node)) continue;
|
||||||
|
|
||||||
|
if (strcmp(node->name, "server") == 0) {
|
||||||
|
relay->server = (char *)xmlNodeListGetString(
|
||||||
|
doc, node->xmlChildrenNode, 1);
|
||||||
|
}
|
||||||
|
else if (strcmp(node->name, "port") == 0) {
|
||||||
|
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||||
|
relay->port = atoi(tmp);
|
||||||
|
if(tmp) xmlFree(tmp);
|
||||||
|
}
|
||||||
|
else if (strcmp(node->name, "mount") == 0) {
|
||||||
|
relay->mount = (char *)xmlNodeListGetString(
|
||||||
|
doc, node->xmlChildrenNode, 1);
|
||||||
|
}
|
||||||
|
} while ((node = node->next));
|
||||||
|
}
|
||||||
|
|
||||||
static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node)
|
static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
|
@ -15,6 +15,13 @@ typedef struct ice_config_dir_tag
|
|||||||
struct ice_config_dir_tag *next;
|
struct ice_config_dir_tag *next;
|
||||||
} ice_config_dir_t;
|
} ice_config_dir_t;
|
||||||
|
|
||||||
|
typedef struct _relay_server {
|
||||||
|
char *server;
|
||||||
|
int port;
|
||||||
|
char *mount;
|
||||||
|
struct _relay_server *next;
|
||||||
|
} relay_server;
|
||||||
|
|
||||||
typedef struct ice_config_tag
|
typedef struct ice_config_tag
|
||||||
{
|
{
|
||||||
char *location;
|
char *location;
|
||||||
@ -45,6 +52,8 @@ typedef struct ice_config_tag
|
|||||||
int master_update_interval;
|
int master_update_interval;
|
||||||
char *master_password;
|
char *master_password;
|
||||||
|
|
||||||
|
relay_server *relay;
|
||||||
|
|
||||||
char *base_dir;
|
char *base_dir;
|
||||||
char *log_dir;
|
char *log_dir;
|
||||||
char *webroot_dir;
|
char *webroot_dir;
|
||||||
|
103
src/slave.c
103
src/slave.c
@ -64,13 +64,53 @@ void slave_shutdown(void) {
|
|||||||
thread_join(_slave_thread_id);
|
thread_join(_slave_thread_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *_slave_thread(void *arg) {
|
static void create_relay_stream(char *server, int port, char *mount)
|
||||||
sock_t mastersock, streamsock;
|
{
|
||||||
char buf[256];
|
sock_t streamsock;
|
||||||
char header[4096];
|
char header[4096];
|
||||||
connection_t *con;
|
connection_t *con;
|
||||||
http_parser_t *parser;
|
http_parser_t *parser;
|
||||||
client_t *client;
|
client_t *client;
|
||||||
|
|
||||||
|
DEBUG1("Adding source at mountpoint \"%s\"", mount);
|
||||||
|
|
||||||
|
streamsock = sock_connect_wto(server, port, 0);
|
||||||
|
if (streamsock == SOCK_ERROR) {
|
||||||
|
WARN0("Failed to relay stream from master server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
con = create_connection(streamsock, NULL);
|
||||||
|
sock_write(streamsock, "GET %s HTTP/1.0\r\n\r\n", mount);
|
||||||
|
memset(header, 0, sizeof(header));
|
||||||
|
if (util_read_header(con->sock, header, 4096) == 0) {
|
||||||
|
connection_close(con);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parser = httpp_create_parser();
|
||||||
|
httpp_initialize(parser, NULL);
|
||||||
|
if(!httpp_parse_response(parser, header, strlen(header), mount)) {
|
||||||
|
if(httpp_getvar(parser, HTTPP_VAR_ERROR_MESSAGE)) {
|
||||||
|
ERROR1("Error parsing relay request: %s",
|
||||||
|
httpp_getvar(parser, HTTPP_VAR_ERROR_MESSAGE));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ERROR0("Error parsing relay request");
|
||||||
|
connection_close(con);
|
||||||
|
httpp_destroy(parser);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
client = client_create(con, parser);
|
||||||
|
if (!connection_create_source(client, con, parser,
|
||||||
|
httpp_getvar(parser, HTTPP_VAR_URI))) {
|
||||||
|
client_destroy(client);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *_slave_thread(void *arg) {
|
||||||
|
sock_t mastersock;
|
||||||
|
char buf[256];
|
||||||
int interval = config_get_config()->master_update_interval;
|
int interval = config_get_config()->master_update_interval;
|
||||||
char *authheader, *data;
|
char *authheader, *data;
|
||||||
int len;
|
int len;
|
||||||
@ -117,45 +157,30 @@ static void *_slave_thread(void *arg) {
|
|||||||
if (!source_find_mount(buf)) {
|
if (!source_find_mount(buf)) {
|
||||||
avl_tree_unlock(global.source_tree);
|
avl_tree_unlock(global.source_tree);
|
||||||
|
|
||||||
DEBUG1("Adding source at mountpoint \"%s\"", buf);
|
create_relay_stream(
|
||||||
streamsock = sock_connect_wto(config_get_config()->master_server, config_get_config()->master_server_port, 0);
|
config_get_config()->master_server,
|
||||||
if (streamsock == SOCK_ERROR) {
|
config_get_config()->master_server_port,
|
||||||
WARN0("Failed to relay stream from master server");
|
buf);
|
||||||
continue;
|
}
|
||||||
}
|
else
|
||||||
con = create_connection(streamsock, NULL);
|
avl_tree_unlock(global.source_tree);
|
||||||
sock_write(streamsock, "GET %s HTTP/1.0\r\n\r\n", buf);
|
|
||||||
memset(header, 0, sizeof(header));
|
|
||||||
if (util_read_header(con->sock, header, 4096) == 0) {
|
|
||||||
connection_close(con);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
parser = httpp_create_parser();
|
|
||||||
httpp_initialize(parser, NULL);
|
|
||||||
if(!httpp_parse_response(parser, header, strlen(header), buf)) {
|
|
||||||
if(httpp_getvar(parser, HTTPP_VAR_ERROR_MESSAGE)) {
|
|
||||||
ERROR1("Error parsing relay request: %s",
|
|
||||||
httpp_getvar(parser, HTTPP_VAR_ERROR_MESSAGE));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ERROR0("Error parsing relay request");
|
|
||||||
connection_close(con);
|
|
||||||
httpp_destroy(parser);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
client = client_create(con, parser);
|
|
||||||
if (!connection_create_source(client, con, parser,
|
|
||||||
httpp_getvar(parser, HTTPP_VAR_URI))) {
|
|
||||||
client_destroy(client);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
avl_tree_unlock(global.source_tree);
|
|
||||||
}
|
}
|
||||||
sock_close(mastersock);
|
sock_close(mastersock);
|
||||||
|
|
||||||
|
/* And now, we process the individual mounts... */
|
||||||
|
relay_server *relay = config_get_config()->relay;
|
||||||
|
while(relay) {
|
||||||
|
avl_tree_rlock(global.source_tree);
|
||||||
|
if(!source_find_mount(relay->mount)) {
|
||||||
|
avl_tree_unlock(global.source_tree);
|
||||||
|
|
||||||
|
create_relay_stream(relay->server, relay->port, relay->mount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
avl_tree_unlock(global.source_tree);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
thread_exit(0);
|
thread_exit(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user