diff --git a/News b/News index 88d1d226..629c8801 100644 --- a/News +++ b/News @@ -1,3 +1,6 @@ +2003-04-23 + Support aliases + 2003-03-09 Support listening on multiple sockets. diff --git a/conf/icecast.xml b/conf/icecast.xml index 17233160..74becc44 100644 --- a/conf/icecast.xml +++ b/conf/icecast.xml @@ -83,6 +83,14 @@ be relative to the new root, not the original root --> /usr/local/icecast/logs /usr/local/icecast/web + + + diff --git a/src/config.c b/src/config.c index b2cbb516..aa3c1c94 100644 --- a/src/config.c +++ b/src/config.c @@ -98,6 +98,7 @@ void config_clear(ice_config_t *c) ice_config_dir_t *dirnode, *nextdirnode; relay_server *relay, *nextrelay; mount_proxy *mount, *nextmount; + aliases *alias, *nextalias; int i; if (c->config_filename) @@ -160,6 +161,16 @@ void config_clear(ice_config_t *c) } thread_mutex_unlock(&(_locks.mounts_lock)); + alias = c->aliases; + while(alias) { + nextalias = alias->next; + xmlFree(alias->source); + xmlFree(alias->destination); + xmlFree(alias->bind_address); + free(alias); + alias = nextalias; + } + dirnode = c->dir_list; while(dirnode) { nextdirnode = dirnode->next; @@ -423,6 +434,7 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, configuration->mounts = mount; mount->max_listeners = -1; + mount->next = NULL; do { if (node == NULL) break; @@ -474,6 +486,8 @@ static void _parse_relay(xmlDocPtr doc, xmlNodePtr node, else configuration->relay = relay; + relay->next = NULL; + do { if (node == NULL) break; if (xmlIsBlankNode(node)) continue; @@ -606,6 +620,9 @@ static void _parse_directory(xmlDocPtr doc, xmlNodePtr node, static void _parse_paths(xmlDocPtr doc, xmlNodePtr node, ice_config_t *configuration) { + char *temp; + aliases *alias, *current, *last; + do { if (node == NULL) break; if (xmlIsBlankNode(node)) continue; @@ -621,7 +638,39 @@ static void _parse_paths(xmlDocPtr doc, xmlNodePtr node, configuration->webroot_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); if(configuration->webroot_dir[strlen(configuration->webroot_dir)-1] == '/') configuration->webroot_dir[strlen(configuration->webroot_dir)-1] = 0; - + } else if (strcmp(node->name, "alias") == 0) { + alias = malloc(sizeof(aliases)); + alias->next = NULL; + alias->source = xmlGetProp(node, "source"); + if(alias->source == NULL) { + free(alias); + continue; + } + alias->destination = xmlGetProp(node, "dest"); + if(alias->destination == NULL) { + xmlFree(alias->source); + free(alias); + continue; + } + temp = NULL; + temp = xmlGetProp(node, "port"); + if(temp != NULL) { + alias->port = atoi(temp); + xmlFree(temp); + } + else + alias->port = -1; + alias->bind_address = xmlGetProp(node, "bind-address"); + current = configuration->aliases; + last = NULL; + while(current) { + last = current; + current = current->next; + } + if(last) + last->next = alias; + else + configuration->aliases = alias; } } while ((node = node->next)); } diff --git a/src/config.h b/src/config.h index 9ae487ee..f9d3b9f1 100644 --- a/src/config.h +++ b/src/config.h @@ -43,6 +43,14 @@ typedef struct _mount_proxy { struct _mount_proxy *next; } mount_proxy; +typedef struct _aliases { + char *source; + char *destination; + int port; + char *bind_address; + struct _aliases *next; +}aliases; + typedef struct { int port; char *bind_address; @@ -89,6 +97,7 @@ typedef struct ice_config_tag char *base_dir; char *log_dir; char *webroot_dir; + aliases *aliases; char *access_log; char *error_log; diff --git a/src/connection.c b/src/connection.c index 6c23cc8b..29ced374 100644 --- a/src/connection.c +++ b/src/connection.c @@ -109,11 +109,12 @@ static unsigned long _next_connection_id(void) return id; } -connection_t *create_connection(sock_t sock, char *ip) { +connection_t *create_connection(sock_t sock, sock_t serversock, char *ip) { connection_t *con; con = (connection_t *)malloc(sizeof(connection_t)); memset(con, 0, sizeof(connection_t)); con->sock = sock; + con->serversock = serversock; con->con_time = time(NULL); con->id = _next_connection_id(); con->ip = ip; @@ -203,7 +204,7 @@ static connection_t *_accept_connection(void) sock = sock_accept(serversock, ip, MAX_ADDR_LEN); if (sock >= 0) { - con = create_connection(sock, ip); + con = create_connection(sock, serversock, ip); return con; } @@ -648,6 +649,10 @@ static void _handle_get_request(connection_t *con, int fileserve; char *host; int port; + int i; + char *serverhost; + int serverport; + aliases *alias; ice_config_t *config; int client_limit; @@ -655,6 +660,14 @@ static void _handle_get_request(connection_t *con, fileserve = config->fileserve; host = config->hostname; port = config->port; + for(i = 0; i < MAX_LISTEN_SOCKETS; i++) { + if(global.serversock[i] == con->serversock) { + serverhost = config->listeners[i].bind_address; + serverport = config->listeners[i].port; + break; + } + } + alias = config->aliases; client_limit = config->client_limit; config_release_config(); @@ -668,13 +681,22 @@ static void _handle_get_request(connection_t *con, /* there are several types of HTTP GET clients ** media clients, which are looking for a source (eg, URI = /stream.ogg) ** stats clients, which are looking for /admin/stats.xml - ** and director server authorizers, which are looking for /GUID-xxxxxxxx + ** and directory server authorizers, which are looking for /GUID-xxxxxxxx ** (where xxxxxx is the GUID in question) - this isn't implemented yet. ** we need to handle the latter two before the former, as the latter two ** aren't subject to the limits. */ /* TODO: add GUID-xxxxxx */ + /* Handle aliases */ + while(alias) { + if(strcmp(uri, alias->source) == 0 && (alias->port == -1 || alias->port == serverport) && (alias->bind_address == NULL || (serverhost != NULL && strcmp(alias->bind_address, serverhost) == 0))) { + uri = alias->destination; + break; + } + alias = alias->next; + } + /* Dispatch all admin requests */ if (strncmp(uri, "/admin/", 7) == 0) { admin_handle_request(client, uri); diff --git a/src/connection.h b/src/connection.h index a7da84f9..aa83ee54 100644 --- a/src/connection.h +++ b/src/connection.h @@ -17,6 +17,7 @@ typedef struct connection_tag uint64_t sent_bytes; int sock; + int serversock; int error; char *ip; @@ -31,7 +32,7 @@ void connection_initialize(void); void connection_shutdown(void); void connection_accept_loop(void); void connection_close(connection_t *con); -connection_t *create_connection(sock_t sock, char *ip); +connection_t *create_connection(sock_t sock, sock_t serversock, char *ip); int connection_create_source(struct _client_tag *client, connection_t *con, http_parser_t *parser, char *mount); diff --git a/src/slave.c b/src/slave.c index 7b386f0e..4094b386 100644 --- a/src/slave.c +++ b/src/slave.c @@ -91,7 +91,7 @@ static void create_relay_stream(char *server, int port, WARN2("Failed to relay stream from master server, couldn't connect to http://%s:%d", server, port); return; } - con = create_connection(streamsock, NULL); + con = create_connection(streamsock, -1, NULL); if(mp3) { /* Some mp3 servers are bitchy, send a user-agent string to make them * send the right response.