summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Cardace <acardace@redhat.com>2020-06-18 18:21:48 +0200
committerAntonio Cardace <acardace@redhat.com>2020-06-26 16:47:52 +0200
commit427fbc85f0f325e3ff4c887ffd0d145cc1112306 (patch)
tree6ab5417811112919e8b91ea88e7fefd1224d4caa
parentd18d75f89c8ef7f6742c8e8153d84124971f99d2 (diff)
downloadNetworkManager-427fbc85f0f325e3ff4c887ffd0d145cc1112306.tar.gz
nmcs-http: fix multiple HTTP request bug
Since just a single pointer is used to store the socket's GSource if more than 1 consecutive request was done through the same HTTP provider the 2nd request would clear the GSource associated to the second request causing the 1st HTTP request to never complete and end up in a expired timeout. Use a hashtable instead so we can correctly track all requests. https://bugzilla.redhat.com/show_bug.cgi?id=1821787 Fixes: 69f048bf0ca3 ('cloud-setup: add tool for automatic IP configuration in cloud')
-rw-r--r--clients/cloud-setup/nm-http-client.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/clients/cloud-setup/nm-http-client.c b/clients/cloud-setup/nm-http-client.c
index 94f3fe2b8a..16dbd5bbe0 100644
--- a/clients/cloud-setup/nm-http-client.c
+++ b/clients/cloud-setup/nm-http-client.c
@@ -16,7 +16,7 @@ typedef struct {
GMainContext *context;
CURLM *mhandle;
GSource *mhandle_source_timeout;
- GSource *mhandle_source_socket;
+ GHashTable *source_sockets_hashtable;
} NMHttpClientPrivate;
struct _NMHttpClient {
@@ -615,12 +615,13 @@ _mhandle_socket_cb (int fd,
static int
_mhandle_socketfunction_cb (CURL *e_handle, curl_socket_t fd, int what, void *user_data, void *socketp)
{
+ GSource *source_socket;
NMHttpClient *self = user_data;
NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
(void) _NM_ENSURE_TYPE (int, fd);
- nm_clear_g_source_inst (&priv->mhandle_source_socket);
+ g_hash_table_remove (priv->source_sockets_hashtable, GINT_TO_POINTER (fd));
if (what != CURL_POLL_REMOVE) {
GIOCondition condition = 0;
@@ -635,13 +636,17 @@ _mhandle_socketfunction_cb (CURL *e_handle, curl_socket_t fd, int what, void *us
condition = 0;
if (condition) {
- priv->mhandle_source_socket = nm_g_unix_fd_source_new (fd,
- condition,
- G_PRIORITY_DEFAULT,
- _mhandle_socket_cb,
- self,
+ source_socket = nm_g_unix_fd_source_new (fd,
+ condition,
+ G_PRIORITY_DEFAULT,
+ _mhandle_socket_cb,
+ self,
NULL);
- g_source_attach (priv->mhandle_source_socket, priv->context);
+ g_source_attach (source_socket, priv->context);
+
+ g_hash_table_insert (priv->source_sockets_hashtable,
+ GINT_TO_POINTER (fd),
+ source_socket);
}
}
@@ -678,6 +683,11 @@ _mhandle_timerfunction_cb (CURLM *multi, long timeout_msec, void *user_data)
static void
nm_http_client_init (NMHttpClient *self)
{
+ NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
+ priv->source_sockets_hashtable = g_hash_table_new_full (nm_direct_hash,
+ NULL,
+ NULL,
+ (GDestroyNotify) nm_g_source_destroy_and_unref);
}
static void
@@ -714,9 +724,9 @@ dispose (GObject *object)
NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
nm_clear_pointer (&priv->mhandle, curl_multi_cleanup);
+ nm_clear_pointer (&priv->source_sockets_hashtable, g_hash_table_unref);
nm_clear_g_source_inst (&priv->mhandle_source_timeout);
- nm_clear_g_source_inst (&priv->mhandle_source_socket);
G_OBJECT_CLASS (nm_http_client_parent_class)->dispose (object);
}