summaryrefslogtreecommitdiff
path: root/libnm/nm-vpn-service-plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm/nm-vpn-service-plugin.c')
-rw-r--r--libnm/nm-vpn-service-plugin.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/libnm/nm-vpn-service-plugin.c b/libnm/nm-vpn-service-plugin.c
index 2644732d96..d9f669c9ee 100644
--- a/libnm/nm-vpn-service-plugin.c
+++ b/libnm/nm-vpn-service-plugin.c
@@ -53,11 +53,13 @@ typedef struct {
GDBusConnection *connection;
NMDBusVpnPlugin *dbus_vpn_service_plugin;
char *dbus_service_name;
+ gboolean dbus_watch_peer;
/* Temporary stuff */
guint connect_timer;
guint quit_timer;
guint fail_stop_id;
+ guint peer_watch_id;
gboolean interactive;
gboolean got_config;
@@ -88,6 +90,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
enum {
PROP_0,
PROP_DBUS_SERVICE_NAME,
+ PROP_DBUS_WATCH_PEER,
PROP_STATE,
LAST_PROP
@@ -184,11 +187,13 @@ nm_vpn_service_plugin_failure (NMVpnServicePlugin *plugin,
gboolean
nm_vpn_service_plugin_disconnect (NMVpnServicePlugin *plugin, GError **err)
{
+ NMVpnServicePluginPrivate *priv;
gboolean ret = FALSE;
NMVpnServiceState state;
g_return_val_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin), FALSE);
+ priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin);
state = nm_vpn_service_plugin_get_state (plugin);
switch (state) {
case NM_VPN_SERVICE_STATE_STOPPING:
@@ -207,6 +212,11 @@ nm_vpn_service_plugin_disconnect (NMVpnServicePlugin *plugin, GError **err)
break;
case NM_VPN_SERVICE_STATE_STARTING:
case NM_VPN_SERVICE_STATE_STARTED:
+ if (priv->peer_watch_id) {
+ g_dbus_connection_signal_unsubscribe (nm_vpn_service_plugin_get_connection (plugin),
+ priv->peer_watch_id);
+ priv->peer_watch_id = 0;
+ }
nm_vpn_service_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPING);
ret = NM_VPN_SERVICE_PLUGIN_GET_CLASS (plugin)->disconnect (plugin, err);
nm_vpn_service_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
@@ -414,6 +424,37 @@ connect_timer_start (NMVpnServicePlugin *plugin)
}
static void
+peer_vanished (GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ nm_vpn_service_plugin_disconnect (NM_VPN_SERVICE_PLUGIN (user_data), NULL);
+}
+
+static guint
+watch_peer (NMVpnServicePlugin *plugin,
+ GDBusMethodInvocation *context)
+{
+ GDBusConnection *connection = g_dbus_method_invocation_get_connection (context);
+ const gchar *peer = g_dbus_message_get_sender (g_dbus_method_invocation_get_message (context));
+
+ return g_dbus_connection_signal_subscribe (connection,
+ "org.freedesktop.DBus",
+ "org.freedesktop.DBus",
+ "NameOwnerChanged",
+ "/org/freedesktop/DBus",
+ peer,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ peer_vanished,
+ plugin,
+ NULL);
+}
+
+static void
_connect_generic (NMVpnServicePlugin *plugin,
GDBusMethodInvocation *context,
GVariant *properties,
@@ -457,6 +498,9 @@ _connect_generic (NMVpnServicePlugin *plugin,
nm_vpn_service_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING);
+ if (priv->dbus_watch_peer)
+ priv->peer_watch_id = watch_peer (plugin, context);
+
if (details) {
priv->interactive = TRUE;
success = vpn_class->connect_interactive (plugin, connection, details, &error);
@@ -994,6 +1038,10 @@ set_property (GObject *object, guint prop_id,
/* Construct-only */
priv->dbus_service_name = g_value_dup_string (value);
break;
+ case PROP_DBUS_WATCH_PEER:
+ /* Construct-only */
+ priv->dbus_watch_peer = g_value_get_boolean (value);
+ break;
case PROP_STATE:
nm_vpn_service_plugin_set_state (NM_VPN_SERVICE_PLUGIN (object),
(NMVpnServiceState) g_value_get_enum (value));
@@ -1014,6 +1062,9 @@ get_property (GObject *object, guint prop_id,
case PROP_DBUS_SERVICE_NAME:
g_value_set_string (value, priv->dbus_service_name);
break;
+ case PROP_DBUS_WATCH_PEER:
+ g_value_set_boolean (value, priv->dbus_watch_peer);
+ break;
case PROP_STATE:
g_value_set_enum (value, nm_vpn_service_plugin_get_state (NM_VPN_SERVICE_PLUGIN (object)));
break;
@@ -1121,6 +1172,20 @@ nm_vpn_service_plugin_class_init (NMVpnServicePluginClass *plugin_class)
G_PARAM_STATIC_STRINGS));
/**
+ * NMVpnServicePlugin:service-name:
+ *
+ * The D-Bus service name of this plugin.
+ *
+ * Since: 1.2
+ */
+ g_object_class_install_property
+ (object_class, PROP_DBUS_WATCH_PEER,
+ g_param_spec_boolean (NM_VPN_SERVICE_PLUGIN_DBUS_WATCH_PEER, "", "",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
* NMVpnServicePlugin:state:
*
* The state of the plugin.