From 82edb5c670838ee73e0117b01bbd3f36e9da8895 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Fri, 11 Mar 2022 12:39:29 +0000 Subject: [PATCH 1/9] Update: Updated submodules --- src/common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common b/src/common index c5a38dc1..bb12858a 160000 --- a/src/common +++ b/src/common @@ -1 +1 @@ -Subproject commit c5a38dc195cd02b94a6541fda2c61cc1f7cdb62a +Subproject commit bb12858abe04bd78f674858bba206ae21d9b6c17 From 4cf821d5927930f87a037d35dd39c7a7c75f8599 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sat, 5 Mar 2022 20:34:55 +0000 Subject: [PATCH 2/9] Feature: Added database functions to find name of listener_type_t, and tlsmode_t --- src/listensocket.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/listensocket.h | 3 +++ 2 files changed, 45 insertions(+) diff --git a/src/listensocket.c b/src/listensocket.c index 95300fef..0e4ced21 100644 --- a/src/listensocket.c +++ b/src/listensocket.c @@ -858,3 +858,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; +} diff --git a/src/listensocket.h b/src/listensocket.h index cb7974df..7c720b8d 100644 --- a/src/listensocket.h +++ b/src/listensocket.h @@ -33,4 +33,7 @@ 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); +const char * listensocket_type_to_string(listener_type_t type); +const char * listensocket_tlsmode_to_string(tlsmode_t mode); + #endif From b7a10102d161d7af4489338e5a3b4818f5217e41 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sun, 6 Mar 2022 18:09:42 +0000 Subject: [PATCH 3/9] Cleanup: Moved authlist template into own file --- admin/Makefile.am | 1 + admin/includes/authlist.xsl | 24 ++++++++++++++++++++++++ admin/listmounts.xsl | 26 +------------------------- admin/stats.xsl | 26 +------------------------- 4 files changed, 27 insertions(+), 50 deletions(-) create mode 100644 admin/includes/authlist.xsl diff --git a/admin/Makefile.am b/admin/Makefile.am index 087a6de3..61c1b642 100644 --- a/admin/Makefile.am +++ b/admin/Makefile.am @@ -25,6 +25,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 \ diff --git a/admin/includes/authlist.xsl b/admin/includes/authlist.xsl new file mode 100644 index 00000000..9b576b13 --- /dev/null +++ b/admin/includes/authlist.xsl @@ -0,0 +1,24 @@ + + +
    + +
  • Role + + + + of type + + + + (Manage) + + + (List) + + + +
  • +
    +
+
+
diff --git a/admin/listmounts.xsl b/admin/listmounts.xsl index eb37eca4..84677fd7 100644 --- a/admin/listmounts.xsl +++ b/admin/listmounts.xsl @@ -3,34 +3,10 @@ + Active Mountpoints - - -
    - -
  • Role - - - - of type - - - - (Manage) - - - (List) - - - -
  • -
    -
-
- -

diff --git a/admin/stats.xsl b/admin/stats.xsl index 9e64d0f9..e18323d5 100644 --- a/admin/stats.xsl +++ b/admin/stats.xsl @@ -4,36 +4,12 @@ + Server status - - -
    - -
  • Role - - - - of type - - - - (Manage) - - - (List) - - - -
  • -
    -
-
- -

Server status

From 4319e8c0e620d35479fe7b3b57add90afe1f8834 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sun, 6 Mar 2022 18:15:34 +0000 Subject: [PATCH 4/9] Update: Translated __add_authstack() into public function stats_add_authstack() --- src/stats.c | 7 ++++--- src/stats.h | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/stats.c b/src/stats.c index b2113b7b..f2717172 100644 --- a/src/stats.c +++ b/src/stats.c @@ -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(); } } diff --git a/src/stats.h b/src/stats.h index 1bdefb73..b149fead 100644 --- a/src/stats.h +++ b/src/stats.h @@ -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__ */ From 80972517da6498df49a1303db590c21c476c2f56 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sun, 6 Mar 2022 18:26:20 +0000 Subject: [PATCH 5/9] Feature: Support asking a listen socket for it's family --- src/listensocket.c | 14 ++++++++++++++ src/listensocket.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/src/listensocket.c b/src/listensocket.c index 0e4ced21..e7b6b6ef 100644 --- a/src/listensocket.c +++ b/src/listensocket.c @@ -799,6 +799,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) { diff --git a/src/listensocket.h b/src/listensocket.h index 7c720b8d..6f8bf94a 100644 --- a/src/listensocket.h +++ b/src/listensocket.h @@ -9,6 +9,8 @@ #ifndef __LISTENSOCKET_H__ #define __LISTENSOCKET_H__ +#include "common/net/sock.h" + #include "icecasttypes.h" #include "refobject.h" #include "cfgfile.h" @@ -32,6 +34,7 @@ connection_t * listensocket_accept(listensocket_t *self, listensock 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); From 567b51420ff141b85bc7b1252c875c2e6c7a6398 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sun, 6 Mar 2022 18:29:30 +0000 Subject: [PATCH 6/9] Feature: Support listing listen socket on web interface --- admin/Makefile.am | 1 + admin/includes/header.xsl | 1 + admin/listensocketlist.xsl | 94 +++++++++++++++++++++++++++ src/admin.c | 126 +++++++++++++++++++++++++++++++++++++ src/listensocket.c | 24 +++++++ src/listensocket.h | 1 + 6 files changed, 247 insertions(+) create mode 100644 admin/listensocketlist.xsl diff --git a/admin/Makefile.am b/admin/Makefile.am index 61c1b642..4183ca7b 100644 --- a/admin/Makefile.am +++ b/admin/Makefile.am @@ -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 \ diff --git a/admin/includes/header.xsl b/admin/includes/header.xsl index 3cdf4f7d..04de7fd7 100644 --- a/admin/includes/header.xsl +++ b/admin/includes/header.xsl @@ -11,6 +11,7 @@ + diff --git a/admin/listensocketlist.xsl b/admin/listensocketlist.xsl new file mode 100644 index 00000000..65476e33 --- /dev/null +++ b/admin/listensocketlist.xsl @@ -0,0 +1,94 @@ + + + + Listen Sockets + + +

+ +
+

Listen Socket

+

Overview

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyValue
ID
On behalf of
Type
Family
+ +

Config

+ + + + + + + + + + + + + + + + + +
KeyValue
+ + +

Header

+ + + + + + + + + + + + + + + + + + + +
TypeNameValueStatus
+
+ + +

Authentication

+ +
+
+
+
+
diff --git a/src/admin.c b/src/admin.c index 93d17f19..9a4f53a8 100644 --- a/src/admin.c +++ b/src/admin.c @@ -28,10 +28,13 @@ #include #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) diff --git a/src/listensocket.c b/src/listensocket.c index e7b6b6ef..6dea8319 100644 --- a/src/listensocket.c +++ b/src/listensocket.c @@ -506,6 +506,30 @@ 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; +} + /* ---------------------------------------------------------------------------- */ static void __listensocket_free(refobject_t self, void **userdata) diff --git a/src/listensocket.h b/src/listensocket.h index 6f8bf94a..77c24c2c 100644 --- a/src/listensocket.h +++ b/src/listensocket.h @@ -25,6 +25,7 @@ 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); REFOBJECT_FORWARD_TYPE(listensocket_t); From 81e965a08f987b87fdf1a063c4f9110bb37ab54a Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sun, 6 Mar 2022 18:49:11 +0000 Subject: [PATCH 7/9] Feature: Warn on dashboard if IPv6 is not enabled --- src/admin.c | 7 ++++++- src/listensocket.c | 18 ++++++++++++++++++ src/listensocket.h | 3 +++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/admin.c b/src/admin.c index 9a4f53a8..270c5509 100644 --- a/src/admin.c +++ b/src/admin.c @@ -1621,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); @@ -1646,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); } @@ -1661,6 +1663,9 @@ 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 (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 .", NULL); if (config->config_problems & CONFIG_PROBLEM_LOCATION) diff --git a/src/listensocket.c b/src/listensocket.c index 6dea8319..ba1a8426 100644 --- a/src/listensocket.c +++ b/src/listensocket.c @@ -530,6 +530,24 @@ listensocket_t ** listensocket_container_list_sockets(listensocket_con 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) diff --git a/src/listensocket.h b/src/listensocket.h index 77c24c2c..f2211b41 100644 --- a/src/listensocket.h +++ b/src/listensocket.h @@ -9,6 +9,8 @@ #ifndef __LISTENSOCKET_H__ #define __LISTENSOCKET_H__ +#include + #include "common/net/sock.h" #include "icecasttypes.h" @@ -26,6 +28,7 @@ int listensocket_container_set_sockcount_cb(listensocket 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); From 661f736415152f46a0bbf13071690570f6869768 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Mon, 7 Mar 2022 09:56:41 +0000 Subject: [PATCH 8/9] Update: Prefer to bind to IPv6 if we have IPv4-mapped support --- src/listensocket.c | 19 +++++++++++++++---- src/listensocket.h | 2 -- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/listensocket.c b/src/listensocket.c index ba1a8426..ab2fd1cb 100644 --- a/src/listensocket.c +++ b/src/listensocket.c @@ -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."); @@ -676,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; @@ -689,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); @@ -717,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; diff --git a/src/listensocket.h b/src/listensocket.h index f2211b41..a37344a7 100644 --- a/src/listensocket.h +++ b/src/listensocket.h @@ -32,8 +32,6 @@ bool listensocket_container_is_family_included(listensock 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); From 389c41c7d01828679fe3b55b73f5fb8427c5412e Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Mon, 7 Mar 2022 10:17:19 +0000 Subject: [PATCH 9/9] Feature: Inform on dashboard if IPv6 is not enabled whether IPv4-mapped is available --- src/admin.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/admin.c b/src/admin.c index 270c5509..d886440c 100644 --- a/src/admin.c +++ b/src/admin.c @@ -1663,8 +1663,12 @@ 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) + 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 .", NULL);