mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-11 08:08:54 +02:00
merge: branch 'dns-hashes'
Refactor dns-manager to isolate resolvconf operations and allow plugins to implement their own checksum https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2215
This commit is contained in:
commit
d04fc18054
15 changed files with 1918 additions and 1334 deletions
|
|
@ -679,11 +679,7 @@ parse_all_interface_config(GVariantBuilder *argument_builder,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
update(NMDnsPlugin *plugin,
|
||||
const NMGlobalDnsConfig *global_config,
|
||||
const CList *ip_data_lst_head,
|
||||
const char *hostdomain,
|
||||
GError **error)
|
||||
update(NMDnsPlugin *plugin, NMDnsUpdateData *update_data, GError **error)
|
||||
{
|
||||
NMDnsDnsconfd *self = NM_DNS_DNSCONFD(plugin);
|
||||
NMDnsDnsconfdPrivate *priv = NM_DNS_DNSCONFD_GET_PRIVATE(self);
|
||||
|
|
@ -698,12 +694,12 @@ update(NMDnsPlugin *plugin,
|
|||
g_variant_builder_init(&argument_builder, G_VARIANT_TYPE("(aa{sv}u)"));
|
||||
g_variant_builder_open(&argument_builder, G_VARIANT_TYPE("aa{sv}"));
|
||||
|
||||
if (global_config) {
|
||||
if (update_data->global_config) {
|
||||
_LOGT("parsing global configuration");
|
||||
parse_global_config(global_config, &argument_builder, &resolve_mode, &ca);
|
||||
parse_global_config(update_data->global_config, &argument_builder, &resolve_mode, &ca);
|
||||
}
|
||||
_LOGT("parsing configuration of interfaces");
|
||||
parse_all_interface_config(&argument_builder, ip_data_lst_head, ca);
|
||||
parse_all_interface_config(&argument_builder, update_data->ip_data_lst_head, ca);
|
||||
|
||||
g_variant_builder_close(&argument_builder);
|
||||
g_variant_builder_add(&argument_builder, "u", resolve_mode);
|
||||
|
|
@ -812,6 +808,77 @@ dispose(GObject *object)
|
|||
g_clear_object(&priv->dbus_connection);
|
||||
}
|
||||
|
||||
static void
|
||||
dnsconfd_checksum(const NML3ConfigData *l3cd,
|
||||
GChecksum *sum,
|
||||
int addr_family,
|
||||
NMDnsIPConfigType dns_ip_config_type)
|
||||
{
|
||||
guint i;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPObject *obj;
|
||||
const NMPlatformIPRoute *route;
|
||||
const char *const *strarr;
|
||||
const in_addr_t *wins;
|
||||
guint element_num;
|
||||
int prio = 0;
|
||||
gboolean empty = TRUE;
|
||||
|
||||
g_return_if_fail(l3cd);
|
||||
g_return_if_fail(sum);
|
||||
|
||||
strarr = nm_l3_config_data_get_nameservers(l3cd, addr_family, &element_num);
|
||||
for (i = 0; i < element_num; i++) {
|
||||
g_checksum_update(sum, (gpointer) strarr[i], strlen(strarr[i]));
|
||||
empty = FALSE;
|
||||
}
|
||||
|
||||
if (addr_family == AF_INET) {
|
||||
wins = nm_l3_config_data_get_wins(l3cd, &element_num);
|
||||
for (i = 0; i < element_num; i++) {
|
||||
g_checksum_update(sum, (guint8 *) &wins[i], 4);
|
||||
empty = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Without servers, the sum should be zero, as Dnsconfd API is oriented
|
||||
* around servers */
|
||||
if (empty) {
|
||||
_LOGT("no servers, thus checksum is zero");
|
||||
return;
|
||||
}
|
||||
|
||||
strarr = nm_l3_config_data_get_searches(l3cd, addr_family, &element_num);
|
||||
for (i = 0; i < element_num; i++) {
|
||||
g_checksum_update(sum, (const guint8 *) strarr[i], strlen(strarr[i]));
|
||||
}
|
||||
|
||||
/* If we've got searches, then we do not care about domains, because
|
||||
* searches have higher priority */
|
||||
if (!element_num) {
|
||||
strarr = nm_l3_config_data_get_domains(l3cd, addr_family, &element_num);
|
||||
for (i = 0; i < element_num; i++) {
|
||||
g_checksum_update(sum, (const guint8 *) strarr[i], strlen(strarr[i]));
|
||||
}
|
||||
}
|
||||
|
||||
nm_l3_config_data_iter_obj_for_each (&ipconf_iter,
|
||||
l3cd,
|
||||
&obj,
|
||||
NMP_OBJECT_TYPE_IP_ROUTE(NM_IS_IPv4(addr_family))) {
|
||||
route = NMP_OBJECT_CAST_IP_ROUTE(obj);
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route)
|
||||
|| route->table_coerced == NM_DNS_ROUTES_FWMARK_TABLE_PRIO) {
|
||||
continue;
|
||||
}
|
||||
g_checksum_update(sum, (const guint8 *) route, sizeof(*route));
|
||||
}
|
||||
|
||||
g_checksum_update(sum, (const guint8 *) &dns_ip_config_type, sizeof(dns_ip_config_type));
|
||||
nm_l3_config_data_get_dns_priority(l3cd, addr_family, &prio);
|
||||
g_checksum_update(sum, (const guint8 *) &prio, sizeof(prio));
|
||||
}
|
||||
|
||||
static void
|
||||
nm_dns_dnsconfd_class_init(NMDnsDnsconfdClass *dns_class)
|
||||
{
|
||||
|
|
@ -825,4 +892,5 @@ nm_dns_dnsconfd_class_init(NMDnsDnsconfdClass *dns_class)
|
|||
plugin_class->stop = stop;
|
||||
plugin_class->update = update;
|
||||
plugin_class->get_update_pending = get_update_pending;
|
||||
plugin_class->checksum = dnsconfd_checksum;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "nm-dbus-manager.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-l3-config-data.h"
|
||||
#include "nm-l3cfg.h"
|
||||
|
||||
#define PIDFILE NMRUNDIR "/dnsmasq.pid"
|
||||
#define CONFDIR NMCONFDIR "/dnsmasq.d"
|
||||
|
|
@ -1207,11 +1208,7 @@ start_dnsmasq(NMDnsDnsmasq *self, gboolean force_start, GError **error)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
update(NMDnsPlugin *plugin,
|
||||
const NMGlobalDnsConfig *global_config,
|
||||
const CList *ip_data_lst_head,
|
||||
const char *hostdomain,
|
||||
GError **error)
|
||||
update(NMDnsPlugin *plugin, NMDnsUpdateData *update_data, GError **error)
|
||||
{
|
||||
NMDnsDnsmasq *self = NM_DNS_DNSMASQ(plugin);
|
||||
NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE(self);
|
||||
|
|
@ -1220,8 +1217,10 @@ update(NMDnsPlugin *plugin,
|
|||
return FALSE;
|
||||
|
||||
nm_clear_pointer(&priv->set_server_ex_args, g_variant_unref);
|
||||
priv->set_server_ex_args =
|
||||
g_variant_ref_sink(create_update_args(self, global_config, ip_data_lst_head, hostdomain));
|
||||
priv->set_server_ex_args = g_variant_ref_sink(create_update_args(self,
|
||||
update_data->global_config,
|
||||
update_data->ip_data_lst_head,
|
||||
update_data->hostdomain));
|
||||
priv->set_server_ex_args_dirty = TRUE;
|
||||
|
||||
send_dnsmasq_update(self);
|
||||
|
|
@ -1230,6 +1229,76 @@ update(NMDnsPlugin *plugin,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
dnsmasq_checksum(const NML3ConfigData *l3cd,
|
||||
GChecksum *sum,
|
||||
int addr_family,
|
||||
NMDnsIPConfigType dns_ip_config_type)
|
||||
{
|
||||
guint i;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPObject *obj;
|
||||
const NMPlatformIPRoute *route;
|
||||
const char *const *strarr;
|
||||
const in_addr_t *wins;
|
||||
guint element_num;
|
||||
int prio = 0;
|
||||
gboolean empty = TRUE;
|
||||
|
||||
g_return_if_fail(l3cd);
|
||||
g_return_if_fail(sum);
|
||||
|
||||
strarr = nm_l3_config_data_get_nameservers(l3cd, addr_family, &element_num);
|
||||
for (i = 0; i < element_num; i++) {
|
||||
g_checksum_update(sum, (gpointer) strarr[i], strlen(strarr[i]));
|
||||
empty = FALSE;
|
||||
}
|
||||
|
||||
if (addr_family == AF_INET) {
|
||||
wins = nm_l3_config_data_get_wins(l3cd, &element_num);
|
||||
for (i = 0; i < element_num; i++) {
|
||||
g_checksum_update(sum, (guint8 *) &wins[i], 4);
|
||||
empty = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Without servers, the sum should be zero, as Dnsmasq plugin depends on servers */
|
||||
if (empty) {
|
||||
return;
|
||||
}
|
||||
|
||||
strarr = nm_l3_config_data_get_searches(l3cd, addr_family, &element_num);
|
||||
for (i = 0; i < element_num; i++) {
|
||||
g_checksum_update(sum, (const guint8 *) strarr[i], strlen(strarr[i]));
|
||||
}
|
||||
|
||||
/* If we've got searches, then we do not care about domains, because
|
||||
* searches have higher priority */
|
||||
if (!element_num) {
|
||||
strarr = nm_l3_config_data_get_domains(l3cd, addr_family, &element_num);
|
||||
for (i = 0; i < element_num; i++) {
|
||||
g_checksum_update(sum, (const guint8 *) strarr[i], strlen(strarr[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/* Dnsmasq consumes reverse dns domains, thus it depends on routes */
|
||||
nm_l3_config_data_iter_obj_for_each (&ipconf_iter,
|
||||
l3cd,
|
||||
&obj,
|
||||
NMP_OBJECT_TYPE_IP_ROUTE(NM_IS_IPv4(addr_family))) {
|
||||
route = NMP_OBJECT_CAST_IP_ROUTE(obj);
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route)
|
||||
|| route->table_coerced == NM_DNS_ROUTES_FWMARK_TABLE_PRIO) {
|
||||
continue;
|
||||
}
|
||||
g_checksum_update(sum, (const guint8 *) route, sizeof(*route));
|
||||
}
|
||||
|
||||
g_checksum_update(sum, (const guint8 *) &dns_ip_config_type, sizeof(dns_ip_config_type));
|
||||
nm_l3_config_data_get_dns_priority(l3cd, addr_family, &prio);
|
||||
g_checksum_update(sum, (const guint8 *) &prio, sizeof(prio));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -1293,4 +1362,5 @@ nm_dns_dnsmasq_class_init(NMDnsDnsmasqClass *dns_class)
|
|||
plugin_class->stop = stop;
|
||||
plugin_class->update = update;
|
||||
plugin_class->get_update_pending = get_update_pending;
|
||||
plugin_class->checksum = dnsmasq_checksum;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -98,44 +98,6 @@ gboolean nm_dns_manager_set_ip_config(NMDnsManager *self,
|
|||
|
||||
void nm_dns_manager_set_hostname(NMDnsManager *self, const char *hostname, gboolean skip_update);
|
||||
|
||||
/**
|
||||
* NMDnsManagerResolvConfManager
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN: unspecified rc-manager.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED: do not touch /etc/resolv.conf
|
||||
* (but still write the internal copy -- unless it is symlinked by
|
||||
* /etc/resolv.conf)
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO: if /etc/resolv.conf is marked
|
||||
* as an immutable file, use "unmanaged" and don't touch /etc/resolv.conf.
|
||||
* Otherwise, if "systemd-resolved" is enabled (or detected), configure systemd-resolved via D-Bus
|
||||
* and don't touch /etc/resolv.conf.
|
||||
* Otherwise, if "resolvconf" application is found, use it.
|
||||
* As last resort, fallback to "symlink" which writes to /etc/resolv.conf
|
||||
* if (and only if) the file is missing or not a symlink.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE: similar to "unmanaged",
|
||||
* but indicates that resolv.conf cannot be modified.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK: NM writes /etc/resolv.conf
|
||||
* if the file is missing or not a symlink. An existing symlink is
|
||||
* left untouched.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE: Write to /etc/resolv.conf directly.
|
||||
* If it is a file, write it as file, otherwise follow symlinks.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF: NM is managing resolv.conf
|
||||
through resolvconf
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG: NM is managing resolv.conf
|
||||
through netconfig
|
||||
*
|
||||
* NMDnsManager's management of resolv.conf
|
||||
*/
|
||||
typedef enum {
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG,
|
||||
} NMDnsManagerResolvConfManager;
|
||||
|
||||
void nm_dns_manager_stop(NMDnsManager *self);
|
||||
|
||||
NMDnsPlugin *nm_dns_manager_get_systemd_resolved(NMDnsManager *self);
|
||||
|
|
|
|||
|
|
@ -62,22 +62,37 @@ G_DEFINE_ABSTRACT_TYPE(NMDnsPlugin, nm_dns_plugin, G_TYPE_OBJECT)
|
|||
} \
|
||||
G_STMT_END
|
||||
|
||||
NM_UTILS_LOOKUP_STR_DEFINE(
|
||||
_rc_manager_to_string,
|
||||
NMDnsManagerResolvConfManager,
|
||||
NM_UTILS_LOOKUP_DEFAULT_WARN(NULL),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO, "auto"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN, "unknown"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED, "unmanaged"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE, "immutable"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK, "symlink"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE, "file"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF, "resolvconf"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG, "netconfig"), );
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nm_dns_plugin_update(NMDnsPlugin *self,
|
||||
const NMGlobalDnsConfig *global_config,
|
||||
const CList *ip_config_lst_head,
|
||||
const char *hostdomain,
|
||||
GError **error)
|
||||
nm_dns_plugin_update(NMDnsPlugin *self, NMDnsUpdateData *update_data, GError **error)
|
||||
{
|
||||
g_return_val_if_fail(NM_DNS_PLUGIN_GET_CLASS(self)->update != NULL, FALSE);
|
||||
|
||||
return NM_DNS_PLUGIN_GET_CLASS(self)->update(self,
|
||||
global_config,
|
||||
ip_config_lst_head,
|
||||
hostdomain,
|
||||
error);
|
||||
return NM_DNS_PLUGIN_GET_CLASS(self)->update(self, update_data, error);
|
||||
}
|
||||
|
||||
void
|
||||
nm_dns_plugin_checksum(NMDnsPlugin *self,
|
||||
const NML3ConfigData *l3cd,
|
||||
GChecksum *sum,
|
||||
int addr_family,
|
||||
NMDnsIPConfigType dns_ip_config_type)
|
||||
{
|
||||
NM_DNS_PLUGIN_GET_CLASS(self)->checksum(l3cd, sum, addr_family, dns_ip_config_type);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
@ -98,6 +113,27 @@ nm_dns_plugin_get_name(NMDnsPlugin *self)
|
|||
return klass->plugin_name;
|
||||
}
|
||||
|
||||
const guint8 *
|
||||
nm_dns_plugin_get_hash(NMDnsPlugin *self)
|
||||
{
|
||||
NMDnsPluginClass *klass;
|
||||
|
||||
g_return_val_if_fail(NM_IS_DNS_PLUGIN(self), NULL);
|
||||
|
||||
klass = NM_DNS_PLUGIN_GET_CLASS(self);
|
||||
|
||||
return klass->hash;
|
||||
}
|
||||
|
||||
void
|
||||
nm_dns_plugin_set_hash(NMDnsPlugin *self, guint8 *hash)
|
||||
{
|
||||
NMDnsPluginClass *klass;
|
||||
|
||||
klass = NM_DNS_PLUGIN_GET_CLASS(self);
|
||||
memcpy(klass->hash, hash, NM_UTILS_CHECKSUM_LENGTH_SHA1);
|
||||
}
|
||||
|
||||
void
|
||||
nm_dns_plugin_stop(NMDnsPlugin *self)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,6 +21,56 @@
|
|||
|
||||
#define NM_DNS_PLUGIN_UPDATE_PENDING_CHANGED "update-pending-changed"
|
||||
|
||||
/**
|
||||
* NMDnsManagerResolvConfManager
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN: unspecified rc-manager.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED: do not touch /etc/resolv.conf
|
||||
* (but still write the internal copy -- unless it is symlinked by
|
||||
* /etc/resolv.conf)
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO: if /etc/resolv.conf is marked
|
||||
* as an immutable file, use "unmanaged" and don't touch /etc/resolv.conf.
|
||||
* Otherwise, if "systemd-resolved" is enabled (or detected), configure systemd-resolved via D-Bus
|
||||
* and don't touch /etc/resolv.conf.
|
||||
* Otherwise, if "resolvconf" application is found, use it.
|
||||
* As last resort, fallback to "symlink" which writes to /etc/resolv.conf
|
||||
* if (and only if) the file is missing or not a symlink.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE: similar to "unmanaged",
|
||||
* but indicates that resolv.conf cannot be modified.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK: NM writes /etc/resolv.conf
|
||||
* if the file is missing or not a symlink. An existing symlink is
|
||||
* left untouched.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE: Write to /etc/resolv.conf directly.
|
||||
* If it is a file, write it as file, otherwise follow symlinks.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF: NM is managing resolv.conf
|
||||
through resolvconf
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG: NM is managing resolv.conf
|
||||
through netconfig
|
||||
*
|
||||
* NMDnsManager's management of resolv.conf
|
||||
*/
|
||||
typedef enum {
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG,
|
||||
} NMDnsManagerResolvConfManager;
|
||||
|
||||
const char *_rc_manager_to_string(NMDnsManagerResolvConfManager val);
|
||||
|
||||
typedef struct {
|
||||
const CList *ip_data_lst_head;
|
||||
gboolean caching_successful;
|
||||
gboolean resolved_used;
|
||||
gboolean resolver_depends_on_nm;
|
||||
NMDnsManagerResolvConfManager rc_manager;
|
||||
const char *hostdomain;
|
||||
NMGlobalDnsConfig *global_config;
|
||||
} NMDnsUpdateData;
|
||||
|
||||
struct _NMDnsPluginPrivate;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -36,11 +86,7 @@ typedef struct {
|
|||
* 'global_config' is the optional global DNS
|
||||
* configuration.
|
||||
*/
|
||||
gboolean (*update)(NMDnsPlugin *self,
|
||||
const NMGlobalDnsConfig *global_config,
|
||||
const CList *ip_config_lst_head,
|
||||
const char *hostdomain,
|
||||
GError **error);
|
||||
gboolean (*update)(NMDnsPlugin *plugin, NMDnsUpdateData *update_data, GError **error);
|
||||
|
||||
void (*stop)(NMDnsPlugin *self);
|
||||
|
||||
|
|
@ -54,6 +100,15 @@ typedef struct {
|
|||
*/
|
||||
bool is_caching : 1;
|
||||
|
||||
guint8 hash[NM_UTILS_CHECKSUM_LENGTH_SHA1]; /* SHA1 hash of current plugin config */
|
||||
|
||||
/* Each way to set up resolution can be sensitive to different
|
||||
* options or data, this function ensures that update is done
|
||||
* only when relevant data change */
|
||||
void (*checksum)(const NML3ConfigData *l3cd,
|
||||
GChecksum *sum,
|
||||
int addr_family,
|
||||
NMDnsIPConfigType dns_ip_config_type);
|
||||
} NMDnsPluginClass;
|
||||
|
||||
GType nm_dns_plugin_get_type(void);
|
||||
|
|
@ -62,11 +117,17 @@ gboolean nm_dns_plugin_is_caching(NMDnsPlugin *self);
|
|||
|
||||
const char *nm_dns_plugin_get_name(NMDnsPlugin *self);
|
||||
|
||||
gboolean nm_dns_plugin_update(NMDnsPlugin *self,
|
||||
const NMGlobalDnsConfig *global_config,
|
||||
const CList *ip_config_lst_head,
|
||||
const char *hostname,
|
||||
GError **error);
|
||||
const guint8 *nm_dns_plugin_get_hash(NMDnsPlugin *self);
|
||||
|
||||
void nm_dns_plugin_set_hash(NMDnsPlugin *self, guint8 *hash);
|
||||
|
||||
gboolean nm_dns_plugin_update(NMDnsPlugin *self, NMDnsUpdateData *update_data, GError **error);
|
||||
|
||||
void nm_dns_plugin_checksum(NMDnsPlugin *self,
|
||||
const NML3ConfigData *l3cd,
|
||||
GChecksum *sum,
|
||||
int addr_family,
|
||||
NMDnsIPConfigType dns_ip_config_type);
|
||||
|
||||
void nm_dns_plugin_stop(NMDnsPlugin *self);
|
||||
|
||||
|
|
|
|||
1179
src/core/dns/nm-dns-resolv_conf.c
Normal file
1179
src/core/dns/nm-dns-resolv_conf.c
Normal file
File diff suppressed because it is too large
Load diff
29
src/core/dns/nm-dns-resolv_conf.h
Normal file
29
src/core/dns/nm-dns-resolv_conf.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2025 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NETWORKMANAGER_DNS_RESOLVCONF_H__
|
||||
#define __NETWORKMANAGER_DNS_RESOLVCONF_H__
|
||||
|
||||
#include "nm-dns-plugin.h"
|
||||
#include "nm-dns-manager.h"
|
||||
|
||||
#define NM_TYPE_DNS_RESOLVCONF (nm_dns_resolvconf_get_type())
|
||||
#define NM_DNS_RESOLVCONF(obj) \
|
||||
(_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DNS_RESOLVCONF, NMDnsResolvconf))
|
||||
#define NM_DNS_RESOLVCONF_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DNS_RESOLVCONF, NMDnsResolvconfClass))
|
||||
#define NM_IS_DNS_RESOLVCONF(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DNS_RESOLVCONF))
|
||||
#define NM_IS_DNS_RESOLVCONF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DNS_RESOLVCONF))
|
||||
#define NM_DNS_RESOLVCONF_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DNS_RESOLVCONF, NMDnsResolvconfClass))
|
||||
|
||||
typedef struct _NMDnsResolvconf NMDnsResolvconf;
|
||||
typedef struct _NMDnsResolvconfClass NMDnsResolvconfClass;
|
||||
|
||||
GType nm_dns_resolvconf_get_type(void);
|
||||
|
||||
NMDnsPlugin *nm_dns_resolvconf_new(void);
|
||||
|
||||
#endif /* __NETWORKMANAGER_DNS_RESOLVCONF_H__ */
|
||||
|
|
@ -801,11 +801,7 @@ start_resolve:
|
|||
}
|
||||
|
||||
static gboolean
|
||||
update(NMDnsPlugin *plugin,
|
||||
const NMGlobalDnsConfig *global_config,
|
||||
const CList *ip_data_lst_head,
|
||||
const char *hostdomain,
|
||||
GError **error)
|
||||
update(NMDnsPlugin *plugin, NMDnsUpdateData *update_data, GError **error)
|
||||
{
|
||||
NMDnsSystemdResolved *self = NM_DNS_SYSTEMD_RESOLVED(plugin);
|
||||
NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE(self);
|
||||
|
|
@ -826,7 +822,7 @@ update(NMDnsPlugin *plugin,
|
|||
interfaces =
|
||||
g_hash_table_new_full(nm_direct_hash, NULL, NULL, (GDestroyNotify) _interface_config_free);
|
||||
|
||||
c_list_for_each_entry (ip_data, ip_data_lst_head, ip_data_lst) {
|
||||
c_list_for_each_entry (ip_data, update_data->ip_data_lst_head, ip_data_lst) {
|
||||
InterfaceConfig *ic = NULL;
|
||||
int ifindex = ip_data->data->ifindex;
|
||||
|
||||
|
|
@ -1241,6 +1237,68 @@ nm_dns_systemd_resolved_resolve_cancel(NMDnsSystemdResolvedResolveHandle *handle
|
|||
_resolve_complete_error(handle, error);
|
||||
}
|
||||
|
||||
static void
|
||||
resolved_checksum(const NML3ConfigData *l3cd,
|
||||
GChecksum *sum,
|
||||
int addr_family,
|
||||
NMDnsIPConfigType dns_ip_config_type)
|
||||
{
|
||||
guint i;
|
||||
int val;
|
||||
const char *const *strarr;
|
||||
const in_addr_t *wins;
|
||||
guint num_elements;
|
||||
|
||||
g_return_if_fail(l3cd);
|
||||
g_return_if_fail(sum);
|
||||
|
||||
strarr = nm_l3_config_data_get_nameservers(l3cd, addr_family, &num_elements);
|
||||
for (i = 0; i < num_elements; i++) {
|
||||
g_checksum_update(sum, (gpointer) strarr[i], strlen(strarr[i]));
|
||||
}
|
||||
|
||||
if (addr_family == AF_INET) {
|
||||
wins = nm_l3_config_data_get_wins(l3cd, &num_elements);
|
||||
for (i = 0; i < num_elements; i++) {
|
||||
g_checksum_update(sum, (guint8 *) &wins[i], 4);
|
||||
}
|
||||
}
|
||||
|
||||
strarr = nm_l3_config_data_get_domains(l3cd, addr_family, &num_elements);
|
||||
for (i = 0; i < num_elements; i++) {
|
||||
g_checksum_update(sum, (const guint8 *) strarr[i], strlen(strarr[i]));
|
||||
}
|
||||
|
||||
strarr = nm_l3_config_data_get_searches(l3cd, addr_family, &num_elements);
|
||||
for (i = 0; i < num_elements; i++) {
|
||||
g_checksum_update(sum, (const guint8 *) strarr[i], strlen(strarr[i]));
|
||||
}
|
||||
|
||||
val = nm_l3_config_data_get_mdns(l3cd);
|
||||
if (val != NM_SETTING_CONNECTION_MDNS_DEFAULT) {
|
||||
g_checksum_update(sum, (const guint8 *) &val, sizeof(val));
|
||||
}
|
||||
|
||||
val = nm_l3_config_data_get_llmnr(l3cd);
|
||||
if (val != NM_SETTING_CONNECTION_LLMNR_DEFAULT) {
|
||||
g_checksum_update(sum, (const guint8 *) &val, sizeof(val));
|
||||
}
|
||||
|
||||
val = nm_l3_config_data_get_dns_over_tls(l3cd);
|
||||
if (val != NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT) {
|
||||
g_checksum_update(sum, (const guint8 *) &val, sizeof(val));
|
||||
}
|
||||
|
||||
/* Priority has to be included everytime, because even if mdns/llmnr is
|
||||
* left to default value, it could be enabled by default and priority
|
||||
* would decide which interface should be used for mdns/llmnr */
|
||||
|
||||
val = 0;
|
||||
g_checksum_update(sum, (const guint8 *) &dns_ip_config_type, sizeof(dns_ip_config_type));
|
||||
nm_l3_config_data_get_dns_priority(l3cd, addr_family, &val);
|
||||
g_checksum_update(sum, (const guint8 *) &val, sizeof(val));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -1354,4 +1412,5 @@ nm_dns_systemd_resolved_class_init(NMDnsSystemdResolvedClass *dns_class)
|
|||
plugin_class->stop = stop;
|
||||
plugin_class->update = update;
|
||||
plugin_class->get_update_pending = get_update_pending;
|
||||
plugin_class->checksum = resolved_checksum;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ libNetworkManager = static_library(
|
|||
'dhcp/nm-dhcp-listener.c',
|
||||
'dns/nm-dns-dnsmasq.c',
|
||||
'dns/nm-dns-dnsconfd.c',
|
||||
'dns/nm-dns-resolv_conf.c',
|
||||
'dns/nm-dns-manager.c',
|
||||
'dns/nm-dns-plugin.c',
|
||||
'dns/nm-dns-systemd-resolved.c',
|
||||
|
|
|
|||
|
|
@ -1119,7 +1119,8 @@ nm_global_dns_config_update_checksum(const NMGlobalDnsConfig *dns_config, GCheck
|
|||
v8 = NM_HASH_COMBINE_BOOLS(guint8,
|
||||
!dns_config->searches,
|
||||
!dns_config->options,
|
||||
!dns_config->domain_list);
|
||||
!dns_config->domain_list,
|
||||
!dns_config->cert_authority);
|
||||
g_checksum_update(sum, (guchar *) &v8, 1);
|
||||
|
||||
if (dns_config->searches) {
|
||||
|
|
@ -1134,6 +1135,12 @@ nm_global_dns_config_update_checksum(const NMGlobalDnsConfig *dns_config, GCheck
|
|||
(guchar *) dns_config->options[i],
|
||||
strlen(dns_config->options[i]) + 1);
|
||||
}
|
||||
if (dns_config->cert_authority) {
|
||||
g_checksum_update(sum,
|
||||
(guchar *) dns_config->cert_authority,
|
||||
strlen(dns_config->cert_authority) + 1);
|
||||
}
|
||||
g_checksum_update(sum, (guchar *) &dns_config->resolve_mode, sizeof(dns_config->resolve_mode));
|
||||
|
||||
if (dns_config->domain_list) {
|
||||
for (i = 0; dns_config->domain_list[i]; i++) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@
|
|||
#include <netinet/ip6.h>
|
||||
#include <linux/if_packet.h>
|
||||
|
||||
#if WITH_LIBPSL
|
||||
#include <libpsl.h>
|
||||
#endif
|
||||
|
||||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
#include "libnm-platform/nmp-base.h"
|
||||
#include "libnm-std-aux/unaligned.h"
|
||||
|
|
@ -4157,6 +4161,26 @@ nm_utils_g_value_set_strv(GValue *value, GPtrArray *strings)
|
|||
g_value_take_boxed(value, strv);
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_g_ptr_array_add_string_item(GPtrArray *array, const char *str, gboolean dup)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_return_if_fail(array != NULL);
|
||||
g_return_if_fail(str != NULL);
|
||||
|
||||
/* Check for dupes before adding */
|
||||
for (i = 0; i < array->len; i++) {
|
||||
const char *candidate = g_ptr_array_index(array, i);
|
||||
|
||||
if (candidate && nm_streq(candidate, str))
|
||||
return;
|
||||
}
|
||||
|
||||
/* No dupes, add the new item */
|
||||
g_ptr_array_add(array, dup ? g_strdup(str) : (gpointer) str);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *
|
||||
|
|
@ -4455,6 +4479,56 @@ nm_utils_parse_dns_domain(const char *domain, gboolean *is_routing)
|
|||
return domain;
|
||||
}
|
||||
|
||||
inline gboolean
|
||||
nm_domain_is_routing(const char *domain)
|
||||
{
|
||||
return domain[0] == '~';
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_domain_is_valid(const char *domain,
|
||||
gboolean reject_public_suffix,
|
||||
gboolean assume_any_tld_is_public)
|
||||
{
|
||||
if (*domain == '\0')
|
||||
return FALSE;
|
||||
|
||||
if (reject_public_suffix) {
|
||||
int is_pub;
|
||||
|
||||
#if !WITH_LIBPSL
|
||||
/* Without libpsl, we cannot detect that the domain is a public suffix, we assume
|
||||
* the domain is not and valid. */
|
||||
is_pub = FALSE;
|
||||
#elif defined(PSL_TYPE_NO_STAR_RULE)
|
||||
/*
|
||||
* If we use PSL_TYPE_ANY, any TLD (top-level domain, i.e., domain
|
||||
* with no dots) is considered *public* by the PSL library even if
|
||||
* it is *not* on the official suffix list. This is the implicit
|
||||
* behavior of the older API function psl_is_public_suffix().
|
||||
* To inhibit that and only deem TLDs explicitly listed in the PSL
|
||||
* as public, we need to turn off the "prevailing star rule" with
|
||||
* PSL_TYPE_NO_STAR_RULE.
|
||||
* For documentation on psl_is_public_suffix2(), see:
|
||||
* https://rockdaboot.github.io/libpsl/libpsl-Public-Suffix-List-functions.html#psl-is-public-suffix2
|
||||
* For more on the public suffix format, including wildcards:
|
||||
* https://github.com/publicsuffix/list/wiki/Format#format
|
||||
*/
|
||||
is_pub =
|
||||
psl_is_public_suffix2(psl_builtin(),
|
||||
domain,
|
||||
assume_any_tld_is_public ? PSL_TYPE_ANY : PSL_TYPE_NO_STAR_RULE);
|
||||
#else
|
||||
is_pub = psl_is_public_suffix(psl_builtin(), domain);
|
||||
#endif
|
||||
|
||||
if (is_pub)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static guint32
|
||||
|
|
|
|||
|
|
@ -423,6 +423,8 @@ void _nm_utils_set_testing(NMUtilsTestFlags flags);
|
|||
|
||||
void nm_utils_g_value_set_strv(GValue *value, GPtrArray *strings);
|
||||
|
||||
void nm_utils_g_ptr_array_add_string_item(GPtrArray *array, const char *str, gboolean dup);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *nm_utils_dnsmasq_status_to_string(int status, char *dest, gsize size);
|
||||
|
|
@ -457,6 +459,12 @@ const char *nm_activation_type_to_string(NMActivationType activation_type);
|
|||
|
||||
const char *nm_utils_parse_dns_domain(const char *domain, gboolean *is_routing);
|
||||
|
||||
gboolean nm_domain_is_routing(const char *domain);
|
||||
|
||||
gboolean nm_domain_is_valid(const char *domain,
|
||||
gboolean reject_public_suffix,
|
||||
gboolean assume_any_tld_is_public);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void nm_wifi_utils_parse_ies(const guint8 *bytes,
|
||||
|
|
|
|||
|
|
@ -219,6 +219,43 @@ _garray_inaddr_clone(const GArray *src, int addr_family)
|
|||
return dst;
|
||||
}
|
||||
|
||||
void
|
||||
nm_l3_config_data_get_dns_domains(GPtrArray *array,
|
||||
int addr_family,
|
||||
const NML3ConfigData *l3cd,
|
||||
gboolean include_routing,
|
||||
gboolean dup)
|
||||
{
|
||||
const char *const *domains;
|
||||
const char *const *searches;
|
||||
guint num_domains;
|
||||
guint num_searches;
|
||||
guint i;
|
||||
const char *str;
|
||||
|
||||
domains = nm_l3_config_data_get_domains(l3cd, addr_family, &num_domains);
|
||||
searches = nm_l3_config_data_get_searches(l3cd, addr_family, &num_searches);
|
||||
|
||||
for (i = 0; i < num_searches; i++) {
|
||||
str = searches[i];
|
||||
if (!include_routing && nm_domain_is_routing(str))
|
||||
continue;
|
||||
if (!nm_domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE, TRUE))
|
||||
continue;
|
||||
nm_utils_g_ptr_array_add_string_item(array, str, dup);
|
||||
}
|
||||
if (num_domains > 1 || num_searches == 0) {
|
||||
for (i = 0; i < num_domains; i++) {
|
||||
str = domains[i];
|
||||
if (!include_routing && nm_domain_is_routing(str))
|
||||
continue;
|
||||
if (!nm_domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE, TRUE))
|
||||
continue;
|
||||
nm_utils_g_ptr_array_add_string_item(array, str, dup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_garray_inaddr_merge(GArray **p_dst, const GArray *src, int addr_family)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -608,6 +608,12 @@ void nm_l3_config_data_set_allow_routes_without_address(NML3ConfigData *self,
|
|||
gboolean nm_l3_config_data_get_routed_dns(const NML3ConfigData *self, int addr_family);
|
||||
void nm_l3_config_data_set_routed_dns(NML3ConfigData *self, int addr_family, gboolean value);
|
||||
|
||||
void nm_l3_config_data_get_dns_domains(GPtrArray *array,
|
||||
int addr_family,
|
||||
const NML3ConfigData *l3cd,
|
||||
gboolean include_routing,
|
||||
gboolean dup);
|
||||
|
||||
NMProxyConfigMethod nm_l3_config_data_get_proxy_method(const NML3ConfigData *self);
|
||||
|
||||
gboolean nm_l3_config_data_set_proxy_method(NML3ConfigData *self, NMProxyConfigMethod value);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue