libnm/vpn-service-plugin: add watch-peer property
Make it possible to construct the plugin instance in a way that disconnects the connection if the DBus client that activated it drops off the bus. This makes the plugins conveniently clean up when NetworkManager crashes. We need this, as with multiple VPN support we can loose track of the client bus names when the daemon crashes leaving to nice way to clean up on respawn. However, this behavior is not desired for debugging or hypotetical VPN plugin users other than NetworkManager (say; "gdbus call -m o.fd.NM.VPN.Plugin.Connect"). Let the plugin decide when to use it.
This commit is contained in:
@@ -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);
|
||||
@@ -413,6 +423,37 @@ connect_timer_start (NMVpnServicePlugin *plugin)
|
||||
priv->connect_timer = g_timeout_add_seconds (60, connect_timer_expired, 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,
|
||||
@@ -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;
|
||||
@@ -1120,6 +1171,20 @@ nm_vpn_service_plugin_class_init (NMVpnServicePluginClass *plugin_class)
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
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:
|
||||
*
|
||||
|
@@ -36,6 +36,7 @@ G_BEGIN_DECLS
|
||||
#define NM_VPN_SERVICE_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePluginClass))
|
||||
|
||||
#define NM_VPN_SERVICE_PLUGIN_DBUS_SERVICE_NAME "service-name"
|
||||
#define NM_VPN_SERVICE_PLUGIN_DBUS_WATCH_PEER "watch-peer"
|
||||
#define NM_VPN_SERVICE_PLUGIN_STATE "state"
|
||||
|
||||
typedef struct {
|
||||
|
Reference in New Issue
Block a user