/*
- * Copyright (C) Jakub Hrozek 2014 <jakub.hrozek@gmail.com>
+ * Copyright (C) Jakub Hrozek 2014 <jakub.hrozek@posteo.se>
*
* All rights reserved.
*
#include <resolv.h>
#define ANSIZE 256
+#define ns_t_uri 256
static void test_res_fake_a_query(void **state)
{
rv = res_nquery(&dnsstate, "cwrap.org", ns_c_in, ns_t_a,
answer, sizeof(answer));
- assert_int_not_equal(rv, -1);
+ assert_in_range(rv, 1, 100);
ns_initparse(answer, sizeof(answer), &handle);
/* The query must finish w/o an error, have one answer and the answer
rv = res_nquery(&dnsstate, "CWRAP.ORG", ns_c_in, ns_t_a,
answer, sizeof(answer));
- assert_int_not_equal(rv, -1);
+ assert_in_range(rv, 1, 100);
ns_initparse(answer, sizeof(answer), &handle);
/* The query must finish w/o an error, have one answer and the answer
rv = res_nquery(&dnsstate, "cwrap.org.", ns_c_in, ns_t_a,
answer, ANSIZE);
- assert_int_not_equal(rv, -1);
+ assert_in_range(rv, 1, 100);
ns_initparse(answer, 256, &handle);
/* The query must finish w/o an error, have one answer and the answer
rv = res_nquery(&dnsstate, "nosuchentry.org", ns_c_in, ns_t_a,
answer, sizeof(answer));
- assert_int_not_equal(rv, -1);
+ assert_in_range(rv, 1, 100);
ns_initparse(answer, sizeof(answer), &handle);
/* The query must finish w/o an error and have no answer */
rv = res_nquery(&dnsstate, "cwrap6.org", ns_c_in, ns_t_aaaa,
answer, sizeof(answer));
- assert_int_not_equal(rv, -1);
+ assert_in_range(rv, 1, 100);
ns_initparse(answer, sizeof(answer), &handle);
/* The query must finish w/o an error, have one answer and the answer
rv = res_nquery(&dnsstate, "nosuchentry.org", ns_c_in, ns_t_aaaa,
answer, sizeof(answer));
- assert_int_not_equal(rv, -1);
+ assert_in_range(rv, 1, 100);
ns_initparse(answer, sizeof(answer), &handle);
/* The query must finish w/o an error and have no answer */
rv = res_nquery(&dnsstate, "_ldap._tcp.cwrap.org", ns_c_in, ns_t_srv,
answer, sizeof(answer));
- assert_int_not_equal(rv, -1);
+ assert_in_range(rv, 1, 100);
ns_initparse(answer, sizeof(answer), &handle);
int weight;
int port;
char hostname[MAXDNAME];
+ char addr[INET_ADDRSTRLEN];
(void) state; /* unused */
rv = res_nquery(&dnsstate, "_krb5._tcp.cwrap.org", ns_c_in, ns_t_srv,
answer, sizeof(answer));
- assert_int_not_equal(rv, -1);
+ assert_in_range(rv, 1, 256);
ns_initparse(answer, sizeof(answer), &handle);
assert_int_equal(weight, 100);
assert_int_equal(port, 88);
assert_string_equal(hostname, "krb5.cwrap.org");
+
+ /* The additional section contains the A record of krb5.cwrap.org */
+ assert_int_equal(ns_msg_count(handle, ns_s_ar), 1);
+ assert_int_equal(ns_parserr(&handle, ns_s_ar, 0, &rr), 0);
+ assert_int_equal(ns_rr_type(rr), ns_t_a);
+ assert_string_equal(ns_rr_name(rr), "krb5.cwrap.org");
+ assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr),
+ addr, sizeof(addr)));
+ assert_string_equal(addr, "127.0.0.23");
+}
+
+static void test_res_fake_uri_query(void **state)
+{
+ int rv;
+ struct __res_state dnsstate;
+ unsigned char answer[ANSIZE];
+ ns_msg handle;
+ ns_rr rr; /* expanded resource record */
+ const uint8_t *rrdata;
+ int prio;
+ int weight;
+ char uri[MAXDNAME];
+
+ (void) state; /* unused */
+
+ memset(&dnsstate, 0, sizeof(struct __res_state));
+ rv = res_ninit(&dnsstate);
+ assert_int_equal(rv, 0);
+
+ rv = res_nquery(&dnsstate, "_vpn.cwrap.org", ns_c_in, ns_t_uri,
+ answer, sizeof(answer));
+ assert_in_range(rv, 1, 100);
+
+ ns_initparse(answer, sizeof(answer), &handle);
+
+ /*
+ * The query must finish w/o an error, have one answer and the answer
+ * must be a parseable RR of type SRV and have the priority, weight,
+ * port and hostname as in the fake hosts file
+ */
+ assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
+ assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
+ assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
+ assert_int_equal(ns_rr_type(rr), ns_t_uri);
+
+ rrdata = ns_rr_rdata(rr);
+ NS_GET16(prio, rrdata);
+ NS_GET16(weight, rrdata);
+
+ rv = ns_name_uncompress(ns_msg_base(handle),
+ ns_msg_end(handle),
+ rrdata,
+ uri, MAXDNAME);
+ assert_int_not_equal(rv, -1);
+
+ assert_int_equal(prio, 2);
+ assert_int_equal(weight, 5);
+ assert_string_equal(uri, "https://vpn.cwrap.org/VPN");
+}
+
+/*
+ * Test the case of a URI record query where the
+ * fake hosts file entry is minimal in the sense
+ * that it omits the priority and weight entries.
+ * The server then fills in some default values.
+ */
+static void test_res_fake_uri_query_minimal(void **state)
+{
+ int rv;
+ struct __res_state dnsstate;
+ unsigned char answer[ANSIZE];
+ ns_msg handle;
+ ns_rr rr; /* expanded resource record */
+ const uint8_t *rrdata;
+ int prio;
+ int weight;
+ char uri[MAXDNAME];
+
+ (void) state; /* unused */
+
+ memset(&dnsstate, 0, sizeof(struct __res_state));
+ rv = res_ninit(&dnsstate);
+ assert_int_equal(rv, 0);
+
+ rv = res_nquery(&dnsstate, "_ftp.cwrap.org", ns_c_in, ns_t_uri,
+ answer, sizeof(answer));
+ assert_in_range(rv, 1, 256);
+
+ ns_initparse(answer, sizeof(answer), &handle);
+
+ /*
+ * The query must finish w/o an error, have one answer and the answer
+ * must be a parseable RR of type SRV and have the priority, weight,
+ * port and hostname as in the fake hosts file
+ */
+ assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
+ assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
+ assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
+ assert_int_equal(ns_rr_type(rr), ns_t_uri);
+
+ rrdata = ns_rr_rdata(rr);
+ NS_GET16(prio, rrdata);
+ NS_GET16(weight, rrdata);
+
+ rv = ns_name_uncompress(ns_msg_base(handle),
+ ns_msg_end(handle),
+ rrdata,
+ uri, MAXDNAME);
+ assert_int_not_equal(rv, -1);
+
+ assert_int_equal(prio, 1);
+ assert_int_equal(weight, 100);
+ assert_string_equal(uri, "ftp://ftp.cwrap.org/public");
}
static void test_res_fake_soa_query(void **state)
rv = res_nquery(&dnsstate, "cwrap.org", ns_c_in, ns_t_soa,
answer, sizeof(answer));
- assert_int_not_equal(rv, -1);
+ assert_in_range(rv, 1, 100);
ns_initparse(answer, sizeof(answer), &handle);
ns_rr rr; /* expanded resource record */
const uint8_t *rrdata;
char cname[MAXDNAME];
+ char addr[INET_ADDRSTRLEN];
(void) state; /* unused */
rv = res_ninit(&dnsstate);
assert_int_equal(rv, 0);
- rv = res_nquery(&dnsstate, "cwrap.org", ns_c_in, ns_t_cname,
+ rv = res_nquery(&dnsstate, "rwrap.org", ns_c_in, ns_t_cname,
answer, sizeof(answer));
- assert_int_not_equal(rv, -1);
+ assert_in_range(rv, 1, 256);
ns_initparse(answer, 256, &handle);
ns_initparse(answer, sizeof(answer), &handle);
cname, MAXDNAME);
assert_int_not_equal(rv, -1);
- assert_string_equal(cname, "therealcwrap.org");
+ assert_string_equal(cname, "web.cwrap.org");
+
+ /* The CNAME points to an A record that's present in the additional
+ * section
+ */
+ assert_int_equal(ns_msg_count(handle, ns_s_ar), 2);
+
+ assert_int_equal(ns_parserr(&handle, ns_s_ar, 0, &rr), 0);
+ assert_int_equal(ns_rr_type(rr), ns_t_cname);
+ assert_string_equal(ns_rr_name(rr), "web.cwrap.org");
+ rrdata = ns_rr_rdata(rr);
+
+ rv = ns_name_uncompress(ns_msg_base(handle),
+ ns_msg_end(handle),
+ rrdata,
+ cname, MAXDNAME);
+ assert_int_not_equal(rv, -1);
+
+ assert_string_equal(cname, "www.cwrap.org");
+
+ assert_int_equal(ns_parserr(&handle, ns_s_ar, 1, &rr), 0);
+ assert_int_equal(ns_rr_type(rr), ns_t_a);
+ assert_string_equal(ns_rr_name(rr), "www.cwrap.org");
+ assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr),
+ addr, sizeof(addr)));
+ assert_string_equal(addr, "127.0.0.22");
+}
+
+static void test_res_fake_a_via_cname(void **state)
+{
+ int rv;
+ struct __res_state dnsstate;
+ unsigned char answer[ANSIZE];
+ ns_msg handle;
+ ns_rr rr; /* expanded resource record */
+ const uint8_t *rrdata;
+ char cname[MAXDNAME];
+ char addr[INET_ADDRSTRLEN];
+
+ (void) state; /* unused */
+
+ memset(&dnsstate, 0, sizeof(struct __res_state));
+ rv = res_ninit(&dnsstate);
+ assert_int_equal(rv, 0);
+
+ /* Query for A record, but the key is a CNAME. The expected result is
+ * that the whole chain of CNAMEs will be included in the answer section
+ * along with the resulting A
+ */
+ rv = res_nquery(&dnsstate, "rwrap.org", ns_c_in, ns_t_a,
+ answer, sizeof(answer));
+ assert_in_range(rv, 1, 256);
+
+ ns_initparse(answer, sizeof(answer), &handle);
+
+ /*
+ * The query must finish w/o an error, have three answers and the answers
+ * must be a parseable RR of type CNAME and have the cname as in the
+ * fake hosts file
+ */
+ assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
+ assert_int_equal(ns_msg_count(handle, ns_s_an), 3);
+
+ assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
+ assert_int_equal(ns_rr_type(rr), ns_t_cname);
+
+ rrdata = ns_rr_rdata(rr);
+
+ rv = ns_name_uncompress(ns_msg_base(handle),
+ ns_msg_end(handle),
+ rrdata,
+ cname, MAXDNAME);
+ assert_int_not_equal(rv, -1);
+
+ assert_string_equal(cname, "web.cwrap.org");
+
+ assert_int_equal(ns_parserr(&handle, ns_s_an, 1, &rr), 0);
+ assert_int_equal(ns_rr_type(rr), ns_t_cname);
+
+ rrdata = ns_rr_rdata(rr);
+
+ rv = ns_name_uncompress(ns_msg_base(handle),
+ ns_msg_end(handle),
+ rrdata,
+ cname, MAXDNAME);
+ assert_int_not_equal(rv, -1);
+
+ assert_string_equal(cname, "www.cwrap.org");
+
+ assert_int_equal(ns_parserr(&handle, ns_s_an, 2, &rr), 0);
+ assert_int_equal(ns_rr_type(rr), ns_t_a);
+ assert_string_equal(ns_rr_name(rr), "www.cwrap.org");
+ assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr),
+ addr, sizeof(addr)));
+ assert_string_equal(addr, "127.0.0.22");
}
int main(void)
{
int rc;
- const UnitTest tests[] = {
- unit_test(test_res_fake_a_query),
- unit_test(test_res_fake_a_query_case_insensitive),
- unit_test(test_res_fake_a_query_trailing_dot),
- unit_test(test_res_fake_a_query_notfound),
- unit_test(test_res_fake_aaaa_query),
- unit_test(test_res_fake_aaaa_query_notfound),
- unit_test(test_res_fake_srv_query),
- unit_test(test_res_fake_srv_query_minimal),
- unit_test(test_res_fake_soa_query),
- unit_test(test_res_fake_cname_query),
+ const struct CMUnitTest fake_tests[] = {
+ cmocka_unit_test(test_res_fake_a_query),
+ cmocka_unit_test(test_res_fake_a_query_case_insensitive),
+ cmocka_unit_test(test_res_fake_a_query_trailing_dot),
+ cmocka_unit_test(test_res_fake_a_query_notfound),
+ cmocka_unit_test(test_res_fake_aaaa_query),
+ cmocka_unit_test(test_res_fake_aaaa_query_notfound),
+ cmocka_unit_test(test_res_fake_srv_query),
+ cmocka_unit_test(test_res_fake_srv_query_minimal),
+ cmocka_unit_test(test_res_fake_uri_query),
+ cmocka_unit_test(test_res_fake_uri_query_minimal),
+ cmocka_unit_test(test_res_fake_soa_query),
+ cmocka_unit_test(test_res_fake_cname_query),
+ cmocka_unit_test(test_res_fake_a_via_cname),
};
- rc = run_tests(tests);
+ rc = cmocka_run_group_tests(fake_tests, NULL, NULL);
return rc;
}