Merge pull request #3329 from efuss/fix-3311
[collectd.git] / src / curl_xml.c
index ed70f69..4524ac3 100644 (file)
@@ -76,6 +76,7 @@ struct cx_s /* {{{ */
   char *host;
 
   char *url;
+  int address_family;
   char *user;
   char *pass;
   char *credentials;
@@ -696,8 +697,8 @@ static int cx_config_add_namespace(cx_t *db, /* {{{ */
     return EINVAL;
   }
 
-  cx_namespace_t *ns = realloc(
-      db->namespaces, sizeof(*db->namespaces) * (db->namespaces_num + 1));
+  cx_namespace_t *ns = realloc(db->namespaces, sizeof(*db->namespaces) *
+                                                   (db->namespaces_num + 1));
   if (ns == NULL) {
     ERROR("curl_xml plugin: realloc failed.");
     return ENOMEM;
@@ -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;
@@ -897,7 +925,8 @@ static int cx_config_add_url(oconfig_item_t *ci) /* {{{ */
   plugin_register_complex_read(/* group = */ "curl_xml", cb_name, cx_read,
                                /* interval = */ interval,
                                &(user_data_t){
-                                   .data = db, .free_func = cx_free,
+                                   .data = db,
+                                   .free_func = cx_free,
                                });
   sfree(cb_name);
   return 0;