X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fwrite_prometheus.c;h=97f583f3f479d54e50eb4dfc959f5657dc50e926;hb=eeca9dc658dfa9ed3c8bfea609fa0a82f9326874;hp=fe6f1cc3a536d563de8fa45cbdb563c02fcad147;hpb=38617fa88d22997e91176ef901f842f384ff3711;p=collectd.git diff --git a/src/write_prometheus.c b/src/write_prometheus.c index fe6f1cc3..97f583f3 100644 --- a/src/write_prometheus.c +++ b/src/write_prometheus.c @@ -731,55 +731,75 @@ metric_family_get(data_set_t const *ds, value_list_t const *vl, size_t ds_index, } /* }}} */ -static int prom_open_socket(int domain, struct sockaddr const *addr, - socklen_t addrlen) { - int fd = socket(domain, SOCK_STREAM | SOCK_CLOEXEC, 0); - if (fd == -1) - return errno; - - if (bind(fd, addr, addrlen) != 0) { - close(fd); +static void prom_logger(__attribute__((unused)) void *arg, char const *fmt, + va_list ap) { + /* {{{ */ + char errbuf[1024]; + vsnprintf(errbuf, sizeof(errbuf), fmt, ap); + + ERROR("write_prometheus plugin: %s", errbuf); +} /* }}} prom_logger */ + +#if MHD_VERSION >= 0x00090000 +static int prom_open_socket(int addrfamily) { + /* {{{ */ + char service[NI_MAXSERV]; + snprintf(service, sizeof(service), "%hu", httpd_port); + + struct addrinfo *res; + int status = getaddrinfo(NULL, service, + &(struct addrinfo){ + .ai_flags = AI_PASSIVE | AI_ADDRCONFIG, + .ai_family = addrfamily, + .ai_socktype = SOCK_STREAM, + }, + &res); + if (status != 0) { return -1; } - if (listen(fd, /* backlog = */ 16) != 0) { - close(fd); - return -1; - } + int fd = -1; + for (struct addrinfo *ai = res; ai != NULL; ai = ai->ai_next) { + fd = socket(ai->ai_family, ai->ai_socktype | SOCK_CLOEXEC, 0); + if (fd == -1) + continue; - return fd; -} + if (bind(fd, ai->ai_addr, ai->ai_addrlen) != 0) { + close(fd); + fd = -1; + continue; + } -static struct MHD_Daemon *prom_start_daemon() { - struct sockaddr_in6 sa6 = { - .sin6_family = AF_INET6, - .sin6_port = htons(httpd_port), - .sin6_addr = IN6ADDR_ANY_INIT, - }; - int fd = prom_open_socket(PF_INET6, (void *)&sa6, sizeof(sa6)); + if (listen(fd, /* backlog = */ 16) != 0) { + close(fd); + fd = -1; + continue; + } - if (fd == -1) { - struct sockaddr_in sa4 = { - .sin_family = AF_INET, - .sin_port = htons(httpd_port), - .sin_addr = - { - .s_addr = INADDR_ANY, - }, - }; - fd = prom_open_socket(PF_INET, (void *)&sa4, sizeof(sa4)); + break; } + freeaddrinfo(res); + + return fd; +} /* }}} int prom_open_socket */ + +static struct MHD_Daemon *prom_start_daemon() { + /* {{{ */ + int fd = prom_open_socket(PF_INET6); + if (fd == -1) + fd = prom_open_socket(PF_INET); if (fd == -1) { ERROR("write_prometheus plugin: Opening a listening socket failed."); return NULL; } - struct MHD_Daemon *d = - MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, 0, - /* MHD_AcceptPolicyCallback = */ NULL, - /* MHD_AcceptPolicyCallback arg = */ NULL, http_handler, - NULL, MHD_OPTION_LISTEN_SOCKET, fd, MHD_OPTION_END); + struct MHD_Daemon *d = MHD_start_daemon( + MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, httpd_port, + /* MHD_AcceptPolicyCallback = */ NULL, + /* MHD_AcceptPolicyCallback arg = */ NULL, http_handler, NULL, + MHD_OPTION_LISTEN_SOCKET, fd, MHD_OPTION_EXTERNAL_LOGGER, prom_logger, + NULL, MHD_OPTION_END); if (d == NULL) { ERROR("write_prometheus plugin: MHD_start_daemon() failed."); close(fd); @@ -787,7 +807,23 @@ static struct MHD_Daemon *prom_start_daemon() { } return d; -} +} /* }}} struct MHD_Daemon *prom_start_daemon */ +#else /* if MHD_VERSION < 0x00090000 */ +static struct MHD_Daemon *prom_start_daemon() { + /* {{{ */ + struct MHD_Daemon *d = MHD_start_daemon( + MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, httpd_port, + /* MHD_AcceptPolicyCallback = */ NULL, + /* MHD_AcceptPolicyCallback arg = */ NULL, http_handler, NULL, + MHD_OPTION_EXTERNAL_LOGGER, prom_logger, NULL, MHD_OPTION_END); + if (d == NULL) { + ERROR("write_prometheus plugin: MHD_start_daemon() failed."); + return NULL; + } + + return d; +} /* }}} struct MHD_Daemon *prom_start_daemon */ +#endif /* * collectd callbacks