13 #include <netinet/in.h>
14 #include <arpa/nameser.h>
15 #include <arpa/inet.h>
18 #define RWRAP_RESOLV_CONF_TMPL "rwrap_resolv_conf_XXXXXX"
20 struct resolv_conf_test_state {
23 char *resolv_conf_path;
26 static void setup(void **state)
28 struct resolv_conf_test_state *test_state;
30 test_state = malloc(sizeof(struct resolv_conf_test_state));
31 assert_non_null(test_state);
32 test_state->rc_fd = -1;
33 test_state->resolv_conf = NULL;
35 test_state->resolv_conf_path = strdup(RWRAP_RESOLV_CONF_TMPL);
36 assert_non_null(test_state->resolv_conf_path);
37 test_state->rc_fd = mkstemp(test_state->resolv_conf_path);
38 assert_non_null(test_state->resolv_conf_path);
39 test_state->resolv_conf = fdopen(test_state->rc_fd, "a");
40 assert_non_null(test_state->resolv_conf);
45 static void teardown(void **state)
47 struct resolv_conf_test_state *test_state;
49 test_state = (struct resolv_conf_test_state *) *state;
51 if (test_state == NULL) return;
53 if (test_state->resolv_conf) {
54 fclose(test_state->resolv_conf);
57 if (test_state->rc_fd != -1) {
58 close(test_state->rc_fd);
61 if (test_state->resolv_conf_path) {
62 unlink(test_state->resolv_conf_path);
63 free(test_state->resolv_conf_path);
69 static void test_res_ninit(void **state)
71 struct resolv_conf_test_state *test_state;
72 struct __res_state dnsstate;
74 * libc resolver only supports 3 name servers. Make sure the
75 * extra are skipped for both v4 and v6. Also make sure there's
76 * 'too many' nameservers even on platforms where v6 is not
79 const char *nameservers[] = {
82 "2607:f8b0:4009:802::1011",
85 "2607:f8b0:4009:802::1012",
90 char straddr[INET6_ADDRSTRLEN] = { '\0' };
91 #ifdef HAVE_RESOLV_IPV6_NSADDRS
92 struct sockaddr_in6 *sa6;
95 test_state = (struct resolv_conf_test_state *) *state;
98 * Write a valid resolv.conf.
99 * Make sure it's possible to skip comments
101 fputs("# Hello world\n", test_state->resolv_conf);
102 fputs("; This is resolv_wrapper\n", test_state->resolv_conf);
103 for (i = 0; nameservers[i]; i++) {
104 fputs("nameserver ", test_state->resolv_conf);
105 fputs(nameservers[i], test_state->resolv_conf);
106 fputs("\n", test_state->resolv_conf);
108 fflush(test_state->resolv_conf);
110 rv = setenv("RESOLV_WRAPPER_CONF", test_state->resolv_conf_path, 1);
111 assert_int_equal(rv, 0);
113 memset(&dnsstate, 0, sizeof(dnsstate));
114 rv = res_ninit(&dnsstate);
115 unsetenv("RESOLV_WRAPPER_CONF");
116 assert_int_equal(rv, 0);
119 * Validate the number of parsed name servers.
122 assert_int_equal(dnsstate.nscount + dnsstate._u._ext.nscount, MAXNS);
124 #ifndef HAVE_RESOLV_IPV6_NSADDRS
126 * On platforms that don't support IPv6, the v6 address is skipped
127 * and we end up reading three v4 addresses.
129 assert_int_equal(dnsstate.nscount, MAXNS);
132 * test we have two v4 and one v6 server
134 * Note: This test assumes MAXNS == 3, which is the
135 * case on all systems encountered so far.
137 assert_int_equal(dnsstate.nscount, 2);
138 assert_int_equal(dnsstate._u._ext.nscount, 1);
139 #endif /* HAVE_RESOLV_IPV6_NSADDRS */
141 /* Validate the servers. */
144 assert_int_equal(dnsstate.nsaddr_list[0].sin_family, AF_INET);
145 assert_int_equal(dnsstate.nsaddr_list[0].sin_port, htons(53));
146 inet_ntop(AF_INET, &(dnsstate.nsaddr_list[0].sin_addr),
147 straddr, INET6_ADDRSTRLEN);
148 assert_string_equal(nameservers[0], straddr);
150 assert_int_equal(dnsstate.nsaddr_list[1].sin_family, AF_INET);
151 assert_int_equal(dnsstate.nsaddr_list[1].sin_port, htons(53));
152 inet_ntop(AF_INET, &(dnsstate.nsaddr_list[1].sin_addr),
153 straddr, INET6_ADDRSTRLEN);
154 assert_string_equal(nameservers[1], straddr);
156 #ifndef HAVE_RESOLV_IPV6_NSADDRS
158 * On platforms that don't support IPv6, the v6 address is skipped
159 * and we end up reading three v4 addresses.
161 assert_int_equal(dnsstate.nsaddr_list[2].sin_family, AF_INET);
162 assert_int_equal(dnsstate.nsaddr_list[2].sin_port, htons(53));
163 inet_ntop(AF_INET, &(dnsstate.nsaddr_list[2].sin_addr),
164 straddr, INET6_ADDRSTRLEN);
165 assert_string_equal(nameservers[3], straddr);
168 sa6 = dnsstate._u._ext.nsaddrs[0];
169 assert_int_equal(sa6->sin6_family, AF_INET6);
170 assert_int_equal(sa6->sin6_port, htons(53));
171 inet_ntop(AF_INET6, &(sa6->sin6_addr), straddr, INET6_ADDRSTRLEN);
172 assert_string_equal(nameservers[2], straddr);
175 res_nclose(&dnsstate);
178 static void test_res_ninit_enoent(void **state)
181 struct __res_state dnsstate;
183 (void) state; /* unused */
185 rv = setenv("RESOLV_WRAPPER_CONF", "/no/such/file", 1);
186 assert_int_equal(rv, 0);
188 /* Just make sure we don't crash, error is fine */
189 memset(&dnsstate, 0, sizeof(dnsstate));
190 rv = res_ninit(&dnsstate);
191 unsetenv("RESOLV_WRAPPER_CONF");
192 assert_int_equal(rv, -1);
198 const UnitTest tests[] = {
199 unit_test_setup_teardown(test_res_ninit, setup, teardown),
200 unit_test(test_res_ninit_enoent),
203 rc = run_tests(tests);