From 7ecfb537e988e6c81daa53c1da33f4f81fe1302d Mon Sep 17 00:00:00 2001 From: Evgeny Khramtsov Date: Sun, 14 Jan 2024 21:49:59 +0100 Subject: [PATCH] Only set MHD_USE_DUAL_STACK if IPv6 is available (#1362) Co-authored-by: Evgeny Khramtsov If IPv6 is not enabled during runtime, prometheus server fails to start with `EAFNOSUPPORT` because `MHD_USE_DUAL_STACK` is set unconditionally. This PR fixes it. As a bonus, it also checks if libmicrohttpd is compiled with IPv6 support. --- src/apps/relay/prom_server.c | 27 ++++++++++++++++++++++++--- src/apps/relay/prom_server.h | 2 ++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index ea6104e..857f5a1 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -1,6 +1,9 @@ #include "prom_server.h" #include "mainrelay.h" #include "ns_turn_utils.h" +#include +#include +#include #if !defined(TURN_NO_PROMETHEUS) @@ -101,11 +104,13 @@ void start_prometheus_server(void) { promhttp_set_active_collector_registry(NULL); // some flags appeared first in microhttpd v0.9.53 - unsigned int flags = MHD_USE_DUAL_STACK + unsigned int flags = 0; + if (MHD_is_feature_supported(MHD_FEATURE_IPv6) && is_ipv6_enabled()) { + flags |= MHD_USE_DUAL_STACK; + } #if MHD_VERSION >= 0x00095300 - | MHD_USE_ERROR_LOG + flags |= MHD_USE_ERROR_LOG; #endif - ; if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) { #if MHD_VERSION >= 0x00095300 flags |= MHD_USE_EPOLL_INTERNAL_THREAD; @@ -196,6 +201,22 @@ void prom_inc_stun_binding_error(void) { } } +int is_ipv6_enabled(void) { + int ret = 0; + +#ifdef AF_INET6 + int fd = socket(AF_INET6, SOCK_STREAM, 0); + if (fd == -1) { + ret = errno != EAFNOSUPPORT; + } else { + ret = 1; + close(fd); + } +#endif /* AF_INET6 */ + + return ret; +} + #else void start_prometheus_server(void) { diff --git a/src/apps/relay/prom_server.h b/src/apps/relay/prom_server.h index 4c05e5c..3e6270f 100644 --- a/src/apps/relay/prom_server.h +++ b/src/apps/relay/prom_server.h @@ -65,6 +65,8 @@ void prom_set_finished_traffic(const char *realm, const char *user, unsigned lon void prom_inc_allocation(SOCKET_TYPE type); void prom_dec_allocation(SOCKET_TYPE type); +int is_ipv6_enabled(void); + void prom_inc_stun_binding_request(void); void prom_inc_stun_binding_response(void); void prom_inc_stun_binding_error(void);