mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-18 12:10:34 +01:00
nm-daemon-helper: add "service" argument
Introduce a new argument to specify a comma-separated list of NSS services to use for the "resolve-address" command. For now only accept "dns" and "files"; the latter can be used to do a lookup into /etc/hosts. Note that previously the command failed in presence of extra arguments. Therefore, when downgrading NetworkManager without restarting the service, the previously-installed version of the daemon (newer) would spawn the helper with the extra argument, and the newly-installed version of the helper (older) would fail. This issue only impacts hostname resolution and can be fixed by just restarting the daemon. In the upgrade path everything works as before, with the only difference that the helper will use by default both "dns" and "files" services. Don't strictly check for the absence of extra arguments, so that in the future we can introduce more arguments without necessarily break the downgrade path.
This commit is contained in:
parent
8c80077805
commit
229bebfae9
1 changed files with 45 additions and 22 deletions
|
|
@ -55,26 +55,31 @@ cmd_version(void)
|
||||||
static int
|
static int
|
||||||
cmd_resolve_address(void)
|
cmd_resolve_address(void)
|
||||||
{
|
{
|
||||||
nm_auto_free char *address = NULL;
|
nm_auto_free char *address = NULL;
|
||||||
|
nm_auto_free char *services = NULL;
|
||||||
union {
|
union {
|
||||||
struct sockaddr_in in;
|
struct sockaddr_in in;
|
||||||
struct sockaddr_in6 in6;
|
struct sockaddr_in6 in6;
|
||||||
} sockaddr;
|
} sockaddr;
|
||||||
socklen_t sockaddr_size;
|
socklen_t sockaddr_size;
|
||||||
char name[NI_MAXHOST];
|
char name[NI_MAXHOST];
|
||||||
|
char *saveptr = NULL;
|
||||||
|
char *service;
|
||||||
|
char *str;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
address = read_arg();
|
address = read_arg();
|
||||||
if (!address)
|
if (!address)
|
||||||
return RETURN_INVALID_ARGS;
|
return RETURN_INVALID_ARGS;
|
||||||
|
|
||||||
if (more_args())
|
services = read_arg();
|
||||||
return RETURN_INVALID_ARGS;
|
if (!services) {
|
||||||
|
/* Called by an old NM version which doesn't support the 'services'
|
||||||
|
* argument. Use both services. */
|
||||||
|
services = strdup("dns,files");
|
||||||
|
}
|
||||||
|
|
||||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||||
#if defined(__GLIBC__)
|
|
||||||
__nss_configure_lookup("hosts", "dns");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (inet_pton(AF_INET, address, &sockaddr.in.sin_addr) == 1) {
|
if (inet_pton(AF_INET, address, &sockaddr.in.sin_addr) == 1) {
|
||||||
sockaddr.in.sin_family = AF_INET;
|
sockaddr.in.sin_family = AF_INET;
|
||||||
|
|
@ -85,33 +90,51 @@ cmd_resolve_address(void)
|
||||||
} else
|
} else
|
||||||
return RETURN_INVALID_ARGS;
|
return RETURN_INVALID_ARGS;
|
||||||
|
|
||||||
ret = getnameinfo((struct sockaddr *) &sockaddr,
|
for (str = services; (service = strtok_r(str, ",", &saveptr)); str = NULL) {
|
||||||
sockaddr_size,
|
if (!NM_IN_STRSET(service, "dns", "files")) {
|
||||||
name,
|
fprintf(stderr, "Unsupported resolver service '%s'\n", service);
|
||||||
sizeof(name),
|
continue;
|
||||||
NULL,
|
}
|
||||||
0,
|
|
||||||
NI_NAMEREQD);
|
#if defined(__GLIBC__)
|
||||||
if (ret != 0) {
|
__nss_configure_lookup("hosts", service);
|
||||||
if (ret == EAI_SYSTEM) {
|
#endif
|
||||||
int errsv = errno;
|
|
||||||
|
ret = getnameinfo((struct sockaddr *) &sockaddr,
|
||||||
|
sockaddr_size,
|
||||||
|
name,
|
||||||
|
sizeof(name),
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NI_NAMEREQD);
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
printf("%s", name);
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
} else if (ret == EAI_SYSTEM) {
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
int errsv = errno;
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"getnameinfo() failed: %d (%s), system error: %d (%s)\n",
|
"getnameinfo() via service '%s' failed: %d (%s), system error: %d (%s)\n",
|
||||||
|
service,
|
||||||
ret,
|
ret,
|
||||||
gai_strerror(ret),
|
gai_strerror(ret),
|
||||||
errsv,
|
errsv,
|
||||||
_nm_strerror_r(errsv, buf, sizeof(buf)));
|
_nm_strerror_r(errsv, buf, sizeof(buf)));
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "getnameinfo() failed: %d (%s)\n", ret, gai_strerror(ret));
|
fprintf(stderr,
|
||||||
|
"getnameinfo() via service '%s' failed: %d (%s)\n",
|
||||||
|
service,
|
||||||
|
ret,
|
||||||
|
gai_strerror(ret));
|
||||||
}
|
}
|
||||||
return RETURN_ERROR;
|
#if !defined(__GLIBC__)
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s", name);
|
return RETURN_ERROR;
|
||||||
|
|
||||||
return RETURN_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue