commit:     c76e3a569dd4139e7f9d3d7888910a4298f9bb3c
Author:     Jory Pratt <anarchy <AT> gentoo <DOT> org>
AuthorDate: Mon Jun 29 01:01:32 2020 +0000
Commit:     Jory Pratt <anarchy <AT> gentoo <DOT> org>
CommitDate: Mon Jun 29 01:01:32 2020 +0000
URL:        https://gitweb.gentoo.org/proj/musl.git/commit/?id=c76e3a56

dev-libs/glib: drop obsolete patches

Package-Manager: Portage-2.3.103, Repoman-2.3.23
Signed-off-by: Jory Pratt <anarchy <AT> gentoo.org>

 dev-libs/glib/files/2.60.7-gdbus-fixes.patch | 301 -----------
 dev-libs/glib/files/CVE-2020-6750.patch      | 763 ---------------------------
 2 files changed, 1064 deletions(-)

diff --git a/dev-libs/glib/files/2.60.7-gdbus-fixes.patch 
b/dev-libs/glib/files/2.60.7-gdbus-fixes.patch
deleted file mode 100644
index e2a066b..0000000
--- a/dev-libs/glib/files/2.60.7-gdbus-fixes.patch
+++ /dev/null
@@ -1,301 +0,0 @@
-From 1cfab12a28d97716ad581c30fbbf3e94e4d7f303 Mon Sep 17 00:00:00 2001
-From: Simon McVittie <s...@collabora.com>
-Date: Mon, 14 Oct 2019 08:22:24 +0100
-Subject: [PATCH 1/3] gcredentialsprivate: Document the various private macros
-
-Signed-off-by: Simon McVittie <s...@collabora.com>
----
- gio/gcredentialsprivate.h | 59 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 59 insertions(+)
-
-diff --git a/gio/gcredentialsprivate.h b/gio/gcredentialsprivate.h
-index 4d1c420a8..06f0aed19 100644
---- a/gio/gcredentialsprivate.h
-+++ b/gio/gcredentialsprivate.h
-@@ -22,6 +22,65 @@
- #include "gio/gcredentials.h"
- #include "gio/gnetworking.h"
- 
-+/*
-+ * G_CREDENTIALS_SUPPORTED:
-+ *
-+ * Defined to 1 if GCredentials works.
-+ */
-+#undef G_CREDENTIALS_SUPPORTED
-+
-+/*
-+ * G_CREDENTIALS_USE_LINUX_UCRED, etc.:
-+ *
-+ * Defined to 1 if GCredentials uses Linux `struct ucred`, etc.
-+ */
-+#undef G_CREDENTIALS_USE_LINUX_UCRED
-+#undef G_CREDENTIALS_USE_FREEBSD_CMSGCRED
-+#undef G_CREDENTIALS_USE_NETBSD_UNPCBID
-+#undef G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
-+#undef G_CREDENTIALS_USE_SOLARIS_UCRED
-+
-+/*
-+ * G_CREDENTIALS_NATIVE_TYPE:
-+ *
-+ * Defined to one of G_CREDENTIALS_TYPE_LINUX_UCRED, etc.
-+ */
-+#undef G_CREDENTIALS_NATIVE_TYPE
-+
-+/*
-+ * G_CREDENTIALS_NATIVE_SIZE:
-+ *
-+ * Defined to the size of the %G_CREDENTIALS_NATIVE_TYPE
-+ */
-+#undef G_CREDENTIALS_NATIVE_SIZE
-+
-+/*
-+ * G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED:
-+ *
-+ * Defined to 1 if we have a message-passing API in which credentials
-+ * are attached to a particular message, such as `SCM_CREDENTIALS` on Linux
-+ * or `SCM_CREDS` on FreeBSD.
-+ */
-+#undef G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
-+
-+/*
-+ * G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED:
-+ *
-+ * Defined to 1 if we have a `getsockopt()`-style API in which one end of
-+ * a socket connection can directly query the credentials of the process
-+ * that initiated the other end, such as `getsockopt SO_PEERCRED` on Linux
-+ * or `getpeereid()` on multiple operating systems.
-+ */
-+#undef G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED
-+
-+/*
-+ * G_CREDENTIALS_SPOOFING_SUPPORTED:
-+ *
-+ * Defined to 1 if privileged processes can spoof their credentials when
-+ * using the message-passing API.
-+ */
-+#undef G_CREDENTIALS_SPOOFING_SUPPORTED
-+
- #ifdef __linux__
- #define G_CREDENTIALS_SUPPORTED 1
- #define G_CREDENTIALS_USE_LINUX_UCRED 1
--- 
-2.20.1
-
-
-From 5f9318af8f19756685c1b79cf8b76f3e66614d84 Mon Sep 17 00:00:00 2001
-From: Simon McVittie <s...@collabora.com>
-Date: Fri, 18 Oct 2019 10:55:09 +0100
-Subject: [PATCH 2/3] credentials: Invalid Linux struct ucred means "no
- information"
-
-On Linux, if getsockopt SO_PEERCRED is used on a TCP socket, one
-might expect it to fail with an appropriate error like ENOTSUP or
-EPROTONOSUPPORT. However, it appears that in fact it succeeds, but
-yields a credentials structure with pid 0, uid -1 and gid -1. These
-are not real process, user and group IDs that can be allocated to a
-real process (pid 0 needs to be reserved to give kill(0) its documented
-special semantics, and similarly uid and gid -1 need to be reserved for
-setresuid() and setresgid()) so it is not meaningful to signal them to
-high-level API users.
-
-An API user with Linux-specific knowledge can still inspect these fields
-via g_credentials_get_native() if desired.
-
-Similarly, if SO_PASSCRED is used to receive a SCM_CREDENTIALS message
-on a receiving Unix socket, but the sending socket had not enabled
-SO_PASSCRED at the time that the message was sent, it is possible
-for it to succeed but yield a credentials structure with pid 0, uid
-/proc/sys/kernel/overflowuid and gid /proc/sys/kernel/overflowgid. Even
-if we were to read those pseudo-files, we cannot distinguish between
-the overflow IDs and a real process that legitimately has the same IDs
-(typically they are set to 'nobody' and 'nogroup', which can be used
-by a real process), so we detect this situation by noticing that
-pid == 0, and to save syscalls we do not read the overflow IDs from
-/proc at all.
-
-This results in a small API change: g_credentials_is_same_user() now
-returns FALSE if we compare two credentials structures that are both
-invalid. This seems like reasonable, conservative behaviour: if we cannot
-prove that they are the same user, we should assume they are not.
-
-(Dropped new translatable string when backporting to `glib-2-62`.)
-
-Signed-off-by: Simon McVittie <s...@collabora.com>
----
- gio/gcredentials.c | 42 +++++++++++++++++++++++++++++++++++++++---
- 1 file changed, 39 insertions(+), 3 deletions(-)
-
-diff --git a/gio/gcredentials.c b/gio/gcredentials.c
-index 57a39f2a2..ff9b7e0b8 100644
---- a/gio/gcredentials.c
-+++ b/gio/gcredentials.c
-@@ -265,6 +265,35 @@ g_credentials_to_string (GCredentials *credentials)
- 
- /* 
----------------------------------------------------------------------------------------------------
 */
- 
-+#if G_CREDENTIALS_USE_LINUX_UCRED
-+/*
-+ * Check whether @native contains invalid data. If getsockopt SO_PEERCRED
-+ * is used on a TCP socket, it succeeds but yields a credentials structure
-+ * with pid 0, uid -1 and gid -1. Similarly, if SO_PASSCRED is used on a
-+ * receiving Unix socket when the sending socket did not also enable
-+ * SO_PASSCRED, it can succeed but yield a credentials structure with
-+ * pid 0, uid /proc/sys/kernel/overflowuid and gid
-+ * /proc/sys/kernel/overflowgid.
-+ */
-+static gboolean
-+linux_ucred_check_valid (struct ucred  *native,
-+                         GError       **error)
-+{
-+  if (native->pid == 0
-+      || native->uid == -1
-+      || native->gid == -1)
-+    {
-+      g_set_error_literal (error,
-+                           G_IO_ERROR,
-+                           G_IO_ERROR_INVALID_DATA,
-+                           "GCredentials contains invalid data");
-+      return FALSE;
-+    }
-+
-+  return TRUE;
-+}
-+#endif
-+
- /**
-  * g_credentials_is_same_user:
-  * @credentials: A #GCredentials.
-@@ -294,7 +323,8 @@ g_credentials_is_same_user (GCredentials  *credentials,
- 
-   ret = FALSE;
- #if G_CREDENTIALS_USE_LINUX_UCRED
--  if (credentials->native.uid == other_credentials->native.uid)
-+  if (linux_ucred_check_valid (&credentials->native, NULL)
-+      && credentials->native.uid == other_credentials->native.uid)
-     ret = TRUE;
- #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
-   if (credentials->native.cmcred_euid == 
other_credentials->native.cmcred_euid)
-@@ -453,7 +483,10 @@ g_credentials_get_unix_user (GCredentials    *credentials,
-   g_return_val_if_fail (error == NULL || *error == NULL, -1);
- 
- #if G_CREDENTIALS_USE_LINUX_UCRED
--  ret = credentials->native.uid;
-+  if (linux_ucred_check_valid (&credentials->native, error))
-+    ret = credentials->native.uid;
-+  else
-+    ret = -1;
- #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
-   ret = credentials->native.cmcred_euid;
- #elif G_CREDENTIALS_USE_NETBSD_UNPCBID
-@@ -499,7 +532,10 @@ g_credentials_get_unix_pid (GCredentials    *credentials,
-   g_return_val_if_fail (error == NULL || *error == NULL, -1);
- 
- #if G_CREDENTIALS_USE_LINUX_UCRED
--  ret = credentials->native.pid;
-+  if (linux_ucred_check_valid (&credentials->native, error))
-+    ret = credentials->native.pid;
-+  else
-+    ret = -1;
- #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
-   ret = credentials->native.cmcred_pid;
- #elif G_CREDENTIALS_USE_NETBSD_UNPCBID
--- 
-2.20.1
-
-
-From c7618cce3752e1f3681f75d0a26c7e07c15bd6a2 Mon Sep 17 00:00:00 2001
-From: Simon McVittie <s...@collabora.com>
-Date: Mon, 14 Oct 2019 08:47:39 +0100
-Subject: [PATCH 3/3] GDBus: prefer getsockopt()-style credentials-passing APIs
-
-Closes: https://gitlab.gnome.org/GNOME/glib/issues/1831
----
- gio/gcredentialsprivate.h | 18 ++++++++++++++++++
- gio/gdbusauth.c           | 27 +++++++++++++++++++++++++--
- 2 files changed, 43 insertions(+), 2 deletions(-)
-
-diff --git a/gio/gcredentialsprivate.h b/gio/gcredentialsprivate.h
-index 06f0aed19..e9ec09b9f 100644
---- a/gio/gcredentialsprivate.h
-+++ b/gio/gcredentialsprivate.h
-@@ -81,6 +81,18 @@
-  */
- #undef G_CREDENTIALS_SPOOFING_SUPPORTED
- 
-+/*
-+ * G_CREDENTIALS_PREFER_MESSAGE_PASSING:
-+ *
-+ * Defined to 1 if the data structure transferred by the message-passing
-+ * API is strictly more informative than the one transferred by the
-+ * `getsockopt()`-style API, and hence should be preferred, even for
-+ * protocols like D-Bus that are defined in terms of the credentials of
-+ * the (process that opened the) socket, as opposed to the credentials
-+ * of an individual message.
-+ */
-+#undef G_CREDENTIALS_PREFER_MESSAGE_PASSING
-+
- #ifdef __linux__
- #define G_CREDENTIALS_SUPPORTED 1
- #define G_CREDENTIALS_USE_LINUX_UCRED 1
-@@ -100,6 +112,12 @@
- #define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct cmsgcred))
- #define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
- #define G_CREDENTIALS_SPOOFING_SUPPORTED 1
-+/* GLib doesn't implement it yet, but FreeBSD's getsockopt()-style API
-+ * is getpeereid(), which is not as informative as struct cmsgcred -
-+ * it does not tell us the PID. As a result, libdbus prefers to use
-+ * SCM_CREDS, and if we implement getpeereid() in future, we should
-+ * do the same. */
-+#define G_CREDENTIALS_PREFER_MESSAGE_PASSING 1
- 
- #elif defined(__NetBSD__)
- #define G_CREDENTIALS_SUPPORTED 1
-diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c
-index 752ec23fc..14cc5d70e 100644
---- a/gio/gdbusauth.c
-+++ b/gio/gdbusauth.c
-@@ -31,6 +31,7 @@
- #include "gdbusutils.h"
- #include "gioenumtypes.h"
- #include "gcredentials.h"
-+#include "gcredentialsprivate.h"
- #include "gdbusprivate.h"
- #include "giostream.h"
- #include "gdatainputstream.h"
-@@ -969,9 +970,31 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
- 
-   g_data_input_stream_set_newline_type (dis, 
G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
- 
--  /* first read the NUL-byte */
-+  /* read the NUL-byte, possibly with credentials attached */
- #ifdef G_OS_UNIX
--  if (G_IS_UNIX_CONNECTION (auth->priv->stream))
-+#ifndef G_CREDENTIALS_PREFER_MESSAGE_PASSING
-+  if (G_IS_SOCKET_CONNECTION (auth->priv->stream))
-+    {
-+      GSocket *sock = g_socket_connection_get_socket (G_SOCKET_CONNECTION 
(auth->priv->stream));
-+
-+      local_error = NULL;
-+      credentials = g_socket_get_credentials (sock, &local_error);
-+
-+      if (credentials == NULL && !g_error_matches (local_error, G_IO_ERROR, 
G_IO_ERROR_NOT_SUPPORTED))
-+        {
-+          g_propagate_error (error, local_error);
-+          goto out;
-+        }
-+      else
-+        {
-+          /* Clear the error indicator, so we can retry with
-+           * g_unix_connection_receive_credentials() if necessary */
-+          g_clear_error (&local_error);
-+        }
-+    }
-+#endif
-+
-+  if (credentials == NULL && G_IS_UNIX_CONNECTION (auth->priv->stream))
-     {
-       local_error = NULL;
-       credentials = g_unix_connection_receive_credentials (G_UNIX_CONNECTION 
(auth->priv->stream),
--- 
-2.20.1
-

diff --git a/dev-libs/glib/files/CVE-2020-6750.patch 
b/dev-libs/glib/files/CVE-2020-6750.patch
deleted file mode 100644
index fe39914..0000000
--- a/dev-libs/glib/files/CVE-2020-6750.patch
+++ /dev/null
@@ -1,763 +0,0 @@
-From cc3cf6b8b2ad12d54f3474113f0ccfa7dcf66b7b Mon Sep 17 00:00:00 2001
-From: Michael Catanzaro <mcatanz...@gnome.org>
-Date: Sat, 4 Jan 2020 20:46:25 -0600
-Subject: [PATCH] gsocketclient: run timeout source on the task's main context
-
-This shouldn't make any difference, because this code should only ever
-be running in the main context that was thread-default at the time the
-task was created, so it should already match the task's context. But
-let's make sure, just in case.
----
- gio/gsocketclient.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
-index 6adeee299..81721795b 100644
---- a/gio/gsocketclient.c
-+++ b/gio/gsocketclient.c
-@@ -1794,7 +1794,7 @@ g_socket_client_enumerator_callback (GObject      
*object,
-   attempt->connection = (GIOStream 
*)g_socket_connection_factory_create_connection (socket);
-   attempt->timeout_source = g_timeout_source_new 
(HAPPY_EYEBALLS_CONNECTION_ATTEMPT_TIMEOUT_MS);
-   g_source_set_callback (attempt->timeout_source, 
on_connection_attempt_timeout, attempt, NULL);
--  g_source_attach (attempt->timeout_source, g_main_context_get_thread_default 
());
-+  g_source_attach (attempt->timeout_source, g_task_get_context (data->task));
-   data->connection_attempts = g_slist_append (data->connection_attempts, 
attempt);
- 
-   if (g_task_get_cancellable (data->task))
--- 
-2.24.1
-
-From d4fcf91460696b09bb2b55c352a023f6dd71c7fe Mon Sep 17 00:00:00 2001
-From: Patrick Griffis <tingp...@tingping.se>
-Date: Thu, 23 Jan 2020 19:58:41 -0800
-Subject: [PATCH] Refactor g_socket_client_connect_async()
-
-This is a fairly large refactoring. The highlights are:
-
-- Removing in-progress connections/addresses from 
GSocketClientAsyncConnectData:
-
-  This caused issues where multiple ConnectionAttempt's would step over 
eachother
-  and modify shared state causing bugs like accidentally bypassing a set proxy.
-
-  Fixes #1871
-  Fixes #1989
-  Fixes #1902
-
-- Cancelling address enumeration on error/completion
-
-- Queuing successful TCP connections and doing application layer work serially:
-
-  This is more in the spirit of Happy Eyeballs but it also greatly simplifies
-  the flow of connection handling so fewer tasks are happening in parallel
-  when they don't need to be.
-
-  The behavior also should more closely match that of 
g_socket_client_connect().
-
-- Better track the state of address enumeration:
-
-  Previously we were over eager to treat enumeration finishing as an error.
-
-  Fixes #1872
-  See also #1982
-
-- Add more detailed documentation and logging.
-
-Closes #1995
----
- gio/gsocketclient.c | 459 ++++++++++++++++++++++++++++----------------
- 1 file changed, 296 insertions(+), 163 deletions(-)
-
-diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
-index 81721795b..c9943309c 100644
---- a/gio/gsocketclient.c
-+++ b/gio/gsocketclient.c
-@@ -1337,13 +1337,15 @@ typedef struct
- 
-   GSocketConnectable *connectable;
-   GSocketAddressEnumerator *enumerator;
--  GProxyAddress *proxy_addr;
--  GSocket *socket;
--  GIOStream *connection;
-+  GCancellable *enumeration_cancellable;
- 
-   GSList *connection_attempts;
-+  GSList *successful_connections;
-   GError *last_error;
- 
-+  gboolean enumerated_at_least_once;
-+  gboolean enumeration_completed;
-+  gboolean connection_in_progress;
-   gboolean completed;
- } GSocketClientAsyncConnectData;
- 
-@@ -1355,10 +1357,9 @@ g_socket_client_async_connect_data_free 
(GSocketClientAsyncConnectData *data)
-   data->task = NULL;
-   g_clear_object (&data->connectable);
-   g_clear_object (&data->enumerator);
--  g_clear_object (&data->proxy_addr);
--  g_clear_object (&data->socket);
--  g_clear_object (&data->connection);
-+  g_clear_object (&data->enumeration_cancellable);
-   g_slist_free_full (data->connection_attempts, connection_attempt_unref);
-+  g_slist_free_full (data->successful_connections, connection_attempt_unref);
- 
-   g_clear_error (&data->last_error);
- 
-@@ -1370,6 +1371,7 @@ typedef struct
-   GSocketAddress *address;
-   GSocket *socket;
-   GIOStream *connection;
-+  GProxyAddress *proxy_addr;
-   GSocketClientAsyncConnectData *data; /* unowned */
-   GSource *timeout_source;
-   GCancellable *cancellable;
-@@ -1401,6 +1403,7 @@ connection_attempt_unref (gpointer pointer)
-       g_clear_object (&attempt->socket);
-       g_clear_object (&attempt->connection);
-       g_clear_object (&attempt->cancellable);
-+      g_clear_object (&attempt->proxy_addr);
-       if (attempt->timeout_source)
-         {
-           g_source_destroy (attempt->timeout_source);
-@@ -1418,37 +1421,59 @@ connection_attempt_remove (ConnectionAttempt *attempt)
- }
- 
- static void
--g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data)
-+cancel_all_attempts (GSocketClientAsyncConnectData *data)
- {
--  g_assert (data->connection);
-+  GSList *l;
- 
--  if (!G_IS_SOCKET_CONNECTION (data->connection))
-+  for (l = data->connection_attempts; l; l = g_slist_next (l))
-     {
--      GSocketConnection *wrapper_connection;
--
--      wrapper_connection = g_tcp_wrapper_connection_new (data->connection, 
data->socket);
--      g_object_unref (data->connection);
--      data->connection = (GIOStream *)wrapper_connection;
-+      ConnectionAttempt *attempt_entry = l->data;
-+      g_cancellable_cancel (attempt_entry->cancellable);
-+      connection_attempt_unref (attempt_entry);
-     }
-+  g_slist_free (data->connection_attempts);
-+  data->connection_attempts = NULL;
- 
--  if (!data->completed)
-+  g_slist_free_full (data->successful_connections, connection_attempt_unref);
-+  data->successful_connections = NULL;
-+
-+  g_cancellable_cancel (data->enumeration_cancellable);
-+}
-+
-+static void
-+g_socket_client_async_connect_complete (ConnectionAttempt *attempt)
-+{
-+  GSocketClientAsyncConnectData *data = attempt->data;
-+  GError *error = NULL;
-+  g_assert (attempt->connection);
-+  g_assert (!data->completed);
-+
-+  if (!G_IS_SOCKET_CONNECTION (attempt->connection))
-     {
--      GError *error = NULL;
-+      GSocketConnection *wrapper_connection;
- 
--      if (g_cancellable_set_error_if_cancelled (g_task_get_cancellable 
(data->task), &error))
--        {
--          g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, 
data->connectable, NULL);
--          g_task_return_error (data->task, g_steal_pointer (&error));
--        }
--      else
--        {
--          g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, 
data->connectable, data->connection);
--          g_task_return_pointer (data->task, g_steal_pointer 
(&data->connection), g_object_unref);
--        }
-+      wrapper_connection = g_tcp_wrapper_connection_new (attempt->connection, 
attempt->socket);
-+      g_object_unref (attempt->connection);
-+      attempt->connection = (GIOStream *)wrapper_connection;
-+    }
- 
--      data->completed = TRUE;
-+  data->completed = TRUE;
-+  cancel_all_attempts (data);
-+
-+  if (g_cancellable_set_error_if_cancelled (g_task_get_cancellable 
(data->task), &error))
-+    {
-+      g_debug ("GSocketClient: Connection cancelled!");
-+      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, 
data->connectable, NULL);
-+      g_task_return_error (data->task, g_steal_pointer (&error));
-+    }
-+  else
-+    {
-+      g_debug ("GSocketClient: Connection successful!");
-+      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, 
data->connectable, attempt->connection);
-+      g_task_return_pointer (data->task, g_steal_pointer 
(&attempt->connection), g_object_unref);
-     }
- 
-+  connection_attempt_unref (attempt);
-   g_object_unref (data->task);
- }
- 
-@@ -1470,59 +1495,63 @@ static void
- enumerator_next_async (GSocketClientAsyncConnectData *data,
-                        gboolean                       add_task_ref)
- {
--  /* We need to cleanup the state */
--  g_clear_object (&data->socket);
--  g_clear_object (&data->proxy_addr);
--  g_clear_object (&data->connection);
--
-   /* Each enumeration takes a ref. This arg just avoids repeated unrefs when
-      an enumeration starts another enumeration */
-   if (add_task_ref)
-     g_object_ref (data->task);
- 
-   g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVING, 
data->connectable, NULL);
-+  g_debug ("GSocketClient: Starting new address enumeration");
-   g_socket_address_enumerator_next_async (data->enumerator,
--                                        g_task_get_cancellable (data->task),
-+                                        data->enumeration_cancellable,
-                                         g_socket_client_enumerator_callback,
-                                         data);
- }
- 
-+static void try_next_connection_or_finish (GSocketClientAsyncConnectData *, 
gboolean);
-+
- static void
- g_socket_client_tls_handshake_callback (GObject      *object,
-                                       GAsyncResult *result,
-                                       gpointer      user_data)
- {
--  GSocketClientAsyncConnectData *data = user_data;
-+  ConnectionAttempt *attempt = user_data;
-+  GSocketClientAsyncConnectData *data = attempt->data;
- 
-   if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (object),
-                                        result,
-                                        &data->last_error))
-     {
--      g_object_unref (data->connection);
--      data->connection = G_IO_STREAM (object);
-+      g_object_unref (attempt->connection);
-+      attempt->connection = G_IO_STREAM (object);
- 
--      g_socket_client_emit_event (data->client, 
G_SOCKET_CLIENT_TLS_HANDSHAKED, data->connectable, data->connection);
--      g_socket_client_async_connect_complete (data);
-+      g_debug ("GSocketClient: TLS handshake succeeded");
-+      g_socket_client_emit_event (data->client, 
G_SOCKET_CLIENT_TLS_HANDSHAKED, data->connectable, attempt->connection);
-+      g_socket_client_async_connect_complete (attempt);
-     }
-   else
-     {
-       g_object_unref (object);
--      enumerator_next_async (data, FALSE);
-+      connection_attempt_unref (attempt);
-+      g_debug ("GSocketClient: TLS handshake failed: %s", 
data->last_error->message);
-+      try_next_connection_or_finish (data, TRUE);
-     }
- }
- 
- static void
--g_socket_client_tls_handshake (GSocketClientAsyncConnectData *data)
-+g_socket_client_tls_handshake (ConnectionAttempt *attempt)
- {
-+  GSocketClientAsyncConnectData *data = attempt->data;
-   GIOStream *tlsconn;
- 
-   if (!data->client->priv->tls)
-     {
--      g_socket_client_async_connect_complete (data);
-+      g_socket_client_async_connect_complete (attempt);
-       return;
-     }
- 
--  tlsconn = g_tls_client_connection_new (data->connection,
-+  g_debug ("GSocketClient: Starting TLS handshake");
-+  tlsconn = g_tls_client_connection_new (attempt->connection,
-                                        data->connectable,
-                                        &data->last_error);
-   if (tlsconn)
-@@ -1534,11 +1563,12 @@ g_socket_client_tls_handshake 
(GSocketClientAsyncConnectData *data)
-                                       G_PRIORITY_DEFAULT,
-                                       g_task_get_cancellable (data->task),
-                                       g_socket_client_tls_handshake_callback,
--                                      data);
-+                                      attempt);
-     }
-   else
-     {
--      enumerator_next_async (data, FALSE);
-+      connection_attempt_unref (attempt);
-+      try_next_connection_or_finish (data, TRUE);
-     }
- }
- 
-@@ -1547,23 +1577,38 @@ g_socket_client_proxy_connect_callback (GObject      
*object,
-                                       GAsyncResult *result,
-                                       gpointer      user_data)
- {
--  GSocketClientAsyncConnectData *data = user_data;
-+  ConnectionAttempt *attempt = user_data;
-+  GSocketClientAsyncConnectData *data = attempt->data;
- 
--  g_object_unref (data->connection);
--  data->connection = g_proxy_connect_finish (G_PROXY (object),
--                                           result,
--                                           &data->last_error);
--  if (data->connection)
-+  g_object_unref (attempt->connection);
-+  attempt->connection = g_proxy_connect_finish (G_PROXY (object),
-+                                                result,
-+                                                &data->last_error);
-+  if (attempt->connection)
-     {
--      g_socket_client_emit_event (data->client, 
G_SOCKET_CLIENT_PROXY_NEGOTIATED, data->connectable, data->connection);
-+      g_socket_client_emit_event (data->client, 
G_SOCKET_CLIENT_PROXY_NEGOTIATED, data->connectable, attempt->connection);
-     }
-   else
-     {
--      enumerator_next_async (data, FALSE);
-+      connection_attempt_unref (attempt);
-+      try_next_connection_or_finish (data, TRUE);
-       return;
-     }
- 
--  g_socket_client_tls_handshake (data);
-+  g_socket_client_tls_handshake (attempt);
-+}
-+
-+static void
-+complete_connection_with_error (GSocketClientAsyncConnectData *data,
-+                                GError                        *error)
-+{
-+  g_debug ("GSocketClient: Connection failed: %s", error->message);
-+  g_assert (!data->completed);
-+
-+  g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, 
data->connectable, NULL);
-+  data->completed = TRUE;
-+  cancel_all_attempts (data);
-+  g_task_return_error (data->task, error);
- }
- 
- static gboolean
-@@ -1577,15 +1622,114 @@ task_completed_or_cancelled 
(GSocketClientAsyncConnectData *data)
-     return TRUE;
-   else if (g_cancellable_set_error_if_cancelled (cancellable, &error))
-     {
--      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, 
data->connectable, NULL);
--      g_task_return_error (task, g_steal_pointer (&error));
--      data->completed = TRUE;
-+      complete_connection_with_error (data, g_steal_pointer (&error));
-       return TRUE;
-     }
-   else
-     return FALSE;
- }
- 
-+static gboolean
-+try_next_successful_connection (GSocketClientAsyncConnectData *data)
-+{
-+  ConnectionAttempt *attempt;
-+  const gchar *protocol;
-+  GProxy *proxy;
-+
-+  if (data->connection_in_progress)
-+    return FALSE;
-+
-+  g_assert (data->successful_connections != NULL);
-+  attempt = data->successful_connections->data;
-+  g_assert (attempt != NULL);
-+  data->successful_connections = g_slist_remove 
(data->successful_connections, attempt);
-+  data->connection_in_progress = TRUE;
-+
-+  g_debug ("GSocketClient: Starting application layer connection");
-+
-+  if (!attempt->proxy_addr)
-+    {
-+      g_socket_client_tls_handshake (g_steal_pointer (&attempt));
-+      return TRUE;
-+    }
-+
-+  protocol = g_proxy_address_get_protocol (attempt->proxy_addr);
-+
-+  /* The connection should not be anything other than TCP,
-+   * but let's put a safety guard in case
-+   */
-+  if (!G_IS_TCP_CONNECTION (attempt->connection))
-+    {
-+      g_critical ("Trying to proxy over non-TCP connection, this is "
-+          "most likely a bug in GLib IO library.");
-+
-+      g_set_error_literal (&data->last_error,
-+          G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-+          _("Proxying over a non-TCP connection is not supported."));
-+    }
-+  else if (g_hash_table_contains (data->client->priv->app_proxies, protocol))
-+    {
-+      /* Simply complete the connection, we don't want to do TLS handshake
-+       * as the application proxy handling may need proxy handshake first */
-+      g_socket_client_async_connect_complete (g_steal_pointer (&attempt));
-+      return TRUE;
-+    }
-+  else if ((proxy = g_proxy_get_default_for_protocol (protocol)))
-+    {
-+      GIOStream *connection = attempt->connection;
-+      GProxyAddress *proxy_addr = attempt->proxy_addr;
-+
-+      g_socket_client_emit_event (data->client, 
G_SOCKET_CLIENT_PROXY_NEGOTIATING, data->connectable, attempt->connection);
-+      g_debug ("GSocketClient: Starting proxy connection");
-+      g_proxy_connect_async (proxy,
-+                             connection,
-+                             proxy_addr,
-+                             g_task_get_cancellable (data->task),
-+                             g_socket_client_proxy_connect_callback,
-+                             g_steal_pointer (&attempt));
-+      g_object_unref (proxy);
-+      return TRUE;
-+    }
-+  else
-+    {
-+      g_clear_error (&data->last_error);
-+
-+      g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-+          _("Proxy protocol ā€œ%sā€ is not supported."),
-+          protocol);
-+    }
-+
-+  data->connection_in_progress = FALSE;
-+  g_clear_pointer (&attempt, connection_attempt_unref);
-+  return FALSE; /* All non-return paths are failures */
-+}
-+
-+static void
-+try_next_connection_or_finish (GSocketClientAsyncConnectData *data,
-+                               gboolean                       
end_current_connection)
-+{
-+  if (end_current_connection)
-+    data->connection_in_progress = FALSE;
-+
-+  if (data->connection_in_progress)
-+    return;
-+
-+  /* Keep trying successful connections until one works, each iteration pops 
one */
-+  while (data->successful_connections)
-+    {
-+      if (try_next_successful_connection (data))
-+        return;
-+    }
-+
-+  if (!data->enumeration_completed)
-+    {
-+      enumerator_next_async (data, FALSE);
-+      return;
-+    }
-+
-+  complete_connection_with_error (data, data->last_error);
-+}
-+
- static void
- g_socket_client_connected_callback (GObject      *source,
-                                   GAsyncResult *result,
-@@ -1593,10 +1737,7 @@ g_socket_client_connected_callback (GObject      
*source,
- {
-   ConnectionAttempt *attempt = user_data;
-   GSocketClientAsyncConnectData *data = attempt->data;
--  GSList *l;
-   GError *error = NULL;
--  GProxy *proxy;
--  const gchar *protocol;
- 
-   if (task_completed_or_cancelled (data) || g_cancellable_is_cancelled 
(attempt->cancellable))
-     {
-@@ -1618,11 +1759,12 @@ g_socket_client_connected_callback (GObject      
*source,
-         {
-           clarify_connect_error (error, data->connectable, attempt->address);
-           set_last_error (data, error);
-+          g_debug ("GSocketClient: Connection attempt failed: %s", 
error->message);
-           connection_attempt_remove (attempt);
--          enumerator_next_async (data, FALSE);
-           connection_attempt_unref (attempt);
-+          try_next_connection_or_finish (data, FALSE);
-         }
--      else
-+      else /* Silently ignore cancelled attempts */
-         {
-           g_clear_error (&error);
-           g_object_unref (data->task);
-@@ -1632,74 +1774,21 @@ g_socket_client_connected_callback (GObject      
*source,
-       return;
-     }
- 
--  data->socket = g_steal_pointer (&attempt->socket);
--  data->connection = g_steal_pointer (&attempt->connection);
--
--  for (l = data->connection_attempts; l; l = g_slist_next (l))
--    {
--      ConnectionAttempt *attempt_entry = l->data;
--      g_cancellable_cancel (attempt_entry->cancellable);
--      connection_attempt_unref (attempt_entry);
--    }
--  g_slist_free (data->connection_attempts);
--  data->connection_attempts = NULL;
--  connection_attempt_unref (attempt);
--
--  g_socket_connection_set_cached_remote_address 
((GSocketConnection*)data->connection, NULL);
--  g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTED, 
data->connectable, data->connection);
-+  g_socket_connection_set_cached_remote_address 
((GSocketConnection*)attempt->connection, NULL);
-+  g_debug ("GSocketClient: TCP connection successful");
-+  g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTED, 
data->connectable, attempt->connection);
- 
-   /* wrong, but backward compatible */
--  g_socket_set_blocking (data->socket, TRUE);
-+  g_socket_set_blocking (attempt->socket, TRUE);
- 
--  if (!data->proxy_addr)
--    {
--      g_socket_client_tls_handshake (data);
--      return;
--    }
--
--  protocol = g_proxy_address_get_protocol (data->proxy_addr);
--
--  /* The connection should not be anything other than TCP,
--   * but let's put a safety guard in case
-+  /* This ends the parallel "happy eyeballs" portion of connecting.
-+     Now that we have a successful tcp connection we will attempt to connect
-+     at the TLS/Proxy layer. If those layers fail we will move on to the next
-+     connection.
-    */
--  if (!G_IS_TCP_CONNECTION (data->connection))
--    {
--      g_critical ("Trying to proxy over non-TCP connection, this is "
--          "most likely a bug in GLib IO library.");
--
--      g_set_error_literal (&data->last_error,
--          G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
--          _("Proxying over a non-TCP connection is not supported."));
--
--      enumerator_next_async (data, FALSE);
--    }
--  else if (g_hash_table_contains (data->client->priv->app_proxies, protocol))
--    {
--      /* Simply complete the connection, we don't want to do TLS handshake
--       * as the application proxy handling may need proxy handshake first */
--      g_socket_client_async_connect_complete (data);
--    }
--  else if ((proxy = g_proxy_get_default_for_protocol (protocol)))
--    {
--      g_socket_client_emit_event (data->client, 
G_SOCKET_CLIENT_PROXY_NEGOTIATING, data->connectable, data->connection);
--      g_proxy_connect_async (proxy,
--                             data->connection,
--                             data->proxy_addr,
--                             g_task_get_cancellable (data->task),
--                             g_socket_client_proxy_connect_callback,
--                             data);
--      g_object_unref (proxy);
--    }
--  else
--    {
--      g_clear_error (&data->last_error);
--
--      g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
--          _("Proxy protocol ā€œ%sā€ is not supported."),
--          protocol);
--
--      enumerator_next_async (data, FALSE);
--    }
-+  connection_attempt_remove (attempt);
-+  data->successful_connections = g_slist_append 
(data->successful_connections, g_steal_pointer (&attempt));
-+  try_next_connection_or_finish (data, FALSE);
- }
- 
- static gboolean
-@@ -1707,7 +1796,11 @@ on_connection_attempt_timeout (gpointer data)
- {
-   ConnectionAttempt *attempt = data;
- 
--  enumerator_next_async (attempt->data, TRUE);
-+  if (!attempt->data->enumeration_completed)
-+    {
-+      g_debug ("GSocketClient: Timeout reached, trying another enumeration");
-+      enumerator_next_async (attempt->data, TRUE);
-+    }
- 
-   g_clear_pointer (&attempt->timeout_source, g_source_unref);
-   return G_SOURCE_REMOVE;
-@@ -1717,9 +1810,9 @@ static void
- on_connection_cancelled (GCancellable *cancellable,
-                          gpointer      data)
- {
--  GCancellable *attempt_cancellable = data;
-+  GCancellable *linked_cancellable = G_CANCELLABLE (data);
- 
--  g_cancellable_cancel (attempt_cancellable);
-+  g_cancellable_cancel (linked_cancellable);
- }
- 
- static void
-@@ -1743,39 +1836,49 @@ g_socket_client_enumerator_callback (GObject      
*object,
-                                                    result, &error);
-   if (address == NULL)
-     {
--      if (data->connection_attempts)
-+      if (G_UNLIKELY (data->enumeration_completed))
-+        return;
-+
-+      data->enumeration_completed = TRUE;
-+      g_debug ("GSocketClient: Address enumeration completed (out of 
addresses)");
-+
-+      /* As per API docs: We only care about error if its the first call,
-+         after that the enumerator is done.
-+
-+         Note that we don't care about cancellation errors because
-+         task_completed_or_cancelled() above should handle that.
-+
-+         If this fails and nothing is in progress then we will complete task 
here.
-+       */
-+      if ((data->enumerated_at_least_once && !data->connection_attempts && 
!data->connection_in_progress) ||
-+          !data->enumerated_at_least_once)
-         {
--          g_object_unref (data->task);
--          return;
-+          g_debug ("GSocketClient: Address enumeration failed: %s", error ? 
error->message : NULL);
-+          if (data->last_error)
-+            {
-+              g_clear_error (&error);
-+              error = data->last_error;
-+              data->last_error = NULL;
-+            }
-+          else if (!error)
-+            {
-+              g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
-+                _("Unknown error on connect"));
-+            }
-+
-+          complete_connection_with_error (data, error);
-         }
- 
--      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, 
data->connectable, NULL);
--      data->completed = TRUE;
--      if (!error)
--      {
--        if (data->last_error)
--          {
--            error = data->last_error;
--            data->last_error = NULL;
--          }
--        else
--          {
--            g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
--                                 _("Unknown error on connect"));
--          }
--      }
--      g_task_return_error (data->task, error);
-+      /* Enumeration should never trigger again, drop our ref */
-       g_object_unref (data->task);
-       return;
-     }
- 
-+  data->enumerated_at_least_once = TRUE;
-+  g_debug ("GSocketClient: Address enumeration succeeded");
-   g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVED,
-                             data->connectable, NULL);
- 
--  if (G_IS_PROXY_ADDRESS (address) &&
--      data->client->priv->enable_proxy)
--    data->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address));
--
-   g_clear_error (&data->last_error);
- 
-   socket = create_socket (data->client, address, &data->last_error);
-@@ -1793,6 +1896,10 @@ g_socket_client_enumerator_callback (GObject      
*object,
-   attempt->cancellable = g_cancellable_new ();
-   attempt->connection = (GIOStream 
*)g_socket_connection_factory_create_connection (socket);
-   attempt->timeout_source = g_timeout_source_new 
(HAPPY_EYEBALLS_CONNECTION_ATTEMPT_TIMEOUT_MS);
-+
-+  if (G_IS_PROXY_ADDRESS (address) && data->client->priv->enable_proxy)
-+    attempt->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address));
-+
-   g_source_set_callback (attempt->timeout_source, 
on_connection_attempt_timeout, attempt, NULL);
-   g_source_attach (attempt->timeout_source, g_task_get_context (data->task));
-   data->connection_attempts = g_slist_append (data->connection_attempts, 
attempt);
-@@ -1802,6 +1909,7 @@ g_socket_client_enumerator_callback (GObject      
*object,
-                            g_object_ref (attempt->cancellable), 
g_object_unref);
- 
-   g_socket_connection_set_cached_remote_address ((GSocketConnection 
*)attempt->connection, address);
-+  g_debug ("GSocketClient: Starting TCP connection attempt");
-   g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTING, 
data->connectable, attempt->connection);
-   g_socket_connection_connect_async (G_SOCKET_CONNECTION 
(attempt->connection),
-                                    address,
-@@ -1854,24 +1962,48 @@ g_socket_client_connect_async (GSocketClient       
*client,
-   else
-     data->enumerator = g_socket_connectable_enumerate (connectable);
- 
--  /* The flow and ownership here isn't quite obvious:
--    - The task starts an async attempt to connect.
--      - Each attempt holds a single ref on task.
--      - Each attempt may create new attempts by timing out (not a failure) so
--        there are multiple attempts happening in parallel.
--      - Upon failure an attempt will start a new attempt that steals its ref
--        until there are no more attempts left and it drops its ref.
--      - Upon success it will cancel all other attempts and continue on
--        to the rest of the connection (tls, proxies, etc) which do not
--        happen in parallel and at the very end drop its ref.
--      - Upon cancellation an attempt drops its ref.
--   */
-+  /* This function tries to match the behavior of g_socket_client_connect ()
-+     which is simple enough but much of it is done in parallel to be as 
responsive
-+     as possible as per Happy Eyeballs (RFC 8305). This complicates flow 
quite a
-+     bit but we can describe it in 3 sections:
-+
-+     Firstly we have address enumeration (DNS):
-+       - This may be triggered multiple times by enumerator_next_async().
-+       - It also has its own cancellable (data->enumeration_cancellable).
-+       - Enumeration is done lazily because GNetworkAddressAddressEnumerator
-+         also does work in parallel and may lazily add new addresses.
-+       - If the first enumeration errors then the task errors. Otherwise all 
enumerations
-+         will potentially be used (until task or enumeration is cancelled).
-+
-+      Then we start attempting connections (TCP):
-+        - Each connection is independent and kept in a ConnectionAttempt 
object.
-+          - They each hold a ref on the main task and have their own 
cancellable.
-+        - Multiple attempts may happen in parallel as per Happy Eyeballs.
-+        - Upon failure or timeouts more connection attempts are made.
-+          - If no connections succeed the task errors.
-+        - Upon success they are kept in a list of successful connections.
-+
-+      Lastly we connect at the application layer (TLS, Proxies):
-+        - These are done in serial.
-+          - The reasoning here is that Happy Eyeballs is about making bad 
connections responsive
-+            at the IP/TCP layers. Issues at the application layer are 
generally not due to
-+            connectivity issues but rather misconfiguration.
-+        - Upon failure it will try the next TCP connection until it runs out 
and
-+          the task errors.
-+        - Upon success it cancels everything remaining (enumeration and 
connections)
-+          and returns the connection.
-+  */
- 
-   data->task = g_task_new (client, cancellable, callback, user_data);
-   g_task_set_check_cancellable (data->task, FALSE); /* We handle this 
manually */
-   g_task_set_source_tag (data->task, g_socket_client_connect_async);
-   g_task_set_task_data (data->task, data, 
(GDestroyNotify)g_socket_client_async_connect_data_free);
- 
-+  data->enumeration_cancellable = g_cancellable_new ();
-+  if (cancellable)
-+    g_cancellable_connect (cancellable, G_CALLBACK (on_connection_cancelled),
-+                           g_object_ref (data->enumeration_cancellable), 
g_object_unref);
-+
-   enumerator_next_async (data, FALSE);
- }
- 
-@@ -1990,6 +2122,7 @@ g_socket_client_connect_to_uri_async (GSocketClient      
  *client,
-     }
-   else
-     {
-+      g_debug("g_socket_client_connect_to_uri_async");
-       g_socket_client_connect_async (client,
-                                    connectable, cancellable,
-                                    callback, user_data);
--- 
-2.24.1
-

Reply via email to