Merge branch 'release/v1.7.0' into develop

This commit is contained in:
Willem Toorop 2021-05-27 22:21:43 +02:00
commit 359a44d336
15 changed files with 208 additions and 86 deletions

View File

@ -13,19 +13,19 @@ endif ()
set(PACKAGE "getdns") set(PACKAGE "getdns")
set(PACKAGE_NAME "getdns") set(PACKAGE_NAME "getdns")
set(PACKAGE_VERSION "1.6.1") set(PACKAGE_VERSION "1.7.0")
set(PACKAGE_BUGREPORT "team@getdnsapi.net") set(PACKAGE_BUGREPORT "team@getdnsapi.net")
set(PACKAGE_URL "https://getdnsapi.net") set(PACKAGE_URL "https://getdnsapi.net")
# Dont forget to put a dash in front of the release candidate!!! # Dont forget to put a dash in front of the release candidate!!!
# That is how it is done with semantic versioning! # That is how it is done with semantic versioning!
set(RELEASE_CANDIDATE "-rc1") set(RELEASE_CANDIDATE "-rc.1")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}${RELEASE_CANDIDATE}") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
set(PACKAGE_TARNAME "${PACKAGE}-${PACKAGE_VERSION}${RELEASE_CANDIDATE}") set(PACKAGE_TARNAME "${PACKAGE}-${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
set(GETDNS_VERSION "${PACKAGE_VERSION}${RELEASE_CANDIDATE}") set(GETDNS_VERSION "${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
set(GETDNS_NUMERIC_VERSION 0x01060000) set(GETDNS_NUMERIC_VERSION 0x010600C1)
set(API_VERSION "December 2015") set(API_VERSION "December 2015")
set(API_NUMERIC_VERSION 0x07df0c00) set(API_NUMERIC_VERSION 0x07df0c00)
@ -68,10 +68,11 @@ set(API_NUMERIC_VERSION 0x07df0c00)
# getdns-1.5.0 had libversion 11:0:1 # getdns-1.5.0 had libversion 11:0:1
# getdns-1.5.1 had libversion 11:1:1 # getdns-1.5.1 had libversion 11:1:1
# getdns-1.5.2 had libversion 11:2:1 # getdns-1.5.2 had libversion 11:2:1
# getdns-1.6.0 has libversion 11:3:1 # getdns-1.6.0 had libversion 11:3:1
set(GETDNS_VERSION_CURRENT 11) # getdns-1.7.0 will have libversion 12:0:2
set(GETDNS_VERSION_REVISION 3) set(GETDNS_VERSION_CURRENT 12)
set(GETDNS_VERSION_AGE 1) set(GETDNS_VERSION_REVISION 0)
set(GETDNS_VERSION_AGE 2)
project(getdns VERSION ${PACKAGE_VERSION} LANGUAGES C) project(getdns VERSION ${PACKAGE_VERSION} LANGUAGES C)

View File

@ -1,15 +1,23 @@
* 2020-0?-??: Version 1.6.1-rc.1 * 2021-06-??: Version 1.7.0
* Make TLS Handshake timeout max 4/5th of timeout for the query, * Make TLS Handshake timeout max 4/5th of timeout for the query,
just like connection setup timeout was, so fallback transport just like connection setup timeout was, so fallback transport
have a chance too when TCP connection setup is less well have a chance too when TCP connection setup is less well
detectable (as with TCP_FASTOPEN on MacOS). detectable (as with TCP_FASTOPEN on MacOS).
* Issue #466: Memory leak with retrying queries (for examples * Issue #466: Memory leak with retrying queries (for examples
with search paths). Thanks doublez13. with search paths). Thanks doublez13.
* Issue #480: Cross compiling is broken with CMake * Issue #480: Handling of strptime when Cross compiling with CMake.
A new option to FORCE_COMPAT_STRPTIME (default disabled) will
(when disabled) make cmake assume the target platform has a POSIX
compatible strptime when cross-compiling.
* Setting of the number of milliseconds send data may remain * Setting of the number of milliseconds send data may remain
unacknowledged by the peer in a TCP connection (when supported unacknowledged by the peer in a TCP connection (when supported
by the OS) with getdns_context_set_tcp_send_timeout() by the OS) with getdns_context_set_tcp_send_timeout()
Thanks maciejsszmigiero. Thanks maciejsszmigiero.
* Issue #497: Fix typo in CMAKE included files, so Stubby can use
TLS v1.3 with chipersuites options ON. Thanks har-riz.
* Basic name compression on server replied messages. Thanks amialkow!
This alleviates (but might not completely resolve) issues #495 and
#320 .
* 2020-02-28: Version 1.6.0 * 2020-02-28: Version 1.6.0
* Issues #457, #458, #461: New symbols with libnettle >= 3.4. * Issues #457, #458, #461: New symbols with libnettle >= 3.4.

View File

@ -823,6 +823,7 @@ _getdns_reply_dict2wire(
getdns_list *section; getdns_list *section;
getdns_dict *rr_dict; getdns_dict *rr_dict;
getdns_bindata *qname; getdns_bindata *qname;
name_cache_t name_cache = {0};
int remove_dnssec; int remove_dnssec;
pkt_start = gldns_buffer_position(buf); pkt_start = gldns_buffer_position(buf);
@ -852,7 +853,7 @@ _getdns_reply_dict2wire(
if (!getdns_dict_get_bindata(reply, "/question/qname", &qname) && if (!getdns_dict_get_bindata(reply, "/question/qname", &qname) &&
!getdns_dict_get_int(reply, "/question/qtype", &qtype)) { !getdns_dict_get_int(reply, "/question/qtype", &qtype)) {
(void)getdns_dict_get_int(reply, "/question/qclass", &qclass); (void)getdns_dict_get_int(reply, "/question/qclass", &qclass);
gldns_buffer_write(buf, qname->data, qname->size); _getdns_rr_buffer_write_cached_name(buf, qname, &name_cache);
gldns_buffer_write_u16(buf, (uint16_t)qtype); gldns_buffer_write_u16(buf, (uint16_t)qtype);
gldns_buffer_write_u16(buf, (uint16_t)qclass); gldns_buffer_write_u16(buf, (uint16_t)qclass);
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1); gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1);
@ -875,7 +876,7 @@ _getdns_reply_dict2wire(
!getdns_dict_get_int(rr_dict, "type", &rr_type) && !getdns_dict_get_int(rr_dict, "type", &rr_type) &&
rr_type == GETDNS_RRTYPE_RRSIG) rr_type == GETDNS_RRTYPE_RRSIG)
continue; continue;
if (!_getdns_rr_dict2wire(rr_dict, buf)) if (!_getdns_rr_dict2wire_cache(rr_dict, buf, &name_cache))
n++; n++;
} }
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, n); gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, n);

View File

@ -232,7 +232,6 @@ INLINE void gldns_buffer_clear(gldns_buffer *buffer)
* the position is set to 0. * the position is set to 0.
* *
* \param[in] buffer the buffer to flip * \param[in] buffer the buffer to flip
* \return void
*/ */
INLINE void gldns_buffer_flip(gldns_buffer *buffer) INLINE void gldns_buffer_flip(gldns_buffer *buffer)
{ {
@ -782,7 +781,6 @@ int gldns_buffer_printf(gldns_buffer *buffer, const char *format, ...)
/** /**
* frees the buffer. * frees the buffer.
* \param[in] *buffer the buffer to be freed * \param[in] *buffer the buffer to be freed
* \return void
*/ */
void gldns_buffer_free(gldns_buffer *buffer); void gldns_buffer_free(gldns_buffer *buffer);
@ -790,7 +788,6 @@ void gldns_buffer_free(gldns_buffer *buffer);
* Makes the buffer fixed and returns a pointer to the data. The * Makes the buffer fixed and returns a pointer to the data. The
* caller is responsible for free'ing the result. * caller is responsible for free'ing the result.
* \param[in] *buffer the buffer to be exported * \param[in] *buffer the buffer to be exported
* \return void
*/ */
void *gldns_buffer_export(gldns_buffer *buffer); void *gldns_buffer_export(gldns_buffer *buffer);

View File

@ -14,9 +14,7 @@
#include <limits.h> #include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef HAVE_STRINGS_H
#include <strings.h> #include <strings.h>
#endif
gldns_lookup_table gldns_directive_types[] = { gldns_lookup_table gldns_directive_types[] = {
{ GLDNS_DIR_TTL, "$TTL" }, { GLDNS_DIR_TTL, "$TTL" },

View File

@ -153,7 +153,6 @@ int gldns_bgetc(struct gldns_buffer *buffer);
* the position to the first character that is not in *s. * the position to the first character that is not in *s.
* \param[in] *buffer buffer to use * \param[in] *buffer buffer to use
* \param[in] *s characters to skip * \param[in] *s characters to skip
* \return void
*/ */
void gldns_bskipcs(struct gldns_buffer *buffer, const char *s); void gldns_bskipcs(struct gldns_buffer *buffer, const char *s);
@ -162,7 +161,6 @@ void gldns_bskipcs(struct gldns_buffer *buffer, const char *s);
* the position to the first character that is not in *s. * the position to the first character that is not in *s.
* \param[in] *fp file to use * \param[in] *fp file to use
* \param[in] *s characters to skip * \param[in] *s characters to skip
* \return void
*/ */
void gldns_fskipcs(FILE *fp, const char *s); void gldns_fskipcs(FILE *fp, const char *s);
@ -173,7 +171,6 @@ void gldns_fskipcs(FILE *fp, const char *s);
* \param[in] *fp file to use * \param[in] *fp file to use
* \param[in] *s characters to skip * \param[in] *s characters to skip
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes) * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
* \return void
*/ */
void gldns_fskipcs_l(FILE *fp, const char *s, int *line_nr); void gldns_fskipcs_l(FILE *fp, const char *s, int *line_nr);

View File

@ -14,12 +14,8 @@
#include "config.h" #include "config.h"
#include "gldns/parseutil.h" #include "gldns/parseutil.h"
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h> #include <time.h>
#endif
#include <ctype.h> #include <ctype.h>
gldns_lookup_table * gldns_lookup_table *
@ -171,7 +167,7 @@ gldns_gmtime64_r(int64_t clock, struct tm *result)
static int64_t static int64_t
gldns_serial_arithmetics_time(int32_t time, time_t now) gldns_serial_arithmetics_time(int32_t time, time_t now)
{ {
int32_t offset = time - (int32_t) now; int32_t offset = (int32_t)((uint32_t) time - (uint32_t) now);
return (int64_t) now + offset; return (int64_t) now + offset;
} }
@ -623,13 +619,18 @@ size_t gldns_b64_ntop_calculate_size(size_t srcsize)
* *
* This routine does not insert spaces or linebreaks after 76 characters. * This routine does not insert spaces or linebreaks after 76 characters.
*/ */
int gldns_b64_ntop(uint8_t const *src, size_t srclength, static int gldns_b64_ntop_base(uint8_t const *src, size_t srclength,
char *target, size_t targsize) char *target, size_t targsize, int base64url, int padding)
{ {
const char* b64 = char* b64;
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const char pad64 = '='; const char pad64 = '=';
size_t i = 0, o = 0; size_t i = 0, o = 0;
if(base64url)
b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123"
"456789-_";
else
b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123"
"456789+/";
if(targsize < gldns_b64_ntop_calculate_size(srclength)) if(targsize < gldns_b64_ntop_calculate_size(srclength))
return -1; return -1;
/* whole chunks: xxxxxxyy yyyyzzzz zzwwwwww */ /* whole chunks: xxxxxxyy yyyyzzzz zzwwwwww */
@ -649,18 +650,26 @@ int gldns_b64_ntop(uint8_t const *src, size_t srclength,
target[o] = b64[src[i] >> 2]; target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ]; target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ];
target[o+2] = b64[ ((src[i+1]&0x0f)<<2) ]; target[o+2] = b64[ ((src[i+1]&0x0f)<<2) ];
if(padding) {
target[o+3] = pad64; target[o+3] = pad64;
/* i += 2; */ /* i += 2; */
o += 4; o += 4;
} else {
o += 3;
}
break; break;
case 1: case 1:
/* one at end, converted into A B = = */ /* one at end, converted into A B = = */
target[o] = b64[src[i] >> 2]; target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) ]; target[o+1] = b64[ ((src[i]&0x03)<<4) ];
if(padding) {
target[o+2] = pad64; target[o+2] = pad64;
target[o+3] = pad64; target[o+3] = pad64;
/* i += 1; */ /* i += 1; */
o += 4; o += 4;
} else {
o += 2;
}
break; break;
case 0: case 0:
default: default:
@ -673,19 +682,36 @@ int gldns_b64_ntop(uint8_t const *src, size_t srclength,
return (int)o; return (int)o;
} }
int gldns_b64_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize)
{
return gldns_b64_ntop_base(src, srclength, target, targsize,
0 /* no base64url */, 1 /* padding */);
}
int gldns_b64url_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize)
{
return gldns_b64_ntop_base(src, srclength, target, targsize,
1 /* base64url */, 0 /* no padding */);
}
size_t gldns_b64_pton_calculate_size(size_t srcsize) size_t gldns_b64_pton_calculate_size(size_t srcsize)
{ {
return (((((srcsize + 3) / 4) * 3)) + 1); return (((((srcsize + 3) / 4) * 3)) + 1);
} }
int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize) /* padding not required if srcsize is set */
static int gldns_b64_pton_base(char const *src, size_t srcsize, uint8_t *target,
size_t targsize, int base64url)
{ {
const uint8_t pad64 = 64; /* is 64th in the b64 array */ const uint8_t pad64 = 64; /* is 64th in the b64 array */
const char* s = src; const char* s = src;
uint8_t in[4]; uint8_t in[4];
size_t o = 0, incount = 0; size_t o = 0, incount = 0;
int check_padding = (srcsize) ? 0 : 1;
while(*s) { while(*s && (check_padding || srcsize)) {
/* skip any character that is not base64 */ /* skip any character that is not base64 */
/* conceptually we do: /* conceptually we do:
const char* b64 = pad'=' is appended to array const char* b64 = pad'=' is appended to array
@ -694,30 +720,43 @@ int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
and use d-b64; and use d-b64;
*/ */
char d = *s++; char d = *s++;
srcsize--;
if(d <= 'Z' && d >= 'A') if(d <= 'Z' && d >= 'A')
d -= 'A'; d -= 'A';
else if(d <= 'z' && d >= 'a') else if(d <= 'z' && d >= 'a')
d = d - 'a' + 26; d = d - 'a' + 26;
else if(d <= '9' && d >= '0') else if(d <= '9' && d >= '0')
d = d - '0' + 52; d = d - '0' + 52;
else if(d == '+') else if(!base64url && d == '+')
d = 62; d = 62;
else if(d == '/') else if(base64url && d == '-')
d = 62;
else if(!base64url && d == '/')
d = 63; d = 63;
else if(d == '=') else if(base64url && d == '_')
d = 64; d = 63;
else continue; else if(d == '=') {
in[incount++] = (uint8_t)d; if(!check_padding)
if(incount != 4)
continue; continue;
d = 64;
} else continue;
in[incount++] = (uint8_t)d;
/* work on block of 4, unless padding is not used and there are
* less than 4 chars left */
if(incount != 4 && (check_padding || srcsize))
continue;
assert(!check_padding || incount==4);
/* process whole block of 4 characters into 3 output bytes */ /* process whole block of 4 characters into 3 output bytes */
if(in[3] == pad64 && in[2] == pad64) { /* A B = = */ if((incount == 2 ||
(incount == 4 && in[3] == pad64 && in[2] == pad64))) { /* A B = = */
if(o+1 > targsize) if(o+1 > targsize)
return -1; return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
o += 1; o += 1;
break; /* we are done */ break; /* we are done */
} else if(in[3] == pad64) { /* A B C = */ } else if(incount == 3 ||
(incount == 4 && in[3] == pad64)) { /* A B C = */
if(o+2 > targsize) if(o+2 > targsize)
return -1; return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
@ -725,7 +764,7 @@ int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
o += 2; o += 2;
break; /* we are done */ break; /* we are done */
} else { } else {
if(o+3 > targsize) if(incount != 4 || o+3 > targsize)
return -1; return -1;
/* write xxxxxxyy yyyyzzzz zzwwwwww */ /* write xxxxxxyy yyyyzzzz zzwwwwww */
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
@ -737,3 +776,17 @@ int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
} }
return (int)o; return (int)o;
} }
int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
{
return gldns_b64_pton_base(src, 0, target, targsize, 0);
}
int gldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
size_t targsize)
{
if(!srcsize) {
return 0;
}
return gldns_b64_pton_base(src, srcsize, target, targsize, 1);
}

View File

@ -92,13 +92,16 @@ size_t gldns_b64_ntop_calculate_size(size_t srcsize);
int gldns_b64_ntop(uint8_t const *src, size_t srclength, int gldns_b64_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize); char *target, size_t targsize);
int gldns_b64url_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize);
/** /**
* calculates the size needed to store the result of gldns_b64_pton * calculates the size needed to store the result of gldns_b64_pton
*/ */
size_t gldns_b64_pton_calculate_size(size_t srcsize); size_t gldns_b64_pton_calculate_size(size_t srcsize);
int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize); int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
int gldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
size_t targsize);
/** /**
* calculates the size needed to store the result of b32_ntop * calculates the size needed to store the result of b32_ntop

View File

@ -195,7 +195,7 @@ enum gldns_enum_rr_type
GLDNS_RR_TYPE_CDNSKEY = 60, /** RFC 7344 */ GLDNS_RR_TYPE_CDNSKEY = 60, /** RFC 7344 */
GLDNS_RR_TYPE_OPENPGPKEY = 61, /* RFC 7929 */ GLDNS_RR_TYPE_OPENPGPKEY = 61, /* RFC 7929 */
GLDNS_RR_TYPE_CSYNC = 62, /* RFC 7477 */ GLDNS_RR_TYPE_CSYNC = 62, /* RFC 7477 */
GLDNS_RR_TYPE_ZONEMD = 63, /* draft-wessels-dns-zone-digest */ GLDNS_RR_TYPE_ZONEMD = 63, /* RFC8976 */
GLDNS_RR_TYPE_SVCB = 64, GLDNS_RR_TYPE_SVCB = 64,
GLDNS_RR_TYPE_HTTPS = 65, GLDNS_RR_TYPE_HTTPS = 65,
@ -434,7 +434,8 @@ enum gldns_enum_edns_option
GLDNS_EDNS_N3U = 7, /* RFC6975 */ GLDNS_EDNS_N3U = 7, /* RFC6975 */
GLDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */ GLDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
GLDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/ GLDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
GLDNS_EDNS_PADDING = 12 /* RFC7830 */ GLDNS_EDNS_PADDING = 12, /* RFC7830 */
GLDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
}; };
typedef enum gldns_enum_edns_option gldns_edns_option; typedef enum gldns_enum_edns_option gldns_edns_option;

View File

@ -930,6 +930,10 @@ int gldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
memmove(parse_state->prev_rr, rr, *dname_len); memmove(parse_state->prev_rr, rr, *dname_len);
parse_state->prev_rr_len = (*dname_len); parse_state->prev_rr_len = (*dname_len);
} }
if(r == GLDNS_WIREPARSE_ERR_OK && parse_state) {
parse_state->default_ttl = gldns_wirerr_get_ttl(
rr, *len, *dname_len);
}
return r; return r;
} }
return GLDNS_WIREPARSE_ERR_OK; return GLDNS_WIREPARSE_ERR_OK;
@ -1494,13 +1498,17 @@ static int
loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e) loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
{ {
uint32_t meters = 0, cm = 0, val; uint32_t meters = 0, cm = 0, val;
char* cm_endstr;
while (isblank((unsigned char)*my_str)) { while (isblank((unsigned char)*my_str)) {
my_str++; my_str++;
} }
meters = (uint32_t)strtol(my_str, &my_str, 10); meters = (uint32_t)strtol(my_str, &my_str, 10);
if (*my_str == '.') { if (*my_str == '.') {
my_str++; my_str++;
cm = (uint32_t)strtol(my_str, &my_str, 10); cm = (uint32_t)strtol(my_str, &cm_endstr, 10);
if(cm_endstr == my_str + 1)
cm *= 10;
my_str = cm_endstr;
} }
if (meters >= 1) { if (meters >= 1) {
*e = 2; *e = 2;

View File

@ -26,9 +26,7 @@
#ifdef HAVE_TIME_H #ifdef HAVE_TIME_H
#include <time.h> #include <time.h>
#endif #endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#include <stdarg.h> #include <stdarg.h>
#include <ctype.h> #include <ctype.h>
#ifdef HAVE_NETDB_H #ifdef HAVE_NETDB_H

View File

@ -1293,8 +1293,39 @@ write_rdata_field(gldns_buffer *buf, uint8_t *rdata_start,
return r != GETDNS_RETURN_NO_SUCH_LIST_ITEM ? r : GETDNS_RETURN_GOOD; return r != GETDNS_RETURN_NO_SUCH_LIST_ITEM ? r : GETDNS_RETURN_GOOD;
} }
void
_getdns_rr_buffer_write_cached_name(gldns_buffer *buf, getdns_bindata *name, name_cache_t *name_cache)
{
size_t name_size = name->size;
uint8_t *name_data = name->data;
if((NULL != name_cache) && (name_size > 2)) {
unsigned count = name_cache->count;
name_cache_entry_t *entry_ptr = &name_cache->entry[(count < NAME_CACHE_ENTRIES)?count:NAME_CACHE_ENTRIES];
name_cache_entry_t *table_start = &name_cache->entry[0];
/* Search backward if name is already in cache */
while(entry_ptr-- > table_start) {
if((entry_ptr->name->size == name_size) &&
!memcmp(entry_ptr->name->data, name_data, name_size)) {
gldns_buffer_write_u16(buf, (uint16_t)(0xc000 | entry_ptr->name_offset));
return;
}
}
unsigned name_offset = gldns_buffer_position(buf);
if (name_offset < 0xc000) {
/* Cache name */
entry_ptr = &name_cache->entry[count % NAME_CACHE_ENTRIES];
entry_ptr->name = name;
entry_ptr->name_offset = name_offset;
name_cache->count = count + 1;
}
}
gldns_buffer_write(buf, name_data, name_size);
return;
}
getdns_return_t getdns_return_t
_getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf) _getdns_rr_dict2wire_cache(const getdns_dict *rr_dict, gldns_buffer *buf,
name_cache_t *name_cache)
{ {
getdns_return_t r = GETDNS_RETURN_GOOD; getdns_return_t r = GETDNS_RETURN_GOOD;
getdns_bindata root = { 1, (void *)"" }; getdns_bindata root = { 1, (void *)"" };
@ -1325,7 +1356,7 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
} else } else
return r; return r;
} }
gldns_buffer_write(buf, name->data, name->size); _getdns_rr_buffer_write_cached_name(buf, name, name_cache);
gldns_buffer_write_u16(buf, (uint16_t)rr_type); gldns_buffer_write_u16(buf, (uint16_t)rr_type);
(void) getdns_dict_get_int(rr_dict, "class", &rr_class); (void) getdns_dict_get_int(rr_dict, "class", &rr_class);
@ -1378,6 +1409,14 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
gldns_buffer_skip(buf, 2); gldns_buffer_skip(buf, 2);
rdata_start = gldns_buffer_current(buf); rdata_start = gldns_buffer_current(buf);
/* Special case CNAME payload */
if((rr_type == GETDNS_RRTYPE_CNAME) && (n_rdata_fields == 1) &&
(rd_def->type & GETDNS_RDF_BINDATA) && !(rd_def->type & GETDNS_RDF_REPEAT) &&
(GETDNS_RETURN_GOOD == (r = getdns_dict_get_bindata(rdata, rd_def->name, &rdata_raw)))) {
_getdns_rr_buffer_write_cached_name(buf, rdata_raw, name_cache);
} else {
for ( rd_def = rr_def->rdata for ( rd_def = rr_def->rdata
, n_rdata_fields = rr_def->n_rdata_fields , n_rdata_fields = rr_def->n_rdata_fields
; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) { ; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) {
@ -1415,6 +1454,7 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
break; break;
} }
} }
}
gldns_buffer_write_u16_at(buf, rdata_size_mark, gldns_buffer_write_u16_at(buf, rdata_size_mark,
(uint16_t)(gldns_buffer_position(buf)-rdata_size_mark-2)); (uint16_t)(gldns_buffer_position(buf)-rdata_size_mark-2));
} }

View File

@ -143,8 +143,25 @@ typedef struct _getdns_rr_def {
const _getdns_rr_def *_getdns_rr_def_lookup(uint16_t rr_type); const _getdns_rr_def *_getdns_rr_def_lookup(uint16_t rr_type);
getdns_return_t _getdns_rr_dict2wire( #define NAME_CACHE_ENTRIES 4
const getdns_dict *rr_dict, gldns_buffer *buf);
typedef struct __name_cache_entry {
getdns_bindata *name;
unsigned name_offset;
} name_cache_entry_t;
typedef struct __name_cache {
unsigned count;
name_cache_entry_t entry[NAME_CACHE_ENTRIES];
} name_cache_t;
void _getdns_rr_buffer_write_cached_name(
gldns_buffer *buf, getdns_bindata *name, name_cache_t *name_cache);
getdns_return_t _getdns_rr_dict2wire_cache(
const getdns_dict *rr_dict, gldns_buffer *buf, name_cache_t *name_cache);
#define _getdns_rr_dict2wire(d, b) _getdns_rr_dict2wire_cache((d),(b), NULL)
const char *_getdns_rr_type_name(int rr_type); const char *_getdns_rr_type_name(int rr_type);

View File

@ -11,5 +11,5 @@ elif ! ( "./${TPKG_NAME}" "${TPKG_NAME}.net-dns.org" | tee out )
then then
exit 1 exit 1
else else
diff out "${TPKG_NAME}.good" diff out "${TPKG_NAME}.good" --ignore-matching-lines=";; MSG SIZE rcvd: "
fi fi

2
stubby

@ -1 +1 @@
Subproject commit ef0a1476ae066612efd99628d7bc36ef8bcf1fb6 Subproject commit 391e5d300b44f8be5231dd00ae51a880fb4c020e