mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-06-20 05:58:30 +02:00
The flag is used for both sleeping and networking disabled conditions. This is because internally they share logic, but it's not obvious for users and it has caused confusion in the past when investigating why devices didn't become managed. Make it explicit that it can be because of either reason. It would be better to create two separate flags, actually, and it doesn't seem complex, but better not to risk introducing bugs for that little benefit. Logs before: device (enp4s0): state change: disconnected -> unmanaged (reason 'unmanaged-sleeping' ... Logs before: device (enp4s0): state change: disconnected -> unmanaged (reason 'unmanaged-nm-disabled' ...
404 lines
21 KiB
C
404 lines
21 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#include "src/core/nm-default-daemon.h"
|
|
#include "src/core/dns/nm-dns-manager.h"
|
|
#include "src/core/dns/nm-dns-systemd-resolved.h"
|
|
|
|
#include "nm-device-utils.h"
|
|
#include "nm-core-utils.h"
|
|
|
|
/*****************************************************************************/
|
|
|
|
NM_UTILS_LOOKUP_STR_DEFINE(
|
|
nm_device_state_queued_state_to_string,
|
|
NMDeviceState,
|
|
NM_UTILS_LOOKUP_DEFAULT(NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "???"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNKNOWN,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unknown"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNMANAGED,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unmanaged"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNAVAILABLE,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unavailable"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_DISCONNECTED,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "disconnected"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_PREPARE,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "prepare"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_CONFIG,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "config"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_NEED_AUTH,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "need-auth"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_IP_CONFIG,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-config"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_IP_CHECK,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-check"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_SECONDARIES,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "secondaries"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_ACTIVATED,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "activated"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_DEACTIVATING,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "deactivating"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_FAILED,
|
|
NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "failed"), );
|
|
|
|
const char *
|
|
nm_device_state_to_string(NMDeviceState state)
|
|
{
|
|
return nm_device_state_queued_state_to_string(state)
|
|
+ NM_STRLEN(NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE);
|
|
}
|
|
|
|
NM_UTILS_LOOKUP_STR_DEFINE(
|
|
nm_device_state_reason_to_string,
|
|
NMDeviceStateReason,
|
|
NM_UTILS_LOOKUP_DEFAULT(NULL),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNKNOWN, "unknown"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NONE, "none"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NOW_MANAGED, "managed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NOW_UNMANAGED, "unmanaged"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONFIG_FAILED, "config-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE, "ip-config-unavailable"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED, "ip-config-expired"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NO_SECRETS, "no-secrets"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT, "supplicant-disconnect"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED,
|
|
"supplicant-config-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED, "supplicant-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT, "supplicant-timeout"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_START_FAILED, "ppp-start-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_DISCONNECT, "ppp-disconnect"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_FAILED, "ppp-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_START_FAILED, "dhcp-start-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_ERROR, "dhcp-error"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_FAILED, "dhcp-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SHARED_START_FAILED, "sharing-start-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SHARED_FAILED, "sharing-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED, "autoip-start-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_ERROR, "autoip-error"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_FAILED, "autoip-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_BUSY, "modem-busy"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE, "modem-no-dialtone"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER, "modem-no-carrier"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT, "modem-dial-timeout"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, "modem-dial-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, "modem-init-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_APN_FAILED, "gsm-apn-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING,
|
|
"gsm-registration-idle"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED,
|
|
"gsm-registration-denied"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT,
|
|
"gsm-registration-timeout"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED,
|
|
"gsm-registration-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED, "gsm-pin-check-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_FIRMWARE_MISSING, "firmware-missing"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_REMOVED, "removed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SLEEPING, "sleeping"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, "connection-removed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_USER_REQUESTED, "user-requested"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CARRIER, "carrier-changed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, "connection-assumed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, "supplicant-available"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND, "modem-not-found"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_BT_FAILED, "bluetooth-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED, "gsm-sim-not-inserted"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED, "gsm-sim-pin-required"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED, "gsm-sim-puk-required"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_WRONG, "gsm-sim-wrong"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_INFINIBAND_MODE, "infiniband-mode"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED, "dependency-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_BR2684_FAILED, "br2684-bridge-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE,
|
|
"modem-manager-unavailable"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SSID_NOT_FOUND, "ssid-not-found"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED,
|
|
"secondary-connection-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED, "dcb-fcoe-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED, "teamd-control-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_FAILED, "modem-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, "modem-available"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT, "sim-pin-incorrect"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NEW_ACTIVATION, "new-activation"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PARENT_CHANGED, "parent-changed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED,
|
|
"parent-managed-changed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_OVSDB_FAILED, "ovsdb-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE, "ip-address-duplicate"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED, "ip-method-unsupported"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED,
|
|
"sriov-configuration-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PEER_NOT_FOUND, "peer-not-found"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DEVICE_HANDLER_FAILED, "device-handler-failed"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_BY_DEFAULT, "unmanaged-by-default"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_EXTERNAL_DOWN,
|
|
"unmanaged-external-down"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_LINK_NOT_INIT,
|
|
"unmanaged-link-not-init"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING, "unmanaged-quitting"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED,
|
|
"unmanaged-nm-disabled"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_CONF, "unmanaged-user-conf"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_EXPLICIT,
|
|
"unmanaged-user-explicit"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_SETTINGS,
|
|
"unmanaged-user-settings"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_UDEV, "unmanaged-user-udev"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NETWORKING_OFF, "networking-off"), );
|
|
|
|
NM_UTILS_LOOKUP_STR_DEFINE(nm_device_mtu_source_to_string,
|
|
NMDeviceMtuSource,
|
|
NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_NONE, "none"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_PARENT, "parent"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_IP_CONFIG, "ip-config"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_CONNECTION,
|
|
"connection"), );
|
|
|
|
NM_UTILS_LOOKUP_STR_DEFINE(nm_device_managed_type_to_string,
|
|
NMDeviceManagedType,
|
|
NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MANAGED_TYPE_EXTERNAL, "external"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MANAGED_TYPE_ASSUME, "assume"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MANAGED_TYPE_FULL, "full"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MANAGED_TYPE_REMOVED, "removed"), );
|
|
|
|
NM_UTILS_LOOKUP_STR_DEFINE(nm_device_ip_state_to_string,
|
|
NMDeviceIPState,
|
|
NM_UTILS_LOOKUP_DEFAULT_WARN("unknown"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_NONE, "none"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_PENDING, "pending"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_READY, "done"),
|
|
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_FAILED, "fail"), );
|
|
|
|
/*****************************************************************************/
|
|
|
|
#define SD_RESOLVED_DNS (1UL << 0)
|
|
/* Don't answer request from locally synthesized records (which includes /etc/hosts) */
|
|
#define SD_RESOLVED_NO_SYNTHESIZE (1UL << 11)
|
|
|
|
typedef struct {
|
|
int addr_family;
|
|
NMIPAddr address;
|
|
gulong cancellable_id;
|
|
GTask *task;
|
|
NMDnsSystemdResolvedResolveHandle *resolved_handle;
|
|
} ResolveAddrInfo;
|
|
|
|
#define _NMLOG_PREFIX_NAME "resolve-addr"
|
|
#define _NMLOG_DOMAIN LOGD_CORE
|
|
#define _NMLOG2(level, info, ...) \
|
|
G_STMT_START \
|
|
{ \
|
|
if (nm_logging_enabled((level), (_NMLOG_DOMAIN))) { \
|
|
ResolveAddrInfo *_info = (info); \
|
|
char _addr_str[NM_INET_ADDRSTRLEN]; \
|
|
\
|
|
_nm_log((level), \
|
|
(_NMLOG_DOMAIN), \
|
|
0, \
|
|
NULL, \
|
|
NULL, \
|
|
_NMLOG_PREFIX_NAME "[" NM_HASH_OBFUSCATE_PTR_FMT \
|
|
",%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
|
NM_HASH_OBFUSCATE_PTR(_info), \
|
|
nm_inet_ntop(_info->addr_family, &_info->address, _addr_str) \
|
|
_NM_UTILS_MACRO_REST(__VA_ARGS__)); \
|
|
} \
|
|
} \
|
|
G_STMT_END
|
|
|
|
static void
|
|
resolve_addr_info_free(ResolveAddrInfo *info)
|
|
{
|
|
nm_assert(info->cancellable_id == 0);
|
|
nm_assert(!info->resolved_handle);
|
|
g_object_unref(info->task);
|
|
g_free(info);
|
|
}
|
|
|
|
static void
|
|
resolve_addr_complete(ResolveAddrInfo *info, char *hostname_take, GError *error_take)
|
|
{
|
|
nm_assert(!!hostname_take != !!error_take);
|
|
|
|
nm_clear_g_cancellable_disconnect(g_task_get_cancellable(info->task), &info->cancellable_id);
|
|
if (error_take)
|
|
g_task_return_error(info->task, error_take);
|
|
else
|
|
g_task_return_pointer(info->task, hostname_take, g_free);
|
|
|
|
resolve_addr_info_free(info);
|
|
}
|
|
|
|
static void
|
|
resolve_addr_helper_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|
{
|
|
ResolveAddrInfo *info = user_data;
|
|
gs_free_error GError *error = NULL;
|
|
gs_free char *output = NULL;
|
|
|
|
output = nm_utils_spawn_helper_finish(result, &error);
|
|
if (nm_utils_error_is_cancelled(error))
|
|
return;
|
|
|
|
_LOG2D(info, "helper returned hostname '%s'", output);
|
|
|
|
resolve_addr_complete(info, g_steal_pointer(&output), g_steal_pointer(&error));
|
|
}
|
|
|
|
typedef enum {
|
|
RESOLVE_ADDR_SERVICE_NONE = 0x0,
|
|
RESOLVE_ADDR_SERVICE_DNS = 0x1,
|
|
RESOLVE_ADDR_SERVICE_FILES = 0x2,
|
|
} ResolveAddrService;
|
|
|
|
static void
|
|
resolve_addr_spawn_helper(ResolveAddrInfo *info, ResolveAddrService services)
|
|
{
|
|
char addr_str[NM_INET_ADDRSTRLEN];
|
|
char str[256];
|
|
char *s = str;
|
|
gsize len = sizeof(str);
|
|
gboolean comma = FALSE;
|
|
|
|
nm_assert(services != RESOLVE_ADDR_SERVICE_NONE);
|
|
nm_assert((services & ~(RESOLVE_ADDR_SERVICE_DNS | RESOLVE_ADDR_SERVICE_FILES)) == 0);
|
|
|
|
if (services & RESOLVE_ADDR_SERVICE_DNS) {
|
|
nm_strbuf_append(&s, &len, "%sdns", comma ? "," : "");
|
|
comma = TRUE;
|
|
}
|
|
if (services & RESOLVE_ADDR_SERVICE_FILES) {
|
|
nm_strbuf_append(&s, &len, "%sfiles", comma ? "," : "");
|
|
comma = TRUE;
|
|
}
|
|
|
|
nm_inet_ntop(info->addr_family, &info->address, addr_str);
|
|
_LOG2D(info, "start lookup via nm-daemon-helper using services: %s", str);
|
|
nm_utils_spawn_helper(NM_MAKE_STRV("resolve-address", addr_str, str),
|
|
g_task_get_cancellable(info->task),
|
|
resolve_addr_helper_cb,
|
|
info);
|
|
}
|
|
|
|
static void
|
|
resolve_addr_resolved_cb(NMDnsSystemdResolved *resolved,
|
|
NMDnsSystemdResolvedResolveHandle *handle,
|
|
const NMDnsSystemdResolvedAddressResult *names,
|
|
guint names_len,
|
|
guint64 flags,
|
|
GError *error,
|
|
gpointer user_data)
|
|
{
|
|
ResolveAddrInfo *info = user_data;
|
|
|
|
info->resolved_handle = NULL;
|
|
|
|
if (nm_utils_error_is_cancelled(error))
|
|
return;
|
|
|
|
if (error) {
|
|
gs_free char *dbus_error = NULL;
|
|
|
|
_LOG2D(info, "error resolving via systemd-resolved: %s", error->message);
|
|
|
|
dbus_error = g_dbus_error_get_remote_error(error);
|
|
if (NM_STR_HAS_PREFIX(dbus_error, "org.freedesktop.resolve1.")) {
|
|
/* systemd-resolved is enabled but it couldn't resolve the
|
|
* address via DNS. Spawn again the helper to check if we
|
|
* can find a result in /etc/hosts. Don't enable the 'dns'
|
|
* service otherwise the helper will possibly ask again to
|
|
* systemd-resolved (via /etc/resolv.conf), potentially using
|
|
* other protocols than DNS or returning synthetic results.
|
|
*
|
|
* See: https://www.freedesktop.org/wiki/Software/systemd/resolved/#commonerrors
|
|
*/
|
|
resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_FILES);
|
|
return;
|
|
}
|
|
|
|
/* systemd-resolved couldn't be contacted, use the helper */
|
|
resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_DNS | RESOLVE_ADDR_SERVICE_FILES);
|
|
return;
|
|
}
|
|
|
|
if (names_len == 0) {
|
|
_LOG2D(info, "systemd-resolved returned no result");
|
|
/* We passed the NO_SYNTHESIZE flag and so systemd-resolved
|
|
* didn't look into /etc/hosts. Spawn the helper for that. */
|
|
resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_FILES);
|
|
return;
|
|
}
|
|
|
|
_LOG2D(info, "systemd-resolved returned hostname '%s'", names[0].name);
|
|
resolve_addr_complete(info, g_strdup(names[0].name), NULL);
|
|
}
|
|
|
|
static void
|
|
resolve_addr_cancelled(GObject *object, gpointer user_data)
|
|
{
|
|
ResolveAddrInfo *info = user_data;
|
|
GError *error = NULL;
|
|
|
|
nm_clear_g_signal_handler(g_task_get_cancellable(info->task), &info->cancellable_id);
|
|
nm_clear_pointer(&info->resolved_handle, nm_dns_systemd_resolved_resolve_cancel);
|
|
nm_utils_error_set_cancelled(&error, FALSE, NULL);
|
|
resolve_addr_complete(info, NULL, error);
|
|
}
|
|
|
|
void
|
|
nm_device_resolve_address(int addr_family,
|
|
gconstpointer address,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer cb_data)
|
|
{
|
|
ResolveAddrInfo *info;
|
|
NMDnsSystemdResolved *resolved;
|
|
|
|
info = g_new(ResolveAddrInfo, 1);
|
|
*info = (ResolveAddrInfo) {
|
|
.task = nm_g_task_new(NULL, cancellable, nm_device_resolve_address, callback, cb_data),
|
|
.addr_family = addr_family,
|
|
.address = nm_ip_addr_init(addr_family, address),
|
|
};
|
|
|
|
if (cancellable) {
|
|
gulong signal_id;
|
|
|
|
signal_id =
|
|
g_cancellable_connect(cancellable, G_CALLBACK(resolve_addr_cancelled), info, NULL);
|
|
if (signal_id == 0) {
|
|
/* the request is already cancelled. Return. */
|
|
return;
|
|
}
|
|
info->cancellable_id = signal_id;
|
|
}
|
|
|
|
resolved = (NMDnsSystemdResolved *) nm_dns_manager_get_systemd_resolved(nm_dns_manager_get());
|
|
if (resolved) {
|
|
_LOG2D(info, "start lookup via systemd-resolved");
|
|
info->resolved_handle =
|
|
nm_dns_systemd_resolved_resolve_address(resolved,
|
|
0,
|
|
addr_family,
|
|
address,
|
|
SD_RESOLVED_DNS | SD_RESOLVED_NO_SYNTHESIZE,
|
|
20000,
|
|
resolve_addr_resolved_cb,
|
|
info);
|
|
return;
|
|
}
|
|
|
|
resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_DNS | RESOLVE_ADDR_SERVICE_FILES);
|
|
}
|
|
|
|
char *
|
|
nm_device_resolve_address_finish(GAsyncResult *result, GError **error)
|
|
{
|
|
GTask *task = G_TASK(result);
|
|
|
|
nm_assert(nm_g_task_is_valid(result, NULL, nm_device_resolve_address));
|
|
|
|
return g_task_propagate_pointer(task, error);
|
|
}
|