Blob Blame History Raw
From c48c984d39afeae84b0cad515f08f83c711fd9c4 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Thu, 13 Sep 2018 10:25:05 +0100
Subject: [PATCH 1/9] gnetworkmonitornm: Set a GError properly on an error
 handling path
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

All the other initialisation failure paths set a GError, but this one
didn’t. Set a GError to avoid breaking the invariant that returning
FALSE should always have a GError set.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/glib/issues/1523
---
 gio/gnetworkmonitornm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c
index 20a86571f..5bc8c925a 100644
--- a/gio/gnetworkmonitornm.c
+++ b/gio/gnetworkmonitornm.c
@@ -309,6 +309,8 @@ g_network_monitor_nm_initable_init (GInitable     *initable,
 
   if (!name_owner)
     {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   _("NetworkManager not running"));
       g_object_unref (proxy);
       return FALSE;
     }
-- 
2.33.1

From d139986b1f213a7e1c1e3968ad2d8270f820bd57 Mon Sep 17 00:00:00 2001
From: Antonio Larrosa <alarrosa@suse.com>
Date: Tue, 12 Mar 2019 18:35:10 +0100
Subject: [PATCH 2/9] Handle an UNKNOWN NetworkManager connectivity as NONE

nm_conn_to_g_conn already handles UNKNOWN like NONE (returning
G_NETWORK_CONNECTIVITY_LOCAL in both cases). So in sync_properties
we should also set new_connectivity to G_NETWORK_CONNECTIVITY_LOCAL
for both NM_CONNECTIVITY_UNKNOWN and NM_CONNECTIVITY_NONE.

This has the added benefit that when NetworkManager returns the network
connectivity is UNKNOWN, we set network_available to FALSE as it should
be. Previously, there were cases in a laptop with no network access,
that g_network_monitor_get_network_available returned true, which was
wrong and is also fixed with this commit.
---
 gio/gnetworkmonitornm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c
index 5bc8c925a..4e2a35e8a 100644
--- a/gio/gnetworkmonitornm.c
+++ b/gio/gnetworkmonitornm.c
@@ -167,7 +167,8 @@ sync_properties (GNetworkMonitorNM *nm,
   nm_connectivity = g_variant_get_uint32 (v);
   g_variant_unref (v);
 
-  if (nm_connectivity == NM_CONNECTIVITY_NONE)
+  if (nm_connectivity == NM_CONNECTIVITY_UNKNOWN ||
+      nm_connectivity == NM_CONNECTIVITY_NONE)
     {
       new_network_available = FALSE;
       new_network_metered = FALSE;
-- 
2.33.1

From 5b4e6f9813cf90c690d8974635b0aeff8f5d2c5d Mon Sep 17 00:00:00 2001
From: Fabrice Bellet <fabrice@bellet.info>
Date: Mon, 29 Apr 2019 12:05:54 +0000
Subject: [PATCH 3/9] gnetworkmonitornm: Fix network available detection

The network-available property can be asserted by querying the NMState
describing the current overval network state, instead of the
NMConnectivityState. The advantage of the NMState is that is reflects
immediately the network state modification, while the connectivity
state is tested at a fixed frequency.
---
 gio/gnetworkmonitornm.c | 39 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c
index 4e2a35e8a..7bb480f54 100644
--- a/gio/gnetworkmonitornm.c
+++ b/gio/gnetworkmonitornm.c
@@ -52,6 +52,19 @@ typedef enum {
   NM_CONNECTIVITY_FULL
 } NMConnectivityState;
 
+/* Copied from https://developer.gnome.org/libnm-util/stable/libnm-util-NetworkManager.html#NMState;
+ * used inline to avoid a NetworkManager dependency from GLib. */
+typedef enum {
+  NM_STATE_UNKNOWN          = 0,
+  NM_STATE_ASLEEP           = 10,
+  NM_STATE_DISCONNECTED     = 20,
+  NM_STATE_DISCONNECTING    = 30,
+  NM_STATE_CONNECTING       = 40,
+  NM_STATE_CONNECTED_LOCAL  = 50,
+  NM_STATE_CONNECTED_SITE   = 60,
+  NM_STATE_CONNECTED_GLOBAL = 70,
+} NMState;
+
 struct _GNetworkMonitorNMPrivate
 {
   GDBusProxy *proxy;
@@ -155,11 +168,19 @@ sync_properties (GNetworkMonitorNM *nm,
                  gboolean           emit_signals)
 {
   GVariant *v;
+  NMState nm_state;
   NMConnectivityState nm_connectivity;
   gboolean new_network_available;
   gboolean new_network_metered;
   GNetworkConnectivity new_connectivity;
 
+  v = g_dbus_proxy_get_cached_property (nm->priv->proxy, "State");
+  if (!v)
+    return;
+
+  nm_state = g_variant_get_uint32 (v);
+  g_variant_unref (v);
+
   v = g_dbus_proxy_get_cached_property (nm->priv->proxy, "Connectivity");
   if (!v)
     return;
@@ -167,14 +188,26 @@ sync_properties (GNetworkMonitorNM *nm,
   nm_connectivity = g_variant_get_uint32 (v);
   g_variant_unref (v);
 
-  if (nm_connectivity == NM_CONNECTIVITY_UNKNOWN ||
-      nm_connectivity == NM_CONNECTIVITY_NONE)
+  if (nm_state <= NM_STATE_CONNECTED_LOCAL)
     {
       new_network_available = FALSE;
       new_network_metered = FALSE;
       new_connectivity = G_NETWORK_CONNECTIVITY_LOCAL;
     }
-  else
+  else if (nm_state <= NM_STATE_CONNECTED_SITE)
+    {
+      new_network_available = FALSE;
+      new_network_metered = FALSE;
+      if (nm_connectivity == NM_CONNECTIVITY_PORTAL)
+        {
+          new_connectivity = G_NETWORK_CONNECTIVITY_PORTAL;
+        }
+      else
+        {
+          new_connectivity = G_NETWORK_CONNECTIVITY_LIMITED;
+        }
+    }
+  else /* nm_state == NM_STATE_CONNECTED_FULL */
     {
 
       /* this is only available post NM 1.0 */
-- 
2.33.1

From 96fba295771d600e4f0f522400b2fb9b1ff42cee Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Fri, 31 May 2019 11:19:07 +0100
Subject: [PATCH 4/9] gnetworkmonitornm: Consider NM_STATE_CONNECTED_SITE to be
 available

`NM_STATE_CONNECTED_SITE` is documented to mean that a default route is
available, but that the internet connectivity check failed. A default
route being available is compatible with the documentation for
GNetworkMonitor:network-available, which should be true if the system
has a default route for at least one of IPv4 and IPv6.

https://developer.gnome.org/NetworkManager/stable/nm-dbus-types.html

Signed-off-by: Philip Withnall <withnall@endlessm.com>

Fixes: #1788
---
 gio/gnetworkmonitornm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c
index 7bb480f54..9013fd49c 100644
--- a/gio/gnetworkmonitornm.c
+++ b/gio/gnetworkmonitornm.c
@@ -196,7 +196,7 @@ sync_properties (GNetworkMonitorNM *nm,
     }
   else if (nm_state <= NM_STATE_CONNECTED_SITE)
     {
-      new_network_available = FALSE;
+      new_network_available = TRUE;
       new_network_metered = FALSE;
       if (nm_connectivity == NM_CONNECTIVITY_PORTAL)
         {
-- 
2.33.1

From 74e5f472c838115f0ba19ac501805cb5b2ca837f Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Mon, 29 Jul 2019 17:25:21 +0200
Subject: [PATCH 5/9] gnetworkmonitornm: Disconnect g-signal from proxy

So that we're sure never to receive a signal if something is keeping the
proxy alive.
---
 gio/gnetworkmonitornm.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c
index 9013fd49c..52073fac9 100644
--- a/gio/gnetworkmonitornm.c
+++ b/gio/gnetworkmonitornm.c
@@ -68,6 +68,7 @@ typedef enum {
 struct _GNetworkMonitorNMPrivate
 {
   GDBusProxy *proxy;
+  guint signal_id;
 
   GNetworkConnectivity connectivity;
   gboolean network_available;
@@ -360,8 +361,8 @@ g_network_monitor_nm_initable_init (GInitable     *initable,
       return FALSE;
     }
 
-  g_signal_connect (G_OBJECT (proxy), "g-signal",
-                    G_CALLBACK (proxy_signal_cb), nm);
+  nm->priv->signal_id = g_signal_connect (G_OBJECT (proxy), "g-signal",
+                                          G_CALLBACK (proxy_signal_cb), nm);
   nm->priv->proxy = proxy;
   sync_properties (nm, FALSE);
 
@@ -373,6 +374,13 @@ g_network_monitor_nm_finalize (GObject *object)
 {
   GNetworkMonitorNM *nm = G_NETWORK_MONITOR_NM (object);
 
+  if (nm->priv->proxy != NULL &&
+      nm->priv->signal_id != 0)
+    {
+      g_signal_handler_disconnect (nm->priv->proxy,
+                                   nm->priv->signal_id);
+      nm->priv->signal_id = 0;
+    }
   g_clear_object (&nm->priv->proxy);
 
   G_OBJECT_CLASS (g_network_monitor_nm_parent_class)->finalize (object);
-- 
2.33.1

From eeaf1de6e695afd971d67137caa8e39e1c1267df Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Mon, 29 Jul 2019 17:26:20 +0200
Subject: [PATCH 6/9] gnetworkmonitornm: Arguments to g-signal's callback are
 const

---
 gio/gnetworkmonitornm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c
index 52073fac9..479653a51 100644
--- a/gio/gnetworkmonitornm.c
+++ b/gio/gnetworkmonitornm.c
@@ -268,8 +268,8 @@ update_cached_property (GDBusProxy   *proxy,
 
 static void
 proxy_signal_cb (GDBusProxy        *proxy,
-                 gchar             *sender_name,
-                 gchar             *signal_name,
+                 const gchar       *sender_name,
+                 const gchar       *signal_name,
                  GVariant          *parameters,
                  GNetworkMonitorNM *nm)
 {
-- 
2.33.1

From 46d70700c85e4419942c8a3d08bd0bf842702c4a Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Mon, 29 Jul 2019 17:26:47 +0200
Subject: [PATCH 7/9] gnetworkmonitornm: Remove double-space

---
 gio/gnetworkmonitornm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c
index 479653a51..5a36a0ba1 100644
--- a/gio/gnetworkmonitornm.c
+++ b/gio/gnetworkmonitornm.c
@@ -391,7 +391,7 @@ g_network_monitor_nm_class_init (GNetworkMonitorNMClass *nl_class)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class);
 
-  gobject_class->finalize  = g_network_monitor_nm_finalize;
+  gobject_class->finalize = g_network_monitor_nm_finalize;
   gobject_class->get_property = g_network_monitor_nm_get_property;
 
   g_object_class_override_property (gobject_class, PROP_NETWORK_AVAILABLE, "network-available");
-- 
2.33.1

From 72291aac3dac7a8ed4c85eb41608f3f5f9ad7681 Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <julian.klode@canonical.com>
Date: Tue, 12 Oct 2021 12:01:50 +0200
Subject: [PATCH 8/9] gnetworkmonitornm: Stop using removed PropertiesChanged
 signal

Use the org.freedesktop.DBus.Properties interface to listen
to PropertiesChanged signals on /org/freedesktop/NetworkManager.

NetworkManager used to provide its own legacy PropertiesChanged
signal, but that was dropped in
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/853

This requires NetworkManager >= 1.2 (2016)

Fixes: #2505
Bug-Ubuntu: https://bugs.launchpad.net/bugs/1946196
---
 gio/gnetworkmonitornm.c | 29 +++++++----------------------
 1 file changed, 7 insertions(+), 22 deletions(-)

diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c
index 5a36a0ba1..6a6d1d666 100644
--- a/gio/gnetworkmonitornm.c
+++ b/gio/gnetworkmonitornm.c
@@ -267,29 +267,14 @@ update_cached_property (GDBusProxy   *proxy,
 }
 
 static void
-proxy_signal_cb (GDBusProxy        *proxy,
-                 const gchar       *sender_name,
-                 const gchar       *signal_name,
-                 GVariant          *parameters,
-                 GNetworkMonitorNM *nm)
+proxy_properties_changed_cb (GDBusProxy        *proxy,
+                             GVariant          *changed_properties,
+                             GStrv              invalidated_properties,
+                             GNetworkMonitorNM *nm)
 {
-  GVariant *asv;
   GVariantDict *dict;
 
-  if (g_strcmp0 (signal_name, "PropertiesChanged") != 0)
-    return;
-
-  g_variant_get (parameters, "(@a{sv})", &asv);
-  if (!asv)
-    return;
-
-  dict = g_variant_dict_new (asv);
-  g_variant_unref (asv);
-  if (!dict)
-    {
-      g_warning ("Failed to handle PropertiesChanged signal from NetworkManager");
-      return;
-    }
+  dict = g_variant_dict_new (changed_properties);
 
   update_cached_property (nm->priv->proxy, "Connectivity", dict);
 
@@ -361,8 +346,8 @@ g_network_monitor_nm_initable_init (GInitable     *initable,
       return FALSE;
     }
 
-  nm->priv->signal_id = g_signal_connect (G_OBJECT (proxy), "g-signal",
-                                          G_CALLBACK (proxy_signal_cb), nm);
+  nm->priv->signal_id = g_signal_connect (G_OBJECT (proxy), "g-properties-changed",
+                                          G_CALLBACK (proxy_properties_changed_cb), nm);
   nm->priv->proxy = proxy;
   sync_properties (nm, FALSE);
 
-- 
2.33.1

From 3bafff71d7588285763f603b23c830722a2169d1 Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <julian.klode@canonical.com>
Date: Tue, 12 Oct 2021 17:31:42 +0200
Subject: [PATCH 9/9] gnetworkmonitornm: Do not re-update cached property

GDBusProxy already takes care of updating the cached property
before emitting the signal, so there is no need to do this
a second time ourselves.
---
 gio/gnetworkmonitornm.c | 22 ----------------------
 1 file changed, 22 deletions(-)

diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c
index 6a6d1d666..a8040fb36 100644
--- a/gio/gnetworkmonitornm.c
+++ b/gio/gnetworkmonitornm.c
@@ -252,34 +252,12 @@ sync_properties (GNetworkMonitorNM *nm,
     }
 }
 
-static void
-update_cached_property (GDBusProxy   *proxy,
-                        const char   *property_name,
-                        GVariantDict *dict)
-{
-  GVariant *v;
-
-  v = g_variant_dict_lookup_value (dict, property_name, NULL);
-  if (!v)
-    return;
-  g_dbus_proxy_set_cached_property (proxy, property_name, v);
-  g_variant_unref (v);
-}
-
 static void
 proxy_properties_changed_cb (GDBusProxy        *proxy,
                              GVariant          *changed_properties,
                              GStrv              invalidated_properties,
                              GNetworkMonitorNM *nm)
 {
-  GVariantDict *dict;
-
-  dict = g_variant_dict_new (changed_properties);
-
-  update_cached_property (nm->priv->proxy, "Connectivity", dict);
-
-  g_variant_dict_unref (dict);
-
   sync_properties (nm, TRUE);
 }
 
-- 
2.33.1