mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Merge branch 'update-listen-sockets' into devel
This commit is contained in:
commit
ababd1c5dd
@ -17,6 +17,7 @@ nobase_dist_admin_DATA = \
|
||||
dashboard.xsl \
|
||||
fallbacks.xsl \
|
||||
showlog.xsl \
|
||||
listensocketlist.xsl \
|
||||
includes/confirm.xsl \
|
||||
includes/footer.xsl \
|
||||
includes/head.xsl \
|
||||
@ -25,6 +26,7 @@ nobase_dist_admin_DATA = \
|
||||
includes/mountnav.xsl \
|
||||
includes/player.xsl \
|
||||
includes/playlist.xsl \
|
||||
includes/authlist.xsl \
|
||||
includes/web-page.xsl \
|
||||
ui/confirmdeleteuser.xsl \
|
||||
ui/confirmkillclient.xsl \
|
||||
|
24
admin/includes/authlist.xsl
Normal file
24
admin/includes/authlist.xsl
Normal file
@ -0,0 +1,24 @@
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<xsl:template name="authlist">
|
||||
<ul>
|
||||
<xsl:for-each select="authentication/role">
|
||||
<li>Role
|
||||
<xsl:if test="@name">
|
||||
<xsl:value-of select="@name" />
|
||||
</xsl:if>
|
||||
of type <xsl:value-of select="@type" />
|
||||
<xsl:if test="@management-url">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@can-adduser='true' or @can-deleteuser='true'">
|
||||
(<a href="{@management-url}">Manage</a>)
|
||||
</xsl:when>
|
||||
<xsl:when test="@can-listuser='true'">
|
||||
(<a href="{@management-url}">List</a>)
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:if>
|
||||
</li>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
@ -11,6 +11,7 @@
|
||||
<li class="adminlink"><a href="/admin/dashboard.xsl">Dashboard</a></li>
|
||||
<li class="adminlink"><a href="/admin/stats.xsl">Server status</a></li>
|
||||
<li class="adminlink"><a href="/admin/listmounts.xsl">Mountpoint list</a></li>
|
||||
<li class="adminlink"><a href="/admin/listensocketlist.xsl">Listen Socket list</a></li>
|
||||
<li class="adminlink"><a href="/admin/showlog.xsl">Logfiles</a></li>
|
||||
<xsl:for-each select="(/report/extension/icestats | /icestats | /iceresponse)/modules/module">
|
||||
<xsl:if test="@management-url and @management-title">
|
||||
|
94
admin/listensocketlist.xsl
Normal file
94
admin/listensocketlist.xsl
Normal file
@ -0,0 +1,94 @@
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<xsl:include href="includes/page.xsl"/>
|
||||
<xsl:include href="includes/authlist.xsl"/>
|
||||
<xsl:variable name="title">Listen Sockets</xsl:variable>
|
||||
|
||||
<xsl:template name="content">
|
||||
<h2><xsl:value-of select="$title" /></h2>
|
||||
<xsl:for-each select="/report/incident">
|
||||
<section class="box">
|
||||
<h3 class="box_title">Listen Socket <code><xsl:value-of select="resource/value[@member='id']/@value" /></code></h3>
|
||||
<h4>Overview</h4>
|
||||
<table class="table-block">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<xsl:if test="resource/value[@member='id']/@state = 'set'">
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td><xsl:value-of select="resource/value[@member='id']/@value" /></td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<xsl:if test="resource/value[@member='on_behalf_of']/@state = 'set'">
|
||||
<tr>
|
||||
<td>On behalf of</td>
|
||||
<td><xsl:value-of select="resource/value[@member='on_behalf_of']/@value" /></td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<tr>
|
||||
<td>Type</td>
|
||||
<td><xsl:value-of select="resource/value[@member='type']/@value" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Family</td>
|
||||
<td><xsl:value-of select="resource/value[@member='family']/@value" /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h4>Config</h4>
|
||||
<table class="table-block">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<xsl:for-each select="resource/value[@member='config']/value">
|
||||
<xsl:if test="@state != 'unset'">
|
||||
<tr>
|
||||
<td><xsl:value-of select="@member" /></td>
|
||||
<td><xsl:value-of select="@value" /></td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<xsl:if test="resource/value[@member='headers']/value">
|
||||
<h4>Header</h4>
|
||||
<table class="table-block">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<xsl:for-each select="resource/value[@member='headers']/value">
|
||||
<tr>
|
||||
<td><xsl:value-of select="value[@member='type']/@value" /></td>
|
||||
<td><xsl:value-of select="value[@member='name']/@value" /></td>
|
||||
<td><xsl:value-of select="value[@member='value']/@value" /></td>
|
||||
<td><xsl:value-of select="value[@member='status']/@value" /></td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</tbody>
|
||||
</table>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:for-each select="resource/extension/icestats">
|
||||
<h4>Authentication</h4>
|
||||
<xsl:call-template name="authlist" />
|
||||
</xsl:for-each>
|
||||
</section>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
@ -3,34 +3,10 @@
|
||||
<xsl:include href="includes/page.xsl"/>
|
||||
<xsl:include href="includes/mountnav.xsl"/>
|
||||
<xsl:include href="includes/player.xsl"/>
|
||||
<xsl:include href="includes/authlist.xsl"/>
|
||||
|
||||
<xsl:variable name="title">Active Mountpoints</xsl:variable>
|
||||
|
||||
<!-- Auth template -->
|
||||
<xsl:template name="authlist">
|
||||
<ul>
|
||||
<xsl:for-each select="authentication/role">
|
||||
<li>Role
|
||||
<xsl:if test="@name">
|
||||
<xsl:value-of select="@name" />
|
||||
</xsl:if>
|
||||
of type <xsl:value-of select="@type" />
|
||||
<xsl:if test="@management-url">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@can-adduser='true' or @can-deleteuser='true'">
|
||||
(<a href="{@management-url}">Manage</a>)
|
||||
</xsl:when>
|
||||
<xsl:when test="@can-listuser='true'">
|
||||
(<a href="{@management-url}">List</a>)
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:if>
|
||||
</li>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template name="content">
|
||||
<div class="section">
|
||||
<h2><xsl:value-of select="$title" /></h2>
|
||||
|
@ -4,36 +4,12 @@
|
||||
<xsl:include href="includes/mountnav.xsl"/>
|
||||
<xsl:include href="includes/player.xsl"/>
|
||||
<xsl:include href="includes/playlist.xsl"/>
|
||||
<xsl:include href="includes/authlist.xsl"/>
|
||||
|
||||
<xsl:param name="param-showall" />
|
||||
<xsl:param name="param-has-mount" />
|
||||
<xsl:variable name="title">Server status</xsl:variable>
|
||||
|
||||
<!-- Auth template -->
|
||||
<xsl:template name="authlist">
|
||||
<ul>
|
||||
<xsl:for-each select="authentication/role">
|
||||
<li>Role
|
||||
<xsl:if test="@name">
|
||||
<xsl:value-of select="@name" />
|
||||
</xsl:if>
|
||||
of type <xsl:value-of select="@type" />
|
||||
<xsl:if test="@management-url">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@can-adduser='true' or @can-deleteuser='true'">
|
||||
(<a href="{@management-url}">Manage</a>)
|
||||
</xsl:when>
|
||||
<xsl:when test="@can-listuser='true'">
|
||||
(<a href="{@management-url}">List</a>)
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:if>
|
||||
</li>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template name="content">
|
||||
<h2>Server status</h2>
|
||||
|
||||
|
137
src/admin.c
137
src/admin.c
@ -28,10 +28,13 @@
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include "common/net/sock.h"
|
||||
|
||||
#include "admin.h"
|
||||
#include "compat.h"
|
||||
#include "cfgfile.h"
|
||||
#include "connection.h"
|
||||
#include "listensocket.h"
|
||||
#include "refbuf.h"
|
||||
#include "client.h"
|
||||
#include "source.h"
|
||||
@ -95,6 +98,8 @@
|
||||
#define STREAMLIST_HTML_REQUEST "streamlist.xsl"
|
||||
#define STREAMLIST_JSON_REQUEST "streamlist.json"
|
||||
#define STREAMLIST_PLAINTEXT_REQUEST "streamlist.txt"
|
||||
#define LISTENSOCKETLIST_RAW_REQUEST "listensocketlist"
|
||||
#define LISTENSOCKETLIST_HTML_REQUEST "listensocketlist.xsl"
|
||||
#define MOVECLIENTS_RAW_REQUEST "moveclients"
|
||||
#define MOVECLIENTS_HTML_REQUEST "moveclients.xsl"
|
||||
#define MOVECLIENTS_JSON_REQUEST "moveclients.json"
|
||||
@ -145,6 +150,7 @@ static void command_stats (client_t *client, source_t *source, adm
|
||||
static void command_public_stats (client_t *client, source_t *source, admin_format_t response);
|
||||
static void command_queue_reload (client_t *client, source_t *source, admin_format_t response);
|
||||
static void command_list_mounts (client_t *client, source_t *source, admin_format_t response);
|
||||
static void command_list_listen_sockets (client_t *client, source_t *source, admin_format_t response);
|
||||
static void command_move_clients (client_t *client, source_t *source, admin_format_t response);
|
||||
static void command_kill_client (client_t *client, source_t *source, admin_format_t response);
|
||||
static void command_kill_source (client_t *client, source_t *source, admin_format_t response);
|
||||
@ -183,6 +189,8 @@ static const admin_command_handler_t handlers[] = {
|
||||
{ STREAMLIST_PLAINTEXT_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_PLAINTEXT, ADMINSAFE_SAFE, command_list_mounts, NULL},
|
||||
{ STREAMLIST_HTML_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_HTML, ADMINSAFE_SAFE, command_list_mounts, NULL},
|
||||
{ STREAMLIST_JSON_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_JSON, ADMINSAFE_SAFE, command_list_mounts, NULL},
|
||||
{ LISTENSOCKETLIST_RAW_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_RAW, ADMINSAFE_SAFE, command_list_listen_sockets, NULL},
|
||||
{ LISTENSOCKETLIST_HTML_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_HTML, ADMINSAFE_SAFE, command_list_listen_sockets, NULL},
|
||||
{ MOVECLIENTS_RAW_REQUEST, ADMINTYPE_MOUNT, ADMIN_FORMAT_RAW, ADMINSAFE_HYBRID, command_move_clients, NULL},
|
||||
{ MOVECLIENTS_HTML_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_HTML, ADMINSAFE_HYBRID, command_move_clients, NULL},
|
||||
{ MOVECLIENTS_JSON_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_JSON, ADMINSAFE_HYBRID, command_move_clients, NULL},
|
||||
@ -1311,6 +1319,124 @@ static void command_list_mounts(client_t *client, source_t *source, admin_format
|
||||
}
|
||||
}
|
||||
|
||||
static void command_list_listen_sockets(client_t *client, source_t *source, admin_format_t response)
|
||||
{
|
||||
reportxml_t *report = client_get_empty_reportxml();
|
||||
listensocket_t ** sockets;
|
||||
size_t i;
|
||||
|
||||
global_lock();
|
||||
sockets = listensocket_container_list_sockets(global.listensockets);
|
||||
global_unlock();
|
||||
|
||||
for (i = 0; sockets[i]; i++) {
|
||||
const listener_t * listener = listensocket_get_listener(sockets[i]);
|
||||
reportxml_node_t * incident = client_add_empty_incident(report, "ee231290-81c6-484a-836c-20a00ad09898", NULL, NULL);
|
||||
reportxml_node_t * resource = reportxml_node_new(REPORTXML_NODE_TYPE_RESOURCE, NULL, NULL, NULL);
|
||||
reportxml_node_t * config = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL);
|
||||
|
||||
reportxml_node_set_attribute(resource, "type", "result");
|
||||
reportxml_node_set_attribute(config, "type", "structure");
|
||||
reportxml_node_set_attribute(config, "member", "config");
|
||||
|
||||
reportxml_node_add_child(resource, config);
|
||||
reportxml_node_add_child(incident, resource);
|
||||
refobject_unref(incident);
|
||||
|
||||
reportxml_helper_add_value_enum(resource, "type", listensocket_type_to_string(listener->type));
|
||||
reportxml_helper_add_value_enum(resource, "family", sock_family_to_string(listensocket_get_family(sockets[i])));
|
||||
reportxml_helper_add_value_string(resource, "id", listener->id);
|
||||
reportxml_helper_add_value_string(resource, "on_behalf_of", listener->on_behalf_of);
|
||||
|
||||
if (listener->port > 0) {
|
||||
reportxml_helper_add_value_int(config, "port", listener->port);
|
||||
} else {
|
||||
reportxml_helper_add_value(config, "int", "port", NULL);
|
||||
}
|
||||
|
||||
if (listener->so_sndbuf) {
|
||||
reportxml_helper_add_value_int(config, "so_sndbuf", listener->so_sndbuf);
|
||||
} else {
|
||||
reportxml_helper_add_value(config, "int", "so_sndbuf", NULL);
|
||||
}
|
||||
|
||||
if (listener->listen_backlog > 0) {
|
||||
reportxml_helper_add_value_int(config, "listen_backlog", listener->listen_backlog);
|
||||
} else {
|
||||
reportxml_helper_add_value(config, "int", "listen_backlog", NULL);
|
||||
}
|
||||
|
||||
reportxml_helper_add_value_string(config, "bind_address", listener->bind_address);
|
||||
reportxml_helper_add_value_boolean(config, "shoutcast_compat", listener->shoutcast_compat);
|
||||
reportxml_helper_add_value_string(config, "shoutcast_mount", listener->shoutcast_mount);
|
||||
reportxml_helper_add_value_enum(config, "tlsmode", listensocket_tlsmode_to_string(listener->tls));
|
||||
|
||||
if (listener->authstack) {
|
||||
reportxml_node_t * extension = reportxml_node_new(REPORTXML_NODE_TYPE_EXTENSION, NULL, NULL, NULL);
|
||||
xmlNodePtr xmlroot = xmlNewNode(NULL, XMLSTR("icestats"));
|
||||
|
||||
reportxml_node_set_attribute(extension, "application", ADMIN_ICESTATS_LEGACY_EXTENSION_APPLICATION);
|
||||
reportxml_node_add_child(resource, extension);
|
||||
|
||||
xmlSetProp(xmlroot, XMLSTR("xmlns"), XMLSTR(XMLNS_LEGACY_STATS));
|
||||
|
||||
stats_add_authstack(listener->authstack, xmlroot);
|
||||
|
||||
reportxml_node_add_xml_child(extension, xmlroot);
|
||||
refobject_unref(extension);
|
||||
xmlFreeNode(xmlroot);
|
||||
}
|
||||
|
||||
if (listener->http_headers) {
|
||||
reportxml_node_t * headers = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL);
|
||||
ice_config_http_header_t *cur;
|
||||
|
||||
reportxml_node_set_attribute(headers, "member", "headers");
|
||||
reportxml_node_set_attribute(headers, "type", "unordered-list");
|
||||
reportxml_node_add_child(resource, headers);
|
||||
|
||||
for (cur = listener->http_headers; cur; cur = cur->next) {
|
||||
reportxml_node_t * header = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL);
|
||||
reportxml_node_set_attribute(header, "type", "structure");
|
||||
reportxml_node_add_child(headers, header);
|
||||
|
||||
switch (cur->type) {
|
||||
case HTTP_HEADER_TYPE_STATIC:
|
||||
reportxml_helper_add_value_enum(header, "type", "static");
|
||||
break;
|
||||
case HTTP_HEADER_TYPE_CORS:
|
||||
reportxml_helper_add_value_enum(header, "type", "cors");
|
||||
break;
|
||||
}
|
||||
|
||||
reportxml_helper_add_value_string(header, "name", cur->name);
|
||||
reportxml_helper_add_value_string(header, "value", cur->value);
|
||||
|
||||
if (cur->status > 100) {
|
||||
reportxml_helper_add_value_int(header, "status", cur->status > 100);
|
||||
} else {
|
||||
reportxml_helper_add_value(header, "int", "status", NULL);
|
||||
}
|
||||
|
||||
reportxml_helper_add_value_string(config, "shoutcast_mount", listener->shoutcast_mount);
|
||||
refobject_unref(header);
|
||||
}
|
||||
|
||||
refobject_unref(headers);
|
||||
}
|
||||
|
||||
refobject_unref(config);
|
||||
refobject_unref(resource);
|
||||
listensocket_release_listener(sockets[i]);
|
||||
refobject_unref(sockets[i]);
|
||||
}
|
||||
|
||||
free(sockets);
|
||||
|
||||
client_send_reportxml(client, report, DOCUMENT_DOMAIN_ADMIN, LISTENSOCKETLIST_HTML_REQUEST, response, 200, NULL);
|
||||
refobject_unref(report);
|
||||
}
|
||||
|
||||
static void command_updatemetadata(client_t *client,
|
||||
source_t *source,
|
||||
admin_format_t response)
|
||||
@ -1495,6 +1621,7 @@ static void command_dashboard (client_t *client, source_t *source, adm
|
||||
bool has_many_clients;
|
||||
bool has_too_many_clients;
|
||||
bool has_legacy_sources;
|
||||
bool inet6_enabled;
|
||||
|
||||
|
||||
resource = reportxml_node_new(REPORTXML_NODE_TYPE_RESOURCE, NULL, NULL, NULL);
|
||||
@ -1520,13 +1647,14 @@ static void command_dashboard (client_t *client, source_t *source, adm
|
||||
has_many_clients = global.clients > ((75 * config->client_limit) / 100);
|
||||
has_too_many_clients = global.clients > ((90 * config->client_limit) / 100);
|
||||
has_legacy_sources = global.sources_legacy > 0;
|
||||
inet6_enabled = listensocket_container_is_family_included(global.listensockets, SOCK_FAMILY_INET6);
|
||||
global_unlock();
|
||||
reportxml_node_add_child(resource, node);
|
||||
refobject_unref(node);
|
||||
|
||||
if (config->config_problems || has_too_many_clients) {
|
||||
status = command_dashboard__atbest(status, ADMIN_DASHBOARD_STATUS_ERROR);
|
||||
} else if (!has_sources || has_many_clients) {
|
||||
} else if (!has_sources || has_many_clients || !inet6_enabled) {
|
||||
status = command_dashboard__atbest(status, ADMIN_DASHBOARD_STATUS_WARNING);
|
||||
}
|
||||
|
||||
@ -1535,6 +1663,13 @@ static void command_dashboard (client_t *client, source_t *source, adm
|
||||
__reportxml_add_maintenance(reportnode, config->reportxml_db, "c704804e-d3b9-4544-898b-d477078135de", "warning", "Developer logging is active. This mode is not for production.", NULL);
|
||||
#endif
|
||||
|
||||
if (!inet6_enabled) {
|
||||
__reportxml_add_maintenance(reportnode, config->reportxml_db, "f90219e1-bd07-4b54-b1ee-0ba6a0289a15", "warning", "IPv6 not enabled.", NULL);
|
||||
if (sock_is_ipv4_mapped_supported()) {
|
||||
__reportxml_add_maintenance(reportnode, config->reportxml_db, "709ab43b-251d-49a5-a4fe-c749eaabf17c", "info", "IPv4-mapped IPv6 is available on this system.", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (config->config_problems & CONFIG_PROBLEM_HOSTNAME)
|
||||
__reportxml_add_maintenance(reportnode, config->reportxml_db, "c4f25c51-2720-4b38-a806-19ef024b5289", "warning", "Hostname is not set to anything useful in <hostname>.", NULL);
|
||||
if (config->config_problems & CONFIG_PROBLEM_LOCATION)
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit c5a38dc195cd02b94a6541fda2c61cc1f7cdb62a
|
||||
Subproject commit bb12858abe04bd78f674858bba206ae21d9b6c17
|
@ -37,6 +37,7 @@
|
||||
struct listensocket_container_tag {
|
||||
refobject_base_t __base;
|
||||
mutex_t lock;
|
||||
bool prefer_inet6;
|
||||
listensocket_t **sock;
|
||||
int *sockref;
|
||||
size_t sock_len;
|
||||
@ -60,6 +61,8 @@ static listensocket_t * listensocket_new(const listener_t *listener);
|
||||
static int listensocket_apply_config(listensocket_t *self);
|
||||
static int listensocket_apply_config__unlocked(listensocket_t *self);
|
||||
static int listensocket_set_update(listensocket_t *self, const listener_t *listener);
|
||||
static int listensocket_refsock(listensocket_t *self, bool prefer_inet6);
|
||||
static int listensocket_unrefsock(listensocket_t *self);
|
||||
#ifdef HAVE_POLL
|
||||
static inline int listensocket__poll_fill(listensocket_t *self, struct pollfd *p);
|
||||
#else
|
||||
@ -271,11 +274,15 @@ int listensocket_container_configure_and_setup(listensoc
|
||||
{
|
||||
void (*cb)(size_t count, void *userdata);
|
||||
int ret;
|
||||
bool prefer_inet6;
|
||||
|
||||
if (!self)
|
||||
return -1;
|
||||
|
||||
prefer_inet6 = sock_is_ipv4_mapped_supported(); /* test before we enter lock to minimise locked time */
|
||||
|
||||
thread_mutex_lock(&self->lock);
|
||||
self->prefer_inet6 = prefer_inet6;
|
||||
cb = self->sockcount_cb;
|
||||
self->sockcount_cb = NULL;
|
||||
|
||||
@ -295,11 +302,15 @@ int listensocket_container_configure_and_setup(listensoc
|
||||
int listensocket_container_setup(listensocket_container_t *self)
|
||||
{
|
||||
int ret;
|
||||
bool prefer_inet6;
|
||||
|
||||
if (!self)
|
||||
return -1;
|
||||
|
||||
prefer_inet6 = sock_is_ipv4_mapped_supported(); /* test before we enter lock to minimise locked time */
|
||||
|
||||
thread_mutex_lock(&self->lock);
|
||||
self->prefer_inet6 = prefer_inet6;
|
||||
ret = listensocket_container_setup__unlocked(self);
|
||||
thread_mutex_unlock(&self->lock);
|
||||
|
||||
@ -320,7 +331,7 @@ static int listensocket_container_setup__unlocked(listensocket_container_t *self
|
||||
self->sockref[i] = 0;
|
||||
}
|
||||
} else if (!self->sockref[i] && type != LISTENER_TYPE_VIRTUAL) {
|
||||
if (listensocket_refsock(self->sock[i]) == 0) {
|
||||
if (listensocket_refsock(self->sock[i], self->prefer_inet6) == 0) {
|
||||
self->sockref[i] = 1;
|
||||
} else {
|
||||
ICECAST_LOG_DEBUG("Can not ref socket.");
|
||||
@ -506,6 +517,48 @@ listensocket_t * listensocket_container_get_by_id(listensocket_container_t *self
|
||||
return NULL;
|
||||
}
|
||||
|
||||
listensocket_t ** listensocket_container_list_sockets(listensocket_container_t *self)
|
||||
{
|
||||
listensocket_t **res;
|
||||
size_t idx = 0;
|
||||
size_t i;
|
||||
|
||||
thread_mutex_lock(&self->lock);
|
||||
res = calloc(self->sock_len + 1, sizeof(*res));
|
||||
if (!res) {
|
||||
thread_mutex_unlock(&self->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < self->sock_len; i++) {
|
||||
if (self->sock[i] != NULL) {
|
||||
refobject_ref(res[idx++] = self->sock[i]);
|
||||
}
|
||||
}
|
||||
|
||||
thread_mutex_unlock(&self->lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool listensocket_container_is_family_included(listensocket_container_t *self, sock_family_t family)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
thread_mutex_lock(&self->lock);
|
||||
for (i = 0; i < self->sock_len; i++) {
|
||||
if (self->sock[i] != NULL) {
|
||||
if (listensocket_get_family(self->sock[i]) == family) {
|
||||
thread_mutex_unlock(&self->lock);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
thread_mutex_unlock(&self->lock);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
|
||||
static void __listensocket_free(refobject_t self, void **userdata)
|
||||
@ -634,7 +687,7 @@ static int listensocket_set_update(listensocket_t *self, const list
|
||||
return 0;
|
||||
}
|
||||
|
||||
int listensocket_refsock(listensocket_t *self)
|
||||
static int listensocket_refsock(listensocket_t *self, bool prefer_inet6)
|
||||
{
|
||||
if (!self)
|
||||
return -1;
|
||||
@ -647,7 +700,7 @@ int listensocket_refsock(listensocket_t *self)
|
||||
}
|
||||
|
||||
thread_rwlock_rlock(&self->listener_rwlock);
|
||||
self->sock = sock_get_server_socket(self->listener->port, self->listener->bind_address);
|
||||
self->sock = sock_get_server_socket(self->listener->port, self->listener->bind_address, self->listener->bind_address ? false : prefer_inet6);
|
||||
thread_rwlock_unlock(&self->listener_rwlock);
|
||||
if (self->sock == SOCK_ERROR) {
|
||||
thread_mutex_unlock(&self->lock);
|
||||
@ -675,7 +728,7 @@ int listensocket_refsock(listensocket_t *self)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int listensocket_unrefsock(listensocket_t *self)
|
||||
static int listensocket_unrefsock(listensocket_t *self)
|
||||
{
|
||||
if (!self)
|
||||
return -1;
|
||||
@ -799,6 +852,20 @@ listener_type_t listensocket_get_type(listensocket_t *self)
|
||||
return ret;
|
||||
}
|
||||
|
||||
sock_family_t listensocket_get_family(listensocket_t *self)
|
||||
{
|
||||
sock_family_t ret;
|
||||
|
||||
if (!self)
|
||||
return SOCK_FAMILY__ERROR;
|
||||
|
||||
thread_mutex_lock(&self->lock);
|
||||
ret = sock_get_family(self->sock);
|
||||
thread_mutex_unlock(&self->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
static inline int listensocket__poll_fill(listensocket_t *self, struct pollfd *p)
|
||||
{
|
||||
@ -858,3 +925,45 @@ static inline int listensocket__select_isset(listensocket_t *self, fd_set *set)
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
|
||||
const char * listensocket_type_to_string(listener_type_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case LISTENER_TYPE_ERROR:
|
||||
return NULL;
|
||||
break;
|
||||
case LISTENER_TYPE_NORMAL:
|
||||
return "normal";
|
||||
break;
|
||||
case LISTENER_TYPE_VIRTUAL:
|
||||
return "virtual";
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char * listensocket_tlsmode_to_string(tlsmode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case ICECAST_TLSMODE_DISABLED:
|
||||
return "disabled";
|
||||
break;
|
||||
case ICECAST_TLSMODE_AUTO:
|
||||
return "auto";
|
||||
break;
|
||||
case ICECAST_TLSMODE_AUTO_NO_PLAIN:
|
||||
return "auto_no_plain";
|
||||
break;
|
||||
case ICECAST_TLSMODE_RFC2817:
|
||||
return "rfc2817";
|
||||
break;
|
||||
case ICECAST_TLSMODE_RFC2818:
|
||||
return "rfc2818";
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -9,6 +9,10 @@
|
||||
#ifndef __LISTENSOCKET_H__
|
||||
#define __LISTENSOCKET_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "common/net/sock.h"
|
||||
|
||||
#include "icecasttypes.h"
|
||||
#include "refobject.h"
|
||||
#include "cfgfile.h"
|
||||
@ -23,14 +27,18 @@ connection_t * listensocket_container_accept(listensocket_container
|
||||
int listensocket_container_set_sockcount_cb(listensocket_container_t *self, void (*cb)(size_t count, void *userdata), void *userdata);
|
||||
ssize_t listensocket_container_sockcount(listensocket_container_t *self);
|
||||
listensocket_t * listensocket_container_get_by_id(listensocket_container_t *self, const char *id);
|
||||
listensocket_t ** listensocket_container_list_sockets(listensocket_container_t *self);
|
||||
bool listensocket_container_is_family_included(listensocket_container_t *self, sock_family_t family);
|
||||
|
||||
REFOBJECT_FORWARD_TYPE(listensocket_t);
|
||||
|
||||
int listensocket_refsock(listensocket_t *self);
|
||||
int listensocket_unrefsock(listensocket_t *self);
|
||||
connection_t * listensocket_accept(listensocket_t *self, listensocket_container_t *container);
|
||||
const listener_t * listensocket_get_listener(listensocket_t *self);
|
||||
int listensocket_release_listener(listensocket_t *self);
|
||||
listener_type_t listensocket_get_type(listensocket_t *self);
|
||||
sock_family_t listensocket_get_family(listensocket_t *self);
|
||||
|
||||
const char * listensocket_type_to_string(listener_type_t type);
|
||||
const char * listensocket_tlsmode_to_string(tlsmode_t mode);
|
||||
|
||||
#endif
|
||||
|
@ -825,7 +825,8 @@ static int _send_event_to_client(stats_event_t *event, client_t *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void __add_authstack (auth_stack_t *stack, xmlNodePtr parent) {
|
||||
void stats_add_authstack(auth_stack_t *stack, xmlNodePtr parent)
|
||||
{
|
||||
xmlNodePtr authentication;
|
||||
authentication = xmlNewTextChild(parent, NULL, XMLSTR("authentication"), NULL);
|
||||
|
||||
@ -866,7 +867,7 @@ static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, unsigned int flags, const
|
||||
flags &= ~(STATS_XML_FLAG_SHOW_LISTENERS|STATS_XML_FLAG_SHOW_HIDDEN);
|
||||
} else {
|
||||
config = config_get_config();
|
||||
__add_authstack(config->authstack, root);
|
||||
stats_add_authstack(config->authstack, root);
|
||||
config_release_config();
|
||||
}
|
||||
|
||||
@ -941,7 +942,7 @@ static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, unsigned int flags, const
|
||||
config = config_get_config();
|
||||
mountproxy = config_find_mount(config, source->source, MOUNT_TYPE_NORMAL);
|
||||
if (mountproxy)
|
||||
__add_authstack(mountproxy->authstack, xmlnode);
|
||||
stats_add_authstack(mountproxy->authstack, xmlnode);
|
||||
config_release_config();
|
||||
}
|
||||
}
|
||||
|
@ -103,5 +103,7 @@ void stats_sendxml(client_t *client);
|
||||
xmlDocPtr stats_get_xml(unsigned int flags, const char *show_mount, client_t *client);
|
||||
char *stats_get_value(const char *source, const char *name);
|
||||
|
||||
void stats_add_authstack(auth_stack_t *stack, xmlNodePtr parent);
|
||||
|
||||
#endif /* __STATS_H__ */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user