mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-09-07 09:45:10 +03:00
test-nss: allow the module and names/addresses to be specified (#4258)
Useful for testing a single module. If nothing is specified, behaviour is the same as before. $ ./test-nss myhostname 192.168.0.14 localhost ======== myhostname ======== _nss_myhostname_gethostbyname4_r("localhost") → status=NSS_STATUS_SUCCESS pat=buffer+0x38 errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "localhost" AF_INET 127.0.0.1 %lo "localhost" AF_INET6 ::1 %lo _nss_myhostname_gethostbyname3_r("localhost", AF_INET) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "localhost" AF_INET 127.0.0.1 canonical: "localhost" _nss_myhostname_gethostbyname3_r("localhost", AF_INET6) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "localhost" AF_INET6 ::1 canonical: "localhost" _nss_myhostname_gethostbyname3_r("localhost", *) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "localhost" AF_INET 127.0.0.1 canonical: "localhost" _nss_myhostname_gethostbyname3_r("localhost", AF_UNIX) → status=NSS_STATUS_UNAVAIL errno=97/EAFNOSUPPORT h_errno=4/No address associated with name ttl=2147483647 _nss_myhostname_gethostbyname2_r("localhost", AF_INET) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) "localhost" AF_INET 127.0.0.1 _nss_myhostname_gethostbyname2_r("localhost", AF_INET6) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) "localhost" AF_INET6 ::1 _nss_myhostname_gethostbyname2_r("localhost", *) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) "localhost" AF_INET 127.0.0.1 _nss_myhostname_gethostbyname2_r("localhost", AF_UNIX) → status=NSS_STATUS_UNAVAIL errno=97/EAFNOSUPPORT h_errno=4/No address associated with name _nss_myhostname_gethostbyname_r("localhost") → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) "localhost" AF_INET 127.0.0.1 _nss_myhostname_gethostbyaddr2_r("192.168.0.14") → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "laptop" AF_INET 192.168.0.14 AF_INET 192.168.122.1 AF_INET 169.254.209.76 _nss_myhostname_gethostbyaddr_r("192.168.0.14") → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) "laptop" AF_INET 192.168.0.14 AF_INET 192.168.122.1 AF_INET 169.254.209.76
This commit is contained in:
committed by
Lennart Poettering
parent
d48bb46b5a
commit
9f7672b3bc
@@ -77,7 +77,8 @@ static void* open_handle(const char* dir, const char* module, int flags) {
|
|||||||
path = strjoina("libnss_", module, ".so.2");
|
path = strjoina("libnss_", module, ".so.2");
|
||||||
|
|
||||||
handle = dlopen(path, flags);
|
handle = dlopen(path, flags);
|
||||||
assert_se(handle);
|
if (!handle)
|
||||||
|
log_error("Failed to load module %s: %s", module, dlerror());
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,75 +380,158 @@ static void test_byaddr(void *handle,
|
|||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int make_addresses(struct local_address **addresses) {
|
||||||
|
int n;
|
||||||
|
size_t n_alloc;
|
||||||
|
_cleanup_free_ struct local_address *addrs = NULL;
|
||||||
|
|
||||||
|
n = local_addresses(NULL, 0, AF_UNSPEC, &addrs);
|
||||||
|
if (n < 0)
|
||||||
|
log_info_errno(n, "Failed to query local addresses: %m");
|
||||||
|
|
||||||
|
n_alloc = n; /* we _can_ do that */
|
||||||
|
if (!GREEDY_REALLOC(addrs, n_alloc, n + 3))
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
addrs[n++] = (struct local_address) { .family = AF_INET,
|
||||||
|
.address.in = { htobe32(0x7F000001) } };
|
||||||
|
addrs[n++] = (struct local_address) { .family = AF_INET,
|
||||||
|
.address.in = { htobe32(0x7F000002) } };
|
||||||
|
addrs[n++] = (struct local_address) { .family = AF_INET6,
|
||||||
|
.address.in6 = in6addr_loopback };
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_one_module(const char* dir,
|
||||||
|
const char *module,
|
||||||
|
char **names,
|
||||||
|
struct local_address *addresses,
|
||||||
|
int n_addresses) {
|
||||||
|
void *handle;
|
||||||
|
char **name;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
|
||||||
|
log_info("======== %s ========", module);
|
||||||
|
|
||||||
|
handle = open_handle(streq(module, "dns") ? NULL : dir,
|
||||||
|
module,
|
||||||
|
RTLD_LAZY|RTLD_NODELETE);
|
||||||
|
if (!handle)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
STRV_FOREACH(name, names)
|
||||||
|
test_byname(handle, module, *name);
|
||||||
|
|
||||||
|
for (i = 0; i < n_addresses; i++)
|
||||||
|
test_byaddr(handle, module,
|
||||||
|
&addresses[i].address,
|
||||||
|
FAMILY_ADDRESS_SIZE(addresses[i].family),
|
||||||
|
addresses[i].family);
|
||||||
|
|
||||||
|
log_info(" ");
|
||||||
|
dlclose(handle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_argv(int argc, char **argv,
|
||||||
|
char ***the_modules,
|
||||||
|
char ***the_names,
|
||||||
|
struct local_address **the_addresses, int *n_addresses) {
|
||||||
|
|
||||||
|
int r, n = 0;
|
||||||
|
_cleanup_strv_free_ char **modules = NULL, **names = NULL;
|
||||||
|
_cleanup_free_ struct local_address *addrs = NULL;
|
||||||
|
size_t n_allocated = 0;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
modules = strv_new(argv[1], NULL);
|
||||||
|
else
|
||||||
|
modules = strv_new(
|
||||||
#ifdef HAVE_MYHOSTNAME
|
#ifdef HAVE_MYHOSTNAME
|
||||||
# define MODULE1 "myhostname\0"
|
"myhostname",
|
||||||
#else
|
|
||||||
# define MODULE1
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_RESOLVED
|
#ifdef HAVE_RESOLVED
|
||||||
# define MODULE2 "resolve\0"
|
"resolve",
|
||||||
#else
|
|
||||||
# define MODULE2
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_MACHINED
|
#ifdef HAVE_MACHINED
|
||||||
# define MODULE3 "mymachines\0"
|
"mymachines",
|
||||||
#else
|
|
||||||
# define MODULE3
|
|
||||||
#endif
|
#endif
|
||||||
#define MODULE4 "dns\0"
|
"dns",
|
||||||
|
NULL);
|
||||||
|
if (!modules)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (argc > 2) {
|
||||||
|
char **name;
|
||||||
|
int family;
|
||||||
|
union in_addr_union address;
|
||||||
|
|
||||||
|
STRV_FOREACH(name, argv + 2) {
|
||||||
|
r = in_addr_from_string_auto(*name, &family, &address);
|
||||||
|
if (r < 0) {
|
||||||
|
/* assume this is a name */
|
||||||
|
r = strv_extend(&names, *name);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
if (!GREEDY_REALLOC0(addrs, n_allocated, n + 1))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
addrs[n++] = (struct local_address) { .family = family,
|
||||||
|
.address = address };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_cleanup_free_ char *hostname;
|
||||||
|
|
||||||
|
hostname = gethostname_malloc();
|
||||||
|
if (!hostname)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
names = strv_new("localhost", "gateway", "foo_no_such_host", hostname, NULL);
|
||||||
|
if (!names)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
n = make_addresses(&addrs);
|
||||||
|
if (n < 0)
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
*the_modules = modules;
|
||||||
|
*the_names = names;
|
||||||
|
modules = names = NULL;
|
||||||
|
*the_addresses = addrs;
|
||||||
|
*n_addresses = n;
|
||||||
|
addrs = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
_cleanup_free_ char *dir = NULL, *hostname = NULL;
|
_cleanup_free_ char *dir = NULL;
|
||||||
const char *module;
|
_cleanup_strv_free_ char **modules = NULL, **names = NULL;
|
||||||
|
|
||||||
const uint32_t local_address_ipv4 = htobe32(0x7F000001);
|
|
||||||
const uint32_t local_address_ipv4_2 = htobe32(0x7F000002);
|
|
||||||
_cleanup_free_ struct local_address *addresses = NULL;
|
_cleanup_free_ struct local_address *addresses = NULL;
|
||||||
int n_addresses;
|
int n_addresses;
|
||||||
|
char **module;
|
||||||
|
int r;
|
||||||
|
|
||||||
log_set_max_level(LOG_INFO);
|
log_set_max_level(LOG_INFO);
|
||||||
log_parse_environment();
|
log_parse_environment();
|
||||||
|
|
||||||
dir = dirname_malloc(argv[0]);
|
r = parse_argv(argc, argv, &modules, &names, &addresses, &n_addresses);
|
||||||
assert_se(dir);
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "Failed to parse arguments: %m");
|
||||||
hostname = gethostname_malloc();
|
return EXIT_FAILURE;
|
||||||
assert_se(hostname);
|
|
||||||
|
|
||||||
n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
|
|
||||||
if (n_addresses < 0) {
|
|
||||||
log_info_errno(n_addresses, "Failed to query local addresses: %m");
|
|
||||||
n_addresses = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NULSTR_FOREACH(module, MODULE1 MODULE2 MODULE3 MODULE4) {
|
dir = dirname_malloc(argv[0]);
|
||||||
void *handle;
|
if (!dir)
|
||||||
const char *name;
|
return EXIT_FAILURE;
|
||||||
int i;
|
|
||||||
|
|
||||||
log_info("======== %s ========", module);
|
STRV_FOREACH(module, modules) {
|
||||||
|
r = test_one_module(dir, *module, names, addresses, n_addresses);
|
||||||
handle = open_handle(streq(module, "dns") ? NULL : dir,
|
if (r < 0)
|
||||||
module,
|
return EXIT_FAILURE;
|
||||||
RTLD_LAZY|RTLD_NODELETE);
|
|
||||||
NULSTR_FOREACH(name, "localhost\0" "gateway\0" "foo_no_such_host\0")
|
|
||||||
test_byname(handle, module, name);
|
|
||||||
|
|
||||||
test_byname(handle, module, hostname);
|
|
||||||
|
|
||||||
test_byaddr(handle, module, &local_address_ipv4, sizeof local_address_ipv4, AF_INET);
|
|
||||||
test_byaddr(handle, module, &local_address_ipv4_2, sizeof local_address_ipv4_2, AF_INET);
|
|
||||||
test_byaddr(handle, module, &in6addr_loopback, sizeof in6addr_loopback, AF_INET6);
|
|
||||||
|
|
||||||
for (i = 0; i < n_addresses; i++)
|
|
||||||
test_byaddr(handle, module,
|
|
||||||
&addresses[i].address,
|
|
||||||
FAMILY_ADDRESS_SIZE(addresses[i].family),
|
|
||||||
addresses[i].family);
|
|
||||||
|
|
||||||
dlclose(handle);
|
|
||||||
|
|
||||||
log_info(" ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
Reference in New Issue
Block a user