瀏覽代碼

Only set MHD_USE_DUAL_STACK if IPv6 is available (#1362)

Co-authored-by: Evgeny Khramtsov <[email protected]>

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.
Evgeny Khramtsov 1 年之前
父節點
當前提交
7ecfb537e9
共有 2 個文件被更改,包括 26 次插入3 次删除
  1. 24 3
      src/apps/relay/prom_server.c
  2. 2 0
      src/apps/relay/prom_server.h

+ 24 - 3
src/apps/relay/prom_server.c

@@ -1,6 +1,9 @@
 #include "prom_server.h"
 #include "mainrelay.h"
 #include "ns_turn_utils.h"
+#include <errno.h>
+#include <sys/socket.h>
+#include <unistd.h>
 
 #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) {

+ 2 - 0
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);