[Icecast-dev] exposed-port option for Icecast behind reverse proxy

Damien Garrido damien.garrido.work at gmail.com
Sat Mar 21 20:10:30 PDT 2015


Hello,

I didn't want to have to choose between Icecast running on port 80 and all
my Apache virtual hosts, running also on port 80, on my sole external IP
address.

I didn't want either to open port 8000 on my firewall because I wanted all
users being able to reach Icecast even the ones behind enterprise firewalls.

So I managed to run Apache 2.2 listening on port 80 and Icecast 2.3.2
listening on port 8000 on the same host.

I added a new virtual host radio.domain.com (listening on port 80) which is
routing the Icecast traffic to/from the local Icecast server (listening on
port 8000):

<VirtualHost *:80>
    ServerName radio.domain.com
    ServerAdmin hostmaster at domain.com
    ProxyPreserveHost On
    ProxyPass / http://localhost:8000/
    ProxyPassReverse / http://localhost:8000/
</VirtualHost>

I was then able to connect audio clients like VLC/Winamp to Icecast mount
points using addresses like http://radio.domain.com/my_stream.

However, when connecting to the Icecast virtual host
http://radio.domain.com/ web page, the m3u and the xspf files where still
exposing the URL http://radio.domain.com:8000/my_stream with that annoying
port 8000. Then people downloading those files weren't able to connect to
the Icecast server because they were trying to connect on the wrong port.
The same was occuring with the YP updates ondir.xiph.org.

I then downloaded the Icecast 2.3.2 source code, and modified it to add a
new option:

<exposed-port>80</exposed-port>

If this option is present in the Icecast configuration file, then m3u/xspf
files as well as YP updates will use that port number.

The below patch is for Icecast version 2.3.2:

diff --git a/src/cfgfile.c b/src/cfgfile.c
index 5eac93d..42d917f 100644
--- a/src/cfgfile.c
+++ b/src/cfgfile.c
@@ -436,6 +436,10 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
configuration->mimetypes_fn = (char *)xmlNodeListGetString(doc,
node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("listen-socket")) == 0) {
_parse_listen_socket(doc, node->xmlChildrenNode, configuration);
+ } else if (xmlStrcmp (node->name, XMLSTR("exposed-port")) == 0) {
+ tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ configuration->exposed_port = atoi(tmp);
+ if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("port")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->port = atoi(tmp);
@@ -801,6 +805,12 @@ static void _parse_listen_socket(xmlDocPtr doc,
xmlNodePtr node,
listener->port = atoi(tmp);
if(tmp) xmlFree(tmp);
}
+ else if (xmlStrcmp (node->name, XMLSTR("exposed-port")) == 0) {
+ tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if(configuration->exposed_port == 0)
+ configuration->exposed_port = atoi(tmp);
+ if(tmp) xmlFree(tmp);
+ }
else if (xmlStrcmp (node->name, XMLSTR("ssl")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
listener->ssl = atoi(tmp);
diff --git a/src/cfgfile.h b/src/cfgfile.h
index fa5aa69..44a5bea 100644
--- a/src/cfgfile.h
+++ b/src/cfgfile.h
@@ -138,6 +138,7 @@ typedef struct ice_config_tag

char *hostname;
int port;
+ int exposed_port;
char *mimetypes_fn;

listener_t *listen_sock;
diff --git a/src/fserve.c b/src/fserve.c
index 724aaaf..3f50472 100644
--- a/src/fserve.c
+++ b/src/fserve.c
@@ -443,7 +443,7 @@ int fserve_client_create (client_t *httpclient, const
char *path)
"HTTP/1.0 200 OK\r\n"
"Content-Type: audio/x-mpegurl\r\n\r\n"
"http://%s:%d%s\r\n",
- config->hostname, config->port,
+ config->hostname, ( config->exposed_port ? config->exposed_port :
config->port ),
sourceuri
);
config_release_config();
diff --git a/src/icecast b/src/icecast
new file mode 100755
index 0000000..7e4f612
Binary files /dev/null and b/src/icecast differ
diff --git a/src/source.c b/src/source.c
index 02bfc74..b838799 100644
--- a/src/source.c
+++ b/src/source.c
@@ -579,7 +579,7 @@ static void source_init (source_t *source)
listenurl = malloc (listen_url_size);
memset (listenurl, '00', listen_url_size);
snprintf (listenurl, listen_url_size, "http://%s:%d%s",
- config->hostname, config->port, source->mount);
+ config->hostname, ( config->exposed_port ? config->exposed_port :
config->port ), source->mount);
config_release_config();

str = httpp_getvar(source->parser, "ice-audio-info");
diff --git a/src/yp.c b/src/yp.c
index 4470d47..e3acb5f 100644
--- a/src/yp.c
+++ b/src/yp.c
@@ -584,12 +584,12 @@ static ypdata_t *create_yp_entry (const char *mount)
if (url == NULL)
break;
config = config_get_config();
- ret = snprintf (url, len, "http://%s:%d%s", config->hostname,
config->port, mount);
+ ret = snprintf (url, len, "http://%s:%d%s", config->hostname, (
config->exposed_port ? config->exposed_port : 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);
+ snprintf (url, ret, "http://%s:%d%s", config->hostname, (
config->exposed_port ? config->exposed_port : config->port ), mount);
}

mountproxy = config_find_mount (config, mount);
-- 
Damien Garrido
Dev (C/C++/PHP/Perl/Python)
Ops (on Debian/Ubuntu)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.xiph.org/pipermail/icecast-dev/attachments/20150322/02198f67/attachment.htm 


More information about the Icecast-dev mailing list