diff options
author | Antonio Cardace <acardace@redhat.com> | 2020-06-18 18:21:48 +0200 |
---|---|---|
committer | Antonio Cardace <acardace@redhat.com> | 2020-06-26 16:47:52 +0200 |
commit | 427fbc85f0f325e3ff4c887ffd0d145cc1112306 (patch) | |
tree | 6ab5417811112919e8b91ea88e7fefd1224d4caa | |
parent | d18d75f89c8ef7f6742c8e8153d84124971f99d2 (diff) | |
download | NetworkManager-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.c | 28 |
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); } |