After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 745307 - [review] dcbw/vpn-gdbus: convert NMVpnConnection <-> VPN service communication to GDBus
[review] dcbw/vpn-gdbus: convert NMVpnConnection <-> VPN service communicatio...
Status: RESOLVED FIXED
Product: NetworkManager
Classification: Platform
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: NetworkManager maintainer(s)
NetworkManager maintainer(s)
Depends on:
Blocks: nm-review
 
 
Reported: 2015-02-27 20:02 UTC by Dan Williams
Modified: 2015-03-03 21:05 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Dan Williams 2015-02-27 20:02:30 UTC
Please review.
Comment 1 Dan Winship 2015-02-27 21:49:37 UTC
>+#define VPN_PLUGIN_ERROR (vpn_plugin_error_quark ())
>+...

You don't need this; nm-errors in libnm-core already defines and registers all the errors used in all public NM APIs.

>+static struct in6_addr
>+ip6_addr_from_variant (GVariant *v, struct in6_addr **new_addr)
...
>+			return * (struct in6_addr *) bytes;

bytes is not necessarily correctly aligned for a struct in6_addr, which might matter on non-x86?

The whole "sometimes the caller wants a const pointer and sometimes they want allocated memory so, hey, let's provide both in the same API" thing is weird anyway. How about just taking a "struct in6_addr *out_addr" and memcpy'ing into it, and do the allocation separately in the two places you need that? (See also below re ip6_external_gw.)

>-	if (val && G_VALUE_HOLDS_BOOLEAN (val) && g_value_get_boolean (val)) {
>+	if (g_variant_lookup (dict, NM_VPN_PLUGIN_CAN_PERSIST, "b", &b)) {

&& b

>+		ip6_addr_from_variant (v, &priv->ip6_external_gw);
>+		if (!IN6_IS_ADDR_UNSPECIFIED (priv->ip6_external_gw))
>+			success = TRUE;

This will crash if v is the wrong length (in which case priv->ip6_external_gw won't have been set).

>+} VpnIp4Route;

appears to be unused

>+	if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_DNS, "@au", &v)) {
>+		u32_array = g_variant_get_fixed_array (v, &len, sizeof (guint32));
>+		for (i = 0; i < len; i++)
>+			nm_ip4_config_add_nameserver (config, u32_array[i]);
>+		g_variant_unref (v);
> 	}

Note that it would be simpler to use the non-"@" form here and elsewhere:

    if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_DNS, "au", &iter)) {
        while (g_variant_iter_next (&iter, "u", &u32))
            nm_ip4_config_add_nameserver (config, u32);
    }

>+		nm_log_warn (LOGD_VPN, "VPN connection '%s' failed to connect: '%s'.",
>+			         nm_connection_get_id (NM_VPN_CONNECTION_GET_PRIVATE (self)->connection),

indentation
Comment 2 Thomas Haller 2015-03-02 11:10:53 UTC
pushed two fixups
Comment 3 Dan Williams 2015-03-02 15:24:28 UTC
(In reply to Thomas Haller from comment #2)
> pushed two fixups

For the GCancellable one, my thought was that if we're cancelling one operation, we're going to cancel them all.  We only cancel anything if the VPN is getting disconnected or getting disposed, so at that point we don't care about any of the ongoing async operations.

The users of a cancellable are:

Connect()
ConnectInteractive()
proxy creation
NewSecrets()
NeedSecrets()

None of these operations overlap, and if any of them are cancelled they all should be.  So I don't think we need to track individual cancellables for every call...
Comment 4 Thomas Haller 2015-03-02 16:48:51 UTC
(In reply to Dan Williams from comment #3)
> None of these operations overlap, and if any of them are cancelled they all
> should be.  So I don't think we need to track individual cancellables for
> every call...

how can you be sure that there are no overlapping invocations?

> priv->proxy receives "g-signal" with "SecretsRequired"
 > signal_cb()
  > plugin_interactive_secrets_required()
   > get_secrets() (set priv->secrets_id)
    > nm_settings_connection_get_secrets()
     |
     | (async)
     |
     > get_secrets_cb() (clear priv->secrets_id)
      > NewSecrets/NeedSecrets

Note that nm_settings_connection_cancel_secrets() does not cancel the pending NewSecrets/NeedSecrets.


It seems complicated to prove that there are no overlapping invocations. And what's the point? If you change anything, you have to do all the reasoning again.
OTOH, you can also add an assertion that might catch a race:

 static AsyncData *
 _create_async_user_data (NMVpnConnection *self)
 {
     NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
     AsyncData *async_data;
+    gboolean had_pending = !!priv->pending_async_data;
 
     async_data = g_slice_new (AsyncData);
     async_data->self = self;
     async_data->cancellable = g_cancellable_new ();
 
     priv->pending_async_data = g_slist_prepend (priv->pending_async_data, async_data);
+    g_return_val_if_fail (!had_pending, async_data);
     return async_data;
 }
Comment 5 Dan Williams 2015-03-02 16:50:53 UTC
I see what you mean with the reference to https://developer.gnome.org/gio/stable/GCancellable.html#g-cancellable-reset though, but the code only cancels the cancellable in dispose(), after which it will never be used.  So I don't think there's any possibility that the same cancellable will get cancelled twice, which is what your patch tries to deal with.
Comment 6 Dan Williams 2015-03-02 16:53:14 UTC
AFAIUI the issue with cancellables is that they should not be re-used after being cancelled, and I don't believe the code in nm-vpn-connection.c ever does that.  They are certainly intended to be passed to multiple operations, all of which can be cancelled at the same time with a single cancellable, which is what the code *does* try to do.
Comment 7 Dan Williams 2015-03-02 16:53:34 UTC
BTW, repushed with fixups for danw's comments...
Comment 8 Thomas Haller 2015-03-02 16:55:33 UTC
(In reply to Dan Williams from comment #6)
> AFAIUI the issue with cancellables is that they should not be re-used after
> being cancelled, and I don't believe the code in nm-vpn-connection.c ever
> does that.  They are certainly intended to be passed to multiple operations,
> all of which can be cancelled at the same time with a single cancellable,
> which is what the code *does* try to do.

I was wrong, you are correct:

https://developer.gnome.org/gio/stable/GCancellable.html#g-cancellable-new

One GCancellable can be used in multiple consecutive operations or in multiple concurrent operations.


good then.
Comment 9 Dan Winship 2015-03-03 18:13:03 UTC
looks good, but remember to remove the GCancellable fixup before squashing
Comment 10 Dan Williams 2015-03-03 21:05:43 UTC
Dropped that commit.  Resulting in:

231b039 vpn: convert NMVpnConnection <-> VPN service communication to GDBus (bgo #745307)