Merge branch 'features/conversion_functions' into develop

This commit is contained in:
Willem Toorop 2015-12-23 12:13:44 +01:00
commit 8ebb047693
31 changed files with 3841 additions and 340 deletions

View File

@ -138,7 +138,20 @@ fi
])
ACX_ARG_RPATH
AC_ARG_ENABLE(debug-sched, AC_HELP_STRING([--enable-debug-sched], [Enable scheduling debugging messages]))
AC_ARG_ENABLE(debug-stub, AC_HELP_STRING([--enable-debug-stub], [Enable stub debugging messages]))
AC_ARG_ENABLE(debug-sec, AC_HELP_STRING([--enable-debug-sec], [Enable dnssec debugging messages]))
AC_ARG_ENABLE(all-debugging, AC_HELP_STRING([--enable-all-debugging], [Enable scheduling, stub and dnssec debugging]))
case "$enable_all_debugging" in
yes)
enable_debug_sched=yes
enable_debug_stub=yes
enable_debug_sec=yes
;;
no|*)
;;
esac
case "$enable_debug_sched" in
yes)
AC_DEFINE_UNQUOTED([SCHED_DEBUG], [1], [Define this to enable printing of scheduling debugging messages.])
@ -146,7 +159,6 @@ case "$enable_debug_sched" in
no|*)
;;
esac
AC_ARG_ENABLE(debug-stub, AC_HELP_STRING([--enable-debug-stub], [Enable stub debugging messages]))
case "$enable_debug_stub" in
yes)
AC_DEFINE_UNQUOTED([STUB_DEBUG], [1], [Define this to enable printing of stub debugging messages.])
@ -154,7 +166,6 @@ case "$enable_debug_stub" in
no|*)
;;
esac
AC_ARG_ENABLE(debug-sec, AC_HELP_STRING([--enable-debug-sec], [Enable dnssec debugging messages]))
case "$enable_debug_sec" in
yes)
AC_DEFINE_UNQUOTED([SEC_DEBUG], [1], [Define this to enable printing of dnssec debugging messages.])

View File

@ -230,14 +230,14 @@ const-info.lo const-info.o: $(srcdir)/const-info.c \
getdns/getdns_extra.h \
$(srcdir)/const-info.h
context.lo context.o: $(srcdir)/context.c \
config.h $(srcdir)/debug.h \
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
config.h \
$(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/libmini_event.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/util-internal.h \
$(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/stub.h \
$(srcdir)/list.h
$(srcdir)/list.h $(srcdir)/dict.h
convert.lo convert.o: $(srcdir)/convert.c \
config.h \
getdns/getdns.h \
@ -245,17 +245,18 @@ convert.lo convert.o: $(srcdir)/convert.c \
$(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/libmini_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
$(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h
$(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/convert.h
dict.lo dict.o: $(srcdir)/dict.c $(srcdir)/types-internal.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h \
config.h $(srcdir)/context.h \
$(srcdir)/extension/libmini_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
config.h \
$(srcdir)/context.h $(srcdir)/extension/libmini_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
$(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h
dnssec.lo dnssec.o: $(srcdir)/dnssec.c \
config.h $(srcdir)/debug.h \
config.h \
$(srcdir)/debug.h \
getdns/getdns.h \
$(srcdir)/context.h \
getdns/getdns_extra.h \
@ -276,8 +277,8 @@ list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h \
config.h $(srcdir)/context.h \
$(srcdir)/extension/libmini_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
config.h \
$(srcdir)/context.h $(srcdir)/extension/libmini_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
$(srcdir)/list.h $(srcdir)/dict.h
request-internal.lo request-internal.o: $(srcdir)/request-internal.c \
@ -288,7 +289,7 @@ request-internal.lo request-internal.o: $(srcdir)/request-internal.c \
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/libmini_event.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h \
$(srcdir)/gldns/rrdef.h $(srcdir)/dict.h
$(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/debug.h
rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h \
config.h \
getdns/getdns.h \
@ -299,21 +300,23 @@ rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h
rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h \
getdns/getdns.h \
$(srcdir)/rr-dict.h config.h \
$(srcdir)/rr-dict.h \
config.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h
stub.lo stub.o: $(srcdir)/stub.c \
config.h $(srcdir)/debug.h \
$(srcdir)/stub.h \
config.h \
$(srcdir)/debug.h $(srcdir)/stub.h \
getdns/getdns.h \
$(srcdir)/types-internal.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/context.h \
$(srcdir)/extension/libmini_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/context.h $(srcdir)/extension/libmini_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/util-internal.h $(srcdir)/general.h
sync.lo sync.o: $(srcdir)/sync.c \
getdns/getdns.h \
config.h $(srcdir)/context.h \
config.h \
$(srcdir)/context.h \
getdns/getdns_extra.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/libmini_event.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/general.h \
@ -327,6 +330,7 @@ util-internal.lo util-internal.o: $(srcdir)/util-internal.c \
$(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/libmini_event.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h
version.lo version.o: version.c
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c \
config.h \
$(srcdir)/gldns/gbuffer.h
@ -393,14 +397,14 @@ libevent.lo libevent.o: $(srcdir)/extension/libevent.c \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h
libmini_event.lo libmini_event.o: $(srcdir)/extension/libmini_event.c \
config.h $(srcdir)/debug.h \
$(srcdir)/types-internal.h \
config.h \
$(srcdir)/debug.h $(srcdir)/types-internal.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/extension/libmini_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
libuv.lo libuv.o: $(srcdir)/extension/libuv.c \
config.h $(srcdir)/debug.h \
$(srcdir)/types-internal.h \
config.h \
$(srcdir)/debug.h $(srcdir)/types-internal.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h

View File

@ -23,6 +23,7 @@ static struct const_info consts_info[] = {
{ 310, "GETDNS_RETURN_MEMORY_ERROR", GETDNS_RETURN_MEMORY_ERROR_TEXT },
{ 311, "GETDNS_RETURN_INVALID_PARAMETER", GETDNS_RETURN_INVALID_PARAMETER_TEXT },
{ 312, "GETDNS_RETURN_NOT_IMPLEMENTED", GETDNS_RETURN_NOT_IMPLEMENTED_TEXT },
{ 399, "GETDNS_RETURN_NEED_MORE_SPACE", GETDNS_RETURN_NEED_MORE_SPACE_TEXT },
{ 400, "GETDNS_DNSSEC_SECURE", GETDNS_DNSSEC_SECURE_TEXT },
{ 401, "GETDNS_DNSSEC_BOGUS", GETDNS_DNSSEC_BOGUS_TEXT },
{ 402, "GETDNS_DNSSEC_INDETERMINATE", GETDNS_DNSSEC_INDETERMINATE_TEXT },

View File

@ -2322,7 +2322,7 @@ ub_setup_recursing(struct ub_ctx *ctx, getdns_context *context)
, context->trust_anchors_len)
; rr ; rr = _getdns_rr_iter_next(rr) ) {
(void) gldns_wire2str_rr_buf(rr->pos,
(void) gldns_wire2str_rr_buf((UNCONST_UINT8_p)rr->pos,
rr->nxt - rr->pos, ta_str, sizeof(ta_str));
(void) ub_ctx_add_ta(ctx, ta_str);
}
@ -2510,8 +2510,7 @@ _getdns_strdup(const struct mem_funcs *mfs, const char *s)
}
struct getdns_bindata *
_getdns_bindata_copy(struct mem_funcs *mfs,
const struct getdns_bindata *src)
_getdns_bindata_copy(struct mem_funcs *mfs, size_t size, const uint8_t *data)
{
/* Don't know why, but nodata allows
* empty bindatas with the python bindings
@ -2519,20 +2518,16 @@ _getdns_bindata_copy(struct mem_funcs *mfs,
static uint8_t nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
struct getdns_bindata *dst;
if (!src)
return NULL;
if (!(dst = GETDNS_MALLOC(*mfs, struct getdns_bindata)))
return NULL;
dst->size = src->size;
if ((dst->size = src->size)) {
dst->data = GETDNS_XMALLOC(*mfs, uint8_t, src->size);
if ((dst->size = size)) {
dst->data = GETDNS_XMALLOC(*mfs, uint8_t, size);
if (!dst->data) {
GETDNS_FREE(*mfs, dst);
return NULL;
}
(void) memcpy(dst->data, src->data, src->size);
(void) memcpy(dst->data, data, size);
} else {
dst->data = nodata;
}
@ -3090,10 +3085,9 @@ getdns_context_get_upstream_recursive_servers(getdns_context *context,
if (upstream->tsig_alg) {
tsig_info = _getdns_get_tsig_info(upstream->tsig_alg);
bindata.data = tsig_info->dname;
bindata.size = tsig_info->dname_len;
if ((r = getdns_dict_set_bindata(
d, "tsig_algorithm", &bindata)))
if ((r = _getdns_dict_set_const_bindata(
d, "tsig_algorithm",
tsig_info->dname_len, tsig_info->dname)))
break;
if (upstream->tsig_dname_len) {

View File

@ -270,8 +270,7 @@ getdns_return_t _getdns_context_cancel_request(struct getdns_context *context,
char *_getdns_strdup(const struct mem_funcs *mfs, const char *str);
struct getdns_bindata *_getdns_bindata_copy(
struct mem_funcs *mfs,
const struct getdns_bindata *src);
struct mem_funcs *mfs, size_t size, const uint8_t *data);
void _getdns_bindata_destroy(
struct mem_funcs *mfs,

View File

@ -46,6 +46,9 @@
#include "util-internal.h"
#include "gldns/wire2str.h"
#include "gldns/str2wire.h"
#include "dict.h"
#include "list.h"
#include "convert.h"
/* stuff to make it compile pedantically */
#define UNUSED_PARAM(x) ((void)(x))
@ -219,4 +222,366 @@ getdns_strerror(getdns_return_t err, char *buf, size_t buflen)
return GETDNS_RETURN_GOOD;
} /* getdns_strerror */
/* --------------------- rr_dict, wire, str conversions --------------------- */
getdns_return_t
getdns_rr_dict2wire(
const getdns_dict *rr_dict, uint8_t **wire, size_t *wire_sz)
{
uint8_t buf_spc[4096], *buf;
size_t buf_len = sizeof(buf_spc);
getdns_return_t r = getdns_rr_dict2wire_buf(
rr_dict, buf_spc, &buf_len);
if (r != GETDNS_RETURN_GOOD && r != GETDNS_RETURN_NEED_MORE_SPACE)
return r;
if (!(buf = malloc(buf_len)))
return GETDNS_RETURN_MEMORY_ERROR;
if (!r)
memcpy(buf, buf_spc, buf_len);
else if ((r = getdns_rr_dict2wire_buf(rr_dict, buf, &buf_len))) {
free(buf);
return r;
}
*wire = buf;
*wire_sz = buf_len;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_rr_dict2wire_buf(
const getdns_dict *rr_dict, uint8_t *wire, size_t *wire_sz)
{
ssize_t my_wire_sz;
getdns_return_t r;
if (!wire_sz)
return GETDNS_RETURN_INVALID_PARAMETER;
else
my_wire_sz = *wire_sz;
r = getdns_rr_dict2wire_scan(rr_dict, &wire, &my_wire_sz);
if (r == GETDNS_RETURN_GOOD || r == GETDNS_RETURN_NEED_MORE_SPACE)
*wire_sz -= my_wire_sz;
return r;
}
getdns_return_t
getdns_rr_dict2wire_scan(
const getdns_dict *rr_dict, uint8_t **wire, ssize_t *wire_sz)
{
getdns_return_t r;
gldns_buffer gbuf;
if (!rr_dict || !wire || !*wire || !wire_sz)
return GETDNS_RETURN_INVALID_PARAMETER;
gldns_buffer_init_frm_data(&gbuf, *wire, *wire_sz);
if ((r = _getdns_rr_dict2wire(rr_dict, &gbuf)))
return r;
if (gldns_buffer_position(&gbuf) == 0)
return GETDNS_RETURN_GENERIC_ERROR;
*wire += gldns_buffer_position(&gbuf);
*wire_sz -= gldns_buffer_position(&gbuf);
if (gldns_buffer_position(&gbuf) > gldns_buffer_limit(&gbuf))
return GETDNS_RETURN_NEED_MORE_SPACE;
else
return GETDNS_RETURN_GOOD;
}
static struct mem_funcs _getdns_plain_mem_funcs = {
MF_PLAIN, .mf.pln = { malloc, realloc, free }
};
getdns_return_t
_getdns_wire2rr_dict(struct mem_funcs *mf,
const uint8_t *wire, size_t wire_len, getdns_dict **rr_dict)
{
return _getdns_wire2rr_dict_scan(mf, &wire, &wire_len, rr_dict);
}
getdns_return_t
getdns_wire2rr_dict(
const uint8_t *wire, size_t wire_len, getdns_dict **rr_dict)
{
return _getdns_wire2rr_dict(
&_getdns_plain_mem_funcs, wire, wire_len, rr_dict);
}
getdns_return_t
_getdns_wire2rr_dict_buf(struct mem_funcs *mf,
const uint8_t *wire, size_t *wire_len, getdns_dict **rr_dict)
{
size_t my_wire_len;
getdns_return_t r;
if (!wire_len)
return GETDNS_RETURN_INVALID_PARAMETER;
else
my_wire_len = *wire_len;
if ((r = _getdns_wire2rr_dict_scan(mf, &wire, &my_wire_len, rr_dict)))
return r;
*wire_len -= my_wire_len;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_wire2rr_dict_buf(
const uint8_t *wire, size_t *wire_len, getdns_dict **rr_dict)
{
return _getdns_wire2rr_dict_buf(
&_getdns_plain_mem_funcs, wire, wire_len, rr_dict);
}
getdns_return_t
_getdns_wire2rr_dict_scan(struct mem_funcs *mf,
const uint8_t **wire, size_t *wire_len, getdns_dict **rr_dict)
{
_getdns_rr_iter rr_iter_spc, *rr_iter;
if (!wire || !*wire || !wire_len || !rr_dict)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!(rr_iter = _getdns_single_rr_iter_init(
&rr_iter_spc, *wire, *wire_len)))
return GETDNS_RETURN_GENERIC_ERROR;
if (!(*rr_dict = _getdns_rr_iter2rr_dict(mf, rr_iter)))
return GETDNS_RETURN_MEMORY_ERROR;
*wire_len -= (rr_iter->nxt - rr_iter->pos);
*wire = rr_iter->nxt;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_wire2rr_dict_scan(
const uint8_t **wire, size_t *wire_len, getdns_dict **rr_dict)
{
return _getdns_wire2rr_dict_scan(
&_getdns_plain_mem_funcs, wire, wire_len, rr_dict);
}
getdns_return_t
getdns_rr_dict2str(
const getdns_dict *rr_dict, char **str)
{
char buf_spc[4096], *buf;
size_t buf_len = sizeof(buf_spc) - 1;
getdns_return_t r = getdns_rr_dict2str_buf(
rr_dict, buf_spc, &buf_len);
if (r != GETDNS_RETURN_GOOD && r != GETDNS_RETURN_NEED_MORE_SPACE)
return r;
if (!(buf = malloc(buf_len + 1)))
return GETDNS_RETURN_MEMORY_ERROR;
if (!r)
memcpy(buf, buf_spc, buf_len);
else if ((r = getdns_rr_dict2str_buf(rr_dict, buf, &buf_len))) {
free(buf);
return r;
}
buf[buf_len] = 0;
*str = buf;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_rr_dict2str_buf(
const getdns_dict *rr_dict, char *str, size_t *str_len)
{
ssize_t my_str_len;
getdns_return_t r;
if (!str_len)
return GETDNS_RETURN_INVALID_PARAMETER;
else
my_str_len = *str_len;
r = getdns_rr_dict2str_scan(rr_dict, &str, &my_str_len);
if (r == GETDNS_RETURN_GOOD || r == GETDNS_RETURN_NEED_MORE_SPACE)
*str_len -= my_str_len;
return r;
}
getdns_return_t
getdns_rr_dict2str_scan(
const getdns_dict *rr_dict, char **str, ssize_t *str_len)
{
getdns_return_t r;
gldns_buffer gbuf;
uint8_t buf_spc[4096], *buf = buf_spc, *scan_buf;
size_t sz, scan_sz;
ssize_t prev_str_len;
char *prev_str;
int sz_needed;
if (!rr_dict || !str || !*str || !str_len)
return GETDNS_RETURN_INVALID_PARAMETER;
gldns_buffer_init_frm_data(&gbuf, buf, sizeof(buf_spc));
r = _getdns_rr_dict2wire(rr_dict, &gbuf);
if (gldns_buffer_position(&gbuf) > sizeof(buf_spc)) {
if (!(buf = GETDNS_XMALLOC(
rr_dict->mf, uint8_t, (sz = gldns_buffer_position(&gbuf))))) {
return GETDNS_RETURN_MEMORY_ERROR;
}
gldns_buffer_init_frm_data(&gbuf, buf, sz);
r = _getdns_rr_dict2wire(rr_dict, &gbuf);
}
if (r) {
if (buf != buf_spc)
GETDNS_FREE(rr_dict->mf, buf);
return r;
}
scan_buf = gldns_buffer_begin(&gbuf);
scan_sz = gldns_buffer_position(&gbuf);
prev_str = *str;
prev_str_len = *str_len;
sz = (size_t)*str_len;
sz_needed = gldns_wire2str_rr_scan(
&scan_buf, &scan_sz, str, &sz, NULL, 0);
if (sz_needed > prev_str_len) {
*str = prev_str + sz_needed;
*str_len = prev_str_len - sz_needed;
r = GETDNS_RETURN_NEED_MORE_SPACE;
} else
*str_len = sz;
if (buf != buf_spc)
GETDNS_FREE(rr_dict->mf, buf);
return r;
}
getdns_return_t
_getdns_str2rr_dict(struct mem_funcs *mf,
const char *str, getdns_dict **rr_dict, const char *origin, uint32_t default_ttl)
{
uint8_t wire_spc[4096], *wire = wire_spc;
uint8_t origin_spc[256], *origin_wf;
size_t origin_len = sizeof(origin_spc), wire_len = sizeof(wire_spc);
int e;
getdns_return_t r;
if (!str || !rr_dict)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!origin)
origin_wf = NULL;
else if (gldns_str2wire_dname_buf(origin, origin_spc, &origin_len))
return GETDNS_RETURN_GENERIC_ERROR;
else
origin_wf = origin_spc;
e = gldns_str2wire_rr_buf(str, wire, &wire_len,
NULL, default_ttl, origin_wf, origin_len, NULL, 0);
if (GLDNS_WIREPARSE_ERROR(e) == GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL) {
if (!(wire = GETDNS_XMALLOC(
*mf, uint8_t, (wire_len = GLDNS_RR_BUF_SIZE))))
return GETDNS_RETURN_MEMORY_ERROR;
e = gldns_str2wire_rr_buf(str, wire, &wire_len,
NULL, default_ttl, origin_wf, origin_len, NULL, 0);
}
if (e) {
if (wire != wire_spc)
GETDNS_FREE(*mf, wire);
return GETDNS_RETURN_GENERIC_ERROR;
}
r = _getdns_wire2rr_dict(mf, wire, wire_len, rr_dict);
if (wire != wire_spc)
GETDNS_FREE(*mf, wire);
return r;
}
getdns_return_t
getdns_str2rr_dict(
const char *str, getdns_dict **rr_dict, const char *origin, uint32_t default_ttl)
{
return _getdns_str2rr_dict(
&_getdns_plain_mem_funcs, str, rr_dict, origin, default_ttl);
}
getdns_return_t
_getdns_fp2rr_list(struct mem_funcs *mf,
FILE *in, getdns_list **rr_list, const char *origin, uint32_t default_ttl)
{
struct gldns_file_parse_state pst;
getdns_list *rrs;
getdns_return_t r = GETDNS_RETURN_GOOD;
uint8_t *rr;
size_t len, dname_len;
getdns_dict *rr_dict;
if (!in || !rr_list)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!origin) {
*pst.origin = 0;
pst.origin_len = 1;
} else if (gldns_str2wire_dname_buf(origin,pst.origin,&pst.origin_len))
return GETDNS_RETURN_GENERIC_ERROR;
*pst.prev_rr = 0;
pst.prev_rr_len = 1;
pst.default_ttl = default_ttl;
pst.lineno = 1;
if (!(rrs = _getdns_list_create_with_mf(mf)))
return GETDNS_RETURN_MEMORY_ERROR;
if (!(rr = GETDNS_XMALLOC(*mf, uint8_t, GLDNS_RR_BUF_SIZE)))
r = GETDNS_RETURN_MEMORY_ERROR;
else while (r == GETDNS_RETURN_GOOD && !feof(in)) {
len = GLDNS_RR_BUF_SIZE;
dname_len = 0;
if (gldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst))
break;
if (dname_len && dname_len < sizeof(pst.prev_rr)) {
memcpy(pst.prev_rr, rr, dname_len);
pst.prev_rr_len = dname_len;
}
if (len == 0)
continue;
if ((r = _getdns_wire2rr_dict(mf, rr, len, &rr_dict)))
break;
r = _getdns_list_append_dict(rrs, rr_dict);
getdns_dict_destroy(rr_dict);
}
if (rr)
GETDNS_FREE(*mf, rr);
if (r)
getdns_list_destroy(rrs);
else
*rr_list = rrs;
return r;
}
getdns_return_t
getdns_fp2rr_list(
FILE *in, getdns_list **rr_list, const char *origin, uint32_t default_ttl)
{
return _getdns_fp2rr_list(
&_getdns_plain_mem_funcs, in, rr_list, origin, default_ttl);
}
/* convert.c */

57
src/convert.h Normal file
View File

@ -0,0 +1,57 @@
/**
*
* \file convert.h
* @brief getdns label conversion functions
*
*/
/*
* Copyright (c) 2013, NLnet Labs, Verisign, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the names of the copyright holders nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _GETDNS_CONVERT_H_
#define _GETDNS_CONVERT_H_
#include "types-internal.h"
#include <stdio.h>
getdns_return_t _getdns_wire2rr_dict(struct mem_funcs *mf,
const uint8_t *wire, size_t wire_len, getdns_dict **rr_dict);
getdns_return_t _getdns_wire2rr_dict_buf(struct mem_funcs *mf,
const uint8_t *wire, size_t *wire_len, getdns_dict **rr_dict);
getdns_return_t _getdns_wire2rr_dict_scan(struct mem_funcs *mf,
const uint8_t **wire, size_t *wire_len, getdns_dict **rr_dict);
getdns_return_t _getdns_str2rr_dict(struct mem_funcs *mf, const char *str,
getdns_dict **rr_dict, const char *origin, uint32_t default_ttl);
getdns_return_t _getdns_fp2rr_list(struct mem_funcs *mf, FILE *in,
getdns_list **rr_list, const char *origin, uint32_t default_ttl);
#endif
/* convert.h */

View File

@ -574,17 +574,17 @@ getdns_dict_set_list(
/*---------------------------------------- getdns_dict_set_bindata */
getdns_return_t
getdns_dict_set_bindata(
getdns_dict *dict, const char *name, const getdns_bindata *child_bindata)
_getdns_dict_set_const_bindata(
getdns_dict *dict, const char *name, size_t size, const uint8_t *data)
{
getdns_item *item;
getdns_bindata *newbindata;
getdns_return_t r;
if (!dict || !name || !child_bindata)
if (!dict || !name)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!(newbindata = _getdns_bindata_copy(&dict->mf, child_bindata)))
if (!(newbindata = _getdns_bindata_copy(&dict->mf, size, data)))
return GETDNS_RETURN_MEMORY_ERROR;
if ((r = _getdns_dict_find_and_add(dict, name, &item))) {
@ -596,6 +596,15 @@ getdns_dict_set_bindata(
return GETDNS_RETURN_GOOD;
} /* getdns_dict_set_bindata */
getdns_return_t
getdns_dict_set_bindata(
getdns_dict *dict, const char *name, const getdns_bindata *child_bindata)
{
return !child_bindata ? GETDNS_RETURN_INVALID_PARAMETER
: _getdns_dict_set_const_bindata(
dict, name, child_bindata->size, child_bindata->data);
}
/*---------------------------------------- getdns_dict_set_bindata */
getdns_return_t
getdns_dict_util_set_string(getdns_dict *dict, char *name, const char *value)

View File

@ -220,16 +220,16 @@
/******************* Frequently Used Utility Functions *********************
*****************************************************************************/
inline static size_t _dname_len(uint8_t *name)
inline static size_t _dname_len(const uint8_t *name)
{
uint8_t *p;
const uint8_t *p;
for (p = name; *p; p += *p + 1)
/* pass */
;
return p - name + 1;
}
inline static size_t _dname_label_count(uint8_t *name)
inline static size_t _dname_label_count(const uint8_t *name)
{
size_t c;
for (c = 0; *name; name += *name + 1, c++)
@ -268,20 +268,24 @@ static uint8_t *_dname_label_copy(uint8_t *dst, const uint8_t *src, size_t dst_l
return r;
}
inline static void _dname_canonicalize(uint8_t *dname)
inline static void _dname_canonicalize(const uint8_t *src, uint8_t *dst)
{
uint8_t *next_label;
const uint8_t *next_label;
while (*dname) {
next_label = dname + *dname + 1;
dname += 1;
while (dname < next_label) {
*dname = (uint8_t)tolower((unsigned char)*dname);
dname++;
}
while (*src) {
next_label = src + *src + 1;
*dst++ = *src++;
while (src < next_label)
*dst++ = (uint8_t)tolower((unsigned char)*src++);
}
}
inline static void _dname_canonicalize2(uint8_t *dname)
{
_dname_canonicalize(dname, dname);
}
/* Fills the array pointed to by labels (of at least 128 uint8_t * pointers)
* with pointers to labels in given dname in reversed order. So that
* labels[0] will point to the root.
@ -295,7 +299,8 @@ inline static void _dname_canonicalize(uint8_t *dname)
* labels[3] will be "www.getdnsapi.net."
* The returned value will be &labels[4]
*/
static uint8_t **reverse_labels(uint8_t *dname, uint8_t **labels)
static const uint8_t **reverse_labels(
const uint8_t *dname, const uint8_t **labels)
{
if (*dname)
labels = reverse_labels(dname + *dname + 1, labels);
@ -303,10 +308,12 @@ static uint8_t **reverse_labels(uint8_t *dname, uint8_t **labels)
return labels + 1;
}
static uint8_t *dname_shared_parent(uint8_t *left, uint8_t *right)
static const uint8_t *dname_shared_parent(
const uint8_t *left, const uint8_t *right)
{
uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel,
**llabel, **rlabel, *l, *r, sz;
const uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel,
**llabel, **rlabel, *l, *r;
uint8_t sz;
last_llabel = reverse_labels(left, llabels);
last_rlabel = reverse_labels(right, rlabels);
@ -334,10 +341,11 @@ static uint8_t *dname_shared_parent(uint8_t *left, uint8_t *right)
return llabel[-1];
}
static int dname_compare(uint8_t *left, uint8_t *right)
static int dname_compare(const uint8_t *left, const uint8_t *right)
{
uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel,
**llabel, **rlabel, *l, *r, lsz, rsz;
const uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel,
**llabel, **rlabel, *l, *r;
uint8_t lsz, rsz;
last_llabel = reverse_labels(left, llabels);
last_rlabel = reverse_labels(right, rlabels);
@ -374,7 +382,7 @@ static int dname_compare(uint8_t *left, uint8_t *right)
static int bitmap_has_type(_getdns_rdf_iter *bitmap, uint16_t rr_type)
{
uint8_t *dptr, *dend;
const uint8_t *dptr, *dend;
uint8_t window = rr_type >> 8;
uint8_t subtype = rr_type & 0xFF;
@ -398,7 +406,7 @@ inline static void debug_sec_print_rr(const char *msg, _getdns_rr_iter *rr)
{
char str_spc[8192], *str = str_spc;
size_t str_len = sizeof(str_spc);
uint8_t *data = rr->pos;
const uint8_t *data = rr->pos;
size_t data_len = rr->nxt - rr->pos;
if (!rr || !rr->pos) {
@ -406,14 +414,16 @@ inline static void debug_sec_print_rr(const char *msg, _getdns_rr_iter *rr)
return;
}
(void) gldns_wire2str_rr_scan(
&data, &data_len, &str, &str_len, rr->pkt, rr->pkt_end - rr->pkt);
(UNCONST_UINT8_p *) &data, &data_len, &str, &str_len,
(UNCONST_UINT8_p) rr->pkt, rr->pkt_end - rr->pkt);
DEBUG_SEC("%s%s", msg, str_spc);
}
inline static void debug_sec_print_dname(const char *msg, uint8_t *label)
inline static void debug_sec_print_dname(const char *msg, const uint8_t *label)
{
char str[1024];
if (label && gldns_wire2str_dname_buf(label, 256, str, sizeof(str)))
if (label && gldns_wire2str_dname_buf(
(UNCONST_UINT8_p)label, 256, str, sizeof(str)))
DEBUG_SEC("%s%s\n", msg, str);
else
DEBUG_SEC("%s<nil>\n", msg);
@ -443,9 +453,10 @@ static inline uint16_t rr_iter_class(_getdns_rr_iter *rr)
{ return rr->rr_type + 4 <= rr->nxt ? gldns_read_uint16(rr->rr_type + 2) : 0; }
/* Utility function to compare owner name of rr with name */
static int rr_owner_equal(_getdns_rr_iter *rr, uint8_t *name)
static int rr_owner_equal(_getdns_rr_iter *rr, const uint8_t *name)
{
uint8_t owner_spc[256], *owner;
uint8_t owner_spc[256];
const uint8_t *owner;
size_t owner_len = sizeof(owner_spc);
return (owner = _getdns_owner_if_or_as_decompressed(rr, owner_spc
@ -471,7 +482,7 @@ static _getdns_rr_iter *rr_iter_ansauth(_getdns_rr_iter *rr)
/* Filter that only iterates over RRs with a certain name/class/type */
static _getdns_rr_iter *rr_iter_name_class_type(_getdns_rr_iter *rr,
uint8_t *name, uint16_t rr_class, uint16_t rr_type)
const uint8_t *name, uint16_t rr_class, uint16_t rr_type)
{
while (rr_iter_ansauth(rr) && !(
rr_iter_type(rr) == rr_type &&
@ -485,7 +496,7 @@ static _getdns_rr_iter *rr_iter_name_class_type(_getdns_rr_iter *rr,
/* Filter that only iterates over RRs that do not have a name/class/type */
static _getdns_rr_iter *rr_iter_not_name_class_type(_getdns_rr_iter *rr,
uint8_t *name, uint16_t rr_class, uint16_t rr_type)
const uint8_t *name, uint16_t rr_class, uint16_t rr_type)
{
while (rr_iter_ansauth(rr) && (
rr_iter_type(rr) == GETDNS_RRTYPE_RRSIG || (
@ -502,7 +513,7 @@ static _getdns_rr_iter *rr_iter_not_name_class_type(_getdns_rr_iter *rr,
* a RRset with a certain name/class/type
*/
static _getdns_rr_iter *rr_iter_rrsig_covering(_getdns_rr_iter *rr,
uint8_t *name, uint16_t rr_class, uint16_t rr_type)
const uint8_t *name, uint16_t rr_class, uint16_t rr_type)
{
while (rr_iter_ansauth(rr) && !(
rr_iter_type(rr) == GETDNS_RRTYPE_RRSIG &&
@ -517,7 +528,7 @@ static _getdns_rr_iter *rr_iter_rrsig_covering(_getdns_rr_iter *rr,
}
typedef struct getdns_rrset {
uint8_t *name;
const uint8_t *name;
uint16_t rr_class;
uint16_t rr_type;
uint8_t *pkt;
@ -591,7 +602,8 @@ static void debug_sec_print_rrset(const char *msg, getdns_rrset *rrset)
return;
}
gldns_buffer_init_frm_data(&buf, buf_space, sizeof(buf_space));
if (gldns_wire2str_dname_buf(rrset->name, 256, owner, sizeof(owner)))
if (gldns_wire2str_dname_buf(
(UNCONST_UINT8_p)rrset->name, 256, owner, sizeof(owner)))
gldns_buffer_printf(&buf, "%s ", owner);
else gldns_buffer_printf(&buf, "<nil> ");
@ -765,23 +777,24 @@ struct chain_node {
* to equip the chain nodes with their RR sets are done alongside construction.
* Hence they need to be enumerated before the construction functions.
*/
static void val_chain_sched(chain_head *head, uint8_t *dname);
static void val_chain_sched_ds(chain_head *head, uint8_t *dname);
static void val_chain_sched(chain_head *head, const uint8_t *dname);
static void val_chain_sched_ds(chain_head *head, const uint8_t *dname);
static void val_chain_sched_signer(chain_head *head, rrsig_iter *rrsig);
static void val_chain_sched_soa(chain_head *head, uint8_t *dname);
static void val_chain_sched_soa(chain_head *head, const uint8_t *dname);
static chain_head *add_rrset2val_chain(struct mem_funcs *mf,
chain_head **chain_p, getdns_rrset *rrset, getdns_network_req *netreq)
{
chain_head *head;
uint8_t *labels[128], **last_label, **label;
const uint8_t *labels[128], **last_label, **label;
size_t max_labels; /* max labels in common */
chain_head *max_head;
chain_node *max_node;
size_t dname_len, head_sz, node_count, n;
uint8_t *dname, *region;
const uint8_t *dname;
uint8_t *region;
chain_node *node;
last_label = reverse_labels(rrset->name, labels);
@ -907,10 +920,11 @@ static int is_synthesized_cname(getdns_rrset *cname)
_getdns_rdf_iter rdf_spc, *rdf;
rrtype_iter drr_spc, *drr;
_getdns_rdf_iter drdf_spc, *drdf;
uint8_t cname_rdata_spc[256], *cname_rdata,
dname_rdata_spc[256], *dname_rdata,
uint8_t cname_rdata_spc[256],
dname_rdata_spc[256],
synth_name[256],
*synth_name_end = synth_name + sizeof(synth_name) - 1, *s, *c;
*synth_name_end = synth_name + sizeof(synth_name) - 1, *s;
const uint8_t *cname_rdata, *dname_rdata, *c;
size_t cname_rdata_len = sizeof(cname_rdata_spc),
dname_rdata_len = sizeof(dname_rdata_len),
cname_labels, dname_labels;
@ -1050,7 +1064,7 @@ static void add_pkt2val_chain(struct mem_funcs *mf,
*/
static void add_question2val_chain(struct mem_funcs *mf,
chain_head **chain_p, uint8_t *pkt, size_t pkt_len,
uint8_t *qname, uint16_t qtype, uint16_t qclass,
const uint8_t *qname, uint16_t qtype, uint16_t qclass,
getdns_network_req *netreq)
{
getdns_rrset q_rrset;
@ -1134,7 +1148,8 @@ static void val_chain_sched_soa_node(chain_node *node)
context = node->chains->netreq->owner->context;
loop = node->chains->netreq->owner->loop;
if (!gldns_wire2str_dname_buf(node->ds.name, 256, name, sizeof(name)))
if (!gldns_wire2str_dname_buf(
(UNCONST_UINT8_p)node->ds.name, 256, name, sizeof(name)))
return;
DEBUG_SEC("schedule SOA lookup for %s\n", name);
@ -1152,7 +1167,7 @@ static void val_chain_sched_soa_node(chain_node *node)
* answer, then a DS/DNSKEY lookup will follow the acquire the link of the
* authentication chain.
*/
static void val_chain_sched_soa(chain_head *head, uint8_t *dname)
static void val_chain_sched_soa(chain_head *head, const uint8_t *dname)
{
chain_node *node;
@ -1181,7 +1196,8 @@ static void val_chain_sched_node(chain_node *node)
context = node->chains->netreq->owner->context;
loop = node->chains->netreq->owner->loop;
if (!gldns_wire2str_dname_buf(node->ds.name, 256, name, sizeof(name)))
if (!gldns_wire2str_dname_buf(
(UNCONST_UINT8_p)node->ds.name, 256, name, sizeof(name)))
return;
DEBUG_SEC("schedule DS & DNSKEY lookup for %s\n", name);
@ -1201,7 +1217,7 @@ static void val_chain_sched_node(chain_node *node)
node->ds_req = dnsreq->netreqs[0];
}
static void val_chain_sched(chain_head *head, uint8_t *dname)
static void val_chain_sched(chain_head *head, const uint8_t *dname)
{
chain_node *node;
@ -1225,7 +1241,9 @@ static void val_chain_sched_ds_node(chain_node *node)
context = node->chains->netreq->owner->context;
loop = node->chains->netreq->owner->loop;
if (!gldns_wire2str_dname_buf(node->ds.name, 256, name, sizeof(name)))
if (!gldns_wire2str_dname_buf(
(UNCONST_UINT8_p)node->ds.name, 256, name, sizeof(name)))
return;
DEBUG_SEC("schedule DS lookup for %s\n", name);
@ -1238,7 +1256,7 @@ static void val_chain_sched_ds_node(chain_node *node)
node->ds_req = ds_req->netreqs[0];
}
static void val_chain_sched_ds(chain_head *head, uint8_t *dname)
static void val_chain_sched_ds(chain_head *head, const uint8_t *dname)
{
chain_node *node;
@ -1255,7 +1273,8 @@ static void val_chain_sched_ds(chain_head *head, uint8_t *dname)
static void val_chain_sched_signer_node(chain_node *node, rrsig_iter *rrsig)
{
_getdns_rdf_iter rdf_spc, *rdf;
uint8_t signer_spc[256], *signer;
uint8_t signer_spc[256];
const uint8_t *signer;
size_t signer_len;
if (!(rdf = _getdns_rdf_iter_init_at(&rdf_spc, &rrsig->rr_i, 7)))
@ -1370,7 +1389,8 @@ static int key_matches_signer(getdns_rrset *dnskey, getdns_rrset *rrset)
rrsig_iter rrsig_spc, *rrsig;
uint16_t keytag;
_getdns_rdf_iter rdf_spc, *rdf;
uint8_t signer_spc[256], *signer;
uint8_t signer_spc[256];
const uint8_t *signer;
size_t signer_len = sizeof(signer_spc);
assert(dnskey->rr_type == GETDNS_RRTYPE_DNSKEY);
@ -1385,7 +1405,8 @@ static int key_matches_signer(getdns_rrset *dnskey, getdns_rrset *rrset)
continue;
/* Then we have at least 4 bytes to calculate keytag */
keytag = gldns_calc_keytag_raw(rr->rr_i.rr_type + 10,
keytag = gldns_calc_keytag_raw(
(UNCONST_UINT8_p)rr->rr_i.rr_type + 10,
rr->rr_i.nxt - rr->rr_i.rr_type - 10);
for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset)
@ -1458,7 +1479,7 @@ typedef struct canon_rdata_iter {
_getdns_rdf_iter rdf_spc;
_getdns_rdf_iter *rdf;
uint8_t cdname[256]; /* Canonical dname */
uint8_t *pos;
const uint8_t *pos;
size_t len;
} canon_rdata_iter;
@ -1468,8 +1489,10 @@ inline static void canon_rdata_iter_field_init(canon_rdata_iter *i)
if ((i->rdf->rdd_pos->type & GETDNS_RDF_N) == GETDNS_RDF_N) {
i->len = sizeof(i->cdname);
if ((i->pos = _getdns_rdf_if_or_as_decompressed(
i->rdf, i->cdname, &i->len)))
_dname_canonicalize(i->pos);
i->rdf, i->cdname, &i->len))) {
_dname_canonicalize(i->pos, i->cdname);
i->pos = i->cdname;
}
} else {
i->pos = i->rdf->pos;
i->len = i->rdf->nxt - i->rdf->pos;
@ -1559,7 +1582,7 @@ static int _rr_iter_rdata_cmp(const void *a, const void *b)
*/
#define VAL_RRSET_SPC_SZ 1024
static int _getdns_verify_rrsig(struct mem_funcs *mf,
getdns_rrset *rrset, rrsig_iter *rrsig, rrtype_iter *key, uint8_t **nc_name)
getdns_rrset *rrset, rrsig_iter *rrsig, rrtype_iter *key, const uint8_t **nc_name)
{
int r;
int to_skip;
@ -1569,7 +1592,8 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
size_t n_rrs, i, valbuf_sz, owner_len;
_getdns_rdf_iter *signer, signer_spc, *rdf, rdf_spc;
uint8_t valbuf_spc[4096], *valbuf_buf = valbuf_spc;
uint8_t cdname_spc[256], *cdname, owner[256];
uint8_t cdname_spc[256], owner[256];
const uint8_t *cdname;
size_t cdname_len, pos;
uint32_t orig_ttl;
gldns_buffer valbuf;
@ -1621,12 +1645,12 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
gldns_buffer_init_frm_data(&valbuf, valbuf_buf, valbuf_sz);
gldns_buffer_write(&valbuf,
rrsig->rr_i.rr_type + 10, signer->nxt - rrsig->rr_i.rr_type - 10);
_dname_canonicalize(gldns_buffer_at(&valbuf, 18));
_dname_canonicalize2(gldns_buffer_at(&valbuf, 18));
orig_ttl = gldns_read_uint32(rrsig->rr_i.rr_type + 14);
(void) memcpy(owner, rrset->name, owner_len);
_dname_canonicalize(owner);
_dname_canonicalize2(owner);
if (!_dnssec_rdata_to_canonicalize(rrset->rr_type))
for (i = 0; i < n_rrs; i++) {
@ -1663,7 +1687,7 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
rdf, cdname_spc, &cdname_len)))
continue;
gldns_buffer_write(&valbuf, cdname, cdname_len);
_dname_canonicalize(
_dname_canonicalize2(
gldns_buffer_current(&valbuf) - cdname_len);
}
gldns_buffer_write_u16_at(&valbuf, pos,
@ -1675,8 +1699,9 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
gldns_buffer_flip(&valbuf);
r = _getdns_verify_canonrrset(&valbuf, key->rr_i.rr_type[13],
signer->nxt, rrsig->rr_i.nxt - signer->nxt,
key->rr_i.rr_type+14, key->rr_i.nxt - key->rr_i.rr_type-14,
(UNCONST_UINT8_p)signer->nxt, rrsig->rr_i.nxt - signer->nxt,
(UNCONST_UINT8_p)key->rr_i.rr_type+14,
key->rr_i.nxt - key->rr_i.rr_type-14,
&reason);
#if defined(SEC_DEBUG) && SEC_DEBUG
@ -1722,7 +1747,8 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
/* Calculates NSEC3 hash for name, and stores that into label */
static uint8_t *_getdns_nsec3_hash_label(uint8_t *label, size_t label_len,
uint8_t *name, uint8_t algorithm, uint16_t iterations, uint8_t *salt)
const uint8_t *name, uint8_t algorithm,
uint16_t iterations, const uint8_t *salt)
{
uint8_t buf[512], *dst, *eob;
const uint8_t *src;
@ -1759,11 +1785,12 @@ static uint8_t *_getdns_nsec3_hash_label(uint8_t *label, size_t label_len,
}
static uint8_t *name2nsec3_label(
getdns_rrset *nsec3, uint8_t *name, uint8_t *label, size_t label_len)
getdns_rrset *nsec3, const uint8_t *name, uint8_t *label, size_t label_len)
{
rrsig_iter rrsig_spc, *rrsig;
_getdns_rdf_iter rdf_spc, *rdf;
uint8_t signer_spc[256], *signer;
uint8_t signer_spc[256];
const uint8_t *signer;
size_t signer_len = sizeof(signer_spc);
rrtype_iter rr_spc, *rr;
@ -1844,11 +1871,12 @@ static int check_dates(int32_t now, int32_t skew, int32_t exp, int32_t inc)
* expansion, nc_name will point to the next closer part of the name in rrset.
*/
static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
rrtype_iter *dnskey, getdns_rrset *rrset, uint8_t **nc_name)
rrtype_iter *dnskey, getdns_rrset *rrset, const uint8_t **nc_name)
{
rrsig_iter rrsig_spc, *rrsig;
_getdns_rdf_iter rdf_spc, *rdf;
uint8_t signer_spc[256], *signer;
uint8_t signer_spc[256];
const uint8_t *signer;
size_t signer_len = sizeof(signer_spc);
uint16_t keytag;
@ -1862,7 +1890,7 @@ static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
return 0;
/* Then we have at least 4 bytes to calculate keytag */
keytag = gldns_calc_keytag_raw(dnskey->rr_i.rr_type + 10,
keytag = gldns_calc_keytag_raw((UNCONST_UINT8_p)dnskey->rr_i.rr_type + 10,
dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10);
for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset)
@ -1911,15 +1939,15 @@ static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
}
static int find_nsec_covering_name(
struct mem_funcs *mf, time_t now, uint32_t skew,
getdns_rrset *dnskey, getdns_rrset *rrset, uint8_t *name, int *opt_out);
struct mem_funcs *mf, time_t now, uint32_t skew, getdns_rrset *dnskey,
getdns_rrset *rrset, const uint8_t *name, int *opt_out);
/* Returns whether a dnskey for keyset signed rrset. */
static int a_key_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
getdns_rrset *keyset, getdns_rrset *rrset)
{
rrtype_iter dnskey_spc, *dnskey;
uint8_t *nc_name;
const uint8_t *nc_name;
int keytag;
assert(keyset->rr_type == GETDNS_RRTYPE_DNSKEY);
@ -1961,7 +1989,7 @@ static int ds_authenticates_keys(struct mem_funcs *mf,
rrtype_iter dnskey_spc, *dnskey;
rrtype_iter ds_spc, *ds;
uint16_t keytag;
uint8_t *nc_name;
const uint8_t *nc_name;
size_t valid_dsses = 0, supported_dsses = 0;
uint8_t max_supported_digest = 0;
int max_supported_result = 0;
@ -1984,7 +2012,7 @@ static int ds_authenticates_keys(struct mem_funcs *mf,
return 0;
(void) memcpy(digest_buf_spc, dnskey_set->name, dnskey_owner_len);
_dname_canonicalize(digest_buf_spc);
_dname_canonicalize2(digest_buf_spc);
for ( dnskey = rrtype_iter_init(&dnskey_spc, dnskey_set)
; dnskey ; dnskey = rrtype_iter_next(dnskey)) {
@ -1993,7 +2021,8 @@ static int ds_authenticates_keys(struct mem_funcs *mf,
if (dnskey->rr_i.nxt < dnskey->rr_i.rr_type + 14)
continue;
keytag = gldns_calc_keytag_raw(dnskey->rr_i.rr_type + 10,
keytag = gldns_calc_keytag_raw(
(UNCONST_UINT8_p) dnskey->rr_i.rr_type + 10,
dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10);
for ( ds = rrtype_iter_init(&ds_spc, ds_set)
@ -2117,16 +2146,16 @@ static int ds_authenticates_keys(struct mem_funcs *mf,
}
static int nsec_covers_name(
getdns_rrset *nsec, uint8_t *name, uint8_t **ce_name)
getdns_rrset *nsec, const uint8_t *name, const uint8_t **ce_name)
{
uint8_t owner_spc[256], *owner;
size_t owner_len = sizeof(owner_spc);
uint8_t next_spc[256], *next;
size_t next_len = sizeof(next_spc);
uint8_t owner_spc[256], next_spc[256];
const uint8_t *owner, *next;
size_t owner_len = sizeof(owner_spc), next_len = sizeof(next_spc);
rrtype_iter rr_spc, *rr;
_getdns_rdf_iter rdf_spc, *rdf;
int nsec_cmp;
uint8_t *common1, *common2;
const uint8_t *common1, *common2;
if (/* Get owner and next, nicely decompressed */
!(rr = rrtype_iter_init(&rr_spc, nsec))
@ -2175,7 +2204,7 @@ static int nsec_covers_name(
}
}
static int nsec3_matches_name(getdns_rrset *nsec3, uint8_t *name)
static int nsec3_matches_name(getdns_rrset *nsec3, const uint8_t *name)
{
uint8_t label[64], owner[64];
@ -2188,7 +2217,8 @@ static int nsec3_matches_name(getdns_rrset *nsec3, uint8_t *name)
return 0;
}
static int nsec3_covers_name(getdns_rrset *nsec3, uint8_t *name, int *opt_out)
static int nsec3_covers_name(
getdns_rrset *nsec3, const uint8_t *name, int *opt_out)
{
uint8_t label[65], next[65], owner[65];
rrtype_iter rr_spc, *rr;
@ -2239,8 +2269,8 @@ static int nsec3_covers_name(getdns_rrset *nsec3, uint8_t *name, int *opt_out)
}
static int find_nsec_covering_name(
struct mem_funcs *mf, time_t now, uint32_t skew,
getdns_rrset *dnskey, getdns_rrset *rrset, uint8_t *name, int *opt_out)
struct mem_funcs *mf, time_t now, uint32_t skew, getdns_rrset *dnskey,
getdns_rrset *rrset, const uint8_t *name, int *opt_out)
{
rrset_iter i_spc, *i;
getdns_rrset *n;
@ -2337,7 +2367,8 @@ static int find_nsec_covering_name(
static int nsec3_find_next_closer(
struct mem_funcs *mf, time_t now, uint32_t skew,
getdns_rrset *dnskey, getdns_rrset *rrset, uint8_t *nc_name, int *opt_out)
getdns_rrset *dnskey, getdns_rrset *rrset,
const uint8_t *nc_name, int *opt_out)
{
uint8_t wc_name[256] = { 1, (uint8_t)'*' };
int my_opt_out, keytag;
@ -2394,7 +2425,7 @@ static int key_proves_nonexistance(
rrtype_iter nsec_spc, *nsec_rr;
_getdns_rdf_iter bitmap_spc, *bitmap;
rrset_iter i_spc, *i;
uint8_t *ce_name, *nc_name;
const uint8_t *ce_name, *nc_name;
uint8_t wc_name[256] = { 1, (uint8_t)'*' };
int keytag;
@ -3080,7 +3111,7 @@ static void append_empty_ds2val_chain_list(
return;
bindata.size = _dname_len(ds->name);
bindata.data = ds->name;
bindata.data = (UNCONST_UINT8_p)ds->name;
(void) getdns_dict_set_bindata(rr_dict, "name", &bindata);
(void) getdns_dict_set_int(rr_dict, "class", ds->rr_class);
(void) getdns_dict_set_int(rr_dict, "type", ds->rr_type);
@ -3261,7 +3292,8 @@ static int wire_validate_dnssec(struct mem_funcs *mf,
chain_head *chain, *head, *next_head;
chain_node *node;
uint8_t qname_spc[256], *qname = NULL;
uint8_t qname_spc[256];
const uint8_t *qname = NULL;
size_t qname_len = sizeof(qname_spc);
uint16_t qtype = 0, qclass = GETDNS_RRCLASS_IN;

View File

@ -30,6 +30,7 @@
#include <getdns/getdns.h>
#include <sys/time.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
@ -400,6 +401,180 @@ getdns_context_get_tls_authentication(getdns_context *context,
#define GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN 545
#define GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
#define GETDNS_RETURN_NEED_MORE_SPACE ((getdns_return_t) 399 )
#define GETDNS_RETURN_NEED_MORE_SPACE_TEXT "The buffer was too small"
/**
* Convert rr_dict to wireformat representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @return wire A newly allocated buffer which will contain the wireformat.
* @return wire_sz The size of the allocated buffer and the wireformat.
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_rr_dict2wire(
const getdns_dict *rr_dict, uint8_t **wire, size_t *wire_sz);
/**
* Convert rr_dict to wireformat representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @param wire The buffer in which the wireformat will be written
* @param wire_sz On input the size of the wire buffer,
* On output the amount of wireformat needed for the
* wireformat representation of the resource record;
* even if it did not fit.
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
* GETDNS_RETURN_NEED_MORE_SPACE will be returned when the buffer was too
* small. wire_sz will be set to the needed buffer space then.
*/
getdns_return_t
getdns_rr_dict2wire_buf(
const getdns_dict *rr_dict, uint8_t *wire, size_t *wire_sz);
/**
* Convert rr_dict to wireformat representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @param wire A pointer to the buffer pointer in which the wireformat
* will be written.
* On output the buffer pointer will have moved along
* the buffer and point right after the just written RR.
* @param wire_sz On input the size of the wire buffer,
* On output the amount of wireformat needed for the
* wireformat will have been substracted from wire_sz.
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
* GETDNS_RETURN_NEED_MORE_SPACE will be returned when the buffer was too
* small. The function will pretend that it had written beyond the end
* of the buffer, and wire will point past the buffer and wire_sz will
* contain a negative value.
*/
getdns_return_t
getdns_rr_dict2wire_scan(
const getdns_dict *rr_dict, uint8_t **wire, ssize_t *wire_sz);
/**
* Convert wireformat resource record in a getdns rr_dict representation.
*
* @param wire Buffer containing the wireformat rr
* @param wire_sz Size of the wire buffer
* @return rr_dict The returned rr_dict
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_wire2rr_dict(
const uint8_t *wire, size_t wire_sz, getdns_dict **rr_dict);
/**
* Convert wireformat resource record in a getdns rr_dict representation.
*
* @param wire Buffer containing the wireformat rr
* @param wire_sz On input the size of the wire buffer
* On output the length of the wireformat rr.
* @return rr_dict The returned rr_dict
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_wire2rr_dict_buf(
const uint8_t *wire, size_t *wire_sz, getdns_dict **rr_dict);
/**
* Convert wireformat resource record in a getdns rr_dict representation.
*
* @param wire A pointer to the pointer of the wireformat buffer.
* On return this pointer is moved to after first read
* in resource record.
* @param wire_sz On input the size of the wire buffer
* On output the size is decreased with the length
* of the wireformat resource record.
* @return rr_dict The returned rr_dict
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_wire2rr_dict_scan(
const uint8_t **wire, size_t *wire_sz, getdns_dict **rr_dict);
/**
* Convert rr_dict to the string representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @return str A newly allocated string representation of the rr
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_rr_dict2str(
const getdns_dict *rr_dict, char **str);
/**
* Convert rr_dict to the string representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @param str The buffer in which the string will be written
* @param str_len On input the size of the text buffer,
* On output the amount of characters needed to write
* the string representation of the rr. Even if it does
* not fit.
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
* GETDNS_RETURN_NEED_MORE_SPACE will be returned when the buffer was too
* small. str_len will be set to the needed buffer space then.
*/
getdns_return_t
getdns_rr_dict2str_buf(
const getdns_dict *rr_dict, char *str, size_t *str_len);
/**
* Convert rr_dict to the string representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @param str A pointer to the buffer pointer in which the string
* will be written.
* On output the buffer pointer will have moved along
* the buffer and point right after the just written RR.
* @param str_len On input the size of the str buffer,
* On output the number of characters needed for the
* string will have been substracted from strlen.
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
* GETDNS_RETURN_NEED_MORE_SPACE will be returned when the buffer was too
* small. The function will pretend that it had written beyond the end
* of the buffer, and str will point past the buffer and str_len will
* contain a negative value.
*/
getdns_return_t
getdns_rr_dict2str_scan(
const getdns_dict *rr_dict, char **str, ssize_t *str_len);
/**
* Convert the string representation of the resource record to rr_dict format.
*
* @param str String representation of the resource record.
* @return rr_dict The result getdns dict representation of the resource record
* @param origin Default suffix for not fully qualified domain names
* @param default_ttl Default ttl
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_str2rr_dict(
const char *str, getdns_dict **rr_dict,
const char *origin, uint32_t default_ttl);
/**
* Read the zonefile and convert to a list of rr_dict's.
*
* @param fp String representation of the resource record.
* @return rr_list The result list of rr_dicts representing the zone file.
* @param origin Default suffix for not fully qualified domain names
* @param default_ttl Default ttl
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_fp2rr_list(
FILE *in, getdns_list **rr_list,
const char *origin, uint32_t default_ttl);
#ifdef __cplusplus
}
#endif

View File

@ -867,7 +867,7 @@ int gldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
return s;
} else if(strncmp(line, "$TTL", 4) == 0 && isspace(line[4])) {
const char* end = NULL;
size_t off = 8;
size_t off = 5;
*len = 0;
*dname_len = 0;
if(!parse_state) return GLDNS_WIREPARSE_ERR_OK;

View File

@ -83,6 +83,7 @@ getdns_dict_set_list
getdns_dict_util_get_string
getdns_dict_util_set_string
getdns_display_ip_address
getdns_fp2rr_list
getdns_general
getdns_general_sync
getdns_get_api_version
@ -114,11 +115,21 @@ getdns_pretty_snprint_list
getdns_print_json_dict
getdns_print_json_list
getdns_root_trust_anchor
getdns_rr_dict2str
getdns_rr_dict2str_buf
getdns_rr_dict2str_scan
getdns_rr_dict2wire
getdns_rr_dict2wire_buf
getdns_rr_dict2wire_scan
getdns_service
getdns_service_sync
getdns_snprint_json_dict
getdns_snprint_json_list
getdns_str2rr_dict
getdns_strerror
getdns_validate_dnssec
getdns_wire2rr_dict
getdns_wire2rr_dict_buf
getdns_wire2rr_dict_scan
plain_mem_funcs_user_arg
priv_getdns_context_mf

View File

@ -107,6 +107,13 @@ _getdns_list_remove_name(getdns_list *list, const char *name)
i = &list->items[index];
if (!*next) {
switch (i->dtype) {
case t_dict : getdns_dict_destroy(i->data.dict); break;
case t_list : getdns_list_destroy(i->data.list); break;
case t_bindata: _getdns_bindata_destroy(
&list->mf, i->data.bindata);
default : break;
}
if (index < list->numinuse - 1)
(void) memmove( i, &i[1],
(list->numinuse - index) * sizeof(getdns_item));
@ -545,17 +552,17 @@ getdns_list_set_list(
} /* getdns_list_set_list */
/*---------------------------------------- getdns_list_set_bindata */
getdns_return_t
getdns_list_set_bindata(
getdns_list *list, size_t index, const getdns_bindata *child_bindata)
static getdns_return_t
_getdns_list_set_const_bindata(
getdns_list *list, size_t index, size_t size, const uint8_t *data)
{
getdns_bindata *newbindata;
getdns_return_t r;
if (!list || !child_bindata)
if (!list)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!(newbindata = _getdns_bindata_copy(&list->mf, child_bindata)))
if (!(newbindata = _getdns_bindata_copy(&list->mf, size, data)))
return GETDNS_RETURN_MEMORY_ERROR;
if ((r = _getdns_list_request_index(list, index))) {
@ -567,6 +574,15 @@ getdns_list_set_bindata(
return GETDNS_RETURN_GOOD;
} /* getdns_list_set_bindata */
getdns_return_t
getdns_list_set_bindata(
getdns_list *list, size_t index, const getdns_bindata *child_bindata)
{
return !child_bindata ? GETDNS_RETURN_INVALID_PARAMETER
: _getdns_list_set_const_bindata(
list, index, child_bindata->size, child_bindata->data);
}
/*----------------------------------------- getdns_list_set_string */
static getdns_return_t
getdns_list_set_string(getdns_list *list, size_t index, const char *value)
@ -631,6 +647,13 @@ _getdns_list_append_bindata(getdns_list *list, const getdns_bindata *child_binda
return getdns_list_set_bindata(list, list->numinuse, child_bindata);
}
getdns_return_t
_getdns_list_append_const_bindata(
getdns_list *list, size_t size, const uint8_t *data)
{
if (!list) return GETDNS_RETURN_INVALID_PARAMETER;
return _getdns_list_set_const_bindata(list, list->numinuse, size, data);
}
getdns_return_t
_getdns_list_append_string(getdns_list *list, const char *value)
{
if (!list) return GETDNS_RETURN_INVALID_PARAMETER;

View File

@ -12,7 +12,7 @@ cat > const-info.c << END_OF_HEAD
static struct const_info consts_info[] = {
{ -1, NULL, "/* <unknown getdns value> */" },
END_OF_HEAD
gawk '/^[ ]+GETDNS_[A-Z_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%4d", $3); consts[key] = $1; }/^#define GETDNS_[A-Z_]+[ ]+[0-9]+/ && !/^#define GETDNS_RRTYPE/ && !/^#define GETDNS_RRCLASS/ && !/^#define GETDNS_OPCODE/ && !/^#define GETDNS_RCODE/ && !/_TEXT/{ key = sprintf("%4d", $3); consts[key] = $2; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ "val", \""name"\", "name"_TEXT },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in | sed 's/,,/,/g' >> const-info.c
gawk '/^[ ]+GETDNS_[A-Z_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%4d", $3); consts[key] = $1; }/^#define GETDNS_[A-Z_]+[ ]+[0-9]+/ && !/^#define GETDNS_RRTYPE/ && !/^#define GETDNS_RRCLASS/ && !/^#define GETDNS_OPCODE/ && !/^#define GETDNS_RCODE/ && !/_TEXT/{ key = sprintf("%4d", $3); consts[key] = $2; }/^#define GETDNS_[A-Z_]+[ ]+\(\(getdns_return_t) [0-9]+ \)/{ key = sprintf("%4d", $4); consts[key] = $2; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ "val", \""name"\", "name"_TEXT },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in | sed 's/,,/,/g' >> const-info.c
cat >> const-info.c << END_OF_TAIL
};

View File

@ -402,13 +402,13 @@ _getdns_network_validate_tsig(getdns_network_req *req)
{
_getdns_rr_iter rr_spc, *rr;
_getdns_rdf_iter rdf_spc, *rdf;
uint8_t *request_mac;
const uint8_t *request_mac;
uint16_t request_mac_len;
uint8_t tsig_vars[MAXIMUM_TSIG_SPACE];
gldns_buffer gbuf;
uint8_t *dname;
const uint8_t *dname;
size_t dname_len;
uint8_t *response_mac;
const uint8_t *response_mac;
uint16_t response_mac_len;
uint8_t other_len;
uint8_t result_mac[EVP_MAX_MD_SIZE];

View File

@ -44,52 +44,139 @@
#define ALEN(a) (sizeof(a)/sizeof(a[0]))
#define UNKNOWN_RDATA NULL
static uint8_t *
apl_n_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
apl_n_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
return rdf < pkt_end ? rdf + 1 : NULL;
}
static getdns_return_t
apl_n_dict_set_value(getdns_dict *dict, uint8_t *rdf)
apl_n_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
return getdns_dict_set_int(dict, "n", (*rdf >> 7));
}
static getdns_return_t
apl_n_list_append_value(getdns_list *list, uint8_t *rdf)
apl_n_wire2list(getdns_list *list, const uint8_t *rdf)
{
return _getdns_list_append_int(list, (*rdf >> 7));
}
static getdns_return_t
apl_n_2wire(uint32_t value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
(void)rdata; /* unused parameter */
if (*rdf_len < 1) {
*rdf_len = 1;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = 1;
*rdf = value ? 0x80 : 0x00;
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
apl_n_dict2wire(const getdns_dict *dict,
uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
uint32_t value;
if ((r = getdns_dict_get_int(dict, "n", &value)))
return r;
else
return apl_n_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
apl_n_list2wire(const getdns_list *list, size_t i,
uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
uint32_t value;
if ((r = getdns_list_get_int(list, i, &value)))
return r;
else
return apl_n_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special apl_n = {
apl_n_rdf_end, apl_n_dict_set_value, apl_n_list_append_value
apl_n_rdf_end,
apl_n_wire2dict, apl_n_wire2list,
apl_n_dict2wire, apl_n_list2wire
};
static uint8_t *
apl_afdpart_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
apl_afdpart_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
uint8_t *end = rdf + (rdf[-1] & 0x7F);
const uint8_t *end = rdf + (rdf[-1] & 0x7F);
return end <= pkt_end ? end : NULL;
}
static getdns_return_t
apl_afdpart_dict_set_value(getdns_dict *dict, uint8_t *rdf)
apl_afdpart_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
getdns_bindata bindata = { (rdf[-1] & 0x7F), rdf };
return getdns_dict_set_bindata(dict, "afdpart", &bindata);
return _getdns_dict_set_const_bindata(
dict, "afdpart", (rdf[-1] & 0x7F), rdf);
}
static getdns_return_t
apl_afdpart_list_append_value(getdns_list *list, uint8_t *rdf)
apl_afdpart_wire2list(getdns_list *list, const uint8_t *rdf)
{
getdns_bindata bindata = { (rdf[-1] & 0x7F), rdf };
return _getdns_list_append_bindata(list, &bindata);
return _getdns_list_append_const_bindata(list, (rdf[-1] & 0x7F), rdf);
}
static getdns_return_t
apl_afdpart_2wire(
const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
if (value->size > 0x7F)
return GETDNS_RETURN_INVALID_PARAMETER;
if (rdf - 1 < rdata)
return GETDNS_RETURN_GENERIC_ERROR;
if (*rdf_len < value->size) {
*rdf_len = value->size;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = value->size;
/* Keeping first bit is safe because value->size <= 0x7F */
rdf[-1] |= value->size;
(void) memcpy(rdf, value->data, value->size);
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
apl_afdpart_dict2wire(
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_dict_get_bindata(dict, "afdpart", &value)))
return r;
else
return apl_afdpart_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
apl_afdpart_list2wire(const getdns_list *list,
size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_list_get_bindata(list, i, &value)))
return r;
else
return apl_afdpart_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special apl_afdpart = {
apl_afdpart_rdf_end,
apl_afdpart_dict_set_value, apl_afdpart_list_append_value
apl_afdpart_wire2dict, apl_afdpart_wire2list,
apl_afdpart_dict2wire, apl_afdpart_list2wire
};
static uint8_t *
ipseckey_gateway_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
ipseckey_gateway_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
uint8_t *end;
const uint8_t *end;
if (rdf - 5 < pkt)
return NULL;
@ -116,15 +203,16 @@ ipseckey_gateway_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
return end <= pkt_end ? end : NULL;
}
static getdns_return_t
ipseckey_gateway_equip_bindata(uint8_t *rdf, getdns_bindata *bindata)
ipseckey_gateway_equip_const_bindata(
const uint8_t *rdf, size_t *size, const uint8_t **data)
{
bindata->data = rdf;
*data = rdf;
switch (rdf[-2]) {
case 0: bindata->size = 0;
case 0: *size = 0;
break;
case 1: bindata->size = 4;
case 1: *size = 4;
break;
case 2: bindata->size = 16;
case 2: *size = 16;
break;
case 3: while (*rdf)
if ((*rdf & 0xC0) == 0xC0)
@ -133,112 +221,318 @@ ipseckey_gateway_equip_bindata(uint8_t *rdf, getdns_bindata *bindata)
return GETDNS_RETURN_GENERIC_ERROR;
else
rdf += *rdf + 1;
bindata->size = rdf + 1 - bindata->data;
*size = rdf + 1 - *data;
break;
default:
return GETDNS_RETURN_GENERIC_ERROR;
}
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
ipseckey_gateway_dict_set_value(getdns_dict *dict, uint8_t *rdf)
{
getdns_bindata bindata;
if (ipseckey_gateway_equip_bindata(rdf, &bindata))
static getdns_return_t
ipseckey_gateway_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
size_t size;
const uint8_t *data;
if (ipseckey_gateway_equip_const_bindata(rdf, &size, &data))
return GETDNS_RETURN_GENERIC_ERROR;
else if (! bindata.size)
else if (! size)
return GETDNS_RETURN_GOOD;
else
return getdns_dict_set_bindata(dict, "gateway", &bindata);
return _getdns_dict_set_const_bindata(dict, "gateway", size, data);
}
static getdns_return_t
ipseckey_gateway_list_append_value(getdns_list *list, uint8_t *rdf)
ipseckey_gateway_wire2list(getdns_list *list, const uint8_t *rdf)
{
getdns_bindata bindata;
size_t size;
const uint8_t *data;
if (ipseckey_gateway_equip_bindata(rdf, &bindata))
if (ipseckey_gateway_equip_const_bindata(rdf, &size, &data))
return GETDNS_RETURN_GENERIC_ERROR;
else if (! bindata.size)
else if (!size)
return GETDNS_RETURN_GOOD;
else
return _getdns_list_append_bindata(list, &bindata);
return _getdns_list_append_const_bindata(list, size, data);
}
static getdns_return_t
ipseckey_gateway_2wire(
const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
if (rdf - 2 < rdata)
return GETDNS_RETURN_GENERIC_ERROR;
switch (rdf[-2]) {
case 0: if (value && value->size > 0)
return GETDNS_RETURN_INVALID_PARAMETER;
break;
case 1: if (!value || value->size != 4)
return GETDNS_RETURN_INVALID_PARAMETER;
if (*rdf_len < 4) {
*rdf_len = 4;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = 4;
(void)memcpy(rdf, value->data, 4);
return GETDNS_RETURN_GOOD;
case 2: if (!value || value->size != 16)
return GETDNS_RETURN_INVALID_PARAMETER;
if (*rdf_len < 16) {
*rdf_len = 16;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = 16;
(void)memcpy(rdf, value->data, 16);
return GETDNS_RETURN_GOOD;
case 3: if (!value || value->size == 0)
return GETDNS_RETURN_INVALID_PARAMETER;
/* Assume bindata is a valid dname; garbage in, garbage out */
if (*rdf_len < value->size) {
*rdf_len = value->size;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = value->size;
(void)memcpy(rdf, value->data, value->size);
return GETDNS_RETURN_GOOD;
default:
return GETDNS_RETURN_GENERIC_ERROR;
}
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
ipseckey_gateway_dict2wire(
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_dict_get_bindata(dict, "gateway", &value)))
return r;
else
return ipseckey_gateway_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
ipseckey_gateway_list2wire(const getdns_list *list,
size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_list_get_bindata(list, i, &value)))
return r;
else
return ipseckey_gateway_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special ipseckey_gateway = {
ipseckey_gateway_rdf_end,
ipseckey_gateway_dict_set_value, ipseckey_gateway_list_append_value
ipseckey_gateway_wire2dict, ipseckey_gateway_wire2list,
ipseckey_gateway_dict2wire, ipseckey_gateway_list2wire
};
static uint8_t *
hip_pk_algorithm_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
hip_pk_algorithm_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
return rdf + 4 > pkt_end ? NULL
: rdf + 4 + *rdf + gldns_read_uint16(rdf + 2) > pkt_end ? NULL
: rdf + 1;
}
static getdns_return_t
hip_pk_algorithm_dict_set_value(getdns_dict *dict, uint8_t *rdf)
hip_pk_algorithm_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
return getdns_dict_set_int(dict, "pk_algorithm", rdf[1]);
}
static getdns_return_t
hip_pk_algorithm_list_append_value(getdns_list *list, uint8_t *rdf)
hip_pk_algorithm_wire2list(getdns_list *list, const uint8_t *rdf)
{
return _getdns_list_append_int(list, rdf[1]);
}
static getdns_return_t
hip_pk_algorithm_2wire(uint32_t value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
if (rdata != rdf)
return GETDNS_RETURN_GENERIC_ERROR;
if (value > 0xFF)
return GETDNS_RETURN_INVALID_PARAMETER;
if (*rdf_len < 4) {
*rdf_len = 4;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = 4;
rdata[1] = value;
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
hip_pk_algorithm_dict2wire(
const getdns_dict *dict,uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
uint32_t value;
if ((r = getdns_dict_get_int(dict, "pk_algorithm", &value)))
return r;
else
return hip_pk_algorithm_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
hip_pk_algorithm_list2wire(const getdns_list *list,
size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
uint32_t value;
if ((r = getdns_list_get_int(list, i, &value)))
return r;
else
return hip_pk_algorithm_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special hip_pk_algorithm = {
hip_pk_algorithm_rdf_end,
hip_pk_algorithm_dict_set_value, hip_pk_algorithm_list_append_value
hip_pk_algorithm_wire2dict, hip_pk_algorithm_wire2list,
hip_pk_algorithm_dict2wire, hip_pk_algorithm_list2wire
};
static uint8_t *
hip_hit_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
hip_hit_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
return rdf + 3 > pkt_end ? NULL
: rdf + 3 + rdf[-1] + gldns_read_uint16(rdf + 1) > pkt_end ? NULL
: rdf + 1;
}
static getdns_return_t
hip_hit_dict_set_value(getdns_dict *dict, uint8_t *rdf)
hip_hit_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
getdns_bindata bindata = { rdf[-1], rdf + 3 };
return getdns_dict_set_bindata(dict, "hit", &bindata);
return _getdns_dict_set_const_bindata(dict, "hit", rdf[-1], rdf + 3);
}
static getdns_return_t
hip_hit_list_append_value(getdns_list *list, uint8_t *rdf)
hip_hit_wire2list(getdns_list *list, const uint8_t *rdf)
{
getdns_bindata bindata = { rdf[-1], rdf + 3 };
return _getdns_list_append_bindata(list, &bindata);
return _getdns_list_append_const_bindata(list, rdf[-1], rdf + 3);
}
static getdns_return_t
hip_hit_2wire(
const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
if (rdata != rdf - 4)
return GETDNS_RETURN_GENERIC_ERROR;
if (value && value->size > 0xFF)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!value || value->size == 0) {
rdata[0] = 0;
*rdf_len = 0;
return GETDNS_RETURN_GOOD;
}
if (value->size > *rdf_len) {
*rdf_len = value->size;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = value->size;
rdata[0] = value->size;
(void)memcpy(rdf, value->data, value->size);
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
hip_hit_dict2wire(
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_dict_get_bindata(dict, "hit", &value)))
return r;
else
return hip_hit_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
hip_hit_list2wire(const getdns_list *list,
size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_list_get_bindata(list, i, &value)))
return r;
else
return hip_hit_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special hip_hit = {
hip_hit_rdf_end, hip_hit_dict_set_value, hip_hit_list_append_value
hip_hit_rdf_end,
hip_hit_wire2dict, hip_hit_wire2list,
hip_hit_dict2wire, hip_hit_list2wire
};
static uint8_t *
hip_public_key_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
hip_public_key_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
return rdf + 2 > pkt_end ? NULL
: rdf + 2 + rdf[-2] + gldns_read_uint16(rdf) > pkt_end ? NULL
: rdf + 2 + rdf[-2] + gldns_read_uint16(rdf);
}
static getdns_return_t
hip_public_key_dict_set_value(getdns_dict *dict, uint8_t *rdf)
hip_public_key_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
getdns_bindata bindata = { gldns_read_uint16(rdf), rdf + 2 + rdf[-2] };
return getdns_dict_set_bindata(dict, "public_key", &bindata);
return _getdns_dict_set_const_bindata(
dict, "public_key", gldns_read_uint16(rdf), rdf + 2 + rdf[-2]);
}
static getdns_return_t
hip_public_key_list_append_value(getdns_list *list, uint8_t *rdf)
hip_public_key_wire2list(getdns_list *list, const uint8_t *rdf)
{
getdns_bindata bindata = { gldns_read_uint16(rdf), rdf + 2 + rdf[-2] };
return _getdns_list_append_bindata(list, &bindata);
return _getdns_list_append_const_bindata(
list, gldns_read_uint16(rdf), rdf + 2 + rdf[-2]);
}
static getdns_return_t
hip_public_key_2wire(
const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
if (rdata > rdf - 4 || rdata + 4 + rdata[0] != rdf)
return GETDNS_RETURN_GENERIC_ERROR;
if (value && value->size > 0xFFFF)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!value || value->size == 0) {
rdata[2] = rdata[3] = 0;
*rdf_len = 0;
return GETDNS_RETURN_GOOD;
}
if (value->size > *rdf_len) {
*rdf_len = value->size;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = value->size;
gldns_write_uint16(rdata + 2, value->size);
(void)memcpy(rdf, value->data, value->size);
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
hip_public_key_dict2wire(
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_dict_get_bindata(dict, "public_key", &value)))
return r;
else
return hip_public_key_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
hip_public_key_list2wire(
const getdns_list *list, size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_list_get_bindata(list, i, &value)))
return r;
else
return hip_public_key_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special hip_public_key = {
hip_public_key_rdf_end,
hip_public_key_dict_set_value, hip_public_key_list_append_value
hip_public_key_wire2dict, hip_public_key_wire2list,
hip_public_key_dict2wire, hip_public_key_list2wire
};
@ -741,22 +1035,131 @@ _getdns_rr_type_name(int rr_type)
return _getdns_rr_def_lookup(rr_type)->name;
}
static void
write_int_rdata(gldns_buffer *buf, _getdns_rdf_type type, uint32_t value)
{
size_t j;
for (j = type & GETDNS_RDF_FIXEDSZ; j; j--)
gldns_buffer_write_u8(buf,
(uint8_t)(value >> (8 * (j - 1))) & 0xff);
}
static void
write_bindata_rdata(gldns_buffer *buf,
_getdns_rdf_type type, getdns_bindata *bindata)
{
if (type & GETDNS_RDF_LEN_VAL)
write_int_rdata(buf, type >> 8, bindata->size);
gldns_buffer_write(buf, bindata->data, bindata->size);
}
static getdns_return_t
write_rdata_field(gldns_buffer *buf, uint8_t *rdata_start,
const _getdns_rdata_def *rd_def, getdns_dict *rdata)
{
getdns_return_t r;
getdns_list *list;
uint32_t value;
getdns_bindata *bindata;
size_t i, rdf_len;
if (rd_def->type & GETDNS_RDF_INTEGER) {
if (!(rd_def->type & GETDNS_RDF_REPEAT)) {
if ((r = getdns_dict_get_int(
rdata, rd_def->name, &value)))
return r;
else
write_int_rdata(buf, rd_def->type, value);
} else if ((r = getdns_dict_get_list(
rdata, rd_def->name, &list)))
return r == GETDNS_RETURN_NO_SUCH_DICT_NAME
? GETDNS_RETURN_GOOD : r;
else for ( i = 0
; GETDNS_RETURN_GOOD ==
(r = getdns_list_get_int(list, i, &value))
; i++)
write_int_rdata(buf, rd_def->type, value);
} else if (rd_def->type & GETDNS_RDF_BINDATA) {
if (!(rd_def->type & GETDNS_RDF_REPEAT)) {
if ((r = getdns_dict_get_bindata(
rdata, rd_def->name, &bindata)))
return r;
else
write_bindata_rdata(buf, rd_def->type, bindata);
} else if ((r = getdns_dict_get_list(
rdata, rd_def->name, &list)))
return r == GETDNS_RETURN_NO_SUCH_DICT_NAME
? GETDNS_RETURN_GOOD : r;
else for ( i = 0
; GETDNS_RETURN_GOOD ==
(r = getdns_list_get_bindata(list, i, &bindata))
; i++)
write_bindata_rdata(buf, rd_def->type, bindata);
} else if (!(rd_def->type & GETDNS_RDF_SPECIAL)) {
/* Unknown rdata type */
return GETDNS_RETURN_GENERIC_ERROR;
} else if (!(rd_def->type & GETDNS_RDF_REPEAT)) {
rdf_len = gldns_buffer_remaining(buf);
r = rd_def->special->dict2wire(rdata, rdata_start,
gldns_buffer_current(buf), &rdf_len);
if (r == GETDNS_RETURN_GOOD ||
r == GETDNS_RETURN_NEED_MORE_SPACE)
gldns_buffer_skip(buf, rdf_len);
if (r)
return r;
} else if ((r = getdns_dict_get_list(rdata, rd_def->name, &list))) {
return r == GETDNS_RETURN_NO_SUCH_DICT_NAME
? GETDNS_RETURN_GOOD : r;
} else for ( i = 0; r == GETDNS_RETURN_GOOD; i++ ) {
rdf_len = gldns_buffer_remaining(buf);
r = rd_def->special->list2wire(list, i, rdata_start,
gldns_buffer_current(buf), &rdf_len);
if (r == GETDNS_RETURN_GOOD ||
r == GETDNS_RETURN_NEED_MORE_SPACE)
gldns_buffer_skip(buf, rdf_len);
}
return r != GETDNS_RETURN_NO_SUCH_LIST_ITEM ? r : GETDNS_RETURN_GOOD;
}
getdns_return_t
_getdns_rr_dict2wire(getdns_dict *rr_dict, gldns_buffer *buf)
_getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
{
getdns_return_t r = GETDNS_RETURN_GOOD;
struct getdns_bindata *name;
struct getdns_bindata *rdata_raw;
struct getdns_bindata *bindata;
struct getdns_dict *rdata;
getdns_bindata *name;
getdns_bindata *rdata_raw;
getdns_dict *rdata;
uint32_t rr_type;
uint32_t rr_class = GETDNS_RRCLASS_IN;
uint32_t rr_ttl = 0;
uint32_t value;
const _getdns_rr_def *rr_def;
const _getdns_rdata_def *rd_def;
int n_rdata_fields;
size_t j, rdata_size_mark;
const _getdns_rdata_def *rd_def, *rep_rd_def;
int n_rdata_fields, rep_n_rdata_fields;
size_t rdata_size_mark;
uint8_t *rdata_start;
getdns_list *list;
size_t i;
assert(rr_dict);
assert(buf);
@ -801,33 +1204,47 @@ _getdns_rr_dict2wire(getdns_dict *rr_dict, gldns_buffer *buf)
} else if (n_rdata_fields || r == GETDNS_RETURN_NO_SUCH_DICT_NAME) {
r = GETDNS_RETURN_GOOD;
rdata_size_mark = gldns_buffer_position(buf);
gldns_buffer_skip(buf, 2);
rdata_start = gldns_buffer_current(buf);
for ( rd_def = rr_def->rdata
, n_rdata_fields = rr_def->n_rdata_fields
; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) {
if (rd_def->type & GETDNS_RDF_BINDATA) {
if ((r = getdns_dict_get_bindata(rdata,
rd_def->name, &bindata)))
if (rd_def->type == GETDNS_RDF_REPEAT)
break;
gldns_buffer_write(buf, bindata->data
, bindata->size );
continue;
}
if (!(rd_def->type & GETDNS_RDF_INTEGER)) {
r = GETDNS_RETURN_GENERIC_ERROR;
if ((r = write_rdata_field(buf,
rdata_start, rd_def, rdata)))
break;
}
if ((r = getdns_dict_get_int(
rdata, rd_def->name, &value)))
break;
if (n_rdata_fields == 0 || r) {
/* pass */;
for (j = rd_def->type & GETDNS_RDF_FIXEDSZ; j; j--)
gldns_buffer_write_u8(buf,
(uint8_t)(value >> (8 * (j - 1))) & 0xff);
} else if ((r = getdns_dict_get_list(
rdata, rd_def->name, &list))) {
/* pass */;
} else for ( i = 0
; r == GETDNS_RETURN_GOOD
; i++) {
if ((r = getdns_list_get_dict(list, i, &rdata))) {
if (r == GETDNS_RETURN_NO_SUCH_LIST_ITEM)
r = GETDNS_RETURN_GOOD;
break;
}
for ( rep_rd_def = rd_def + 1
, rep_n_rdata_fields = n_rdata_fields - 1
; rep_n_rdata_fields
; rep_n_rdata_fields--, rep_rd_def++ ) {
if ((r = write_rdata_field(buf,
rdata_start, rep_rd_def, rdata)))
break;
}
}
gldns_buffer_write_u16_at(buf, rdata_size_mark,
(uint16_t)(gldns_buffer_position(buf)-rdata_size_mark-2));

View File

@ -36,18 +36,28 @@
#include "getdns/getdns.h"
#include "gldns/gbuffer.h"
typedef uint8_t *(*_getdns_rdf_end_t)(
uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf);
/* rdf_end returns a pointer to the end of this rdf's data,
* i.e. where the next rdata field will start.
*/
typedef const uint8_t *(*_getdns_rdf_end_t)(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf);
/* Limit checks are already done with _getdns_rdf_end_t */
typedef getdns_return_t (*_getdns_rdf_dict_set_value_t)(
getdns_dict *dict, uint8_t *rdf);
typedef getdns_return_t (*_getdns_rdf_list_append_value_t)(
getdns_list *list, uint8_t *rdf);
typedef getdns_return_t (*_getdns_rdf_wire2dict_t)(
getdns_dict *dict, const uint8_t *rdf);
typedef getdns_return_t (*_getdns_rdf_wire2list_t)(
getdns_list *list, const uint8_t *rdf);
typedef getdns_return_t (*_getdns_rdf_dict2wire_t)(
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len);
typedef getdns_return_t (*_getdns_rdf_list2wire_t)(
const getdns_list *list, size_t index,
uint8_t *rdata, uint8_t *rdf, size_t *rdf_len);
typedef struct _getdns_rdf_special {
_getdns_rdf_end_t rdf_end;
_getdns_rdf_dict_set_value_t dict_set_value;
_getdns_rdf_list_append_value_t list_append_value;
_getdns_rdf_wire2dict_t wire2dict;
_getdns_rdf_wire2list_t wire2list;
_getdns_rdf_dict2wire_t dict2wire;
_getdns_rdf_list2wire_t list2wire;
} _getdns_rdf_special;
/* draft-levine-dnsextlang'ish type rr and rdata definitions */
@ -134,7 +144,7 @@ typedef struct _getdns_rr_def {
const _getdns_rr_def *_getdns_rr_def_lookup(uint16_t rr_type);
getdns_return_t _getdns_rr_dict2wire(
getdns_dict *rr_dict, gldns_buffer *buf);
const getdns_dict *rr_dict, gldns_buffer *buf);
const char *_getdns_rr_type_name(int rr_type);

View File

@ -39,7 +39,7 @@ rr_iter_find_nxt(_getdns_rr_iter *i)
assert(i);
assert(i->rr_type);
i->nxt = i->n < GLDNS_QDCOUNT(i->pkt)
i->nxt = i->pkt && i->n < GLDNS_QDCOUNT(i->pkt)
? i->rr_type + 4
: i->rr_type + 10 > i->pkt_end
? i->pkt_end
@ -51,13 +51,14 @@ rr_iter_find_nxt(_getdns_rr_iter *i)
static _getdns_rr_iter *
find_rrtype(_getdns_rr_iter *i)
{
uint8_t *pos;
const uint8_t *pos;
assert(i);
assert(i->pos);
/* Past the last RR in the pkt */
if (GLDNS_QDCOUNT(i->pkt) + GLDNS_ANCOUNT(i->pkt) +
if (i->pkt &&
GLDNS_QDCOUNT(i->pkt) + GLDNS_ANCOUNT(i->pkt) +
GLDNS_NSCOUNT(i->pkt) + GLDNS_ARCOUNT(i->pkt) <= i->n)
goto done;
@ -83,7 +84,7 @@ done:
}
_getdns_rr_iter *
_getdns_rr_iter_init(_getdns_rr_iter *i, uint8_t *pkt, size_t pkt_len)
_getdns_rr_iter_init(_getdns_rr_iter *i, const uint8_t *pkt, size_t pkt_len)
{
assert(i);
@ -99,6 +100,25 @@ _getdns_rr_iter_init(_getdns_rr_iter *i, uint8_t *pkt, size_t pkt_len)
return find_rrtype(i);
}
_getdns_rr_iter *
_getdns_single_rr_iter_init(
_getdns_rr_iter *i, const uint8_t *wire, size_t wire_len)
{
assert(i);
if (!wire || wire_len < 5 /* name + type + class */) {
i->pos = NULL;
return NULL;
}
i->pkt = NULL;
i->pos = wire;
i->pkt_end = wire + wire_len;
i->n = 0;
return find_rrtype(i);
}
_getdns_rr_iter *
_getdns_rr_iter_rewind(_getdns_rr_iter *i)
{
@ -121,14 +141,14 @@ _getdns_rr_iter_next(_getdns_rr_iter *i)
return find_rrtype(i);
}
static uint8_t *
dname_if_or_as_decompressed(uint8_t *pkt, uint8_t *pkt_end, uint8_t *pos,
uint8_t *buf, size_t *len, size_t refs)
static const uint8_t *
dname_if_or_as_decompressed(const uint8_t *pkt, const uint8_t *pkt_end,
const uint8_t *pos, uint8_t *buf, size_t *len, size_t refs)
{
uint16_t offset;
uint8_t *start, *dst;
const uint8_t *start;
uint8_t *dst;
assert(pkt);
assert(pkt_end);
assert(pos);
assert(buf);
@ -138,7 +158,7 @@ dname_if_or_as_decompressed(uint8_t *pkt, uint8_t *pkt_end, uint8_t *pos,
goto error;
if ((*pos & 0xC0) == 0xC0) {
if (pos + 1 >= pkt_end)
if (!pkt || pos + 1 >= pkt_end)
goto error;
offset = gldns_read_uint16(pos) & 0x3FFF;
if (pkt + offset >= pkt_end)
@ -175,7 +195,7 @@ dname_if_or_as_decompressed(uint8_t *pkt, uint8_t *pkt_end, uint8_t *pos,
start = pos;
}
if ((*pos & 0xC0) == 0xC0) {
if (pos + 1 >= pkt_end)
if (!pkt || pos + 1 >= pkt_end)
goto error;
offset = gldns_read_uint16(pos) & 0x3FFF;
if (pkt + offset >= pkt_end)
@ -204,7 +224,7 @@ error:
return NULL;
}
uint8_t *
const uint8_t *
_getdns_owner_if_or_as_decompressed(_getdns_rr_iter *i,
uint8_t *ff_bytes, size_t *len)
{
@ -215,7 +235,7 @@ _getdns_owner_if_or_as_decompressed(_getdns_rr_iter *i,
static _getdns_rdf_iter *
rdf_iter_find_nxt(_getdns_rdf_iter *i)
{
uint8_t *pos;
const uint8_t *pos;
assert(i);
assert(i->pos);
@ -279,7 +299,7 @@ _getdns_rdf_iter_init(_getdns_rdf_iter *i, _getdns_rr_iter *rr)
i->end = NULL;
/* rr_iter already done or in question section */
if (!rr->pos || rr->n < GLDNS_QDCOUNT(rr->pkt))
if (!rr->pos || _getdns_rr_iter_section(rr) == GLDNS_SECTION_QUESTION)
goto done;
i->pkt = rr->pkt;
@ -334,7 +354,7 @@ _getdns_rdf_iter_init_at(
return i;
}
uint8_t *
const uint8_t *
_getdns_rdf_if_or_as_decompressed(
_getdns_rdf_iter *i, uint8_t *ff_bytes, size_t *len)
{

View File

@ -38,8 +38,8 @@
#include "gldns/gbuffer.h"
typedef struct _getdns_rr_iter {
uint8_t *pkt;
uint8_t *pkt_end;
const uint8_t *pkt;
const uint8_t *pkt_end;
/* Which RR are we currently at */
size_t n;
@ -47,32 +47,37 @@ typedef struct _getdns_rr_iter {
/* pos points to start of the owner name the RR.
* Or is NULL when there are no RR's left.
*/
uint8_t *pos;
const uint8_t *pos;
/* rr_type will point to the rr_type right after the RR's owner name.
* rr_type is guaranteed to have a value when pos has a value
*/
uint8_t *rr_type;
const uint8_t *rr_type;
/* nxt point to the owner name of the next RR or to pkt_end */
uint8_t *nxt;
const uint8_t *nxt;
} _getdns_rr_iter;
_getdns_rr_iter *_getdns_rr_iter_init(_getdns_rr_iter *i,
uint8_t *pkt, size_t pkt_len);
const uint8_t *pkt, const size_t pkt_len);
_getdns_rr_iter *_getdns_single_rr_iter_init(_getdns_rr_iter *i,
const uint8_t *wire, const size_t wire_len);
_getdns_rr_iter *_getdns_rr_iter_rewind(_getdns_rr_iter *i);
_getdns_rr_iter *_getdns_rr_iter_next(_getdns_rr_iter *i);
uint8_t *_getdns_owner_if_or_as_decompressed(
const uint8_t *_getdns_owner_if_or_as_decompressed(
_getdns_rr_iter *i, uint8_t *ff_bytes, size_t *len);
static inline gldns_pkt_section
_getdns_rr_iter_section(_getdns_rr_iter *i)
{
return i->n < GLDNS_QDCOUNT(i->pkt) ? GLDNS_SECTION_QUESTION
return !i->pkt ? (i->nxt - i->rr_type == 4 ? GLDNS_SECTION_QUESTION
: GLDNS_SECTION_ANSWER )
: i->n < GLDNS_QDCOUNT(i->pkt) ? GLDNS_SECTION_QUESTION
: i->n < GLDNS_QDCOUNT(i->pkt)
+ GLDNS_ANCOUNT(i->pkt) ? GLDNS_SECTION_ANSWER
: i->n < GLDNS_QDCOUNT(i->pkt)
@ -86,14 +91,14 @@ _getdns_rr_iter_section(_getdns_rr_iter *i)
}
typedef struct piv_getdns_rdf_iter {
uint8_t *pkt;
uint8_t *pkt_end;
const uint8_t *pkt;
const uint8_t *pkt_end;
const _getdns_rdata_def *rdd_pos;
const _getdns_rdata_def *rdd_end;
const _getdns_rdata_def *rdd_repeat;
uint8_t *pos;
uint8_t *end;
uint8_t *nxt;
const uint8_t *pos;
const uint8_t *end;
const uint8_t *nxt;
} _getdns_rdf_iter;
_getdns_rdf_iter *_getdns_rdf_iter_init(_getdns_rdf_iter *i,
@ -104,7 +109,7 @@ _getdns_rdf_iter *_getdns_rdf_iter_next(_getdns_rdf_iter *i);
_getdns_rdf_iter *_getdns_rdf_iter_init_at(_getdns_rdf_iter *i,
_getdns_rr_iter *rr, size_t pos);
uint8_t *_getdns_rdf_if_or_as_decompressed(
const uint8_t *_getdns_rdf_if_or_as_decompressed(
_getdns_rdf_iter *i, uint8_t *ff_bytes, size_t *len);
#endif

View File

@ -197,10 +197,10 @@ attach_edns_cookie(getdns_network_req *req)
/* Will find a matching OPT RR, but leaves the caller to validate it*/
static int
match_edns_opt_rr(uint16_t code, uint8_t *response, size_t response_len,
uint8_t **position, uint16_t *option_len)
const uint8_t **position, uint16_t *option_len)
{
_getdns_rr_iter rr_iter_storage, *rr_iter;
uint8_t *pos;
const uint8_t *pos;
uint16_t rdata_len, opt_code = 0, opt_len = 0;
/* Search for the OPT RR (if any) */
@ -226,10 +226,10 @@ match_edns_opt_rr(uint16_t code, uint8_t *response, size_t response_len,
#if defined(STUB_DEBUG) && STUB_DEBUG
char str_spc[8192], *str = str_spc;
size_t str_len = sizeof(str_spc);
uint8_t *data = rr_iter->pos;
uint8_t *data = (uint8_t *)rr_iter->pos;
size_t data_len = rr_iter->nxt - rr_iter->pos;
(void) gldns_wire2str_rr_scan(
&data, &data_len, &str, &str_len, rr_iter->pkt, rr_iter->pkt_end - rr_iter->pkt);
&data, &data_len, &str, &str_len, (uint8_t *)rr_iter->pkt, rr_iter->pkt_end - rr_iter->pkt);
DEBUG_STUB("OPT RR: %s", str_spc);
#endif
@ -262,7 +262,7 @@ static int
match_and_process_server_cookie(
getdns_upstream *upstream, uint8_t *response, size_t response_len)
{
uint8_t *position = NULL;
const uint8_t *position = NULL;
uint16_t option_len = 0;
int found = match_edns_opt_rr(EDNS_COOKIE_OPCODE, response,
response_len, &position, &option_len);
@ -299,7 +299,7 @@ process_keepalive(
getdns_upstream *upstream, getdns_network_req *netreq,
uint8_t *response, size_t response_len)
{
uint8_t *position = NULL;
const uint8_t *position = NULL;
uint16_t option_len = 0;
int found = match_edns_opt_rr(GLDNS_EDNS_KEEPALIVE, response,
response_len, &position, &option_len);

View File

@ -0,0 +1,15 @@
builddir = @BUILDDIR@
testname = @TPKG_NAME@
LIBTOOL = $(builddir)/libtool
CFLAGS=-I$(builddir)/src
LDLIBS=$(builddir)/src/libgetdns.la
.SUFFIXES: .c .o .a .lo .h
.c.lo:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
$(testname): $(testname).lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(LDLIBS) $(LDFLAGS) -o $@ $<

View File

@ -0,0 +1,325 @@
#include <stdio.h>
#include <ctype.h>
#include <getdns/getdns.h>
#include <getdns/getdns_extra.h>
#define FAIL(...) do { \
fprintf(stderr, "ERROR in %s:%d, ", __FILE__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
exit(EXIT_FAILURE); \
} while (0)
#define FAIL_r(function_name) FAIL( "%s returned %d: %s", function_name \
, (int)r, getdns_get_errorstr_by_id(r));
void print_dict(getdns_dict *rr_dict)
{
char *str = getdns_pretty_print_dict(rr_dict);
printf("%s\n", str);
free(str);
}
void print_list(getdns_list *rr_list)
{
char *str = getdns_pretty_print_list(rr_list);
printf("%s\n", str);
free(str);
}
void print_wire(uint8_t *wire, size_t wire_len)
{
size_t pos, i;
for (pos = 0; pos < wire_len; pos += 16) {
printf("%.4zx", pos);
for (i = 0; i < 16; i++) {
if (i % 8 == 0)
printf(" ");
if (pos + i < wire_len)
printf(" %.2x", (int)wire[pos + i]);
else
printf(" ");
}
printf(" ");
for (i = 0; i < 16; i++) {
if (i % 8 == 0)
printf(" ");
if (pos + i < wire_len && isprint(wire[pos + i]))
printf("%c", wire[pos + i]);
else
printf(".");
}
printf("\n");
}
}
int main(int argc, char const * const argv[])
{
getdns_return_t r;
getdns_dict *rr_dict;
getdns_bindata *dns_name;
getdns_bindata address = { 4, "\xb9\x31\x8d\x25" };
getdns_bindata fourth = { 11, "last string" };
size_t length;
char *str;
uint8_t *wire, *prev_wire;
size_t wire_len;
getdns_list *rr_list;
FILE *in;
uint8_t wire_buf[8200];
size_t i;
ssize_t available;
char str_buf[10000];
ssize_t str_len = sizeof(str_buf);
/* Convert string to rr_dict
*/
if ((r = getdns_str2rr_dict(
"some.domain.tld. 60 IN TXT \"first string\" second \"and third\"",
&rr_dict, NULL, 3600)))
FAIL_r("getdns_str2rr_dict");
/* Add a fourth text element.
*/
if ((r = getdns_dict_set_bindata(rr_dict, "/rdata/txt_strings/-", &fourth)))
FAIL_r("getdns_list_set_bindata");
print_dict(rr_dict);
/* Convert to wireformat from rdata_raw.
* Added fourth list element should NOT show.
*/
wire = NULL;
if ((r = getdns_rr_dict2wire(rr_dict, &wire, &wire_len)))
FAIL_r("getdns_rr_dict2wire");
print_wire(wire, wire_len);
free(wire);
/* Convert to wireformat from parsing rdata fields.
* Added fourth list element should show.
*/
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rdata_raw")))
FAIL_r("getdns_dict_remove_name");
printf("\nremoved \"/rdata/rdata_raw\":\n\n");
if ((r = getdns_rr_dict2wire(rr_dict, &wire, &wire_len)))
FAIL_r("getdns_rr_dict2wire");
print_wire(wire, wire_len);
free(wire);
/* Remove second and third string elements and show text format.
*/
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/1")))
FAIL_r("getdns_dict_remove_name");
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/1")))
FAIL_r("getdns_dict_remove_name");
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("\n%s", str);
free(str);
/* Remove all string elements and show text format.
*/
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/0")))
FAIL_r("getdns_dict_remove_name");
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/0")))
FAIL_r("getdns_dict_remove_name");
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("%s", str);
free(str);
getdns_dict_destroy(rr_dict);
/* Construct rr_dict and convert to string
*/
if (!(rr_dict = getdns_dict_create()))
FAIL("getdns_dict_create returned NULL");
if ((r = getdns_convert_fqdn_to_dns_name("www.getdnsapi.net", &dns_name)))
FAIL_r("getdns_convert_fqdn_to_dns_name");
r = getdns_dict_set_bindata(rr_dict, "name", dns_name);
free(dns_name->data);
free(dns_name);
if (r)
FAIL_r("getdns_dict_set_bindata");
if ((r = getdns_dict_set_int(rr_dict, "type", GETDNS_RRTYPE_A)))
FAIL_r("getdns_dict_set_int");
if ((r = getdns_dict_set_bindata(rr_dict, "/rdata/ipv4_address", &address)))
FAIL_r("getdns_dict_set_int");
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("\n%s\n", str);
free(str);
if ((r = getdns_rr_dict2wire(rr_dict, &wire, &wire_len)))
FAIL_r("getdns_rr_dict2wire");
getdns_dict_destroy(rr_dict);
print_wire(wire, wire_len);
free(wire);
/* Convert RR with special rdata fields and repeating last element
* from string to rr_dict
*/
if ((r = getdns_str2rr_dict(
"hip2 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs1.example.com. rvs2.example.com.",
&rr_dict, "nlnetlabs.nl", 3600)))
FAIL_r("getdns_str2rr_dict");
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rdata_raw")))
FAIL_r("getdns_dict_remove_name");
printf("\n");
print_dict(rr_dict);
/* Convert RR with special rdata fields and repeating last element
* back to string.
*/
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("%s", str);
free(str);
/* Convert RR with special rdata fields without repeating last element
* to string.
*/
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rendezvous_servers")))
FAIL_r("getdns_dict_remove_name");
if ((r = getdns_dict_get_bindata(rr_dict, "name", &dns_name)))
FAIL_r("getdns_dict_get_bindata");
dns_name->data[4] = '0';
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("%s\n", str);
free(str);
getdns_dict_destroy(rr_dict);
/* Convert RR with repeat block from string to rr_dict
*/
if ((r = getdns_str2rr_dict(
"apl APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42.128/25 1:224.0.0.0/4 2:FF00:0:0:0:0:0:0:0/8",
&rr_dict, "net-dns.org", 3600)))
FAIL_r("getdns_str2rr_dict");
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rdata_raw")))
FAIL_r("getdns_dict_remove_name");
print_dict(rr_dict);
/* Convert repeat block from rr_dict back to string.
*/
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("%s", str);
free(str);
getdns_dict_destroy(rr_dict);
if (!(in = fopen(argv[1], "r")))
FAIL("Could not fopen %s\n", argv[1]);
if ((r = getdns_fp2rr_list(in, &rr_list, NULL, 0)))
FAIL_r("getdns_fp2rr_list");
fclose(in);
print_list(rr_list);
/* Fill the wire_buf with wireformat RR's in rr_list
* wire_buf is too small for last two rr's.
*/
wire = wire_buf;
available = sizeof(wire_buf);
for (i = 0; !(r = getdns_list_get_dict(rr_list, i, &rr_dict)); i++) {
prev_wire = wire;
if ((r = getdns_rr_dict2wire_scan(rr_dict,&wire,&available))) {
if (r == GETDNS_RETURN_NEED_MORE_SPACE) {
printf("record %.3zu, available buffer space: "
"%zi\n", i, available);
/* The buffer was too small to fit the wire-
* format representation. available now holds
* a negative number. the wire pointer is this
* much beyond the end of the buffer space.
*
* If we would add available to wire, wire
* would be positioned at the end of the buffer
* but would not be positioned at a clean RR
* border. Therefore we have to remember the
* previous position of wire, so we can reset
* it at the end of the wireformat representa-
* tion of the previously converted rr_dict.
*/
wire = prev_wire;
break;
}
else
FAIL_r("getdns_rr_dict2wire_scan");
}
printf("record %3zu, available buffer space: "
"%zi\n", i, available);
fflush(stdout);
}
if (r == GETDNS_RETURN_NO_SUCH_LIST_ITEM)
r = GETDNS_RETURN_GOOD;
getdns_list_destroy(rr_list);
/* Now scan over the wireformat buffer and convert to rr_dicts again.
* Then fill a string buffer with those rr_dicts.
*/
available = wire - wire_buf;
wire = wire_buf;
str = str_buf;
str_len = sizeof(str_buf);
while (available > 0 && str_len > 0) {
rr_dict = NULL;
if ((r = getdns_wire2rr_dict_scan(
(const uint8_t **)&wire, &available, &rr_dict)))
FAIL_r("getdns_wire2rr_dict_scan");
if ((r = getdns_rr_dict2str_scan(rr_dict, &str, &str_len)))
FAIL_r("getdns_rr_dict2str_scan");
getdns_dict_destroy(rr_dict);
}
*str = 0;
/* Print the entire buffer */
printf("%s", str_buf);
exit(EXIT_SUCCESS);
}

View File

@ -0,0 +1,16 @@
BaseName: 260-conversion-functions
Version: 1.0
Description: Test json pointers
CreationDate: vr dec 11 13:09:47 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 200-stub-only-compile.tpkg
Help: 260-conversion-functions.help
Pre: 260-conversion-functions.pre
Post:
Test: 260-conversion-functions.test
AuxFiles:
Passed:
Failure:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
Compile a program that setups a dict with json pointers and pretty prints the dict.
Then compare the output to the known to be good output.

View File

@ -0,0 +1,133 @@
$ORIGIN .
$TTL 30 ; 30 seconds
net-dns.org IN SOA ns.nlnetlabs.nl. sysadmin.nlnetlabs.nl. (
2015081800 ; serial
450 ; refresh (7 minutes 30 seconds)
600 ; retry (10 minutes)
345600 ; expire (4 days)
300 ; minimum (5 minutes)
)
NS ns.nlnetlabs.nl
NS ns.hactrn.net.
NS mcvax.nlnet.nl.
NS sec2.authdns.ripe.net.
A 185.49.140.22
AAAA 2a04:b900::2:0:0:22
MX 10 dicht.nlnetlabs.nl.
MX 20 mcvax.nlnet.nl.
TXT "Net::DNS domain"
$ORIGIN net-dns.org.
_443._tcp TLSA 3 1 1 274c6f96c9885c8050e8a05ad1c3162c1d51752c35b6196474e3f05ad31cd923
_443._tcp.www TLSA 3 1 1 274c6f96c9885c8050e8a05ad1c3162c1d51752c35b6196474e3f05ad31cd923
dynup TXT "fooFoo2" "Bla \; Foo"
lists A 63.209.15.196
localhost A 127.0.0.1
overflow TXT "And line 1 of al sorts of crap that will just fill the packet "
TXT "And line 2 of al sorts of crap that will just fill the packet "
TXT "And line 3 of al sorts of crap that will just fill the packet "
TXT "And line 4 of al sorts of crap that will just fill the packet "
TXT "And line 5 of al sorts of crap that will just fill the packet "
TXT "And line 6 of al sorts of crap that will just fill the packet "
TXT "And line 7 of al sorts of crap that will just fill the packet "
TXT "And line 8 of al sorts of crap that will just fill the packet "
TXT "And line 9 of al sorts of crap that will just fill the packet "
TXT "And line 10 of al sorts of crap that will just fill the packet "
TXT "And line 11 of al sorts of crap that will just fill the packet "
TXT "And line 12 of al sorts of crap that will just fill the packet "
TXT "And line 13 of al sorts of crap that will just fill the packet "
TXT "And line 14 of al sorts of crap that will just fill the packet "
TXT "And line 15 of al sorts of crap that will just fill the packet "
TXT "And line 16 of al sorts of crap that will just fill the packet "
TXT "And line 17 of al sorts of crap that will just fill the packet "
TXT "And line 18 of al sorts of crap that will just fill the packet "
TXT "And line 19 of al sorts of crap that will just fill the packet "
TXT "And line 20 of al sorts of crap that will just fill the packet "
TXT "And line 21 of al sorts of crap that will just fill the packet "
TXT "And line 22 of al sorts of crap that will just fill the packet "
TXT "And line 23 of al sorts of crap that will just fill the packet "
TXT "And line 25 of al sorts of crap that will just fill the packet "
TXT "And line 26 of al sorts of crap that will just fill the packet "
TXT "And line 27 of al sorts of crap that will just fill the packet "
TXT "And line 28 of al sorts of crap that will just fill the packet "
TXT "And line 29 of al sorts of crap that will just fill the packet "
TXT "And line 30 of al sorts of crap that will just fill the packet "
TXT "And line 31 of al sorts of crap that will just fill the packet "
TXT "And line 32 of al sorts of crap that will just fill the packet "
TXT "And line 33 of al sorts of crap that will just fill the packet "
TXT "And line 34 of al sorts of crap that will just fill the packet "
TXT "And line 35 of al sorts of crap that will just fill the packet "
TXT "And line 36 of al sorts of crap that will just fill the packet "
TXT "And line 37 of al sorts of crap that will just fill the packet "
TXT "And line 38 of al sorts of crap that will just fill the packet "
TXT "And line 39 of al sorts of crap that will just fill the packet "
TXT "And line 40 of al sorts of crap that will just fill the packet "
TXT "And line 41 of al sorts of crap that will just fill the packet "
TXT "And line 42 of al sorts of crap that will just fill the packet "
TXT "And line 43 of al sorts of crap that will just fill the packet "
TXT "And line 44 of al sorts of crap that will just fill the packet "
TXT "And line 45 of al sorts of crap that will just fill the packet "
TXT "And line 46 of al sorts of crap that will just fill the packet "
TXT "And line 47 of al sorts of crap that will just fill the packet "
TXT "And line 48 of al sorts of crap that will just fill the packet "
TXT "And line 49 of al sorts of crap that will just fill the packet "
TXT "And line 50 of al sorts of crap that will just fill the packet "
TXT "And line 51 of al sorts of crap that will just fill the packet "
TXT "And line 52 of al sorts of crap that will just fill the packet "
TXT "And line 53 of al sorts of crap that will just fill the packet "
TXT "And line 54 of al sorts of crap that will just fill the packet "
TXT "And line 55 of al sorts of crap that will just fill the packet "
TXT "And line 56 of al sorts of crap that will just fill the packet "
TXT "And line 57 of al sorts of crap that will just fill the packet "
TXT "And line 58 of al sorts of crap that will just fill the packet "
TXT "And line 59 of al sorts of crap that will just fill the packet "
TXT "And line 60 of al sorts of crap that will just fill the packet "
TXT "And line 224 of al sorts of crap that will just fill the packet "
TXT "An increadibly large answer section that will lead to packet overflow"
t TXT "The names within this domain are used for testing"
$ORIGIN t.net-dns.org.
a A 10.0.1.128
a2 A 10.0.1.129
cname CNAME a
mx MX 10 a
mx2 MX 10 a
MX 15 a2
txt TXT "Net-DNS"
txt2 TXT "Net-DNS\; complicated $tuff" "sort of \" text\; and binary \000 data"
connection-test TXT "connection-test succes"
txt-utf8 TXT \# 33 09E58FA4E6B1A0E382840CE89B99E9A39BE8BEBCE3828009E6B0B4E381AEE99FB3
txt-utf8-bin TXT "古池や" "蛙飛込む" "水の音"
a.few.empty.non.terminals TXT a few empty non terminals
A 185.49.140.22
AAAA 2a04:b900::2:0:0:22
yx1.cname CNAME -
yx2.cname CNAME a-a
yx3.cname CNAME a\.
yx4.cname CNAME a\000
nx1.cname CNAME does.not.exist
nx2.cname CNAME empty.non.terminals
$ORIGIN net-dns.org.
www A 185.49.140.22
www AAAA 2a04:b900::2:0:0:22
apl APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42.128/25 1:224.0.0.0/4 2:FF00:0:0:0:0:0:0:0/8
ipseckey0 IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey1 IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey2 IPSECKEY 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey3 IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
IPSECKEY 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
default._domainkey IN TXT "v=DKIM1; r=postmaster; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVG/lfF5GtPlMOcSGnfbp5u+EWM+OOg/f6QmbDXOW/zKQkRIRIZ+BtfSYchP8MeFPfMvUZtdRPzCWg1G7OdD7qaTUqc6kV84on6/8kPVMgdDLyLl2DeU/Lts9hfVHVDSpWuChwDAFXnbnW8jpp54zuof9OIbWSWIxZqLL8flgOsQIDAQAB" ; ----- DKIM default for example.com
2.3.3.updates.spamassassin TXT "1418219 "
mirrors.updates.spamassassin TXT "http://anonymous@spamassassin.apache.org/updates/MIRRORED.BY"

View File

@ -0,0 +1,14 @@
# #-- 260-conversion-functions.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
(
grep '^CC=' "${BUILDDIR}/build-stub-only/src/Makefile"
grep '^LDFLAGS=' "${BUILDDIR}/build-stub-only/src/Makefile"
BUILDDIR4SED=`echo "${BUILDDIR}/build-stub-only" | sed 's/\//\\\\\//g'`
sed -e "s/@BUILDDIR@/${BUILDDIR4SED}/g" \
-e "s/@TPKG_NAME@/${TPKG_NAME}/g" "${TPKG_NAME}.Makefile"
) > Makefile

View File

@ -0,0 +1,15 @@
# #-- 260-conversion-functions.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
if ! make
then
exit 1
elif ! ( "./${TPKG_NAME}" "${TPKG_NAME}.net-dns.org" | tee out )
then
exit 1
else
diff out "${TPKG_NAME}.good"
fi

View File

@ -7,10 +7,10 @@
rm -fr "${BUILDDIR}/build-event-loops"
mkdir "${BUILDDIR}/build-event-loops"
cd "${BUILDDIR}/build-event-loops"
"${SRCROOT}/configure" --enable-all-drafts --with-libevent --with-libev --with-libuv \
|| "${SRCROOT}/configure" --enable-all-drafts --with-libevent --with-libev \
|| "${SRCROOT}/configure" --enable-all-drafts --with-libevent --with-libuv \
|| "${SRCROOT}/configure" --enable-all-drafts --with-libev --with-libuv \
|| "${SRCROOT}/configure" --enable-all-drafts --with-libevent \
|| "${SRCROOT}/configure" --enable-all-drafts --with-libev \
|| "${SRCROOT}/configure" --enable-all-drafts --with-libuv
"${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libevent --with-libev --with-libuv \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libevent --with-libev \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libevent --with-libuv \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libev --with-libuv \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libevent \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libev \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libuv

View File

@ -172,9 +172,10 @@ getdns_dict *
_getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i)
{
getdns_dict *rr_dict, *rdata_dict;
getdns_bindata bindata;
const uint8_t *bin_data;
size_t bin_size;
uint32_t int_val = 0;
getdns_data_type val_type;
enum wf_data_type { wf_int, wf_bindata, wf_special } val_type;
_getdns_rdf_iter rdf_storage, *rdf;
getdns_list *repeat_list = NULL;
getdns_dict *repeat_dict = NULL;
@ -185,8 +186,8 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i)
if (!(rr_dict = _getdns_dict_create_with_mf(mf)))
return NULL;
bindata.data = _getdns_owner_if_or_as_decompressed(
i, ff_bytes, &bindata.size);
bin_data = _getdns_owner_if_or_as_decompressed(
i, ff_bytes, &bin_size);
/* question */
if (_getdns_rr_iter_section(i) == GLDNS_SECTION_QUESTION) {
@ -197,7 +198,8 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i)
getdns_dict_set_int(rr_dict, "qclass",
(uint32_t) gldns_read_uint16(i->rr_type + 2)) ||
getdns_dict_set_bindata(rr_dict, "qname", &bindata)) {
_getdns_dict_set_const_bindata(
rr_dict, "qname", bin_size, bin_data)) {
goto error;
}
@ -234,7 +236,8 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i)
getdns_dict_set_int(rr_dict, "ttl",
(uint32_t) gldns_read_uint32(i->rr_type + 4)) ||
getdns_dict_set_bindata(rr_dict, "name", &bindata)) {
_getdns_dict_set_const_bindata(
rr_dict, "name", bin_size, bin_data)) {
goto error;
}
@ -242,15 +245,16 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i)
return NULL;
if (i->rr_type + 10 <= i->nxt) {
bindata.size = i->nxt - (i->rr_type + 10);
bindata.data = i->rr_type + 10;
if (getdns_dict_set_bindata(rdata_dict, "rdata_raw", &bindata))
bin_size = i->nxt - (i->rr_type + 10);
bin_data = i->rr_type + 10;
if (_getdns_dict_set_const_bindata(
rdata_dict, "rdata_raw", bin_size, bin_data))
goto rdata_error;
}
for ( rdf = _getdns_rdf_iter_init(&rdf_storage, i)
; rdf; rdf = _getdns_rdf_iter_next(rdf)) {
if (rdf->rdd_pos->type & GETDNS_RDF_INTEGER) {
val_type = t_int;
val_type = wf_int;
switch (rdf->rdd_pos->type & GETDNS_RDF_FIXEDSZ) {
case 1: int_val = *rdf->pos;
break;
@ -262,52 +266,51 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i)
goto rdata_error;
}
} else if (rdf->rdd_pos->type & GETDNS_RDF_DNAME) {
val_type = t_bindata;
val_type = wf_bindata;
bindata.data = _getdns_rdf_if_or_as_decompressed(
rdf, ff_bytes, &bindata.size);
bin_data = _getdns_rdf_if_or_as_decompressed(
rdf, ff_bytes, &bin_size);
} else if (rdf->rdd_pos->type & GETDNS_RDF_BINDATA) {
val_type = t_bindata;
val_type = wf_bindata;
if (rdf->rdd_pos->type & GETDNS_RDF_FIXEDSZ) {
bindata.size = rdf->rdd_pos->type
bin_size = rdf->rdd_pos->type
& GETDNS_RDF_FIXEDSZ;
bindata.data = rdf->pos;
bin_data = rdf->pos;
} else switch(rdf->rdd_pos->type & GETDNS_RDF_LEN_VAL){
case 0x100:
bindata.size = *rdf->pos;
bindata.data = rdf->pos + 1;
bin_size = *rdf->pos;
bin_data = rdf->pos + 1;
break;
case 0x200:
bindata.size = gldns_read_uint16(rdf->pos);
bindata.data = rdf->pos + 2;
bin_size = gldns_read_uint16(rdf->pos);
bin_data = rdf->pos + 2;
break;
default:
bindata.size = rdf->nxt - rdf->pos;
bindata.data = rdf->pos;
bin_size = rdf->nxt - rdf->pos;
bin_data = rdf->pos;
break;
}
} else if (rdf->rdd_pos->type == GETDNS_RDF_SPECIAL)
/* Abuse t_dict for special values */
val_type = t_dict;
val_type = wf_special;
else
assert(0);
if (! rdf->rdd_repeat) {
switch (val_type) {
case t_int:
case wf_int:
if (getdns_dict_set_int(rdata_dict,
rdf->rdd_pos->name, int_val))
goto rdata_error;
break;
case t_bindata:
if (getdns_dict_set_bindata(rdata_dict,
rdf->rdd_pos->name, &bindata))
case wf_bindata:
if (_getdns_dict_set_const_bindata(rdata_dict,
rdf->rdd_pos->name, bin_size, bin_data))
goto rdata_error;
break;
case t_dict:
if (rdf->rdd_pos->special->dict_set_value(
case wf_special:
if (rdf->rdd_pos->special->wire2dict(
rdata_dict, rdf->pos))
goto rdata_error;
default:
@ -324,18 +327,18 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i)
goto rdata_error;
switch (val_type) {
case t_int:
case wf_int:
if (_getdns_list_append_int(repeat_list,
int_val))
goto rdata_error;
break;
case t_bindata:
if (_getdns_list_append_bindata(repeat_list,
&bindata))
case wf_bindata:
if (_getdns_list_append_const_bindata(
repeat_list, bin_size, bin_data))
goto rdata_error;
break;
case t_dict:
if (rdf->rdd_pos->special->list_append_value(
case wf_special:
if (rdf->rdd_pos->special->wire2list(
repeat_list, rdf->pos))
goto rdata_error;
default:
@ -363,18 +366,18 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i)
}
assert(repeat_dict);
switch (val_type) {
case t_int:
case wf_int:
if (getdns_dict_set_int(repeat_dict,
rdf->rdd_pos->name, int_val))
goto rdata_error;
break;
case t_bindata:
if (getdns_dict_set_bindata(repeat_dict,
rdf->rdd_pos->name, &bindata))
case wf_bindata:
if (_getdns_dict_set_const_bindata(repeat_dict,
rdf->rdd_pos->name, bin_size, bin_data))
goto rdata_error;
break;
case t_dict:
if (rdf->rdd_pos->special->dict_set_value(
case wf_special:
if (rdf->rdd_pos->special->wire2dict(
repeat_dict, rdf->pos))
goto rdata_error;
default:
@ -497,11 +500,11 @@ _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
getdns_dict *rr_dict = NULL;
_getdns_rr_iter rr_iter_storage, *rr_iter;
_getdns_rdf_iter rdf_iter_storage, *rdf_iter;
getdns_bindata bindata;
size_t bin_size;
const uint8_t *bin_data;
gldns_pkt_section section;
uint8_t canonical_name_space[256],
*canonical_name = canonical_name_space;
uint8_t owner_name_space[256], *owner_name;
uint8_t canonical_name_space[256], owner_name_space[256];
const uint8_t *canonical_name = canonical_name_space, *owner_name;
size_t canonical_name_len = sizeof(canonical_name_space),
owner_name_len = sizeof(owner_name_space);
int new_canonical = 0;
@ -592,14 +595,15 @@ _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
&rdf_iter_storage, rr_iter)))
continue;
bindata.size = rdf_iter->nxt - rdf_iter->pos;
bindata.data = rdf_iter->pos;
bin_size = rdf_iter->nxt - rdf_iter->pos;
bin_data = rdf_iter->pos;
if (!set_dict(&rr_dict, getdns_dict_create_with_context(context)) ||
getdns_dict_util_set_string(rr_dict, "address_type",
rr_type == GETDNS_RRTYPE_A ? "IPv4" : "IPv6" ) ||
getdns_dict_set_bindata(rr_dict,"address_data",&bindata) ||
_getdns_dict_set_const_bindata(
rr_dict, "address_data", bin_size, bin_data) ||
(just_addrs && _getdns_list_append_dict(just_addrs, rr_dict))) {
@ -656,9 +660,8 @@ _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
new_canonical = 1;
}
}
bindata.data = canonical_name;
bindata.size = canonical_name_len;
if (getdns_dict_set_bindata(result, "canonical_name", &bindata))
if (_getdns_dict_set_const_bindata(
result, "canonical_name", canonical_name_len, canonical_name))
goto error;
goto success;

View File

@ -42,6 +42,7 @@
#include "context.h"
#include "rr-iter.h"
#define UNCONST_UINT8_p uint8_t *
#ifdef S_SPLINT_S
# define INLINE
@ -81,6 +82,12 @@ getdns_return_t _getdns_list_append_string(getdns_list *list,
getdns_return_t _getdns_list_append_int(getdns_list *list,
uint32_t child_uint32);
getdns_return_t _getdns_list_append_const_bindata(getdns_list *list,
size_t size, const uint8_t *data);
getdns_return_t _getdns_dict_set_const_bindata(getdns_dict *dict,
const char *name, size_t size, const uint8_t *data);
/**
* private function (API users should not be calling this), this uses library
* routines to make a copy of the list - would be faster to make the copy directly