[PATCH] URI RR Support for resolv_wrapper
Jakub Hrozek
jakub.hrozek at posteo.se
Fri Aug 19 10:06:41 UTC 2016
On Thu, Aug 18, 2016 at 05:51:11PM +0200, Jakub Hrozek wrote:
> + if (rr == NULL || rr->type != ns_t_ptr) {
> + RWRAP_LOG(RWRAP_LOG_ERROR,
> + "Malformed record, no or wrong value!\n");
Andreas asked me to change this error message, so I did in the attached
patch. (btw now the messages are inconsistent, should we change them all
in another patch?)
-------------- next part --------------
>From 33a9e7a87891b8dd5e0af5171a5c461cdb624d51 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Thu, 18 Aug 2016 17:49:00 +0200
Subject: [PATCH] Add support for the PTR DNS Resource Record type
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
---
src/resolv_wrapper.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/fake_hosts.in | 1 +
tests/test_dns_fake.c | 42 +++++++++++++++++++++++++++++++++++++++
3 files changed, 97 insertions(+)
diff --git a/src/resolv_wrapper.c b/src/resolv_wrapper.c
index a07086a8baa9fe946d5bf7624b550de63867a9ee..4aba14ab415d3948f3169728fd8beaaf1f4ba60d 100644
--- a/src/resolv_wrapper.c
+++ b/src/resolv_wrapper.c
@@ -192,6 +192,7 @@ struct rwrap_fake_rr {
struct rwrap_uri_rrdata uri_rec;
struct rwrap_soa_rrdata soa_rec;
char cname_rec[MAXDNAME];
+ char ptr_rec[MAXDNAME];
} rrdata;
char key[MAXDNAME];
@@ -381,6 +382,16 @@ static int rwrap_create_fake_cname_rr(const char *key,
return 0;
}
+static int rwrap_create_fake_ptr_rr(const char *key,
+ const char *value,
+ struct rwrap_fake_rr *rr)
+{
+ memcpy(rr->rrdata.ptr_rec , value, strlen(value) + 1);
+ memcpy(rr->key, key, strlen(key) + 1);
+ rr->type = ns_t_ptr;
+ return 0;
+}
+
/* Prepares a fake header with a single response. Advances header_blob */
static ssize_t rwrap_fake_header(uint8_t **header_blob, size_t remaining,
size_t ancount, size_t arcount)
@@ -741,6 +752,41 @@ static ssize_t rwrap_fake_cname(struct rwrap_fake_rr *rr,
return resp_size;
}
+static ssize_t rwrap_fake_ptr(struct rwrap_fake_rr *rr,
+ uint8_t *answer,
+ size_t anslen)
+{
+ uint8_t *a = answer;
+ ssize_t rdata_size;
+ ssize_t resp_size;
+ unsigned char hostname_compressed[MAXDNAME];
+
+ if (rr == NULL || rr->type != ns_t_ptr) {
+ RWRAP_LOG(RWRAP_LOG_ERROR,
+ "Malformed record or wrong value!\n");
+ return -1;
+ }
+ RWRAP_LOG(RWRAP_LOG_TRACE, "Adding PTR RR");
+
+ /* Prepare the data to write */
+ rdata_size = ns_name_compress(rr->rrdata.ptr_rec,
+ hostname_compressed, MAXDNAME,
+ NULL, NULL);
+ if (rdata_size < 0) {
+ return -1;
+ }
+
+ resp_size = rwrap_fake_rdata_common(ns_t_ptr, rdata_size,
+ rr->key, anslen, &a);
+ if (resp_size < 0) {
+ return -1;
+ }
+
+ memcpy(a, hostname_compressed, rdata_size);
+
+ return resp_size;
+}
+
#define RESOLV_MATCH(line, name) \
(strncmp(line, name, sizeof(name) - 1) == 0 && \
(line[sizeof(name) - 1] == ' ' || \
@@ -880,6 +926,10 @@ static int rwrap_get_record(const char *hostfile, unsigned recursion,
value, rr + 1);
}
break;
+ } else if (TYPE_MATCH(type, ns_t_ptr,
+ rec_type, "PTR", key, query)) {
+ rc = rwrap_create_fake_ptr_rr(key, value, rr);
+ break;
}
}
@@ -931,6 +981,7 @@ static inline bool rwrap_known_type(int type)
case ns_t_uri:
case ns_t_soa:
case ns_t_cname:
+ case ns_t_ptr:
return true;
}
@@ -1002,6 +1053,9 @@ static ssize_t rwrap_add_rr(struct rwrap_fake_rr *rr,
case ns_t_cname:
resp_data = rwrap_fake_cname(rr, answer, anslen);
break;
+ case ns_t_ptr:
+ resp_data = rwrap_fake_ptr(rr, answer, anslen);
+ break;
default:
return -1;
}
diff --git a/tests/fake_hosts.in b/tests/fake_hosts.in
index d7bf9a27006d99a0765ad39dd86c756201ad4748..181297973c69ff9bad36963fba3fcddf8cf65c5a 100644
--- a/tests/fake_hosts.in
+++ b/tests/fake_hosts.in
@@ -14,3 +14,4 @@ A ns1.cwrap.org 127.0.0.24
A ns2.cwrap.org 127.0.0.25
URI _vpn.cwrap.org https://vpn.cwrap.org/VPN 2 5
URI _ftp.cwrap.org ftp://ftp.cwrap.org/public
+PTR 22.0.0.127.in-addr.arpa www.cwrap.org
diff --git a/tests/test_dns_fake.c b/tests/test_dns_fake.c
index 0702dc8f2267744a515ea979b39afeac0dc73ad6..0715ade30840279dddf4eec3bb9fd4041530a6a7 100644
--- a/tests/test_dns_fake.c
+++ b/tests/test_dns_fake.c
@@ -664,6 +664,47 @@ static void test_res_fake_a_via_cname(void **state)
assert_string_equal(addr, "127.0.0.22");
}
+static void test_res_fake_ptr_query(void **state)
+{
+ int rv;
+ struct __res_state dnsstate;
+ unsigned char answer[ANSIZE];
+ const uint8_t *rrdata;
+ char ptrname[MAXDNAME];
+ ns_msg handle;
+ ns_rr rr; /* expanded resource record */
+
+ (void) state; /* unused */
+
+ memset(&dnsstate, 0, sizeof(struct __res_state));
+ rv = res_ninit(&dnsstate);
+ assert_int_equal(rv, 0);
+
+ rv = res_nquery(&dnsstate, "22.0.0.127.in-addr.arpa", ns_c_in, ns_t_ptr,
+ 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 PTR and have the name that our
+ * fake hosts file contains
+ */
+ 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_ptr);
+
+ rrdata = ns_rr_rdata(rr);
+
+ rv = ns_name_uncompress(ns_msg_base(handle),
+ ns_msg_end(handle),
+ rrdata,
+ ptrname, MAXDNAME);
+ assert_int_not_equal(rv, -1);
+
+ assert_string_equal(ptrname, "www.cwrap.org");
+}
+
int main(void)
{
int rc;
@@ -682,6 +723,7 @@ int main(void)
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),
+ cmocka_unit_test(test_res_fake_ptr_query),
};
rc = cmocka_run_group_tests(fake_tests, NULL, NULL);
--
2.4.11
More information about the samba-technical
mailing list