summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-04-23 18:11:10 +0200
committerThomas Haller <thaller@redhat.com>2017-04-23 18:15:34 +0200
commitb495d0bf94e5cc043636064abf8a6053ff965af2 (patch)
treea4f5c8d1d6478fb810ead3f448ad617271fd81cf
parent7d1f725743146a1ff8740bba5f4503a5ddd23a3d (diff)
parent019b9fbfc0aa2123d1e0a742c0b3d01caaa7d874 (diff)
downloadNetworkManager-b495d0bf94e5cc043636064abf8a6053ff965af2.tar.gz
proxy: merge branch 'th/proxy-rh1444374'
https://bugzilla.redhat.com/show_bug.cgi?id=1444374
-rw-r--r--src/devices/nm-device.c55
-rw-r--r--src/nm-pacrunner-manager.c173
-rw-r--r--src/nm-pacrunner-manager.h22
-rw-r--r--src/vpn/nm-vpn-connection.c33
4 files changed, 168 insertions, 115 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 160e5a7259..2b17db97b6 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -323,7 +323,7 @@ typedef struct _NMDevicePrivate {
/* Proxy Configuration */
NMProxyConfig *proxy_config;
NMPacrunnerManager *pacrunner_manager;
- bool proxy_config_sent;
+ NMPacrunnerCallId *pacrunner_call_id;
/* IP4 configuration info */
NMIP4Config * ip4_config; /* Combined config from VPN, settings, and device */
@@ -8880,23 +8880,32 @@ nm_device_reactivate_ip6_config (NMDevice *self,
}
static void
-reactivate_proxy_config (NMDevice *self)
+_pacrunner_manager_send (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- if (!priv->proxy_config_sent)
- return;
+ nm_pacrunner_manager_remove_clear (priv->pacrunner_manager,
+ &priv->pacrunner_call_id);
- nm_pacrunner_manager_remove (priv->pacrunner_manager,
- nm_device_get_ip_iface (self));
+ if (!priv->pacrunner_manager)
+ priv->pacrunner_manager = g_object_ref (nm_pacrunner_manager_get ());
+
+ priv->pacrunner_call_id = nm_pacrunner_manager_send (priv->pacrunner_manager,
+ nm_device_get_ip_iface (self),
+ priv->proxy_config,
+ NULL,
+ NULL);
+}
+
+static void
+reactivate_proxy_config (NMDevice *self)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ if (!priv->pacrunner_call_id)
+ return;
nm_device_set_proxy_config (self, priv->dhcp4.pac_url);
- nm_pacrunner_manager_send (priv->pacrunner_manager,
- nm_device_get_ip_iface (self),
- nm_device_get_ip_iface (self),
- priv->proxy_config,
- NULL,
- NULL);
+ _pacrunner_manager_send (self);
}
static gboolean
@@ -12565,11 +12574,8 @@ _set_state_full (NMDevice *self,
}
}
- if (priv->proxy_config_sent) {
- nm_pacrunner_manager_remove (priv->pacrunner_manager,
- nm_device_get_ip_iface (self));
- priv->proxy_config_sent = FALSE;
- }
+ nm_pacrunner_manager_remove_clear (priv->pacrunner_manager,
+ &priv->pacrunner_call_id);
break;
case NM_DEVICE_STATE_DISCONNECTED:
if ( priv->queued_act_request
@@ -12594,15 +12600,8 @@ _set_state_full (NMDevice *self,
req,
NULL, NULL, NULL);
- if (priv->proxy_config) {
- nm_pacrunner_manager_send (priv->pacrunner_manager,
- nm_device_get_ip_iface (self),
- nm_device_get_ip_iface (self),
- priv->proxy_config,
- NULL,
- NULL);
- priv->proxy_config_sent = TRUE;
- }
+ if (priv->proxy_config)
+ _pacrunner_manager_send (self);
break;
case NM_DEVICE_STATE_FAILED:
/* Usually upon failure the activation chain is interrupted in
@@ -13608,8 +13607,6 @@ nm_device_init (NMDevice *self)
priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
priv->sys_iface_state = NM_DEVICE_SYS_IFACE_STATE_EXTERNAL;
- priv->pacrunner_manager = g_object_ref (nm_pacrunner_manager_get ());
-
priv->default_route.v4_is_assumed = TRUE;
priv->default_route.v6_is_assumed = TRUE;
@@ -13734,6 +13731,8 @@ dispose (GObject *object)
dispatcher_cleanup (self);
+ nm_pacrunner_manager_remove_clear (priv->pacrunner_manager,
+ &priv->pacrunner_call_id);
g_clear_object (&priv->pacrunner_manager);
_cleanup_generic_pre (self, CLEANUP_TYPE_KEEP);
diff --git a/src/nm-pacrunner-manager.c b/src/nm-pacrunner-manager.c
index d4a5b5ab9a..cfc028c2cc 100644
--- a/src/nm-pacrunner-manager.c
+++ b/src/nm-pacrunner-manager.c
@@ -36,14 +36,15 @@ static void pacrunner_remove_done (GDBusProxy *proxy, GAsyncResult *res, gpointe
/*****************************************************************************/
-typedef struct {
- char *tag;
+struct _NMPacrunnerCallId {
NMPacrunnerManager *manager;
GVariant *args;
char *path;
guint refcount;
bool removed;
-} Config;
+};
+
+typedef struct _NMPacrunnerCallId Config;
typedef struct {
char *iface;
@@ -74,16 +75,25 @@ NM_DEFINE_SINGLETON_GETTER (NMPacrunnerManager, nm_pacrunner_manager_get, NM_TYP
#define _NMLOG_DOMAIN LOGD_PROXY
#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "pacrunner", __VA_ARGS__)
+#define _NMLOG2_PREFIX_NAME "pacrunner"
+#define _NMLOG2(level, config, ...) \
+ G_STMT_START { \
+ nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \
+ "%s%p]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
+ "pacrunner: call[", \
+ (config) \
+ _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
+ } G_STMT_END
+
/*****************************************************************************/
static Config *
-config_new (NMPacrunnerManager *manager, char *tag, GVariant *args)
+config_new (NMPacrunnerManager *manager, GVariant *args)
{
Config *config;
config = g_slice_new0 (Config);
config->manager = manager;
- config->tag = tag;
config->args = g_variant_ref_sink (args);
config->refcount = 1;
@@ -106,7 +116,6 @@ config_unref (Config *config)
g_assert (config->refcount > 0);
if (config->refcount == 1) {
- g_free (config->tag);
g_variant_unref (config->args);
g_free (config->path);
g_slice_free (Config, config);
@@ -232,13 +241,13 @@ pacrunner_send_done (GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
self = NM_PACRUNNER_MANAGER (config->manager);
priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
- if (!variant) {
- _LOGD ("send config for '%s' failed: %s", config->tag, error->message);
- } else {
+ if (!variant)
+ _LOG2D (config, "sending failed: %s", error->message);
+ else {
g_variant_get (variant, "(&o)", &path);
config->path = g_strdup (path);
- _LOGD ("successfully sent config for '%s'", config->tag);
+ _LOG2D (config, "sent");
if (config->removed) {
g_dbus_proxy_call (priv->pacrunner,
@@ -260,10 +269,7 @@ pacrunner_send_config (NMPacrunnerManager *self, Config *config)
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
if (priv->pacrunner) {
- gs_free char *args_str = NULL;
-
- _LOGT ("sending proxy config for '%s': %s", config->tag,
- (args_str = g_variant_print (config->args, FALSE)));
+ _LOG2T (config, "sending...");
config_ref (config);
g_clear_pointer (&config->path, g_free);
@@ -280,16 +286,13 @@ pacrunner_send_config (NMPacrunnerManager *self, Config *config)
}
static void
-name_owner_changed (GObject *object,
- GParamSpec *pspec,
- gpointer user_data)
+name_owner_changed (NMPacrunnerManager *self)
{
- NMPacrunnerManager *self = NM_PACRUNNER_MANAGER (user_data);
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
gs_free char *owner = NULL;
GList *iter = NULL;
- owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (object));
+ owner = g_dbus_proxy_get_name_owner (priv->pacrunner);
if (owner) {
_LOGD ("name owner appeared (%s)", owner);
for (iter = g_list_first (priv->configs); iter; iter = g_list_next (iter))
@@ -300,6 +303,14 @@ name_owner_changed (GObject *object,
}
static void
+name_owner_changed_cb (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ name_owner_changed (user_data);
+}
+
+static void
pacrunner_proxy_cb (GObject *source, GAsyncResult *res, gpointer user_data)
{
NMPacrunnerManager *self = user_data;
@@ -321,22 +332,29 @@ pacrunner_proxy_cb (GObject *source, GAsyncResult *res, gpointer user_data)
nm_clear_g_cancellable (&priv->pacrunner_cancellable);
g_signal_connect (priv->pacrunner, "notify::g-name-owner",
- G_CALLBACK (name_owner_changed), self);
+ G_CALLBACK (name_owner_changed_cb), self);
+ name_owner_changed (self);
}
/**
* nm_pacrunner_manager_send:
* @self: the #NMPacrunnerManager
* @iface: the iface for the connection or %NULL
- * @tag: unique configuration identifier
* @proxy_config: proxy config of the connection
* @ip4_config: IP4 config of the connection to extract domain info from
* @ip6_config: IP6 config of the connection to extract domain info from
+ *
+ * Returns: a #NMPacrunnerCallId call id. The function cannot
+ * fail and always returns a non NULL pointer. The call-id may
+ * be used to remove the configuration later via nm_pacrunner_manager_remove().
+ * Note that the call-id does not keep the @self instance alive.
+ * If you plan to remove the configuration later, you must keep
+ * the instance alive long enough. You can remove the configuration
+ * at most once using this call call-id.
*/
-void
+NMPacrunnerCallId *
nm_pacrunner_manager_send (NMPacrunnerManager *self,
const char *iface,
- const char *tag,
NMProxyConfig *proxy_config,
NMIP4Config *ip4_config,
NMIP6Config *ip6_config)
@@ -348,8 +366,8 @@ nm_pacrunner_manager_send (NMPacrunnerManager *self,
GPtrArray *domains;
Config *config;
- g_return_if_fail (NM_IS_PACRUNNER_MANAGER (self));
- g_return_if_fail (proxy_config);
+ g_return_val_if_fail (NM_IS_PACRUNNER_MANAGER (self), NULL);
+ g_return_val_if_fail (proxy_config, NULL);
priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
@@ -401,15 +419,23 @@ nm_pacrunner_manager_send (NMPacrunnerManager *self,
}
}
- config = config_new (self, g_strdup (tag),
- g_variant_new ("(a{sv})", &proxy_data));
+ config = config_new (self, g_variant_new ("(a{sv})", &proxy_data));
priv->configs = g_list_append (priv->configs, config);
+ {
+ gs_free char *args_str = NULL;
+
+ _LOG2D (config, "send: new config %s",
+ (args_str = g_variant_print (config->args, FALSE)));
+ }
+
/* Send if pacrunner is available on bus, otherwise
* config has already been appended above to be
* sent when pacrunner appears.
*/
pacrunner_send_config (self, config);
+
+ return config;
}
static void
@@ -429,9 +455,9 @@ pacrunner_remove_done (GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
self = NM_PACRUNNER_MANAGER (config->manager);
if (!ret)
- _LOGD ("couldn't remove config for '%s': %s", config->tag, error->message);
+ _LOG2D (config, "remove failed: %s", error->message);
else
- _LOGD ("successfully removed config for '%s'", config->tag);
+ _LOG2D (config, "removed");
config_unref (config);
}
@@ -439,49 +465,64 @@ pacrunner_remove_done (GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
/**
* nm_pacrunner_manager_remove:
* @self: the #NMPacrunnerManager
- * @iface: the iface for the connection to be removed
- * from pacrunner
+ * @call_id: the call-id obtained from nm_pacrunner_manager_send()
*/
void
-nm_pacrunner_manager_remove (NMPacrunnerManager *self, const char *tag)
+nm_pacrunner_manager_remove (NMPacrunnerManager *self, NMPacrunnerCallId *call_id)
{
- NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
+ NMPacrunnerManagerPrivate *priv;
+ Config *config;
GList *list;
- g_return_if_fail (tag);
-
- _LOGT ("removing config for '%s'", tag);
-
- for (list = g_list_first (priv->configs); list; list = g_list_next (list)) {
- Config *config = list->data;
-
- if (nm_streq (config->tag, tag)) {
- if (priv->pacrunner) {
- if (!config->path) {
- /* send() failed or is still pending. Mark the item as
- * removed, so that we ask pacrunner to drop it when the
- * send() completes.
- */
- config->removed = TRUE;
- config_unref (config);
- } else {
- g_dbus_proxy_call (priv->pacrunner,
- "DestroyProxyConfiguration",
- g_variant_new ("(o)", config->path),
- G_DBUS_CALL_FLAGS_NO_AUTO_START,
- -1,
- priv->pacrunner_cancellable,
- (GAsyncReadyCallback) pacrunner_remove_done,
- config);
- }
- } else
- config_unref (config);
- priv->configs = g_list_delete_link (priv->configs, list);
- return;
+ g_return_if_fail (NM_IS_PACRUNNER_MANAGER (self));
+ g_return_if_fail (call_id);
+
+ config = call_id;
+ priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
+
+ _LOG2T (config, "removing...");
+
+ list = g_list_find (priv->configs, config);
+ if (!list)
+ g_return_if_reached ();
+
+ if (priv->pacrunner) {
+ if (!config->path) {
+ /* send() failed or is still pending. Mark the item as
+ * removed, so that we ask pacrunner to drop it when the
+ * send() completes.
+ */
+ config->removed = TRUE;
+ config_unref (config);
+ } else {
+ g_dbus_proxy_call (priv->pacrunner,
+ "DestroyProxyConfiguration",
+ g_variant_new ("(o)", config->path),
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ -1,
+ priv->pacrunner_cancellable,
+ (GAsyncReadyCallback) pacrunner_remove_done,
+ config);
}
- }
- /* bug, remove() should always match a previous send() for a given tag */
- g_return_if_reached ();
+ } else
+ config_unref (config);
+ priv->configs = g_list_delete_link (priv->configs, list);
+}
+
+gboolean
+nm_pacrunner_manager_remove_clear (NMPacrunnerManager *self,
+ NMPacrunnerCallId **p_call_id)
+{
+ g_return_val_if_fail (p_call_id, FALSE);
+
+ /* if we have no call-id, allow for %NULL */
+ g_return_val_if_fail ((!self && !*p_call_id) || NM_IS_PACRUNNER_MANAGER (self), FALSE);
+
+ if (!*p_call_id)
+ return FALSE;
+ nm_pacrunner_manager_remove (self,
+ g_steal_pointer (p_call_id));
+ return TRUE;
}
/*****************************************************************************/
diff --git a/src/nm-pacrunner-manager.h b/src/nm-pacrunner-manager.h
index 4f6ad15857..3080c4f5fd 100644
--- a/src/nm-pacrunner-manager.h
+++ b/src/nm-pacrunner-manager.h
@@ -15,7 +15,8 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * (C) Copyright 2016 Atul Anand <atulhjp@gmail.com>.
+ * Copyright 2016 Atul Anand <atulhjp@gmail.com>.
+ * Copyright 2016 - 2017 Red Hat, Inc.
*/
#ifndef __NETWORKMANAGER_PACRUNNER_MANAGER_H__
@@ -30,17 +31,22 @@
typedef struct _NMPacrunnerManagerClass NMPacrunnerManagerClass;
+typedef struct _NMPacrunnerCallId NMPacrunnerCallId;
+
GType nm_pacrunner_manager_get_type (void);
NMPacrunnerManager *nm_pacrunner_manager_get (void);
-void nm_pacrunner_manager_send (NMPacrunnerManager *self,
- const char *iface,
- const char *tag,
- NMProxyConfig *proxy_config,
- NMIP4Config *ip4_config,
- NMIP6Config *ip6_config);
+NMPacrunnerCallId *nm_pacrunner_manager_send (NMPacrunnerManager *self,
+ const char *iface,
+ NMProxyConfig *proxy_config,
+ NMIP4Config *ip4_config,
+ NMIP6Config *ip6_config);
+
+void nm_pacrunner_manager_remove (NMPacrunnerManager *self,
+ NMPacrunnerCallId *call_id);
-void nm_pacrunner_manager_remove (NMPacrunnerManager *self, const char *tag);
+gboolean nm_pacrunner_manager_remove_clear (NMPacrunnerManager *self,
+ NMPacrunnerCallId **p_call_id);
#endif /* __NETWORKMANAGER_PACRUNNER_MANAGER_H__ */
diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c
index dba3546ff0..ecc820685c 100644
--- a/src/vpn/nm-vpn-connection.c
+++ b/src/vpn/nm-vpn-connection.c
@@ -128,7 +128,8 @@ typedef struct {
GVariant *connect_hash;
guint connect_timeout;
NMProxyConfig *proxy_config;
- gboolean proxy_config_sent;
+ NMPacrunnerManager *pacrunner_manager;
+ NMPacrunnerCallId *pacrunner_call_id;
gboolean has_ip4;
NMIP4Config *ip4_config;
guint32 ip4_internal_gw;
@@ -559,13 +560,18 @@ _set_vpn_state (NMVpnConnection *self,
NULL);
if (priv->proxy_config) {
- nm_pacrunner_manager_send (nm_pacrunner_manager_get (),
- priv->ip_iface,
- nm_connection_get_uuid (applied),
- priv->proxy_config,
- priv->ip4_config,
- priv->ip6_config);
- priv->proxy_config_sent = TRUE;
+ nm_pacrunner_manager_remove_clear (priv->pacrunner_manager,
+ &priv->pacrunner_call_id);
+ if (!priv->pacrunner_manager) {
+ /* the pending call doesn't keep NMPacrunnerManager alive.
+ * Take a reference to it. */
+ priv->pacrunner_manager = g_object_ref (nm_pacrunner_manager_get ());
+ }
+ priv->pacrunner_call_id = nm_pacrunner_manager_send (priv->pacrunner_manager,
+ priv->ip_iface,
+ priv->proxy_config,
+ priv->ip4_config,
+ priv->ip6_config);
}
break;
case STATE_DEACTIVATING:
@@ -596,11 +602,8 @@ _set_vpn_state (NMVpnConnection *self,
}
}
- if (priv->proxy_config_sent) {
- nm_pacrunner_manager_remove (nm_pacrunner_manager_get(),
- nm_connection_get_uuid (applied));
- priv->proxy_config_sent = FALSE;
- }
+ nm_pacrunner_manager_remove_clear (priv->pacrunner_manager,
+ &priv->pacrunner_call_id);
break;
case STATE_FAILED:
case STATE_DISCONNECTED:
@@ -2649,6 +2652,10 @@ dispose (GObject *object)
fw_call_cleanup (self);
+ nm_pacrunner_manager_remove_clear (priv->pacrunner_manager,
+ &priv->pacrunner_call_id);
+ g_clear_object (&priv->pacrunner_manager);
+
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object);
}