|
Packit Service |
5ffa24 |
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
Packit Service |
5ffa24 |
/*
|
|
Packit Service |
5ffa24 |
* Copyright (C) 2016 Atul Anand <atulhjp@gmail.com>.
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#include "nm-default.h"
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#include "nm-pacrunner-manager.h"
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#include "nm-utils.h"
|
|
Packit Service |
5ffa24 |
#include "NetworkManagerUtils.h"
|
|
Packit Service |
5ffa24 |
#include "platform/nm-platform.h"
|
|
Packit Service |
5ffa24 |
#include "nm-dbus-manager.h"
|
|
Packit Service |
5ffa24 |
#include "nm-proxy-config.h"
|
|
Packit Service |
5ffa24 |
#include "nm-ip4-config.h"
|
|
Packit Service |
5ffa24 |
#include "nm-ip6-config.h"
|
|
Packit Service |
5ffa24 |
#include "c-list/src/c-list.h"
|
|
Packit Service |
5ffa24 |
#include "nm-glib-aux/nm-dbus-aux.h"
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#define PACRUNNER_DBUS_SERVICE "org.pacrunner"
|
|
Packit Service |
5ffa24 |
#define PACRUNNER_DBUS_INTERFACE "org.pacrunner.Manager"
|
|
Packit Service |
5ffa24 |
#define PACRUNNER_DBUS_PATH "/org/pacrunner/manager"
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
struct _NMPacrunnerConfId {
|
|
Packit Service |
5ffa24 |
CList conf_id_lst;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
NMPacrunnerManager *self;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
GVariant *parameters;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
char * path;
|
|
Packit Service |
5ffa24 |
guint64 log_id;
|
|
Packit Service |
5ffa24 |
guint refcount;
|
|
Packit Service |
5ffa24 |
};
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
typedef struct {
|
|
Packit Service |
5ffa24 |
GDBusConnection *dbus_connection;
|
|
Packit Service |
5ffa24 |
GCancellable * cancellable;
|
|
Packit Service |
5ffa24 |
CList conf_id_lst_head;
|
|
Packit Service |
5ffa24 |
guint64 log_id_counter;
|
|
Packit Service |
5ffa24 |
guint name_owner_changed_id;
|
|
Packit Service |
5ffa24 |
bool dbus_initied : 1;
|
|
Packit Service |
5ffa24 |
bool has_name_owner : 1;
|
|
Packit Service |
5ffa24 |
bool try_start_blocked : 1;
|
|
Packit Service |
5ffa24 |
} NMPacrunnerManagerPrivate;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
struct _NMPacrunnerManager {
|
|
Packit Service |
5ffa24 |
GObject parent;
|
|
Packit Service |
5ffa24 |
NMPacrunnerManagerPrivate _priv;
|
|
Packit Service |
5ffa24 |
};
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
struct _NMPacrunnerManagerClass {
|
|
Packit Service |
5ffa24 |
GObjectClass parent;
|
|
Packit Service |
5ffa24 |
};
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
G_DEFINE_TYPE(NMPacrunnerManager, nm_pacrunner_manager, G_TYPE_OBJECT)
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#define NM_PACRUNNER_MANAGER_GET_PRIVATE(self) \
|
|
Packit Service |
5ffa24 |
_NM_GET_PRIVATE(self, NMPacrunnerManager, NM_IS_PACRUNNER_MANAGER)
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
NM_DEFINE_SINGLETON_GETTER(NMPacrunnerManager, nm_pacrunner_manager_get, NM_TYPE_PACRUNNER_MANAGER);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#define _NMLOG_DOMAIN LOGD_PROXY
|
|
Packit Service |
5ffa24 |
#define _NMLOG(level, ...) __NMLOG_DEFAULT(level, _NMLOG_DOMAIN, "pacrunner", __VA_ARGS__)
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#define _NMLOG2_PREFIX_NAME "pacrunner"
|
|
Packit Service |
5ffa24 |
#define _NMLOG2(level, conf_id, ...) \
|
|
Packit Service |
5ffa24 |
G_STMT_START \
|
|
Packit Service |
5ffa24 |
{ \
|
|
Packit Service |
5ffa24 |
nm_log((level), \
|
|
Packit Service |
5ffa24 |
_NMLOG_DOMAIN, \
|
|
Packit Service |
5ffa24 |
NULL, \
|
|
Packit Service |
5ffa24 |
NULL, \
|
|
Packit Service |
5ffa24 |
"%s%" G_GUINT64_FORMAT "]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
|
Packit Service |
5ffa24 |
_NMLOG2_PREFIX_NAME ": call[", \
|
|
Packit Service |
5ffa24 |
(conf_id)->log_id _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
|
|
Packit Service |
5ffa24 |
} \
|
|
Packit Service |
5ffa24 |
G_STMT_END
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void _call_destroy_proxy_configuration(NMPacrunnerManager *self,
|
|
Packit Service |
5ffa24 |
NMPacrunnerConfId * conf_id,
|
|
Packit Service |
5ffa24 |
const char * path,
|
|
Packit Service |
5ffa24 |
gboolean verbose_log);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static NMPacrunnerConfId *
|
|
Packit Service |
5ffa24 |
conf_id_ref(NMPacrunnerConfId *conf_id)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
nm_assert(conf_id);
|
|
Packit Service |
5ffa24 |
nm_assert(conf_id->refcount > 0);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
conf_id->refcount++;
|
|
Packit Service |
5ffa24 |
return conf_id;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
conf_id_unref(NMPacrunnerConfId *conf_id)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
nm_assert(conf_id);
|
|
Packit Service |
5ffa24 |
nm_assert(conf_id->refcount > 0);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (conf_id->refcount == 1) {
|
|
Packit Service |
5ffa24 |
g_variant_unref(conf_id->parameters);
|
|
Packit Service |
5ffa24 |
g_free(conf_id->path);
|
|
Packit Service |
5ffa24 |
c_list_unlink_stale(&conf_id->conf_id_lst);
|
|
Packit Service |
5ffa24 |
g_object_unref(conf_id->self);
|
|
Packit Service |
5ffa24 |
g_slice_free(NMPacrunnerConfId, conf_id);
|
|
Packit Service |
5ffa24 |
} else
|
|
Packit Service |
5ffa24 |
conf_id->refcount--;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
NM_AUTO_DEFINE_FCN0(NMPacrunnerConfId *, _nm_auto_unref_conf_id, conf_id_unref);
|
|
Packit Service |
5ffa24 |
#define nm_auto_unref_conf_id nm_auto(_nm_auto_unref_conf_id)
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
get_ip_domains(GPtrArray *domains, NMIPConfig *ip_config)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMDedupMultiIter ipconf_iter;
|
|
Packit Service |
5ffa24 |
char * cidr;
|
|
Packit Service |
5ffa24 |
guint i, num;
|
|
Packit Service |
5ffa24 |
char sbuf[NM_UTILS_INET_ADDRSTRLEN];
|
|
Packit Service |
5ffa24 |
int addr_family;
|
|
Packit Service |
5ffa24 |
const NMPlatformIPAddress *address;
|
|
Packit Service |
5ffa24 |
const NMPlatformIPRoute * routes;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!ip_config)
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
addr_family = nm_ip_config_get_addr_family(ip_config);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
num = nm_ip_config_get_num_searches(ip_config);
|
|
Packit Service |
5ffa24 |
for (i = 0; i < num; i++)
|
|
Packit Service |
5ffa24 |
g_ptr_array_add(domains, g_strdup(nm_ip_config_get_search(ip_config, i)));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
num = nm_ip_config_get_num_domains(ip_config);
|
|
Packit Service |
5ffa24 |
for (i = 0; i < num; i++)
|
|
Packit Service |
5ffa24 |
g_ptr_array_add(domains, g_strdup(nm_ip_config_get_domain(ip_config, i)));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_ip_config_iter_ip_address_for_each (&ipconf_iter, ip_config, &address) {
|
|
Packit Service |
5ffa24 |
cidr = g_strdup_printf("%s/%u",
|
|
Packit Service |
5ffa24 |
nm_utils_inet_ntop(addr_family, address->address_ptr, sbuf),
|
|
Packit Service |
5ffa24 |
address->plen);
|
|
Packit Service |
5ffa24 |
g_ptr_array_add(domains, cidr);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_ip_config_iter_ip_route_for_each (&ipconf_iter, ip_config, &routes) {
|
|
Packit Service |
5ffa24 |
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(routes))
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
cidr = g_strdup_printf("%s/%u",
|
|
Packit Service |
5ffa24 |
nm_utils_inet_ntop(addr_family, routes->network_ptr, sbuf),
|
|
Packit Service |
5ffa24 |
routes->plen);
|
|
Packit Service |
5ffa24 |
g_ptr_array_add(domains, cidr);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static GVariant *
|
|
Packit Service |
5ffa24 |
_make_request_create_proxy_configuration(NMProxyConfig *proxy_config,
|
|
Packit Service |
5ffa24 |
const char * iface,
|
|
Packit Service |
5ffa24 |
NMIP4Config * ip4_config,
|
|
Packit Service |
5ffa24 |
NMIP6Config * ip6_config)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
GVariantBuilder builder;
|
|
Packit Service |
5ffa24 |
NMProxyConfigMethod method;
|
|
Packit Service |
5ffa24 |
const char * pac_url;
|
|
Packit Service |
5ffa24 |
const char * pac_script;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_assert(NM_IS_PROXY_CONFIG(proxy_config));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (iface) {
|
|
Packit Service |
5ffa24 |
g_variant_builder_add(&builder, "{sv}", "Interface", g_variant_new_string(iface));
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
method = nm_proxy_config_get_method(proxy_config);
|
|
Packit Service |
5ffa24 |
switch (method) {
|
|
Packit Service |
5ffa24 |
case NM_PROXY_CONFIG_METHOD_AUTO:
|
|
Packit Service |
5ffa24 |
g_variant_builder_add(&builder, "{sv}", "Method", g_variant_new_string("auto"));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
pac_url = nm_proxy_config_get_pac_url(proxy_config);
|
|
Packit Service |
5ffa24 |
if (pac_url) {
|
|
Packit Service |
5ffa24 |
g_variant_builder_add(&builder, "{sv}", "URL", g_variant_new_string(pac_url));
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
pac_script = nm_proxy_config_get_pac_script(proxy_config);
|
|
Packit Service |
5ffa24 |
if (pac_script) {
|
|
Packit Service |
5ffa24 |
g_variant_builder_add(&builder, "{sv}", "Script", g_variant_new_string(pac_script));
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
case NM_PROXY_CONFIG_METHOD_NONE:
|
|
Packit Service |
5ffa24 |
g_variant_builder_add(&builder, "{sv}", "Method", g_variant_new_string("direct"));
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_variant_builder_add(&builder,
|
|
Packit Service |
5ffa24 |
"{sv}",
|
|
Packit Service |
5ffa24 |
"BrowserOnly",
|
|
Packit Service |
5ffa24 |
g_variant_new_boolean(nm_proxy_config_get_browser_only(proxy_config)));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (ip4_config || ip6_config) {
|
|
Packit Service |
5ffa24 |
gs_unref_ptrarray GPtrArray *domains = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
domains = g_ptr_array_new_with_free_func(g_free);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
get_ip_domains(domains, NM_IP_CONFIG_CAST(ip4_config));
|
|
Packit Service |
5ffa24 |
get_ip_domains(domains, NM_IP_CONFIG_CAST(ip6_config));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (domains->len > 0) {
|
|
Packit Service |
5ffa24 |
g_variant_builder_add(
|
|
Packit Service |
5ffa24 |
&builder,
|
|
Packit Service |
5ffa24 |
"{sv}",
|
|
Packit Service |
5ffa24 |
"Domains",
|
|
Packit Service |
5ffa24 |
g_variant_new_strv((const char *const *) domains->pdata, domains->len));
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
return g_variant_new("(a{sv})", &builder);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
_call_destroy_proxy_configuration_cb(GObject *source, GAsyncResult *res, gpointer user_data)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
nm_auto_unref_conf_id NMPacrunnerConfId *conf_id = user_data;
|
|
Packit Service |
5ffa24 |
gs_free_error GError *error = NULL;
|
|
Packit Service |
5ffa24 |
gs_unref_variant GVariant *ret = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error);
|
|
Packit Service |
5ffa24 |
if (!ret) {
|
|
Packit Service |
5ffa24 |
if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id, "destroy proxy configuration: failed with %s", error->message);
|
|
Packit Service |
5ffa24 |
else
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id, "destroy proxy configuration: cancelled");
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id, "destroy proxy configuration: success");
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
_call_create_proxy_configuration_cb(GObject *source, GAsyncResult *res, gpointer user_data)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
nm_auto_unref_conf_id NMPacrunnerConfId *conf_id = user_data;
|
|
Packit Service |
5ffa24 |
NMPacrunnerManager * self = NM_PACRUNNER_MANAGER(conf_id->self);
|
|
Packit Service |
5ffa24 |
gs_free_error GError *error = NULL;
|
|
Packit Service |
5ffa24 |
gs_unref_variant GVariant *variant = NULL;
|
|
Packit Service |
5ffa24 |
const char * path = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_assert(!conf_id->path);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
variant = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!variant) {
|
|
Packit Service |
5ffa24 |
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id, "create proxy configuration failed: %s", error->message);
|
|
Packit Service |
5ffa24 |
else
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id, "create proxy configuration cancelled");
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_variant_get(variant, "(&o)", &path);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (c_list_is_empty(&conf_id->conf_id_lst)) {
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id,
|
|
Packit Service |
5ffa24 |
"create proxy configuration succeeded (%s), but destroy it right away",
|
|
Packit Service |
5ffa24 |
path);
|
|
Packit Service |
5ffa24 |
_call_destroy_proxy_configuration(self, conf_id, path, FALSE);
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id, "create proxy configuration succeeded (%s)", path);
|
|
Packit Service |
5ffa24 |
conf_id->path = g_strdup(path);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
_call_destroy_proxy_configuration(NMPacrunnerManager *self,
|
|
Packit Service |
5ffa24 |
NMPacrunnerConfId * conf_id,
|
|
Packit Service |
5ffa24 |
const char * path,
|
|
Packit Service |
5ffa24 |
gboolean verbose_log)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (verbose_log)
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id, "destroy proxy configuration %s...", path);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_dbus_connection_call(priv->dbus_connection,
|
|
Packit Service |
5ffa24 |
PACRUNNER_DBUS_SERVICE,
|
|
Packit Service |
5ffa24 |
PACRUNNER_DBUS_PATH,
|
|
Packit Service |
5ffa24 |
PACRUNNER_DBUS_INTERFACE,
|
|
Packit Service |
5ffa24 |
"DestroyProxyConfiguration",
|
|
Packit Service |
5ffa24 |
g_variant_new("(o)", path),
|
|
Packit Service |
5ffa24 |
G_VARIANT_TYPE("()"),
|
|
Packit Service |
5ffa24 |
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
|
Packit Service |
5ffa24 |
NM_SHUTDOWN_TIMEOUT_MS,
|
|
Packit Service |
5ffa24 |
priv->cancellable,
|
|
Packit Service |
5ffa24 |
_call_destroy_proxy_configuration_cb,
|
|
Packit Service |
5ffa24 |
conf_id_ref(conf_id));
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
_call_create_proxy_configuration(NMPacrunnerManager *self,
|
|
Packit Service |
5ffa24 |
NMPacrunnerConfId * conf_id,
|
|
Packit Service |
5ffa24 |
gboolean verbose_log)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (verbose_log)
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id, "create proxy configuration...");
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_dbus_connection_call(priv->dbus_connection,
|
|
Packit Service |
5ffa24 |
PACRUNNER_DBUS_SERVICE,
|
|
Packit Service |
5ffa24 |
PACRUNNER_DBUS_PATH,
|
|
Packit Service |
5ffa24 |
PACRUNNER_DBUS_INTERFACE,
|
|
Packit Service |
5ffa24 |
"CreateProxyConfiguration",
|
|
Packit Service |
5ffa24 |
conf_id->parameters,
|
|
Packit Service |
5ffa24 |
G_VARIANT_TYPE("(o)"),
|
|
Packit Service |
5ffa24 |
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
|
Packit Service |
5ffa24 |
NM_SHUTDOWN_TIMEOUT_MS,
|
|
Packit Service |
5ffa24 |
priv->cancellable,
|
|
Packit Service |
5ffa24 |
_call_create_proxy_configuration_cb,
|
|
Packit Service |
5ffa24 |
conf_id_ref(conf_id));
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static gboolean
|
|
Packit Service |
5ffa24 |
_try_start_service_by_name(NMPacrunnerManager *self)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (priv->try_start_blocked || !priv->dbus_initied)
|
|
Packit Service |
5ffa24 |
return FALSE;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
_LOGD("try D-Bus activating pacrunner...");
|
|
Packit Service |
5ffa24 |
priv->try_start_blocked = TRUE;
|
|
Packit Service |
5ffa24 |
nm_dbus_connection_call_start_service_by_name(priv->dbus_connection,
|
|
Packit Service |
5ffa24 |
PACRUNNER_DBUS_SERVICE,
|
|
Packit Service |
5ffa24 |
-1,
|
|
Packit Service |
5ffa24 |
NULL,
|
|
Packit Service |
5ffa24 |
NULL,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
return TRUE;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/**
|
|
Packit Service |
5ffa24 |
* nm_pacrunner_manager_add:
|
|
Packit Service |
5ffa24 |
* @self: the #NMPacrunnerManager
|
|
Packit Service |
5ffa24 |
* @proxy_config: proxy config of the connection
|
|
Packit Service |
5ffa24 |
* @iface: the iface for the connection or %NULL
|
|
Packit Service |
5ffa24 |
* @ip4_config: IP4 config of the connection to extract domain info from
|
|
Packit Service |
5ffa24 |
* @ip6_config: IP6 config of the connection to extract domain info from
|
|
Packit Service |
5ffa24 |
*
|
|
Packit Service |
5ffa24 |
* Returns: a #NMPacrunnerConfId id. The function cannot
|
|
Packit Service |
5ffa24 |
* fail and always returns a non NULL pointer. The conf-id may
|
|
Packit Service |
5ffa24 |
* be used to remove the configuration later via nm_pacrunner_manager_remove().
|
|
Packit Service |
5ffa24 |
* Note that the conf-id keeps the @self instance alive.
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
NMPacrunnerConfId *
|
|
Packit Service |
5ffa24 |
nm_pacrunner_manager_add(NMPacrunnerManager *self,
|
|
Packit Service |
5ffa24 |
NMProxyConfig * proxy_config,
|
|
Packit Service |
5ffa24 |
const char * iface,
|
|
Packit Service |
5ffa24 |
NMIP4Config * ip4_config,
|
|
Packit Service |
5ffa24 |
NMIP6Config * ip6_config)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMPacrunnerManagerPrivate *priv;
|
|
Packit Service |
5ffa24 |
NMPacrunnerConfId * conf_id;
|
|
Packit Service |
5ffa24 |
gs_free char * log_msg = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_return_val_if_fail(NM_IS_PACRUNNER_MANAGER(self), NULL);
|
|
Packit Service |
5ffa24 |
g_return_val_if_fail(proxy_config, NULL);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
conf_id = g_slice_new(NMPacrunnerConfId);
|
|
Packit Service |
5ffa24 |
*conf_id = (NMPacrunnerConfId){
|
|
Packit Service |
5ffa24 |
.log_id = ++priv->log_id_counter,
|
|
Packit Service |
5ffa24 |
.refcount = 1,
|
|
Packit Service |
5ffa24 |
.self = g_object_ref(self),
|
|
Packit Service |
5ffa24 |
.parameters = g_variant_ref_sink(
|
|
Packit Service |
5ffa24 |
_make_request_create_proxy_configuration(proxy_config, iface, ip4_config, ip6_config)),
|
|
Packit Service |
5ffa24 |
};
|
|
Packit Service |
5ffa24 |
c_list_link_tail(&priv->conf_id_lst_head, &conf_id->conf_id_lst);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!priv->has_name_owner) {
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id,
|
|
Packit Service |
5ffa24 |
"add config: %s (%s)",
|
|
Packit Service |
5ffa24 |
(log_msg = g_variant_print(conf_id->parameters, FALSE)),
|
|
Packit Service |
5ffa24 |
"pacrunner D-Bus service not running");
|
|
Packit Service |
5ffa24 |
_try_start_service_by_name(self);
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id,
|
|
Packit Service |
5ffa24 |
"add config: %s (%s)",
|
|
Packit Service |
5ffa24 |
(log_msg = g_variant_print(conf_id->parameters, FALSE)),
|
|
Packit Service |
5ffa24 |
"create proxy configuration");
|
|
Packit Service |
5ffa24 |
_call_create_proxy_configuration(self, conf_id, FALSE);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
return conf_id;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/**
|
|
Packit Service |
5ffa24 |
* nm_pacrunner_manager_remove:
|
|
Packit Service |
5ffa24 |
* @conf_id: the conf id obtained from nm_pacrunner_manager_add()
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
void
|
|
Packit Service |
5ffa24 |
nm_pacrunner_manager_remove(NMPacrunnerConfId *conf_id)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
_nm_unused nm_auto_unref_conf_id NMPacrunnerConfId *conf_id_free = conf_id;
|
|
Packit Service |
5ffa24 |
NMPacrunnerManager * self;
|
|
Packit Service |
5ffa24 |
NMPacrunnerManagerPrivate * priv;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_return_if_fail(conf_id);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
self = conf_id->self;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_return_if_fail(NM_IS_PACRUNNER_MANAGER(self));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
_LOG2T(conf_id, "removing...");
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_assert(c_list_contains(&priv->conf_id_lst_head, &conf_id->conf_id_lst));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
c_list_unlink(&conf_id->conf_id_lst);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!conf_id->path) {
|
|
Packit Service |
5ffa24 |
/* There is no ID to destroy the configuration.
|
|
Packit Service |
5ffa24 |
*
|
|
Packit Service |
5ffa24 |
* That can happen because:
|
|
Packit Service |
5ffa24 |
*
|
|
Packit Service |
5ffa24 |
* - pacrunner D-Bus service is not running (no name owner) and we didn't call CreateProxyConfiguration.
|
|
Packit Service |
5ffa24 |
* - CreateProxyConfiguration failed.
|
|
Packit Service |
5ffa24 |
* - CreateProxyConfiguration is in progress.
|
|
Packit Service |
5ffa24 |
*
|
|
Packit Service |
5ffa24 |
* In all cases there is nothing to do. Note that if CreateProxyConfiguration is in progress
|
|
Packit Service |
5ffa24 |
* it has a reference on the conf-id and it will automatically destroy the configuration
|
|
Packit Service |
5ffa24 |
* when it completes.
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
_call_destroy_proxy_configuration(self, conf_id, conf_id->path, TRUE);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
gboolean
|
|
Packit Service |
5ffa24 |
nm_pacrunner_manager_remove_clear(NMPacrunnerConfId **p_conf_id)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
g_return_val_if_fail(p_conf_id, FALSE);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!*p_conf_id)
|
|
Packit Service |
5ffa24 |
return FALSE;
|
|
Packit Service |
5ffa24 |
nm_pacrunner_manager_remove(g_steal_pointer(p_conf_id));
|
|
Packit Service |
5ffa24 |
return TRUE;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
name_owner_changed(NMPacrunnerManager *self, const char *name_owner)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
5ffa24 |
NMPacrunnerConfId * conf_id;
|
|
Packit Service |
5ffa24 |
gboolean has_name_owner;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
has_name_owner = (name_owner && name_owner[0]);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (priv->dbus_initied && priv->has_name_owner == has_name_owner)
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
priv->has_name_owner = has_name_owner;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_clear_g_cancellable(&priv->cancellable);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (has_name_owner) {
|
|
Packit Service |
5ffa24 |
priv->dbus_initied = TRUE;
|
|
Packit Service |
5ffa24 |
priv->try_start_blocked = FALSE;
|
|
Packit Service |
5ffa24 |
_LOGD("pacrunner appeared on D-Bus (%s)", name_owner);
|
|
Packit Service |
5ffa24 |
priv->cancellable = g_cancellable_new();
|
|
Packit Service |
5ffa24 |
c_list_for_each_entry (conf_id, &priv->conf_id_lst_head, conf_id_lst)
|
|
Packit Service |
5ffa24 |
_call_create_proxy_configuration(self, conf_id, TRUE);
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
if (!priv->dbus_initied) {
|
|
Packit Service |
5ffa24 |
priv->dbus_initied = TRUE;
|
|
Packit Service |
5ffa24 |
nm_assert(!priv->try_start_blocked);
|
|
Packit Service |
5ffa24 |
_LOGD("pacrunner not on D-Bus");
|
|
Packit Service |
5ffa24 |
} else
|
|
Packit Service |
5ffa24 |
_LOGD("pacrunner disappeared from D-Bus");
|
|
Packit Service |
5ffa24 |
if (!c_list_is_empty(&priv->conf_id_lst_head)) {
|
|
Packit Service |
5ffa24 |
c_list_for_each_entry (conf_id, &priv->conf_id_lst_head, conf_id_lst)
|
|
Packit Service |
5ffa24 |
nm_clear_g_free(&conf_id->path);
|
|
Packit Service |
5ffa24 |
_try_start_service_by_name(self);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
name_owner_changed_cb(GDBusConnection *connection,
|
|
Packit Service |
5ffa24 |
const char * sender_name,
|
|
Packit Service |
5ffa24 |
const char * object_path,
|
|
Packit Service |
5ffa24 |
const char * interface_name,
|
|
Packit Service |
5ffa24 |
const char * signal_name,
|
|
Packit Service |
5ffa24 |
GVariant * parameters,
|
|
Packit Service |
5ffa24 |
gpointer user_data)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
const char *new_owner;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)")))
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_owner);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
name_owner_changed(user_data, new_owner);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
get_name_owner_cb(const char *name_owner, GError *error, gpointer user_data)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
if (!name_owner && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
name_owner_changed(user_data, name_owner);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
nm_pacrunner_manager_init(NMPacrunnerManager *self)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
c_list_init(&priv->conf_id_lst_head);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
priv->dbus_connection = nm_g_object_ref(NM_MAIN_DBUS_CONNECTION_GET);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!priv->dbus_connection) {
|
|
Packit Service |
5ffa24 |
_LOGD("no D-Bus connection to talk to pacrunner");
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
priv->name_owner_changed_id =
|
|
Packit Service |
5ffa24 |
nm_dbus_connection_signal_subscribe_name_owner_changed(priv->dbus_connection,
|
|
Packit Service |
5ffa24 |
PACRUNNER_DBUS_SERVICE,
|
|
Packit Service |
5ffa24 |
name_owner_changed_cb,
|
|
Packit Service |
5ffa24 |
self,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
priv->cancellable = g_cancellable_new();
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_dbus_connection_call_get_name_owner(priv->dbus_connection,
|
|
Packit Service |
5ffa24 |
PACRUNNER_DBUS_SERVICE,
|
|
Packit Service |
5ffa24 |
-1,
|
|
Packit Service |
5ffa24 |
priv->cancellable,
|
|
Packit Service |
5ffa24 |
get_name_owner_cb,
|
|
Packit Service |
5ffa24 |
self);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
dispose(GObject *object)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(object);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_assert(c_list_is_empty(&priv->conf_id_lst_head));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* we cancel all pending operations. Note that pacrunner automatically
|
|
Packit Service |
5ffa24 |
* removes all configuration once NetworkManager disconnects from
|
|
Packit Service |
5ffa24 |
* the bus -- which happens soon after we destroy the pacrunner manager.
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
nm_clear_g_cancellable(&priv->cancellable);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->name_owner_changed_id);
|
|
Packit Service |
5ffa24 |
g_clear_object(&priv->dbus_connection);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
G_OBJECT_CLASS(nm_pacrunner_manager_parent_class)->dispose(object);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
nm_pacrunner_manager_class_init(NMPacrunnerManagerClass *klass)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
object_class->dispose = dispose;
|
|
Packit Service |
5ffa24 |
}
|