mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-03-02 00:20:33 +01:00
The full output of the daemon helper is added to a NMStrBuf, without interpreting it as a string (that is, without stopping at the first NUL character). However, when we retrieve the content from the NMStrBuf we assume it's a string. This is fine for certain commands that expect a string output, but it's not for other commands as the read-file-as-user one. Add a new argument to nm_utils_spawn_helper() to specify whether the output is binary or not. Also have different finish functions depending on the return type. (cherry picked from commit1d90d50fc6) (cherry picked from commit59df5fc93f) (cherry picked from commit7acf70dfb9)
403 lines
21 KiB
C
403 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_SLEEPING, "unmanaged-sleeping"),
|
|
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_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_string(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),
|
|
FALSE,
|
|
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);
|
|
}
|