diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c index 276dd03658..00ce4e8f52 100644 --- a/src/vpn-manager/nm-vpn-manager.c +++ b/src/vpn-manager/nm-vpn-manager.c @@ -186,7 +186,7 @@ vpn_dir_changed (GFileMonitor *monitor, const char *service_name = nm_vpn_service_get_dbus_service (service); /* Stop active VPN connections and destroy the service */ - nm_vpn_service_connections_stop (service, TRUE, + nm_vpn_service_stop_connections (service, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); nm_log_info (LOGD_VPN, "VPN: unloaded %s", service_name); g_hash_table_remove (priv->services, service_name); @@ -257,6 +257,21 @@ nm_vpn_manager_init (NMVPNManager *self) } } +static void +stop_all_services (NMVPNManager *self) +{ + NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); + GHashTableIter iter; + NMVPNService *service; + + g_hash_table_iter_init (&iter, priv->services); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &service)) { + nm_vpn_service_stop_connections (service, + TRUE, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); + } +} + static void dispose (GObject *object) { @@ -270,6 +285,7 @@ dispose (GObject *object) } if (priv->services) { + stop_all_services (NM_VPN_MANAGER (object)); g_hash_table_destroy (priv->services); priv->services = NULL; } diff --git a/src/vpn-manager/nm-vpn-service.c b/src/vpn-manager/nm-vpn-service.c index ac329422f4..3752797fb8 100644 --- a/src/vpn-manager/nm-vpn-service.c +++ b/src/vpn-manager/nm-vpn-service.c @@ -138,8 +138,8 @@ connection_vpn_state_changed (NMVPNConnection *connection, } void -nm_vpn_service_connections_stop (NMVPNService *service, - gboolean fail, +nm_vpn_service_stop_connections (NMVPNService *service, + gboolean quitting, NMVPNConnectionStateReason reason) { NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service); @@ -157,7 +157,8 @@ nm_vpn_service_connections_stop (NMVPNService *service, NMVPNConnection *vpn = NM_VPN_CONNECTION (iter->data); g_signal_handlers_disconnect_by_func (vpn, G_CALLBACK (connection_vpn_state_changed), service); - nm_vpn_connection_stop (vpn, fail, reason); + /* Quitting terminates the VPN cleanly, otherwise failure is assumed */ + nm_vpn_connection_stop (vpn, quitting ? FALSE : TRUE, reason); g_object_unref (vpn); } g_clear_pointer (&priv->pending, g_slist_free); @@ -185,7 +186,7 @@ _daemon_exec_timeout (gpointer data) nm_log_warn (LOGD_VPN, "VPN service '%s' start timed out", priv->name); priv->start_timeout = 0; - nm_vpn_service_connections_stop (self, TRUE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT); + nm_vpn_service_stop_connections (self, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT); return G_SOURCE_REMOVE; } @@ -218,7 +219,7 @@ nm_vpn_service_daemon_exec (NMVPNService *service, GError **error) NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED, "%s", spawn_error ? spawn_error->message : "unknown g_spawn_async() error"); - nm_vpn_service_connections_stop (service, TRUE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED); + nm_vpn_service_stop_connections (service, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED); if (spawn_error) g_error_free (spawn_error); } @@ -333,7 +334,7 @@ _name_owner_changed (NMDBusManager *mgr, /* service went away */ priv->service_running = FALSE; nm_log_info (LOGD_VPN, "VPN service '%s' disappeared", priv->name); - nm_vpn_service_connections_stop (service, TRUE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); + nm_vpn_service_stop_connections (service, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); } } @@ -359,9 +360,9 @@ dispose (GObject *object) priv->start_timeout = 0; } - nm_vpn_service_connections_stop (NM_VPN_SERVICE (object), - FALSE, - NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); + /* VPNService owner is required to stop connections before releasing */ + g_assert (priv->active == NULL); + g_assert (priv->pending == NULL); g_signal_handlers_disconnect_by_func (nm_dbus_manager_get (), G_CALLBACK (_name_owner_changed), diff --git a/src/vpn-manager/nm-vpn-service.h b/src/vpn-manager/nm-vpn-service.h index 1edde7b526..4545d1f07d 100644 --- a/src/vpn-manager/nm-vpn-service.h +++ b/src/vpn-manager/nm-vpn-service.h @@ -56,8 +56,8 @@ gboolean nm_vpn_service_activate (NMVPNService *service, NMVPNConnection *vpn, GError **error); -void nm_vpn_service_connections_stop (NMVPNService *service, - gboolean fail, +void nm_vpn_service_stop_connections (NMVPNService *service, + gboolean quitting, NMVPNConnectionStateReason reason); #endif /* NM_VPN_VPN_SERVICE_H */