mirror of https://github.com/getdnsapi/getdns.git
Merge branch 'develop' into devel/spki_pinset_via_tlsa_checking
This commit is contained in:
commit
9c5a93bbdf
|
@ -329,7 +329,7 @@ convert.lo convert.o: $(srcdir)/convert.c \
|
||||||
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h \
|
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h \
|
||||||
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/gldns/wire2str.h \
|
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/gldns/wire2str.h \
|
||||||
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h \
|
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h \
|
||||||
$(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(stubbysrcdir)/src/yaml/convert_yaml_to_json.h $(srcdir)/convert.h
|
$(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h
|
||||||
dict.lo dict.o: $(srcdir)/dict.c \
|
dict.lo dict.o: $(srcdir)/dict.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/types-internal.h \
|
$(srcdir)/types-internal.h \
|
||||||
|
|
|
@ -56,7 +56,9 @@
|
||||||
#include "dict.h"
|
#include "dict.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "jsmn/jsmn.h"
|
#include "jsmn/jsmn.h"
|
||||||
|
#ifdef USE_YAML_CONFIG
|
||||||
#include "yaml/convert_yaml_to_json.h"
|
#include "yaml/convert_yaml_to_json.h"
|
||||||
|
#endif
|
||||||
#include "convert.h"
|
#include "convert.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
43
src/dnssec.c
43
src/dnssec.c
|
@ -1755,6 +1755,26 @@ static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns whether a dnskey for keyset signed a non wildcard rrset. */
|
||||||
|
static int a_key_signed_rrset_no_wc(struct mem_funcs *mf, time_t now,
|
||||||
|
uint32_t skew, _getdns_rrset *keyset, _getdns_rrset *rrset)
|
||||||
|
{
|
||||||
|
_getdns_rrtype_iter dnskey_spc, *dnskey;
|
||||||
|
const uint8_t *nc_name;
|
||||||
|
int keytag;
|
||||||
|
|
||||||
|
assert(keyset->rr_type == GETDNS_RRTYPE_DNSKEY);
|
||||||
|
|
||||||
|
for ( dnskey = _getdns_rrtype_iter_init(&dnskey_spc, keyset)
|
||||||
|
; dnskey ; dnskey = _getdns_rrtype_iter_next(dnskey) ) {
|
||||||
|
|
||||||
|
if ((keytag = dnskey_signed_rrset(mf, now, skew,
|
||||||
|
dnskey, rrset, &nc_name)) && !nc_name)
|
||||||
|
return keytag;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int find_nsec_covering_name(
|
static int find_nsec_covering_name(
|
||||||
struct mem_funcs *mf, time_t now, uint32_t skew, _getdns_rrset *dnskey,
|
struct mem_funcs *mf, time_t now, uint32_t skew, _getdns_rrset *dnskey,
|
||||||
_getdns_rrset *rrset, const uint8_t *name, int *opt_out);
|
_getdns_rrset *rrset, const uint8_t *name, int *opt_out);
|
||||||
|
@ -2110,7 +2130,8 @@ static int find_nsec_covering_name(
|
||||||
&& (bitmap = _getdns_rdf_iter_init_at(
|
&& (bitmap = _getdns_rdf_iter_init_at(
|
||||||
&bitmap_spc, &nsec_rr->rr_i, 5))
|
&bitmap_spc, &nsec_rr->rr_i, 5))
|
||||||
|
|
||||||
&& (keytag = a_key_signed_rrset(mf, now, skew, dnskey, n))
|
&& (keytag = a_key_signed_rrset_no_wc(
|
||||||
|
mf, now, skew, dnskey, n))
|
||||||
&& ( keytag & NSEC3_ITERATION_COUNT_HIGH
|
&& ( keytag & NSEC3_ITERATION_COUNT_HIGH
|
||||||
|
|
||||||
|| ( nsec3_covers_name(n, name, opt_out)
|
|| ( nsec3_covers_name(n, name, opt_out)
|
||||||
|
@ -2174,7 +2195,8 @@ static int find_nsec_covering_name(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
&& (keytag = a_key_signed_rrset(mf,now,skew, dnskey, n))) {
|
&& (keytag = a_key_signed_rrset_no_wc(
|
||||||
|
mf, now, skew, dnskey, n))) {
|
||||||
|
|
||||||
debug_sec_print_rrset("NSEC: ", n);
|
debug_sec_print_rrset("NSEC: ", n);
|
||||||
debug_sec_print_dname("covered: ", name);
|
debug_sec_print_dname("covered: ", name);
|
||||||
|
@ -2297,7 +2319,8 @@ static int key_proves_nonexistance(
|
||||||
|| bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA))
|
|| bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA))
|
||||||
|
|
||||||
/* And a valid signature please */
|
/* And a valid signature please */
|
||||||
&& (keytag = a_key_signed_rrset(mf,now,skew,keyset,&nsec_rrset))) {
|
&& (keytag = a_key_signed_rrset_no_wc(
|
||||||
|
mf, now, skew, keyset, &nsec_rrset))) {
|
||||||
|
|
||||||
debug_sec_print_rrset("NSEC NODATA proof for: ", rrset);
|
debug_sec_print_rrset("NSEC NODATA proof for: ", rrset);
|
||||||
return keytag;
|
return keytag;
|
||||||
|
@ -2353,7 +2376,7 @@ static int key_proves_nonexistance(
|
||||||
)
|
)
|
||||||
|
|
||||||
/* And a valid signature please (as always) */
|
/* And a valid signature please (as always) */
|
||||||
|| !(keytag = a_key_signed_rrset(
|
|| !(keytag = a_key_signed_rrset_no_wc(
|
||||||
mf, now, skew, keyset, cover)))
|
mf, now, skew, keyset, cover)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2437,7 +2460,8 @@ static int key_proves_nonexistance(
|
||||||
|| bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA))
|
|| bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA))
|
||||||
|
|
||||||
/* It must have a valid signature */
|
/* It must have a valid signature */
|
||||||
&& (keytag = a_key_signed_rrset(mf, now, skew, keyset, ce))
|
&& (keytag = a_key_signed_rrset_no_wc(
|
||||||
|
mf, now, skew, keyset, ce))
|
||||||
|
|
||||||
/* The qname must match the NSEC3 */
|
/* The qname must match the NSEC3 */
|
||||||
&& ( keytag & NSEC3_ITERATION_COUNT_HIGH
|
&& ( keytag & NSEC3_ITERATION_COUNT_HIGH
|
||||||
|
@ -2493,7 +2517,7 @@ static int key_proves_nonexistance(
|
||||||
&& !bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA)
|
&& !bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA)
|
||||||
)
|
)
|
||||||
|
|
||||||
|| !(keytag = a_key_signed_rrset(
|
|| !(keytag = a_key_signed_rrset_no_wc(
|
||||||
mf, now, skew, keyset, ce))
|
mf, now, skew, keyset, ce))
|
||||||
|| ( !(keytag & NSEC3_ITERATION_COUNT_HIGH)
|
|| ( !(keytag & NSEC3_ITERATION_COUNT_HIGH)
|
||||||
&& !nsec3_matches_name(ce, ce_name)))
|
&& !nsec3_matches_name(ce, ce_name)))
|
||||||
|
@ -2545,7 +2569,7 @@ static int chain_node_get_trusted_keys(
|
||||||
} else if (ta->rr_type == GETDNS_RRTYPE_DNSKEY) {
|
} else if (ta->rr_type == GETDNS_RRTYPE_DNSKEY) {
|
||||||
|
|
||||||
/* ta is KSK */
|
/* ta is KSK */
|
||||||
if ((keytag = a_key_signed_rrset(
|
if ((keytag = a_key_signed_rrset_no_wc(
|
||||||
mf, now, skew, ta, &node->dnskey))) {
|
mf, now, skew, ta, &node->dnskey))) {
|
||||||
*keys = &node->dnskey;
|
*keys = &node->dnskey;
|
||||||
node->dnskey_signer = keytag;
|
node->dnskey_signer = keytag;
|
||||||
|
@ -2563,7 +2587,8 @@ static int chain_node_get_trusted_keys(
|
||||||
return GETDNS_DNSSEC_INSECURE;
|
return GETDNS_DNSSEC_INSECURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((keytag = a_key_signed_rrset(mf,now,skew,ta,&node->ds))) {
|
if ((keytag = a_key_signed_rrset_no_wc(
|
||||||
|
mf, now, skew, ta, &node->ds))) {
|
||||||
node->ds_signer = keytag;
|
node->ds_signer = keytag;
|
||||||
if ((keytag = ds_authenticates_keys(
|
if ((keytag = ds_authenticates_keys(
|
||||||
mf, now, skew, &node->ds, &node->dnskey))) {
|
mf, now, skew, &node->ds, &node->dnskey))) {
|
||||||
|
@ -2597,7 +2622,7 @@ static int chain_node_get_trusted_keys(
|
||||||
}
|
}
|
||||||
if (key_matches_signer(ta, &node->ds)) {
|
if (key_matches_signer(ta, &node->ds)) {
|
||||||
|
|
||||||
if ((node->ds_signer = a_key_signed_rrset(
|
if ((node->ds_signer = a_key_signed_rrset_no_wc(
|
||||||
mf, now, skew, ta, &node->ds))
|
mf, now, skew, ta, &node->ds))
|
||||||
&& (keytag = ds_authenticates_keys(
|
&& (keytag = ds_authenticates_keys(
|
||||||
mf, now, skew, &node->ds, &node->dnskey))){
|
mf, now, skew, &node->ds, &node->dnskey))){
|
||||||
|
|
|
@ -697,6 +697,8 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
/* clean up the request */
|
/* clean up the request */
|
||||||
_getdns_context_clear_outbound_request(req);
|
_getdns_context_clear_outbound_request(req);
|
||||||
_getdns_dns_req_free(req);
|
_getdns_dns_req_free(req);
|
||||||
|
if (return_netreq_p)
|
||||||
|
*return_netreq_p = NULL;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
|
|
196
src/server.c
196
src/server.c
|
@ -34,6 +34,10 @@
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_FCNTL)
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "getdns/getdns_extra.h"
|
#include "getdns/getdns_extra.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "types-internal.h"
|
#include "types-internal.h"
|
||||||
|
@ -118,6 +122,25 @@ typedef struct tcp_connection {
|
||||||
size_t to_answer;
|
size_t to_answer;
|
||||||
} tcp_connection;
|
} tcp_connection;
|
||||||
|
|
||||||
|
/** best effort to set nonblocking */
|
||||||
|
static void
|
||||||
|
getdns_sock_nonblock(int sockfd)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_FCNTL)
|
||||||
|
int flag;
|
||||||
|
if((flag = fcntl(sockfd, F_GETFL)) != -1) {
|
||||||
|
flag |= O_NONBLOCK;
|
||||||
|
if(fcntl(sockfd, F_SETFL, flag) == -1) {
|
||||||
|
/* ignore error, continue blockingly */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(HAVE_IOCTLSOCKET)
|
||||||
|
unsigned long on = 1;
|
||||||
|
if(ioctlsocket(sockfd, FIONBIO, &on) != 0) {
|
||||||
|
/* ignore error, continue blockingly */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void free_listen_set_when_done(listen_set *set);
|
static void free_listen_set_when_done(listen_set *set);
|
||||||
static void tcp_connection_destroy(tcp_connection *conn)
|
static void tcp_connection_destroy(tcp_connection *conn)
|
||||||
|
@ -127,22 +150,33 @@ static void tcp_connection_destroy(tcp_connection *conn)
|
||||||
|
|
||||||
tcp_to_write *cur, *next;
|
tcp_to_write *cur, *next;
|
||||||
|
|
||||||
if (!(mf = &conn->super.l->set->context->mf))
|
mf = &conn->super.l->set->context->mf;
|
||||||
return;
|
|
||||||
|
|
||||||
if (getdns_context_get_eventloop(conn->super.l->set->context, &loop))
|
if (getdns_context_get_eventloop(conn->super.l->set->context, &loop))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (conn->event.read_cb||conn->event.write_cb||conn->event.timeout_cb)
|
if (conn->event.ev)
|
||||||
loop->vmt->clear(loop, &conn->event);
|
loop->vmt->clear(loop, &conn->event);
|
||||||
|
|
||||||
if (conn->fd >= 0)
|
if (conn->event.read_cb||conn->event.write_cb||conn->event.timeout_cb) {
|
||||||
|
conn->event.read_cb = conn->event.write_cb =
|
||||||
|
conn->event.timeout_cb = NULL;
|
||||||
|
}
|
||||||
|
if (conn->fd >= 0) {
|
||||||
(void) _getdns_closesocket(conn->fd);
|
(void) _getdns_closesocket(conn->fd);
|
||||||
GETDNS_FREE(*mf, conn->read_buf);
|
conn->fd = -1;
|
||||||
|
}
|
||||||
for (cur = conn->to_write; cur; cur = next) {
|
if (conn->read_buf) {
|
||||||
next = cur->next;
|
GETDNS_FREE(*mf, conn->read_buf);
|
||||||
GETDNS_FREE(*mf, cur);
|
conn->read_buf = conn->read_pos = NULL;
|
||||||
|
conn->to_read = 0;
|
||||||
|
}
|
||||||
|
if ((cur = conn->to_write)) {
|
||||||
|
while (cur) {
|
||||||
|
next = cur->next;
|
||||||
|
GETDNS_FREE(*mf, cur);
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
conn->to_write = NULL;
|
||||||
}
|
}
|
||||||
if (conn->to_answer > 0)
|
if (conn->to_answer > 0)
|
||||||
return;
|
return;
|
||||||
|
@ -191,15 +225,16 @@ static void tcp_write_cb(void *userarg)
|
||||||
(const void *)&to_write->write_buf[to_write->written],
|
(const void *)&to_write->write_buf[to_write->written],
|
||||||
to_write->write_buf_len - to_write->written, 0)) == -1) {
|
to_write->write_buf_len - to_write->written, 0)) == -1) {
|
||||||
|
|
||||||
if (_getdns_socketerror_wants_retry())
|
if (conn->fd != -1) {
|
||||||
return;
|
if (_getdns_socketerror_wants_retry()) {
|
||||||
|
(void) loop->vmt->schedule(loop, conn->fd,
|
||||||
DEBUG_SERVER("I/O error from send(): %s\n",
|
DOWNSTREAM_IDLE_TIMEOUT, &conn->event);
|
||||||
_getdns_errnostr());
|
return;
|
||||||
|
}
|
||||||
|
DEBUG_SERVER("I/O error from send(): %s\n",
|
||||||
|
_getdns_errnostr());
|
||||||
|
}
|
||||||
/* IO error, close connection */
|
/* IO error, close connection */
|
||||||
conn->event.read_cb = conn->event.write_cb =
|
|
||||||
conn->event.timeout_cb = NULL;
|
|
||||||
tcp_connection_destroy(conn);
|
tcp_connection_destroy(conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -317,8 +352,10 @@ getdns_reply(
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
if (!(to_write = (tcp_to_write *)GETDNS_XMALLOC(
|
if (!(to_write = (tcp_to_write *)GETDNS_XMALLOC(
|
||||||
*mf, uint8_t, sizeof(tcp_to_write) + len + 2)))
|
*mf, uint8_t, sizeof(tcp_to_write) + len + 2))) {
|
||||||
|
tcp_connection_destroy(conn);
|
||||||
return GETDNS_RETURN_MEMORY_ERROR;
|
return GETDNS_RETURN_MEMORY_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
to_write->write_buf_len = len + 2;
|
to_write->write_buf_len = len + 2;
|
||||||
to_write->write_buf[0] = (len >> 8) & 0xFF;
|
to_write->write_buf[0] = (len >> 8) & 0xFF;
|
||||||
|
@ -327,20 +364,27 @@ getdns_reply(
|
||||||
to_write->next = NULL;
|
to_write->next = NULL;
|
||||||
(void) memcpy(to_write->write_buf + 2, buf, len);
|
(void) memcpy(to_write->write_buf + 2, buf, len);
|
||||||
|
|
||||||
/* Appen to_write to conn->to_write list */
|
/* Append to_write to conn->to_write list */
|
||||||
for ( to_write_p = &conn->to_write
|
for ( to_write_p = &conn->to_write
|
||||||
; *to_write_p
|
; *to_write_p
|
||||||
; to_write_p = &(*to_write_p)->next)
|
; to_write_p = &(*to_write_p)->next)
|
||||||
; /* pass */
|
; /* pass */
|
||||||
*to_write_p = to_write;
|
*to_write_p = to_write;
|
||||||
|
|
||||||
loop->vmt->clear(loop, &conn->event);
|
|
||||||
conn->event.write_cb = tcp_write_cb;
|
|
||||||
if (conn->to_answer > 0)
|
if (conn->to_answer > 0)
|
||||||
conn->to_answer--;
|
conn->to_answer--;
|
||||||
(void) loop->vmt->schedule(loop,
|
|
||||||
conn->fd, DOWNSTREAM_IDLE_TIMEOUT,
|
/* When event is scheduled, and doesn't have tcp_write_cb:
|
||||||
&conn->event);
|
* reschedule.
|
||||||
|
*/
|
||||||
|
if (conn->event.write_cb == NULL) {
|
||||||
|
if (conn->event.ev)
|
||||||
|
loop->vmt->clear(loop, &conn->event);
|
||||||
|
conn->event.write_cb = tcp_write_cb;
|
||||||
|
(void) loop->vmt->schedule(loop,
|
||||||
|
conn->fd, DOWNSTREAM_IDLE_TIMEOUT,
|
||||||
|
&conn->event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* TODO: other transport types */
|
/* TODO: other transport types */
|
||||||
|
|
||||||
|
@ -366,18 +410,19 @@ static void tcp_read_cb(void *userarg)
|
||||||
|
|
||||||
/* Reset tcp_connection idle timeout */
|
/* Reset tcp_connection idle timeout */
|
||||||
loop->vmt->clear(loop, &conn->event);
|
loop->vmt->clear(loop, &conn->event);
|
||||||
(void) loop->vmt->schedule(loop, conn->fd,
|
if (conn->fd == -1 ||
|
||||||
DOWNSTREAM_IDLE_TIMEOUT, &conn->event);
|
(bytes_read = recv(conn->fd,
|
||||||
|
|
||||||
if ((bytes_read = recv(conn->fd,
|
|
||||||
(void *)conn->read_pos, conn->to_read, 0)) < 0) {
|
(void *)conn->read_pos, conn->to_read, 0)) < 0) {
|
||||||
if (_getdns_socketerror_wants_retry())
|
if (conn->fd != -1) {
|
||||||
return; /* Come back to do the read later */
|
if (_getdns_socketerror_wants_retry()) {
|
||||||
|
(void) loop->vmt->schedule(loop, conn->fd,
|
||||||
/* IO error, close connection */
|
DOWNSTREAM_IDLE_TIMEOUT, &conn->event);
|
||||||
DEBUG_SERVER("I/O error from recv(): %s\n",
|
return; /* Come back to do the read later */
|
||||||
_getdns_errnostr());
|
}
|
||||||
|
/* IO error, close connection */
|
||||||
|
DEBUG_SERVER("I/O error from recv(): %s\n",
|
||||||
|
_getdns_errnostr());
|
||||||
|
}
|
||||||
tcp_connection_destroy(conn);
|
tcp_connection_destroy(conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -391,9 +436,9 @@ static void tcp_read_cb(void *userarg)
|
||||||
conn->to_read -= bytes_read;
|
conn->to_read -= bytes_read;
|
||||||
conn->read_pos += bytes_read;
|
conn->read_pos += bytes_read;
|
||||||
if (conn->to_read)
|
if (conn->to_read)
|
||||||
return; /* More to read */
|
; /* Schedule for more reading */
|
||||||
|
|
||||||
if (conn->read_pos - conn->read_buf == 2) {
|
else if (conn->read_pos - conn->read_buf == 2) {
|
||||||
/* read length of dns msg to read */
|
/* read length of dns msg to read */
|
||||||
conn->to_read = (conn->read_buf[0] << 8) | conn->read_buf[1];
|
conn->to_read = (conn->read_buf[0] << 8) | conn->read_buf[1];
|
||||||
if (conn->to_read > conn->read_buf_len) {
|
if (conn->to_read > conn->read_buf_len) {
|
||||||
|
@ -413,47 +458,60 @@ static void tcp_read_cb(void *userarg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
conn->read_pos = conn->read_buf;
|
conn->read_pos = conn->read_buf;
|
||||||
return; /* Read DNS message */
|
; /* Schedule for more reading */
|
||||||
}
|
|
||||||
if ((r = getdns_wire2msg_dict(conn->read_buf,
|
|
||||||
(conn->read_pos - conn->read_buf), &request_dict)))
|
|
||||||
; /* FROMERR on input, ignore */
|
|
||||||
|
|
||||||
else {
|
} else {
|
||||||
conn->to_answer++;
|
/* Ready for reading a new packet */
|
||||||
|
|
||||||
/* TODO: wish list item:
|
if (!(r = getdns_wire2msg_dict(conn->read_buf,
|
||||||
* (void) getdns_dict_set_int64(
|
(conn->read_pos - conn->read_buf), &request_dict))) {
|
||||||
* request_dict, "request_id", intptr_t)conn);
|
|
||||||
*/
|
|
||||||
/* Call request handler */
|
|
||||||
conn->super.l->set->handler(
|
|
||||||
conn->super.l->set->context, GETDNS_CALLBACK_COMPLETE,
|
|
||||||
request_dict, conn->super.l->set->userarg, (intptr_t)conn);
|
|
||||||
|
|
||||||
|
conn->to_answer++;
|
||||||
|
|
||||||
|
/* TODO: wish list item:
|
||||||
|
* (void) getdns_dict_set_int64(
|
||||||
|
* request_dict, "request_id", intptr_t)conn);
|
||||||
|
*/
|
||||||
|
/* Call request handler */
|
||||||
|
|
||||||
|
conn->to_answer += 1; /* conn removal protection */
|
||||||
|
conn->super.l->set->handler(
|
||||||
|
conn->super.l->set->context,
|
||||||
|
GETDNS_CALLBACK_COMPLETE, request_dict,
|
||||||
|
conn->super.l->set->userarg, (intptr_t)conn);
|
||||||
|
conn->to_answer -= 1; /* conn removal protection */
|
||||||
|
|
||||||
|
if (conn->fd == -1) {
|
||||||
|
tcp_connection_destroy(conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
conn->read_pos = conn->read_buf;
|
conn->read_pos = conn->read_buf;
|
||||||
conn->to_read = 2;
|
conn->to_read = 2;
|
||||||
return; /* Read more requests */
|
; /* Schedule for more reading */
|
||||||
}
|
}
|
||||||
conn->read_pos = conn->read_buf;
|
|
||||||
conn->to_read = 2;
|
|
||||||
/* Read more requests */
|
/* Read more requests */
|
||||||
|
if (!conn->event.ev) { /* event not scheduled */
|
||||||
|
conn->event.write_cb = conn->to_write ? tcp_write_cb : NULL;
|
||||||
|
(void) loop->vmt->schedule(loop, conn->fd,
|
||||||
|
DOWNSTREAM_IDLE_TIMEOUT, &conn->event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcp_timeout_cb(void *userarg)
|
static void tcp_timeout_cb(void *userarg)
|
||||||
{
|
{
|
||||||
tcp_connection *conn = (tcp_connection *)userarg;
|
tcp_connection *conn = (tcp_connection *)userarg;
|
||||||
|
getdns_eventloop *loop;
|
||||||
|
|
||||||
assert(userarg);
|
assert(userarg);
|
||||||
|
|
||||||
if (conn->to_answer) {
|
if (getdns_context_get_eventloop(
|
||||||
getdns_eventloop *loop;
|
conn->super.l->set->context, &loop))
|
||||||
|
return;
|
||||||
|
|
||||||
if (getdns_context_get_eventloop(
|
loop->vmt->clear(loop, &conn->event);
|
||||||
conn->super.l->set->context, &loop))
|
|
||||||
return;
|
|
||||||
|
|
||||||
loop->vmt->clear(loop, &conn->event);
|
if (conn->to_answer && conn->fd >= 0) {
|
||||||
(void) loop->vmt->schedule(loop,
|
(void) loop->vmt->schedule(loop,
|
||||||
conn->fd, DOWNSTREAM_IDLE_TIMEOUT,
|
conn->fd, DOWNSTREAM_IDLE_TIMEOUT,
|
||||||
&conn->event);
|
&conn->event);
|
||||||
|
@ -501,8 +559,10 @@ static void tcp_accept_cb(void *userarg)
|
||||||
GETDNS_FREE(*mf, conn);
|
GETDNS_FREE(*mf, conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
getdns_sock_nonblock(conn->fd);
|
||||||
if (!(conn->read_buf = malloc(DNS_REQUEST_SZ))) {
|
if (!(conn->read_buf = malloc(DNS_REQUEST_SZ))) {
|
||||||
/* Memory error */
|
/* Memory error */
|
||||||
|
(void) _getdns_closesocket(conn->fd);
|
||||||
GETDNS_FREE(*mf, conn);
|
GETDNS_FREE(*mf, conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -518,6 +578,7 @@ static void tcp_accept_cb(void *userarg)
|
||||||
if (!_getdns_rbtree_insert(
|
if (!_getdns_rbtree_insert(
|
||||||
&l->set->connections_set, &conn->super.super)) {
|
&l->set->connections_set, &conn->super.super)) {
|
||||||
/* Memory error */
|
/* Memory error */
|
||||||
|
(void) _getdns_closesocket(conn->fd);
|
||||||
GETDNS_FREE(*mf, conn);
|
GETDNS_FREE(*mf, conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -730,8 +791,17 @@ static void remove_listeners(listen_set *set)
|
||||||
|
|
||||||
conn_p = (tcp_connection **)&l->connections;
|
conn_p = (tcp_connection **)&l->connections;
|
||||||
while (*conn_p) {
|
while (*conn_p) {
|
||||||
|
tcp_connection *prev_conn_p = *conn_p;
|
||||||
|
|
||||||
|
loop->vmt->clear(loop, &(*conn_p)->event);
|
||||||
tcp_connection_destroy(*conn_p);
|
tcp_connection_destroy(*conn_p);
|
||||||
if (*conn_p && (*conn_p)->to_answer > 0)
|
/* tcp_connection_destroy() updates the pointer to the
|
||||||
|
* connection. For the first connection this is
|
||||||
|
* l->connections. When the connection is not actually
|
||||||
|
* destroyed, the value of *conn_p thus remains the
|
||||||
|
* same. When it is destroyed it is updated.
|
||||||
|
*/
|
||||||
|
if (*conn_p == prev_conn_p)
|
||||||
conn_p = (tcp_connection **)
|
conn_p = (tcp_connection **)
|
||||||
&(*conn_p)->super.next;
|
&(*conn_p)->super.next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -965,6 +965,7 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
|
||||||
"%-40s : ERROR: Hostname Authentication not available from TLS library (check library version)\n",
|
"%-40s : ERROR: Hostname Authentication not available from TLS library (check library version)\n",
|
||||||
upstream->addr_str);
|
upstream->addr_str);
|
||||||
upstream->tls_hs_state = GETDNS_HS_FAILED;
|
upstream->tls_hs_state = GETDNS_HS_FAILED;
|
||||||
|
SSL_free(ssl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -982,6 +983,7 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
|
||||||
DEBUG_STUB("%s %-35s: ERROR: No host name or pubkey pinset provided for TLS authentication\n",
|
DEBUG_STUB("%s %-35s: ERROR: No host name or pubkey pinset provided for TLS authentication\n",
|
||||||
STUB_DEBUG_SETUP_TLS, __FUNC__);
|
STUB_DEBUG_SETUP_TLS, __FUNC__);
|
||||||
upstream->tls_hs_state = GETDNS_HS_FAILED;
|
upstream->tls_hs_state = GETDNS_HS_FAILED;
|
||||||
|
SSL_free(ssl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1613,7 +1613,43 @@ static void incoming_request_handler(getdns_context *context,
|
||||||
fprintf(stderr, "Could set class from query: %s\n",
|
fprintf(stderr, "Could set class from query: %s\n",
|
||||||
getdns_get_errorstr_by_id(r));
|
getdns_get_errorstr_by_id(r));
|
||||||
|
|
||||||
else if ((r = getdns_general(context, qname_str, qtype,
|
else if (qtype == GETDNS_RRTYPE_TXT && qclass == GETDNS_RRCLASS_CH &&
|
||||||
|
strcasecmp(qname_str, "version.bind.") == 0) {
|
||||||
|
const char *getdns_query_version = "getdns_query " GETDNS_VERSION;
|
||||||
|
char getdns_version[100] = "getdns ";
|
||||||
|
char getdns_api_version[100] = "getdns API ";
|
||||||
|
|
||||||
|
response = request;
|
||||||
|
(void) getdns_dict_set_bindata(response, "/answer/0/name", qname);
|
||||||
|
(void) getdns_dict_set_int(response, "/answer/0/type", qtype);
|
||||||
|
(void) getdns_dict_set_int(response, "/answer/0/class", qclass);
|
||||||
|
(void) getdns_dict_set_int(response, "/answer/0/ttl", 0);
|
||||||
|
(void) getdns_dict_util_set_string(response,
|
||||||
|
"/answer/0/rdata/txt_strings/0", getdns_query_version);
|
||||||
|
|
||||||
|
(void) getdns_dict_set_bindata(response, "/answer/1/name", qname);
|
||||||
|
(void) getdns_dict_set_int(response, "/answer/1/type", qtype);
|
||||||
|
(void) getdns_dict_set_int(response, "/answer/1/class", qclass);
|
||||||
|
(void) getdns_dict_set_int(response, "/answer/1/ttl", 0);
|
||||||
|
(void) strncat(getdns_version + 7,
|
||||||
|
getdns_get_version(), sizeof(getdns_version) - 8);
|
||||||
|
(void) getdns_dict_util_set_string(response,
|
||||||
|
"/answer/1/rdata/txt_strings/0",getdns_version);
|
||||||
|
|
||||||
|
(void) getdns_dict_set_bindata(response, "/answer/2/name", qname);
|
||||||
|
(void) getdns_dict_set_int(response, "/answer/2/type", qtype);
|
||||||
|
(void) getdns_dict_set_int(response, "/answer/2/class", qclass);
|
||||||
|
(void) getdns_dict_set_int(response, "/answer/2/ttl", 0);
|
||||||
|
(void) strncat(getdns_api_version + 11,
|
||||||
|
getdns_get_api_version(), sizeof(getdns_api_version) - 12);
|
||||||
|
(void) getdns_dict_util_set_string(response,
|
||||||
|
"/answer/2/rdata/txt_strings/0",getdns_api_version);
|
||||||
|
|
||||||
|
(void) getdns_dict_set_int(response, "/header/ancount", 3);
|
||||||
|
|
||||||
|
goto answer_request;
|
||||||
|
|
||||||
|
} else if ((r = getdns_general(context, qname_str, qtype,
|
||||||
qext, msg, &transaction_id, request_cb)))
|
qext, msg, &transaction_id, request_cb)))
|
||||||
fprintf(stderr, "Could not schedule query: %s\n",
|
fprintf(stderr, "Could not schedule query: %s\n",
|
||||||
getdns_get_errorstr_by_id(r));
|
getdns_get_errorstr_by_id(r));
|
||||||
|
@ -1624,9 +1660,8 @@ static void incoming_request_handler(getdns_context *context,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
error:
|
error:
|
||||||
if (qname_str)
|
|
||||||
free(qname_str);
|
|
||||||
servfail(msg, &response);
|
servfail(msg, &response);
|
||||||
|
answer_request:
|
||||||
#if defined(SERVER_DEBUG) && SERVER_DEBUG
|
#if defined(SERVER_DEBUG) && SERVER_DEBUG
|
||||||
do {
|
do {
|
||||||
char *request_str = getdns_pretty_print_dict(request);
|
char *request_str = getdns_pretty_print_dict(request);
|
||||||
|
@ -1643,13 +1678,17 @@ error:
|
||||||
/* Cancel reply */
|
/* Cancel reply */
|
||||||
getdns_reply(context, NULL, request_id);
|
getdns_reply(context, NULL, request_id);
|
||||||
}
|
}
|
||||||
|
if (response && response != request)
|
||||||
|
getdns_dict_destroy(response);
|
||||||
|
|
||||||
|
if (qname_str)
|
||||||
|
free(qname_str);
|
||||||
|
|
||||||
if (msg) {
|
if (msg) {
|
||||||
if (msg->request)
|
if (msg->request)
|
||||||
getdns_dict_destroy(msg->request);
|
getdns_dict_destroy(msg->request);
|
||||||
free(msg);
|
free(msg);
|
||||||
}
|
}
|
||||||
if (response)
|
|
||||||
getdns_dict_destroy(response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _getdns_query_log(void *userarg, uint64_t system,
|
static void _getdns_query_log(void *userarg, uint64_t system,
|
||||||
|
|
Loading…
Reference in New Issue