Commit 0ac7ed9e authored by Philipp Schafft's avatar Philipp Schafft 🦁

Fix: Corrected blocking state of connections

Thanks to Bernd Geiser <bg@ferncast.de> for initial report.

Fixes: #2309
parent 0496602d
...@@ -85,6 +85,11 @@ extern "C" { ...@@ -85,6 +85,11 @@ extern "C" {
#define SHOUT_TLS_RFC2818 ( 11) /* Use TLS for transport layer like HTTPS [RFC2818] does. */ #define SHOUT_TLS_RFC2818 ( 11) /* Use TLS for transport layer like HTTPS [RFC2818] does. */
#define SHOUT_TLS_RFC2817 ( 12) /* Use TLS via HTTP Upgrade:-header [RFC2817]. */ #define SHOUT_TLS_RFC2817 ( 12) /* Use TLS via HTTP Upgrade:-header [RFC2817]. */
/* Possible values for blocking */
#define SHOUT_BLOCKING_DEFAULT (255) /* Use the default blocking setting. */
#define SHOUT_BLOCKING_FULL ( 0) /* Block in all I/O related functions */
#define SHOUT_BLOCKING_NONE ( 1) /* Do not block in I/O related functions */
#define SHOUT_AI_BITRATE "bitrate" #define SHOUT_AI_BITRATE "bitrate"
#define SHOUT_AI_SAMPLERATE "samplerate" #define SHOUT_AI_SAMPLERATE "samplerate"
#define SHOUT_AI_CHANNELS "channels" #define SHOUT_AI_CHANNELS "channels"
...@@ -244,7 +249,8 @@ int shout_set_protocol(shout_t *self, unsigned int protocol); ...@@ -244,7 +249,8 @@ int shout_set_protocol(shout_t *self, unsigned int protocol);
unsigned int shout_get_protocol(shout_t *self); unsigned int shout_get_protocol(shout_t *self);
/* Instructs libshout to use nonblocking I/O. Must be called before /* Instructs libshout to use nonblocking I/O. Must be called before
* shout_open (no switching back and forth midstream at the moment). */ * shout_open (no switching back and forth midstream at the moment).
* nonblocking is one of SHOUT_BLOCKING_xxx. */
int shout_set_nonblocking(shout_t* self, unsigned int nonblocking); int shout_set_nonblocking(shout_t* self, unsigned int nonblocking);
unsigned int shout_get_nonblocking(shout_t *self); unsigned int shout_get_nonblocking(shout_t *self);
......
...@@ -118,7 +118,7 @@ static struct timeval shout_connection_iter__wait_for_io__get_timeout(shout_conn ...@@ -118,7 +118,7 @@ static struct timeval shout_connection_iter__wait_for_io__get_timeout(shout_conn
.tv_usec = (timeout % 1000) * 1000 .tv_usec = (timeout % 1000) * 1000
}; };
return tv; return tv;
} else if (con->nonblocking) { } else if (con->nonblocking == SHOUT_BLOCKING_NONE) {
return tv_nonblocking; return tv_nonblocking;
} else { } else {
return tv_blocking; return tv_blocking;
...@@ -167,7 +167,7 @@ static shout_connection_return_state_t shout_connection_iter__socket(shout_conne ...@@ -167,7 +167,7 @@ static shout_connection_return_state_t shout_connection_iter__socket(shout_conne
} }
break; break;
case SHOUT_SOCKSTATE_CONNECTING: case SHOUT_SOCKSTATE_CONNECTING:
if (con->nonblocking) { if (con->nonblocking == SHOUT_BLOCKING_NONE) {
ret = shout_connection_iter__wait_for_io(con, shout, 1, 1, 0); ret = shout_connection_iter__wait_for_io(con, shout, 1, 1, 0);
if (ret != SHOUT_RS_DONE) { if (ret != SHOUT_RS_DONE) {
return ret; return ret;
...@@ -460,7 +460,7 @@ int shout_connection_iter(shout_connection_t *con, shout_t *shou ...@@ -460,7 +460,7 @@ int shout_connection_iter(shout_connection_t *con, shout_t *shou
break; \ break; \
case SHOUT_RS_TIMEOUT: \ case SHOUT_RS_TIMEOUT: \
case SHOUT_RS_NOTNOW: \ case SHOUT_RS_NOTNOW: \
if (con->nonblocking) \ if (con->nonblocking == SHOUT_BLOCKING_NONE) \
return SHOUTERR_RETRY; \ return SHOUTERR_RETRY; \
retry = 1; \ retry = 1; \
break; \ break; \
...@@ -518,7 +518,7 @@ int shout_connection_select_tlsmode(shout_connection_t *con, int ...@@ -518,7 +518,7 @@ int shout_connection_select_tlsmode(shout_connection_t *con, int
} }
int shout_connection_set_nonblocking(shout_connection_t *con, unsigned int nonblocking) int shout_connection_set_nonblocking(shout_connection_t *con, unsigned int nonblocking)
{ {
if (!con) if (!con || (nonblocking != SHOUT_BLOCKING_DEFAULT && nonblocking != SHOUT_BLOCKING_FULL && nonblocking != SHOUT_BLOCKING_NONE))
return SHOUTERR_INSANE; return SHOUTERR_INSANE;
if (con->socket != SOCK_ERROR) if (con->socket != SOCK_ERROR)
...@@ -563,13 +563,14 @@ int shout_connection_connect(shout_connection_t *con, shout_t *s ...@@ -563,13 +563,14 @@ int shout_connection_connect(shout_connection_t *con, shout_t *s
if (con->socket != SOCK_ERROR || con->current_socket_state != SHOUT_SOCKSTATE_UNCONNECTED) if (con->socket != SOCK_ERROR || con->current_socket_state != SHOUT_SOCKSTATE_UNCONNECTED)
return SHOUTERR_BUSY; return SHOUTERR_BUSY;
shout_connection_set_nonblocking(con, shout_get_nonblocking(shout)); if (con->nonblocking == SHOUT_BLOCKING_DEFAULT)
shout_connection_set_nonblocking(con, shout_get_nonblocking(shout));
port = shout->port; port = shout->port;
if (shout_get_protocol(shout) == SHOUT_PROTOCOL_ICY) if (shout_get_protocol(shout) == SHOUT_PROTOCOL_ICY)
port++; port++;
if (con->nonblocking) { if (con->nonblocking == SHOUT_BLOCKING_NONE) {
con->socket = sock_connect_non_blocking(shout->host, port); con->socket = sock_connect_non_blocking(shout->host, port);
} else { } else {
con->socket = sock_connect(shout->host, port); con->socket = sock_connect(shout->host, port);
......
...@@ -417,7 +417,7 @@ int shout_set_metadata(shout_t *self, shout_metadata_t *metadata) ...@@ -417,7 +417,7 @@ int shout_set_metadata(shout_t *self, shout_metadata_t *metadata)
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
shout_connection_select_tlsmode(connection, self->tls_mode); shout_connection_select_tlsmode(connection, self->tls_mode);
#endif #endif
shout_connection_set_nonblocking(connection, 0); shout_connection_set_nonblocking(connection, SHOUT_BLOCKING_FULL);
connection->target_message_state = SHOUT_MSGSTATE_PARSED_FINAL; connection->target_message_state = SHOUT_MSGSTATE_PARSED_FINAL;
...@@ -989,7 +989,10 @@ unsigned int shout_get_protocol(shout_t *self) ...@@ -989,7 +989,10 @@ unsigned int shout_get_protocol(shout_t *self)
int shout_set_nonblocking(shout_t *self, unsigned int nonblocking) int shout_set_nonblocking(shout_t *self, unsigned int nonblocking)
{ {
if (!self || (nonblocking != 0 && nonblocking != 1)) if (nonblocking == SHOUT_BLOCKING_DEFAULT)
nonblocking = SHOUT_BLOCKING_FULL;
if (!self || (nonblocking != SHOUT_BLOCKING_FULL && nonblocking != SHOUT_BLOCKING_NONE))
return SHOUTERR_INSANE; return SHOUTERR_INSANE;
if (self->connection) if (self->connection)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment