mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-04 04:00:17 +01:00
pacrunner: refactor pacrunner to use GDBusConnection
- use GDBusConnection instead of GDBusProxy.
- rename "call-id" to "conf-id". It's really not a "call" but
configuration that gets added and NMPacrunnerManager ensures that
the configuration is send to pacrunner.
- let "conf-id" keep a reference to NMPacrunnerManager. For one,
when we remove configurations we need to call DestroyProxyConfiguration
to remove it again. We cannot just abort the requests but must linger
around until our configuration is properly cleaned up. Hence, we
anyway cannot destroy the NMPacrunnerManager earlier.
With respect to fixing shutdown not to leak anything, this merely
means that we must wait (and iterate the main loop) as long as
NMPacrunnerManager singleton still exits (that is anyway the plan
how to fix shutdown).
With these considerations it's also clear that our D-Bus calls must
have a stricter timeout: NM_SHUTDOWN_TIMEOUT_MS.
This is also nice because nm_pacrunner_manager_remove() no longer
needs a manager parameter, it can just rely on having a reference
to the manager.
- for logging the configuration IDs, don't log pointer values.
Logging pointer values should be avoided as it defeats ASLR.
Instead, give them a "log_id" number.
- pacrunner is a D-Bus activatable service. D-Bus activatable services
needs special care. We don't want to start it over and over again.
Instead, we only try to "StartServiceByName" if
- we have any configuration to add
- if pacrunner is currently confirmed not to be running (by watching
name owner changes)
- we didn't try to start it already. That means, only start it
at the beginning and afterwards set a flag to block it. When
we see pacrunner appear on D-Bus we always clear that flag,
that means if pacrunner drops of, we will try to restart it
(once).
This commit is contained in:
parent
cbdb498197
commit
83476a3fb6
5 changed files with 477 additions and 441 deletions
|
|
@ -78,7 +78,7 @@ NMPlatformRoutingRule *nm_ip_routing_rule_to_platform (const NMIPRoutingRule *ru
|
|||
* SIGKILL.
|
||||
*
|
||||
* After NM_SHUTDOWN_TIMEOUT_MS, NetworkManager will however not yet terminate right
|
||||
* away. It iterates the mainloop for another NM_SHUTDOWN_TIMEOUT_MS_EXTRA. This
|
||||
* away. It iterates the mainloop for another NM_SHUTDOWN_TIMEOUT_MS_WATCHDOG. This
|
||||
* should give time to reap the child process (after SIGKILL).
|
||||
*
|
||||
* So, the maximum time we should wait before sending SIGKILL should be at most
|
||||
|
|
|
|||
|
|
@ -397,8 +397,7 @@ typedef struct _NMDevicePrivate {
|
|||
|
||||
/* Proxy Configuration */
|
||||
NMProxyConfig *proxy_config;
|
||||
NMPacrunnerManager *pacrunner_manager;
|
||||
NMPacrunnerCallId *pacrunner_call_id;
|
||||
NMPacrunnerConfId *pacrunner_conf_id;
|
||||
|
||||
/* IP configuration info. Combined config from VPN, settings, and device */
|
||||
union {
|
||||
|
|
@ -11128,21 +11127,17 @@ nm_device_reactivate_ip6_config (NMDevice *self,
|
|||
}
|
||||
|
||||
static void
|
||||
_pacrunner_manager_send (NMDevice *self)
|
||||
_pacrunner_manager_add (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
nm_pacrunner_manager_remove_clear (priv->pacrunner_manager,
|
||||
&priv->pacrunner_call_id);
|
||||
nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id);
|
||||
|
||||
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);
|
||||
priv->pacrunner_conf_id = nm_pacrunner_manager_add (nm_pacrunner_manager_get (),
|
||||
priv->proxy_config,
|
||||
nm_device_get_ip_iface (self),
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -11150,10 +11145,10 @@ reactivate_proxy_config (NMDevice *self)
|
|||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if (!priv->pacrunner_call_id)
|
||||
if (!priv->pacrunner_conf_id)
|
||||
return;
|
||||
nm_device_set_proxy_config (self, priv->dhcp4.pac_url);
|
||||
_pacrunner_manager_send (self);
|
||||
_pacrunner_manager_add (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -15081,8 +15076,7 @@ _set_state_full (NMDevice *self,
|
|||
}
|
||||
}
|
||||
|
||||
nm_pacrunner_manager_remove_clear (priv->pacrunner_manager,
|
||||
&priv->pacrunner_call_id);
|
||||
nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id);
|
||||
break;
|
||||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
if ( priv->queued_act_request
|
||||
|
|
@ -15102,7 +15096,7 @@ _set_state_full (NMDevice *self,
|
|||
NULL, NULL, NULL);
|
||||
|
||||
if (priv->proxy_config)
|
||||
_pacrunner_manager_send (self);
|
||||
_pacrunner_manager_add (self);
|
||||
break;
|
||||
case NM_DEVICE_STATE_FAILED:
|
||||
/* Usually upon failure the activation chain is interrupted in
|
||||
|
|
@ -16345,9 +16339,7 @@ dispose (GObject *object)
|
|||
|
||||
dispatcher_cleanup (self);
|
||||
|
||||
nm_pacrunner_manager_remove_clear (priv->pacrunner_manager,
|
||||
&priv->pacrunner_call_id);
|
||||
g_clear_object (&priv->pacrunner_manager);
|
||||
nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id);
|
||||
|
||||
_cleanup_generic_pre (self, CLEANUP_TYPE_KEEP);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,14 @@
|
|||
#include "nm-pacrunner-manager.h"
|
||||
|
||||
#include "nm-utils.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "platform/nm-platform.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-proxy-config.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "nm-ip6-config.h"
|
||||
#include "c-list/src/c-list.h"
|
||||
#include "nm-glib-aux/nm-dbus-aux.h"
|
||||
|
||||
#define PACRUNNER_DBUS_SERVICE "org.pacrunner"
|
||||
#define PACRUNNER_DBUS_INTERFACE "org.pacrunner.Manager"
|
||||
|
|
@ -35,25 +38,27 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct _NMPacrunnerCallId {
|
||||
CList lst;
|
||||
struct _NMPacrunnerConfId {
|
||||
CList conf_id_lst;
|
||||
|
||||
/* this might be a dangling pointer after the async operation
|
||||
* is cancelled. */
|
||||
NMPacrunnerManager *manager_maybe_dangling;
|
||||
NMPacrunnerManager *self;
|
||||
|
||||
GVariant *parameters;
|
||||
|
||||
GVariant *args;
|
||||
char *path;
|
||||
guint64 log_id;
|
||||
guint refcount;
|
||||
};
|
||||
|
||||
typedef struct _NMPacrunnerCallId Config;
|
||||
|
||||
typedef struct {
|
||||
char *iface;
|
||||
GDBusProxy *pacrunner;
|
||||
GDBusConnection *dbus_connection;
|
||||
GCancellable *cancellable;
|
||||
CList configs;
|
||||
CList conf_id_lst_head;
|
||||
guint64 log_id_counter;
|
||||
guint name_owner_changed_id;
|
||||
bool dbus_initied:1;
|
||||
bool has_name_owner:1;
|
||||
bool try_start_blocked:1;
|
||||
} NMPacrunnerManagerPrivate;
|
||||
|
||||
struct _NMPacrunnerManager {
|
||||
|
|
@ -79,332 +84,139 @@ NM_DEFINE_SINGLETON_GETTER (NMPacrunnerManager, nm_pacrunner_manager_get, NM_TYP
|
|||
#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "pacrunner", __VA_ARGS__)
|
||||
|
||||
#define _NMLOG2_PREFIX_NAME "pacrunner"
|
||||
#define _NMLOG2(level, config, ...) \
|
||||
#define _NMLOG2(level, conf_id, ...) \
|
||||
G_STMT_START { \
|
||||
nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \
|
||||
"%s%p]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
||||
"%s%"G_GUINT64_FORMAT"]: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
|
||||
_NMLOG2_PREFIX_NAME": call[", \
|
||||
(config) \
|
||||
_NM_UTILS_MACRO_REST(__VA_ARGS__)); \
|
||||
(conf_id)->log_id \
|
||||
_NM_UTILS_MACRO_REST (__VA_ARGS__)); \
|
||||
} G_STMT_END
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void pacrunner_remove_done (GObject *source, GAsyncResult *res, gpointer user_data);
|
||||
static void _call_destroy_proxy_configuration (NMPacrunnerManager *self,
|
||||
NMPacrunnerConfId *conf_id,
|
||||
const char *path,
|
||||
gboolean verbose_log);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static Config *
|
||||
config_new (NMPacrunnerManager *manager, GVariant *args)
|
||||
static NMPacrunnerConfId *
|
||||
conf_id_ref (NMPacrunnerConfId *conf_id)
|
||||
{
|
||||
Config *config;
|
||||
nm_assert (conf_id);
|
||||
nm_assert (conf_id->refcount > 0);
|
||||
|
||||
config = g_slice_new0 (Config);
|
||||
config->manager_maybe_dangling = manager;
|
||||
config->args = g_variant_ref_sink (args);
|
||||
config->refcount = 1;
|
||||
c_list_link_tail (&NM_PACRUNNER_MANAGER_GET_PRIVATE (manager)->configs,
|
||||
&config->lst);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
static Config *
|
||||
config_ref (Config *config)
|
||||
{
|
||||
nm_assert (config);
|
||||
nm_assert (config->refcount > 0);
|
||||
|
||||
config->refcount++;
|
||||
return config;
|
||||
conf_id->refcount++;
|
||||
return conf_id;
|
||||
}
|
||||
|
||||
static void
|
||||
config_unref (Config *config)
|
||||
conf_id_unref (NMPacrunnerConfId *conf_id)
|
||||
{
|
||||
nm_assert (config);
|
||||
nm_assert (config->refcount > 0);
|
||||
nm_assert (conf_id);
|
||||
nm_assert (conf_id->refcount > 0);
|
||||
|
||||
if (config->refcount == 1) {
|
||||
g_variant_unref (config->args);
|
||||
g_free (config->path);
|
||||
c_list_unlink_stale (&config->lst);
|
||||
g_slice_free (Config, config);
|
||||
if (conf_id->refcount == 1) {
|
||||
g_variant_unref (conf_id->parameters);
|
||||
g_free (conf_id->path);
|
||||
c_list_unlink_stale (&conf_id->conf_id_lst);
|
||||
g_object_unref (conf_id->self);
|
||||
g_slice_free (NMPacrunnerConfId, conf_id);
|
||||
} else
|
||||
config->refcount--;
|
||||
conf_id->refcount--;
|
||||
}
|
||||
|
||||
NM_AUTO_DEFINE_FCN0 (NMPacrunnerConfId *, _nm_auto_unref_conf_id, conf_id_unref);
|
||||
#define nm_auto_unref_conf_id nm_auto (_nm_auto_unref_conf_id)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
add_proxy_config (GVariantBuilder *proxy_data, const NMProxyConfig *proxy_config)
|
||||
{
|
||||
const char *pac_url, *pac_script;
|
||||
NMProxyConfigMethod method;
|
||||
|
||||
method = nm_proxy_config_get_method (proxy_config);
|
||||
|
||||
if (method == NM_PROXY_CONFIG_METHOD_AUTO) {
|
||||
pac_url = nm_proxy_config_get_pac_url (proxy_config);
|
||||
if (pac_url) {
|
||||
g_variant_builder_add (proxy_data, "{sv}",
|
||||
"URL",
|
||||
g_variant_new_string (pac_url));
|
||||
}
|
||||
|
||||
pac_script = nm_proxy_config_get_pac_script (proxy_config);
|
||||
if (pac_script) {
|
||||
g_variant_builder_add (proxy_data, "{sv}",
|
||||
"Script",
|
||||
g_variant_new_string (pac_script));
|
||||
}
|
||||
}
|
||||
|
||||
g_variant_builder_add (proxy_data, "{sv}",
|
||||
"BrowserOnly",
|
||||
g_variant_new_boolean (nm_proxy_config_get_browser_only (proxy_config)));
|
||||
}
|
||||
|
||||
static void
|
||||
get_ip4_domains (GPtrArray *domains, NMIP4Config *ip4)
|
||||
get_ip_domains (GPtrArray *domains, NMIPConfig *ip_config)
|
||||
{
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
char *cidr;
|
||||
const NMPlatformIP4Address *address;
|
||||
const NMPlatformIP4Route *routes;
|
||||
guint i;
|
||||
guint i, num;
|
||||
char sbuf[NM_UTILS_INET_ADDRSTRLEN];
|
||||
int addr_family;
|
||||
|
||||
/* Extract searches */
|
||||
for (i = 0; i < nm_ip4_config_get_num_searches (ip4); i++)
|
||||
g_ptr_array_add (domains, g_strdup (nm_ip4_config_get_search (ip4, i)));
|
||||
|
||||
/* Extract domains */
|
||||
for (i = 0; i < nm_ip4_config_get_num_domains (ip4); i++)
|
||||
g_ptr_array_add (domains, g_strdup (nm_ip4_config_get_domain (ip4, i)));
|
||||
|
||||
/* Add addresses and routes in CIDR form */
|
||||
|
||||
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &address) {
|
||||
cidr = g_strdup_printf ("%s/%u",
|
||||
nm_utils_inet4_ntop (address->address, sbuf),
|
||||
address->plen);
|
||||
g_ptr_array_add (domains, cidr);
|
||||
}
|
||||
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &routes) {
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (routes))
|
||||
continue;
|
||||
cidr = g_strdup_printf ("%s/%u",
|
||||
nm_utils_inet4_ntop (routes->network, sbuf),
|
||||
routes->plen);
|
||||
g_ptr_array_add (domains, cidr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_ip6_domains (GPtrArray *domains, NMIP6Config *ip6)
|
||||
{
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
char *cidr;
|
||||
const NMPlatformIP6Address *address;
|
||||
const NMPlatformIP6Route *routes;
|
||||
guint i;
|
||||
char sbuf[NM_UTILS_INET_ADDRSTRLEN];
|
||||
|
||||
/* Extract searches */
|
||||
for (i = 0; i < nm_ip6_config_get_num_searches (ip6); i++)
|
||||
g_ptr_array_add (domains, g_strdup (nm_ip6_config_get_search (ip6, i)));
|
||||
|
||||
/* Extract domains */
|
||||
for (i = 0; i < nm_ip6_config_get_num_domains (ip6); i++)
|
||||
g_ptr_array_add (domains, g_strdup (nm_ip6_config_get_domain (ip6, i)));
|
||||
|
||||
/* Add addresses and routes in CIDR form */
|
||||
nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &address) {
|
||||
cidr = g_strdup_printf ("%s/%u",
|
||||
nm_utils_inet6_ntop (&address->address, sbuf),
|
||||
address->plen);
|
||||
g_ptr_array_add (domains, cidr);
|
||||
}
|
||||
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &routes) {
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (routes))
|
||||
continue;
|
||||
cidr = g_strdup_printf ("%s/%u",
|
||||
nm_utils_inet6_ntop (&routes->network, sbuf),
|
||||
routes->plen);
|
||||
g_ptr_array_add (domains, cidr);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static GCancellable *
|
||||
_ensure_cancellable (NMPacrunnerManagerPrivate *priv)
|
||||
{
|
||||
if (G_UNLIKELY (!priv->cancellable))
|
||||
priv->cancellable = g_cancellable_new ();
|
||||
return priv->cancellable;
|
||||
}
|
||||
|
||||
static void
|
||||
pacrunner_send_done (GObject *source, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
Config *config = user_data;
|
||||
NMPacrunnerManager *self;
|
||||
NMPacrunnerManagerPrivate *priv;
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_unref_variant GVariant *variant = NULL;
|
||||
const char *path = NULL;
|
||||
|
||||
nm_assert (!config->path);
|
||||
|
||||
variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
goto out;
|
||||
|
||||
self = NM_PACRUNNER_MANAGER (config->manager_maybe_dangling);
|
||||
priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
if (!variant)
|
||||
_LOG2D (config, "sending failed: %s", error->message);
|
||||
else {
|
||||
g_variant_get (variant, "(&o)", &path);
|
||||
|
||||
if (c_list_is_empty (&config->lst)) {
|
||||
_LOG2D (config, "sent (%s), but destroy it right away", path);
|
||||
g_dbus_proxy_call (priv->pacrunner,
|
||||
"DestroyProxyConfiguration",
|
||||
g_variant_new ("(o)", path),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
-1,
|
||||
_ensure_cancellable (priv),
|
||||
pacrunner_remove_done,
|
||||
config_ref (config));
|
||||
} else {
|
||||
_LOG2D (config, "sent (%s)", path);
|
||||
config->path = g_strdup (path);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
config_unref (config);
|
||||
}
|
||||
|
||||
static void
|
||||
pacrunner_send_config (NMPacrunnerManager *self, Config *config)
|
||||
{
|
||||
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
if (priv->pacrunner) {
|
||||
_LOG2T (config, "sending...");
|
||||
|
||||
nm_assert (!config->path);
|
||||
g_dbus_proxy_call (priv->pacrunner,
|
||||
"CreateProxyConfiguration",
|
||||
config->args,
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
-1,
|
||||
_ensure_cancellable (priv),
|
||||
pacrunner_send_done,
|
||||
config_ref (config));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
name_owner_changed (NMPacrunnerManager *self)
|
||||
{
|
||||
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
|
||||
gs_free char *owner = NULL;
|
||||
CList *iter;
|
||||
|
||||
owner = g_dbus_proxy_get_name_owner (priv->pacrunner);
|
||||
if (owner) {
|
||||
_LOGD ("name owner appeared (%s)", owner);
|
||||
c_list_for_each (iter, &priv->configs)
|
||||
pacrunner_send_config (self, c_list_entry (iter, Config, lst));
|
||||
} else {
|
||||
_LOGD ("name owner disappeared");
|
||||
nm_clear_g_cancellable (&priv->cancellable);
|
||||
c_list_for_each (iter, &priv->configs)
|
||||
nm_clear_g_free (&c_list_entry (iter, Config, lst)->path);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
NMPacrunnerManagerPrivate *priv;
|
||||
gs_free_error GError *error = NULL;
|
||||
GDBusProxy *proxy;
|
||||
|
||||
proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
||||
if (!proxy) {
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
_LOGE ("failed to create D-Bus proxy for pacrunner: %s", error->message);
|
||||
if (!ip_config)
|
||||
return;
|
||||
|
||||
addr_family = nm_ip_config_get_addr_family (ip_config);
|
||||
|
||||
num = nm_ip_config_get_num_searches (ip_config);
|
||||
for (i = 0; i < num; i++)
|
||||
g_ptr_array_add (domains, g_strdup (nm_ip_config_get_search (ip_config, i)));
|
||||
|
||||
num = nm_ip_config_get_num_domains (ip_config);
|
||||
for (i = 0; i < num; i++)
|
||||
g_ptr_array_add (domains, g_strdup (nm_ip_config_get_domain (ip_config, i)));
|
||||
|
||||
if (addr_family == AF_INET) {
|
||||
const NMPlatformIP4Address *address;
|
||||
|
||||
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, (NMIP4Config *) ip_config, &address) {
|
||||
cidr = g_strdup_printf ("%s/%u",
|
||||
nm_utils_inet4_ntop (address->address, sbuf),
|
||||
address->plen);
|
||||
g_ptr_array_add (domains, cidr);
|
||||
}
|
||||
} else {
|
||||
const NMPlatformIP6Address *address;
|
||||
|
||||
nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, (NMIP6Config *) ip_config, &address) {
|
||||
cidr = g_strdup_printf ("%s/%u",
|
||||
nm_utils_inet6_ntop (&address->address, sbuf),
|
||||
address->plen);
|
||||
g_ptr_array_add (domains, cidr);
|
||||
}
|
||||
}
|
||||
|
||||
priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
|
||||
if (addr_family == AF_INET) {
|
||||
const NMPlatformIP4Route *routes;
|
||||
|
||||
priv->pacrunner = proxy;
|
||||
g_signal_connect (priv->pacrunner, "notify::g-name-owner",
|
||||
G_CALLBACK (name_owner_changed_cb), self);
|
||||
name_owner_changed (self);
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, (NMIP4Config *) ip_config, &routes) {
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (routes))
|
||||
continue;
|
||||
cidr = g_strdup_printf ("%s/%u",
|
||||
nm_utils_inet4_ntop (routes->network, sbuf),
|
||||
routes->plen);
|
||||
g_ptr_array_add (domains, cidr);
|
||||
}
|
||||
} else {
|
||||
const NMPlatformIP6Route *routes;
|
||||
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, (NMIP6Config *) ip_config, &routes) {
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (routes))
|
||||
continue;
|
||||
cidr = g_strdup_printf ("%s/%u",
|
||||
nm_utils_inet6_ntop (&routes->network, sbuf),
|
||||
routes->plen);
|
||||
g_ptr_array_add (domains, cidr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_pacrunner_manager_send:
|
||||
* @self: the #NMPacrunnerManager
|
||||
* @iface: the iface for the connection or %NULL
|
||||
* @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.
|
||||
*/
|
||||
NMPacrunnerCallId *
|
||||
nm_pacrunner_manager_send (NMPacrunnerManager *self,
|
||||
const char *iface,
|
||||
NMProxyConfig *proxy_config,
|
||||
NMIP4Config *ip4_config,
|
||||
NMIP6Config *ip6_config)
|
||||
static GVariant *
|
||||
_make_request_create_proxy_configuration (NMProxyConfig *proxy_config,
|
||||
const char *iface,
|
||||
NMIP4Config *ip4_config,
|
||||
NMIP6Config *ip6_config)
|
||||
{
|
||||
char **strv = NULL;
|
||||
GVariantBuilder builder;
|
||||
NMProxyConfigMethod method;
|
||||
NMPacrunnerManagerPrivate *priv;
|
||||
GVariantBuilder proxy_data;
|
||||
GPtrArray *domains;
|
||||
Config *config;
|
||||
const char *pac_url;
|
||||
const char *pac_script;
|
||||
|
||||
g_return_val_if_fail (NM_IS_PACRUNNER_MANAGER (self), NULL);
|
||||
g_return_val_if_fail (proxy_config, NULL);
|
||||
nm_assert (NM_IS_PROXY_CONFIG (proxy_config));
|
||||
|
||||
priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
g_free (priv->iface);
|
||||
priv->iface = g_strdup (iface);
|
||||
|
||||
g_variant_builder_init (&proxy_data, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
||||
|
||||
if (iface) {
|
||||
g_variant_builder_add (&proxy_data, "{sv}",
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
"Interface",
|
||||
g_variant_new_string (iface));
|
||||
}
|
||||
|
|
@ -412,167 +224,410 @@ nm_pacrunner_manager_send (NMPacrunnerManager *self,
|
|||
method = nm_proxy_config_get_method (proxy_config);
|
||||
switch (method) {
|
||||
case NM_PROXY_CONFIG_METHOD_AUTO:
|
||||
g_variant_builder_add (&proxy_data, "{sv}",
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
"Method",
|
||||
g_variant_new_string ("auto"));
|
||||
|
||||
pac_url = nm_proxy_config_get_pac_url (proxy_config);
|
||||
if (pac_url) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
"URL",
|
||||
g_variant_new_string (pac_url));
|
||||
}
|
||||
|
||||
pac_script = nm_proxy_config_get_pac_script (proxy_config);
|
||||
if (pac_script) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
"Script",
|
||||
g_variant_new_string (pac_script));
|
||||
}
|
||||
break;
|
||||
case NM_PROXY_CONFIG_METHOD_NONE:
|
||||
g_variant_builder_add (&proxy_data, "{sv}",
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
"Method",
|
||||
g_variant_new_string ("direct"));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Extract stuff from configs */
|
||||
add_proxy_config (&proxy_data, proxy_config);
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
"BrowserOnly",
|
||||
g_variant_new_boolean (nm_proxy_config_get_browser_only (proxy_config)));
|
||||
|
||||
if (ip4_config || ip6_config) {
|
||||
gs_unref_ptrarray GPtrArray *domains = NULL;
|
||||
|
||||
domains = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
if (ip4_config)
|
||||
get_ip4_domains (domains, ip4_config);
|
||||
if (ip6_config)
|
||||
get_ip6_domains (domains, ip6_config);
|
||||
get_ip_domains (domains, NM_IP_CONFIG_CAST (ip4_config));
|
||||
get_ip_domains (domains, NM_IP_CONFIG_CAST (ip6_config));
|
||||
|
||||
g_ptr_array_add (domains, NULL);
|
||||
strv = (char **) g_ptr_array_free (domains, (domains->len == 1));
|
||||
|
||||
if (strv) {
|
||||
g_variant_builder_add (&proxy_data, "{sv}",
|
||||
if (domains->len > 0) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
"Domains",
|
||||
g_variant_new_strv ((const char *const *) strv, -1));
|
||||
g_strfreev (strv);
|
||||
g_variant_new_strv ((const char *const*) domains->pdata,
|
||||
domains->len));
|
||||
}
|
||||
}
|
||||
|
||||
config = config_new (self, g_variant_new ("(a{sv})", &proxy_data));
|
||||
|
||||
{
|
||||
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;
|
||||
return g_variant_new ("(a{sv})", &builder);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
pacrunner_remove_done (GObject *source, GAsyncResult *res, gpointer user_data)
|
||||
_call_destroy_proxy_configuration_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
Config *config = user_data;
|
||||
nm_auto_unref_conf_id NMPacrunnerConfId *conf_id = user_data;
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_unref_variant GVariant *ret = NULL;
|
||||
|
||||
ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error);
|
||||
ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), res, &error);
|
||||
if (!ret) {
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
goto out;
|
||||
_LOG2D (config, "remove failed: %s", error->message);
|
||||
goto out;
|
||||
_LOG2T (conf_id, "destroy proxy configuration: failed with %s", error->message);
|
||||
else
|
||||
_LOG2T (conf_id, "destroy proxy configuration: cancelled");
|
||||
return;
|
||||
}
|
||||
_LOG2T (conf_id, "destroy proxy configuration: success");
|
||||
}
|
||||
|
||||
static void
|
||||
_call_create_proxy_configuration_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
nm_auto_unref_conf_id NMPacrunnerConfId *conf_id = user_data;
|
||||
NMPacrunnerManager *self = NM_PACRUNNER_MANAGER (conf_id->self);
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_unref_variant GVariant *variant = NULL;
|
||||
const char *path = NULL;
|
||||
|
||||
nm_assert (!conf_id->path);
|
||||
|
||||
variant = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), res, &error);
|
||||
|
||||
if (!variant) {
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
_LOG2T (conf_id, "create proxy configuration failed: %s", error->message);
|
||||
else
|
||||
_LOG2T (conf_id, "create proxy configuration cancelled");
|
||||
return;
|
||||
}
|
||||
|
||||
_LOG2D (config, "removed");
|
||||
g_variant_get (variant, "(&o)", &path);
|
||||
|
||||
out:
|
||||
config_unref (config);
|
||||
if (c_list_is_empty (&conf_id->conf_id_lst)) {
|
||||
_LOG2T (conf_id, "create proxy configuration succeeded (%s), but destroy it right away", path);
|
||||
_call_destroy_proxy_configuration (self,
|
||||
conf_id,
|
||||
path,
|
||||
FALSE);
|
||||
} else {
|
||||
_LOG2T (conf_id, "create proxy configuration succeeded (%s)", path);
|
||||
conf_id->path = g_strdup (path);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_call_destroy_proxy_configuration (NMPacrunnerManager *self,
|
||||
NMPacrunnerConfId *conf_id,
|
||||
const char *path,
|
||||
gboolean verbose_log)
|
||||
{
|
||||
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
if (verbose_log)
|
||||
_LOG2T (conf_id, "destroy proxy configuration %s...", path);
|
||||
|
||||
g_dbus_connection_call (priv->dbus_connection,
|
||||
PACRUNNER_DBUS_SERVICE,
|
||||
PACRUNNER_DBUS_PATH,
|
||||
PACRUNNER_DBUS_INTERFACE,
|
||||
"DestroyProxyConfiguration",
|
||||
g_variant_new ("(o)", path),
|
||||
G_VARIANT_TYPE ("()"),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
NM_SHUTDOWN_TIMEOUT_MS,
|
||||
priv->cancellable,
|
||||
_call_destroy_proxy_configuration_cb,
|
||||
conf_id_ref (conf_id));
|
||||
}
|
||||
|
||||
static void
|
||||
_call_create_proxy_configuration (NMPacrunnerManager *self,
|
||||
NMPacrunnerConfId *conf_id,
|
||||
gboolean verbose_log)
|
||||
{
|
||||
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
if (verbose_log)
|
||||
_LOG2T (conf_id, "create proxy configuration...");
|
||||
|
||||
g_dbus_connection_call (priv->dbus_connection,
|
||||
PACRUNNER_DBUS_SERVICE,
|
||||
PACRUNNER_DBUS_PATH,
|
||||
PACRUNNER_DBUS_INTERFACE,
|
||||
"CreateProxyConfiguration",
|
||||
conf_id->parameters,
|
||||
G_VARIANT_TYPE ("(o)"),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
NM_SHUTDOWN_TIMEOUT_MS,
|
||||
priv->cancellable,
|
||||
_call_create_proxy_configuration_cb,
|
||||
conf_id_ref (conf_id));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_try_start_service_by_name (NMPacrunnerManager *self)
|
||||
{
|
||||
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
if ( priv->try_start_blocked
|
||||
|| !priv->dbus_initied)
|
||||
return FALSE;
|
||||
|
||||
_LOGD ("try D-Bus activating pacrunner...");
|
||||
priv->try_start_blocked = TRUE;
|
||||
nm_dbus_connection_call_start_service_by_name (priv->dbus_connection,
|
||||
PACRUNNER_DBUS_SERVICE,
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_pacrunner_manager_add:
|
||||
* @self: the #NMPacrunnerManager
|
||||
* @proxy_config: proxy config of the connection
|
||||
* @iface: the iface for the connection or %NULL
|
||||
* @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 #NMPacrunnerConfId id. The function cannot
|
||||
* fail and always returns a non NULL pointer. The conf-id may
|
||||
* be used to remove the configuration later via nm_pacrunner_manager_remove().
|
||||
* Note that the conf-id keeps the @self instance alive.
|
||||
*/
|
||||
NMPacrunnerConfId *
|
||||
nm_pacrunner_manager_add (NMPacrunnerManager *self,
|
||||
NMProxyConfig *proxy_config,
|
||||
const char *iface,
|
||||
NMIP4Config *ip4_config,
|
||||
NMIP6Config *ip6_config)
|
||||
{
|
||||
NMPacrunnerManagerPrivate *priv;
|
||||
NMPacrunnerConfId *conf_id;
|
||||
gs_free char *log_msg = NULL;
|
||||
|
||||
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);
|
||||
|
||||
conf_id = g_slice_new (NMPacrunnerConfId);
|
||||
*conf_id = (NMPacrunnerConfId) {
|
||||
.log_id = ++priv->log_id_counter,
|
||||
.refcount = 1,
|
||||
.self = g_object_ref (self),
|
||||
.parameters = g_variant_ref_sink (_make_request_create_proxy_configuration (proxy_config,
|
||||
iface,
|
||||
ip4_config,
|
||||
ip6_config)),
|
||||
};
|
||||
c_list_link_tail (&priv->conf_id_lst_head,
|
||||
&conf_id->conf_id_lst);
|
||||
|
||||
if (!priv->has_name_owner) {
|
||||
_LOG2T (conf_id, "add config: %s (%s)",
|
||||
(log_msg = g_variant_print (conf_id->parameters, FALSE)),
|
||||
"pacrunner D-Bus service not running");
|
||||
_try_start_service_by_name (self);
|
||||
} else {
|
||||
_LOG2T (conf_id, "add config: %s (%s)",
|
||||
(log_msg = g_variant_print (conf_id->parameters, FALSE)),
|
||||
"create proxy configuration");
|
||||
_call_create_proxy_configuration (self, conf_id, FALSE);
|
||||
}
|
||||
|
||||
return conf_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_pacrunner_manager_remove:
|
||||
* @self: the #NMPacrunnerManager
|
||||
* @call_id: the call-id obtained from nm_pacrunner_manager_send()
|
||||
* @conf_id: the conf id obtained from nm_pacrunner_manager_add()
|
||||
*/
|
||||
void
|
||||
nm_pacrunner_manager_remove (NMPacrunnerManager *self, NMPacrunnerCallId *call_id)
|
||||
nm_pacrunner_manager_remove (NMPacrunnerConfId *conf_id)
|
||||
{
|
||||
_nm_unused nm_auto_unref_conf_id NMPacrunnerConfId *conf_id_free = conf_id;
|
||||
NMPacrunnerManager *self;
|
||||
NMPacrunnerManagerPrivate *priv;
|
||||
Config *config;
|
||||
|
||||
g_return_if_fail (conf_id);
|
||||
|
||||
self = conf_id->self;
|
||||
|
||||
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...");
|
||||
_LOG2T (conf_id, "removing...");
|
||||
|
||||
nm_assert (c_list_contains (&priv->configs, &config->lst));
|
||||
nm_assert (c_list_contains (&priv->conf_id_lst_head, &conf_id->conf_id_lst));
|
||||
|
||||
if (priv->pacrunner) {
|
||||
if (!config->path) {
|
||||
/* send() failed or is still pending. The item is unlinked from
|
||||
* priv->configs, so pacrunner_send_done() knows to call
|
||||
* DestroyProxyConfiguration right away.
|
||||
*/
|
||||
} else {
|
||||
g_dbus_proxy_call (priv->pacrunner,
|
||||
"DestroyProxyConfiguration",
|
||||
g_variant_new ("(o)", config->path),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
-1,
|
||||
_ensure_cancellable (priv),
|
||||
pacrunner_remove_done,
|
||||
config_ref (config));
|
||||
nm_clear_g_free (&config->path);
|
||||
}
|
||||
c_list_unlink (&conf_id->conf_id_lst);
|
||||
|
||||
if (!conf_id->path) {
|
||||
/* There is no ID to destroy the configuration.
|
||||
*
|
||||
* That can happen because:
|
||||
*
|
||||
* - pacrunner D-Bus service is not running (no name owner) and we didn't call CreateProxyConfiguration.
|
||||
* - CreateProxyConfiguration failed.
|
||||
* - CreateProxyConfiguration is in progress.
|
||||
*
|
||||
* In all cases there is nothing to do. Note that if CreateProxyConfiguration is in progress
|
||||
* it has a reference on the conf-id and it will automatically destroy the configuration
|
||||
* when it completes.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
c_list_unlink (&config->lst);
|
||||
config_unref (config);
|
||||
_call_destroy_proxy_configuration (self, conf_id, conf_id->path, TRUE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_pacrunner_manager_remove_clear (NMPacrunnerManager *self,
|
||||
NMPacrunnerCallId **p_call_id)
|
||||
nm_pacrunner_manager_remove_clear (NMPacrunnerConfId **p_conf_id)
|
||||
{
|
||||
g_return_val_if_fail (p_call_id, FALSE);
|
||||
g_return_val_if_fail (p_conf_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)
|
||||
if (!*p_conf_id)
|
||||
return FALSE;
|
||||
nm_pacrunner_manager_remove (self,
|
||||
g_steal_pointer (p_call_id));
|
||||
nm_pacrunner_manager_remove (g_steal_pointer (p_conf_id));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
name_owner_changed (NMPacrunnerManager *self,
|
||||
const char *name_owner)
|
||||
{
|
||||
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
|
||||
NMPacrunnerConfId *conf_id;
|
||||
gboolean has_name_owner;
|
||||
|
||||
has_name_owner = (name_owner && name_owner[0]);
|
||||
|
||||
if ( priv->dbus_initied
|
||||
&& priv->has_name_owner == has_name_owner)
|
||||
return;
|
||||
|
||||
priv->has_name_owner = has_name_owner;
|
||||
|
||||
nm_clear_g_cancellable (&priv->cancellable);
|
||||
|
||||
if (has_name_owner) {
|
||||
priv->dbus_initied = TRUE;
|
||||
priv->try_start_blocked = FALSE;
|
||||
_LOGD ("pacrunner appeared on D-Bus (%s)", name_owner);
|
||||
priv->cancellable = g_cancellable_new ();
|
||||
c_list_for_each_entry (conf_id, &priv->conf_id_lst_head, conf_id_lst)
|
||||
_call_create_proxy_configuration (self, conf_id, TRUE);
|
||||
} else {
|
||||
if (!priv->dbus_initied) {
|
||||
priv->dbus_initied = TRUE;
|
||||
nm_assert (!priv->try_start_blocked);
|
||||
_LOGD ("pacrunner not on D-Bus");
|
||||
} else
|
||||
_LOGD ("pacrunner disappeared from D-Bus");
|
||||
if (!c_list_is_empty (&priv->conf_id_lst_head)) {
|
||||
c_list_for_each_entry (conf_id, &priv->conf_id_lst_head, conf_id_lst)
|
||||
nm_clear_g_free (&conf_id->path);
|
||||
_try_start_service_by_name (self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
name_owner_changed_cb (GDBusConnection *connection,
|
||||
const char *sender_name,
|
||||
const char *object_path,
|
||||
const char *interface_name,
|
||||
const char *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *new_owner;
|
||||
|
||||
if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sss)")))
|
||||
return;
|
||||
|
||||
g_variant_get (parameters,
|
||||
"(&s&s&s)",
|
||||
NULL,
|
||||
NULL,
|
||||
&new_owner);
|
||||
|
||||
name_owner_changed (user_data, new_owner);
|
||||
}
|
||||
|
||||
static void
|
||||
get_name_owner_cb (const char *name_owner,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
if ( !name_owner
|
||||
&& g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
name_owner_changed (user_data, name_owner);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nm_pacrunner_manager_init (NMPacrunnerManager *self)
|
||||
{
|
||||
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
c_list_init (&priv->configs);
|
||||
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
PACRUNNER_DBUS_SERVICE,
|
||||
PACRUNNER_DBUS_PATH,
|
||||
PACRUNNER_DBUS_INTERFACE,
|
||||
_ensure_cancellable (priv),
|
||||
pacrunner_proxy_cb,
|
||||
self);
|
||||
c_list_init (&priv->conf_id_lst_head);
|
||||
|
||||
priv->dbus_connection = nm_g_object_ref (NM_MAIN_DBUS_CONNECTION_GET);
|
||||
|
||||
if (!priv->dbus_connection) {
|
||||
_LOGD ("no D-Bus connection to talk to pacrunner");
|
||||
return;
|
||||
}
|
||||
|
||||
priv->name_owner_changed_id = nm_dbus_connection_signal_subscribe_name_owner_changed (priv->dbus_connection,
|
||||
PACRUNNER_DBUS_SERVICE,
|
||||
name_owner_changed_cb,
|
||||
self,
|
||||
NULL);
|
||||
priv->cancellable = g_cancellable_new ();
|
||||
|
||||
nm_dbus_connection_call_get_name_owner (priv->dbus_connection,
|
||||
PACRUNNER_DBUS_SERVICE,
|
||||
-1,
|
||||
priv->cancellable,
|
||||
get_name_owner_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE ((NMPacrunnerManager *) object);
|
||||
CList *iter, *safe;
|
||||
|
||||
c_list_for_each_safe (iter, safe, &priv->configs) {
|
||||
c_list_unlink (iter);
|
||||
config_unref (c_list_entry (iter, Config, lst));
|
||||
}
|
||||
nm_assert (c_list_is_empty (&priv->conf_id_lst_head));
|
||||
|
||||
/* we cancel all pending operations. Note that pacrunner automatically
|
||||
* removes all configuration once NetworkManager disconnects from
|
||||
|
|
@ -580,8 +635,9 @@ dispose (GObject *object)
|
|||
*/
|
||||
nm_clear_g_cancellable (&priv->cancellable);
|
||||
|
||||
g_clear_pointer (&priv->iface, g_free);
|
||||
g_clear_object (&priv->pacrunner);
|
||||
nm_clear_g_dbus_connection_signal (priv->dbus_connection,
|
||||
&priv->name_owner_changed_id);
|
||||
g_clear_object (&priv->dbus_connection);
|
||||
|
||||
G_OBJECT_CLASS (nm_pacrunner_manager_parent_class)->dispose (object);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,22 +31,20 @@
|
|||
|
||||
typedef struct _NMPacrunnerManagerClass NMPacrunnerManagerClass;
|
||||
|
||||
typedef struct _NMPacrunnerCallId NMPacrunnerCallId;
|
||||
typedef struct _NMPacrunnerConfId NMPacrunnerConfId;
|
||||
|
||||
GType nm_pacrunner_manager_get_type (void);
|
||||
|
||||
NMPacrunnerManager *nm_pacrunner_manager_get (void);
|
||||
|
||||
NMPacrunnerCallId *nm_pacrunner_manager_send (NMPacrunnerManager *self,
|
||||
const char *iface,
|
||||
NMProxyConfig *proxy_config,
|
||||
NMIP4Config *ip4_config,
|
||||
NMIP6Config *ip6_config);
|
||||
NMPacrunnerConfId *nm_pacrunner_manager_add (NMPacrunnerManager *self,
|
||||
NMProxyConfig *proxy_config,
|
||||
const char *iface,
|
||||
NMIP4Config *ip4_config,
|
||||
NMIP6Config *ip6_config);
|
||||
|
||||
void nm_pacrunner_manager_remove (NMPacrunnerManager *self,
|
||||
NMPacrunnerCallId *call_id);
|
||||
void nm_pacrunner_manager_remove (NMPacrunnerConfId *conf_id);
|
||||
|
||||
gboolean nm_pacrunner_manager_remove_clear (NMPacrunnerManager *self,
|
||||
NMPacrunnerCallId **p_call_id);
|
||||
gboolean nm_pacrunner_manager_remove_clear (NMPacrunnerConfId **p_conf_id);
|
||||
|
||||
#endif /* __NETWORKMANAGER_PACRUNNER_MANAGER_H__ */
|
||||
|
|
|
|||
|
|
@ -124,8 +124,7 @@ typedef struct {
|
|||
GVariant *connect_hash;
|
||||
guint connect_timeout;
|
||||
NMProxyConfig *proxy_config;
|
||||
NMPacrunnerManager *pacrunner_manager;
|
||||
NMPacrunnerCallId *pacrunner_call_id;
|
||||
NMPacrunnerConfId *pacrunner_conf_id;
|
||||
gboolean has_ip4;
|
||||
NMIP4Config *ip4_config;
|
||||
guint32 ip4_internal_gw;
|
||||
|
|
@ -552,18 +551,12 @@ _set_vpn_state (NMVpnConnection *self,
|
|||
NULL);
|
||||
|
||||
if (priv->proxy_config) {
|
||||
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);
|
||||
nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id);
|
||||
priv->pacrunner_conf_id = nm_pacrunner_manager_add (nm_pacrunner_manager_get (),
|
||||
priv->proxy_config,
|
||||
priv->ip_iface,
|
||||
priv->ip4_config,
|
||||
priv->ip6_config);
|
||||
}
|
||||
break;
|
||||
case STATE_DEACTIVATING:
|
||||
|
|
@ -594,8 +587,7 @@ _set_vpn_state (NMVpnConnection *self,
|
|||
}
|
||||
}
|
||||
|
||||
nm_pacrunner_manager_remove_clear (priv->pacrunner_manager,
|
||||
&priv->pacrunner_call_id);
|
||||
nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id);
|
||||
break;
|
||||
case STATE_FAILED:
|
||||
case STATE_DISCONNECTED:
|
||||
|
|
@ -2801,9 +2793,7 @@ 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);
|
||||
nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id);
|
||||
|
||||
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue