summary refs log tree commit diff
path: root/clients/cloud-setup/nmcs-provider-ec2.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
committerMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
commit80ec1decc49c72efec2a8b87c06245c92c0ab807 (patch)
treee3b229aa94e8dcf0590f2317664176e7b8f7607b /clients/cloud-setup/nmcs-provider-ec2.c
parent65f86e8f56267192d42f2b629fc6b0c99fb9cd0c (diff)
New upstream version 1.29.90 upstream/1.29.90
Diffstat (limited to 'clients/cloud-setup/nmcs-provider-ec2.c')
-rw-r--r--clients/cloud-setup/nmcs-provider-ec2.c265
1 files changed, 87 insertions, 178 deletions
diff --git a/clients/cloud-setup/nmcs-provider-ec2.c b/clients/cloud-setup/nmcs-provider-ec2.c
index fb82914f..1e060034 100644
--- a/clients/cloud-setup/nmcs-provider-ec2.c
+++ b/clients/cloud-setup/nmcs-provider-ec2.c
@@ -1,6 +1,6 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include "nm-default.h"
+#include "libnm/nm-default-client.h"
 
 #include "nmcs-provider-ec2.h"
 
@@ -72,11 +72,11 @@ G_DEFINE_TYPE(NMCSProviderEC2, nmcs_provider_ec2, NMCS_TYPE_PROVIDER);
 
 static gboolean
 _detect_get_meta_data_check_cb(long     response_code,
-                               GBytes * response_data,
+                               GBytes * response,
                                gpointer check_user_data,
                                GError **error)
 {
-    return response_code == 200 && nmcs_utils_parse_get_full_line(response_data, "ami-id");
+    return response_code == 200 && nmcs_utils_parse_get_full_line(response, "ami-id");
 }
 
 static void
@@ -129,114 +129,69 @@ detect(NMCSProvider *provider, GTask *task)
 
 /*****************************************************************************/
 
-typedef struct {
-    NMCSProviderGetConfigTaskData *get_config_data;
-    GError *                       error;
-    GCancellable *                 cancellable;
-    gulong                         cancelled_id;
-    guint                          n_pending;
-} GetConfigIfaceData;
-
 static void
-_get_config_task_maybe_return(GetConfigIfaceData *iface_data, GError *error_take)
+_get_config_fetch_done_cb(NMHttpClient *http_client,
+                          GAsyncResult *result,
+                          gpointer      user_data,
+                          gboolean      is_local_ipv4)
 {
-    NMCSProviderGetConfigTaskData *get_config_data = iface_data->get_config_data;
-
-    if (error_take) {
-        if (!iface_data->error)
-            iface_data->error = error_take;
-        else if (!nm_utils_error_is_cancelled(iface_data->error)
-                 && nm_utils_error_is_cancelled(error_take)) {
-            nm_clear_error(&iface_data->error);
-            iface_data->error = error_take;
-        } else
-            g_error_free(error_take);
-    }
+    NMCSProviderGetConfigTaskData *get_config_data;
+    const char *                   hwaddr = NULL;
+    gs_unref_bytes GBytes *response       = NULL;
+    gs_free_error GError *          error = NULL;
+    NMCSProviderGetConfigIfaceData *config_iface_data;
+    in_addr_t                       tmp_addr;
+    int                             tmp_prefix;
 
-    if (iface_data->n_pending > 0)
-        return;
+    nm_utils_user_data_unpack(user_data, &get_config_data, &hwaddr);
 
-    nm_clear_g_cancellable_disconnect(g_task_get_cancellable(get_config_data->task),
-                                      &iface_data->cancelled_id);
+    nm_http_client_poll_get_finish(http_client, result, NULL, &response, &error);
 
-    nm_clear_g_cancellable(&iface_data->cancellable);
+    if (nm_utils_error_is_cancelled(error))
+        return;
 
-    if (iface_data->error) {
-        if (nm_utils_error_is_cancelled(iface_data->error))
-            _LOGD("get-config: cancelled");
-        else
-            _LOGD("get-config: failed: %s", iface_data->error->message);
-        g_task_return_error(get_config_data->task, g_steal_pointer(&iface_data->error));
-    } else {
-        _LOGD("get-config: success");
-        g_task_return_pointer(get_config_data->task,
-                              g_hash_table_ref(get_config_data->result_dict),
-                              (GDestroyNotify) g_hash_table_unref);
-    }
+    if (error)
+        goto out;
 
-    nm_g_slice_free(iface_data);
-    g_object_unref(get_config_data->task);
-}
+    config_iface_data = g_hash_table_lookup(get_config_data->result_dict, hwaddr);
 
-static void
-_get_config_fetch_done_cb(NMHttpClient *http_client,
-                          GAsyncResult *result,
-                          gpointer      user_data,
-                          gboolean      is_local_ipv4)
-{
-    GetConfigIfaceData *iface_data;
-    const char *        hwaddr           = NULL;
-    gs_unref_bytes GBytes *response_data = NULL;
-    gs_free_error GError *error          = NULL;
+    if (is_local_ipv4) {
+        gs_free const char **s_addrs = NULL;
+        gsize                i, len;
 
-    nm_utils_user_data_unpack(user_data, &iface_data, &hwaddr);
+        s_addrs = nm_utils_strsplit_set_full(g_bytes_get_data(response, NULL),
+                                             "\n",
+                                             NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP);
+        len     = NM_PTRARRAY_LEN(s_addrs);
 
-    nm_http_client_poll_get_finish(http_client, result, NULL, &response_data, &error);
+        nm_assert(!config_iface_data->has_ipv4s);
+        nm_assert(!config_iface_data->ipv4s_arr);
+        config_iface_data->has_ipv4s = TRUE;
+        config_iface_data->ipv4s_len = 0;
+        if (len > 0) {
+            config_iface_data->ipv4s_arr = g_new(in_addr_t, len);
 
-    if (!error) {
-        NMCSProviderGetConfigIfaceData *config_iface_data;
-        in_addr_t                       tmp_addr;
-        int                             tmp_prefix;
-
-        config_iface_data = g_hash_table_lookup(iface_data->get_config_data->result_dict, hwaddr);
-
-        if (is_local_ipv4) {
-            gs_free const char **s_addrs = NULL;
-            gsize                i, len;
-
-            s_addrs = nm_utils_strsplit_set_full(g_bytes_get_data(response_data, NULL),
-                                                 "\n",
-                                                 NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP);
-            len     = NM_PTRARRAY_LEN(s_addrs);
-
-            nm_assert(!config_iface_data->has_ipv4s);
-            nm_assert(!config_iface_data->ipv4s_arr);
-            config_iface_data->has_ipv4s = TRUE;
-            config_iface_data->ipv4s_len = 0;
-            if (len > 0) {
-                config_iface_data->ipv4s_arr = g_new(in_addr_t, len);
-
-                for (i = 0; i < len; i++) {
-                    if (nm_utils_parse_inaddr_bin(AF_INET, s_addrs[i], NULL, &tmp_addr))
-                        config_iface_data->ipv4s_arr[config_iface_data->ipv4s_len++] = tmp_addr;
-                }
-            }
-        } else {
-            if (nm_utils_parse_inaddr_prefix_bin(AF_INET,
-                                                 g_bytes_get_data(response_data, NULL),
-                                                 NULL,
-                                                 &tmp_addr,
-                                                 &tmp_prefix)) {
-                nm_assert(!config_iface_data->has_cidr);
-                config_iface_data->has_cidr    = TRUE;
-                config_iface_data->cidr_prefix = tmp_prefix;
-                config_iface_data->cidr_addr   = tmp_addr;
+            for (i = 0; i < len; i++) {
+                if (nm_utils_parse_inaddr_bin(AF_INET, s_addrs[i], NULL, &tmp_addr))
+                    config_iface_data->ipv4s_arr[config_iface_data->ipv4s_len++] = tmp_addr;
             }
         }
+    } else {
+        if (nm_utils_parse_inaddr_prefix_bin(AF_INET,
+                                             g_bytes_get_data(response, NULL),
+                                             NULL,
+                                             &tmp_addr,
+                                             &tmp_prefix)) {
+            nm_assert(!config_iface_data->has_cidr);
+            config_iface_data->has_cidr    = TRUE;
+            config_iface_data->cidr_prefix = tmp_prefix;
+            config_iface_data->cidr_addr   = tmp_addr;
+        }
     }
 
-    iface_data->n_pending--;
-    _get_config_task_maybe_return(iface_data, g_steal_pointer(&error));
+out:
+    get_config_data->n_pending--;
+    _nmcs_provider_get_config_task_maybe_return(get_config_data, g_steal_pointer(&error));
 }
 
 static void
@@ -253,24 +208,6 @@ _get_config_fetch_done_cb_local_ipv4s(GObject *source, GAsyncResult *result, gpo
     _get_config_fetch_done_cb(NM_HTTP_CLIENT(source), result, user_data, TRUE);
 }
 
-static void
-_get_config_fetch_cancelled_cb(GObject *object, gpointer user_data)
-{
-    GetConfigIfaceData *iface_data = user_data;
-
-    if (iface_data->cancelled_id == 0)
-        return;
-
-    nm_clear_g_signal_handler(g_task_get_cancellable(iface_data->get_config_data->task),
-                              &iface_data->cancelled_id);
-    _get_config_task_maybe_return(iface_data, nm_utils_error_new_cancelled(FALSE, NULL));
-}
-
-typedef struct {
-    NMCSProviderGetConfigTaskData *get_config_data;
-    GHashTable *                   response_parsed;
-} GetConfigMetadataData;
-
 typedef struct {
     gssize iface_idx;
     char   path[0];
@@ -279,60 +216,33 @@ typedef struct {
 static void
 _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-    GetConfigMetadataData *        metadata_data = user_data;
-    GetConfigIfaceData *           iface_data;
-    NMCSProviderGetConfigTaskData *get_config_data = metadata_data->get_config_data;
-    gs_unref_hashtable GHashTable *response_parsed =
-        g_steal_pointer(&metadata_data->response_parsed);
-    gs_free_error GError *error = NULL;
-    GCancellable *        cancellable;
+    NMCSProviderGetConfigTaskData *get_config_data;
+    gs_unref_hashtable GHashTable *response_parsed = NULL;
+    gs_free_error GError *error                    = NULL;
     GetConfigMetadataMac *v_mac_data;
     const char *          v_hwaddr;
     GHashTableIter        h_iter;
     NMHttpClient *        http_client;
 
-    nm_g_slice_free(metadata_data);
-
     nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, NULL, &error);
 
-    iface_data  = g_slice_new(GetConfigIfaceData);
-    *iface_data = (GetConfigIfaceData){
-        .get_config_data = get_config_data,
-        .n_pending       = 0,
-    };
-
-    if (nm_utils_error_is_cancelled(error)) {
-        _get_config_task_maybe_return(iface_data, g_steal_pointer(&error));
+    if (nm_utils_error_is_cancelled(error))
         return;
-    }
+
+    get_config_data = user_data;
+
+    response_parsed                     = g_steal_pointer(&get_config_data->extra_data);
+    get_config_data->extra_data_destroy = NULL;
 
     /* We ignore errors. Only if we got no response at all, it's a problem.
      * Otherwise, we proceed with whatever we could fetch. */
     if (!response_parsed) {
-        _get_config_task_maybe_return(
-            iface_data,
+        _nmcs_provider_get_config_task_maybe_return(
+            get_config_data,
             nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, "meta data for interfaces not found"));
         return;
     }
 
-    cancellable = g_task_get_cancellable(get_config_data->task);
-    if (cancellable) {
-        gulong cancelled_id;
-
-        cancelled_id = g_cancellable_connect(cancellable,
-                                             G_CALLBACK(_get_config_fetch_cancelled_cb),
-                                             iface_data,
-                                             NULL);
-        if (cancelled_id == 0) {
-            _get_config_task_maybe_return(iface_data, nm_utils_error_new_cancelled(FALSE, NULL));
-            return;
-        }
-
-        iface_data->cancelled_id = cancelled_id;
-    }
-
-    iface_data->cancellable = g_cancellable_new();
-
     http_client = nmcs_provider_get_http_client(g_task_get_source_object(get_config_data->task));
 
     g_hash_table_iter_init(&h_iter, response_parsed);
@@ -359,6 +269,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
         }
 
         nm_assert(config_iface_data->iface_idx == -1);
+
         config_iface_data->iface_idx = v_mac_data->iface_idx;
 
         _LOGD("get-config: start fetching meta data for #%" G_GSSIZE_FORMAT ", %s (%s)",
@@ -366,7 +277,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
               hwaddr,
               v_mac_data->path);
 
-        iface_data->n_pending++;
+        get_config_data->n_pending++;
         nm_http_client_poll_get(
             http_client,
             (uri1 = _ec2_uri_interfaces(v_mac_data->path,
@@ -377,13 +288,13 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
             10000,
             1000,
             NULL,
-            iface_data->cancellable,
+            get_config_data->intern_cancellable,
             NULL,
             NULL,
             _get_config_fetch_done_cb_subnet_ipv4_cidr_block,
-            nm_utils_user_data_pack(iface_data, hwaddr));
+            nm_utils_user_data_pack(get_config_data, hwaddr));
 
-        iface_data->n_pending++;
+        get_config_data->n_pending++;
         nm_http_client_poll_get(
             http_client,
             (uri2 = _ec2_uri_interfaces(v_mac_data->path,
@@ -394,23 +305,23 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
             10000,
             1000,
             NULL,
-            iface_data->cancellable,
+            get_config_data->intern_cancellable,
             NULL,
             NULL,
             _get_config_fetch_done_cb_local_ipv4s,
-            nm_utils_user_data_pack(iface_data, hwaddr));
+            nm_utils_user_data_pack(get_config_data, hwaddr));
     }
 
-    _get_config_task_maybe_return(iface_data, NULL);
+    _nmcs_provider_get_config_task_maybe_return(get_config_data, NULL);
 }
 
 static gboolean
 _get_config_metadata_ready_check(long     response_code,
-                                 GBytes * response_data,
+                                 GBytes * response,
                                  gpointer check_user_data,
                                  GError **error)
 {
-    GetConfigMetadataData *metadata_data           = check_user_data;
+    NMCSProviderGetConfigTaskData *get_config_data = check_user_data;
     gs_unref_hashtable GHashTable *response_parsed = NULL;
     const guint8 *                 r_data;
     const char *                   cur_line;
@@ -421,12 +332,12 @@ _get_config_metadata_ready_check(long     response_code,
     const char *                   c_hwaddr;
     gssize                         iface_idx_counter = 0;
 
-    if (response_code != 200 || !response_data) {
+    if (response_code != 200 || !response) {
         /* we wait longer. */
         return FALSE;
     }
 
-    r_data = g_bytes_get_data(response_data, &r_len);
+    r_data = g_bytes_get_data(response, &r_len);
     /* NMHttpClient guarantees that there is a trailing NUL after the data. */
     nm_assert(r_data[r_len] == 0);
 
@@ -437,7 +348,7 @@ _get_config_metadata_ready_check(long     response_code,
         if (cur_line_len == 0)
             continue;
 
-        /* Truncate the string. It's safe to do, because we own @response_data an it has an
+        /* Truncate the string. It's safe to do, because we own @response an it has an
          * extra NUL character after the buffer. */
         ((char *) cur_line)[cur_line_len] = '\0';
 
@@ -454,11 +365,12 @@ _get_config_metadata_ready_check(long     response_code,
         mac_data->iface_idx = iface_idx_counter++;
         memcpy(mac_data->path, cur_line, cur_line_len + 1u);
 
+        /* here we will ignore duplicate responses. */
         g_hash_table_insert(response_parsed, hwaddr, mac_data);
     }
 
     has_all = TRUE;
-    g_hash_table_iter_init(&h_iter, metadata_data->get_config_data->result_dict);
+    g_hash_table_iter_init(&h_iter, get_config_data->result_dict);
     while (g_hash_table_iter_next(&h_iter, (gpointer *) &c_hwaddr, NULL)) {
         if (!response_parsed || !g_hash_table_contains(response_parsed, c_hwaddr)) {
             has_all = FALSE;
@@ -466,21 +378,18 @@ _get_config_metadata_ready_check(long     response_code,
         }
     }
 
-    nm_clear_pointer(&metadata_data->response_parsed, g_hash_table_unref);
-    metadata_data->response_parsed = g_steal_pointer(&response_parsed);
+    nm_clear_pointer(&get_config_data->extra_data, g_hash_table_unref);
+    if (response_parsed) {
+        get_config_data->extra_data         = g_steal_pointer(&response_parsed);
+        get_config_data->extra_data_destroy = (GDestroyNotify) g_hash_table_unref;
+    }
     return has_all;
 }
 
 static void
 get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_data)
 {
-    gs_free char *         uri = NULL;
-    GetConfigMetadataData *metadata_data;
-
-    metadata_data  = g_slice_new(GetConfigMetadataData);
-    *metadata_data = (GetConfigMetadataData){
-        .get_config_data = get_config_data,
-    };
+    gs_free char *uri = NULL;
 
     /* First we fetch the "macs/". If the caller requested some particular
      * MAC addresses, then we poll until we see them. They might not yet be
@@ -493,11 +402,11 @@ get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_dat
                             15000,
                             1000,
                             NULL,
-                            g_task_get_cancellable(get_config_data->task),
+                            get_config_data->intern_cancellable,
                             _get_config_metadata_ready_check,
-                            metadata_data,
+                            get_config_data,
                             _get_config_metadata_ready_cb,
-                            metadata_data);
+                            get_config_data);
 }
 
 /*****************************************************************************/