mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-04-18 00:48:43 -04:00
Cleanup codestyle
This commit cleanups codestyle a bit, yet there is still some work to be done
This commit is contained in:
parent
9d84ba2036
commit
0dfc7c5b6a
56
src/acl.c
56
src/acl.c
@ -46,15 +46,19 @@ struct acl_tag {
|
||||
};
|
||||
|
||||
/* some string util functions */
|
||||
static inline void __skip_spaces(const char **str) {
|
||||
static inline void __skip_spaces(const char **str)
|
||||
{
|
||||
register const char * p;
|
||||
|
||||
for (p = *str; *p == ' '; p++);
|
||||
|
||||
*str = p;
|
||||
}
|
||||
|
||||
int acl_set_ANY_str(acl_t * acl, acl_policy_t policy, const char * str, int (*callback)(acl_t *, acl_policy_t, const char *)) {
|
||||
int acl_set_ANY_str(acl_t *acl,
|
||||
acl_policy_t policy,
|
||||
const char *str,
|
||||
int (*callback)(acl_t *, acl_policy_t, const char *))
|
||||
{
|
||||
const char *end;
|
||||
size_t len;
|
||||
char buf[64];
|
||||
@ -88,7 +92,8 @@ int acl_set_ANY_str(acl_t * acl, acl_policy_t policy, const char * str, int (*ca
|
||||
}
|
||||
|
||||
/* basic functions to work with ACLs */
|
||||
acl_t * acl_new(void) {
|
||||
acl_t *acl_new(void)
|
||||
{
|
||||
acl_t * ret = calloc(1, sizeof(*ret));
|
||||
if (!ret)
|
||||
return NULL;
|
||||
@ -109,7 +114,8 @@ acl_t * acl_new(void) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
acl_t * acl_new_from_xml_node(xmlNodePtr node) {
|
||||
acl_t *acl_new_from_xml_node(xmlNodePtr node)
|
||||
{
|
||||
acl_t * ret;
|
||||
char * tmp;
|
||||
xmlAttrPtr prop;
|
||||
@ -191,14 +197,16 @@ acl_t * acl_new_from_xml_node(xmlNodePtr node) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void acl_addref(acl_t * acl) {
|
||||
void acl_addref(acl_t * acl)
|
||||
{
|
||||
if (!acl)
|
||||
return;
|
||||
|
||||
acl->refcount++;
|
||||
}
|
||||
|
||||
void acl_release(acl_t * acl) {
|
||||
void acl_release(acl_t * acl)
|
||||
{
|
||||
if (!acl)
|
||||
return;
|
||||
|
||||
@ -210,7 +218,10 @@ void acl_release(acl_t * acl) {
|
||||
}
|
||||
|
||||
/* HTTP Method specific functions */
|
||||
int acl_set_method_str__callback(acl_t * acl, acl_policy_t policy, const char * str) {
|
||||
int acl_set_method_str__callback(acl_t *acl,
|
||||
acl_policy_t policy,
|
||||
const char *str)
|
||||
{
|
||||
httpp_request_type_e method;
|
||||
size_t i;
|
||||
|
||||
@ -228,7 +239,8 @@ int acl_set_method_str__callback(acl_t * acl, acl_policy_t policy, const char *
|
||||
return 0;
|
||||
}
|
||||
|
||||
acl_policy_t acl_test_method(acl_t * acl, httpp_request_type_e method) {
|
||||
acl_policy_t acl_test_method(acl_t * acl, httpp_request_type_e method)
|
||||
{
|
||||
if (!acl || method < httpp_req_none || method > httpp_req_unknown)
|
||||
return ACL_POLICY_ERROR;
|
||||
|
||||
@ -236,7 +248,10 @@ acl_policy_t acl_test_method(acl_t * acl, httpp_request_type_e method) {
|
||||
}
|
||||
|
||||
/* admin/ interface specific functions */
|
||||
int acl_set_admin_str__callbck(acl_t * acl, acl_policy_t policy, const char * str) {
|
||||
int acl_set_admin_str__callbck(acl_t *acl,
|
||||
acl_policy_t policy,
|
||||
const char *str)
|
||||
{
|
||||
size_t read_i, write_i;
|
||||
int command = admin_get_command(str);
|
||||
|
||||
@ -264,7 +279,8 @@ int acl_set_admin_str__callbck(acl_t * acl, acl_policy_t policy, const char * st
|
||||
return 0;
|
||||
}
|
||||
|
||||
acl_policy_t acl_test_admin(acl_t * acl, int command) {
|
||||
acl_policy_t acl_test_admin(acl_t *acl, int command)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!acl)
|
||||
@ -278,7 +294,8 @@ acl_policy_t acl_test_admin(acl_t * acl, int command) {
|
||||
}
|
||||
|
||||
/* web/ interface specific functions */
|
||||
int acl_set_web_policy(acl_t * acl, acl_policy_t policy) {
|
||||
int acl_set_web_policy(acl_t *acl, acl_policy_t policy)
|
||||
{
|
||||
if (!acl || (policy != ACL_POLICY_ALLOW && policy != ACL_POLICY_DENY))
|
||||
return -1;
|
||||
|
||||
@ -287,7 +304,8 @@ int acl_set_web_policy(acl_t * acl, acl_policy_t policy) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
acl_policy_t acl_test_web(acl_t * acl) {
|
||||
acl_policy_t acl_test_web(acl_t *acl)
|
||||
{
|
||||
if (!acl)
|
||||
return ACL_POLICY_ERROR;
|
||||
|
||||
@ -295,7 +313,8 @@ acl_policy_t acl_test_web(acl_t * acl) {
|
||||
}
|
||||
|
||||
/* mount specific functons */
|
||||
int acl_set_max_connection_duration(acl_t * acl, time_t duration) {
|
||||
int acl_set_max_connection_duration(acl_t *acl, time_t duration)
|
||||
{
|
||||
if (!acl)
|
||||
return -1;
|
||||
|
||||
@ -304,14 +323,16 @@ int acl_set_max_connection_duration(acl_t * acl, time_t duration) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_t acl_get_max_connection_duration(acl_t * acl) {
|
||||
time_t acl_get_max_connection_duration(acl_t *acl)
|
||||
{
|
||||
if (!acl)
|
||||
return -1;
|
||||
|
||||
return acl->max_connection_duration;
|
||||
}
|
||||
|
||||
int acl_set_max_connections_per_user(acl_t * acl, size_t limit) {
|
||||
int acl_set_max_connections_per_user(acl_t *acl, size_t limit)
|
||||
{
|
||||
if (!acl)
|
||||
return -1;
|
||||
|
||||
@ -320,7 +341,8 @@ int acl_set_max_connections_per_user(acl_t * acl, size_t limit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t acl_get_max_connections_per_user(acl_t * acl) {
|
||||
ssize_t acl_get_max_connections_per_user(acl_t *acl)
|
||||
{
|
||||
if (!acl)
|
||||
return -1;
|
||||
|
||||
|
175
src/admin.c
175
src/admin.c
@ -166,7 +166,8 @@ static const admin_command_t commands[] = {
|
||||
{COMMAND_ANY, "*", ADMINTYPE_GENERAL, TRANSFORMED} /* for ACL framework */
|
||||
};
|
||||
|
||||
int admin_get_command(const char *command) {
|
||||
int admin_get_command(const char *command)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < (sizeof(commands)/sizeof(*commands)); i++)
|
||||
@ -176,7 +177,8 @@ int admin_get_command(const char *command) {
|
||||
return COMMAND_ERROR;
|
||||
}
|
||||
|
||||
int admin_get_command_type(int command) {
|
||||
int admin_get_command_type(int command)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (command == ADMIN_COMMAND_ERROR || command == COMMAND_ANY)
|
||||
@ -266,10 +268,8 @@ xmlDocPtr admin_build_sourcelist (const char *mount)
|
||||
acl_release(acl);
|
||||
config_release_config();
|
||||
|
||||
if (source->running)
|
||||
{
|
||||
if (source->client)
|
||||
{
|
||||
if (source->running) {
|
||||
if (source->client) {
|
||||
snprintf(buf, sizeof(buf), "%lu",
|
||||
(unsigned long)(now - source->con->con_time));
|
||||
xmlNewChild(srcnode, NULL, XMLSTR("Connected"), XMLSTR(buf));
|
||||
@ -283,11 +283,12 @@ xmlDocPtr admin_build_sourcelist (const char *mount)
|
||||
return(doc);
|
||||
}
|
||||
|
||||
void admin_send_response (xmlDocPtr doc, client_t *client,
|
||||
int response, const char *xslt_template)
|
||||
{
|
||||
if (response == RAW)
|
||||
void admin_send_response(xmlDocPtr doc,
|
||||
client_t *client,
|
||||
int response,
|
||||
const char *xslt_template)
|
||||
{
|
||||
if (response == RAW) {
|
||||
xmlChar *buff = NULL;
|
||||
int len = 0;
|
||||
size_t buf_len;
|
||||
@ -345,8 +346,7 @@ void admin_send_response (xmlDocPtr doc, client_t *client,
|
||||
client->respcode = 200;
|
||||
fserve_add_client (client, NULL);
|
||||
}
|
||||
if (response == TRANSFORMED)
|
||||
{
|
||||
if (response == TRANSFORMED) {
|
||||
char *fullpath_xslt_template;
|
||||
int fullpath_xslt_template_len;
|
||||
ice_config_t *config = config_get_config();
|
||||
@ -397,7 +397,8 @@ void admin_handle_request(client_t *client, const char *uri)
|
||||
if (client->admin_command == COMMAND_RAW_METADATA_UPDATE &&
|
||||
(acl_test_method(client->acl, httpp_req_source) == ACL_POLICY_ALLOW ||
|
||||
acl_test_method(client->acl, httpp_req_put) == ACL_POLICY_ALLOW)) {
|
||||
ICECAST_LOG_DEBUG("Granted right to call COMMAND_RAW_METADATA_UPDATE to client because it is allowed to do SOURCE or PUT.");
|
||||
ICECAST_LOG_DEBUG("Granted right to call COMMAND_RAW_METADATA_UPDATE to "
|
||||
"client because it is allowed to do SOURCE or PUT.");
|
||||
} else {
|
||||
client_send_error(client, 401, 1, "You need to authenticate\r\n");
|
||||
return;
|
||||
@ -419,17 +420,13 @@ void admin_handle_request(client_t *client, const char *uri)
|
||||
avl_tree_rlock(global.source_tree);
|
||||
source = source_find_mount_raw(mount);
|
||||
|
||||
if (source == NULL)
|
||||
{
|
||||
if (source == NULL) {
|
||||
ICECAST_LOG_WARN("Admin command %s on non-existent source %s",
|
||||
command_string, mount);
|
||||
avl_tree_unlock(global.source_tree);
|
||||
client_send_error(client, 400, 0, "Source does not exist");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (source->running == 0 && source->on_demand == 0)
|
||||
{
|
||||
} else {
|
||||
if (source->running == 0 && source->on_demand == 0) {
|
||||
avl_tree_unlock(global.source_tree);
|
||||
ICECAST_LOG_INFO("Received admin command %s on unavailable mount \"%s\"",
|
||||
command_string, mount);
|
||||
@ -437,8 +434,7 @@ void admin_handle_request(client_t *client, const char *uri)
|
||||
return;
|
||||
}
|
||||
if (client->admin_command == COMMAND_SHOUTCAST_METADATA_UPDATE &&
|
||||
source->shoutcast_compat == 0)
|
||||
{
|
||||
source->shoutcast_compat == 0) {
|
||||
avl_tree_unlock(global.source_tree);
|
||||
ICECAST_LOG_ERROR("illegal change of metadata on non-shoutcast "
|
||||
"compatible stream");
|
||||
@ -450,8 +446,7 @@ void admin_handle_request(client_t *client, const char *uri)
|
||||
admin_handle_mount_request(client, source);
|
||||
avl_tree_unlock(global.source_tree);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
admin_handle_general_request(client);
|
||||
}
|
||||
}
|
||||
@ -502,7 +497,8 @@ static void admin_handle_general_request(client_t *client)
|
||||
}
|
||||
}
|
||||
|
||||
static void admin_handle_mount_request(client_t *client, source_t *source) {
|
||||
static void admin_handle_mount_request(client_t *client, source_t *source)
|
||||
{
|
||||
switch(client->admin_command) {
|
||||
case COMMAND_RAW_STATS:
|
||||
command_stats(client, source->mount, RAW);
|
||||
@ -570,6 +566,7 @@ static void admin_handle_mount_request(client_t *client, source_t *source) {
|
||||
return; \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
#define COMMAND_OPTIONAL(client,name,var) \
|
||||
(var) = httpp_get_query_param((client)->parser, (name))
|
||||
|
||||
@ -577,8 +574,8 @@ static void html_success(client_t *client, char *message)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE, 0,
|
||||
0, 200, NULL,
|
||||
ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
|
||||
0, 0, 200, NULL,
|
||||
"text/html", "utf-8",
|
||||
"", NULL);
|
||||
|
||||
@ -598,7 +595,8 @@ static void html_success(client_t *client, char *message)
|
||||
}
|
||||
|
||||
|
||||
static void command_move_clients(client_t *client, source_t *source,
|
||||
static void command_move_clients(client_t *client,
|
||||
source_t *source,
|
||||
int response)
|
||||
{
|
||||
const char *dest_source;
|
||||
@ -623,20 +621,17 @@ static void command_move_clients(client_t *client, source_t *source,
|
||||
|
||||
dest = source_find_mount(dest_source);
|
||||
|
||||
if (dest == NULL)
|
||||
{
|
||||
if (dest == NULL) {
|
||||
client_send_error(client, 400, 0, "No such destination");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp (dest->mount, source->mount) == 0)
|
||||
{
|
||||
if (strcmp(dest->mount, source->mount) == 0) {
|
||||
client_send_error(client, 400, 0, "supplied mountpoints are identical");
|
||||
return;
|
||||
}
|
||||
|
||||
if (dest->running == 0 && dest->on_demand == 0)
|
||||
{
|
||||
if (dest->running == 0 && dest->on_demand == 0) {
|
||||
client_send_error(client, 400, 0, "Destination not running");
|
||||
return;
|
||||
}
|
||||
@ -655,12 +650,15 @@ static void command_move_clients(client_t *client, source_t *source,
|
||||
xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR(buf));
|
||||
xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
|
||||
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
admin_send_response(doc, client, response, ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
}
|
||||
|
||||
static inline xmlNodePtr __add_listener(client_t *client, xmlNodePtr parent, time_t now, operation_mode mode) {
|
||||
static inline xmlNodePtr __add_listener(client_t *client,
|
||||
xmlNodePtr parent,
|
||||
time_t now,
|
||||
operation_mode mode)
|
||||
{
|
||||
const char *tmp;
|
||||
xmlNodePtr node;
|
||||
char buf[22];
|
||||
@ -703,7 +701,10 @@ static inline xmlNodePtr __add_listener(client_t *client, xmlNodePtr parent, tim
|
||||
return node;
|
||||
}
|
||||
|
||||
void admin_add_listeners_to_mount(source_t *source, xmlNodePtr parent, operation_mode mode) {
|
||||
void admin_add_listeners_to_mount(source_t *source,
|
||||
xmlNodePtr parent,
|
||||
operation_mode mode)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
avl_node *client_node;
|
||||
|
||||
@ -716,7 +717,8 @@ void admin_add_listeners_to_mount(source_t *source, xmlNodePtr parent, operation
|
||||
avl_tree_unlock(source->client_tree);
|
||||
}
|
||||
|
||||
static void command_show_listeners(client_t *client, source_t *source,
|
||||
static void command_show_listeners(client_t *client,
|
||||
source_t *source,
|
||||
int response)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
@ -750,12 +752,13 @@ static void command_buildm3u(client_t *client, const char *mount)
|
||||
COMMAND_REQUIRE(client, "username", username);
|
||||
COMMAND_REQUIRE(client, "password", password);
|
||||
|
||||
ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE, 0,
|
||||
0, 200, NULL,
|
||||
ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
|
||||
0, 0, 200, NULL,
|
||||
"audio/x-mpegurl", NULL,
|
||||
NULL, NULL);
|
||||
|
||||
if (ret == -1 || ret >= (PER_CLIENT_REFBUF_SIZE - 512)) { /* we want at least 512 Byte left for data */
|
||||
if (ret == -1 || ret >= (PER_CLIENT_REFBUF_SIZE - 512)) {
|
||||
/* we want at least 512 Byte left for data */
|
||||
ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
|
||||
client_send_error(client, 500, 0, "Header generation failed.");
|
||||
return;
|
||||
@ -779,7 +782,8 @@ static void command_buildm3u(client_t *client, const char *mount)
|
||||
fserve_add_client (client, NULL);
|
||||
}
|
||||
|
||||
xmlNodePtr admin_add_role_to_authentication(auth_t *auth, xmlNodePtr parent) {
|
||||
xmlNodePtr admin_add_role_to_authentication(auth_t *auth, xmlNodePtr parent)
|
||||
{
|
||||
xmlNodePtr rolenode = xmlNewChild(parent, NULL, XMLSTR("role"), NULL);
|
||||
char idbuf[32];
|
||||
|
||||
@ -800,7 +804,8 @@ xmlNodePtr admin_add_role_to_authentication(auth_t *auth, xmlNodePtr parent) {
|
||||
return rolenode;
|
||||
}
|
||||
|
||||
static void command_manageauth(client_t *client, int response) {
|
||||
static void command_manageauth(client_t *client, int response)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node, rolenode, usersnode, msgnode;
|
||||
const char *action = NULL;
|
||||
@ -814,8 +819,7 @@ static void command_manageauth(client_t *client, int response) {
|
||||
ice_config_t *config = config_get_config();
|
||||
auth_t *auth;
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
/* get id */
|
||||
COMMAND_REQUIRE(client, "id", idstring);
|
||||
id = atol(idstring);
|
||||
@ -848,8 +852,7 @@ static void command_manageauth(client_t *client, int response) {
|
||||
if (action == NULL)
|
||||
action = "list";
|
||||
|
||||
if (!strcmp(action, "add"))
|
||||
{
|
||||
if (!strcmp(action, "add")) {
|
||||
const char *password = NULL;
|
||||
COMMAND_OPTIONAL(client, "password", password);
|
||||
|
||||
@ -872,8 +875,7 @@ static void command_manageauth(client_t *client, int response) {
|
||||
message = strdup("User already exists - not added");
|
||||
}
|
||||
}
|
||||
if (!strcmp(action, "delete"))
|
||||
{
|
||||
if (!strcmp(action, "delete")) {
|
||||
if (username == NULL) {
|
||||
ICECAST_LOG_WARN("manage auth request delete for %lu but no username", id);
|
||||
break;
|
||||
@ -924,7 +926,8 @@ static void command_manageauth(client_t *client, int response) {
|
||||
client_send_error(client, error_code, 0, error_message);
|
||||
}
|
||||
|
||||
static void command_kill_source(client_t *client, source_t *source,
|
||||
static void command_kill_source(client_t *client,
|
||||
source_t *source,
|
||||
int response)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
@ -943,7 +946,8 @@ static void command_kill_source(client_t *client, source_t *source,
|
||||
xmlFreeDoc(doc);
|
||||
}
|
||||
|
||||
static void command_kill_client(client_t *client, source_t *source,
|
||||
static void command_kill_client(client_t *client,
|
||||
source_t *source,
|
||||
int response)
|
||||
{
|
||||
const char *idtext;
|
||||
@ -987,7 +991,8 @@ static void command_kill_client(client_t *client, source_t *source,
|
||||
xmlFreeDoc(doc);
|
||||
}
|
||||
|
||||
static void command_fallback(client_t *client, source_t *source,
|
||||
static void command_fallback(client_t *client,
|
||||
source_t *source,
|
||||
int response)
|
||||
{
|
||||
const char *fallback;
|
||||
@ -1004,7 +1009,8 @@ static void command_fallback(client_t *client, source_t *source,
|
||||
html_success(client, "Fallback configured");
|
||||
}
|
||||
|
||||
static void command_metadata(client_t *client, source_t *source,
|
||||
static void command_metadata(client_t *client,
|
||||
source_t *source,
|
||||
int response)
|
||||
{
|
||||
const char *action;
|
||||
@ -1021,7 +1027,8 @@ static void command_metadata(client_t *client, source_t *source,
|
||||
ICECAST_LOG_DEBUG("Got metadata update request");
|
||||
|
||||
if (source->parser->req_type == httpp_req_put) {
|
||||
ICECAST_LOG_ERROR("Got legacy SOURCE-style metadata update command on source connected with PUT at mountpoint %s", source->mount);
|
||||
ICECAST_LOG_ERROR("Got legacy SOURCE-style metadata update command on "
|
||||
"source connected with PUT at mountpoint %s", source->mount);
|
||||
}
|
||||
|
||||
COMMAND_REQUIRE(client, "mode", action);
|
||||
@ -1030,12 +1037,10 @@ static void command_metadata(client_t *client, source_t *source,
|
||||
COMMAND_OPTIONAL(client, "artist", artist);
|
||||
COMMAND_OPTIONAL(client, "charset", charset);
|
||||
|
||||
if (strcmp (action, "updinfo") != 0)
|
||||
{
|
||||
if (strcmp (action, "updinfo") != 0) {
|
||||
xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR("No such action"));
|
||||
xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("0"));
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
admin_send_response(doc, client, response, ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
return;
|
||||
}
|
||||
@ -1045,17 +1050,12 @@ static void command_metadata(client_t *client, source_t *source,
|
||||
if (response == RAW && acl_test_admin(client->acl, COMMAND_RAW_METADATA_UPDATE) != ACL_POLICY_ALLOW)
|
||||
same_ip = 0;
|
||||
|
||||
if (same_ip && plugin && plugin->set_tag)
|
||||
{
|
||||
if (song)
|
||||
{
|
||||
if (same_ip && plugin && plugin->set_tag) {
|
||||
if (song) {
|
||||
plugin->set_tag (plugin, "song", song, charset);
|
||||
ICECAST_LOG_INFO("Metadata on mountpoint %s changed to \"%s\"", source->mount, song);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (artist && title)
|
||||
{
|
||||
} else {
|
||||
if (artist && title) {
|
||||
plugin->set_tag(plugin, "title", title, charset);
|
||||
plugin->set_tag(plugin, "artist", artist, charset);
|
||||
ICECAST_LOG_INFO("Metadata on mountpoint %s changed to \"%s - %s\"",
|
||||
@ -1064,9 +1064,7 @@ static void command_metadata(client_t *client, source_t *source,
|
||||
}
|
||||
/* updates are now done, let them be pushed into the stream */
|
||||
plugin->set_tag (plugin, NULL, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
xmlNewChild(node, NULL, XMLSTR("message"),
|
||||
XMLSTR("Mountpoint will not accept URL updates"));
|
||||
xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
|
||||
@ -1078,8 +1076,7 @@ static void command_metadata(client_t *client, source_t *source,
|
||||
|
||||
xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR("Metadata update successful"));
|
||||
xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
admin_send_response(doc, client, response, ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
}
|
||||
|
||||
@ -1092,14 +1089,14 @@ static void command_shoutcast_metadata(client_t *client, source_t *source)
|
||||
ICECAST_LOG_DEBUG("Got shoutcast metadata update request");
|
||||
|
||||
if (source->parser->req_type == httpp_req_put) {
|
||||
ICECAST_LOG_ERROR("Got legacy shoutcast-style metadata update command on source connected with PUT at mountpoint %s", source->mount);
|
||||
ICECAST_LOG_ERROR("Got legacy shoutcast-style metadata update command "
|
||||
"on source connected with PUT at mountpoint %s", source->mount);
|
||||
}
|
||||
|
||||
COMMAND_REQUIRE(client, "mode", action);
|
||||
COMMAND_REQUIRE(client, "song", value);
|
||||
|
||||
if (strcmp (action, "updinfo") != 0)
|
||||
{
|
||||
if (strcmp (action, "updinfo") != 0) {
|
||||
client_send_error(client, 400, 0, "No such action");
|
||||
return;
|
||||
}
|
||||
@ -1107,22 +1104,20 @@ static void command_shoutcast_metadata(client_t *client, source_t *source)
|
||||
if (acl_test_admin(client->acl, COMMAND_RAW_METADATA_UPDATE) != ACL_POLICY_ALLOW)
|
||||
same_ip = 0;
|
||||
|
||||
if (same_ip && source->format && source->format->set_tag)
|
||||
{
|
||||
if (same_ip && source->format && source->format->set_tag) {
|
||||
source->format->set_tag (source->format, "title", value, NULL);
|
||||
source->format->set_tag (source->format, NULL, NULL, NULL);
|
||||
|
||||
ICECAST_LOG_DEBUG("Metadata on mountpoint %s changed to \"%s\"",
|
||||
source->mount, value);
|
||||
html_success(client, "Metadata update successful");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
client_send_error(client, 400, 0, "mountpoint will not accept URL updates");
|
||||
}
|
||||
}
|
||||
|
||||
static void command_stats(client_t *client, const char *mount, int response) {
|
||||
static void command_stats(client_t *client, const char *mount, int response)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
|
||||
ICECAST_LOG_DEBUG("Stats request, sending xml stats");
|
||||
@ -1133,7 +1128,8 @@ static void command_stats(client_t *client, const char *mount, int response) {
|
||||
return;
|
||||
}
|
||||
|
||||
static void command_queue_reload(client_t *client, int response) {
|
||||
static void command_queue_reload(client_t *client, int response)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node;
|
||||
|
||||
@ -1156,9 +1152,9 @@ static void command_list_mounts(client_t *client, int response)
|
||||
{
|
||||
ICECAST_LOG_DEBUG("List mounts request");
|
||||
|
||||
if (response == PLAINTEXT)
|
||||
{
|
||||
ssize_t ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE, 0,
|
||||
if (response == PLAINTEXT) {
|
||||
ssize_t ret = util_http_build_header(client->refbuf->data,
|
||||
PER_CLIENT_REFBUF_SIZE, 0,
|
||||
0, 200, NULL,
|
||||
"text/plain", "utf-8",
|
||||
"", NULL);
|
||||
@ -1174,9 +1170,7 @@ static void command_list_mounts(client_t *client, int response)
|
||||
|
||||
client->refbuf->next = stats_get_streams ();
|
||||
fserve_add_client (client, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
xmlDocPtr doc;
|
||||
avl_tree_rlock(global.source_tree);
|
||||
doc = admin_build_sourcelist(NULL);
|
||||
@ -1188,7 +1182,8 @@ static void command_list_mounts(client_t *client, int response)
|
||||
}
|
||||
}
|
||||
|
||||
static void command_updatemetadata(client_t *client, source_t *source,
|
||||
static void command_updatemetadata(client_t *client,
|
||||
source_t *source,
|
||||
int response)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
|
12
src/admin.h
12
src/admin.h
@ -37,10 +37,16 @@
|
||||
#define ADMIN_COMMAND_ANY 0 /* for ACL framework */
|
||||
|
||||
void admin_handle_request(client_t *client, const char *uri);
|
||||
void admin_send_response(xmlDocPtr doc, client_t *client,
|
||||
int response, const char *xslt_template);
|
||||
|
||||
void admin_add_listeners_to_mount(source_t *source, xmlNodePtr parent, operation_mode mode);
|
||||
void admin_send_response(xmlDocPtr doc,
|
||||
client_t *client,
|
||||
int response,
|
||||
const char *xslt_template);
|
||||
|
||||
void admin_add_listeners_to_mount(source_t *source,
|
||||
xmlNodePtr parent,
|
||||
operation_mode mode);
|
||||
|
||||
xmlNodePtr admin_add_role_to_authentication(auth_t *auth, xmlNodePtr parent);
|
||||
|
||||
int admin_get_command(const char *command);
|
||||
|
@ -133,7 +133,12 @@ void auth_addref (auth_t *authenticator);
|
||||
|
||||
int auth_release_client(client_t *client);
|
||||
|
||||
void auth_stack_add_client(auth_stack_t *stack, client_t *client, void (*on_result)(client_t *client, void *userdata, auth_result result), void *userdata);
|
||||
void auth_stack_add_client(auth_stack_t *stack,
|
||||
client_t *client,
|
||||
void (*on_result)(client_t *client,
|
||||
void *userdata,
|
||||
auth_result result),
|
||||
void *userdata);
|
||||
|
||||
void auth_stack_release(auth_stack_t *stack);
|
||||
void auth_stack_addref(auth_stack_t *stack);
|
||||
|
@ -20,11 +20,13 @@
|
||||
#include "logging.h"
|
||||
#define CATMODULE "auth_anonymous"
|
||||
|
||||
static auth_result anonymous_auth (auth_client *auth_user) {
|
||||
static auth_result anonymous_auth(auth_client *auth_user)
|
||||
{
|
||||
return AUTH_OK;
|
||||
}
|
||||
|
||||
int auth_get_anonymous_auth (auth_t *authenticator, config_options_t *options) {
|
||||
int auth_get_anonymous_auth(auth_t *authenticator, config_options_t *options)
|
||||
{
|
||||
authenticator->authenticate_client = anonymous_auth;
|
||||
authenticator->immediate = 1;
|
||||
return 0;
|
||||
|
@ -45,8 +45,7 @@ static auth_result htpasswd_deleteuser(auth_t *auth, const char *username);
|
||||
static auth_result htpasswd_userlist(auth_t *auth, xmlNodePtr srcnode);
|
||||
static int _free_user (void *key);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *pass;
|
||||
} htpasswd_user;
|
||||
@ -58,7 +57,8 @@ typedef struct {
|
||||
time_t mtime;
|
||||
} htpasswd_auth_state;
|
||||
|
||||
static void htpasswd_clear(auth_t *self) {
|
||||
static void htpasswd_clear(auth_t *self)
|
||||
{
|
||||
htpasswd_auth_state *state = self->state;
|
||||
free(state->filename);
|
||||
if (state->users)
|
||||
@ -114,8 +114,7 @@ static void htpasswd_recheckfile (htpasswd_auth_state *htpasswd)
|
||||
|
||||
if (htpasswd->filename == NULL)
|
||||
return;
|
||||
if (stat (htpasswd->filename, &file_stat) < 0)
|
||||
{
|
||||
if (stat (htpasswd->filename, &file_stat) < 0) {
|
||||
ICECAST_LOG_WARN("failed to check status of %s", htpasswd->filename);
|
||||
|
||||
/* Create a dummy users tree for things to use later */
|
||||
@ -127,15 +126,13 @@ static void htpasswd_recheckfile (htpasswd_auth_state *htpasswd)
|
||||
return;
|
||||
}
|
||||
|
||||
if (file_stat.st_mtime == htpasswd->mtime)
|
||||
{
|
||||
if (file_stat.st_mtime == htpasswd->mtime) {
|
||||
/* common case, no update to file */
|
||||
return;
|
||||
}
|
||||
ICECAST_LOG_INFO("re-reading htpasswd file \"%s\"", htpasswd->filename);
|
||||
passwdfile = fopen (htpasswd->filename, "rb");
|
||||
if (passwdfile == NULL)
|
||||
{
|
||||
if (passwdfile == NULL) {
|
||||
ICECAST_LOG_WARN("Failed to open authentication database \"%s\": %s",
|
||||
htpasswd->filename, strerror(errno));
|
||||
return;
|
||||
@ -144,8 +141,7 @@ static void htpasswd_recheckfile (htpasswd_auth_state *htpasswd)
|
||||
|
||||
new_users = avl_tree_new (compare_users, NULL);
|
||||
|
||||
while (get_line(passwdfile, line, MAX_LINE_LEN))
|
||||
{
|
||||
while (get_line(passwdfile, line, MAX_LINE_LEN)) {
|
||||
int len;
|
||||
htpasswd_user *entry;
|
||||
|
||||
@ -154,8 +150,7 @@ static void htpasswd_recheckfile (htpasswd_auth_state *htpasswd)
|
||||
continue;
|
||||
|
||||
sep = strrchr (line, ':');
|
||||
if (sep == NULL)
|
||||
{
|
||||
if (sep == NULL) {
|
||||
ICECAST_LOG_WARN("No separator on line %d (%s)", num, htpasswd->filename);
|
||||
continue;
|
||||
}
|
||||
@ -196,15 +191,13 @@ static auth_result htpasswd_auth (auth_client *auth_user)
|
||||
|
||||
thread_rwlock_rlock (&htpasswd->file_rwlock);
|
||||
entry.name = client->username;
|
||||
if (avl_get_by_key (htpasswd->users, &entry, &result) == 0)
|
||||
{
|
||||
if (avl_get_by_key (htpasswd->users, &entry, &result) == 0) {
|
||||
htpasswd_user *found = result;
|
||||
char *hashed_pw;
|
||||
|
||||
thread_rwlock_unlock (&htpasswd->file_rwlock);
|
||||
hashed_pw = get_hash (client->password, strlen (client->password));
|
||||
if (strcmp (found->pass, hashed_pw) == 0)
|
||||
{
|
||||
if (strcmp (found->pass, hashed_pw) == 0) {
|
||||
free (hashed_pw);
|
||||
return AUTH_OK;
|
||||
}
|
||||
@ -231,19 +224,19 @@ int auth_get_htpasswd_auth (auth_t *authenticator, config_options_t *options)
|
||||
state = calloc(1, sizeof(htpasswd_auth_state));
|
||||
|
||||
while(options) {
|
||||
if(!strcmp(options->name, "filename"))
|
||||
{
|
||||
if(!strcmp(options->name, "filename")) {
|
||||
free (state->filename);
|
||||
state->filename = strdup(options->value);
|
||||
}
|
||||
options = options->next;
|
||||
}
|
||||
|
||||
if (state->filename)
|
||||
if (state->filename) {
|
||||
ICECAST_LOG_INFO("Configured htpasswd authentication using password file \"%s\"",
|
||||
state->filename);
|
||||
else
|
||||
} else {
|
||||
ICECAST_LOG_ERROR("No filename given in options for authenticator.");
|
||||
}
|
||||
|
||||
authenticator->state = state;
|
||||
|
||||
@ -267,16 +260,14 @@ static auth_result htpasswd_adduser (auth_t *auth, const char *username, const c
|
||||
thread_rwlock_wlock (&state->file_rwlock);
|
||||
|
||||
entry.name = (char*)username;
|
||||
if (avl_get_by_key (state->users, &entry, &result) == 0)
|
||||
{
|
||||
if (avl_get_by_key (state->users, &entry, &result) == 0) {
|
||||
thread_rwlock_unlock (&state->file_rwlock);
|
||||
return AUTH_USEREXISTS;
|
||||
}
|
||||
|
||||
passwdfile = fopen(state->filename, "ab");
|
||||
|
||||
if (passwdfile == NULL)
|
||||
{
|
||||
if (passwdfile == NULL) {
|
||||
thread_rwlock_unlock (&state->file_rwlock);
|
||||
ICECAST_LOG_WARN("Failed to open authentication database \"%s\": %s",
|
||||
state->filename, strerror(errno));
|
||||
@ -320,8 +311,7 @@ static auth_result htpasswd_deleteuser(auth_t *auth, const char *username)
|
||||
tmpfile_len = strlen(state->filename) + 6;
|
||||
tmpfile = calloc(1, tmpfile_len);
|
||||
snprintf (tmpfile, tmpfile_len, "%s.tmp", state->filename);
|
||||
if (stat (tmpfile, &file_info) == 0)
|
||||
{
|
||||
if (stat (tmpfile, &file_info) == 0) {
|
||||
ICECAST_LOG_WARN("temp file \"%s\" exists, rejecting operation", tmpfile);
|
||||
free (tmpfile);
|
||||
fclose (passwdfile);
|
||||
@ -369,8 +359,7 @@ static auth_result htpasswd_deleteuser(auth_t *auth, const char *username)
|
||||
if (remove(state->filename) != 0) {
|
||||
ICECAST_LOG_ERROR("Problem moving temp authentication file to original \"%s\" - \"%s\": %s",
|
||||
tmpfile, state->filename, strerror(errno));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (rename(tmpfile, state->filename) != 0) {
|
||||
ICECAST_LOG_ERROR("Problem moving temp authentication file to original \"%s\" - \"%s\": %s",
|
||||
tmpfile, state->filename, strerror(errno));
|
||||
@ -396,8 +385,7 @@ static auth_result htpasswd_userlist(auth_t *auth, xmlNodePtr srcnode)
|
||||
|
||||
thread_rwlock_rlock(&state->file_rwlock);
|
||||
node = avl_get_first(state->users);
|
||||
while (node)
|
||||
{
|
||||
while (node) {
|
||||
htpasswd_user *user = (htpasswd_user *)node->key;
|
||||
newnode = xmlNewChild(srcnode, NULL, XMLSTR("user"), NULL);
|
||||
xmlNewChild(newnode, NULL, XMLSTR("username"), XMLSTR(user->name));
|
||||
|
@ -28,7 +28,8 @@ typedef struct auth_static {
|
||||
char *password;
|
||||
} auth_static_t;
|
||||
|
||||
static auth_result static_auth (auth_client *auth_user) {
|
||||
static auth_result static_auth(auth_client *auth_user)
|
||||
{
|
||||
client_t *client = auth_user->client;
|
||||
auth_t *auth = client->auth;
|
||||
auth_static_t *auth_info = auth->state;
|
||||
@ -49,15 +50,19 @@ static auth_result static_auth (auth_client *auth_user) {
|
||||
return AUTH_FAILED;
|
||||
}
|
||||
|
||||
static void clear_auth (auth_t *auth) {
|
||||
static void clear_auth (auth_t *auth)
|
||||
{
|
||||
auth_static_t *auth_info = auth->state;
|
||||
if (auth_info->username) free(auth_info->username);
|
||||
if (auth_info->password) free(auth_info->password);
|
||||
if (auth_info->username)
|
||||
free(auth_info->username);
|
||||
if (auth_info->password)
|
||||
free(auth_info->password);
|
||||
free(auth_info);
|
||||
auth->state = NULL;
|
||||
}
|
||||
|
||||
static auth_result static_userlist(auth_t *auth, xmlNodePtr srcnode) {
|
||||
static auth_result static_userlist(auth_t *auth, xmlNodePtr srcnode)
|
||||
{
|
||||
auth_static_t *auth_info = auth->state;
|
||||
xmlNodePtr newnode;
|
||||
|
||||
@ -68,7 +73,8 @@ static auth_result static_userlist(auth_t *auth, xmlNodePtr srcnode) {
|
||||
return AUTH_OK;
|
||||
}
|
||||
|
||||
int auth_get_static_auth (auth_t *authenticator, config_options_t *options) {
|
||||
int auth_get_static_auth (auth_t *authenticator, config_options_t *options)
|
||||
{
|
||||
auth_static_t *auth_info;
|
||||
int need_user;
|
||||
|
||||
@ -93,10 +99,12 @@ int auth_get_static_auth (auth_t *authenticator, config_options_t *options) {
|
||||
|
||||
while (options) {
|
||||
if (strcmp(options->name, "username") == 0) {
|
||||
if (auth_info->username) free(auth_info->username);
|
||||
if (auth_info->username)
|
||||
free(auth_info->username);
|
||||
auth_info->username = strdup(options->value);
|
||||
} else if (strcmp(options->name, "password") == 0) {
|
||||
if (auth_info->password) free(auth_info->password);
|
||||
if (auth_info->password)
|
||||
free(auth_info->password);
|
||||
auth_info->password = strdup(options->value);
|
||||
} else {
|
||||
ICECAST_LOG_ERROR("Unknown option: %s", options->name);
|
||||
|
162
src/auth_url.c
162
src/auth_url.c
@ -131,26 +131,27 @@ static int my_getpass(void *client, char *prompt, char *buffer, int buflen)
|
||||
#endif
|
||||
|
||||
|
||||
static size_t handle_returned_header (void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
static size_t handle_returned_header(void *ptr,
|
||||
size_t size,
|
||||
size_t nmemb,
|
||||
void *stream)
|
||||
{
|
||||
auth_client *auth_user = stream;
|
||||
unsigned bytes = size * nmemb;
|
||||
client_t *client = auth_user->client;
|
||||
|
||||
if (client)
|
||||
{
|
||||
if (client) {
|
||||
auth_t *auth = client->auth;
|
||||
auth_url *url = auth->state;
|
||||
if (strncasecmp(ptr, url->auth_header, url->auth_header_len) == 0)
|
||||
url->result = AUTH_OK;
|
||||
if (strncasecmp (ptr, url->timelimit_header, url->timelimit_header_len) == 0)
|
||||
{
|
||||
if (strncasecmp(ptr, url->timelimit_header,
|
||||
url->timelimit_header_len) == 0) {
|
||||
unsigned int limit = 0;
|
||||
sscanf ((char *)ptr+url->timelimit_header_len, "%u\r\n", &limit);
|
||||
client->con->discon_time = time(NULL) + limit;
|
||||
}
|
||||
if (strncasecmp (ptr, "icecast-auth-message: ", 22) == 0)
|
||||
{
|
||||
if (strncasecmp (ptr, "icecast-auth-message: ", 22) == 0) {
|
||||
char *eol;
|
||||
snprintf(url->errormsg, sizeof(url->errormsg), "%s", (char*)ptr+22);
|
||||
eol = strchr(url->errormsg, '\r');
|
||||
@ -165,7 +166,10 @@ static size_t handle_returned_header (void *ptr, size_t size, size_t nmemb, void
|
||||
}
|
||||
|
||||
/* capture returned data, but don't do anything with it */
|
||||
static size_t handle_returned_data (void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
static size_t handle_returned_data(void *ptr,
|
||||
size_t size,
|
||||
size_t nmemb,
|
||||
void *stream)
|
||||
{
|
||||
return (int)(size*nmemb);
|
||||
}
|
||||
@ -177,13 +181,18 @@ static auth_result url_remove_client (auth_client *auth_user)
|
||||
auth_t *auth = client->auth;
|
||||
auth_url *url = auth->state;
|
||||
time_t duration = time(NULL) - client->con->con_time;
|
||||
char *username, *password, *mount, *server;
|
||||
char *username,
|
||||
*password,
|
||||
*mount,
|
||||
*server;
|
||||
const char *mountreq;
|
||||
ice_config_t *config;
|
||||
int port;
|
||||
char *userpwd = NULL, post [4096];
|
||||
char *userpwd = NULL,
|
||||
post[4096];
|
||||
const char *agent;
|
||||
char *user_agent, *ipaddr;
|
||||
char *user_agent,
|
||||
*ipaddr;
|
||||
|
||||
if (url->removeurl == NULL)
|
||||
return AUTH_OK;
|
||||
@ -194,20 +203,23 @@ static auth_result url_remove_client (auth_client *auth_user)
|
||||
config_release_config();
|
||||
|
||||
agent = httpp_getvar(client->parser, "user-agent");
|
||||
if (agent)
|
||||
if (agent) {
|
||||
user_agent = util_url_escape(agent);
|
||||
else
|
||||
} else {
|
||||
user_agent = strdup("-");
|
||||
}
|
||||
|
||||
if (client->username)
|
||||
if (client->username) {
|
||||
username = util_url_escape(client->username);
|
||||
else
|
||||
} else {
|
||||
username = strdup("");
|
||||
}
|
||||
|
||||
if (client->password)
|
||||
if (client->password) {
|
||||
password = util_url_escape(client->password);
|
||||
else
|
||||
} else {
|
||||
password = strdup("");
|
||||
}
|
||||
|
||||
/* get the full uri (with query params if available) */
|
||||
mountreq = httpp_getvar(client->parser, HTTPP_VAR_RAWURI);
|
||||
@ -222,6 +234,7 @@ static auth_result url_remove_client (auth_client *auth_user)
|
||||
url->removeaction, /* already escaped */
|
||||
server, port, client->con->id, mount, username,
|
||||
password, (long unsigned)duration, ipaddr, user_agent);
|
||||
|
||||
free(server);
|
||||
free(mount);
|
||||
free(username);
|
||||
@ -229,26 +242,23 @@ static auth_result url_remove_client (auth_client *auth_user)
|
||||
free(ipaddr);
|
||||
free(user_agent);
|
||||
|
||||
if (strchr (url->removeurl, '@') == NULL)
|
||||
{
|
||||
if (url->userpwd)
|
||||
if (strchr (url->removeurl, '@') == NULL) {
|
||||
if (url->userpwd) {
|
||||
curl_easy_setopt(url->handle, CURLOPT_USERPWD, url->userpwd);
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* auth'd requests may not have a user/pass, but may use query args */
|
||||
if (client->username && client->password)
|
||||
{
|
||||
size_t len = strlen (client->username) + strlen (client->password) + 2;
|
||||
if (client->username && client->password) {
|
||||
size_t len = strlen(client->username) +
|
||||
strlen(client->password) + 2;
|
||||
userpwd = malloc(len);
|
||||
snprintf (userpwd, len, "%s:%s", client->username, client->password);
|
||||
snprintf(userpwd, len, "%s:%s",
|
||||
client->username, client->password);
|
||||
curl_easy_setopt(url->handle, CURLOPT_USERPWD, userpwd);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
curl_easy_setopt(url->handle, CURLOPT_USERPWD, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* url has user/pass but libcurl may need to clear any existing settings */
|
||||
curl_easy_setopt(url->handle, CURLOPT_USERPWD, "");
|
||||
}
|
||||
@ -257,7 +267,8 @@ static auth_result url_remove_client (auth_client *auth_user)
|
||||
curl_easy_setopt(url->handle, CURLOPT_WRITEHEADER, auth_user);
|
||||
|
||||
if (curl_easy_perform (url->handle))
|
||||
ICECAST_LOG_WARN("auth to server %s failed with %s", url->removeurl, url->errormsg);
|
||||
ICECAST_LOG_WARN("auth to server %s failed with %s",
|
||||
url->removeurl, url->errormsg);
|
||||
|
||||
free(userpwd);
|
||||
|
||||
@ -270,15 +281,22 @@ static auth_result url_add_client (auth_client *auth_user)
|
||||
client_t *client = auth_user->client;
|
||||
auth_t *auth = client->auth;
|
||||
auth_url *url = auth->state;
|
||||
int res = 0, port;
|
||||
int res = 0,
|
||||
port;
|
||||
const char *agent;
|
||||
char *user_agent, *username, *password;
|
||||
char *user_agent,
|
||||
*username,
|
||||
*password;
|
||||
const char *mountreq;
|
||||
char *mount, *ipaddr, *server;
|
||||
char *mount,
|
||||
*ipaddr,
|
||||
*server;
|
||||
ice_config_t *config;
|
||||
char *userpwd = NULL, post [4096];
|
||||
ssize_t post_offset;
|
||||
char *pass_headers, *cur_header, *next_header;
|
||||
char *pass_headers,
|
||||
*cur_header,
|
||||
*next_header;
|
||||
const char *header_val;
|
||||
char *header_valesc;
|
||||
|
||||
@ -291,20 +309,23 @@ static auth_result url_add_client (auth_client *auth_user)
|
||||
config_release_config();
|
||||
|
||||
agent = httpp_getvar(client->parser, "user-agent");
|
||||
if (agent)
|
||||
if (agent) {
|
||||
user_agent = util_url_escape(agent);
|
||||
else
|
||||
} else {
|
||||
user_agent = strdup("-");
|
||||
}
|
||||
|
||||
if (client->username)
|
||||
if (client->username) {
|
||||
username = util_url_escape(client->username);
|
||||
else
|
||||
} else {
|
||||
username = strdup("");
|
||||
}
|
||||
|
||||
if (client->password)
|
||||
if (client->password) {
|
||||
password = util_url_escape(client->password);
|
||||
else
|
||||
} else {
|
||||
password = strdup("");
|
||||
}
|
||||
|
||||
/* get the full uri (with query params if available) */
|
||||
mountreq = httpp_getvar(client->parser, HTTPP_VAR_RAWURI);
|
||||
@ -319,6 +340,7 @@ static auth_result url_add_client (auth_client *auth_user)
|
||||
url->addaction, /* already escaped */
|
||||
server, port, client->con->id, mount, username,
|
||||
password, ipaddr, user_agent);
|
||||
|
||||
free(server);
|
||||
free(mount);
|
||||
free(user_agent);
|
||||
@ -329,23 +351,21 @@ static auth_result url_add_client (auth_client *auth_user)
|
||||
pass_headers = NULL;
|
||||
if (url->pass_headers)
|
||||
pass_headers = strdup(url->pass_headers);
|
||||
if (pass_headers)
|
||||
{
|
||||
if (pass_headers) {
|
||||
cur_header = pass_headers;
|
||||
while (cur_header)
|
||||
{
|
||||
while (cur_header) {
|
||||
next_header = strstr(cur_header, ",");
|
||||
if (next_header)
|
||||
{
|
||||
if (next_header) {
|
||||
*next_header=0;
|
||||
next_header++;
|
||||
}
|
||||
|
||||
header_val = httpp_getvar (client->parser, cur_header);
|
||||
if (header_val)
|
||||
{
|
||||
if (header_val) {
|
||||
header_valesc = util_url_escape (header_val);
|
||||
post_offset += snprintf (post+post_offset, sizeof (post)-post_offset, "&%s%s=%s",
|
||||
post_offset += snprintf(post + post_offset,
|
||||
sizeof(post) - post_offset,
|
||||
"&%s%s=%s",
|
||||
url->prefix_headers ? url->prefix_headers : "",
|
||||
cur_header, header_valesc);
|
||||
free(header_valesc);
|
||||
@ -355,26 +375,22 @@ static auth_result url_add_client (auth_client *auth_user)
|
||||
}
|
||||
}
|
||||
|
||||
if (strchr (url->addurl, '@') == NULL)
|
||||
{
|
||||
if (url->userpwd)
|
||||
if (strchr(url->addurl, '@') == NULL) {
|
||||
if (url->userpwd) {
|
||||
curl_easy_setopt(url->handle, CURLOPT_USERPWD, url->userpwd);
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* auth'd requests may not have a user/pass, but may use query args */
|
||||
if (client->username && client->password)
|
||||
{
|
||||
if (client->username && client->password) {
|
||||
size_t len = strlen(client->username) + strlen(client->password) + 2;
|
||||
userpwd = malloc (len);
|
||||
snprintf (userpwd, len, "%s:%s", client->username, client->password);
|
||||
snprintf(userpwd, len, "%s:%s",
|
||||
client->username, client->password);
|
||||
curl_easy_setopt(url->handle, CURLOPT_USERPWD, userpwd);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
curl_easy_setopt (url->handle, CURLOPT_USERPWD, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* url has user/pass but libcurl may need to clear any existing settings */
|
||||
curl_easy_setopt(url->handle, CURLOPT_USERPWD, "");
|
||||
}
|
||||
@ -388,19 +404,22 @@ static auth_result url_add_client (auth_client *auth_user)
|
||||
|
||||
free(userpwd);
|
||||
|
||||
if (res)
|
||||
{
|
||||
ICECAST_LOG_WARN("auth to server %s failed with %s", url->addurl, url->errormsg);
|
||||
if (res) {
|
||||
ICECAST_LOG_WARN("auth to server %s failed with %s",
|
||||
url->addurl, url->errormsg);
|
||||
return AUTH_FAILED;
|
||||
}
|
||||
/* we received a response, lets see what it is */
|
||||
if (url->result == AUTH_FAILED) {
|
||||
ICECAST_LOG_INFO("client auth (%s) failed with \"%s\"", url->addurl, url->errormsg);
|
||||
ICECAST_LOG_INFO("client auth (%s) failed with \"%s\"",
|
||||
url->addurl, url->errormsg);
|
||||
}
|
||||
return url->result;
|
||||
}
|
||||
|
||||
static auth_result auth_url_adduser(auth_t *auth, const char *username, const char *password)
|
||||
static auth_result auth_url_adduser(auth_t *auth,
|
||||
const char *username,
|
||||
const char *password)
|
||||
{
|
||||
return AUTH_FAILED;
|
||||
}
|
||||
@ -476,8 +495,7 @@ int auth_get_url_auth(auth_t *authenticator, config_options_t *options)
|
||||
url_info->removeaction = util_url_escape(removeaction);
|
||||
|
||||
url_info->handle = curl_easy_init();
|
||||
if (url_info->handle == NULL)
|
||||
{
|
||||
if (url_info->handle == NULL) {
|
||||
auth_url_clear(authenticator);
|
||||
return -1;
|
||||
}
|
||||
@ -498,11 +516,11 @@ int auth_get_url_auth(auth_t *authenticator, config_options_t *options)
|
||||
#endif
|
||||
curl_easy_setopt(url_info->handle, CURLOPT_ERRORBUFFER, &url_info->errormsg[0]);
|
||||
|
||||
if (url_info->username && url_info->password)
|
||||
{
|
||||
if (url_info->username && url_info->password) {
|
||||
int len = strlen(url_info->username) + strlen(url_info->password) + 2;
|
||||
url_info->userpwd = malloc(len);
|
||||
snprintf (url_info->userpwd, len, "%s:%s", url_info->username, url_info->password);
|
||||
snprintf(url_info->userpwd, len, "%s:%s",
|
||||
url_info->username, url_info->password);
|
||||
}
|
||||
|
||||
ICECAST_LOG_INFO("URL based authentication setup");
|
||||
|
1067
src/cfgfile.c
1067
src/cfgfile.c
File diff suppressed because it is too large
Load Diff
@ -77,32 +77,47 @@ typedef enum _mount_type {
|
||||
} mount_type;
|
||||
|
||||
typedef struct _mount_proxy {
|
||||
char *mountname; /* The mountpoint this proxy is used for */
|
||||
|
||||
mount_type mounttype; /* The type of the mount point */
|
||||
|
||||
char *dumpfile; /* Filename to dump this stream to (will be appended). NULL
|
||||
to not dump. */
|
||||
char *intro_filename; /* Send contents of file to client before the stream */
|
||||
int fallback_when_full; /* switch new listener to fallback source
|
||||
when max listeners reached */
|
||||
int max_listeners; /* Max listeners for this mountpoint only. -1 to not
|
||||
limit here (i.e. only use the global limit) */
|
||||
char *fallback_mount; /* Fallback mountname */
|
||||
|
||||
int fallback_override; /* When this source arrives, do we steal back
|
||||
clients from the fallback? */
|
||||
int no_mount; /* Do we permit direct requests of this mountpoint? (or only
|
||||
indirect, through fallbacks) */
|
||||
int burst_size; /* amount to send to a new client if possible, -1 take
|
||||
* from global setting */
|
||||
/* The mountpoint this proxy is used for */
|
||||
char *mountname;
|
||||
/* The type of the mount point */
|
||||
mount_type mounttype;
|
||||
/* Filename to dump this stream to (will be appended).
|
||||
* NULL to not dump.
|
||||
*/
|
||||
char *dumpfile;
|
||||
/* Send contents of file to client before the stream */
|
||||
char *intro_filename;
|
||||
/* Switch new listener to fallback source when max listeners reached */
|
||||
int fallback_when_full;
|
||||
/* Max listeners for this mountpoint only.
|
||||
* -1 to not limit here (i.e. only use the global limit)
|
||||
*/
|
||||
int max_listeners;
|
||||
/* Fallback mountname */
|
||||
char *fallback_mount;
|
||||
/* When this source arrives, do we steal back
|
||||
* clients from the fallback?
|
||||
*/
|
||||
int fallback_override;
|
||||
/* Do we permit direct requests of this mountpoint?
|
||||
* (or only indirect, through fallbacks)
|
||||
*/
|
||||
int no_mount;
|
||||
/* amount to send to a new client if possible, -1 take
|
||||
* from global setting
|
||||
*/
|
||||
int burst_size;
|
||||
unsigned int queue_size_limit;
|
||||
int hidden; /* Do we list this on the xsl pages */
|
||||
unsigned int source_timeout; /* source timeout in seconds */
|
||||
char *charset; /* character set if not utf8 */
|
||||
int mp3_meta_interval; /* outgoing per-stream metadata interval */
|
||||
|
||||
ice_config_http_header_t *http_headers; /* additional HTTP headers */
|
||||
/* Do we list this on the xsl pages */
|
||||
int hidden;
|
||||
/* source timeout in seconds */
|
||||
unsigned int source_timeout;
|
||||
/* character set if not utf8 */
|
||||
char *charset;
|
||||
/* outgoing per-stream metadata interval */
|
||||
int mp3_meta_interval;
|
||||
/* additional HTTP headers */
|
||||
ice_config_http_header_t *http_headers;
|
||||
|
||||
struct event_registration_tag *event;
|
||||
|
||||
|
18
src/client.c
18
src/client.c
@ -70,10 +70,11 @@ int client_create(client_t **c_ptr, connection_t *con, http_parser_t *parser)
|
||||
config = config_get_config();
|
||||
|
||||
global.clients++;
|
||||
if (config->client_limit < global.clients)
|
||||
if (config->client_limit < global.clients) {
|
||||
ICECAST_LOG_WARN("server client limit reached (%d/%d)", config->client_limit, global.clients);
|
||||
else
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
config_release_config ();
|
||||
|
||||
@ -99,8 +100,7 @@ void client_destroy(client_t *client)
|
||||
|
||||
/* release the buffer now, as the buffer could be on the source queue
|
||||
* and may of disappeared after auth completes */
|
||||
if (client->refbuf)
|
||||
{
|
||||
if (client->refbuf) {
|
||||
refbuf_release (client->refbuf);
|
||||
client->refbuf = NULL;
|
||||
}
|
||||
@ -113,7 +113,6 @@ void client_destroy(client_t *client)
|
||||
*/
|
||||
if (client->respcode && client->parser)
|
||||
logging_access(client);
|
||||
|
||||
if (client->con)
|
||||
connection_close(client->con);
|
||||
if (client->parser)
|
||||
@ -141,14 +140,12 @@ int client_read_bytes(client_t *client, void *buf, unsigned len)
|
||||
{
|
||||
int bytes;
|
||||
|
||||
if (client->refbuf && client->refbuf->len)
|
||||
{
|
||||
if (client->refbuf && client->refbuf->len) {
|
||||
/* we have data to read from a refbuf first */
|
||||
if (client->refbuf->len < len)
|
||||
len = client->refbuf->len;
|
||||
memcpy (buf, client->refbuf->data, len);
|
||||
if (len < client->refbuf->len)
|
||||
{
|
||||
if (len < client->refbuf->len) {
|
||||
char *ptr = client->refbuf->data;
|
||||
memmove (ptr, ptr+len, client->refbuf->len - len);
|
||||
}
|
||||
@ -200,7 +197,8 @@ void client_send_100(client_t *client)
|
||||
}
|
||||
|
||||
/* this function is designed to work even if client is in bad state */
|
||||
static inline void client_send_500(client_t *client, const char *message) {
|
||||
static inline void client_send_500(client_t *client, const char *message)
|
||||
{
|
||||
const char header[] = "HTTP/1.0 500 Internal Server Error\r\nContent-Type: text/plain; charset=utf-8\r\n\r\n"
|
||||
"500 - Internal Server Error\n---------------------------\n";
|
||||
const ssize_t header_len = sizeof(header) - 1;
|
||||
|
345
src/connection.c
345
src/connection.c
@ -135,7 +135,8 @@ static int free_filtered_ip (void*x)
|
||||
|
||||
void connection_initialize(void)
|
||||
{
|
||||
if (_initialized) return;
|
||||
if (_initialized)
|
||||
return;
|
||||
|
||||
thread_spin_create (&_connection_lock);
|
||||
thread_mutex_create(&move_clients_mutex);
|
||||
@ -157,7 +158,8 @@ void connection_initialize(void)
|
||||
|
||||
void connection_shutdown(void)
|
||||
{
|
||||
if (!_initialized) return;
|
||||
if (!_initialized)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
SSL_CTX_free (ssl_ctx);
|
||||
@ -204,27 +206,22 @@ static void get_ssl_certificate (ice_config_t *config)
|
||||
SSL_CTX_set_options(ssl_ctx, ssl_opts|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
|
||||
#endif
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
if (config->cert_file == NULL)
|
||||
break;
|
||||
if (SSL_CTX_use_certificate_chain_file (ssl_ctx, config->cert_file) <= 0)
|
||||
{
|
||||
if (SSL_CTX_use_certificate_chain_file (ssl_ctx, config->cert_file) <= 0) {
|
||||
ICECAST_LOG_WARN("Invalid cert file %s", config->cert_file);
|
||||
break;
|
||||
}
|
||||
if (SSL_CTX_use_PrivateKey_file (ssl_ctx, config->cert_file, SSL_FILETYPE_PEM) <= 0)
|
||||
{
|
||||
if (SSL_CTX_use_PrivateKey_file (ssl_ctx, config->cert_file, SSL_FILETYPE_PEM) <= 0) {
|
||||
ICECAST_LOG_WARN("Invalid private key file %s", config->cert_file);
|
||||
break;
|
||||
}
|
||||
if (!SSL_CTX_check_private_key (ssl_ctx))
|
||||
{
|
||||
if (!SSL_CTX_check_private_key (ssl_ctx)) {
|
||||
ICECAST_LOG_ERROR("Invalid %s - Private key does not match cert public key", config->cert_file);
|
||||
break;
|
||||
}
|
||||
if (SSL_CTX_set_cipher_list(ssl_ctx, config->cipher_list) <= 0)
|
||||
{
|
||||
if (SSL_CTX_set_cipher_list(ssl_ctx, config->cipher_list) <= 0) {
|
||||
ICECAST_LOG_WARN("Invalid cipher list: %s", config->cipher_list);
|
||||
}
|
||||
ssl_ok = 1;
|
||||
@ -243,10 +240,8 @@ static int connection_read_ssl (connection_t *con, void *buf, size_t len)
|
||||
{
|
||||
int bytes = SSL_read(con->ssl, buf, len);
|
||||
|
||||
if (bytes < 0)
|
||||
{
|
||||
switch (SSL_get_error (con->ssl, bytes))
|
||||
{
|
||||
if (bytes < 0) {
|
||||
switch (SSL_get_error(con->ssl, bytes)) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
return -1;
|
||||
@ -260,18 +255,16 @@ static int connection_send_ssl (connection_t *con, const void *buf, size_t len)
|
||||
{
|
||||
int bytes = SSL_write (con->ssl, buf, len);
|
||||
|
||||
if (bytes < 0)
|
||||
{
|
||||
switch (SSL_get_error (con->ssl, bytes))
|
||||
{
|
||||
if (bytes < 0) {
|
||||
switch (SSL_get_error(con->ssl, bytes)){
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
return -1;
|
||||
}
|
||||
con->error = 1;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
con->sent_bytes += bytes;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
#else
|
||||
@ -301,13 +294,12 @@ static int connection_read (connection_t *con, void *buf, size_t len)
|
||||
static int connection_send(connection_t *con, const void *buf, size_t len)
|
||||
{
|
||||
int bytes = sock_write_bytes(con->sock, buf, len);
|
||||
if (bytes < 0)
|
||||
{
|
||||
if (bytes < 0) {
|
||||
if (!sock_recoverable(sock_error()))
|
||||
con->error = 1;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
con->sent_bytes += bytes;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@ -318,8 +310,7 @@ static int connection_send (connection_t *con, const void *buf, size_t len)
|
||||
static void recheck_ip_file(cache_file_contents *cache)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
if (now >= cache->file_recheck)
|
||||
{
|
||||
if (now >= cache->file_recheck) {
|
||||
struct stat file_stat;
|
||||
FILE *file = NULL;
|
||||
int count = 0;
|
||||
@ -327,17 +318,14 @@ static void recheck_ip_file(cache_file_contents *cache)
|
||||
char line[MAX_LINE_LEN];
|
||||
|
||||
cache->file_recheck = now + 10;
|
||||
if (cache->filename == NULL)
|
||||
{
|
||||
if (cache->contents)
|
||||
{
|
||||
if (cache->filename == NULL) {
|
||||
if (cache->contents) {
|
||||
avl_tree_free (cache->contents, free_filtered_ip);
|
||||
cache->contents = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (stat (cache->filename, &file_stat) < 0)
|
||||
{
|
||||
if (stat(cache->filename, &file_stat) < 0) {
|
||||
ICECAST_LOG_WARN("failed to check status of \"%s\": %s", cache->filename, strerror(errno));
|
||||
return;
|
||||
}
|
||||
@ -347,16 +335,14 @@ static void recheck_ip_file(cache_file_contents *cache)
|
||||
cache->file_mtime = file_stat.st_mtime;
|
||||
|
||||
file = fopen (cache->filename, "r");
|
||||
if (file == NULL)
|
||||
{
|
||||
if (file == NULL) {
|
||||
ICECAST_LOG_WARN("Failed to open file \"%s\": %s", cache->filename, strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
new_ips = avl_tree_new(compare_ip, NULL);
|
||||
|
||||
while (get_line (file, line, MAX_LINE_LEN))
|
||||
{
|
||||
while (get_line(file, line, MAX_LINE_LEN)) {
|
||||
char *str;
|
||||
if(!line[0] || line[0] == '#')
|
||||
continue;
|
||||
@ -368,7 +354,8 @@ static void recheck_ip_file(cache_file_contents *cache)
|
||||
fclose (file);
|
||||
ICECAST_LOG_INFO("%d entries read from file \"%s\"", count, cache->filename);
|
||||
|
||||
if (cache->contents) avl_tree_free (cache->contents, free_filtered_ip);
|
||||
if (cache->contents)
|
||||
avl_tree_free(cache->contents, free_filtered_ip);
|
||||
cache->contents = new_ips;
|
||||
}
|
||||
}
|
||||
@ -382,23 +369,17 @@ static int accept_ip_address(char *ip)
|
||||
recheck_ip_file(&banned_ip);
|
||||
recheck_ip_file(&allowed_ip);
|
||||
|
||||
if (banned_ip.contents)
|
||||
{
|
||||
if (avl_get_by_key (banned_ip.contents, ip, &result) == 0)
|
||||
{
|
||||
if (banned_ip.contents) {
|
||||
if (avl_get_by_key (banned_ip.contents, ip, &result) == 0) {
|
||||
ICECAST_LOG_DEBUG("%s is banned", ip);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (allowed_ip.contents)
|
||||
{
|
||||
if (avl_get_by_key (allowed_ip.contents, ip, &result) == 0)
|
||||
{
|
||||
if (allowed_ip.contents) {
|
||||
if (avl_get_by_key (allowed_ip.contents, ip, &result) == 0) {
|
||||
ICECAST_LOG_DEBUG("%s is allowed", ip);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ICECAST_LOG_DEBUG("%s is not allowed", ip);
|
||||
return 0;
|
||||
}
|
||||
@ -411,8 +392,7 @@ connection_t *connection_create (sock_t sock, sock_t serversock, char *ip)
|
||||
{
|
||||
connection_t *con;
|
||||
con = (connection_t *)calloc(1, sizeof(connection_t));
|
||||
if (con)
|
||||
{
|
||||
if (con) {
|
||||
con->sock = sock;
|
||||
con->serversock = serversock;
|
||||
con->con_time = time(NULL);
|
||||
@ -453,19 +433,15 @@ static sock_t wait_for_serversock(int timeout)
|
||||
ret = poll(ufds, global.server_sockets, timeout);
|
||||
if(ret < 0) {
|
||||
return SOCK_ERROR;
|
||||
}
|
||||
else if(ret == 0) {
|
||||
} else if(ret == 0) {
|
||||
return SOCK_ERROR;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
int dst;
|
||||
for(i=0; i < global.server_sockets; i++) {
|
||||
if(ufds[i].revents & POLLIN)
|
||||
return ufds[i].fd;
|
||||
if(ufds[i].revents & (POLLHUP|POLLERR|POLLNVAL))
|
||||
{
|
||||
if (ufds[i].revents & (POLLHUP|POLLERR))
|
||||
{
|
||||
if(ufds[i].revents & (POLLHUP|POLLERR|POLLNVAL)) {
|
||||
if (ufds[i].revents & (POLLHUP|POLLERR)) {
|
||||
sock_close (global.serversock[i]);
|
||||
ICECAST_LOG_WARN("Had to close a listening socket");
|
||||
}
|
||||
@ -473,8 +449,7 @@ static sock_t wait_for_serversock(int timeout)
|
||||
}
|
||||
}
|
||||
/* remove any closed sockets */
|
||||
for(i=0, dst=0; i < global.server_sockets; i++)
|
||||
{
|
||||
for(i=0, dst=0; i < global.server_sockets; i++) {
|
||||
if (global.serversock[i] == SOCK_ERROR)
|
||||
continue;
|
||||
if (i!=dst)
|
||||
@ -507,11 +482,9 @@ static sock_t wait_for_serversock(int timeout)
|
||||
ret = select(max+1, &rfds, NULL, NULL, p);
|
||||
if(ret < 0) {
|
||||
return SOCK_ERROR;
|
||||
}
|
||||
else if(ret == 0) {
|
||||
} else if(ret == 0) {
|
||||
return SOCK_ERROR;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for(i=0; i < global.server_sockets; i++) {
|
||||
if(FD_ISSET(global.serversock[i], &rfds))
|
||||
return global.serversock[i];
|
||||
@ -534,8 +507,7 @@ static connection_t *_accept_connection(int duration)
|
||||
ip = (char *)malloc(MAX_ADDR_LEN);
|
||||
|
||||
sock = sock_accept(serversock, ip, MAX_ADDR_LEN);
|
||||
if (sock != SOCK_ERROR)
|
||||
{
|
||||
if (sock != SOCK_ERROR) {
|
||||
connection_t *con = NULL;
|
||||
/* Make any IPv4 mapped IPv6 address look like a normal IPv4 address */
|
||||
if (strncmp(ip, "::ffff:", 7) == 0)
|
||||
@ -546,11 +518,8 @@ static connection_t *_accept_connection(int duration)
|
||||
if (con)
|
||||
return con;
|
||||
sock_close(sock);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sock_recoverable(sock_error()))
|
||||
{
|
||||
} else {
|
||||
if (!sock_recoverable(sock_error())) {
|
||||
ICECAST_LOG_WARN("accept() failed with error %d: %s", sock_error(), strerror(sock_error()));
|
||||
thread_sleep(500000);
|
||||
}
|
||||
@ -582,8 +551,7 @@ static client_queue_t *_get_connection(void)
|
||||
|
||||
thread_spin_lock(&_connection_lock);
|
||||
|
||||
if (_con_queue)
|
||||
{
|
||||
if (_con_queue){
|
||||
node = (client_queue_t *)_con_queue;
|
||||
_con_queue = node->next;
|
||||
if (_con_queue == NULL)
|
||||
@ -604,23 +572,21 @@ static void process_request_queue (void)
|
||||
int timeout = config->header_timeout;
|
||||
config_release_config();
|
||||
|
||||
while (*node_ref)
|
||||
{
|
||||
while (*node_ref) {
|
||||
client_queue_t *node = *node_ref;
|
||||
client_t *client = node->client;
|
||||
int len = PER_CLIENT_REFBUF_SIZE - 1 - node->offset;
|
||||
char *buf = client->refbuf->data + node->offset;
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
if (client->con->con_time + timeout <= time(NULL))
|
||||
if (len > 0) {
|
||||
if (client->con->con_time + timeout <= time(NULL)) {
|
||||
len = 0;
|
||||
else
|
||||
} else {
|
||||
len = client_read_bytes(client, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
if (len > 0) {
|
||||
int pass_it = 1;
|
||||
char *ptr;
|
||||
|
||||
@ -628,10 +594,8 @@ static void process_request_queue (void)
|
||||
* EOL as \r\r\n */
|
||||
node->offset += len;
|
||||
client->refbuf->data[node->offset] = '\000';
|
||||
do
|
||||
{
|
||||
if (node->shoutcast == 1)
|
||||
{
|
||||
do {
|
||||
if (node->shoutcast == 1) {
|
||||
/* password line */
|
||||
if (strstr (client->refbuf->data, "\r\r\n") != NULL)
|
||||
break;
|
||||
@ -643,28 +607,24 @@ static void process_request_queue (void)
|
||||
/* stream_offset refers to the start of any data sent after the
|
||||
* http style headers, we don't want to lose those */
|
||||
ptr = strstr(client->refbuf->data, "\r\r\n\r\r\n");
|
||||
if (ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
node->stream_offset = (ptr+6) - client->refbuf->data;
|
||||
break;
|
||||
}
|
||||
ptr = strstr(client->refbuf->data, "\r\n\r\n");
|
||||
if (ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
node->stream_offset = (ptr+4) - client->refbuf->data;
|
||||
break;
|
||||
}
|
||||
ptr = strstr(client->refbuf->data, "\n\n");
|
||||
if (ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
node->stream_offset = (ptr+2) - client->refbuf->data;
|
||||
break;
|
||||
}
|
||||
pass_it = 0;
|
||||
} while (0);
|
||||
|
||||
if (pass_it)
|
||||
{
|
||||
if (pass_it) {
|
||||
if ((client_queue_t **)_req_queue_tail == &(node->next))
|
||||
_req_queue_tail = (volatile client_queue_t **)node_ref;
|
||||
*node_ref = node->next;
|
||||
@ -672,11 +632,8 @@ static void process_request_queue (void)
|
||||
_add_connection(node);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len == 0 || client->con->error)
|
||||
{
|
||||
} else {
|
||||
if (len == 0 || client->con->error) {
|
||||
if ((client_queue_t **)_req_queue_tail == &node->next)
|
||||
_req_queue_tail = (volatile client_queue_t **)node_ref;
|
||||
*node_ref = node->next;
|
||||
@ -711,20 +668,17 @@ void connection_accept_loop (void)
|
||||
get_ssl_certificate(config);
|
||||
config_release_config();
|
||||
|
||||
while (global.running == ICECAST_RUNNING)
|
||||
{
|
||||
while (global.running == ICECAST_RUNNING) {
|
||||
con = _accept_connection (duration);
|
||||
|
||||
if (con)
|
||||
{
|
||||
if (con) {
|
||||
client_queue_t *node;
|
||||
ice_config_t *config;
|
||||
client_t *client = NULL;
|
||||
listener_t *listener;
|
||||
|
||||
global_lock();
|
||||
if (client_create (&client, con, NULL) < 0)
|
||||
{
|
||||
if (client_create (&client, con, NULL) < 0) {
|
||||
global_unlock();
|
||||
client_send_error(client, 403, 1, "Icecast connection limit reached");
|
||||
/* don't be too eager as this is an imposed hard limit */
|
||||
@ -735,8 +689,7 @@ void connection_accept_loop (void)
|
||||
/* setup client for reading incoming http */
|
||||
client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000';
|
||||
|
||||
if (sock_set_blocking (client->con->sock, 0) || sock_set_nodelay (client->con->sock))
|
||||
{
|
||||
if (sock_set_blocking (client->con->sock, 0) || sock_set_nodelay (client->con->sock)) {
|
||||
global_unlock();
|
||||
ICECAST_LOG_WARN("failed to set tcp options on client connection, dropping");
|
||||
client_destroy(client);
|
||||
@ -744,8 +697,7 @@ void connection_accept_loop (void)
|
||||
}
|
||||
|
||||
node = calloc (1, sizeof (client_queue_t));
|
||||
if (node == NULL)
|
||||
{
|
||||
if (node == NULL) {
|
||||
global_unlock();
|
||||
client_destroy(client);
|
||||
continue;
|
||||
@ -755,8 +707,7 @@ void connection_accept_loop (void)
|
||||
config = config_get_config();
|
||||
listener = config_get_listen_sock(config, client->con);
|
||||
|
||||
if (listener)
|
||||
{
|
||||
if (listener) {
|
||||
if (listener->shoutcast_compat)
|
||||
node->shoutcast = 1;
|
||||
if (listener->ssl && ssl_ok)
|
||||
@ -770,9 +721,7 @@ void connection_accept_loop (void)
|
||||
_add_request_queue(node);
|
||||
stats_event_inc(NULL, "connections");
|
||||
duration = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (_req_queue == NULL)
|
||||
duration = 300; /* use longer timeouts when nothing waiting */
|
||||
}
|
||||
@ -799,8 +748,7 @@ int connection_complete_source (source_t *source, int response)
|
||||
ICECAST_LOG_DEBUG("sources count is %d", global.sources);
|
||||
|
||||
config = config_get_config();
|
||||
if (global.sources < config->source_limit)
|
||||
{
|
||||
if (global.sources < config->source_limit) {
|
||||
const char *contenttype;
|
||||
const char *expectcontinue;
|
||||
mount_proxy *mountinfo;
|
||||
@ -808,12 +756,10 @@ int connection_complete_source (source_t *source, int response)
|
||||
|
||||
/* setup format handler */
|
||||
contenttype = httpp_getvar (source->parser, "content-type");
|
||||
if (contenttype != NULL)
|
||||
{
|
||||
if (contenttype != NULL) {
|
||||
format_type = format_get_type(contenttype);
|
||||
|
||||
if (format_type == FORMAT_ERROR)
|
||||
{
|
||||
if (format_type == FORMAT_ERROR) {
|
||||
config_release_config();
|
||||
global_unlock();
|
||||
if (response) {
|
||||
@ -839,12 +785,10 @@ int connection_complete_source (source_t *source, int response)
|
||||
format_type = FORMAT_TYPE_GENERIC;
|
||||
}
|
||||
|
||||
if (format_get_plugin (format_type, source) < 0)
|
||||
{
|
||||
if (format_get_plugin (format_type, source) < 0) {
|
||||
global_unlock();
|
||||
config_release_config();
|
||||
if (response)
|
||||
{
|
||||
if (response) {
|
||||
client_send_error(source->client, 403, 1, "internal format allocation problem");
|
||||
source->client = NULL;
|
||||
}
|
||||
@ -854,8 +798,7 @@ int connection_complete_source (source_t *source, int response)
|
||||
|
||||
/* For PUT support we check for 100-continue and send back a 100 to stay in spec */
|
||||
expectcontinue = httpp_getvar (source->parser, "expect");
|
||||
if (expectcontinue != NULL)
|
||||
{
|
||||
if (expectcontinue != NULL) {
|
||||
#ifdef HAVE_STRCASESTR
|
||||
if (strcasestr (expectcontinue, "100-continue") != NULL)
|
||||
#else
|
||||
@ -888,8 +831,7 @@ int connection_complete_source (source_t *source, int response)
|
||||
global_unlock();
|
||||
config_release_config();
|
||||
|
||||
if (response)
|
||||
{
|
||||
if (response) {
|
||||
client_send_error(source->client, 403, 1, "too many sources connected");
|
||||
source->client = NULL;
|
||||
}
|
||||
@ -902,13 +844,11 @@ static inline void source_startup (client_t *client, const char *uri)
|
||||
source_t *source;
|
||||
source = source_reserve(uri);
|
||||
|
||||
if (source)
|
||||
{
|
||||
if (source) {
|
||||
source->client = client;
|
||||
source->parser = client->parser;
|
||||
source->con = client->con;
|
||||
if (connection_complete_source (source, 1) < 0)
|
||||
{
|
||||
if (connection_complete_source(source, 1) < 0) {
|
||||
source_clear_source(source);
|
||||
source_free_source(source);
|
||||
return;
|
||||
@ -932,9 +872,7 @@ static inline void source_startup (client_t *client, const char *uri)
|
||||
client->refbuf = ok;
|
||||
fserve_add_client_callback(client, source_client_callback, source);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
client_send_error(client, 403, 1, "Mountpoint in use");
|
||||
ICECAST_LOG_WARN("Mountpoint %s in use", uri);
|
||||
}
|
||||
@ -946,8 +884,7 @@ static void _handle_source_request (client_t *client, const char *uri)
|
||||
ICECAST_LOG_INFO("Source logging in at mountpoint \"%s\" from %s as role %s",
|
||||
uri, client->con->ip, client->role);
|
||||
|
||||
if (uri[0] != '/')
|
||||
{
|
||||
if (uri[0] != '/') {
|
||||
ICECAST_LOG_WARN("source mountpoint not starting with /");
|
||||
client_send_error(client, 400, 1, "source mountpoint not starting with /");
|
||||
return;
|
||||
@ -975,8 +912,7 @@ static int __add_listener_to_source (source_t *source, client_t *client)
|
||||
{
|
||||
size_t loop = 10;
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
ICECAST_LOG_DEBUG("max on %s is %ld (cur %lu)", source->mount,
|
||||
source->max_listeners, source->listeners);
|
||||
if (source->max_listeners == -1)
|
||||
@ -984,15 +920,13 @@ static int __add_listener_to_source (source_t *source, client_t *client)
|
||||
if (source->listeners < (unsigned long)source->max_listeners)
|
||||
break;
|
||||
|
||||
if (loop && source->fallback_when_full && source->fallback_mount)
|
||||
{
|
||||
if (loop && source->fallback_when_full && source->fallback_mount) {
|
||||
source_t *next = source_find_mount (source->fallback_mount);
|
||||
if (!next) {
|
||||
ICECAST_LOG_ERROR("Fallback '%s' for full source '%s' not found",
|
||||
source->mount, source->fallback_mount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ICECAST_LOG_INFO("stream full trying %s", next->mount);
|
||||
source = next;
|
||||
loop--;
|
||||
@ -1012,8 +946,7 @@ static int __add_listener_to_source (source_t *source, client_t *client)
|
||||
avl_insert(source->pending_tree, client);
|
||||
avl_tree_unlock(source->pending_tree);
|
||||
|
||||
if (source->running == 0 && source->on_demand)
|
||||
{
|
||||
if (source->running == 0 && source->on_demand) {
|
||||
/* enable on-demand relay to start, wake up the slave thread */
|
||||
ICECAST_LOG_DEBUG("kicking off on-demand relay");
|
||||
source->on_demand_req = 1;
|
||||
@ -1034,26 +967,26 @@ static inline ssize_t __count_user_role_on_mount (source_t *source, client_t *cl
|
||||
if (existing_client->username && client->username &&
|
||||
strcmp(existing_client->username, client->username) == 0 &&
|
||||
existing_client->role && client->role &&
|
||||
strcmp(existing_client->role, client->role) == 0)
|
||||
strcmp(existing_client->role, client->role) == 0) {
|
||||
ret++;
|
||||
}
|
||||
node = avl_get_next(node);
|
||||
}
|
||||
avl_tree_unlock(source->client_tree);
|
||||
|
||||
avl_tree_rlock(source->pending_tree);
|
||||
node = avl_get_first(source->pending_tree);
|
||||
while (node)
|
||||
{
|
||||
while (node) {
|
||||
client_t *existing_client = (client_t *)node->key;
|
||||
if (existing_client->username && client->username &&
|
||||
strcmp(existing_client->username, client->username) == 0 &&
|
||||
existing_client->role && client->role &&
|
||||
strcmp(existing_client->role, client->role) == 0)
|
||||
strcmp(existing_client->role, client->role) == 0){
|
||||
ret++;
|
||||
}
|
||||
node = avl_get_next(node);
|
||||
}
|
||||
avl_tree_unlock(source->pending_tree);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1106,7 +1039,8 @@ static void _handle_get_request (client_t *client, char *uri) {
|
||||
/* check for duplicate_logins */
|
||||
if (max_connections_per_user > 0) { /* -1 = not set (-> default=unlimited), 0 = unlimited */
|
||||
if (max_connections_per_user <= __count_user_role_on_mount(source, client)) {
|
||||
client_send_error(client, 403, 1, "Reached limit of concurrent connections on those credentials");
|
||||
client_send_error(client, 403, 1, "Reached limit of concurrent "
|
||||
"connections on those credentials");
|
||||
in_error = 1;
|
||||
}
|
||||
}
|
||||
@ -1152,23 +1086,20 @@ static void _handle_shoutcast_compatible (client_queue_t *node)
|
||||
|
||||
/* Get rid of trailing \r\n or \n after password */
|
||||
ptr = strstr(client->refbuf->data, "\r\r\n");
|
||||
if (ptr)
|
||||
if (ptr) {
|
||||
headers = ptr+3;
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ptr = strstr(client->refbuf->data, "\r\n");
|
||||
if (ptr)
|
||||
if (ptr) {
|
||||
headers = ptr+2;
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ptr = strstr(client->refbuf->data, "\n");
|
||||
if (ptr)
|
||||
headers = ptr+1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
{
|
||||
if (ptr == NULL){
|
||||
client_destroy(client);
|
||||
free(node->shoutcast_mount);
|
||||
free(node);
|
||||
@ -1202,13 +1133,11 @@ static void _handle_shoutcast_compatible (client_queue_t *node)
|
||||
|
||||
parser = httpp_create_parser();
|
||||
httpp_initialize(parser, NULL);
|
||||
if (httpp_parse (parser, http_compliant, strlen(http_compliant)))
|
||||
{
|
||||
if (httpp_parse(parser, http_compliant, strlen(http_compliant))) {
|
||||
/* we may have more than just headers, so prepare for it */
|
||||
if (node->stream_offset == node->offset)
|
||||
if (node->stream_offset == node->offset) {
|
||||
client->refbuf->len = 0;
|
||||
else
|
||||
{
|
||||
} else {
|
||||
char *ptr = client->refbuf->data;
|
||||
client->refbuf->len = node->offset - node->stream_offset;
|
||||
memmove(ptr, ptr + node->stream_offset, client->refbuf->len);
|
||||
@ -1217,8 +1146,7 @@ static void _handle_shoutcast_compatible (client_queue_t *node)
|
||||
client->protocol = ICECAST_PROTOCOL_SHOUTCAST;
|
||||
node->shoutcast = 0;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
httpp_destroy(parser);
|
||||
client_destroy(client);
|
||||
}
|
||||
@ -1231,7 +1159,8 @@ static void _handle_shoutcast_compatible (client_queue_t *node)
|
||||
/* Handle <alias> lookups here.
|
||||
*/
|
||||
|
||||
static int _handle_aliases(client_t *client, char **uri) {
|
||||
static int _handle_aliases(client_t *client, char **uri)
|
||||
{
|
||||
const char *http_host = httpp_getvar(client->parser, "host");
|
||||
char *serverhost = NULL;
|
||||
int serverport = 0;
|
||||
@ -1253,8 +1182,7 @@ static int _handle_aliases(client_t *client, char **uri) {
|
||||
|
||||
config = config_get_config();
|
||||
listen_sock = config_get_listen_sock (config, client->con);
|
||||
if (listen_sock)
|
||||
{
|
||||
if (listen_sock) {
|
||||
serverhost = listen_sock->bind_address;
|
||||
serverport = listen_sock->port;
|
||||
}
|
||||
@ -1291,7 +1219,8 @@ static int _handle_aliases(client_t *client, char **uri) {
|
||||
|
||||
/* Handle any client that passed the authing process.
|
||||
*/
|
||||
static void _handle_authed_client(client_t *client, void *uri, auth_result result) {
|
||||
static void _handle_authed_client(client_t *client, void *uri, auth_result result)
|
||||
{
|
||||
auth_stack_release(client->authstack);
|
||||
client->authstack = NULL;
|
||||
|
||||
@ -1331,7 +1260,8 @@ static void _handle_authed_client(client_t *client, void *uri, auth_result resul
|
||||
/* Handle clients that still need to authenticate.
|
||||
*/
|
||||
|
||||
static void _handle_authentication_global(client_t *client, void *uri, auth_result result) {
|
||||
static void _handle_authentication_global(client_t *client, void *uri, auth_result result)
|
||||
{
|
||||
ice_config_t *config;
|
||||
|
||||
auth_stack_release(client->authstack);
|
||||
@ -1349,14 +1279,16 @@ static void _handle_authentication_global(client_t *client, void *uri, auth_resu
|
||||
config_release_config();
|
||||
}
|
||||
|
||||
static inline mount_proxy * __find_non_admin_mount(ice_config_t *config, const char *name, mount_type type) {
|
||||
static inline mount_proxy * __find_non_admin_mount(ice_config_t *config, const char *name, mount_type type)
|
||||
{
|
||||
if (strcmp(name, "/admin.cgi") == 0 || strncmp(name, "/admin/", 7) == 0)
|
||||
return NULL;
|
||||
|
||||
return config_find_mount(config, name, type);
|
||||
}
|
||||
|
||||
static void _handle_authentication_mount_generic(client_t *client, void *uri, mount_type type, void (*callback)(client_t*, void*, auth_result)) {
|
||||
static void _handle_authentication_mount_generic(client_t *client, void *uri, mount_type type, void (*callback)(client_t*, void*, auth_result))
|
||||
{
|
||||
ice_config_t *config;
|
||||
mount_proxy *mountproxy;
|
||||
auth_stack_t *stack = NULL;
|
||||
@ -1384,7 +1316,8 @@ static void _handle_authentication_mount_generic(client_t *client, void *uri, mo
|
||||
}
|
||||
}
|
||||
|
||||
static void _handle_authentication_mount_default(client_t *client, void *uri, auth_result result) {
|
||||
static void _handle_authentication_mount_default(client_t *client, void *uri, auth_result result)
|
||||
{
|
||||
auth_stack_release(client->authstack);
|
||||
client->authstack = NULL;
|
||||
|
||||
@ -1398,16 +1331,19 @@ static void _handle_authentication_mount_default(client_t *client, void *uri, au
|
||||
_handle_authentication_mount_generic(client, uri, MOUNT_TYPE_DEFAULT, _handle_authentication_global);
|
||||
}
|
||||
|
||||
static void _handle_authentication_mount_normal(client_t *client, char *uri) {
|
||||
static void _handle_authentication_mount_normal(client_t *client, char *uri)
|
||||
{
|
||||
ICECAST_LOG_DEBUG("Trying <mount type=\"normal\"> specific authenticators for client %p.", client);
|
||||
_handle_authentication_mount_generic(client, uri, MOUNT_TYPE_NORMAL, _handle_authentication_mount_default);
|
||||
}
|
||||
|
||||
static void _handle_authentication(client_t *client, char *uri) {
|
||||
static void _handle_authentication(client_t *client, char *uri)
|
||||
{
|
||||
_handle_authentication_mount_normal(client, uri);
|
||||
}
|
||||
|
||||
static void __prepare_shoutcast_admin_cgi_request(client_t *client) {
|
||||
static void __prepare_shoutcast_admin_cgi_request(client_t *client)
|
||||
{
|
||||
ice_config_t *config;
|
||||
const char *sc_mount;
|
||||
const char *pass = httpp_get_query_param(client->parser, "pass");
|
||||
@ -1448,17 +1384,14 @@ static void _handle_connection(void)
|
||||
const char *rawuri;
|
||||
client_queue_t *node;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (1) {
|
||||
node = _get_connection();
|
||||
if (node)
|
||||
{
|
||||
if (node) {
|
||||
client_t *client = node->client;
|
||||
int already_parsed = 0;
|
||||
|
||||
/* Check for special shoutcast compatability processing */
|
||||
if (node->shoutcast)
|
||||
{
|
||||
if (node->shoutcast) {
|
||||
_handle_shoutcast_compatible (node);
|
||||
if (node->shoutcast)
|
||||
continue;
|
||||
@ -1473,15 +1406,13 @@ static void _handle_connection(void)
|
||||
httpp_initialize(parser, NULL);
|
||||
client->parser = parser;
|
||||
}
|
||||
if (already_parsed || httpp_parse (parser, client->refbuf->data, node->offset))
|
||||
{
|
||||
if (already_parsed || httpp_parse (parser, client->refbuf->data, node->offset)) {
|
||||
char *uri;
|
||||
|
||||
/* we may have more than just headers, so prepare for it */
|
||||
if (node->stream_offset == node->offset)
|
||||
if (node->stream_offset == node->offset) {
|
||||
client->refbuf->len = 0;
|
||||
else
|
||||
{
|
||||
} else {
|
||||
char *ptr = client->refbuf->data;
|
||||
client->refbuf->len = node->offset - node->stream_offset;
|
||||
memmove (ptr, ptr + node->stream_offset, client->refbuf->len);
|
||||
@ -1529,9 +1460,7 @@ static void _handle_connection(void)
|
||||
}
|
||||
|
||||
_handle_authentication(client, uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
free (node);
|
||||
ICECAST_LOG_ERROR("HTTP request parsing failed");
|
||||
client_destroy (client);
|
||||
@ -1555,15 +1484,13 @@ int connection_setup_sockets (ice_config_t *config)
|
||||
allowed_ip.filename = NULL;
|
||||
|
||||
global_lock();
|
||||
if (global.serversock)
|
||||
{
|
||||
if (global.serversock) {
|
||||
for (; count < global.server_sockets; count++)
|
||||
sock_close (global.serversock [count]);
|
||||
free (global.serversock);
|
||||
global.serversock = NULL;
|
||||
}
|
||||
if (config == NULL)
|
||||
{
|
||||
if (config == NULL) {
|
||||
global_unlock();
|
||||
return 0;
|
||||
}
|
||||
@ -1580,17 +1507,14 @@ int connection_setup_sockets (ice_config_t *config)
|
||||
|
||||
listener = config->listen_sock;
|
||||
prev = &config->listen_sock;
|
||||
while (listener)
|
||||
{
|
||||
while (listener) {
|
||||
int successful = 0;
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
sock_t sock = sock_get_server_socket (listener->port, listener->bind_address);
|
||||
if (sock == SOCK_ERROR)
|
||||
break;
|
||||
if (sock_listen (sock, ICECAST_LISTEN_QUEUE) == SOCK_ERROR)
|
||||
{
|
||||
if (sock_listen (sock, ICECAST_LISTEN_QUEUE) == SOCK_ERROR) {
|
||||
sock_close (sock);
|
||||
break;
|
||||
}
|
||||
@ -1602,22 +1526,23 @@ int connection_setup_sockets (ice_config_t *config)
|
||||
global.serversock [count] = sock;
|
||||
count++;
|
||||
} while(0);
|
||||
if (successful == 0)
|
||||
{
|
||||
if (listener->bind_address)
|
||||
if (successful == 0) {
|
||||
if (listener->bind_address) {
|
||||
ICECAST_LOG_ERROR("Could not create listener socket on port %d bind %s",
|
||||
listener->port, listener->bind_address);
|
||||
else
|
||||
} else {
|
||||
ICECAST_LOG_ERROR("Could not create listener socket on port %d", listener->port);
|
||||
}
|
||||
/* remove failed connection */
|
||||
*prev = config_clear_listener (listener);
|
||||
listener = *prev;
|
||||
continue;
|
||||
}
|
||||
if (listener->bind_address)
|
||||
if (listener->bind_address) {
|
||||
ICECAST_LOG_INFO("listener socket on port %d address %s", listener->port, listener->bind_address);
|
||||
else
|
||||
} else {
|
||||
ICECAST_LOG_INFO("listener socket on port %d", listener->port);
|
||||
}
|
||||
prev = &listener->next;
|
||||
listener = listener->next;
|
||||
}
|
||||
@ -1634,8 +1559,10 @@ int connection_setup_sockets (ice_config_t *config)
|
||||
void connection_close(connection_t *con)
|
||||
{
|
||||
sock_close(con->sock);
|
||||
if (con->ip) free(con->ip);
|
||||
if (con->host) free(con->host);
|
||||
if (con->ip)
|
||||
free(con->ip);
|
||||
if (con->host)
|
||||
free(con->host);
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (con->ssl) { SSL_shutdown(con->ssl); SSL_free(con->ssl); }
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user