1
0
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:
Michael Smith 2003-02-07 10:53:38 +00:00
parent 9e168dc870
commit e3bb942ed9
4 changed files with 120 additions and 39 deletions

View File

@ -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>

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}
con = create_connection(streamsock, NULL);
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); else
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;
} }