From 102fd13d23aace5ca80cfa0a38184a5c3c392b10 Mon Sep 17 00:00:00 2001 From: Jakub Jankowski Date: Tue, 14 May 2019 02:16:35 +0200 Subject: [PATCH] curl_xml plugin: add AddressFamily In situations when hostnames in URLs resolve to both IPv4 and IPv6 addresses, sometimes it's useful to have separate statistics for both of these separately. With this commit, within block you can set AddressFamily "ipv6" or AddressFamily "ipv4" to specifically use one or the other. Signed-off-by: Jakub Jankowski --- src/collectd.conf.in | 1 + src/collectd.conf.pod | 13 +++++++++++++ src/curl_xml.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/src/collectd.conf.in b/src/collectd.conf.in index f1c82c55..7f5bda37 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -495,6 +495,7 @@ # # +# AddressFamily "any" # Host "my_host" # #Plugin "stats" # Instance "some_instance" diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 70ed9bce..cf048724 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -2087,6 +2087,7 @@ The B uses B (L) and B + AddressFamily "any" Host "my_host" #Plugin "curl_xml" Instance "some_instance" @@ -2123,6 +2124,18 @@ Within the B block the following options are accepted: =over 4 +=item B I + +IP version to resolve URL to. Useful in cases when hostname in URL resolves +to both IPv4 and IPv6 addresses, and you are interested in using one of them +specifically. +Use C to enforce IPv4, C to enforce IPv6, or C to keep the +default behavior of resolving addresses to all IP versions your system allows. +If C is compiled without IPv6 support, using C will result in +a warning and fallback to C. +If C cannot be parsed, a warning will be printed and the whole B +block will be ignored. + =item B I Use I as the host name when submitting values. Defaults to the global diff --git a/src/curl_xml.c b/src/curl_xml.c index 0bed05a5..a8bc3c0b 100644 --- a/src/curl_xml.c +++ b/src/curl_xml.c @@ -76,6 +76,7 @@ struct cx_s /* {{{ */ char *host; char *url; + int address_family; char *user; char *pass; char *credentials; @@ -736,6 +737,7 @@ static int cx_init_curl(cx_t *db) /* {{{ */ curl_easy_setopt(db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf); curl_easy_setopt(db->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(db->curl, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(db->curl, CURLOPT_IPRESOLVE, db->address_family); if (db->user != NULL) { #ifdef HAVE_CURLOPT_USERNAME @@ -814,6 +816,7 @@ static int cx_config_add_url(oconfig_item_t *ci) /* {{{ */ } db->timeout = -1; + db->address_family = CURL_IPRESOLVE_WHATEVER; int status = cf_util_get_string(ci, &db->url); if (status != 0) { @@ -863,6 +866,31 @@ static int cx_config_add_url(oconfig_item_t *ci) /* {{{ */ db->stats = curl_stats_from_config(child); if (db->stats == NULL) status = -1; + } else if (strcasecmp("AddressFamily", child->key) == 0) { + char *af = NULL; + status = cf_util_get_string(child, &af); + if (status != 0 || af == NULL) { + WARNING("curl_xml plugin: Cannot parse value of `%s' for URL `%s'.", + child->key, db->url); + } else if (strcasecmp("any", af) == 0) { + db->address_family = CURL_IPRESOLVE_WHATEVER; + } else if (strcasecmp("ipv4", af) == 0) { + db->address_family = CURL_IPRESOLVE_V4; + } else if (strcasecmp("ipv6", af) == 0) { + /* If curl supports ipv6, use it. If not, log a warning and + * fall back to default - don't set status to non-zero. + */ + curl_version_info_data *curl_info = curl_version_info(CURLVERSION_NOW); + if (curl_info->features & CURL_VERSION_IPV6) + db->address_family = CURL_IPRESOLVE_V6; + else + WARNING("curl_xml plugin: IPv6 not supported by this libCURL. " + "Using fallback `any'."); + } else { + WARNING("curl_xml plugin: Unsupported value of `%s' for URL `%s'.", + child->key, db->url); + status = -1; + } } else { WARNING("curl_xml plugin: Option `%s' not allowed here.", child->key); status = -1; -- 2.11.0