Hello
I am currently unable to connect to Shoutcast servers, too. I did some investigations and here is what I found:
First of all, there is an issue with sockets connecting in non-blocking mode. The connection gets closed before the three-way handshake is completed. I was able to solve this by doing a little change in shout_connection_iter__wait_for_io__get_timeout(). There is a struct timeval tv_nonblocking there, and I increased the tv_sec member to 1.
After that, the handshake could be completed. But, immediately, another problem occurred. The client was sending "!POKE" to the server instead of the password and the rest of the connect data.
Solved this by modifying * shout_create_icy_request()* in *proto_icy.c * to only perform a shout_create_icy_request_real() regardless of the connection->server_caps.
I am aware these may be not proper fixes. These work for Shoutcast only, in my case, Currently I've got no posibility to test them with any other server. For these reasons, I have not turned these findings into patches, yet
Just one more thing. Metadata updates are done on source port, instead of listen/web port. They do not have any effect. They should be done apart from the source context.
I tested with a Shoutcast V1.9.8 (doh!) install on a spare PC. Also Mixxx 2.2.1 as source . Should be the same on newer versions of the Shoutcast server (and,fortunately or not, tarballs are still to be found on the web).
You're welcome, Let me know if I can be of more help.
First of all, I grabbed the master branch (the head) and compiled it, This is what i used for testing.
To clarify things a little. Most of the Shoutcast sources use V1 protocol, which is very simple. There is also an Ultravox protocol, which is more complicated, and tries to achieve on the Shoutcast servers what Icecast already does - multi sources, encryption, and so on. But this one is not (yet) implemented on libshout. So, we stick to Shoutcast 1 source protocol for now.
The link below has the most comprehensive documentation. Yes, this is all there is :)
So, it seems the Shoutcast server always expects the password and the stream configuration in the first packet sent by the source. If the first packet has a "!POKE" as payload, the server interprets this as a (wrong) password and drops the connection.
If the password is correct, the server response is "OK2" The server capabilities are always sent back after that, as "icy-caps:11" whatever this means. So, skip the POKE for Shoutcast.
About the "port++". Shoutcast uses port n for the listeners and the web interface. Metadata is also sent as HTTP, on this port n, as a HTTP "GET" request. BUT the source should connect on port n + 1 to stream data.
So, actually, a Shoutcast connection uses two consecutive ports. This is the toughest fix...
Haven't investigated thoroughly yet the blocking/nonblocking issue. Just increased the timeout on poll/ select
You may easily set a Shoutcast server on your own computer for testing.
The poke request makes the connection be rejected for good, At least Mixxx displays the "Invalid username or password" error and quits broadcasting.
The "port++" code above is executed for all ICY connections. Unfortunately, there is currently no way to tell which ICY connections are stream sources and which are metadata/administrative, So, the metadata request gets sent on the wrong port.
I can send all the patches I have for these issues. They are mostly quick hacks, but they work for me.
@cburneci please note that you're not the only person reading this ticket. The question was open and it is quite possible that one of the Icecast team members has a SC server sitting around somewhere for testing. (I don't, last time I touched it is almost 20 years ago)
Note also that, if a socket is to be opened in non-blocking mode, the 1ms timeout mai be too small to actually let the initial handshake be finished. I understand that shout should use blocking mode, though.