mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-09-16 06:40:41 +00:00
policy: use the hostname setting
Rework update_system_hostname() to use the new properties from the hostname setting. In the default configuration where all the 3 boolean properties hostname.{from-dhcp,from-dns,only-from-default} are true, the behavior is the same as before.
This commit is contained in:
parent
abd002642f
commit
09c8387114
|
@ -206,6 +206,23 @@ typedef struct {
|
|||
NMEthtoolRingState * ring;
|
||||
} EthtoolState;
|
||||
|
||||
typedef enum {
|
||||
RESOLVER_WAIT_ADDRESS = 0,
|
||||
RESOLVER_IN_PROGRESS,
|
||||
RESOLVER_DONE,
|
||||
} ResolverState;
|
||||
|
||||
typedef struct {
|
||||
ResolverState state;
|
||||
GResolver * resolver;
|
||||
GInetAddress *address;
|
||||
GCancellable *cancellable;
|
||||
char * hostname;
|
||||
NMDevice * device;
|
||||
guint timeout_id; /* Used when waiting for the address */
|
||||
int addr_family;
|
||||
} HostnameResolver;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
enum {
|
||||
|
@ -218,6 +235,7 @@ enum {
|
|||
REMOVED,
|
||||
RECHECK_AUTO_ACTIVATE,
|
||||
RECHECK_ASSUME,
|
||||
DNS_LOOKUP_DONE,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
static guint signals[LAST_SIGNAL] = {0};
|
||||
|
@ -324,6 +342,14 @@ typedef struct _NMDevicePrivate {
|
|||
|
||||
int auth_retries;
|
||||
|
||||
union {
|
||||
struct {
|
||||
HostnameResolver *hostname_resolver_6;
|
||||
HostnameResolver *hostname_resolver_4;
|
||||
};
|
||||
HostnameResolver *hostname_resolver_x[2];
|
||||
};
|
||||
|
||||
union {
|
||||
const guint8 hw_addr_len; /* read-only */
|
||||
guint8 hw_addr_len_;
|
||||
|
@ -866,6 +892,22 @@ static NM_UTILS_LOOKUP_STR_DEFINE(mtu_source_to_str,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_hostname_resolver_free(HostnameResolver *resolver)
|
||||
{
|
||||
if (!resolver)
|
||||
return;
|
||||
|
||||
nm_clear_g_source(&resolver->timeout_id);
|
||||
nm_clear_g_cancellable(&resolver->cancellable);
|
||||
nm_g_object_unref(resolver->resolver);
|
||||
nm_g_object_unref(resolver->address);
|
||||
g_free(resolver->hostname);
|
||||
nm_g_slice_free(resolver);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static NMSettingIP6ConfigPrivacy
|
||||
_ip6_privacy_clamp(NMSettingIP6ConfigPrivacy use_tempaddr)
|
||||
{
|
||||
|
@ -15618,6 +15660,7 @@ static void
|
|||
_cleanup_generic_pre(NMDevice *self, CleanupType cleanup_type)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
guint i;
|
||||
|
||||
_cancel_activation(self);
|
||||
|
||||
|
@ -15642,6 +15685,9 @@ _cleanup_generic_pre(NMDevice *self, CleanupType cleanup_type)
|
|||
|
||||
nm_clear_pointer(&priv->shared_ip_handle, nm_netns_shared_ip_release);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
nm_clear_pointer(&priv->hostname_resolver_x[i], _hostname_resolver_free);
|
||||
|
||||
_cleanup_ip_pre(self, AF_INET, cleanup_type);
|
||||
_cleanup_ip_pre(self, AF_INET6, cleanup_type);
|
||||
}
|
||||
|
@ -17467,6 +17513,178 @@ nm_device_auth_retries_try_next(NMDevice *self)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
hostname_dns_lookup_callback(GObject *source, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
HostnameResolver *resolver;
|
||||
NMDevice * self;
|
||||
gs_free char * hostname = NULL;
|
||||
gs_free char * addr_str = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
hostname = g_resolver_lookup_by_address_finish(G_RESOLVER(source), result, &error);
|
||||
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
resolver = user_data;
|
||||
self = resolver->device;
|
||||
resolver->state = RESOLVER_DONE;
|
||||
resolver->hostname = g_strdup(hostname);
|
||||
|
||||
_LOGD(LOGD_DNS,
|
||||
"hostname-from-dns: lookup done for %s, result %s%s%s",
|
||||
(addr_str = g_inet_address_to_string(resolver->address)),
|
||||
NM_PRINT_FMT_QUOTE_STRING(hostname));
|
||||
|
||||
nm_clear_g_cancellable(&resolver->cancellable);
|
||||
g_signal_emit(self, signals[DNS_LOOKUP_DONE], 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
hostname_dns_address_timeout(gpointer user_data)
|
||||
{
|
||||
HostnameResolver *resolver = user_data;
|
||||
NMDevice * self = resolver->device;
|
||||
|
||||
g_return_val_if_fail(NM_IS_DEVICE(self), G_SOURCE_REMOVE);
|
||||
|
||||
nm_assert(resolver->state == RESOLVER_WAIT_ADDRESS);
|
||||
nm_assert(!resolver->address);
|
||||
nm_assert(!resolver->cancellable);
|
||||
|
||||
_LOGT(LOGD_DNS,
|
||||
"hostname-from-dns: timed out while waiting IPv%c address",
|
||||
nm_utils_addr_family_to_char(resolver->addr_family));
|
||||
|
||||
resolver->timeout_id = 0;
|
||||
resolver->state = RESOLVER_DONE;
|
||||
g_signal_emit(self, signals[DNS_LOOKUP_DONE], 0);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/* return value is valid only immediately */
|
||||
const char *
|
||||
nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean *out_wait)
|
||||
{
|
||||
NMDevicePrivate * priv;
|
||||
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
||||
HostnameResolver *resolver;
|
||||
NMIPConfig * ip_config;
|
||||
const char * method;
|
||||
gboolean address_changed = FALSE;
|
||||
gs_unref_object GInetAddress *new_address = NULL;
|
||||
|
||||
g_return_val_if_fail(NM_IS_DEVICE(self), NULL);
|
||||
priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
|
||||
/* If the device is not supposed to have addresses,
|
||||
* return an immediate empty result.*/
|
||||
method = nm_device_get_effective_ip_config_method(self, addr_family);
|
||||
if (IS_IPv4) {
|
||||
if (NM_IN_STRSET(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
|
||||
nm_clear_pointer(&priv->hostname_resolver_x[IS_IPv4], _hostname_resolver_free);
|
||||
NM_SET_OUT(out_wait, FALSE);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (NM_IN_STRSET(method,
|
||||
NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
|
||||
NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) {
|
||||
nm_clear_pointer(&priv->hostname_resolver_x[IS_IPv4], _hostname_resolver_free);
|
||||
NM_SET_OUT(out_wait, FALSE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
resolver = priv->hostname_resolver_x[IS_IPv4];
|
||||
if (!resolver) {
|
||||
resolver = g_slice_new(HostnameResolver);
|
||||
*resolver = (HostnameResolver){
|
||||
.resolver = g_resolver_get_default(),
|
||||
.device = self,
|
||||
.addr_family = addr_family,
|
||||
.state = RESOLVER_WAIT_ADDRESS,
|
||||
};
|
||||
priv->hostname_resolver_x[IS_IPv4] = resolver;
|
||||
}
|
||||
|
||||
/* Determine the first address of the interface and
|
||||
* whether it changed from the previous lookup */
|
||||
ip_config = priv->ip_config_x[IS_IPv4];
|
||||
if (ip_config) {
|
||||
const NMPlatformIPAddress *addr;
|
||||
|
||||
addr = nm_ip_config_get_first_address(ip_config);
|
||||
if (addr) {
|
||||
new_address = g_inet_address_new_from_bytes(addr->address_ptr,
|
||||
IS_IPv4 ? G_SOCKET_FAMILY_IPV4
|
||||
: G_SOCKET_FAMILY_IPV6);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_address && resolver->address) {
|
||||
if (!g_inet_address_equal(new_address, resolver->address))
|
||||
address_changed = TRUE;
|
||||
} else if (new_address != resolver->address)
|
||||
address_changed = TRUE;
|
||||
|
||||
{
|
||||
gs_free char *old_str = NULL;
|
||||
gs_free char *new_str = NULL;
|
||||
|
||||
_LOGT(LOGD_DNS,
|
||||
"hostname-from-dns: ipv%c resolver state %d, old address %s, new address %s",
|
||||
nm_utils_addr_family_to_char(resolver->addr_family),
|
||||
resolver->state,
|
||||
resolver->address ? (old_str = g_inet_address_to_string(resolver->address))
|
||||
: "(null)",
|
||||
new_address ? (new_str = g_inet_address_to_string(new_address)) : "(null)");
|
||||
}
|
||||
|
||||
/* In every state, if the address changed, we restart
|
||||
* the resolution with the new address */
|
||||
if (address_changed) {
|
||||
nm_clear_g_cancellable(&resolver->cancellable);
|
||||
nm_g_object_unref(resolver->address);
|
||||
resolver->state = RESOLVER_WAIT_ADDRESS;
|
||||
}
|
||||
|
||||
if (address_changed && new_address) {
|
||||
gs_free char *str = NULL;
|
||||
|
||||
_LOGT(LOGD_DNS,
|
||||
"hostname-from-dns: starting lookup for address %s",
|
||||
(str = g_inet_address_to_string(new_address)));
|
||||
|
||||
resolver->state = RESOLVER_IN_PROGRESS;
|
||||
resolver->cancellable = g_cancellable_new();
|
||||
resolver->address = g_steal_pointer(&new_address);
|
||||
g_resolver_lookup_by_address_async(resolver->resolver,
|
||||
resolver->address,
|
||||
resolver->cancellable,
|
||||
hostname_dns_lookup_callback,
|
||||
resolver);
|
||||
nm_clear_g_source(&resolver->timeout_id);
|
||||
}
|
||||
|
||||
switch (resolver->state) {
|
||||
case RESOLVER_WAIT_ADDRESS:
|
||||
if (!resolver->timeout_id)
|
||||
resolver->timeout_id = g_timeout_add(30000, hostname_dns_address_timeout, resolver);
|
||||
NM_SET_OUT(out_wait, TRUE);
|
||||
return NULL;
|
||||
case RESOLVER_IN_PROGRESS:
|
||||
NM_SET_OUT(out_wait, TRUE);
|
||||
return NULL;
|
||||
case RESOLVER_DONE:
|
||||
NM_SET_OUT(out_wait, FALSE);
|
||||
return resolver->hostname;
|
||||
}
|
||||
|
||||
return nm_assert_unreachable_val(NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const char *
|
||||
|
@ -18644,6 +18862,16 @@ nm_device_class_init(NMDeviceClass *klass)
|
|||
NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
signals[DNS_LOOKUP_DONE] = g_signal_new(NM_DEVICE_DNS_LOOKUP_DONE,
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
||||
|
||||
/* Connection defaults from plugins */
|
||||
|
|
|
@ -116,6 +116,7 @@ nm_device_state_reason_check(NMDeviceStateReason reason)
|
|||
#define NM_DEVICE_HAS_PENDING_ACTION "has-pending-action" /* Internal only */
|
||||
|
||||
/* Internal signals */
|
||||
#define NM_DEVICE_DNS_LOOKUP_DONE "dns-lookup-done"
|
||||
#define NM_DEVICE_IP4_CONFIG_CHANGED "ip4-config-changed"
|
||||
#define NM_DEVICE_IP6_CONFIG_CHANGED "ip6-config-changed"
|
||||
#define NM_DEVICE_IP6_PREFIX_DELEGATED "ip6-prefix-delegated"
|
||||
|
@ -863,4 +864,7 @@ const char *nm_device_state_reason_to_str(NMDeviceStateReason reason);
|
|||
|
||||
gboolean nm_device_is_vpn(NMDevice *self);
|
||||
|
||||
const char *
|
||||
nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean *out_pending);
|
||||
|
||||
#endif /* __NETWORKMANAGER_DEVICE_H__ */
|
||||
|
|
310
src/nm-policy.c
310
src/nm-policy.c
|
@ -117,6 +117,8 @@ _PRIV_TO_SELF(NMPolicyPrivate *priv)
|
|||
/*****************************************************************************/
|
||||
|
||||
#define _NMLOG_PREFIX_NAME "policy"
|
||||
#undef _NMLOG_ENABLED
|
||||
#define _NMLOG_ENABLED(level, domain) (nm_logging_enabled((level), (domain)))
|
||||
#define _NMLOG(level, domain, ...) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
|
@ -131,6 +133,7 @@ _PRIV_TO_SELF(NMPolicyPrivate *priv)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void update_system_hostname(NMPolicy *self, const char *msg);
|
||||
static void schedule_activate_all(NMPolicy *self);
|
||||
static void schedule_activate_check(NMPolicy *self, NMDevice *device);
|
||||
static NMDevice *get_default_device(NMPolicy *self, int addr_family);
|
||||
|
@ -671,20 +674,168 @@ lookup_by_address(NMPolicy *self)
|
|||
self);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
NMDevice *device;
|
||||
int priority;
|
||||
bool from_dhcp : 1;
|
||||
bool from_dns : 1;
|
||||
|
||||
union {
|
||||
struct {
|
||||
bool ip_6;
|
||||
bool ip_4;
|
||||
};
|
||||
bool ip_x[2];
|
||||
};
|
||||
} DeviceHostnameInfo;
|
||||
|
||||
static int
|
||||
device_hostname_info_compare(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const DeviceHostnameInfo *info1 = a;
|
||||
const DeviceHostnameInfo *info2 = b;
|
||||
|
||||
NM_CMP_FIELD(info1, info2, priority);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NM_CON_DEFAULT_NOP("hostname.from-dhcp");
|
||||
NM_CON_DEFAULT_NOP("hostname.from-dns-lookup");
|
||||
NM_CON_DEFAULT_NOP("hostname.only-from-default");
|
||||
|
||||
static gboolean
|
||||
device_get_hostname_property_boolean(NMDevice *device, const char *name)
|
||||
{
|
||||
NMSettingHostname *s_hostname;
|
||||
char buf[128];
|
||||
int value;
|
||||
|
||||
nm_assert(NM_IN_STRSET(name,
|
||||
NM_SETTING_HOSTNAME_FROM_DHCP,
|
||||
NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP,
|
||||
NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT));
|
||||
|
||||
s_hostname = nm_device_get_applied_setting(device, NM_TYPE_SETTING_HOSTNAME);
|
||||
|
||||
if (s_hostname) {
|
||||
g_object_get(s_hostname, name, &value, NULL);
|
||||
if (NM_IN_SET(value, NM_TERNARY_FALSE, NM_TERNARY_TRUE))
|
||||
return value;
|
||||
}
|
||||
|
||||
return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
|
||||
nm_sprintf_buf(buf, "hostname.%s", name),
|
||||
device,
|
||||
NM_TERNARY_FALSE,
|
||||
NM_TERNARY_TRUE,
|
||||
NM_TERNARY_TRUE);
|
||||
}
|
||||
|
||||
static int
|
||||
device_get_hostname_priority(NMDevice *device)
|
||||
{
|
||||
NMSettingHostname *s_hostname;
|
||||
int priority;
|
||||
|
||||
s_hostname = nm_device_get_applied_setting(device, NM_TYPE_SETTING_HOSTNAME);
|
||||
if (s_hostname) {
|
||||
priority = nm_setting_hostname_get_priority(s_hostname);
|
||||
if (priority != 0)
|
||||
return priority;
|
||||
}
|
||||
|
||||
return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
|
||||
NM_CON_DEFAULT("hostname.priority"),
|
||||
device,
|
||||
G_MININT,
|
||||
G_MAXINT,
|
||||
100);
|
||||
}
|
||||
|
||||
static GArray *
|
||||
build_device_hostname_infos(NMPolicy *self)
|
||||
{
|
||||
NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self);
|
||||
const CList * tmp_clist;
|
||||
NMActiveConnection *ac;
|
||||
GArray * array = NULL;
|
||||
|
||||
nm_manager_for_each_active_connection (priv->manager, ac, tmp_clist) {
|
||||
DeviceHostnameInfo *info;
|
||||
NMDevice * device;
|
||||
gboolean only_from_default;
|
||||
|
||||
device = nm_active_connection_get_device(ac);
|
||||
if (!device)
|
||||
continue;
|
||||
|
||||
only_from_default =
|
||||
device_get_hostname_property_boolean(device, NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT);
|
||||
if (only_from_default && ac != priv->default_ac4 && ac != priv->default_ac6)
|
||||
continue;
|
||||
|
||||
if (!array)
|
||||
array = g_array_sized_new(FALSE, FALSE, sizeof(DeviceHostnameInfo), 4);
|
||||
|
||||
info = nm_g_array_append_new(array, DeviceHostnameInfo);
|
||||
*info = (DeviceHostnameInfo){
|
||||
.device = device,
|
||||
.priority = device_get_hostname_priority(device),
|
||||
.from_dhcp =
|
||||
device_get_hostname_property_boolean(device, NM_SETTING_HOSTNAME_FROM_DHCP),
|
||||
.from_dns =
|
||||
device_get_hostname_property_boolean(device, NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP),
|
||||
.ip_4 = priv->default_ac4 || !only_from_default,
|
||||
.ip_6 = priv->default_ac6 || !only_from_default,
|
||||
};
|
||||
}
|
||||
|
||||
if (array && array->len > 1) {
|
||||
const DeviceHostnameInfo *info0;
|
||||
guint i;
|
||||
|
||||
g_array_sort(array, device_hostname_info_compare);
|
||||
|
||||
info0 = &g_array_index(array, DeviceHostnameInfo, 0);
|
||||
if (info0->priority < 0) {
|
||||
for (i = 1; i < array->len; i++) {
|
||||
const DeviceHostnameInfo *info = &g_array_index(array, DeviceHostnameInfo, i);
|
||||
|
||||
if (info->priority > info0->priority) {
|
||||
g_array_set_size(array, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
static void
|
||||
device_dns_lookup_done(NMDevice *device, gpointer user_data)
|
||||
{
|
||||
NMPolicy *self = user_data;
|
||||
|
||||
g_signal_handlers_disconnect_by_func(device, device_dns_lookup_done, self);
|
||||
|
||||
update_system_hostname(self, "lookup finished");
|
||||
}
|
||||
|
||||
static void
|
||||
update_system_hostname(NMPolicy *self, const char *msg)
|
||||
{
|
||||
NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self);
|
||||
const char * configured_hostname;
|
||||
gs_free char * temp_hostname = NULL;
|
||||
const char * dhcp_hostname, *p;
|
||||
NMIP4Config * ip4_config;
|
||||
NMIP6Config * ip6_config;
|
||||
gboolean external_hostname = FALSE;
|
||||
const NMPlatformIP4Address *addr4;
|
||||
const NMPlatformIP6Address *addr6;
|
||||
NMDevice * device;
|
||||
NMDhcpConfig * dhcp_config;
|
||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self);
|
||||
const char * configured_hostname;
|
||||
gs_free char * temp_hostname = NULL;
|
||||
const char * dhcp_hostname, *p;
|
||||
gboolean external_hostname = FALSE;
|
||||
NMDhcpConfig * dhcp_config;
|
||||
gs_unref_array GArray *infos = NULL;
|
||||
DeviceHostnameInfo * info;
|
||||
guint i;
|
||||
int IS_IPv4;
|
||||
|
||||
g_return_if_fail(self != NULL);
|
||||
|
||||
|
@ -724,10 +875,9 @@ update_system_hostname(NMPolicy *self, const char *msg)
|
|||
/* Hostname precedence order:
|
||||
*
|
||||
* 1) a configured hostname (from settings)
|
||||
* 2) automatic hostname from the default device's config (DHCP, VPN, etc)
|
||||
* 3) the last hostname set outside NM
|
||||
* 4) reverse-DNS of the best device's IPv4 address
|
||||
*
|
||||
* 2) automatic hostname from DHCP of eligible interfaces
|
||||
* 3) reverse-DNS lookup of the first address on eligible interfaces
|
||||
* 4) the last hostname set outside NM
|
||||
*/
|
||||
|
||||
/* Try a persistent hostname first */
|
||||
|
@ -738,40 +888,73 @@ update_system_hostname(NMPolicy *self, const char *msg)
|
|||
return;
|
||||
}
|
||||
|
||||
if (priv->default_ac4) {
|
||||
/* Grab a hostname out of the device's DHCP4 config */
|
||||
dhcp_config = nm_device_get_dhcp_config(get_default_device(self, AF_INET), AF_INET);
|
||||
if (dhcp_config) {
|
||||
dhcp_hostname = nm_dhcp_config_get_option(dhcp_config, "host_name");
|
||||
if (dhcp_hostname && dhcp_hostname[0]) {
|
||||
p = nm_str_skip_leading_spaces(dhcp_hostname);
|
||||
if (p[0]) {
|
||||
_set_hostname(self, p, "from DHCPv4");
|
||||
priv->dhcp_hostname = TRUE;
|
||||
return;
|
||||
}
|
||||
_LOGW(LOGD_DNS,
|
||||
"set-hostname: DHCPv4-provided hostname '%s' looks invalid; ignoring it",
|
||||
dhcp_hostname);
|
||||
}
|
||||
infos = build_device_hostname_infos(self);
|
||||
|
||||
if (infos && _LOGT_ENABLED(LOGD_DNS)) {
|
||||
_LOGT(LOGD_DNS, "device hostname info:");
|
||||
for (i = 0; i < infos->len; i++) {
|
||||
info = &g_array_index(infos, DeviceHostnameInfo, i);
|
||||
_LOGT(LOGD_DNS,
|
||||
" - prio:%4d ipv:%c%c dhcp:%d dns:%d dev:%s",
|
||||
info->priority,
|
||||
info->ip_4 ? '4' : '-',
|
||||
info->ip_6 ? '6' : '-',
|
||||
info->from_dhcp,
|
||||
info->from_dns,
|
||||
nm_device_get_iface(info->device));
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->default_ac6) {
|
||||
/* Grab a hostname out of the device's DHCP6 config */
|
||||
dhcp_config = nm_device_get_dhcp_config(get_default_device(self, AF_INET6), AF_INET6);
|
||||
if (dhcp_config) {
|
||||
dhcp_hostname = nm_dhcp_config_get_option(dhcp_config, "fqdn_fqdn");
|
||||
if (dhcp_hostname && dhcp_hostname[0]) {
|
||||
p = nm_str_skip_leading_spaces(dhcp_hostname);
|
||||
if (p[0]) {
|
||||
_set_hostname(self, p, "from DHCPv6");
|
||||
priv->dhcp_hostname = TRUE;
|
||||
return;
|
||||
for (i = 0; infos && i < infos->len; i++) {
|
||||
info = &g_array_index(infos, DeviceHostnameInfo, i);
|
||||
g_signal_handlers_disconnect_by_func(info->device, device_dns_lookup_done, self);
|
||||
for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) {
|
||||
const int addr_family = IS_IPv4 ? AF_INET : AF_INET6;
|
||||
|
||||
if (info->from_dhcp && info->ip_x[IS_IPv4]) {
|
||||
dhcp_config = nm_device_get_dhcp_config(info->device, addr_family);
|
||||
if (dhcp_config) {
|
||||
dhcp_hostname =
|
||||
nm_dhcp_config_get_option(dhcp_config, IS_IPv4 ? "host_name" : "fqdn_fqdn");
|
||||
if (dhcp_hostname && dhcp_hostname[0]) {
|
||||
p = nm_str_skip_leading_spaces(dhcp_hostname);
|
||||
if (p[0]) {
|
||||
_set_hostname(self, p, IS_IPv4 ? "from DHCPv4" : "from DHCPv6");
|
||||
priv->dhcp_hostname = TRUE;
|
||||
return;
|
||||
}
|
||||
_LOGW(LOGD_DNS,
|
||||
"set-hostname: DHCPv%c-provided hostname '%s' looks invalid; "
|
||||
"ignoring it",
|
||||
nm_utils_addr_family_to_char(addr_family),
|
||||
dhcp_hostname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->hostname_mode != NM_POLICY_HOSTNAME_MODE_DHCP) {
|
||||
for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) {
|
||||
const int addr_family = IS_IPv4 ? AF_INET6 : AF_INET;
|
||||
|
||||
if (info->from_dns && info->ip_x[IS_IPv4]) {
|
||||
const char *result;
|
||||
gboolean wait;
|
||||
|
||||
result =
|
||||
nm_device_get_hostname_from_dns_lookup(info->device, addr_family, &wait);
|
||||
if (result) {
|
||||
_set_hostname(self, result, "from address lookup");
|
||||
return;
|
||||
}
|
||||
if (wait) {
|
||||
g_signal_connect(info->device,
|
||||
NM_DEVICE_DNS_LOOKUP_DONE,
|
||||
(GCallback) device_dns_lookup_done,
|
||||
self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_LOGW(LOGD_DNS,
|
||||
"set-hostname: DHCPv6-provided hostname '%s' looks invalid; ignoring it",
|
||||
dhcp_hostname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -795,14 +978,6 @@ update_system_hostname(NMPolicy *self, const char *msg)
|
|||
|
||||
priv->dhcp_hostname = FALSE;
|
||||
|
||||
if (!priv->default_ac4 && !priv->default_ac6) {
|
||||
/* No best device; fall back to the last hostname set externally
|
||||
* to NM or if there wasn't one, 'localhost.localdomain'
|
||||
*/
|
||||
_set_hostname(self, priv->orig_hostname, "no default device");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If no automatically-configured hostname, try using the last hostname
|
||||
* set externally to NM
|
||||
*/
|
||||
|
@ -811,30 +986,7 @@ update_system_hostname(NMPolicy *self, const char *msg)
|
|||
return;
|
||||
}
|
||||
|
||||
/* No configured hostname, no automatically determined hostname, and no
|
||||
* bootup hostname. Start reverse DNS of the current IPv4 or IPv6 address.
|
||||
*/
|
||||
device = get_default_device(self, AF_INET);
|
||||
ip4_config = device ? nm_device_get_ip4_config(device) : NULL;
|
||||
|
||||
device = get_default_device(self, AF_INET6);
|
||||
ip6_config = device ? nm_device_get_ip6_config(device) : NULL;
|
||||
|
||||
if (ip4_config && (addr4 = nm_ip4_config_get_first_address(ip4_config))) {
|
||||
g_clear_object(&priv->lookup.addr);
|
||||
priv->lookup.addr =
|
||||
g_inet_address_new_from_bytes((guint8 *) &addr4->address, G_SOCKET_FAMILY_IPV4);
|
||||
} else if (ip6_config && (addr6 = nm_ip6_config_get_first_address(ip6_config))) {
|
||||
g_clear_object(&priv->lookup.addr);
|
||||
priv->lookup.addr =
|
||||
g_inet_address_new_from_bytes((guint8 *) &addr6->address, G_SOCKET_FAMILY_IPV6);
|
||||
} else {
|
||||
/* No valid IP config; fall back to localhost.localdomain */
|
||||
_set_hostname(self, NULL, "no IP config");
|
||||
return;
|
||||
}
|
||||
|
||||
lookup_by_address(self);
|
||||
_set_hostname(self, NULL, "no hostname found");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1796,6 +1948,8 @@ device_state_changed(NMDevice * device,
|
|||
|
||||
switch (new_state) {
|
||||
case NM_DEVICE_STATE_FAILED:
|
||||
g_signal_handlers_disconnect_by_func(device, device_dns_lookup_done, self);
|
||||
|
||||
/* Mark the connection invalid if it failed during activation so that
|
||||
* it doesn't get automatically chosen over and over and over again.
|
||||
*/
|
||||
|
@ -1934,6 +2088,8 @@ device_state_changed(NMDevice * device,
|
|||
ip6_remove_device_prefix_delegations(self, device);
|
||||
break;
|
||||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
g_signal_handlers_disconnect_by_func(device, device_dns_lookup_done, self);
|
||||
|
||||
/* Reset retry counts for a device's connections when carrier on; if cable
|
||||
* was unplugged and plugged in again, we should try to reconnect.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue