/* Test parsing of /etc/resolv.conf. Genric version.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
#include <errno.h>
#include <gnu/lib-names.h>
#include <netdb.h>
-#include <resolv/resolv-internal.h> /* For DEPRECATED_RES_USE_INET6. */
#include <resolv/resolv_context.h>
#include <stdio.h>
#include <stdlib.h>
res_init. */
static const char *const test_hostname = "www.example.com";
-/* Path to the test root directory. */
-static char *path_chroot;
-
-/* Path to resolv.conf under path_chroot (outside the chroot). */
-static char *path_resolv_conf;
+struct support_chroot *chroot_env;
static void
prepare (int argc, char **argv)
{
- path_chroot = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
- if (mkdtemp (path_chroot) == NULL)
- FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", path_chroot);
- add_temp_file (path_chroot);
-
- /* Create the /etc directory in the chroot environment. */
- char *path_etc = xasprintf ("%s/etc", path_chroot);
- xmkdir (path_etc, 0777);
- add_temp_file (path_etc);
-
- /* Create an empty resolv.conf file. */
- path_resolv_conf = xasprintf ("%s/resolv.conf", path_etc);
- add_temp_file (path_resolv_conf);
- support_write_file_string (path_resolv_conf, "");
-
- free (path_etc);
-
- /* valgrind needs a temporary directory in the chroot. */
- {
- char *path_tmp = xasprintf ("%s/tmp", path_chroot);
- xmkdir (path_tmp, 0777);
- add_temp_file (path_tmp);
- free (path_tmp);
- }
+ chroot_env = support_chroot_create
+ ((struct support_chroot_configuration)
+ {
+ .resolv_conf = "",
+ });
}
/* Verify that the chroot environment has been set up. */
static void
check_chroot_working (void *closure)
{
- xchroot (path_chroot);
+ xchroot (chroot_env->path_chroot);
FILE *fp = xfopen (_PATH_RESCONF, "r");
xfclose (fp);
if (resp->retry != RES_DFLRETRY)
fprintf (fp, " attempts:%d", resp->retry);
print_option_flag (fp, &options, RES_USEVC, "use-vc");
- print_option_flag (fp, &options, DEPRECATED_RES_USE_INET6, "inet6");
print_option_flag (fp, &options, RES_ROTATE, "rotate");
print_option_flag (fp, &options, RES_USE_EDNS0, "edns0");
print_option_flag (fp, &options, RES_SNGLKUP,
print_option_flag (fp, &options, RES_SNGLKUPREOP,
"single-request-reopen");
print_option_flag (fp, &options, RES_NOTLDQUERY, "no-tld-query");
+ print_option_flag (fp, &options, RES_NORELOAD, "no-reload");
fputc ('\n', fp);
if (options != 0)
fprintf (fp, "; error: unresolved option bits: 0x%x\n", options);
/* Setting for the RES_OPTIONS environment variable. NULL if the
variable is not to be set. */
const char *res_options;
+
+ /* Override the system host name. NULL means that no change is made
+ and the default is used (test_hostname). */
+ const char *hostname;
};
enum test_init
/* Load nss_dns outside of the chroot. */
if (dlopen (LIBNSS_DNS_SO, RTLD_LAZY) == NULL)
FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ());
- xchroot (path_chroot);
+ xchroot (chroot_env->path_chroot);
/* Force the use of nss_dns. */
__nss_configure_lookup ("hosts", "dns");
}
setenv ("LOCALDOMAIN", ctx->t->localdomain, 1);
if (ctx->t->res_options != NULL)
setenv ("RES_OPTIONS", ctx->t->res_options, 1);
+ if (ctx->t->hostname != NULL)
+ {
+#ifdef CLONE_NEWUTS
+ /* This test needs its own namespace, to avoid changing the host
+ name for the parent, too. */
+ TEST_VERIFY_EXIT (unshare (CLONE_NEWUTS) == 0);
+ if (sethostname (ctx->t->hostname, strlen (ctx->t->hostname)) != 0)
+ FAIL_EXIT1 ("sethostname (\"%s\"): %m", ctx->t->hostname);
+#else
+ FAIL_UNSUPPORTED ("clone (CLONE_NEWUTS) not supported");
+#endif
+ }
switch (ctx->init)
{
case test_init:
- xchroot (path_chroot);
+ xchroot (chroot_env->path_chroot);
TEST_VERIFY (res_init () == 0);
print_resp (stdout, &_res);
return;
case test_ninit:
- xchroot (path_chroot);
+ xchroot (chroot_env->path_chroot);
res_state resp = xmalloc (sizeof (*resp));
memset (resp, 0, sizeof (*resp));
TEST_VERIFY (res_ninit (resp) == 0);
return;
case test_mkquery:
- xchroot (path_chroot);
+ xchroot (chroot_env->path_chroot);
unsigned char buf[512];
TEST_VERIFY (res_mkquery (QUERY, "www.example",
C_IN, ns_t_a, NULL, 0,
"nameserver 127.0.0.1\n"
"; nameserver[0]: [127.0.0.1]:53\n"
},
+ {.name = "empty file, no-dot hostname",
+ .conf = "",
+ .expected = "nameserver 127.0.0.1\n"
+ "; nameserver[0]: [127.0.0.1]:53\n",
+ .hostname = "example",
+ },
{.name = "empty file with LOCALDOMAIN",
.conf = "",
.expected = "search example.net\n"
.res_options = "edns0 attempts:5",
},
{.name = "basic",
- .conf = "domain example.net\n"
- "search corp.example.com example.com\n"
+ .conf = "search corp.example.com example.com\n"
"nameserver 192.0.2.1\n",
.expected = "search corp.example.com example.com\n"
"; search[0]: corp.example.com\n"
"nameserver 192.0.2.1\n"
"; nameserver[0]: [192.0.2.1]:53\n"
},
+ {.name = "basic with no-dot hostname",
+ .conf = "search corp.example.com example.com\n"
+ "nameserver 192.0.2.1\n",
+ .expected = "search corp.example.com example.com\n"
+ "; search[0]: corp.example.com\n"
+ "; search[1]: example.com\n"
+ "nameserver 192.0.2.1\n"
+ "; nameserver[0]: [192.0.2.1]:53\n",
+ .hostname = "example",
+ },
+ {.name = "basic no-reload",
+ .conf = "options no-reload\n"
+ "search corp.example.com example.com\n"
+ "nameserver 192.0.2.1\n",
+ .expected = "options no-reload\n"
+ "search corp.example.com example.com\n"
+ "; search[0]: corp.example.com\n"
+ "; search[1]: example.com\n"
+ "nameserver 192.0.2.1\n"
+ "; nameserver[0]: [192.0.2.1]:53\n"
+ },
+ {.name = "basic no-reload via RES_OPTIONS",
+ .conf = "search corp.example.com example.com\n"
+ "nameserver 192.0.2.1\n",
+ .expected = "options no-reload\n"
+ "search corp.example.com example.com\n"
+ "; search[0]: corp.example.com\n"
+ "; search[1]: example.com\n"
+ "nameserver 192.0.2.1\n"
+ "; nameserver[0]: [192.0.2.1]:53\n",
+ .res_options = "no-reload"
+ },
{.name = "whitespace",
.conf = "# This test covers comment and whitespace processing "
" (trailing whitespace,\n"
"nameserver 192.0.2.1\n"
"nameserver ::1\n"
"nameserver 192.0.2.2\n",
- .expected = "options ndots:3 timeout:19 attempts:5 inet6 edns0\n"
+ .expected = "options ndots:3 timeout:19 attempts:5 edns0\n"
"search corp.example.com example.com\n"
"; search[0]: corp.example.com\n"
"; search[1]: example.com\n"
}
/* Special tests which do not follow the general pattern. */
-enum { special_tests_count = 7 };
-
-#if TEST_THREAD
-/* Called from test number 3-6 to trigger reloading of the
- configuration. */
-static void *
-special_test_call_res_init (void *closure)
-{
- TEST_VERIFY (res_init () == 0);
- return NULL;
-}
-#endif
+enum { special_tests_count = 11 };
/* Implementation of special tests. */
static void
TEST_VERIFY (test_index < special_tests_count);
if (test_verbose > 0)
printf ("info: special test %u\n", test_index);
- xchroot (path_chroot);
+ xchroot (chroot_env->path_chroot);
switch (test_index)
{
case 4:
case 5:
case 6:
- /* Test res_init change broadcast. This requires a second
- thread to trigger the reload. */
-#if TEST_THREAD
support_write_file_string (_PATH_RESCONF,
"options edns0\n"
"nameserver 192.0.2.1\n");
+ goto reload_tests;
+ case 7: /* 7 and the following tests are with no-reload. */
+ case 8:
+ case 9:
+ case 10:
+ support_write_file_string (_PATH_RESCONF,
+ "options edns0 no-reload\n"
+ "nameserver 192.0.2.1\n");
+ /* Fall through. */
+ reload_tests:
for (int iteration = 0; iteration < 2; ++iteration)
{
switch (test_index)
{
case 3:
+ case 7:
TEST_VERIFY (res_init () == 0);
break;
case 4:
+ case 8:
{
unsigned char buf[512];
TEST_VERIFY
}
break;
case 5:
+ case 9:
gethostbyname (test_hostname);
break;
case 6:
+ case 10:
{
struct addrinfo *ai;
(void) getaddrinfo (test_hostname, NULL, NULL, &ai);
}
break;
}
- if (iteration == 0)
+ /* test_index == 7 is res_init and performs a reload even
+ with no-reload. */
+ if (iteration == 0 || test_index > 7)
{
TEST_VERIFY (_res.options & RES_USE_EDNS0);
TEST_VERIFY (!(_res.options & RES_ROTATE));
+ if (test_index < 7)
+ TEST_VERIFY (!(_res.options & RES_NORELOAD));
+ else
+ TEST_VERIFY (_res.options & RES_NORELOAD);
TEST_VERIFY (_res.nscount == 1);
+ /* File change triggers automatic reloading. */
support_write_file_string (_PATH_RESCONF,
"options rotate\n"
"nameserver 192.0.2.1\n"
"nameserver 192.0.2.2\n");
- xpthread_join (xpthread_create
- (NULL, special_test_call_res_init, NULL));
}
else
{
- /* edns0 was dropped, but the flag is not cleared. See
- bug 21701. */
- /* TEST_VERIFY (!(_res.options & RES_USE_EDNS0)); */
+ if (test_index != 3 && test_index != 7)
+ /* test_index 3, 7 are res_init; this function does
+ not reset flags. See bug 21701. */
+ TEST_VERIFY (!(_res.options & RES_USE_EDNS0));
TEST_VERIFY (_res.options & RES_ROTATE);
TEST_VERIFY (_res.nscount == 2);
}
}
-#endif
break;
}
}
TEST_VERIFY (test_cases[i].conf != NULL);
TEST_VERIFY (test_cases[i].expected != NULL);
- support_write_file_string (path_resolv_conf, test_cases[i].conf);
+ support_write_file_string (chroot_env->path_resolv_conf,
+ test_cases[i].conf);
test_file_contents (&test_cases[i]);
{
if (test_verbose > 0)
printf ("info: special test: missing file\n");
- TEST_VERIFY (unlink (path_resolv_conf) == 0);
+ TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0);
test_file_contents (&test_cases[i]);
if (test_verbose > 0)
printf ("info: special test: dangling symbolic link\n");
- TEST_VERIFY (symlink ("does-not-exist", path_resolv_conf) == 0);
+ TEST_VERIFY (symlink ("does-not-exist", chroot_env->path_resolv_conf) == 0);
test_file_contents (&test_cases[i]);
- TEST_VERIFY (unlink (path_resolv_conf) == 0);
+ TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0);
if (test_verbose > 0)
printf ("info: special test: unreadable file\n");
- support_write_file_string (path_resolv_conf, "");
- TEST_VERIFY (chmod (path_resolv_conf, 0) == 0);
+ support_write_file_string (chroot_env->path_resolv_conf, "");
+ TEST_VERIFY (chmod (chroot_env->path_resolv_conf, 0) == 0);
test_file_contents (&test_cases[i]);
/* Restore the empty file. */
- TEST_VERIFY (unlink (path_resolv_conf) == 0);
- support_write_file_string (path_resolv_conf, "");
+ TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0);
+ support_write_file_string (chroot_env->path_resolv_conf, "");
}
}
xwaitpid (server, NULL, 0);
}
- free (path_chroot);
- path_chroot = NULL;
- free (path_resolv_conf);
- path_resolv_conf = NULL;
+ support_chroot_free (chroot_env);
return 0;
}