Doc of (|_buf|_scan) style conversion funcs

+ (|_buf|_scan) versions of most of the conversion directions.
+ mk-const-info handles new return_t's defines
This commit is contained in:
Willem Toorop 2015-12-22 16:04:43 +01:00
parent 6519a05780
commit 0cb513e9b7
7 changed files with 315 additions and 44 deletions

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

@ -220,62 +220,192 @@ 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_sz)
if (!rr_dict || !wire || !*wire || !wire_sz)
return GETDNS_RETURN_INVALID_PARAMETER;
gldns_buffer_init_frm_data(&gbuf, wire, *wire_sz);
r = _getdns_rr_dict2wire(rr_dict, &gbuf);
*wire_sz = gldns_buffer_position(&gbuf);
if (r)
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 ||
gldns_buffer_position(&gbuf) > gldns_buffer_capacity(&gbuf))
if (gldns_buffer_position(&gbuf) == 0)
return GETDNS_RETURN_GENERIC_ERROR;
return GETDNS_RETURN_GOOD;
*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;
}
getdns_return_t
getdns_wire2rr_dict(
const uint8_t *wire, size_t wire_len, getdns_dict **rr_dict)
{
return getdns_wire2rr_dict_scan(&wire, &wire_len, rr_dict);
}
getdns_return_t
getdns_wire2rr_dict_buf(
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(&wire, &my_wire_len, rr_dict)))
return r;
*wire_len -= my_wire_len;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_wire2rr_dict_scan(
const uint8_t **wire, size_t *wire_len, getdns_dict **rr_dict)
{
static struct mem_funcs plain_mem_funcs = {
MF_PLAIN, .mf.pln = { malloc, realloc, free }
};
_getdns_rr_iter rr_iter_spc, *rr_iter;
if (!wire || !rr_dict)
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)))
&rr_iter_spc, *wire, *wire_len)))
return GETDNS_RETURN_GENERIC_ERROR;
if (!(*rr_dict = _getdns_rr_iter2rr_dict(&plain_mem_funcs, rr_iter)))
return GETDNS_RETURN_MEMORY_ERROR;
*wire_len -= (rr_iter->nxt - rr_iter->pos);
*wire = rr_iter->pos;
return GETDNS_RETURN_GOOD;
}
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;
size_t sz;
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)
if (!rr_dict || !str || !*str || !str_len)
return GETDNS_RETURN_INVALID_PARAMETER;
gldns_buffer_init_frm_data(&gbuf, buf, sizeof(buf_spc));
@ -293,15 +423,27 @@ getdns_rr_dict2str(
GETDNS_FREE(rr_dict->mf, buf);
return r;
}
if (!(*str = gldns_wire2str_rr(gldns_buffer_begin(&gbuf),
gldns_buffer_position(&gbuf))))
r = GETDNS_RETURN_MEMORY_ERROR;
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(
const char *str, getdns_dict **rr_dict, const char *origin, uint32_t default_ttl)

View File

@ -400,21 +400,166 @@ 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);
const char *str, getdns_dict **rr_dict,
const char *origin, uint32_t default_ttl);
#ifdef __cplusplus
}

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

@ -36,8 +36,6 @@
#include "getdns/getdns.h"
#include "gldns/gbuffer.h"
#define GETDNS_RETURN_NEED_MORE_SPACE ((getdns_return_t)399)
/* rdf_end returns a pointer to the end of this rdf's data,
* i.e. where the next rdata field will start.
*/

View File

@ -39,11 +39,7 @@ rr_iter_find_nxt(_getdns_rr_iter *i)
assert(i);
assert(i->rr_type);
if (!i->pkt) {
i->nxt = i->pkt_end;
return;
}
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

View File

@ -58,7 +58,7 @@ int main()
size_t length;
getdns_list *list;
char *str;
uint8_t wire_buf[4096], *wire = wire_buf, *end_of_wire;
uint8_t *wire;
size_t wire_len;
@ -81,11 +81,12 @@ int main()
/* Convert to wireformat from rdata_raw.
* Added fourth list element should NOT show.
*/
wire_len = sizeof(wire_buf);
if ((r = getdns_rr_dict2wire(rr_dict, wire, &wire_len)))
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.
@ -96,11 +97,11 @@ int main()
printf("\nremoved \"/rdata/rdata_raw\":\n\n");
wire_len = sizeof(wire_buf);
if ((r = getdns_rr_dict2wire(rr_dict, wire, &wire_len)))
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.
@ -132,11 +133,6 @@ int main()
getdns_dict_destroy(rr_dict);
/* Forward wireformat to test scanning from wireformat later on
*/
wire += wire_len;
wire_len = sizeof(wire_buf) - (wire - wire_buf);
/* Construct rr_dict and convert to string
*/
if (!(rr_dict = getdns_dict_create()))
@ -163,14 +159,12 @@ int main()
printf("\n%s\n", str);
free(str);
if ((r = getdns_rr_dict2wire(rr_dict, wire, &wire_len)))
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);
wire += wire_len;
wire_len = sizeof(wire_buf) - (wire - wire_buf);
free(wire);
/* Convert RR with special rdata fields and repeating last element
@ -239,10 +233,5 @@ int main()
getdns_dict_destroy(rr_dict);
/* Parse over wire data, convert to string via dict, and print */
end_of_wire = wire;
wire = wire_buf;
wire_len = end_of_wire - wire;
exit(EXIT_SUCCESS);
}