From 639239f45cb44c4fed0853320d9cbd7d0c63af0a Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 13 Mar 2017 14:20:47 +0100 Subject: [PATCH 01/21] Schedule dnsreqs with absolute timeout/expiry time --- src/dnssec.c | 3 ++- src/general.c | 19 +++++++++++-------- src/general.h | 2 +- src/request-internal.c | 8 +++++++- src/stub.c | 23 ++++++++++++----------- src/stub.h | 3 ++- src/types-internal.h | 7 ++++++- src/util-internal.h | 20 ++++++++++++++++++++ 8 files changed, 61 insertions(+), 24 deletions(-) diff --git a/src/dnssec.c b/src/dnssec.c index 0396f045..b689aba5 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -3032,6 +3032,7 @@ static void check_chain_complete(chain_head *chain) int r = GETDNS_RETURN_GOOD; getdns_network_req **netreq_p, *netreq; + uint64_t now_ms = 0; dnsreq->avoid_dnssec_roadblocks = 1; @@ -3041,7 +3042,7 @@ static void check_chain_complete(chain_head *chain) netreq->state = NET_REQ_NOT_SENT; netreq->owner = dnsreq; - r = _getdns_submit_netreq(netreq); + r = _getdns_submit_netreq(netreq, &now_ms); } return; } diff --git a/src/general.c b/src/general.c index 69dc7462..c71a4944 100644 --- a/src/general.c +++ b/src/general.c @@ -91,6 +91,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) { getdns_network_req **netreq_p, *netreq; int results_found = 0, r; + uint64_t now_ms = 0; for (netreq_p = dns_req->netreqs; (netreq = *netreq_p); netreq_p++) if (!_getdns_netreq_finished(netreq)) @@ -126,7 +127,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) ; (netreq = *netreq_p) ; netreq_p++ ) { _getdns_netreq_reinit(netreq); - if ((r = _getdns_submit_netreq(netreq))) { + if ((r = _getdns_submit_netreq(netreq, &now_ms))) { if (r == DNS_REQ_FINISHED) return; netreq->state = NET_REQ_FINISHED; @@ -164,7 +165,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) ; (netreq = *netreq_p) ; netreq_p++ ) { _getdns_netreq_reinit(netreq); - if ((r = _getdns_submit_netreq(netreq))) { + if ((r = _getdns_submit_netreq(netreq, &now_ms))) { if (r == DNS_REQ_FINISHED) return; netreq->state = NET_REQ_FINISHED; @@ -248,7 +249,7 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res) int -_getdns_submit_netreq(getdns_network_req *netreq) +_getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms) { getdns_return_t r; getdns_dns_req *dns_req = netreq->owner; @@ -284,7 +285,8 @@ _getdns_submit_netreq(getdns_network_req *netreq) _getdns_context_request_timed_out; dns_req->timeout.ev = NULL; if ((r = dns_req->loop->vmt->schedule(dns_req->loop, -1, - dns_req->context->timeout, &dns_req->timeout))) + _getdns_ms_until_expiry2(dns_req->expires, now_ms), + &dns_req->timeout))) return r; } (void) gldns_wire2str_dname_buf(dns_req->name, @@ -314,7 +316,7 @@ _getdns_submit_netreq(getdns_network_req *netreq) } /* Submit with stub resolver */ dns_req->freed = &dnsreq_freed; - r = _getdns_submit_stub_request(netreq); + r = _getdns_submit_stub_request(netreq, now_ms); if (dnsreq_freed) return DNS_REQ_FINISHED; dns_req->freed = NULL; @@ -413,6 +415,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, getdns_dns_req *req; getdns_dict *localnames_response; size_t i; + uint64_t now_ms = 0; if (!context || !name || (!callbackfn && !internal_cb)) return GETDNS_RETURN_INVALID_PARAMETER; @@ -430,7 +433,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, /* create the request */ if (!(req = _getdns_dns_req_new( - context, loop, name, request_type, extensions))) + context, loop, name, request_type, extensions, &now_ms))) return GETDNS_RETURN_MEMORY_ERROR; req->user_pointer = userarg; @@ -448,7 +451,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, for ( netreq_p = req->netreqs ; !r && (netreq = *netreq_p) ; netreq_p++) { - if ((r = _getdns_submit_netreq(netreq))) { + if ((r = _getdns_submit_netreq(netreq, &now_ms))) { if (r == DNS_REQ_FINISHED) { if (return_netreq_p) *return_netreq_p = NULL; @@ -500,7 +503,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, for ( netreq_p = req->netreqs ; !r && (netreq = *netreq_p) ; netreq_p++) { - if ((r = _getdns_submit_netreq(netreq))) { + if ((r = _getdns_submit_netreq(netreq, &now_ms))) { if (r == DNS_REQ_FINISHED) { if (return_netreq_p) *return_netreq_p = NULL; diff --git a/src/general.h b/src/general.h index 29b52f47..dcd9b9be 100644 --- a/src/general.h +++ b/src/general.h @@ -46,7 +46,7 @@ void _getdns_call_user_callback(getdns_dns_req *, getdns_dict *); void _getdns_check_dns_req_complete(getdns_dns_req *dns_req); -int _getdns_submit_netreq(getdns_network_req *netreq); +int _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms); getdns_return_t diff --git a/src/request-internal.c b/src/request-internal.c index eae467e9..6c9cd9ec 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -658,7 +658,8 @@ static const uint8_t no_suffixes[] = { 1, 0 }; /* create a new dns req to be submitted */ getdns_dns_req * _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, - const char *name, uint16_t request_type, getdns_dict *extensions) + const char *name, uint16_t request_type, getdns_dict *extensions, + uint64_t *now_ms) { int dnssec_return_status = is_extension_set( extensions, "dnssec_return_status", @@ -953,5 +954,10 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, netreq_sz - sizeof(getdns_network_req), max_query_sz, extensions); + if (*now_ms == 0 && (*now_ms = _getdns_get_now_ms()) == 0) + result->expires = 0; + else + result->expires = *now_ms + context->timeout; + return result; } diff --git a/src/stub.c b/src/stub.c index e905f600..f7f1fddb 100644 --- a/src/stub.c +++ b/src/stub.c @@ -1358,8 +1358,8 @@ stub_udp_read_cb(void *userarg) dnsreq)) == -1) break; upstream_schedule_netreq(netreq->upstream, netreq); - GETDNS_SCHEDULE_EVENT( - dnsreq->loop, -1, dnsreq->context->timeout, + GETDNS_SCHEDULE_EVENT(dnsreq->loop, -1, + _getdns_ms_until_expiry(dnsreq->expires), getdns_eventloop_event_init(&netreq->event, netreq, NULL, NULL, stub_timeout_cb)); @@ -1421,8 +1421,8 @@ stub_udp_write_cb(void *userarg) #endif return; } - GETDNS_SCHEDULE_EVENT( - dnsreq->loop, netreq->fd, dnsreq->context->timeout, + GETDNS_SCHEDULE_EVENT(dnsreq->loop, netreq->fd, + _getdns_ms_until_expiry(dnsreq->expires), getdns_eventloop_event_init(&netreq->event, netreq, stub_udp_read_cb, NULL, stub_timeout_cb)); } @@ -1928,12 +1928,13 @@ upstream_find_for_netreq(getdns_network_req *netreq) static int fallback_on_write(getdns_network_req *netreq) { + uint64_t now_ms = 0; /* Deal with UDP one day*/ DEBUG_STUB("%s %-35s: MSG: %p FALLING BACK \n", STUB_DEBUG_SCHEDULE, __FUNC__, (void*)netreq); /* Try to find a fallback transport*/ - getdns_return_t result = _getdns_submit_stub_request(netreq); + getdns_return_t result = _getdns_submit_stub_request(netreq, &now_ms); if (result != GETDNS_RETURN_GOOD) return STUB_TCP_ERROR; @@ -1997,8 +1998,8 @@ upstream_schedule_netreq(getdns_upstream *upstream, getdns_network_req *netreq) if (upstream->queries_sent == 0) { /* Set a timeout on the upstream so we can catch failed setup*/ upstream->event.timeout_cb = upstream_setup_timeout_cb; - GETDNS_SCHEDULE_EVENT(upstream->loop, - upstream->fd, netreq->owner->context->timeout / 2, + GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd, + _getdns_ms_until_expiry(netreq->owner->expires)/2, &upstream->event); } else { GETDNS_SCHEDULE_EVENT(upstream->loop, @@ -2027,7 +2028,7 @@ upstream_schedule_netreq(getdns_upstream *upstream, getdns_network_req *netreq) } getdns_return_t -_getdns_submit_stub_request(getdns_network_req *netreq) +_getdns_submit_stub_request(getdns_network_req *netreq, uint64_t *now_ms) { DEBUG_STUB("%s %-35s: MSG: %p TYPE: %d\n", STUB_DEBUG_ENTRY, __FUNC__, (void*)netreq, netreq->request_type); @@ -2046,8 +2047,8 @@ _getdns_submit_stub_request(getdns_network_req *netreq) case GETDNS_TRANSPORT_UDP: netreq->fd = fd; GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event); - GETDNS_SCHEDULE_EVENT( - dnsreq->loop, netreq->fd, dnsreq->context->timeout, + GETDNS_SCHEDULE_EVENT(dnsreq->loop, netreq->fd, + _getdns_ms_until_expiry2(dnsreq->expires, now_ms), getdns_eventloop_event_init(&netreq->event, netreq, NULL, stub_udp_write_cb, stub_timeout_cb)); return GETDNS_RETURN_GOOD; @@ -2121,7 +2122,7 @@ _getdns_submit_stub_request(getdns_network_req *netreq) */ GETDNS_SCHEDULE_EVENT( dnsreq->loop, -1, - dnsreq->context->timeout, + _getdns_ms_until_expiry2(dnsreq->expires, now_ms), getdns_eventloop_event_init( &netreq->event, netreq, NULL, NULL, stub_timeout_cb)); diff --git a/src/stub.h b/src/stub.h index 41aa629a..da45eded 100644 --- a/src/stub.h +++ b/src/stub.h @@ -37,7 +37,8 @@ #include "getdns/getdns.h" #include "types-internal.h" -getdns_return_t _getdns_submit_stub_request(getdns_network_req *netreq); +getdns_return_t _getdns_submit_stub_request( + getdns_network_req *netreq, uint64_t *now_ms); void _getdns_cancel_stub_request(getdns_network_req *netreq); diff --git a/src/types-internal.h b/src/types-internal.h index 78f1935a..9afb105d 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -338,6 +338,11 @@ typedef struct getdns_dns_req { /* the transaction id */ getdns_transaction_t trans_id; + /* Absolute time (in miliseconds since epoch), + * after which this dns request is expired; i.e. timed out + */ + uint64_t expires; + /* for scheduling timeouts when using libunbound */ getdns_eventloop_event timeout; @@ -408,7 +413,7 @@ extern getdns_dict *dnssec_ok_checking_disabled_avoid_roadblocks; /* dns request utils */ getdns_dns_req *_getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, - const char *name, uint16_t request_type, getdns_dict *extensions); + const char *name, uint16_t request_type, getdns_dict *extensions, uint64_t *now_ms); void _getdns_dns_req_free(getdns_dns_req * req); diff --git a/src/util-internal.h b/src/util-internal.h index 54c81d9d..6f8de235 100644 --- a/src/util-internal.h +++ b/src/util-internal.h @@ -198,5 +198,25 @@ INLINE void _dname_canonicalize2(uint8_t *dname) _dname_canonicalize(dname, dname); } +INLINE uint64_t _getdns_get_now_ms() +{ + struct timeval tv; + + (void) gettimeofday(&tv, NULL); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +INLINE uint64_t _getdns_ms_until_expiry(uint64_t expires) +{ + uint64_t now_ms = _getdns_get_now_ms(); + return now_ms >= expires ? 0 : expires - now_ms; +} + +INLINE uint64_t _getdns_ms_until_expiry2(uint64_t expires, uint64_t *now_ms) +{ + if (*now_ms == 0) *now_ms = _getdns_get_now_ms(); + return *now_ms >= expires ? 0 : expires - *now_ms; +} + #endif /* util-internal.h */ From 0655a08fa7a1b050151ba73a2669adf3ec488899 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 14 Mar 2017 15:03:43 +0100 Subject: [PATCH 02/21] Unit test for set_limit_outstanding_queries --- .../280-limit_outstanding_queries.Makefile | 15 + .../280-limit_outstanding_queries.c | 136 +++ .../280-limit_outstanding_queries.dsc | 16 + .../280-limit_outstanding_queries.pre | 14 + .../280-limit_outstanding_queries.queries | 1000 +++++++++++++++++ .../280-limit_outstanding_queries.test | 21 + 6 files changed, 1202 insertions(+) create mode 100644 src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.Makefile create mode 100644 src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.c create mode 100644 src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.dsc create mode 100644 src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.pre create mode 100644 src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.queries create mode 100644 src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test diff --git a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.Makefile b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.Makefile new file mode 100644 index 00000000..c297df6d --- /dev/null +++ b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.Makefile @@ -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 $(testname) $(testname).lo + diff --git a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.c b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.c new file mode 100644 index 00000000..78107b57 --- /dev/null +++ b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.c @@ -0,0 +1,136 @@ +/* + * delaydns.c - A DNS proxy that adds delay to replies + * + * Copyright (c) 2016, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * 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 name of the NLNET LABS 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 THE COPYRIGHT + * HOLDER OR CONTRIBUTORS 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. + */ + +#include +#include +#include + + +static int n_requests = 0; + +typedef struct transaction_t { + getdns_transaction_t request_id; + getdns_dict *request; + + getdns_context *context; + getdns_eventloop *loop; + getdns_eventloop_event ev; +} transaction_t; + + +void delay_cb(void *userarg) +{ + transaction_t *trans = userarg; + + trans->loop->vmt->clear(trans->loop, &trans->ev); + (void) getdns_reply(trans->context, trans->request, trans->request_id); + getdns_dict_destroy(trans->request); + free(trans); + n_requests -= 1; +} + +void handler(getdns_context *context, getdns_callback_type_t callback_type, + getdns_dict *request, void *userarg, getdns_transaction_t request_id) +{ + transaction_t *trans; + getdns_bindata *qname; + char nreq_str[255]; + getdns_bindata nreq_bd = { 0, nreq_str }; + + (void) userarg; + nreq_bd.size = snprintf(nreq_str, sizeof(nreq_str), "n_requests: %d", ++n_requests); + + if (getdns_dict_get_bindata(request, "/question/qname", &qname) || + getdns_dict_set_bindata(request, "/answer/0/name", qname) || + getdns_dict_set_int(request, "/answer/0/type", GETDNS_RRTYPE_TXT) || + getdns_dict_set_bindata(request, "/answer/0/rdata/txt_strings/-", &nreq_bd)) + fprintf(stderr, "Request init error\n"); + + else if (qname->size >= 6 && qname->data[0] == 4 && + qname->data[1] == 'q' && qname->data[2] == 'u' && + qname->data[3] == 'i' && qname->data[4] == 't') { + + (void) getdns_reply(context, request, request_id); + (void) getdns_context_set_listen_addresses(trans->context, NULL, NULL, NULL); + n_requests -= 1; + return; + + } else if (!(trans = malloc(sizeof(transaction_t)))) + perror("memerror"); + else { + (void) memset(trans, 0, sizeof(transaction_t)); + trans->request_id = request_id; + trans->request = request; + trans->context = context; + trans->ev.userarg = trans; + trans->ev.timeout_cb = delay_cb; + + if (getdns_context_get_eventloop(context, &trans->loop) + || trans->loop->vmt->schedule(trans->loop, -1, 300, &trans->ev)) + fprintf(stderr, "Could not schedule delay\n"); + else return; + } + exit(EXIT_FAILURE); +} + +int main() +{ + getdns_context *context = NULL; + getdns_list *listeners = NULL; + getdns_dict *address = NULL; + uint32_t port = 18000; + getdns_return_t r; + + if ((r = getdns_str2list("[ 127.0.0.1:18000 ]", &listeners)) || + (r = getdns_list_get_dict(listeners, 0, &address)) || + (r = getdns_context_create(&context, 0))) + fprintf(stderr, "Error initializing: "); + + else while (++port < 18200 && + !(r = getdns_dict_set_int(address, "port", port)) && + (r = getdns_context_set_listen_addresses( + context, listeners, NULL, handler))) + ; /* pass */ + + if (r) fprintf(stderr, "%s\n", getdns_get_errorstr_by_id(r)); + else { + fprintf(stdout, "%d\n", (int)port); + fflush(stdout); + getdns_context_run(context); + } + getdns_list_destroy(listeners); + getdns_context_destroy(context); + return r; +} diff --git a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.dsc b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.dsc new file mode 100644 index 00000000..f1f0aa4b --- /dev/null +++ b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.dsc @@ -0,0 +1,16 @@ +BaseName: 280-limit_outstanding_queries +Version: 1.0 +Description: Test if outstanding queries setting is obeyed +CreationDate: Tue Mar 14 10:43:45 CET 2017 +Maintainer: Willem Toorop +Category: +Component: +CmdDepends: +Depends: 210-stub-only-link.tpkg +Help: +Pre: 280-limit_outstanding_queries.pre +Post: +Test: 280-limit_outstanding_queries.test +AuxFiles: +Passed: +Failure: diff --git a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.pre b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.pre new file mode 100644 index 00000000..b4ee91ac --- /dev/null +++ b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.pre @@ -0,0 +1,14 @@ +# #-- 280-limit_outstanding_queries.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 diff --git a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.queries b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.queries new file mode 100644 index 00000000..0cc2103d --- /dev/null +++ b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.queries @@ -0,0 +1,1000 @@ +q1. +q2. +q3. +q4. +q5. +q6. +q7. +q8. +q9. +q10. +q11. +q12. +q13. +q14. +q15. +q16. +q17. +q18. +q19. +q20. +q21. +q22. +q23. +q24. +q25. +q26. +q27. +q28. +q29. +q30. +q31. +q32. +q33. +q34. +q35. +q36. +q37. +q38. +q39. +q40. +q41. +q42. +q43. +q44. +q45. +q46. +q47. +q48. +q49. +q50. +q51. +q52. +q53. +q54. +q55. +q56. +q57. +q58. +q59. +q60. +q61. +q62. +q63. +q64. +q65. +q66. +q67. +q68. +q69. +q70. +q71. +q72. +q73. +q74. +q75. +q76. +q77. +q78. +q79. +q80. +q81. +q82. +q83. +q84. +q85. +q86. +q87. +q88. +q89. +q90. +q91. +q92. +q93. +q94. +q95. +q96. +q97. +q98. +q99. +q100. +q101. +q102. +q103. +q104. +q105. +q106. +q107. +q108. +q109. +q110. +q111. +q112. +q113. +q114. +q115. +q116. +q117. +q118. +q119. +q120. +q121. +q122. +q123. +q124. +q125. +q126. +q127. +q128. +q129. +q130. +q131. +q132. +q133. +q134. +q135. +q136. +q137. +q138. +q139. +q140. +q141. +q142. +q143. +q144. +q145. +q146. +q147. +q148. +q149. +q150. +q151. +q152. +q153. +q154. +q155. +q156. +q157. +q158. +q159. +q160. +q161. +q162. +q163. +q164. +q165. +q166. +q167. +q168. +q169. +q170. +q171. +q172. +q173. +q174. +q175. +q176. +q177. +q178. +q179. +q180. +q181. +q182. +q183. +q184. +q185. +q186. +q187. +q188. +q189. +q190. +q191. +q192. +q193. +q194. +q195. +q196. +q197. +q198. +q199. +q200. +q201. +q202. +q203. +q204. +q205. +q206. +q207. +q208. +q209. +q210. +q211. +q212. +q213. +q214. +q215. +q216. +q217. +q218. +q219. +q220. +q221. +q222. +q223. +q224. +q225. +q226. +q227. +q228. +q229. +q230. +q231. +q232. +q233. +q234. +q235. +q236. +q237. +q238. +q239. +q240. +q241. +q242. +q243. +q244. +q245. +q246. +q247. +q248. +q249. +q250. +q251. +q252. +q253. +q254. +q255. +q256. +q257. +q258. +q259. +q260. +q261. +q262. +q263. +q264. +q265. +q266. +q267. +q268. +q269. +q270. +q271. +q272. +q273. +q274. +q275. +q276. +q277. +q278. +q279. +q280. +q281. +q282. +q283. +q284. +q285. +q286. +q287. +q288. +q289. +q290. +q291. +q292. +q293. +q294. +q295. +q296. +q297. +q298. +q299. +q300. +q301. +q302. +q303. +q304. +q305. +q306. +q307. +q308. +q309. +q310. +q311. +q312. +q313. +q314. +q315. +q316. +q317. +q318. +q319. +q320. +q321. +q322. +q323. +q324. +q325. +q326. +q327. +q328. +q329. +q330. +q331. +q332. +q333. +q334. +q335. +q336. +q337. +q338. +q339. +q340. +q341. +q342. +q343. +q344. +q345. +q346. +q347. +q348. +q349. +q350. +q351. +q352. +q353. +q354. +q355. +q356. +q357. +q358. +q359. +q360. +q361. +q362. +q363. +q364. +q365. +q366. +q367. +q368. +q369. +q370. +q371. +q372. +q373. +q374. +q375. +q376. +q377. +q378. +q379. +q380. +q381. +q382. +q383. +q384. +q385. +q386. +q387. +q388. +q389. +q390. +q391. +q392. +q393. +q394. +q395. +q396. +q397. +q398. +q399. +q400. +q401. +q402. +q403. +q404. +q405. +q406. +q407. +q408. +q409. +q410. +q411. +q412. +q413. +q414. +q415. +q416. +q417. +q418. +q419. +q420. +q421. +q422. +q423. +q424. +q425. +q426. +q427. +q428. +q429. +q430. +q431. +q432. +q433. +q434. +q435. +q436. +q437. +q438. +q439. +q440. +q441. +q442. +q443. +q444. +q445. +q446. +q447. +q448. +q449. +q450. +q451. +q452. +q453. +q454. +q455. +q456. +q457. +q458. +q459. +q460. +q461. +q462. +q463. +q464. +q465. +q466. +q467. +q468. +q469. +q470. +q471. +q472. +q473. +q474. +q475. +q476. +q477. +q478. +q479. +q480. +q481. +q482. +q483. +q484. +q485. +q486. +q487. +q488. +q489. +q490. +q491. +q492. +q493. +q494. +q495. +q496. +q497. +q498. +q499. +q500. +q501. +q502. +q503. +q504. +q505. +q506. +q507. +q508. +q509. +q510. +q511. +q512. +q513. +q514. +q515. +q516. +q517. +q518. +q519. +q520. +q521. +q522. +q523. +q524. +q525. +q526. +q527. +q528. +q529. +q530. +q531. +q532. +q533. +q534. +q535. +q536. +q537. +q538. +q539. +q540. +q541. +q542. +q543. +q544. +q545. +q546. +q547. +q548. +q549. +q550. +q551. +q552. +q553. +q554. +q555. +q556. +q557. +q558. +q559. +q560. +q561. +q562. +q563. +q564. +q565. +q566. +q567. +q568. +q569. +q570. +q571. +q572. +q573. +q574. +q575. +q576. +q577. +q578. +q579. +q580. +q581. +q582. +q583. +q584. +q585. +q586. +q587. +q588. +q589. +q590. +q591. +q592. +q593. +q594. +q595. +q596. +q597. +q598. +q599. +q600. +q601. +q602. +q603. +q604. +q605. +q606. +q607. +q608. +q609. +q610. +q611. +q612. +q613. +q614. +q615. +q616. +q617. +q618. +q619. +q620. +q621. +q622. +q623. +q624. +q625. +q626. +q627. +q628. +q629. +q630. +q631. +q632. +q633. +q634. +q635. +q636. +q637. +q638. +q639. +q640. +q641. +q642. +q643. +q644. +q645. +q646. +q647. +q648. +q649. +q650. +q651. +q652. +q653. +q654. +q655. +q656. +q657. +q658. +q659. +q660. +q661. +q662. +q663. +q664. +q665. +q666. +q667. +q668. +q669. +q670. +q671. +q672. +q673. +q674. +q675. +q676. +q677. +q678. +q679. +q680. +q681. +q682. +q683. +q684. +q685. +q686. +q687. +q688. +q689. +q690. +q691. +q692. +q693. +q694. +q695. +q696. +q697. +q698. +q699. +q700. +q701. +q702. +q703. +q704. +q705. +q706. +q707. +q708. +q709. +q710. +q711. +q712. +q713. +q714. +q715. +q716. +q717. +q718. +q719. +q720. +q721. +q722. +q723. +q724. +q725. +q726. +q727. +q728. +q729. +q730. +q731. +q732. +q733. +q734. +q735. +q736. +q737. +q738. +q739. +q740. +q741. +q742. +q743. +q744. +q745. +q746. +q747. +q748. +q749. +q750. +q751. +q752. +q753. +q754. +q755. +q756. +q757. +q758. +q759. +q760. +q761. +q762. +q763. +q764. +q765. +q766. +q767. +q768. +q769. +q770. +q771. +q772. +q773. +q774. +q775. +q776. +q777. +q778. +q779. +q780. +q781. +q782. +q783. +q784. +q785. +q786. +q787. +q788. +q789. +q790. +q791. +q792. +q793. +q794. +q795. +q796. +q797. +q798. +q799. +q800. +q801. +q802. +q803. +q804. +q805. +q806. +q807. +q808. +q809. +q810. +q811. +q812. +q813. +q814. +q815. +q816. +q817. +q818. +q819. +q820. +q821. +q822. +q823. +q824. +q825. +q826. +q827. +q828. +q829. +q830. +q831. +q832. +q833. +q834. +q835. +q836. +q837. +q838. +q839. +q840. +q841. +q842. +q843. +q844. +q845. +q846. +q847. +q848. +q849. +q850. +q851. +q852. +q853. +q854. +q855. +q856. +q857. +q858. +q859. +q860. +q861. +q862. +q863. +q864. +q865. +q866. +q867. +q868. +q869. +q870. +q871. +q872. +q873. +q874. +q875. +q876. +q877. +q878. +q879. +q880. +q881. +q882. +q883. +q884. +q885. +q886. +q887. +q888. +q889. +q890. +q891. +q892. +q893. +q894. +q895. +q896. +q897. +q898. +q899. +q900. +q901. +q902. +q903. +q904. +q905. +q906. +q907. +q908. +q909. +q910. +q911. +q912. +q913. +q914. +q915. +q916. +q917. +q918. +q919. +q920. +q921. +q922. +q923. +q924. +q925. +q926. +q927. +q928. +q929. +q930. +q931. +q932. +q933. +q934. +q935. +q936. +q937. +q938. +q939. +q940. +q941. +q942. +q943. +q944. +q945. +q946. +q947. +q948. +q949. +q950. +q951. +q952. +q953. +q954. +q955. +q956. +q957. +q958. +q959. +q960. +q961. +q962. +q963. +q964. +q965. +q966. +q967. +q968. +q969. +q970. +q971. +q972. +q973. +q974. +q975. +q976. +q977. +q978. +q979. +q980. +q981. +q982. +q983. +q984. +q985. +q986. +q987. +q988. +q989. +q990. +q991. +q992. +q993. +q994. +q995. +q996. +q997. +q998. +q999. +q1000. diff --git a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test new file mode 100644 index 00000000..828d0a96 --- /dev/null +++ b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test @@ -0,0 +1,21 @@ +# #-- 280-limit_outstanding_queries.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 + +QLIMIT=10 +make && "./${TPKG_NAME}" | ( + read PORT + ${GETDNS_STUB_QUERY} @127.0.0.1:$PORT TXT \ + -a -F "./${TPKG_NAME}.queries" \ + "{limit_outstanding_queries:$QLIMIT}" 2>&1 > out + + ${GETDNS_STUB_QUERY} -q @127.0.0.1:$PORT TXT quit. +) && grep '"n_requests: [0-9][0-9]*"' out | sed -e 's/^.*n_requests: //g' -e 's/".*$//g' \ + | awk -vQLIMIT=$QLIMIT '{ + if ($1 > QLIMIT) { + print "ERROR: More than "QLIMIT" outstanding queries!"; + exit(-1); + } +}' && echo "SUCCESS: No more than ${QLIMIT} outstanding queries" From b8f43c8acd81f4b61c4e584a83341740d3a6f2f0 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 14 Mar 2017 15:20:56 +0100 Subject: [PATCH 03/21] Mention the number of simultaneous queries in error (and success) --- .../280-limit_outstanding_queries.test | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test index 828d0a96..d033f6ee 100644 --- a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test +++ b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test @@ -13,9 +13,19 @@ make && "./${TPKG_NAME}" | ( ${GETDNS_STUB_QUERY} -q @127.0.0.1:$PORT TXT quit. ) && grep '"n_requests: [0-9][0-9]*"' out | sed -e 's/^.*n_requests: //g' -e 's/".*$//g' \ - | awk -vQLIMIT=$QLIMIT '{ - if ($1 > QLIMIT) { - print "ERROR: More than "QLIMIT" outstanding queries!"; + | awk -vQLIMIT=$QLIMIT ' + +BEGIN{ + max_outstanding = 0; +} +{ + if ($1 > max_outstanding) + max_outstanding = $1; +} +END{ + if (max_outstanding > QLIMIT) { + print "ERROR: More than "QLIMIT" outstanding queries: "max_outstanding; exit(-1); - } -}' && echo "SUCCESS: No more than ${QLIMIT} outstanding queries" + } else + print "SUCCESS: No more than "QLIMIT" outstanding queries: "max_outstanding; +}' From 14c9f3aafcf9c41778d1224060ae7b9bb0ee9eaf Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 14 Mar 2017 17:17:56 +0100 Subject: [PATCH 04/21] Track netreqs "in flight" --- src/context.c | 23 +++++++++++++++++++ src/context.h | 17 +++++++++++++- src/dnssec.c | 2 +- src/general.c | 16 +++++++------ src/mdns.c | 4 ++-- src/request-internal.c | 6 ++++- src/stub.c | 10 ++++---- .../280-limit_outstanding_queries.test | 4 +++- 8 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/context.c b/src/context.c index 5421fd81..1f739fff 100644 --- a/src/context.c +++ b/src/context.c @@ -1330,6 +1330,8 @@ getdns_context_create_with_extended_memory_functions( _getdns_rbtree_init(&result->outbound_requests, transaction_id_cmp); _getdns_rbtree_init(&result->local_hosts, local_host_cmp); + /* TODO: Initialize pending_netreqs */ + result->netreqs_in_flight = 0; result->server = NULL; @@ -2980,6 +2982,27 @@ _getdns_context_request_timed_out(getdns_dns_req *dnsreq) _getdns_context_cancel_request(dnsreq); } + +void +_getdns_netreq_change_state(getdns_network_req *netreq, network_req_state new_state) +{ + if (!netreq) + return; + + if (netreq->state != NET_REQ_IN_FLIGHT) { + if (new_state == NET_REQ_IN_FLIGHT) + netreq->owner->context->netreqs_in_flight += 1; + netreq->state = new_state; + return; + } + if (new_state == NET_REQ_IN_FLIGHT) /* No change */ + return; + netreq->state = new_state; + netreq->owner->context->netreqs_in_flight -= 1; + /* TODO: Schedule pending netreqs + * when netreqs_in_flight < oustanding_queries */ +} + static void accumulate_outstanding_transactions(_getdns_rbnode_t *node, void* arg) { diff --git a/src/context.h b/src/context.h index e6ed49fb..6fe02d23 100644 --- a/src/context.h +++ b/src/context.h @@ -291,6 +291,11 @@ struct getdns_context { */ _getdns_rbtree_t outbound_requests; + /* network requests + */ + size_t netreqs_in_flight; + _getdns_rbtree_t pending_netreqs; + struct listen_set *server; /* Event loop extension. */ @@ -372,12 +377,22 @@ void _getdns_context_clear_outbound_request(getdns_dns_req *dnsreq); */ void _getdns_context_cancel_request(getdns_dns_req *dnsreq); - /* Calls user callback (with GETDNS_CALLBACK_TIMEOUT + response dict), then * cancels and frees the getdns_dns_req with _getdns_context_cancel_request() */ void _getdns_context_request_timed_out(getdns_dns_req *dnsreq); +/* Change state of the netreq req. + * - Increments context->netreqs_in_flight + * when state changes from NOT_SENT to IN_FLIGHT + * - Decrements context->netreqs_in_flight + * when state changes from IN_FLIGHT to FINISHED, TIMED_OUT or ERRORED + * - Resubmits NOT_SENT netreqs from context->pending_netreqs, + * when # pending_netreqs < limit_outstanding_queries + */ +void _getdns_netreq_change_state( + getdns_network_req *req, network_req_state new_state); + char *_getdns_strdup(const struct mem_funcs *mfs, const char *str); struct getdns_bindata *_getdns_bindata_copy( diff --git a/src/dnssec.c b/src/dnssec.c index b689aba5..b3e86bae 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -3040,7 +3040,7 @@ static void check_chain_complete(chain_head *chain) ; !r && (netreq = *netreq_p) ; netreq_p++) { - netreq->state = NET_REQ_NOT_SENT; + _getdns_netreq_change_state(netreq, NET_REQ_NOT_SENT); netreq->owner = dnsreq; r = _getdns_submit_netreq(netreq, &now_ms); } diff --git a/src/general.c b/src/general.c index c71a4944..3781e1da 100644 --- a/src/general.c +++ b/src/general.c @@ -130,7 +130,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) if ((r = _getdns_submit_netreq(netreq, &now_ms))) { if (r == DNS_REQ_FINISHED) return; - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_ERRORED); } } _getdns_check_dns_req_complete(dns_req); @@ -168,7 +168,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) if ((r = _getdns_submit_netreq(netreq, &now_ms))) { if (r == DNS_REQ_FINISHED) return; - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_ERRORED); } } _getdns_check_dns_req_complete(dns_req); @@ -209,7 +209,7 @@ ub_resolve_event_callback(void* arg, int rcode, void *pkt, int pkt_len, getdns_network_req *netreq = (getdns_network_req *) arg; getdns_dns_req *dns_req = netreq->owner; - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_FINISHED); /* parse */ if (getdns_apply_network_result( netreq, rcode, pkt, pkt_len, sec, why_bogus)) { @@ -227,7 +227,7 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res) getdns_network_req *netreq = (getdns_network_req *) arg; getdns_dns_req *dns_req = netreq->owner; - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_FINISHED); if (err != 0) { _getdns_call_user_callback(dns_req, NULL); return; @@ -259,6 +259,8 @@ _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms) int ub_resolve_r; #endif + _getdns_netreq_change_state(netreq, NET_REQ_IN_FLIGHT); + #ifdef STUB_NATIVE_DNSSEC # ifdef DNSSEC_ROADBLOCK_AVOIDANCE @@ -457,7 +459,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, *return_netreq_p = NULL; return GETDNS_RETURN_GOOD; } - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_ERRORED); } } @@ -486,7 +488,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, *return_netreq_p = NULL; return GETDNS_RETURN_GOOD; } - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_ERRORED); } } /* Stop processing more namespaces, since there was a match */ @@ -509,7 +511,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, *return_netreq_p = NULL; return GETDNS_RETURN_GOOD; } - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_ERRORED); } } break; diff --git a/src/mdns.c b/src/mdns.c index 253bf972..441701c0 100644 --- a/src/mdns.c +++ b/src/mdns.c @@ -121,7 +121,7 @@ mdns_timeout_cb(void *userarg) #else close(netreq->fd); #endif - netreq->state = NET_REQ_TIMED_OUT; + _getdns_netreq_change_state(netreq, NET_REQ_TIMED_OUT); if (netreq->owner->user_callback) { netreq->debug_end_time = _getdns_get_time_as_uintt64(); (void)_getdns_context_request_timed_out(netreq->owner); @@ -182,7 +182,7 @@ mdns_udp_read_cb(void *userarg) netreq->response_len = read; netreq->debug_end_time = _getdns_get_time_as_uintt64(); - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_FINISHED); _getdns_check_dns_req_complete(dnsreq); } diff --git a/src/request-internal.c b/src/request-internal.c index 6c9cd9ec..8eec6b7a 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -118,7 +118,7 @@ netreq_reset(getdns_network_req *net_req) /* variables that need to be reset on reinit */ net_req->unbound_id = -1; - net_req->state = NET_REQ_NOT_SENT; + _getdns_netreq_change_state(net_req, NET_REQ_NOT_SENT); net_req->dnssec_status = GETDNS_DNSSEC_INDETERMINATE; net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE; net_req->query_id = 0; @@ -183,6 +183,10 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner, net_req->debug_tls_auth_status = GETDNS_AUTH_NONE; net_req->debug_udp = 0; + /* Scheduling, touch only via _getdns_netreq_change_state! + */ + net_req->state = NET_REQ_NOT_SENT; + if (max_query_sz == 0) { net_req->query = NULL; net_req->opt = NULL; diff --git a/src/stub.c b/src/stub.c index f7f1fddb..1fefaa8c 100644 --- a/src/stub.c +++ b/src/stub.c @@ -550,7 +550,7 @@ upstream_failed(getdns_upstream *upstream, int during_setup) netreq = (getdns_network_req *) _getdns_rbtree_first(&upstream->netreq_by_query_id); stub_cleanup(netreq); - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_FINISHED); _getdns_check_dns_req_complete(netreq->owner); } } @@ -580,7 +580,7 @@ stub_timeout_cb(void *userarg) DEBUG_STUB("%s %-35s: MSG: %p\n", STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq); stub_cleanup(netreq); - netreq->state = NET_REQ_TIMED_OUT; + _getdns_netreq_change_state(netreq, NET_REQ_TIMED_OUT); /* Handle upstream*/ if (netreq->fd >= 0) { #ifdef USE_WINSOCK @@ -1368,7 +1368,7 @@ stub_udp_read_cb(void *userarg) netreq->response_len = read; dnsreq->upstreams->current_udp = 0; netreq->debug_end_time = _getdns_get_time_as_uintt64(); - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_FINISHED); upstream->udp_responses++; #if defined(DAEMON_DEBUG) && DAEMON_DEBUG if (upstream->udp_responses == 1 || @@ -1495,7 +1495,7 @@ upstream_read_cb(void *userarg) DEBUG_STUB("%s %-35s: MSG: %p (read)\n", STUB_DEBUG_READ, __FUNC__, (void*)netreq); - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_FINISHED); netreq->response = upstream->tcp.read_buf; netreq->response_len = upstream->tcp.read_pos - upstream->tcp.read_buf; @@ -1614,7 +1614,7 @@ upstream_write_cb(void *userarg) #endif if (fallback_on_write(netreq) == STUB_TCP_ERROR) { /* TODO: Need new state to report transport unavailable*/ - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_FINISHED); _getdns_check_dns_req_complete(netreq->owner); } return; diff --git a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test index d033f6ee..37915e43 100644 --- a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test +++ b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test @@ -4,7 +4,9 @@ # use .tpkg.var.test for in test variable passing [ -f .tpkg.var.test ] && source .tpkg.var.test -QLIMIT=10 +# TODO: Change QLIMIT to 10 once implement pending netreq resubmission +# +QLIMIT=1000 make && "./${TPKG_NAME}" | ( read PORT ${GETDNS_STUB_QUERY} @127.0.0.1:$PORT TXT \ From 5ea181172a6325ecb6996295948f7e1b2ff33694 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 15 Mar 2017 15:16:42 +0100 Subject: [PATCH 05/21] Reschedule pending netreqs --- src/context.c | 50 ++++---- src/context.h | 16 +-- src/general.c | 114 ++++++++++++++++-- src/general.h | 12 ++ src/request-internal.c | 1 + .../280-limit_outstanding_queries.test | 15 ++- 6 files changed, 159 insertions(+), 49 deletions(-) diff --git a/src/context.c b/src/context.c index 1f739fff..aabe13f5 100644 --- a/src/context.c +++ b/src/context.c @@ -1267,6 +1267,26 @@ NULL_update_callback( getdns_context *context, getdns_context_code_t code, void *userarg) { (void)context; (void)code; (void)userarg; } +static int +netreq_expiry_cmp(const void *id1, const void *id2) +{ + getdns_network_req *req1 = (getdns_network_req *)id1; + getdns_network_req *req2 = (getdns_network_req *)id2; + + return req1->owner->expires < req2->owner->expires ? -1 : + req1->owner->expires > req2->owner->expires ? 1 : + req1 < req2 ? -1 : + req1 > req2 ? 1 : 0; +} + +void _getdns_check_expired_pending_netreqs( + getdns_context *context, uint64_t *now_ms); +static void _getdns_check_expired_pending_netreqs_cb(void *arg) +{ + uint64_t now_ms = 0; + _getdns_check_expired_pending_netreqs((getdns_context *)arg, &now_ms); +} + /* * getdns_context_create * @@ -1330,8 +1350,15 @@ getdns_context_create_with_extended_memory_functions( _getdns_rbtree_init(&result->outbound_requests, transaction_id_cmp); _getdns_rbtree_init(&result->local_hosts, local_host_cmp); - /* TODO: Initialize pending_netreqs */ + _getdns_rbtree_init(&result->pending_netreqs, netreq_expiry_cmp); + result->first_pending_netreq = NULL; result->netreqs_in_flight = 0; + result->pending_timeout_event.userarg = result; + result->pending_timeout_event.read_cb = NULL; + result->pending_timeout_event.write_cb = NULL; + result->pending_timeout_event.timeout_cb = + _getdns_check_expired_pending_netreqs_cb; + result->pending_timeout_event.ev = NULL; result->server = NULL; @@ -2982,27 +3009,6 @@ _getdns_context_request_timed_out(getdns_dns_req *dnsreq) _getdns_context_cancel_request(dnsreq); } - -void -_getdns_netreq_change_state(getdns_network_req *netreq, network_req_state new_state) -{ - if (!netreq) - return; - - if (netreq->state != NET_REQ_IN_FLIGHT) { - if (new_state == NET_REQ_IN_FLIGHT) - netreq->owner->context->netreqs_in_flight += 1; - netreq->state = new_state; - return; - } - if (new_state == NET_REQ_IN_FLIGHT) /* No change */ - return; - netreq->state = new_state; - netreq->owner->context->netreqs_in_flight -= 1; - /* TODO: Schedule pending netreqs - * when netreqs_in_flight < oustanding_queries */ -} - static void accumulate_outstanding_transactions(_getdns_rbnode_t *node, void* arg) { diff --git a/src/context.h b/src/context.h index 6fe02d23..e1c838f6 100644 --- a/src/context.h +++ b/src/context.h @@ -294,7 +294,10 @@ struct getdns_context { /* network requests */ size_t netreqs_in_flight; - _getdns_rbtree_t pending_netreqs; + + _getdns_rbtree_t pending_netreqs; + getdns_network_req *first_pending_netreq; + getdns_eventloop_event pending_timeout_event; struct listen_set *server; @@ -382,17 +385,6 @@ void _getdns_context_cancel_request(getdns_dns_req *dnsreq); */ void _getdns_context_request_timed_out(getdns_dns_req *dnsreq); -/* Change state of the netreq req. - * - Increments context->netreqs_in_flight - * when state changes from NOT_SENT to IN_FLIGHT - * - Decrements context->netreqs_in_flight - * when state changes from IN_FLIGHT to FINISHED, TIMED_OUT or ERRORED - * - Resubmits NOT_SENT netreqs from context->pending_netreqs, - * when # pending_netreqs < limit_outstanding_queries - */ -void _getdns_netreq_change_state( - getdns_network_req *req, network_req_state new_state); - char *_getdns_strdup(const struct mem_funcs *mfs, const char *str); struct getdns_bindata *_getdns_bindata_copy( diff --git a/src/general.c b/src/general.c index 3781e1da..14b7ee40 100644 --- a/src/general.c +++ b/src/general.c @@ -90,14 +90,23 @@ void _getdns_check_dns_req_complete(getdns_dns_req *dns_req) { getdns_network_req **netreq_p, *netreq; - int results_found = 0, r; + int results_found = 0, timed_out = 1, r; uint64_t now_ms = 0; for (netreq_p = dns_req->netreqs; (netreq = *netreq_p); netreq_p++) if (!_getdns_netreq_finished(netreq)) return; - else if (netreq->response_len > 0) - results_found = 1; + else { + if (netreq->state != NET_REQ_TIMED_OUT) + timed_out = 0; + if (netreq->response_len > 0) + results_found = 1; + } + + if (timed_out) { + _getdns_context_request_timed_out(dns_req); + return; + } /* Do we have to check more suffixes on nxdomain/nodata? */ @@ -248,30 +257,113 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res) #endif +void _getdns_check_expired_pending_netreqs( + getdns_context *context, uint64_t *now_ms) +{ + getdns_network_req *first; + + assert(context); + + while (context->pending_netreqs.count) { + first = (getdns_network_req *) + _getdns_rbtree_first(&context->pending_netreqs); + + if (_getdns_ms_until_expiry2(first->owner->expires, now_ms) > 0) + break; + + (void) _getdns_rbtree_delete(&context->pending_netreqs, first); + _getdns_netreq_change_state(first, NET_REQ_TIMED_OUT); + _getdns_check_dns_req_complete(first->owner); + } + first = context->pending_netreqs.count ? (getdns_network_req *) + _getdns_rbtree_first(&context->pending_netreqs) : NULL; + + if (first == context->first_pending_netreq || + (first && context->first_pending_netreq && + first->owner->expires == context->first_pending_netreq->owner->expires)) + return; /* Nothing changed */ + + if (context->first_pending_netreq) + GETDNS_CLEAR_EVENT( context->extension + , &context->pending_timeout_event); + + if ((context->first_pending_netreq = first)) + GETDNS_SCHEDULE_EVENT( context->extension, -1, + _getdns_ms_until_expiry2(first->owner->expires, now_ms), + &context->pending_timeout_event); +} + +void +_getdns_netreq_change_state( + getdns_network_req *netreq, network_req_state new_state) +{ + getdns_context *context; + uint64_t now_ms; + + if (!netreq) + return; + + context = netreq->owner->context; + + if (netreq->state != NET_REQ_IN_FLIGHT) { + if (new_state == NET_REQ_IN_FLIGHT) + context->netreqs_in_flight += 1; + netreq->state = new_state; + return; + } + if (new_state == NET_REQ_IN_FLIGHT) /* No change */ + return; + netreq->state = new_state; + context->netreqs_in_flight -= 1; + + now_ms = 0; + while (context->limit_outstanding_queries > 0 && + context->pending_netreqs.count > 0 && + context->netreqs_in_flight < context->limit_outstanding_queries) { + + getdns_network_req *first = (getdns_network_req *) + _getdns_rbtree_first(&context->pending_netreqs); + (void) _getdns_rbtree_delete(&context->pending_netreqs, first); + (void) _getdns_submit_netreq(first, &now_ms); + } +} + int _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms) { getdns_return_t r; getdns_dns_req *dns_req = netreq->owner; + getdns_context *context = dns_req->context; char name[1024]; int dnsreq_freed = 0; #ifdef HAVE_LIBUNBOUND int ub_resolve_r; #endif + if (context->limit_outstanding_queries > 0 && + context->netreqs_in_flight >= context->limit_outstanding_queries) { + + netreq->node.key = netreq; + if (_getdns_rbtree_insert( + &context->pending_netreqs, &netreq->node)) { + + _getdns_check_expired_pending_netreqs(context, now_ms); + return GETDNS_RETURN_GOOD; + } + } _getdns_netreq_change_state(netreq, NET_REQ_IN_FLIGHT); #ifdef STUB_NATIVE_DNSSEC # ifdef DNSSEC_ROADBLOCK_AVOIDANCE - if ((dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING + if ((context->resolution_type == GETDNS_RESOLUTION_RECURSING && !dns_req->dnssec_roadblock_avoidance) || dns_req->avoid_dnssec_roadblocks) { # else - if ( dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING) { + if ( context->resolution_type == GETDNS_RESOLUTION_RECURSING) { # endif #else - if ( dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING + if ( context->resolution_type == GETDNS_RESOLUTION_RECURSING || dns_req->dnssec_return_status || dns_req->dnssec_return_only_secure || dns_req->dnssec_return_all_statuses @@ -297,15 +389,15 @@ _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms) #ifdef HAVE_LIBUNBOUND dns_req->freed = &dnsreq_freed; #ifdef HAVE_UNBOUND_EVENT_API - if (_getdns_ub_loop_enabled(&dns_req->context->ub_loop)) - ub_resolve_r = ub_resolve_event(dns_req->context->unbound_ctx, - name, netreq->request_type, netreq->owner->request_class, + if (_getdns_ub_loop_enabled(&context->ub_loop)) + ub_resolve_r = ub_resolve_event(context->unbound_ctx, + name, netreq->request_type, dns_req->request_class, netreq, ub_resolve_event_callback, &(netreq->unbound_id)) ? GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD; else #endif - ub_resolve_r = ub_resolve_async(dns_req->context->unbound_ctx, - name, netreq->request_type, netreq->owner->request_class, + ub_resolve_r = ub_resolve_async(context->unbound_ctx, + name, netreq->request_type, dns_req->request_class, netreq, ub_resolve_callback, &(netreq->unbound_id)) ? GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD; if (dnsreq_freed) diff --git a/src/general.h b/src/general.h index dcd9b9be..e0860c78 100644 --- a/src/general.h +++ b/src/general.h @@ -45,6 +45,18 @@ #define DNS_REQ_FINISHED -1 void _getdns_call_user_callback(getdns_dns_req *, getdns_dict *); + +/* Change state of the netreq req. + * - Increments context->netreqs_in_flight + * when state changes from NOT_SENT to IN_FLIGHT + * - Decrements context->netreqs_in_flight + * when state changes from IN_FLIGHT to FINISHED, TIMED_OUT or ERRORED + * - Resubmits NOT_SENT netreqs from context->pending_netreqs, + * when # pending_netreqs < limit_outstanding_queries + */ +void _getdns_netreq_change_state( + getdns_network_req *netreq, network_req_state new_state); + void _getdns_check_dns_req_complete(getdns_dns_req *dns_req); int _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms); diff --git a/src/request-internal.c b/src/request-internal.c index 8eec6b7a..2259286e 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -43,6 +43,7 @@ #include "dict.h" #include "debug.h" #include "convert.h" +#include "general.h" /* MAXIMUM_TSIG_SPACE = TSIG name (dname) : 256 * TSIG type (uint16_t) : 2 diff --git a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test index 37915e43..177cc1c7 100644 --- a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test +++ b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.test @@ -4,9 +4,15 @@ # use .tpkg.var.test for in test variable passing [ -f .tpkg.var.test ] && source .tpkg.var.test -# TODO: Change QLIMIT to 10 once implement pending netreq resubmission -# -QLIMIT=1000 + +QLIMIT=64 +NQUERIES=`wc "./${TPKG_NAME}.queries"|sed 's/ .*$//g'` + +# Test will take NQUERIES / QLIMIT * answer delay +# For current parameters this is 1000 / 64 * 0.3 = 4.6875 +# which is smaller than 5 seconds default query timeout value, +# so the test should succeed. + make && "./${TPKG_NAME}" | ( read PORT ${GETDNS_STUB_QUERY} @127.0.0.1:$PORT TXT \ @@ -15,7 +21,7 @@ make && "./${TPKG_NAME}" | ( ${GETDNS_STUB_QUERY} -q @127.0.0.1:$PORT TXT quit. ) && grep '"n_requests: [0-9][0-9]*"' out | sed -e 's/^.*n_requests: //g' -e 's/".*$//g' \ - | awk -vQLIMIT=$QLIMIT ' + | awk -vQLIMIT=$QLIMIT -vNQUERIES=$NQUERIES ' BEGIN{ max_outstanding = 0; @@ -25,6 +31,7 @@ BEGIN{ max_outstanding = $1; } END{ + printf("%d of %d queries answered (%.1f%%)\n", NR, NQUERIES, (NR / NQUERIES * 100)); if (max_outstanding > QLIMIT) { print "ERROR: More than "QLIMIT" outstanding queries: "max_outstanding; exit(-1); From f0f3c43552936a8bd40d59d388cac2c4d7ac09b2 Mon Sep 17 00:00:00 2001 From: Sara Dickinson Date: Thu, 16 Mar 2017 14:51:46 +0000 Subject: [PATCH 06/21] - Add a new mode where for TLS (and infact TCP too) the upstream selection simply cycles over all the upstreams rather than treating them as an ordered list and always using the first open one. - Make IP field in debug output fixed width - Collect all the one line config options at the top of the stubby.conf file to make it easier to read --- src/const-info.c | 2 + src/context.c | 45 +++++++++++++++++++--- src/context.h | 2 + src/getdns/getdns_extra.h.in | 9 +++++ src/libgetdns.symbols | 2 + src/stub.c | 75 ++++++++++++++++++++++++++---------- src/tools/stubby.conf | 11 +++--- 7 files changed, 116 insertions(+), 30 deletions(-) diff --git a/src/const-info.c b/src/const-info.c index 4556634a..b539094a 100644 --- a/src/const-info.c +++ b/src/const-info.c @@ -73,6 +73,7 @@ static struct const_info consts_info[] = { { 619, "GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE", GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE_TEXT }, { 620, "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE_TEXT }, { 621, "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", GETDNS_CONTEXT_CODE_PUBKEY_PINSET_TEXT }, + { 622, "GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS", GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS_TEXT }, { 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT }, { 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT }, { 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT }, @@ -161,6 +162,7 @@ static struct const_name_info consts_name_info[] = { { "GETDNS_CONTEXT_CODE_TIMEOUT", 616 }, { "GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION", 618 }, { "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 }, + { "GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS", 622 }, { "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", 603 }, { "GETDNS_DNSSEC_BOGUS", 401 }, { "GETDNS_DNSSEC_INDETERMINATE", 402 }, diff --git a/src/context.c b/src/context.c index 5421fd81..e5b183d6 100644 --- a/src/context.c +++ b/src/context.c @@ -647,6 +647,7 @@ upstreams_create(getdns_context *context, size_t size) r->referenced = 1; r->count = 0; r->current_udp = 0; + r->current_stateful = 0; return r; } @@ -721,17 +722,17 @@ _getdns_upstream_shutdown(getdns_upstream *upstream) if (upstream->tls_auth_state > upstream->best_tls_auth_state) upstream->best_tls_auth_state = upstream->tls_auth_state; #if defined(DAEMON_DEBUG) && DAEMON_DEBUG - DEBUG_DAEMON("%s %s : Conn closed : Transport=%s - Resp=%d,Timeouts=%d,Auth=%s,Keepalive(ms)=%d\n", + DEBUG_DAEMON("%s %-40s : Conn closed : Transport=%s - Resp=%d,Timeouts=%d,Auth=%s,Keepalive(ms)=%d\n", STUB_DEBUG_DAEMON, upstream->addr_str, (upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"), (int)upstream->responses_received, (int)upstream->responses_timeouts, _getdns_auth_str(upstream->tls_auth_state), (int)upstream->keepalive_timeout); - DEBUG_DAEMON("%s %s : Upstream stats: Transport=%s - Resp=%d,Timeouts=%d,Best_auth=%s\n", + DEBUG_DAEMON("%s %-40s : Upstream stats: Transport=%s - Resp=%d,Timeouts=%d,Best_auth=%s\n", STUB_DEBUG_DAEMON, upstream->addr_str, (upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"), (int)upstream->total_responses, (int)upstream->total_timeouts, _getdns_auth_str(upstream->best_tls_auth_state)); - DEBUG_DAEMON("%s %s : Upstream stats: Transport=%s - Conns=%d,Conn_fails=%d,Conn_shutdowns=%d,Backoffs=%d\n", + DEBUG_DAEMON("%s %-40s : Upstream stats: Transport=%s - Conns=%d,Conn_fails=%d,Conn_shutdowns=%d,Backoffs=%d\n", STUB_DEBUG_DAEMON, upstream->addr_str, (upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"), (int)upstream->conn_completed, (int)upstream->conn_setup_failed, @@ -760,7 +761,7 @@ _getdns_upstream_shutdown(getdns_upstream *upstream) upstream->conn_shutdowns = 0; upstream->conn_backoffs++; #if defined(DAEMON_DEBUG) && DAEMON_DEBUG - DEBUG_DAEMON("%s %s : !Backing off this upstream - Will retry as new upstream at %s", + DEBUG_DAEMON("%s %-40s : !Backing off this upstream - Will retry as new upstream at %s", STUB_DEBUG_DAEMON, upstream->addr_str, asctime(gmtime(&upstream->conn_retry_time))); #endif @@ -1428,6 +1429,7 @@ getdns_context_create_with_extended_memory_functions( goto error; result->tls_auth = GETDNS_AUTHENTICATION_NONE; result->tls_auth_min = GETDNS_AUTHENTICATION_NONE; + result->tls_use_all_upstreams = 0; result->limit_outstanding_queries = 0; /* unbound context is initialized here */ @@ -2031,6 +2033,27 @@ getdns_context_set_tls_authentication(getdns_context *context, return GETDNS_RETURN_GOOD; } /* getdns_context_set_tls_authentication_list */ +/* + * getdns_context_set_tls_use_all_upstreams + * + */ +getdns_return_t +getdns_context_set_tls_use_all_upstreams(getdns_context *context, uint8_t value) +{ + RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); + /* only allow 0 or 1 */ + if (value != 0 && value != 1) { + return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; + } + + context->tls_use_all_upstreams = value; + + dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS); + + return GETDNS_RETURN_GOOD; +} /* getdns_context_set_tls_use_all_upstreams */ + + #ifdef HAVE_LIBUNBOUND static void set_ub_limit_outstanding_queries(getdns_context* context, uint16_t value) { @@ -3467,7 +3490,9 @@ _get_context_settings(getdns_context* context) || getdns_dict_set_int(result, "append_name", context->append_name) || getdns_dict_set_int(result, "tls_authentication", - context->tls_auth)) + context->tls_auth) + || getdns_dict_set_int(result, "tls_use_all_upstreams", + context->tls_use_all_upstreams)) goto error; /* list fields */ @@ -3763,6 +3788,15 @@ getdns_context_get_tls_authentication(getdns_context *context, return GETDNS_RETURN_GOOD; } +getdns_return_t +getdns_context_get_tls_use_all_upstreams(getdns_context *context, + uint8_t* value) { + RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); + RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); + *value = context->tls_use_all_upstreams; + return GETDNS_RETURN_GOOD; +} + getdns_return_t getdns_context_get_limit_outstanding_queries(getdns_context *context, uint16_t* value) { @@ -4158,6 +4192,7 @@ _getdns_context_config_setting(getdns_context *context, CONTEXT_SETTING_INT(edns_client_subnet_private) CONTEXT_SETTING_INT(tls_authentication) + CONTEXT_SETTING_INT(tls_use_all_upstreams) CONTEXT_SETTING_INT(tls_query_padding_blocksize) /**************************************/ diff --git a/src/context.h b/src/context.h index e6ed49fb..df9eb88f 100644 --- a/src/context.h +++ b/src/context.h @@ -217,6 +217,7 @@ typedef struct getdns_upstreams { size_t referenced; size_t count; size_t current_udp; + size_t current_stateful; getdns_upstream upstreams[]; } getdns_upstreams; @@ -248,6 +249,7 @@ struct getdns_context { uint32_t dnssec_allowed_skew; getdns_tls_authentication_t tls_auth; /* What user requested for TLS*/ getdns_tls_authentication_t tls_auth_min; /* Derived minimum auth allowed*/ + uint8_t tls_use_all_upstreams; getdns_transport_list_t *dns_transports; size_t dns_transport_count; diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index a76564eb..90c33c44 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -76,6 +76,8 @@ extern "C" { #define GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE_TEXT "Change related to getdns_context_set_tls_query_padding_blocksize" #define GETDNS_CONTEXT_CODE_PUBKEY_PINSET 621 #define GETDNS_CONTEXT_CODE_PUBKEY_PINSET_TEXT "Change related to getdns_context_set_pubkey_pinset" +#define GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS 622 +#define GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS_TEXT "Change related to getdns_context_set_pubkey_pinset" /** @} */ @@ -265,6 +267,9 @@ getdns_return_t getdns_context_set_tls_authentication( getdns_context *context, getdns_tls_authentication_t value); +getdns_return_t +getdns_context_set_tls_use_all_upstreams(getdns_context *context, uint8_t value); + getdns_return_t getdns_context_set_edns_client_subnet_private(getdns_context *context, uint8_t value); @@ -356,6 +361,10 @@ getdns_return_t getdns_context_get_tls_authentication(getdns_context *context, getdns_tls_authentication_t* value); +getdns_return_t +getdns_context_get_tls_use_all_upstreams(getdns_context *context, + uint8_t* value); + /** * Get the currently registered callback function and user defined argument * for context changes. diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index 6e3cb128..6890dc85 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -30,6 +30,7 @@ getdns_context_get_suffix getdns_context_get_timeout getdns_context_get_tls_authentication getdns_context_get_tls_query_padding_blocksize +getdns_context_get_tls_use_all_upstreams getdns_context_get_update_callback getdns_context_get_upstream_recursive_servers getdns_context_process_async @@ -60,6 +61,7 @@ getdns_context_set_suffix getdns_context_set_timeout getdns_context_set_tls_authentication getdns_context_set_tls_query_padding_blocksize +getdns_context_get_tls_use_all_upstreams getdns_context_set_update_callback getdns_context_set_upstream_recursive_servers getdns_context_set_use_threads diff --git a/src/stub.c b/src/stub.c index e905f600..fe4c52c2 100644 --- a/src/stub.c +++ b/src/stub.c @@ -591,7 +591,7 @@ stub_timeout_cb(void *userarg) netreq->upstream->udp_timeouts++; #if defined(DAEMON_DEBUG) && DAEMON_DEBUG if (netreq->upstream->udp_timeouts % 100 == 0) - DEBUG_DAEMON("%s %s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n", + DEBUG_DAEMON("%s %-40s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n", STUB_DEBUG_DAEMON, netreq->upstream->addr_str, (int)netreq->upstream->udp_responses, (int)netreq->upstream->udp_timeouts); #endif @@ -907,7 +907,7 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd); #if defined(DAEMON_DEBUG) && DAEMON_DEBUG else - DEBUG_DAEMON("%s %s : Conn failed : Transport=TLS - *Failure* - Pinset validation failure\n", + DEBUG_DAEMON("%s %-40s : Conn failed : Transport=TLS - *Failure* - Pinset validation failure\n", STUB_DEBUG_DAEMON, upstream->addr_str); #endif } else { @@ -1373,7 +1373,7 @@ stub_udp_read_cb(void *userarg) #if defined(DAEMON_DEBUG) && DAEMON_DEBUG if (upstream->udp_responses == 1 || upstream->udp_responses % 100 == 0) - DEBUG_DAEMON("%s %s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n", + DEBUG_DAEMON("%s %-40s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n", STUB_DEBUG_DAEMON, upstream->addr_str, (int)upstream->udp_responses, (int)upstream->udp_timeouts); #endif @@ -1608,7 +1608,7 @@ upstream_write_cb(void *userarg) /* Cleaning up after connection or auth check failure. Need to fallback. */ stub_cleanup(netreq); #if defined(DAEMON_DEBUG) && DAEMON_DEBUG - DEBUG_DAEMON("%s %s : Conn closed : Transport=%s - *Failure*\n", + DEBUG_DAEMON("%s %-40s : Conn closed : Transport=%s - *Failure*\n", STUB_DEBUG_DAEMON, upstream->addr_str, (upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP")); #endif @@ -1672,6 +1672,17 @@ upstream_active(getdns_upstream *upstream) return 0; } +static int +upstream_usable(getdns_upstream *upstream) +{ + if ((upstream->conn_state == GETDNS_CONN_CLOSED || + upstream->conn_state == GETDNS_CONN_SETUP || + upstream->conn_state == GETDNS_CONN_OPEN) && + upstream->keepalive_shutdown == 0) + return 1; + return 0; +} + static int upstream_auth_status_ok(getdns_upstream *upstream, getdns_network_req *netreq) { if (netreq->tls_auth_min != GETDNS_AUTHENTICATION_REQUIRED) @@ -1692,10 +1703,16 @@ upstream_valid(getdns_upstream *upstream, getdns_transport_list_t transport, getdns_network_req *netreq) { - if (upstream->transport != transport || upstream->conn_state != GETDNS_CONN_CLOSED) + if (upstream->transport != transport && upstream_usable(upstream)) return 0; if (transport == GETDNS_TRANSPORT_TCP) return 1; + if (upstream->conn_state == GETDNS_CONN_OPEN) { + if (!upstream_auth_status_ok(upstream, netreq)) + return 0; + else + return 1; + } /* We need to check past authentication history to see if this is usable for TLS.*/ if (netreq->tls_auth_min != GETDNS_AUTHENTICATION_REQUIRED) return 1; @@ -1728,7 +1745,7 @@ upstream_select_stateful(getdns_network_req *netreq, getdns_transport_list_t tra getdns_upstreams *upstreams = netreq->owner->upstreams; size_t i; time_t now = time(NULL); - + if (!upstreams->count) return NULL; @@ -1738,37 +1755,55 @@ upstream_select_stateful(getdns_network_req *netreq, getdns_transport_list_t tra upstreams->upstreams[i].conn_retry_time < now) { upstreams->upstreams[i].conn_state = GETDNS_CONN_CLOSED; #if defined(DAEMON_DEBUG) && DAEMON_DEBUG - DEBUG_DAEMON("%s %s : Re-instating upstream\n", + DEBUG_DAEMON("%s %-40s : Re-instating upstream\n", STUB_DEBUG_DAEMON, upstreams->upstreams[i].addr_str); #endif } } - /* First find if an open upstream has the correct properties and use that*/ - for (i = 0; i < upstreams->count; i++) { - if (upstream_valid_and_open(&upstreams->upstreams[i], transport, netreq)) - return &upstreams->upstreams[i]; + if (netreq->owner->context->tls_use_all_upstreams == 0) { + /* First find if an open upstream has the correct properties and use that*/ + for (i = 0; i < upstreams->count; i++) { + if (upstream_valid_and_open(&upstreams->upstreams[i], transport, netreq)) + return &upstreams->upstreams[i]; + } } - /* OK - we will have to open one. Choose the first one that has the best stats - and the right properties, but because we completely back off failed + /* OK - Find the next one to use. First check we have at least one valid + upstream because we completely back off failed upstreams we may have no valid upstream at all (in contrast to UDP). This will be better communicated to the user when we have better error codes*/ - for (i = 0; i < upstreams->count; i++) { + i = upstreams->current_stateful; + do { DEBUG_STUB("%s %-35s: Testing upstreams %d %d\n", STUB_DEBUG_SETUP, __FUNC__, (int)i, (int)upstreams->upstreams[i].conn_state); if (upstream_valid(&upstreams->upstreams[i], transport, netreq)) { upstream = &upstreams->upstreams[i]; break; } - } + i++; + if (i >= upstreams->count) + i = 0; + } while (i != upstreams->current_stateful); if (!upstream) return NULL; - for (i++; i < upstreams->count; i++) { - if (upstream_valid(&upstreams->upstreams[i], transport, netreq) && - upstream_stats(&upstreams->upstreams[i]) > upstream_stats(upstream)) - upstream = &upstreams->upstreams[i]; + + /* Now select the specific upstream */ + if (netreq->owner->context->tls_use_all_upstreams == 0) { + /* Base the decision on the stats, noting we will have started from 0*/ + for (i++; i < upstreams->count; i++) { + if (upstream_valid(&upstreams->upstreams[i], transport, netreq) && + upstream_stats(&upstreams->upstreams[i]) > upstream_stats(upstream)) + upstream = &upstreams->upstreams[i]; + } + } else { + /* Simplistic, but always just pick the first one, incrementing the current. + Note we are not distinguishing TCP/TLS here....*/ + upstreams->current_stateful+=GETDNS_UPSTREAM_TRANSPORTS; + if (upstreams->current_stateful >= upstreams->count) + upstreams->current_stateful = 0; } + return upstream; } @@ -1853,7 +1888,7 @@ upstream_connect(getdns_upstream *upstream, getdns_transport_list_t transport, } upstream->conn_state = GETDNS_CONN_SETUP; #if defined(DAEMON_DEBUG) && DAEMON_DEBUG - DEBUG_DAEMON("%s %s : Conn init : Transport=%s - Profile=%s\n", STUB_DEBUG_DAEMON, + DEBUG_DAEMON("%s %-40s : Conn init : Transport=%s - Profile=%s\n", STUB_DEBUG_DAEMON, upstream->addr_str, transport == GETDNS_TRANSPORT_TLS ? "TLS":"TCP", dnsreq->context->tls_auth_min == GETDNS_AUTHENTICATION_NONE ? "Opportunistic":"Strict"); #endif diff --git a/src/tools/stubby.conf b/src/tools/stubby.conf index 1055e277..0bda0e7c 100644 --- a/src/tools/stubby.conf +++ b/src/tools/stubby.conf @@ -1,5 +1,11 @@ { resolution_type: GETDNS_RESOLUTION_STUB , dns_transport_list: [ GETDNS_TRANSPORT_TLS ] +, tls_authentication: GETDNS_AUTHENTICATION_REQUIRED +, tls_query_padding_blocksize: 256 +, edns_client_subnet_private : 1 +, listen_addresses: [ 127.0.0.1, 0::1 ] +, idle_timeout: 10000 +, tls_use_all_upstreams: 1 , upstream_recursive_servers: [ { address_data: 145.100.185.15 , tls_auth_name: "dnsovertls.sinodun.com" @@ -56,9 +62,4 @@ } ] } ] -, tls_authentication: GETDNS_AUTHENTICATION_REQUIRED -, tls_query_padding_blocksize: 256 -, edns_client_subnet_private : 1 -, listen_addresses: [ 127.0.0.1, 0::1 ] -, idle_timeout: 10000 } From 2a1a6768cb0225e6b31cdfff536cd9c114be9d3c Mon Sep 17 00:00:00 2001 From: Sara Dickinson Date: Thu, 16 Mar 2017 16:26:34 +0000 Subject: [PATCH 07/21] Add unit test and catch a typo --- src/libgetdns.symbols | 2 +- ...tdns_context_set_context_update_callback.h | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index 6890dc85..71f63a1f 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -61,7 +61,7 @@ getdns_context_set_suffix getdns_context_set_timeout getdns_context_set_tls_authentication getdns_context_set_tls_query_padding_blocksize -getdns_context_get_tls_use_all_upstreams +getdns_context_set_tls_use_all_upstreams getdns_context_set_update_callback getdns_context_set_upstream_recursive_servers getdns_context_set_use_threads diff --git a/src/test/check_getdns_context_set_context_update_callback.h b/src/test/check_getdns_context_set_context_update_callback.h index d816a149..25b302d8 100644 --- a/src/test/check_getdns_context_set_context_update_callback.h +++ b/src/test/check_getdns_context_set_context_update_callback.h @@ -434,6 +434,29 @@ } END_TEST + + START_TEST (getdns_context_set_context_update_callback_23) + { + /* + * value is NULL + * expect: GETDNS_RETURN_INVALID_PARAMETER + */ + + struct getdns_context *context = NULL; + CONTEXT_CREATE(TRUE); + + ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn), + GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()"); + + expected_changed_item = GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS; + + ASSERT_RC(getdns_context_set_tls_use_all_upstreams(context, 1), + GETDNS_RETURN_GOOD, "Return code from getdns_context_set_timeout()"); + + CONTEXT_DESTROY; + + } + END_TEST Suite * getdns_context_set_context_update_callback_suite (void) @@ -462,6 +485,7 @@ tcase_add_test(tc_pos, getdns_context_set_context_update_callback_20); tcase_add_test(tc_pos, getdns_context_set_context_update_callback_21); tcase_add_test(tc_pos, getdns_context_set_context_update_callback_22); + tcase_add_test(tc_pos, getdns_context_set_context_update_callback_23); suite_add_tcase(s, tc_pos); return s; From 6734a00d59ed4b6d5c0c38e7d9ab10367d449073 Mon Sep 17 00:00:00 2001 From: Sara Dickinson Date: Fri, 17 Mar 2017 11:25:47 +0000 Subject: [PATCH 08/21] Improve the logging --- src/stub.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/stub.c b/src/stub.c index fe4c52c2..ee691153 100644 --- a/src/stub.c +++ b/src/stub.c @@ -870,7 +870,7 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) #endif #if defined(DAEMON_DEBUG) && DAEMON_DEBUG if (!preverify_ok && !upstream->tls_fallback_ok) - DEBUG_DAEMON("%s %s : Conn failed : Transport=TLS - *Failure* - (%d) \"%s\"\n", + DEBUG_DAEMON("%s %-40s : Verify failed : Transport=TLS - *Failure* - (%d) \"%s\"\n", STUB_DEBUG_DAEMON, upstream->addr_str, err, X509_verify_cert_error_string(err)); #endif @@ -920,6 +920,10 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) preverify_ok = 1; DEBUG_STUB("%s %-35s: FD: %d, Allowing self-signed (%d) cert since pins match\n", STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd, err); +#if defined(DAEMON_DEBUG) && DAEMON_DEBUG + DEBUG_DAEMON("%s %-40s : Verify passed : Transport=TLS - Allowing self-signed cert since pins match\n", + STUB_DEBUG_DAEMON, upstream->addr_str); +#endif } } From 1d4e3dd7907b5f36ede0f284853982446fefe17b Mon Sep 17 00:00:00 2001 From: Sara Dickinson Date: Fri, 17 Mar 2017 16:53:03 +0000 Subject: [PATCH 09/21] Update the name of the new option to 'round_robin_upstreams' --- src/const-info.c | 4 ++-- src/context.c | 22 +++++++++---------- src/context.h | 2 +- src/getdns/getdns_extra.h.in | 8 +++---- src/libgetdns.symbols | 4 ++-- src/stub.c | 6 ++--- ...tdns_context_set_context_update_callback.h | 4 ++-- src/tools/stubby.conf | 2 +- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/const-info.c b/src/const-info.c index b539094a..f105b756 100644 --- a/src/const-info.c +++ b/src/const-info.c @@ -73,7 +73,7 @@ static struct const_info consts_info[] = { { 619, "GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE", GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE_TEXT }, { 620, "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE_TEXT }, { 621, "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", GETDNS_CONTEXT_CODE_PUBKEY_PINSET_TEXT }, - { 622, "GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS", GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS_TEXT }, + { 622, "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS_TEXT }, { 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT }, { 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT }, { 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT }, @@ -158,11 +158,11 @@ static struct const_name_info consts_name_info[] = { { "GETDNS_CONTEXT_CODE_NAMESPACES", 600 }, { "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", 621 }, { "GETDNS_CONTEXT_CODE_RESOLUTION_TYPE", 601 }, + { "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", 622 }, { "GETDNS_CONTEXT_CODE_SUFFIX", 608 }, { "GETDNS_CONTEXT_CODE_TIMEOUT", 616 }, { "GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION", 618 }, { "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 }, - { "GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS", 622 }, { "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", 603 }, { "GETDNS_DNSSEC_BOGUS", 401 }, { "GETDNS_DNSSEC_INDETERMINATE", 402 }, diff --git a/src/context.c b/src/context.c index e5b183d6..2bc6963a 100644 --- a/src/context.c +++ b/src/context.c @@ -1429,7 +1429,7 @@ getdns_context_create_with_extended_memory_functions( goto error; result->tls_auth = GETDNS_AUTHENTICATION_NONE; result->tls_auth_min = GETDNS_AUTHENTICATION_NONE; - result->tls_use_all_upstreams = 0; + result->round_robin_upstreams = 0; result->limit_outstanding_queries = 0; /* unbound context is initialized here */ @@ -2034,11 +2034,11 @@ getdns_context_set_tls_authentication(getdns_context *context, } /* getdns_context_set_tls_authentication_list */ /* - * getdns_context_set_tls_use_all_upstreams + * getdns_context_set_round_robin_upstreams * */ getdns_return_t -getdns_context_set_tls_use_all_upstreams(getdns_context *context, uint8_t value) +getdns_context_set_round_robin_upstreams(getdns_context *context, uint8_t value) { RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); /* only allow 0 or 1 */ @@ -2046,12 +2046,12 @@ getdns_context_set_tls_use_all_upstreams(getdns_context *context, uint8_t value) return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; } - context->tls_use_all_upstreams = value; + context->round_robin_upstreams = value; - dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS); + dispatch_updated(context, GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS); return GETDNS_RETURN_GOOD; -} /* getdns_context_set_tls_use_all_upstreams */ +} /* getdns_context_set_round_robin_upstreams */ #ifdef HAVE_LIBUNBOUND @@ -3491,8 +3491,8 @@ _get_context_settings(getdns_context* context) context->append_name) || getdns_dict_set_int(result, "tls_authentication", context->tls_auth) - || getdns_dict_set_int(result, "tls_use_all_upstreams", - context->tls_use_all_upstreams)) + || getdns_dict_set_int(result, "round_robin_upstreams", + context->round_robin_upstreams)) goto error; /* list fields */ @@ -3789,11 +3789,11 @@ getdns_context_get_tls_authentication(getdns_context *context, } getdns_return_t -getdns_context_get_tls_use_all_upstreams(getdns_context *context, +getdns_context_get_round_robin_upstreams(getdns_context *context, uint8_t* value) { RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->tls_use_all_upstreams; + *value = context->round_robin_upstreams; return GETDNS_RETURN_GOOD; } @@ -4192,7 +4192,7 @@ _getdns_context_config_setting(getdns_context *context, CONTEXT_SETTING_INT(edns_client_subnet_private) CONTEXT_SETTING_INT(tls_authentication) - CONTEXT_SETTING_INT(tls_use_all_upstreams) + CONTEXT_SETTING_INT(round_robin_upstreams) CONTEXT_SETTING_INT(tls_query_padding_blocksize) /**************************************/ diff --git a/src/context.h b/src/context.h index df9eb88f..3f4bf5df 100644 --- a/src/context.h +++ b/src/context.h @@ -249,7 +249,7 @@ struct getdns_context { uint32_t dnssec_allowed_skew; getdns_tls_authentication_t tls_auth; /* What user requested for TLS*/ getdns_tls_authentication_t tls_auth_min; /* Derived minimum auth allowed*/ - uint8_t tls_use_all_upstreams; + uint8_t round_robin_upstreams; getdns_transport_list_t *dns_transports; size_t dns_transport_count; diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index 90c33c44..2c03dcfc 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -76,8 +76,8 @@ extern "C" { #define GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE_TEXT "Change related to getdns_context_set_tls_query_padding_blocksize" #define GETDNS_CONTEXT_CODE_PUBKEY_PINSET 621 #define GETDNS_CONTEXT_CODE_PUBKEY_PINSET_TEXT "Change related to getdns_context_set_pubkey_pinset" -#define GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS 622 -#define GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS_TEXT "Change related to getdns_context_set_pubkey_pinset" +#define GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS 622 +#define GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS_TEXT "Change related to getdns_context_set_pubkey_pinset" /** @} */ @@ -268,7 +268,7 @@ getdns_context_set_tls_authentication( getdns_context *context, getdns_tls_authentication_t value); getdns_return_t -getdns_context_set_tls_use_all_upstreams(getdns_context *context, uint8_t value); +getdns_context_set_round_robin_upstreams(getdns_context *context, uint8_t value); getdns_return_t getdns_context_set_edns_client_subnet_private(getdns_context *context, uint8_t value); @@ -362,7 +362,7 @@ getdns_context_get_tls_authentication(getdns_context *context, getdns_tls_authentication_t* value); getdns_return_t -getdns_context_get_tls_use_all_upstreams(getdns_context *context, +getdns_context_get_round_robin_upstreams(getdns_context *context, uint8_t* value); /** diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index 71f63a1f..be63ec40 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -30,7 +30,7 @@ getdns_context_get_suffix getdns_context_get_timeout getdns_context_get_tls_authentication getdns_context_get_tls_query_padding_blocksize -getdns_context_get_tls_use_all_upstreams +getdns_context_get_round_robin_upstreams getdns_context_get_update_callback getdns_context_get_upstream_recursive_servers getdns_context_process_async @@ -61,7 +61,7 @@ getdns_context_set_suffix getdns_context_set_timeout getdns_context_set_tls_authentication getdns_context_set_tls_query_padding_blocksize -getdns_context_set_tls_use_all_upstreams +getdns_context_set_round_robin_upstreams getdns_context_set_update_callback getdns_context_set_upstream_recursive_servers getdns_context_set_use_threads diff --git a/src/stub.c b/src/stub.c index ee691153..3a600c90 100644 --- a/src/stub.c +++ b/src/stub.c @@ -1707,7 +1707,7 @@ upstream_valid(getdns_upstream *upstream, getdns_transport_list_t transport, getdns_network_req *netreq) { - if (upstream->transport != transport && upstream_usable(upstream)) + if (!(upstream->transport == transport && upstream_usable(upstream))) return 0; if (transport == GETDNS_TRANSPORT_TCP) return 1; @@ -1765,7 +1765,7 @@ upstream_select_stateful(getdns_network_req *netreq, getdns_transport_list_t tra } } - if (netreq->owner->context->tls_use_all_upstreams == 0) { + if (netreq->owner->context->round_robin_upstreams == 0) { /* First find if an open upstream has the correct properties and use that*/ for (i = 0; i < upstreams->count; i++) { if (upstream_valid_and_open(&upstreams->upstreams[i], transport, netreq)) @@ -1793,7 +1793,7 @@ upstream_select_stateful(getdns_network_req *netreq, getdns_transport_list_t tra return NULL; /* Now select the specific upstream */ - if (netreq->owner->context->tls_use_all_upstreams == 0) { + if (netreq->owner->context->round_robin_upstreams == 0) { /* Base the decision on the stats, noting we will have started from 0*/ for (i++; i < upstreams->count; i++) { if (upstream_valid(&upstreams->upstreams[i], transport, netreq) && diff --git a/src/test/check_getdns_context_set_context_update_callback.h b/src/test/check_getdns_context_set_context_update_callback.h index 25b302d8..214893a2 100644 --- a/src/test/check_getdns_context_set_context_update_callback.h +++ b/src/test/check_getdns_context_set_context_update_callback.h @@ -448,9 +448,9 @@ ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn), GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()"); - expected_changed_item = GETDNS_CONTEXT_CODE_TLS_USE_ALL_UPSTREAMS; + expected_changed_item = GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS; - ASSERT_RC(getdns_context_set_tls_use_all_upstreams(context, 1), + ASSERT_RC(getdns_context_set_round_robin_upstreams(context, 1), GETDNS_RETURN_GOOD, "Return code from getdns_context_set_timeout()"); CONTEXT_DESTROY; diff --git a/src/tools/stubby.conf b/src/tools/stubby.conf index 0bda0e7c..92cb38be 100644 --- a/src/tools/stubby.conf +++ b/src/tools/stubby.conf @@ -5,7 +5,7 @@ , edns_client_subnet_private : 1 , listen_addresses: [ 127.0.0.1, 0::1 ] , idle_timeout: 10000 -, tls_use_all_upstreams: 1 +, round_robin_upstreams: 1 , upstream_recursive_servers: [ { address_data: 145.100.185.15 , tls_auth_name: "dnsovertls.sinodun.com" From dd76132a92443b372b46821a898646c37e984eab Mon Sep 17 00:00:00 2001 From: Sara Dickinson Date: Fri, 17 Mar 2017 17:16:14 +0000 Subject: [PATCH 10/21] Implement round robin for UDP. Not sure this is the best option though. Noticed it results in more timeouts if one resolver isn't responding because it is retried more frequently. Willem - please review. --- src/stub.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/stub.c b/src/stub.c index 3a600c90..6931e418 100644 --- a/src/stub.c +++ b/src/stub.c @@ -1370,7 +1370,13 @@ stub_udp_read_cb(void *userarg) return; } netreq->response_len = read; - dnsreq->upstreams->current_udp = 0; + if (!dnsreq->context->round_robin_upstreams) + dnsreq->upstreams->current_udp = 0; + else { + dnsreq->upstreams->current_udp+=GETDNS_UPSTREAM_TRANSPORTS; + if (dnsreq->upstreams->current_udp >= dnsreq->upstreams->count) + dnsreq->upstreams->current_udp = 0; + } netreq->debug_end_time = _getdns_get_time_as_uintt64(); netreq->state = NET_REQ_FINISHED; upstream->udp_responses++; From 6f7bad5d73ead1b43fb3b278c73739e26ffdcccb Mon Sep 17 00:00:00 2001 From: Sara Dickinson Date: Fri, 17 Mar 2017 14:43:26 +0000 Subject: [PATCH 11/21] Add new configuration parameters for TLS back off time and connection retries --- src/const-info.c | 4 ++ src/context.c | 78 +++++++++++++++++++++++++++++++----- src/context.h | 4 ++ src/getdns/getdns_extra.h.in | 18 +++++++++ src/libgetdns.symbols | 4 ++ src/stub.c | 3 +- src/types-internal.h | 1 - 7 files changed, 101 insertions(+), 11 deletions(-) diff --git a/src/const-info.c b/src/const-info.c index f105b756..c78f4816 100644 --- a/src/const-info.c +++ b/src/const-info.c @@ -74,6 +74,8 @@ static struct const_info consts_info[] = { { 620, "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE_TEXT }, { 621, "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", GETDNS_CONTEXT_CODE_PUBKEY_PINSET_TEXT }, { 622, "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS_TEXT }, + { 623, "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT }, + { 624, "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT }, { 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT }, { 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT }, { 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT }, @@ -162,6 +164,8 @@ static struct const_name_info consts_name_info[] = { { "GETDNS_CONTEXT_CODE_SUFFIX", 608 }, { "GETDNS_CONTEXT_CODE_TIMEOUT", 616 }, { "GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION", 618 }, + { "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", 623 }, + { "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", 624 }, { "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 }, { "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", 603 }, { "GETDNS_DNSSEC_BOGUS", 401 }, diff --git a/src/context.c b/src/context.c index 2bc6963a..d80e5091 100644 --- a/src/context.c +++ b/src/context.c @@ -89,9 +89,6 @@ typedef unsigned short in_port_t; #define GETDNS_STR_PORT_ZERO "0" #define GETDNS_STR_PORT_DNS "53" #define GETDNS_STR_PORT_DNS_OVER_TLS "853" -/* How long to wait in seconds before re-trying a connection based backed-off - upstream. Using 1 hour for all transports - based on RFC7858 value for for TLS.*/ -#define BACKOFF_RETRY 3600 #ifdef HAVE_PTHREADS static pthread_mutex_t ssl_init_lock = PTHREAD_MUTEX_INITIALIZER; @@ -648,6 +645,8 @@ upstreams_create(getdns_context *context, size_t size) r->count = 0; r->current_udp = 0; r->current_stateful = 0; + r->tls_backoff_time = context->tls_backoff_time; + r->tls_connection_retries = context->tls_connection_retries; return r; } @@ -744,16 +743,16 @@ _getdns_upstream_shutdown(getdns_upstream *upstream) Leave choice between working upstreams to the stub. This back-off should be time based for TLS according to RFC7858. For now, use the same basis if we simply can't get TCP service either.*/ - + uint16_t conn_retries = upstream->upstreams->tls_connection_retries; /* [TLS1]TODO: This arbitrary logic at the moment - review and improve!*/ - if (upstream->conn_setup_failed >= GETDNS_CONN_ATTEMPTS || - (upstream->conn_shutdowns >= GETDNS_CONN_ATTEMPTS*GETDNS_TRANSPORT_FAIL_MULT - && upstream->total_responses == 0) || - (upstream->conn_completed >= GETDNS_CONN_ATTEMPTS && + if (upstream->conn_setup_failed >= conn_retries + || (upstream->conn_shutdowns >= conn_retries*GETDNS_TRANSPORT_FAIL_MULT + && upstream->total_responses == 0) + || (upstream->conn_completed >= conn_retries && upstream->total_responses == 0 && upstream->total_timeouts > GETDNS_TRANSPORT_FAIL_MULT)) { upstream->conn_state = GETDNS_CONN_BACKOFF; - upstream->conn_retry_time = time(NULL) + BACKOFF_RETRY; + upstream->conn_retry_time = time(NULL) + upstream->upstreams->tls_backoff_time; upstream->total_responses = 0; upstream->total_timeouts = 0; upstream->conn_completed = 0; @@ -1430,6 +1429,8 @@ getdns_context_create_with_extended_memory_functions( result->tls_auth = GETDNS_AUTHENTICATION_NONE; result->tls_auth_min = GETDNS_AUTHENTICATION_NONE; result->round_robin_upstreams = 0; + result->tls_backoff_time = 3600; + result->tls_connection_retries = 2; result->limit_outstanding_queries = 0; /* unbound context is initialized here */ @@ -2053,6 +2054,41 @@ getdns_context_set_round_robin_upstreams(getdns_context *context, uint8_t value) return GETDNS_RETURN_GOOD; } /* getdns_context_set_round_robin_upstreams */ +/* + * getdns_context_set_tls_backoff_time + * + */ +getdns_return_t +getdns_context_set_tls_backoff_time(getdns_context *context, uint16_t value) +{ + RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); + /* Value is in seconds. Should we have a lower limit? 1 second?*/ + context->tls_backoff_time = value; + + dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME); + + return GETDNS_RETURN_GOOD; +} /* getdns_context_set_tls_backoff_time */ + +/* + * getdns_context_set_tls_connection_retries + * + */ +getdns_return_t +getdns_context_set_tls_connection_retries(getdns_context *context, uint16_t value) +{ + RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); + /* Should we put a sensible upper limit on this? 10?*/ + // if (value > 10) { + // return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; + // } + + context->tls_connection_retries = value; + + dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES); + + return GETDNS_RETURN_GOOD; +} /* getdns_context_set_tls_connection retries */ #ifdef HAVE_LIBUNBOUND static void @@ -3493,6 +3529,10 @@ _get_context_settings(getdns_context* context) context->tls_auth) || getdns_dict_set_int(result, "round_robin_upstreams", context->round_robin_upstreams)) + || getdns_dict_set_int(result, "tls_backoff_time", + context->tls_backoff_time) + || getdns_dict_set_int(result, "tls_connection_retries", + context->tls_connection_retries)) goto error; /* list fields */ @@ -3797,6 +3837,24 @@ getdns_context_get_round_robin_upstreams(getdns_context *context, return GETDNS_RETURN_GOOD; } +getdns_return_t +getdns_context_get_tls_backoff_time(getdns_context *context, + uint16_t* value) { + RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); + RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); + *value = context->tls_backoff_time; + return GETDNS_RETURN_GOOD; +} + +getdns_return_t +getdns_context_get_tls_connection_retries(getdns_context *context, + uint16_t* value) { + RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); + RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); + *value = context->tls_connection_retries; + return GETDNS_RETURN_GOOD; +} + getdns_return_t getdns_context_get_limit_outstanding_queries(getdns_context *context, uint16_t* value) { @@ -4193,6 +4251,8 @@ _getdns_context_config_setting(getdns_context *context, CONTEXT_SETTING_INT(edns_client_subnet_private) CONTEXT_SETTING_INT(tls_authentication) CONTEXT_SETTING_INT(round_robin_upstreams) + CONTEXT_SETTING_INT(tls_backoff_time) + CONTEXT_SETTING_INT(tls_connection_retries) CONTEXT_SETTING_INT(tls_query_padding_blocksize) /**************************************/ diff --git a/src/context.h b/src/context.h index 3f4bf5df..91250648 100644 --- a/src/context.h +++ b/src/context.h @@ -218,6 +218,8 @@ typedef struct getdns_upstreams { size_t count; size_t current_udp; size_t current_stateful; + uint16_t tls_backoff_time; + uint16_t tls_connection_retries; getdns_upstream upstreams[]; } getdns_upstreams; @@ -250,6 +252,8 @@ struct getdns_context { getdns_tls_authentication_t tls_auth; /* What user requested for TLS*/ getdns_tls_authentication_t tls_auth_min; /* Derived minimum auth allowed*/ uint8_t round_robin_upstreams; + uint16_t tls_backoff_time; + uint16_t tls_connection_retries; getdns_transport_list_t *dns_transports; size_t dns_transport_count; diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index 2c03dcfc..8926ede2 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -78,6 +78,10 @@ extern "C" { #define GETDNS_CONTEXT_CODE_PUBKEY_PINSET_TEXT "Change related to getdns_context_set_pubkey_pinset" #define GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS 622 #define GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS_TEXT "Change related to getdns_context_set_pubkey_pinset" +#define GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME 623 +#define GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT "Change related to getdns_context_set_pubkey_pinset" +#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES 624 +#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT "Change related to getdns_context_set_pubkey_pinset" /** @} */ @@ -270,6 +274,12 @@ getdns_context_set_tls_authentication( getdns_return_t getdns_context_set_round_robin_upstreams(getdns_context *context, uint8_t value); +getdns_return_t +getdns_context_set_tls_backoff_time(getdns_context *context, uint16_t value); + +getdns_return_t +getdns_context_set_tls_connection_reuse(getdns_context *context, uint16_t value); + getdns_return_t getdns_context_set_edns_client_subnet_private(getdns_context *context, uint8_t value); @@ -365,6 +375,14 @@ getdns_return_t getdns_context_get_round_robin_upstreams(getdns_context *context, uint8_t* value); +getdns_return_t +getdns_context_get_tls_backoff_time(getdns_context *context, + uint16_t* value); + +getdns_return_t +getdns_context_get_tls_connection_retries(getdns_context *context, + uint16_t* value); + /** * Get the currently registered callback function and user defined argument * for context changes. diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index be63ec40..069a97e7 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -29,6 +29,8 @@ getdns_context_get_resolution_type getdns_context_get_suffix getdns_context_get_timeout getdns_context_get_tls_authentication +getdns_context_get_tls_backoff_time +getdns_context_get_tls_connection_retries getdns_context_get_tls_query_padding_blocksize getdns_context_get_round_robin_upstreams getdns_context_get_update_callback @@ -60,6 +62,8 @@ getdns_context_set_return_dnssec_status getdns_context_set_suffix getdns_context_set_timeout getdns_context_set_tls_authentication +getdns_context_set_tls_backoff_time +getdns_context_set_tls_connection_retries getdns_context_set_tls_query_padding_blocksize getdns_context_set_round_robin_upstreams getdns_context_set_update_callback diff --git a/src/stub.c b/src/stub.c index 6931e418..790b74cd 100644 --- a/src/stub.c +++ b/src/stub.c @@ -1669,7 +1669,8 @@ upstream_working_ok(getdns_upstream *upstream) { /* [TLS1]TODO: This arbitrary logic at the moment - review and improve!*/ return (upstream->responses_timeouts > - upstream->responses_received*GETDNS_CONN_ATTEMPTS ? 0 : 1); + upstream->responses_received* + upstream->upstreams->tls_connection_retries ? 0 : 1); } static int diff --git a/src/types-internal.h b/src/types-internal.h index 78f1935a..17e5b3fb 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -124,7 +124,6 @@ struct getdns_upstream; #define GETDNS_TRANSPORTS_MAX 3 #define GETDNS_UPSTREAM_TRANSPORTS 2 -#define GETDNS_CONN_ATTEMPTS 2 #define GETDNS_TRANSPORT_FAIL_MULT 5 From 68eadedc108e63e6fa1dfe06fc05c24a991fb10c Mon Sep 17 00:00:00 2001 From: Sara Dickinson Date: Fri, 17 Mar 2017 17:35:47 +0000 Subject: [PATCH 12/21] Fix rogue bracket --- src/context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context.c b/src/context.c index d80e5091..09edcbf1 100644 --- a/src/context.c +++ b/src/context.c @@ -3528,7 +3528,7 @@ _get_context_settings(getdns_context* context) || getdns_dict_set_int(result, "tls_authentication", context->tls_auth) || getdns_dict_set_int(result, "round_robin_upstreams", - context->round_robin_upstreams)) + context->round_robin_upstreams) || getdns_dict_set_int(result, "tls_backoff_time", context->tls_backoff_time) || getdns_dict_set_int(result, "tls_connection_retries", From 915689141b8db4821a37ac07e92d1add0705ad99 Mon Sep 17 00:00:00 2001 From: Sara Dickinson Date: Fri, 17 Mar 2017 17:47:30 +0000 Subject: [PATCH 13/21] Fix symbol order --- src/libgetdns.symbols | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index be63ec40..68057574 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -26,11 +26,11 @@ getdns_context_get_limit_outstanding_queries getdns_context_get_namespaces getdns_context_get_num_pending_requests getdns_context_get_resolution_type +getdns_context_get_round_robin_upstreams getdns_context_get_suffix getdns_context_get_timeout getdns_context_get_tls_authentication getdns_context_get_tls_query_padding_blocksize -getdns_context_get_round_robin_upstreams getdns_context_get_update_callback getdns_context_get_upstream_recursive_servers getdns_context_process_async @@ -57,11 +57,11 @@ getdns_context_set_memory_functions getdns_context_set_namespaces getdns_context_set_resolution_type getdns_context_set_return_dnssec_status +getdns_context_set_round_robin_upstreams getdns_context_set_suffix getdns_context_set_timeout getdns_context_set_tls_authentication getdns_context_set_tls_query_padding_blocksize -getdns_context_set_round_robin_upstreams getdns_context_set_update_callback getdns_context_set_upstream_recursive_servers getdns_context_set_use_threads From 1cf39c91345e461696b2b0092b35a6540a44e219 Mon Sep 17 00:00:00 2001 From: Sara Dickinson Date: Fri, 17 Mar 2017 18:33:33 +0000 Subject: [PATCH 14/21] Typo --- src/getdns/getdns_extra.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index 8926ede2..af53a5f2 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -278,7 +278,7 @@ getdns_return_t getdns_context_set_tls_backoff_time(getdns_context *context, uint16_t value); getdns_return_t -getdns_context_set_tls_connection_reuse(getdns_context *context, uint16_t value); +getdns_context_set_tls_connection_retries(getdns_context *context, uint16_t value); getdns_return_t getdns_context_set_edns_client_subnet_private(getdns_context *context, uint8_t value); From 8b09633c94cc3aabb1c42c5d4cc43b0af8ecf26b Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 20 Mar 2017 11:03:15 +0100 Subject: [PATCH 15/21] Bug and mem-leak fix --- .../280-limit_outstanding_queries.Makefile | 2 +- .../280-limit_outstanding_queries.c | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.Makefile b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.Makefile index c297df6d..70d86616 100644 --- a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.Makefile +++ b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.Makefile @@ -2,7 +2,7 @@ builddir = @BUILDDIR@ testname = @TPKG_NAME@ LIBTOOL = $(builddir)/libtool -CFLAGS=-I$(builddir)/src +CFLAGS=-Wall -Wextra -I$(builddir)/src LDLIBS=$(builddir)/src/libgetdns.la .SUFFIXES: .c .o .a .lo .h diff --git a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.c b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.c index 78107b57..1467ec34 100644 --- a/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.c +++ b/src/test/tpkg/280-limit_outstanding_queries.tpkg/280-limit_outstanding_queries.c @@ -64,12 +64,12 @@ void delay_cb(void *userarg) void handler(getdns_context *context, getdns_callback_type_t callback_type, getdns_dict *request, void *userarg, getdns_transaction_t request_id) { - transaction_t *trans; + transaction_t *trans = NULL; getdns_bindata *qname; char nreq_str[255]; - getdns_bindata nreq_bd = { 0, nreq_str }; + getdns_bindata nreq_bd = { 0, (void *)nreq_str }; - (void) userarg; + (void) userarg; (void)callback_type; nreq_bd.size = snprintf(nreq_str, sizeof(nreq_str), "n_requests: %d", ++n_requests); if (getdns_dict_get_bindata(request, "/question/qname", &qname) || @@ -83,8 +83,8 @@ void handler(getdns_context *context, getdns_callback_type_t callback_type, qname->data[3] == 'i' && qname->data[4] == 't') { (void) getdns_reply(context, request, request_id); - (void) getdns_context_set_listen_addresses(trans->context, NULL, NULL, NULL); - n_requests -= 1; + (void) getdns_context_set_listen_addresses(context, NULL, NULL, NULL); + getdns_dict_destroy(request); return; } else if (!(trans = malloc(sizeof(transaction_t)))) @@ -102,6 +102,8 @@ void handler(getdns_context *context, getdns_callback_type_t callback_type, fprintf(stderr, "Could not schedule delay\n"); else return; } + getdns_dict_destroy(trans->request); + if (trans) free(trans); exit(EXIT_FAILURE); } From 0891e16147d77d0bbe1a6c2cd8927776f9500977 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 20 Mar 2017 15:20:17 +0100 Subject: [PATCH 16/21] Pend netreqs when out of filedescriptors --- src/general.c | 17 +- src/stub.c | 32 +- .../285-out_of_filedescriptors.Makefile | 15 + .../285-out_of_filedescriptors.c | 143 +++ .../285-out_of_filedescriptors.dsc | 16 + .../285-out_of_filedescriptors.pre | 14 + .../285-out_of_filedescriptors.queries | 1000 +++++++++++++++++ .../285-out_of_filedescriptors.test | 48 + 8 files changed, 1276 insertions(+), 9 deletions(-) create mode 100644 src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.Makefile create mode 100644 src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.c create mode 100644 src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.dsc create mode 100644 src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.pre create mode 100644 src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.queries create mode 100644 src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.test diff --git a/src/general.c b/src/general.c index 14b7ee40..6ed44004 100644 --- a/src/general.c +++ b/src/general.c @@ -299,6 +299,7 @@ _getdns_netreq_change_state( { getdns_context *context; uint64_t now_ms; + getdns_network_req *prev; if (!netreq) return; @@ -317,12 +318,22 @@ _getdns_netreq_change_state( context->netreqs_in_flight -= 1; now_ms = 0; - while (context->limit_outstanding_queries > 0 && - context->pending_netreqs.count > 0 && - context->netreqs_in_flight < context->limit_outstanding_queries) { + prev = NULL; + while (context->pending_netreqs.count > 0 && + ( context->limit_outstanding_queries > context->netreqs_in_flight + || context->limit_outstanding_queries == 0 )) { getdns_network_req *first = (getdns_network_req *) _getdns_rbtree_first(&context->pending_netreqs); + + /* To prevent loops due to _getdns_submit_netreq re-inserting + * because of errno == EMFILE + */ + if (first == prev) + break; + else + prev = first; + (void) _getdns_rbtree_delete(&context->pending_netreqs, first); (void) _getdns_submit_netreq(first, &now_ms); } diff --git a/src/stub.c b/src/stub.c index 1fefaa8c..20695d25 100644 --- a/src/stub.c +++ b/src/stub.c @@ -54,15 +54,18 @@ typedef u_short sa_family_t; #define _getdns_EWOULDBLOCK (WSAGetLastError() == WSATRY_AGAIN ||\ WSAGetLastError() == WSAEWOULDBLOCK) #define _getdns_EINPROGRESS (WSAGetLastError() == WSAEINPROGRESS) +#define _getdns_EMFILE (WSAGetLastError() == WSAEMFILE) #else #define _getdns_EWOULDBLOCK (errno == EAGAIN || errno == EWOULDBLOCK) #define _getdns_EINPROGRESS (errno == EINPROGRESS) +#define _getdns_EMFILE (errno == EMFILE) #endif /* WSA TODO: * STUB_TCP_WOULDBLOCK added to deal with edge triggered event loops (versus * level triggered). See also lines containing WSA TODO below... */ +#define STUB_TRY_AGAIN_LATER -24 /* EMFILE, i.e. Out of OS resources */ #define STUB_NO_AUTH -8 /* Existing TLS connection is not authenticated */ #define STUB_CONN_GONE -7 /* Connection has failed, clear queue*/ #define STUB_TCP_WOULDBLOCK -6 @@ -1905,8 +1908,14 @@ upstream_find_for_netreq(getdns_network_req *netreq) upstream = upstream_find_for_transport(netreq, netreq->transports[i], &fd); - if (fd == -1 || !upstream) + if (!upstream) continue; + + if (fd == -1) { + if (_getdns_EMFILE) + return STUB_TRY_AGAIN_LATER; + return -1; + } netreq->transport_current = i; netreq->upstream = upstream; netreq->keepalive_sent = 0; @@ -2030,10 +2039,15 @@ upstream_schedule_netreq(getdns_upstream *upstream, getdns_network_req *netreq) getdns_return_t _getdns_submit_stub_request(getdns_network_req *netreq, uint64_t *now_ms) { + int fd = -1; + getdns_dns_req *dnsreq; + getdns_context *context; + DEBUG_STUB("%s %-35s: MSG: %p TYPE: %d\n", STUB_DEBUG_ENTRY, __FUNC__, (void*)netreq, netreq->request_type); - int fd = -1; - getdns_dns_req *dnsreq = netreq->owner; + + dnsreq = netreq->owner; + context = dnsreq->context; /* This does a best effort to get a initial fd. * All other set up is done async*/ @@ -2041,9 +2055,15 @@ _getdns_submit_stub_request(getdns_network_req *netreq, uint64_t *now_ms) if (fd == -1) return GETDNS_RETURN_NO_UPSTREAM_AVAILABLE; - getdns_transport_list_t transport = - netreq->transports[netreq->transport_current]; - switch(transport) { + else if (fd == STUB_TRY_AGAIN_LATER) { + _getdns_netreq_change_state(netreq, NET_REQ_NOT_SENT); + netreq->node.key = netreq; + if (_getdns_rbtree_insert( + &context->pending_netreqs, &netreq->node)) + return GETDNS_RETURN_GOOD; + return GETDNS_RETURN_NO_UPSTREAM_AVAILABLE; + } + switch(netreq->transports[netreq->transport_current]) { case GETDNS_TRANSPORT_UDP: netreq->fd = fd; GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event); diff --git a/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.Makefile b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.Makefile new file mode 100644 index 00000000..70d86616 --- /dev/null +++ b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.Makefile @@ -0,0 +1,15 @@ +builddir = @BUILDDIR@ +testname = @TPKG_NAME@ +LIBTOOL = $(builddir)/libtool + +CFLAGS=-Wall -Wextra -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 $(testname) $(testname).lo + diff --git a/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.c b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.c new file mode 100644 index 00000000..e495466d --- /dev/null +++ b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.c @@ -0,0 +1,143 @@ +/* + * delaydns.c - A DNS proxy that adds delay to replies + * + * Copyright (c) 2016, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * 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 name of the NLNET LABS 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 THE COPYRIGHT + * HOLDER OR CONTRIBUTORS 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. + */ + +#include +#include +#include + + +static int n_requests = 0; + +typedef struct transaction_t { + getdns_transaction_t request_id; + getdns_dict *request; + + getdns_context *context; + getdns_eventloop *loop; + getdns_eventloop_event ev; +} transaction_t; + + +void delay_cb(void *userarg) +{ + transaction_t *trans = userarg; + + trans->loop->vmt->clear(trans->loop, &trans->ev); + (void) getdns_reply(trans->context, trans->request, trans->request_id); + getdns_dict_destroy(trans->request); + free(trans); + n_requests -= 1; +} + +void handler(getdns_context *context, getdns_callback_type_t callback_type, + getdns_dict *request, void *userarg, getdns_transaction_t request_id) +{ + transaction_t *trans = NULL; + getdns_bindata *qname; + char nreq_str[255]; + getdns_bindata nreq_bd = { 0, (void *)nreq_str }; + + (void) userarg; (void)callback_type; + nreq_bd.size = snprintf(nreq_str, sizeof(nreq_str), "n_requests: %d", ++n_requests); + + if (getdns_dict_get_bindata(request, "/question/qname", &qname) || + getdns_dict_set_bindata(request, "/answer/0/name", qname) || + getdns_dict_set_int(request, "/answer/0/type", GETDNS_RRTYPE_TXT) || + getdns_dict_set_bindata(request, "/answer/0/rdata/txt_strings/-", &nreq_bd)) + fprintf(stderr, "Request init error\n"); + + else if (qname->size >= 6 && qname->data[0] == 4 && + qname->data[1] == 'q' && qname->data[2] == 'u' && + qname->data[3] == 'i' && qname->data[4] == 't') { + + (void) getdns_reply(context, request, request_id); + (void) getdns_context_set_listen_addresses(context, NULL, NULL, NULL); + getdns_dict_destroy(request); + return; + + } else if (!(trans = malloc(sizeof(transaction_t)))) + perror("memerror"); + else { + char *fqdn; + getdns_convert_dns_name_to_fqdn(qname, &fqdn); + + (void) memset(trans, 0, sizeof(transaction_t)); + trans->request_id = request_id; + trans->request = request; + trans->context = context; + trans->ev.userarg = trans; + trans->ev.timeout_cb = delay_cb; + + fprintf(stderr, "sched delay for query %s, n_request %d\n", fqdn, (int)n_requests); + free(fqdn); + if (getdns_context_get_eventloop(context, &trans->loop) + || trans->loop->vmt->schedule(trans->loop, -1, 300, &trans->ev)) + fprintf(stderr, "Could not schedule delay\n"); + else return; + } + getdns_dict_destroy(trans->request); + if (trans) free(trans); + exit(EXIT_FAILURE); +} + +int main() +{ + getdns_context *context = NULL; + getdns_list *listeners = NULL; + getdns_dict *address = NULL; + uint32_t port = 18000; + getdns_return_t r; + + if ((r = getdns_str2list("[ 127.0.0.1:18000 ]", &listeners)) || + (r = getdns_list_get_dict(listeners, 0, &address)) || + (r = getdns_context_create(&context, 0))) + fprintf(stderr, "Error initializing: "); + + else while (++port < 18200 && + !(r = getdns_dict_set_int(address, "port", port)) && + (r = getdns_context_set_listen_addresses( + context, listeners, NULL, handler))) + ; /* pass */ + + if (r) fprintf(stderr, "%s\n", getdns_get_errorstr_by_id(r)); + else { + fprintf(stdout, "%d\n", (int)port); + fflush(stdout); + getdns_context_run(context); + } + getdns_list_destroy(listeners); + getdns_context_destroy(context); + return r; +} diff --git a/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.dsc b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.dsc new file mode 100644 index 00000000..6b00775a --- /dev/null +++ b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.dsc @@ -0,0 +1,16 @@ +BaseName: 285-out_of_filedescriptors +Version: 1.0 +Description: Test if outstanding queries setting is obeyed +CreationDate: ma 20 mrt 2017 15:17:45 CET +Maintainer: Willem Toorop +Category: +Component: +CmdDepends: +Depends: 210-stub-only-link.tpkg +Help: +Pre: 285-out_of_filedescriptors.pre +Post: +Test: 285-out_of_filedescriptors.test +AuxFiles: +Passed: +Failure: diff --git a/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.pre b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.pre new file mode 100644 index 00000000..6e7ff3ff --- /dev/null +++ b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.pre @@ -0,0 +1,14 @@ +# #-- 285-out_of_filedescriptors.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 diff --git a/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.queries b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.queries new file mode 100644 index 00000000..0cc2103d --- /dev/null +++ b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.queries @@ -0,0 +1,1000 @@ +q1. +q2. +q3. +q4. +q5. +q6. +q7. +q8. +q9. +q10. +q11. +q12. +q13. +q14. +q15. +q16. +q17. +q18. +q19. +q20. +q21. +q22. +q23. +q24. +q25. +q26. +q27. +q28. +q29. +q30. +q31. +q32. +q33. +q34. +q35. +q36. +q37. +q38. +q39. +q40. +q41. +q42. +q43. +q44. +q45. +q46. +q47. +q48. +q49. +q50. +q51. +q52. +q53. +q54. +q55. +q56. +q57. +q58. +q59. +q60. +q61. +q62. +q63. +q64. +q65. +q66. +q67. +q68. +q69. +q70. +q71. +q72. +q73. +q74. +q75. +q76. +q77. +q78. +q79. +q80. +q81. +q82. +q83. +q84. +q85. +q86. +q87. +q88. +q89. +q90. +q91. +q92. +q93. +q94. +q95. +q96. +q97. +q98. +q99. +q100. +q101. +q102. +q103. +q104. +q105. +q106. +q107. +q108. +q109. +q110. +q111. +q112. +q113. +q114. +q115. +q116. +q117. +q118. +q119. +q120. +q121. +q122. +q123. +q124. +q125. +q126. +q127. +q128. +q129. +q130. +q131. +q132. +q133. +q134. +q135. +q136. +q137. +q138. +q139. +q140. +q141. +q142. +q143. +q144. +q145. +q146. +q147. +q148. +q149. +q150. +q151. +q152. +q153. +q154. +q155. +q156. +q157. +q158. +q159. +q160. +q161. +q162. +q163. +q164. +q165. +q166. +q167. +q168. +q169. +q170. +q171. +q172. +q173. +q174. +q175. +q176. +q177. +q178. +q179. +q180. +q181. +q182. +q183. +q184. +q185. +q186. +q187. +q188. +q189. +q190. +q191. +q192. +q193. +q194. +q195. +q196. +q197. +q198. +q199. +q200. +q201. +q202. +q203. +q204. +q205. +q206. +q207. +q208. +q209. +q210. +q211. +q212. +q213. +q214. +q215. +q216. +q217. +q218. +q219. +q220. +q221. +q222. +q223. +q224. +q225. +q226. +q227. +q228. +q229. +q230. +q231. +q232. +q233. +q234. +q235. +q236. +q237. +q238. +q239. +q240. +q241. +q242. +q243. +q244. +q245. +q246. +q247. +q248. +q249. +q250. +q251. +q252. +q253. +q254. +q255. +q256. +q257. +q258. +q259. +q260. +q261. +q262. +q263. +q264. +q265. +q266. +q267. +q268. +q269. +q270. +q271. +q272. +q273. +q274. +q275. +q276. +q277. +q278. +q279. +q280. +q281. +q282. +q283. +q284. +q285. +q286. +q287. +q288. +q289. +q290. +q291. +q292. +q293. +q294. +q295. +q296. +q297. +q298. +q299. +q300. +q301. +q302. +q303. +q304. +q305. +q306. +q307. +q308. +q309. +q310. +q311. +q312. +q313. +q314. +q315. +q316. +q317. +q318. +q319. +q320. +q321. +q322. +q323. +q324. +q325. +q326. +q327. +q328. +q329. +q330. +q331. +q332. +q333. +q334. +q335. +q336. +q337. +q338. +q339. +q340. +q341. +q342. +q343. +q344. +q345. +q346. +q347. +q348. +q349. +q350. +q351. +q352. +q353. +q354. +q355. +q356. +q357. +q358. +q359. +q360. +q361. +q362. +q363. +q364. +q365. +q366. +q367. +q368. +q369. +q370. +q371. +q372. +q373. +q374. +q375. +q376. +q377. +q378. +q379. +q380. +q381. +q382. +q383. +q384. +q385. +q386. +q387. +q388. +q389. +q390. +q391. +q392. +q393. +q394. +q395. +q396. +q397. +q398. +q399. +q400. +q401. +q402. +q403. +q404. +q405. +q406. +q407. +q408. +q409. +q410. +q411. +q412. +q413. +q414. +q415. +q416. +q417. +q418. +q419. +q420. +q421. +q422. +q423. +q424. +q425. +q426. +q427. +q428. +q429. +q430. +q431. +q432. +q433. +q434. +q435. +q436. +q437. +q438. +q439. +q440. +q441. +q442. +q443. +q444. +q445. +q446. +q447. +q448. +q449. +q450. +q451. +q452. +q453. +q454. +q455. +q456. +q457. +q458. +q459. +q460. +q461. +q462. +q463. +q464. +q465. +q466. +q467. +q468. +q469. +q470. +q471. +q472. +q473. +q474. +q475. +q476. +q477. +q478. +q479. +q480. +q481. +q482. +q483. +q484. +q485. +q486. +q487. +q488. +q489. +q490. +q491. +q492. +q493. +q494. +q495. +q496. +q497. +q498. +q499. +q500. +q501. +q502. +q503. +q504. +q505. +q506. +q507. +q508. +q509. +q510. +q511. +q512. +q513. +q514. +q515. +q516. +q517. +q518. +q519. +q520. +q521. +q522. +q523. +q524. +q525. +q526. +q527. +q528. +q529. +q530. +q531. +q532. +q533. +q534. +q535. +q536. +q537. +q538. +q539. +q540. +q541. +q542. +q543. +q544. +q545. +q546. +q547. +q548. +q549. +q550. +q551. +q552. +q553. +q554. +q555. +q556. +q557. +q558. +q559. +q560. +q561. +q562. +q563. +q564. +q565. +q566. +q567. +q568. +q569. +q570. +q571. +q572. +q573. +q574. +q575. +q576. +q577. +q578. +q579. +q580. +q581. +q582. +q583. +q584. +q585. +q586. +q587. +q588. +q589. +q590. +q591. +q592. +q593. +q594. +q595. +q596. +q597. +q598. +q599. +q600. +q601. +q602. +q603. +q604. +q605. +q606. +q607. +q608. +q609. +q610. +q611. +q612. +q613. +q614. +q615. +q616. +q617. +q618. +q619. +q620. +q621. +q622. +q623. +q624. +q625. +q626. +q627. +q628. +q629. +q630. +q631. +q632. +q633. +q634. +q635. +q636. +q637. +q638. +q639. +q640. +q641. +q642. +q643. +q644. +q645. +q646. +q647. +q648. +q649. +q650. +q651. +q652. +q653. +q654. +q655. +q656. +q657. +q658. +q659. +q660. +q661. +q662. +q663. +q664. +q665. +q666. +q667. +q668. +q669. +q670. +q671. +q672. +q673. +q674. +q675. +q676. +q677. +q678. +q679. +q680. +q681. +q682. +q683. +q684. +q685. +q686. +q687. +q688. +q689. +q690. +q691. +q692. +q693. +q694. +q695. +q696. +q697. +q698. +q699. +q700. +q701. +q702. +q703. +q704. +q705. +q706. +q707. +q708. +q709. +q710. +q711. +q712. +q713. +q714. +q715. +q716. +q717. +q718. +q719. +q720. +q721. +q722. +q723. +q724. +q725. +q726. +q727. +q728. +q729. +q730. +q731. +q732. +q733. +q734. +q735. +q736. +q737. +q738. +q739. +q740. +q741. +q742. +q743. +q744. +q745. +q746. +q747. +q748. +q749. +q750. +q751. +q752. +q753. +q754. +q755. +q756. +q757. +q758. +q759. +q760. +q761. +q762. +q763. +q764. +q765. +q766. +q767. +q768. +q769. +q770. +q771. +q772. +q773. +q774. +q775. +q776. +q777. +q778. +q779. +q780. +q781. +q782. +q783. +q784. +q785. +q786. +q787. +q788. +q789. +q790. +q791. +q792. +q793. +q794. +q795. +q796. +q797. +q798. +q799. +q800. +q801. +q802. +q803. +q804. +q805. +q806. +q807. +q808. +q809. +q810. +q811. +q812. +q813. +q814. +q815. +q816. +q817. +q818. +q819. +q820. +q821. +q822. +q823. +q824. +q825. +q826. +q827. +q828. +q829. +q830. +q831. +q832. +q833. +q834. +q835. +q836. +q837. +q838. +q839. +q840. +q841. +q842. +q843. +q844. +q845. +q846. +q847. +q848. +q849. +q850. +q851. +q852. +q853. +q854. +q855. +q856. +q857. +q858. +q859. +q860. +q861. +q862. +q863. +q864. +q865. +q866. +q867. +q868. +q869. +q870. +q871. +q872. +q873. +q874. +q875. +q876. +q877. +q878. +q879. +q880. +q881. +q882. +q883. +q884. +q885. +q886. +q887. +q888. +q889. +q890. +q891. +q892. +q893. +q894. +q895. +q896. +q897. +q898. +q899. +q900. +q901. +q902. +q903. +q904. +q905. +q906. +q907. +q908. +q909. +q910. +q911. +q912. +q913. +q914. +q915. +q916. +q917. +q918. +q919. +q920. +q921. +q922. +q923. +q924. +q925. +q926. +q927. +q928. +q929. +q930. +q931. +q932. +q933. +q934. +q935. +q936. +q937. +q938. +q939. +q940. +q941. +q942. +q943. +q944. +q945. +q946. +q947. +q948. +q949. +q950. +q951. +q952. +q953. +q954. +q955. +q956. +q957. +q958. +q959. +q960. +q961. +q962. +q963. +q964. +q965. +q966. +q967. +q968. +q969. +q970. +q971. +q972. +q973. +q974. +q975. +q976. +q977. +q978. +q979. +q980. +q981. +q982. +q983. +q984. +q985. +q986. +q987. +q988. +q989. +q990. +q991. +q992. +q993. +q994. +q995. +q996. +q997. +q998. +q999. +q1000. diff --git a/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.test b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.test new file mode 100644 index 00000000..64a53cfb --- /dev/null +++ b/src/test/tpkg/285-out_of_filedescriptors.tpkg/285-out_of_filedescriptors.test @@ -0,0 +1,48 @@ +# #-- 285-out_of_filedescriptors.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 + + +QLIMIT=79 +NQUERIES=`wc "./${TPKG_NAME}.queries"|sed 's/ .*$//g'` + +# This time the query limit is set by setting the maximum open +# filedescriptors. We seem to be needing a higher QLIMIT, than +# with limit_outstanding_queries unit test. +# +# 4 filedescriptors are already needed for overhead (logging etc), +# but experiments showed that to prevent timeouts, we should +# have a higher value than 72 at least. +# +# Test will take NQUERIES / QLIMIT * answer delay +# For current parameters this is 1000 / 75 * 0.3 = 4.0 +# which is smaller than 5 seconds default query timeout value, +# so the test should succeed. + +make && "./${TPKG_NAME}" | ( + read PORT + ulimit -n $QLIMIT + ${GETDNS_STUB_QUERY} @127.0.0.1:$PORT TXT \ + -a -F "./${TPKG_NAME}.queries" 2>&1 > out + + ${GETDNS_STUB_QUERY} -q @127.0.0.1:$PORT TXT quit. +) && grep '"n_requests: [0-9][0-9]*"' out | sed -e 's/^.*n_requests: //g' -e 's/".*$//g' \ + | awk -vQLIMIT=$QLIMIT -vNQUERIES=$NQUERIES ' + +BEGIN{ + max_outstanding = 0; +} +{ + if ($1 > max_outstanding) + max_outstanding = $1; +} +END{ + printf("%d of %d queries answered (%.1f%%)\n", NR, NQUERIES, (NR / NQUERIES * 100)); + if (max_outstanding > QLIMIT) { + print "ERROR: More than "QLIMIT" outstanding queries: "max_outstanding; + exit(-1); + } else + print "SUCCESS: No more than "QLIMIT" outstanding queries: "max_outstanding; +}' From 0048066a2a6c7e99f0767ce00f3293f88f6e3f7e Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 20 Mar 2017 16:15:02 +0100 Subject: [PATCH 17/21] Test op coding practices --- .../070-coding-practice.dsc | 16 ++++++++ .../070-coding-practice.pre | 14 +++++++ .../070-coding-practice.test | 40 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.dsc create mode 100644 src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.pre create mode 100644 src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.test diff --git a/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.dsc b/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.dsc new file mode 100644 index 00000000..b2101c47 --- /dev/null +++ b/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.dsc @@ -0,0 +1,16 @@ +BaseName: 070-coding-practice +Version: 1.0 +Description: Check for non-recommended coding practices +CreationDate: ma 20 mrt 2017 15:55:19 CET +Maintainer: Willem Toorop +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: 070-coding-practice.pre +Post: +Test: 070-coding-practice.test +AuxFiles: +Passed: +Failure: diff --git a/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.pre b/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.pre new file mode 100644 index 00000000..150497af --- /dev/null +++ b/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.pre @@ -0,0 +1,14 @@ +# #-- 070-coding-practice.pre--# +# source the master var file when it's there +if [ -f ../.tpkg.var.master ] +then + source ../.tpkg.var.master +else + ( + cd .. + [ -f "${TPKG_SRCDIR}/setup-env.sh" ] \ + && sh "${TPKG_SRCDIR}/setup-env.sh" + ) && source ../.tpkg.var.master +fi +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test diff --git a/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.test b/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.test new file mode 100644 index 00000000..b0360279 --- /dev/null +++ b/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.test @@ -0,0 +1,40 @@ +# #-- 070-coding-practice.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 + +rm -f report.txt +( + cd ${SRCROOT}/src + if [ `grep '[^!=]=[ ][ ]*NET_REQ_' *.[ch] */*.[ch] | wc -l` -gt 1 ] + then + echo "*** " + echo "*** Setting getdns_network_req->state should be done via" + echo "*** _getdns_netreq_change_state() only, for anticipating" + echo "*** running out of filedescriptors (sockets) and for the" + echo "*** limit_outstanding_queries feature." + echo "*** " + grep '[^!=]=[ ][ ]*NET_REQ_' *.[ch] */*.[ch] + echo "" + fi +) >> report.txt +( + cd ${SRCROOT}/src + if [ `grep '__FUNCTION__' *.[ch] */*.[ch] | wc -l` -gt 0 ] + then + echo "*** " + echo "*** Use __FUNC__ instead of __FUNCTION__ for portability" + echo "*** __FUNC__ is aliases in config.h to name to be used" + echo "*** for the system with a #define" + echo "*** " + grep '__FUNCION__' *.[ch] */*.[ch] + echo "" + fi +) >> report.txt + +if [ -s report.txt ] +then + cat report.txt + false +fi From a3fe9583879b7b510a1efb1662cb2fa14a643cb4 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 20 Mar 2017 16:41:57 +0100 Subject: [PATCH 18/21] Sync with unbound --- configure.ac | 9 ++ src/util/lookup3.c | 1 - src/util/lruhash.c | 173 ++++++++++++++++---------------- src/util/lruhash.h | 38 +------ src/util/orig-headers/lruhash.h | 32 ++++++ src/util/val_secalgo.c | 92 ++++++++++++++--- 6 files changed, 207 insertions(+), 138 deletions(-) diff --git a/configure.ac b/configure.ac index bb2fa22f..3cb6d24c 100644 --- a/configure.ac +++ b/configure.ac @@ -311,6 +311,15 @@ AC_INCLUDES_DEFAULT fi +AC_ARG_ENABLE(sha1, AC_HELP_STRING([--disable-sha1], [Disable SHA1 RRSIG support, does not disable nsec3 support])) + case "$enable_sha1" in + no) + ;; + yes|*) + AC_DEFINE([USE_SHA1], [1], [Define this to enable SHA1 support.]) + ;; +esac + AC_ARG_ENABLE(sha2, AC_HELP_STRING([--disable-sha2], [Disable SHA256 and SHA512 RRSIG support])) case "$enable_sha2" in no) diff --git a/src/util/lookup3.c b/src/util/lookup3.c index dedcdcaf..e9b05af3 100644 --- a/src/util/lookup3.c +++ b/src/util/lookup3.c @@ -45,7 +45,6 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy. /*#define SELF_TEST 1*/ #include "config.h" -#include "util/lookup3.h" #include "util/storage/lookup3.h" #include /* defines printf for tests */ #include /* defines time_t for timings in the test */ diff --git a/src/util/lruhash.c b/src/util/lruhash.c index fd091ef9..0003ff49 100644 --- a/src/util/lruhash.c +++ b/src/util/lruhash.c @@ -41,7 +41,6 @@ */ #include "config.h" -#include "util/lruhash.h" #include "util/storage/lruhash.h" #include "util/fptr_wlist.h" @@ -297,92 +296,6 @@ lru_touch(struct lruhash* table, struct lruhash_entry* entry) lru_front(table, entry); } - -/* - * Demote: the opposite of touch, move an entry to the bottom - * of the LRU pile. - */ - -void -lru_demote(struct lruhash* table, struct lruhash_entry* entry) -{ - log_assert(table && entry); - if (entry == table->lru_end) - return; /* nothing to do */ - /* remove from current lru position */ - lru_remove(table, entry); - /* add at end */ - entry->lru_next = NULL; - entry->lru_prev = table->lru_end; - - if (table->lru_end == NULL) - { - table->lru_start = entry; - } - else - { - table->lru_end->lru_next = entry; - } - table->lru_end = entry; -} - -struct lruhash_entry* -lruhash_insert_or_retrieve(struct lruhash* table, hashvalue_type hash, -struct lruhash_entry* entry, void* data, void* cb_arg) -{ - struct lruhash_bin* bin; - struct lruhash_entry* found, *reclaimlist = NULL; - size_t need_size; - fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc)); - fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc)); - fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc)); - fptr_ok(fptr_whitelist_hash_compfunc(table->compfunc)); - fptr_ok(fptr_whitelist_hash_markdelfunc(table->markdelfunc)); - need_size = table->sizefunc(entry->key, data); - if (cb_arg == NULL) cb_arg = table->cb_arg; - - /* find bin */ - lock_quick_lock(&table->lock); - bin = &table->array[hash & table->size_mask]; - lock_quick_lock(&bin->lock); - - /* see if entry exists already */ - if ((found = bin_find_entry(table, bin, hash, entry->key)) != NULL) { - /* if so: keep the existing data - acquire a writelock */ - lock_rw_wrlock(&found->lock); - } - else - { - /* if not: add to bin */ - entry->overflow_next = bin->overflow_list; - bin->overflow_list = entry; - lru_front(table, entry); - table->num++; - table->space_used += need_size; - /* return the entry that was presented, and lock it */ - found = entry; - lock_rw_wrlock(&found->lock); - } - lock_quick_unlock(&bin->lock); - if (table->space_used > table->space_max) - reclaim_space(table, &reclaimlist); - if (table->num >= table->size) - table_grow(table); - lock_quick_unlock(&table->lock); - - /* finish reclaim if any (outside of critical region) */ - while (reclaimlist) { - struct lruhash_entry* n = reclaimlist->overflow_next; - void* d = reclaimlist->data; - (*table->delkeyfunc)(reclaimlist->key, cb_arg); - (*table->deldatafunc)(d, cb_arg); - reclaimlist = n; - } - - /* return the entry that was selected */ - return found; -} - void lruhash_insert(struct lruhash* table, hashvalue_type hash, struct lruhash_entry* entry, void* data, void* cb_arg) @@ -630,3 +543,89 @@ lruhash_traverse(struct lruhash* h, int wr, } lock_quick_unlock(&h->lock); } + +/* + * Demote: the opposite of touch, move an entry to the bottom + * of the LRU pile. + */ + +void +lru_demote(struct lruhash* table, struct lruhash_entry* entry) +{ + log_assert(table && entry); + if (entry == table->lru_end) + return; /* nothing to do */ + /* remove from current lru position */ + lru_remove(table, entry); + /* add at end */ + entry->lru_next = NULL; + entry->lru_prev = table->lru_end; + + if (table->lru_end == NULL) + { + table->lru_start = entry; + } + else + { + table->lru_end->lru_next = entry; + } + table->lru_end = entry; +} + +struct lruhash_entry* +lruhash_insert_or_retrieve(struct lruhash* table, hashvalue_type hash, + struct lruhash_entry* entry, void* data, void* cb_arg) +{ + struct lruhash_bin* bin; + struct lruhash_entry* found, *reclaimlist = NULL; + size_t need_size; + fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc)); + fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc)); + fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc)); + fptr_ok(fptr_whitelist_hash_compfunc(table->compfunc)); + fptr_ok(fptr_whitelist_hash_markdelfunc(table->markdelfunc)); + need_size = table->sizefunc(entry->key, data); + if (cb_arg == NULL) cb_arg = table->cb_arg; + + /* find bin */ + lock_quick_lock(&table->lock); + bin = &table->array[hash & table->size_mask]; + lock_quick_lock(&bin->lock); + + /* see if entry exists already */ + if ((found = bin_find_entry(table, bin, hash, entry->key)) != NULL) { + /* if so: keep the existing data - acquire a writelock */ + lock_rw_wrlock(&found->lock); + } + else + { + /* if not: add to bin */ + entry->overflow_next = bin->overflow_list; + bin->overflow_list = entry; + lru_front(table, entry); + table->num++; + table->space_used += need_size; + /* return the entry that was presented, and lock it */ + found = entry; + lock_rw_wrlock(&found->lock); + } + lock_quick_unlock(&bin->lock); + if (table->space_used > table->space_max) + reclaim_space(table, &reclaimlist); + if (table->num >= table->size) + table_grow(table); + lock_quick_unlock(&table->lock); + + /* finish reclaim if any (outside of critical region) */ + while (reclaimlist) { + struct lruhash_entry* n = reclaimlist->overflow_next; + void* d = reclaimlist->data; + (*table->delkeyfunc)(reclaimlist->key, cb_arg); + (*table->deldatafunc)(d, cb_arg); + reclaimlist = n; + } + + /* return the entry that was selected */ + return found; +} + diff --git a/src/util/lruhash.h b/src/util/lruhash.h index 8c0d1a18..6796a68d 100644 --- a/src/util/lruhash.h +++ b/src/util/lruhash.h @@ -46,12 +46,13 @@ #define lruhash_delete _getdns_lruhash_delete #define lruhash_clear _getdns_lruhash_clear #define lruhash_insert _getdns_lruhash_insert -#define lruhash_insert_or_retrieve _getdns_lruhash_insert_or_retrieve #define lruhash_lookup _getdns_lruhash_lookup #define lru_touch _getdns_lru_touch -#define lru_demote _getdns_lru_demote #define lruhash_setmarkdel _getdns_lruhash_setmarkdel +#define lru_demote _getdns_lru_demote +#define lruhash_insert_or_retrieve _getdns_lruhash_insert_or_retrieve + #define lruhash_remove _getdns_lruhash_remove #define bin_init _getdns_bin_init #define bin_delete _getdns_bin_delete @@ -67,37 +68,4 @@ #define lruhash_traverse _getdns_lruhash_traverse #include "util/orig-headers/lruhash.h" - -/* - * Additional function definitions, not found in original header. - */ - - /** - * Demote entry, so it becomes the least recently used in the LRU list. - * Caller must hold hash table lock. The entry must be inserted already. - * @param table: hash table. - * @param entry: entry to make last in LRU. - */ -void lru_demote(struct lruhash* table, struct lruhash_entry* entry); - -/** - * Insert a new element into the hashtable, or retrieve the corresponding - * element of it exits. - * - * If key is already present data pointer in that entry is kept. - * If it is not present, a new entry is created. In that case, - * the space calculation function is called with the key, data. - * If necessary the least recently used entries are deleted to make space. - * If necessary the hash array is grown up. - * - * @param table: hash table. - * @param hash: hash value. User calculates the hash. - * @param entry: identifies the entry. - * @param data: the data. - * @param cb_override: if not null overrides the cb_arg for the deletefunc. - * @return: pointer to the existing entry if the key was already present, - * or to the entry argument if it was not. - */ -struct lruhash_entry* lruhash_insert_or_retrieve(struct lruhash* table, hashvalue_type hash, - struct lruhash_entry* entry, void* data, void* cb_arg); #endif diff --git a/src/util/orig-headers/lruhash.h b/src/util/orig-headers/lruhash.h index c3937408..af06b622 100644 --- a/src/util/orig-headers/lruhash.h +++ b/src/util/orig-headers/lruhash.h @@ -301,6 +301,38 @@ void lru_touch(struct lruhash* table, struct lruhash_entry* entry); */ void lruhash_setmarkdel(struct lruhash* table, lruhash_markdelfunc_type md); +/************************* getdns functions ************************/ +/*** these are used by getdns only and not by unbound. ***/ + +/** + * Demote entry, so it becomes the least recently used in the LRU list. + * Caller must hold hash table lock. The entry must be inserted already. + * @param table: hash table. + * @param entry: entry to make last in LRU. + */ +void lru_demote(struct lruhash* table, struct lruhash_entry* entry); + +/** + * Insert a new element into the hashtable, or retrieve the corresponding + * element of it exits. + * + * If key is already present data pointer in that entry is kept. + * If it is not present, a new entry is created. In that case, + * the space calculation function is called with the key, data. + * If necessary the least recently used entries are deleted to make space. + * If necessary the hash array is grown up. + * + * @param table: hash table. + * @param hash: hash value. User calculates the hash. + * @param entry: identifies the entry. + * @param data: the data. + * @param cb_override: if not null overrides the cb_arg for the deletefunc. + * @return: pointer to the existing entry if the key was already present, + * or to the entry argument if it was not. + */ +struct lruhash_entry* lruhash_insert_or_retrieve(struct lruhash* table, hashvalue_type hash, + struct lruhash_entry* entry, void* data, void* cb_arg); + /************************* Internal functions ************************/ /*** these are only exposed for unit tests. ***/ diff --git a/src/util/val_secalgo.c b/src/util/val_secalgo.c index 302820fc..be88ff43 100644 --- a/src/util/val_secalgo.c +++ b/src/util/val_secalgo.c @@ -74,6 +74,8 @@ /** fake DSA support for unit tests */ int fake_dsa = 0; +/** fake SHA1 support for unit tests */ +int fake_sha1 = 0; /* return size of digest if supported, or 0 otherwise */ size_t @@ -116,9 +118,12 @@ size_t ds_digest_size_supported(int algo) { switch(algo) { -#ifdef HAVE_EVP_SHA1 case LDNS_SHA1: +#if defined(HAVE_EVP_SHA1) && defined(USE_SHA1) return SHA_DIGEST_LENGTH; +#else + if(fake_sha1) return 20; + return 0; #endif #ifdef HAVE_EVP_SHA256 case LDNS_SHA256: @@ -158,7 +163,7 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len, unsigned char* res) { switch(algo) { -#ifdef HAVE_EVP_SHA1 +#if defined(HAVE_EVP_SHA1) && defined(USE_SHA1) case LDNS_SHA1: (void)SHA1(buf, len, res); return 1; @@ -197,14 +202,22 @@ dnskey_algo_id_is_supported(int id) return 0; case LDNS_DSA: case LDNS_DSA_NSEC3: -#ifdef USE_DSA +#if defined(USE_DSA) && defined(USE_SHA1) return 1; #else - if(fake_dsa) return 1; + if(fake_dsa || fake_sha1) return 1; return 0; #endif + case LDNS_RSASHA1: case LDNS_RSASHA1_NSEC3: +#ifdef USE_SHA1 + return 1; +#else + if(fake_sha1) return 1; + return 0; +#endif + #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) case LDNS_RSASHA256: #endif @@ -215,7 +228,10 @@ dnskey_algo_id_is_supported(int id) case LDNS_ECDSAP256SHA256: case LDNS_ECDSAP384SHA384: #endif +#if (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) || defined(USE_ECDSA) return 1; +#endif + #ifdef USE_GOST case LDNS_ECC_GOST: /* we support GOST if it can be loaded */ @@ -392,13 +408,13 @@ static int setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, unsigned char* key, size_t keylen) { -#ifdef USE_DSA +#if defined(USE_DSA) && defined(USE_SHA1) DSA* dsa; #endif RSA* rsa; switch(algo) { -#ifdef USE_DSA +#if defined(USE_DSA) && defined(USE_SHA1) case LDNS_DSA: case LDNS_DSA_NSEC3: *evp_key = EVP_PKEY_new(); @@ -424,9 +440,13 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, #endif break; -#endif /* USE_DSA */ +#endif /* USE_DSA && USE_SHA1 */ + +#if defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) +#ifdef USE_SHA1 case LDNS_RSASHA1: case LDNS_RSASHA1_NSEC3: +#endif #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) case LDNS_RSASHA256: #endif @@ -461,9 +481,14 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, *digest_type = EVP_sha512(); else #endif +#ifdef USE_SHA1 *digest_type = EVP_sha1(); - +#else + { verbose(VERB_QUERY, "no digest available"); return 0; } +#endif break; +#endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */ + case LDNS_RSAMD5: *evp_key = EVP_PKEY_new(); if(!*evp_key) { @@ -562,7 +587,11 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, EVP_PKEY *evp_key = NULL; #ifndef USE_DSA - if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && fake_dsa) + if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1)) + return sec_status_secure; +#endif +#ifndef USE_SHA1 + if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3)) return sec_status_secure; #endif @@ -706,8 +735,10 @@ ds_digest_size_supported(int algo) { /* uses libNSS */ switch(algo) { +#ifdef USE_SHA1 case LDNS_SHA1: return SHA1_LENGTH; +#endif #ifdef USE_SHA2 case LDNS_SHA256: return SHA256_LENGTH; @@ -729,9 +760,11 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len, { /* uses libNSS */ switch(algo) { +#ifdef USE_SHA1 case LDNS_SHA1: return HASH_HashBuf(HASH_AlgSHA1, res, buf, len) == SECSuccess; +#endif #if defined(USE_SHA2) case LDNS_SHA256: return HASH_HashBuf(HASH_AlgSHA256, res, buf, len) @@ -759,12 +792,15 @@ dnskey_algo_id_is_supported(int id) case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */ return 0; -#ifdef USE_DSA +#if defined(USE_SHA1) || defined(USE_SHA2) +#if defined(USE_DSA) && defined(USE_SHA1) case LDNS_DSA: case LDNS_DSA_NSEC3: #endif +#ifdef USE_SHA1 case LDNS_RSASHA1: case LDNS_RSASHA1_NSEC3: +#endif #ifdef USE_SHA2 case LDNS_RSASHA256: #endif @@ -772,6 +808,8 @@ dnskey_algo_id_is_supported(int id) case LDNS_RSASHA512: #endif return 1; +#endif /* SHA1 or SHA2 */ + #ifdef USE_ECDSA case LDNS_ECDSAP256SHA256: case LDNS_ECDSAP384SHA384: @@ -1003,7 +1041,9 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype, */ switch(algo) { -#ifdef USE_DSA + +#if defined(USE_SHA1) || defined(USE_SHA2) +#if defined(USE_DSA) && defined(USE_SHA1) case LDNS_DSA: case LDNS_DSA_NSEC3: *pubkey = nss_buf2dsa(key, keylen); @@ -1015,8 +1055,10 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype, /* no prefix for DSA verification */ break; #endif +#ifdef USE_SHA1 case LDNS_RSASHA1: case LDNS_RSASHA1_NSEC3: +#endif #ifdef USE_SHA2 case LDNS_RSASHA256: #endif @@ -1043,13 +1085,22 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype, *prefixlen = sizeof(p_sha512); } else #endif +#ifdef USE_SHA1 { *htype = HASH_AlgSHA1; *prefix = p_sha1; *prefixlen = sizeof(p_sha1); } +#else + { + verbose(VERB_QUERY, "verify: no digest algo"); + return 0; + } +#endif break; +#endif /* SHA1 or SHA2 */ + case LDNS_RSAMD5: *pubkey = nss_buf2rsa(key, keylen); if(!*pubkey) { @@ -1131,7 +1182,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, return sec_status_bogus; } -#ifdef USE_DSA +#if defined(USE_DSA) && defined(USE_SHA1) /* need to convert DSA, ECDSA signatures? */ if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) { if(sigblock_len == 1+2*SHA1_LENGTH) { @@ -1312,7 +1363,12 @@ ds_digest_size_supported(int algo) { switch(algo) { case LDNS_SHA1: +#ifdef USE_SHA1 return SHA1_DIGEST_SIZE; +#else + if(fake_sha1) return 20; + return 0; +#endif #ifdef USE_SHA2 case LDNS_SHA256: return SHA256_DIGEST_SIZE; @@ -1334,8 +1390,10 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len, unsigned char* res) { switch(algo) { +#ifdef USE_SHA1 case LDNS_SHA1: return _digest_nettle(SHA1_DIGEST_SIZE, buf, len, res); +#endif #if defined(USE_SHA2) case LDNS_SHA256: return _digest_nettle(SHA256_DIGEST_SIZE, buf, len, res); @@ -1359,12 +1417,14 @@ dnskey_algo_id_is_supported(int id) { /* uses libnettle */ switch(id) { -#ifdef USE_DSA +#if defined(USE_DSA) && defined(USE_SHA1) case LDNS_DSA: case LDNS_DSA_NSEC3: #endif +#ifdef USE_SHA1 case LDNS_RSASHA1: case LDNS_RSASHA1_NSEC3: +#endif #ifdef USE_SHA2 case LDNS_RSASHA256: case LDNS_RSASHA512: @@ -1381,7 +1441,7 @@ dnskey_algo_id_is_supported(int id) } } -#ifdef USE_DSA +#if defined(USE_DSA) && defined(USE_SHA1) static char * _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock, unsigned int sigblock_len, unsigned char* key, unsigned int keylen) @@ -1641,7 +1701,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, } switch(algo) { -#ifdef USE_DSA +#if defined(USE_DSA) && defined(USE_SHA1) case LDNS_DSA: case LDNS_DSA_NSEC3: *reason = _verify_nettle_dsa(buf, sigblock, sigblock_len, key, keylen); @@ -1651,9 +1711,11 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, return sec_status_secure; #endif /* USE_DSA */ +#ifdef USE_SHA1 case LDNS_RSASHA1: case LDNS_RSASHA1_NSEC3: digest_size = (digest_size ? digest_size : SHA1_DIGEST_SIZE); +#endif #ifdef USE_SHA2 case LDNS_RSASHA256: digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE); From 24abf43de17fff8d58f0ded804bc3b6def8b9947 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 20 Mar 2017 21:33:19 +0100 Subject: [PATCH 19/21] Fit mdns code with pending dns netreqs on EMFILE --- configure.ac | 5 ++++- src/general.c | 15 ++++++++++----- src/mdns.c | 14 +++++++------- src/request-internal.c | 1 + .../070-coding-practice.test | 5 +++-- src/types-internal.h | 1 + 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index 3cb6d24c..fa6a2436 100644 --- a/configure.ac +++ b/configure.ac @@ -1011,7 +1011,10 @@ fi #---- check for pthreads library -AC_SEARCH_LIBS([pthread_mutex_init],[pthread],[AC_DEFINE([HAVE_PTHREAD], [1], [Have pthreads library])], [AC_MSG_WARN([pthreads not available])]) +AC_SEARCH_LIBS([pthread_mutex_init],[pthread], [ + AC_DEFINE([HAVE_PTHREAD], [1], [Have pthreads library]) + LIBS="-lpthread $LIBS" +], [AC_MSG_WARN([pthreads not available])]) AC_MSG_CHECKING([whether the C compiler (${CC-cc}) supports the __func__ variable]) AC_LANG_PUSH(C) diff --git a/src/general.c b/src/general.c index 6ed44004..8d780eb7 100644 --- a/src/general.c +++ b/src/general.c @@ -110,7 +110,8 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) /* Do we have to check more suffixes on nxdomain/nodata? */ - if (dns_req->suffix_appended && /* Something was appended */ + if (dns_req->is_dns_request && + dns_req->suffix_appended && /* Something was appended */ dns_req->suffix_len > 1 && /* Next suffix available */ no_answer(dns_req)) { /* Remove suffix from name */ @@ -146,6 +147,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) return; } } else if ( + dns_req->is_dns_request && ( dns_req->append_name == GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE || dns_req->append_name == @@ -189,7 +191,9 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) dns_req->internal_cb(dns_req); } else if (! results_found) _getdns_call_user_callback(dns_req, NULL); - else if (dns_req->dnssec_return_validation_chain + else if ( + dns_req->is_dns_request && + (dns_req->dnssec_return_validation_chain #ifdef DNSSEC_ROADBLOCK_AVOIDANCE || ( dns_req->dnssec_roadblock_avoidance && !dns_req->avoid_dnssec_roadblocks) @@ -202,7 +206,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) dns_req->dnssec_return_all_statuses )) #endif - ) + )) _getdns_get_validation_chain(dns_req); else _getdns_call_user_callback( @@ -301,7 +305,7 @@ _getdns_netreq_change_state( uint64_t now_ms; getdns_network_req *prev; - if (!netreq) + if (!netreq || !netreq->owner->is_dns_request) return; context = netreq->owner->context; @@ -571,7 +575,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, if (!(r = _getdns_context_local_namespace_resolve( req, &localnames_response))) { - + req->is_dns_request = 0; _getdns_call_user_callback ( req, localnames_response); break; @@ -581,6 +585,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, /* Check whether the name belongs in the MDNS space */ if (!(r = _getdns_mdns_namespace_check(req))) { + req->is_dns_request = 0; // Submit the query to the MDNS transport. for (netreq_p = req->netreqs ; !r && (netreq = *netreq_p) diff --git a/src/mdns.c b/src/mdns.c index b18368ff..6373b265 100644 --- a/src/mdns.c +++ b/src/mdns.c @@ -513,7 +513,7 @@ static void msdn_cache_deldata(void* vdata, void* vcontext) /* TODO: treating as a timeout for now, may consider treating as error */ netreq->debug_end_time = _getdns_get_time_as_uintt64(); - netreq->state = NET_REQ_TIMED_OUT; + _getdns_netreq_change_state(netreq, NET_REQ_TIMED_OUT); if (netreq->owner->user_callback) { (void)_getdns_context_request_timed_out(netreq->owner); } @@ -1008,7 +1008,7 @@ mdns_complete_query_from_cache_entry( netreq->response_len = packet_length; netreq->debug_end_time = _getdns_get_time_as_uintt64(); - netreq->state = NET_REQ_FINISHED; + _getdns_netreq_change_state(netreq, NET_REQ_FINISHED); _getdns_check_dns_req_complete(netreq->owner); } else @@ -1016,7 +1016,7 @@ mdns_complete_query_from_cache_entry( /* Fail the query? */ netreq->response_len = 0; netreq->debug_end_time = _getdns_get_time_as_uintt64(); - netreq->state = NET_REQ_ERRORED; + _getdns_netreq_change_state(netreq, NET_REQ_ERRORED); _getdns_check_dns_req_complete(netreq->owner); } } @@ -1026,7 +1026,7 @@ mdns_complete_query_from_cache_entry( /* Failure */ netreq->response_len = 0; netreq->debug_end_time = _getdns_get_time_as_uintt64(); - netreq->state = NET_REQ_ERRORED; + _getdns_netreq_change_state(netreq, NET_REQ_ERRORED); _getdns_check_dns_req_complete(netreq->owner); } @@ -1085,7 +1085,7 @@ mdns_mcast_timeout_cb(void *userarg) int found = 0; DEBUG_MDNS("%s %-35s: MSG: %p\n", - MDNS_DEBUG_CLEANUP, __FUNCTION__, netreq); + MDNS_DEBUG_CLEANUP, __FUNC__, netreq); msdn_cache_create_key_in_buffer(temp_key, dnsreq->name, dnsreq->name_len, netreq->request_type, dnsreq->request_class); @@ -1113,7 +1113,7 @@ mdns_mcast_timeout_cb(void *userarg) /* Fail the request on timeout */ netreq->response_len = 0; netreq->debug_end_time = _getdns_get_time_as_uintt64(); - netreq->state = NET_REQ_ERRORED; + _getdns_netreq_change_state(netreq, NET_REQ_ERRORED); _getdns_check_dns_req_complete(netreq->owner); } } @@ -1128,7 +1128,7 @@ mdns_udp_multicast_read_cb(void *userarg) uint64_t current_time; ssize_t read; DEBUG_MDNS("%s %-35s: CTX: %p, NET=%d \n", MDNS_DEBUG_MREAD, - __FUNCTION__, cnx->context, cnx->addr_mcast.ss_family); + __FUNC__, cnx->context, cnx->addr_mcast.ss_family); current_time = _getdns_get_time_as_uintt64(); diff --git a/src/request-internal.c b/src/request-internal.c index 2259286e..a74fe8f0 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -938,6 +938,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, result->finished_next = NULL; result->freed = NULL; result->validating = 0; + result->is_dns_request = 1; result->chain = NULL; network_req_init(result->netreqs[0], result, diff --git a/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.test b/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.test index b0360279..b628a657 100644 --- a/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.test +++ b/src/test/tpkg/070-coding-practice.tpkg/070-coding-practice.test @@ -15,7 +15,8 @@ rm -f report.txt echo "*** running out of filedescriptors (sockets) and for the" echo "*** limit_outstanding_queries feature." echo "*** " - grep '[^!=]=[ ][ ]*NET_REQ_' *.[ch] */*.[ch] + grep -n '[^!=]=[ ][ ]*NET_REQ_' *.[ch] */*.[ch] | \ + grep -v '^request-internal.c:[12][0-9][0-9]: *net_req->state = NET_REQ_NOT_SENT;$' echo "" fi ) >> report.txt @@ -28,7 +29,7 @@ rm -f report.txt echo "*** __FUNC__ is aliases in config.h to name to be used" echo "*** for the system with a #define" echo "*** " - grep '__FUNCION__' *.[ch] */*.[ch] + grep -n '__FUNCTION__' *.[ch] */*.[ch] echo "" fi ) >> report.txt diff --git a/src/types-internal.h b/src/types-internal.h index ad1e9806..856651a3 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -313,6 +313,7 @@ typedef struct getdns_dns_req { /* Internally used by return_validation_chain */ unsigned dnssec_ok_checking_disabled : 1; unsigned is_sync_request : 1; + unsigned is_dns_request : 1; /* The validating and freed variables are used to make sure a single * code path is followed while processing a DNS request, even when From a77a3353704dbd9b833ca55a463468d4b2dbaefd Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 20 Mar 2017 21:57:57 +0100 Subject: [PATCH 20/21] Comment out dead assignement To silence static code analysis --- src/mdns.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mdns.c b/src/mdns.c index 6373b265..8a63f013 100644 --- a/src/mdns.c +++ b/src/mdns.c @@ -788,7 +788,9 @@ mdns_update_cache_ttl_and_prune(struct getdns_context *context, memmove(old_record + last_copied_index, old_record + current_hole_index, answer_index - current_hole_index); last_copied_index += answer_index - current_hole_index; - answer_index = last_copied_index; + + /* dead assignment */ + /* answer_index = last_copied_index; */ } /* if some records were deleted, update the record headers */ From a5876d57fea29647429cf7f13d5487bfac019969 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 20 Mar 2017 21:58:45 +0100 Subject: [PATCH 21/21] Dependencies --- spec/example/Makefile.in | 24 ++- src/Makefile.in | 434 +++++++++++++++++++++++++-------------- src/test/Makefile.in | 71 +++++-- src/tools/Makefile.in | 7 +- 4 files changed, 346 insertions(+), 190 deletions(-) diff --git a/spec/example/Makefile.in b/spec/example/Makefile.in index 7bf5e016..8ff7f2d1 100644 --- a/spec/example/Makefile.in +++ b/spec/example/Makefile.in @@ -149,16 +149,24 @@ depend: # Dependencies for the examples example-all-functions.lo example-all-functions.o: $(srcdir)/example-all-functions.c $(srcdir)/getdns_libevent.h \ - ../../src/config.h ../../src/getdns/getdns.h \ - $(srcdir)/../../src/getdns/getdns_ext_libevent.h ../../src/getdns/getdns_extra.h -example-reverse.lo example-reverse.o: $(srcdir)/example-reverse.c $(srcdir)/getdns_libevent.h ../../src/config.h \ - ../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ + ../../src/config.h \ + ../../src/getdns/getdns.h \ + $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ + ../../src/getdns/getdns_extra.h +example-reverse.lo example-reverse.o: $(srcdir)/example-reverse.c $(srcdir)/getdns_libevent.h \ + ../../src/config.h \ + ../../src/getdns/getdns.h \ + $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ ../../src/getdns/getdns_extra.h example-simple-answers.lo example-simple-answers.o: $(srcdir)/example-simple-answers.c $(srcdir)/getdns_libevent.h \ - ../../src/config.h ../../src/getdns/getdns.h \ - $(srcdir)/../../src/getdns/getdns_ext_libevent.h ../../src/getdns/getdns_extra.h + ../../src/config.h \ + ../../src/getdns/getdns.h \ + $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ + ../../src/getdns/getdns_extra.h example-synchronous.lo example-synchronous.o: $(srcdir)/example-synchronous.c $(srcdir)/getdns_core_only.h \ ../../src/getdns/getdns.h -example-tree.lo example-tree.o: $(srcdir)/example-tree.c $(srcdir)/getdns_libevent.h ../../src/config.h \ - ../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ +example-tree.lo example-tree.o: $(srcdir)/example-tree.c $(srcdir)/getdns_libevent.h \ + ../../src/config.h \ + ../../src/getdns/getdns.h \ + $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ ../../src/getdns/getdns_extra.h diff --git a/src/Makefile.in b/src/Makefile.in index 6497cc6a..c1cb8f12 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -216,169 +216,287 @@ depend: FORCE: # Dependencies for gldns, utils, the extensions and compat functions -const-info.lo const-info.o: $(srcdir)/const-info.c getdns/getdns.h getdns/getdns_extra.h \ - getdns/getdns.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 getdns/getdns.h getdns/getdns_extra.h \ - getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/server.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)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h \ - $(srcdir)/pubkey-pinning.h -convert.lo convert.o: $(srcdir)/convert.c config.h getdns/getdns.h getdns/getdns_extra.h \ - getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.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/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h -dict.lo dict.o: $(srcdir)/dict.c config.h $(srcdir)/types-internal.h getdns/getdns.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ - $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ - getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.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 $(srcdir)/gldns/parseutil.h -dnssec.lo dnssec.o: $(srcdir)/dnssec.c config.h $(srcdir)/debug.h getdns/getdns.h $(srcdir)/context.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/server.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)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ - $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h \ - $(srcdir)/list.h $(srcdir)/util/val_secalgo.h $(srcdir)/util/orig-headers/val_secalgo.h -general.lo general.o: $(srcdir)/general.c config.h $(srcdir)/general.h getdns/getdns.h $(srcdir)/types-internal.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \ - $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ - getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/server.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)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h $(srcdir)/mdns.h -list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \ - getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h \ - config.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h -mdns.lo mdns.o: $(srcdir)/mdns.c config.h $(srcdir)/debug.h $(srcdir)/context.h getdns/getdns.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/general.h $(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h \ - $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/mdns.h -pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c config.h $(srcdir)/debug.h getdns/getdns.h \ - $(srcdir)/context.h getdns/getdns.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h \ - config.h $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h \ - $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ - $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h -request-internal.lo request-internal.o: $(srcdir)/request-internal.c config.h $(srcdir)/types-internal.h \ - getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ - $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ - getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.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)/convert.h -rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h config.h getdns/getdns.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/util-internal.h $(srcdir)/context.h getdns/getdns_extra.h getdns/getdns.h \ +const-info.lo const-info.o: $(srcdir)/const-info.c \ + getdns/getdns.h \ + 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 \ + getdns/getdns.h \ + getdns/getdns_extra.h \ $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \ - $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ - getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ - $(srcdir)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h -rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h config.h getdns/getdns.h \ - $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h -server.lo server.o: $(srcdir)/server.c config.h getdns/getdns_extra.h getdns/getdns.h \ - $(srcdir)/context.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h -stub.lo stub.o: $(srcdir)/stub.c config.h $(srcdir)/debug.h $(srcdir)/stub.h getdns/getdns.h $(srcdir)/types-internal.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.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/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h -sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h config.h $(srcdir)/context.h getdns/getdns_extra.h \ - getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/general.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)/gldns/rrdef.h $(srcdir)/stub.h \ - $(srcdir)/gldns/wire2str.h -ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h config.h getdns/getdns.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h -util-internal.lo util-internal.o: $(srcdir)/util-internal.c config.h getdns/getdns.h $(srcdir)/dict.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/types-internal.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h \ - $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ - getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.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 $(srcdir)/dnssec.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 -keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c config.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h -parse.lo parse.o: $(srcdir)/gldns/parse.c config.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h \ - $(srcdir)/gldns/gbuffer.h -parseutil.lo parseutil.o: $(srcdir)/gldns/parseutil.c config.h $(srcdir)/gldns/parseutil.h -rrdef.lo rrdef.o: $(srcdir)/gldns/rrdef.c config.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h -str2wire.lo str2wire.o: $(srcdir)/gldns/str2wire.c config.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ - $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h -wire2str.lo wire2str.o: $(srcdir)/gldns/wire2str.c config.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h \ - $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/gldns/keyraw.h -arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c config.h -arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h -arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c config.h -explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h -getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h -getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h -getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h -getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c -gettimeofday.lo gettimeofday.o: $(srcdir)/compat/gettimeofday.c config.h -inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c config.h -inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c config.h -sha512.lo sha512.o: $(srcdir)/compat/sha512.c config.h -strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h -locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ - $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h -lookup3.lo lookup3.o: $(srcdir)/util/lookup3.c config.h $(srcdir)/util/auxiliary/util/storage/lookup3.h \ - $(srcdir)/util/lookup3.h $(srcdir)/util/orig-headers/lookup3.h -lruhash.lo lruhash.o: $(srcdir)/util/lruhash.c config.h $(srcdir)/util/auxiliary/util/storage/lruhash.h \ + $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.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)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h \ + $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h +convert.lo convert.o: $(srcdir)/convert.c \ + config.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h \ + $(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ $(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \ - $(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h \ - $(srcdir)/util/auxiliary/util/fptr_wlist.h -rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/auxiliary/log.h \ - $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h $(srcdir)/util/auxiliary/fptr_wlist.h \ - $(srcdir)/util/auxiliary/util/fptr_wlist.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h -val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c config.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)/gldns/wire2str.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 $(srcdir)/convert.h +dict.lo dict.o: $(srcdir)/dict.c \ + config.h \ + $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ + $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.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)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h \ + $(srcdir)/gldns/parseutil.h +dnssec.lo dnssec.o: $(srcdir)/dnssec.c \ + config.h \ + $(srcdir)/debug.h \ + getdns/getdns.h \ + $(srcdir)/context.h \ + getdns/getdns_extra.h \ + $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \ + $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.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)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h \ + $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h \ + $(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/util/val_secalgo.h \ + $(srcdir)/util/orig-headers/val_secalgo.h +general.lo general.o: $(srcdir)/general.c \ + config.h \ + $(srcdir)/general.h \ + getdns/getdns.h \ + $(srcdir)/types-internal.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h \ + $(srcdir)/gldns/wire2str.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \ + $(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.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)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h \ + $(srcdir)/mdns.h +list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h \ + config.h \ + $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.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)/list.h $(srcdir)/dict.h +mdns.lo mdns.o: $(srcdir)/mdns.c \ + config.h \ + $(srcdir)/debug.h $(srcdir)/context.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \ + $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/general.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \ + $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/mdns.h \ + $(srcdir)/util/auxiliary/util/fptr_wlist.h $(srcdir)/util/lookup3.h \ + $(srcdir)/util/orig-headers/lookup3.h +pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \ + config.h \ + $(srcdir)/debug.h \ + getdns/getdns.h \ + $(srcdir)/context.h \ + getdns/getdns_extra.h \ + $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \ + $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ + $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h +request-internal.lo request-internal.o: $(srcdir)/request-internal.c \ + config.h \ + $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ + $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.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)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h \ + $(srcdir)/convert.h $(srcdir)/general.h +rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h \ + config.h \ + getdns/getdns.h \ + $(srcdir)/gldns/gbuffer.h $(srcdir)/util-internal.h $(srcdir)/context.h \ + getdns/getdns_extra.h \ + $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \ + $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h +rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ + config.h \ + getdns/getdns.h \ + $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h +server.lo server.o: $(srcdir)/server.c \ + config.h \ + getdns/getdns_extra.h \ + getdns/getdns.h \ + $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \ + $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h +stub.lo stub.o: $(srcdir)/stub.c \ + config.h \ + $(srcdir)/debug.h $(srcdir)/stub.h \ + getdns/getdns.h \ + $(srcdir)/types-internal.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ + $(srcdir)/gldns/rrdef.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/default_eventloop.h \ + $(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \ + $(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \ + $(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h \ + $(srcdir)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h +sync.lo sync.o: $(srcdir)/sync.c \ + getdns/getdns.h \ + config.h \ + $(srcdir)/context.h \ + getdns/getdns_extra.h \ + $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \ + $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/general.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)/gldns/rrdef.h $(srcdir)/stub.h \ + $(srcdir)/gldns/wire2str.h +ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \ + config.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h +util-internal.lo util-internal.o: $(srcdir)/util-internal.c \ + config.h \ + getdns/getdns.h \ + $(srcdir)/dict.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/types-internal.h \ + getdns/getdns_extra.h \ + $(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \ + $(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ + $(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.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)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ + $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h +gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c \ + config.h \ + $(srcdir)/gldns/gbuffer.h +keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c \ + config.h \ + $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h +parse.lo parse.o: $(srcdir)/gldns/parse.c \ + config.h \ + $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h +parseutil.lo parseutil.o: $(srcdir)/gldns/parseutil.c \ + config.h \ + $(srcdir)/gldns/parseutil.h +rrdef.lo rrdef.o: $(srcdir)/gldns/rrdef.c \ + config.h \ + $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h +str2wire.lo str2wire.o: $(srcdir)/gldns/str2wire.c \ + config.h \ + $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h +wire2str.lo wire2str.o: $(srcdir)/gldns/wire2str.c \ + config.h \ + $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h \ + $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/keyraw.h +arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c \ + config.h +arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c \ + config.h \ + $(srcdir)/compat/chacha_private.h +arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c \ + config.h +explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c \ + config.h +getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c \ + config.h +getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c \ + config.h +getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c \ + config.h +getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c +gettimeofday.lo gettimeofday.o: $(srcdir)/compat/gettimeofday.c \ + config.h +inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c \ + config.h +inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c \ + config.h +sha512.lo sha512.o: $(srcdir)/compat/sha512.c \ + config.h +strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c \ + config.h +locks.lo locks.o: $(srcdir)/util/locks.c \ + config.h \ + $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h +lookup3.lo lookup3.o: $(srcdir)/util/lookup3.c \ + config.h \ + $(srcdir)/util/auxiliary/util/storage/lookup3.h $(srcdir)/util/lookup3.h \ + $(srcdir)/util/orig-headers/lookup3.h +lruhash.lo lruhash.o: $(srcdir)/util/lruhash.c \ + config.h \ + $(srcdir)/util/auxiliary/util/storage/lruhash.h $(srcdir)/util/lruhash.h \ + $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util/auxiliary/util/fptr_wlist.h +rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c \ + config.h \ + $(srcdir)/util/auxiliary/log.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h \ + $(srcdir)/util/auxiliary/fptr_wlist.h $(srcdir)/util/auxiliary/util/fptr_wlist.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h +val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c \ + config.h \ $(srcdir)/util/auxiliary/util/data/packed_rrset.h \ $(srcdir)/util/auxiliary/validator/val_secalgo.h $(srcdir)/util/val_secalgo.h \ $(srcdir)/util/orig-headers/val_secalgo.h $(srcdir)/util/auxiliary/validator/val_nsec3.h \ - $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h $(srcdir)/util/auxiliary/sldns/rrdef.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util/auxiliary/sldns/rrdef.h \ $(srcdir)/gldns/rrdef.h $(srcdir)/util/auxiliary/sldns/keyraw.h $(srcdir)/gldns/keyraw.h \ $(srcdir)/util/auxiliary/sldns/sbuffer.h $(srcdir)/gldns/gbuffer.h jsmn.lo jsmn.o: $(srcdir)/jsmn/jsmn.c $(srcdir)/jsmn/jsmn.h -libev.lo libev.o: $(srcdir)/extension/libev.c config.h $(srcdir)/types-internal.h getdns/getdns.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h \ - getdns/getdns_extra.h -libevent.lo libevent.o: $(srcdir)/extension/libevent.c config.h $(srcdir)/types-internal.h \ - getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h \ - getdns/getdns_extra.h -libuv.lo libuv.o: $(srcdir)/extension/libuv.c config.h $(srcdir)/debug.h config.h $(srcdir)/types-internal.h \ - getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h \ - getdns/getdns_extra.h -poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns.h getdns/getdns_extra.h \ - $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h config.h -select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c config.h \ - $(srcdir)/extension/select_eventloop.h getdns/getdns.h getdns/getdns_extra.h \ - $(srcdir)/debug.h config.h $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h +libev.lo libev.o: $(srcdir)/extension/libev.c \ + config.h \ + $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h +libevent.lo libevent.o: $(srcdir)/extension/libevent.c \ + config.h \ + $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h +libuv.lo libuv.o: $(srcdir)/extension/libuv.c \ + config.h \ + $(srcdir)/debug.h $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h +poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c \ + config.h \ + $(srcdir)/extension/poll_eventloop.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h +select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c \ + config.h \ + $(srcdir)/extension/select_eventloop.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/debug.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h diff --git a/src/test/Makefile.in b/src/test/Makefile.in index c481fdab..758435c1 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -216,10 +216,13 @@ depend: .PHONY: clean test # Dependencies for the unit tests -check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c ../getdns/getdns.h $(srcdir)/check_getdns_common.h \ - ../getdns/getdns_extra.h $(srcdir)/check_getdns_address.h \ - $(srcdir)/check_getdns_address_sync.h $(srcdir)/check_getdns_cancel_callback.h \ - $(srcdir)/check_getdns_context_create.h $(srcdir)/check_getdns_context_destroy.h \ +check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c \ + ../getdns/getdns.h \ + $(srcdir)/check_getdns_common.h \ + ../getdns/getdns_extra.h \ + $(srcdir)/check_getdns_address.h $(srcdir)/check_getdns_address_sync.h \ + $(srcdir)/check_getdns_cancel_callback.h $(srcdir)/check_getdns_context_create.h \ + $(srcdir)/check_getdns_context_destroy.h \ $(srcdir)/check_getdns_context_set_context_update_callback.h \ $(srcdir)/check_getdns_context_set_dns_transport.h \ $(srcdir)/check_getdns_context_set_timeout.h \ @@ -239,34 +242,58 @@ check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c ../getdns/getdns.h $(sr $(srcdir)/check_getdns_list_get_list.h $(srcdir)/check_getdns_pretty_print_dict.h \ $(srcdir)/check_getdns_service.h $(srcdir)/check_getdns_service_sync.h \ $(srcdir)/check_getdns_transport.h -check_getdns_common.lo check_getdns_common.o: $(srcdir)/check_getdns_common.c ../getdns/getdns.h \ - ../config.h $(srcdir)/check_getdns_common.h ../getdns/getdns_extra.h \ +check_getdns_common.lo check_getdns_common.o: $(srcdir)/check_getdns_common.c \ + ../getdns/getdns.h \ + ../config.h \ + $(srcdir)/check_getdns_common.h \ + ../getdns/getdns_extra.h \ $(srcdir)/check_getdns_eventloop.h check_getdns_context_set_timeout.lo check_getdns_context_set_timeout.o: $(srcdir)/check_getdns_context_set_timeout.c \ $(srcdir)/check_getdns_context_set_timeout.h $(srcdir)/check_getdns_common.h \ - ../getdns/getdns.h ../getdns/getdns_extra.h + ../getdns/getdns.h \ + ../getdns/getdns_extra.h check_getdns_libev.lo check_getdns_libev.o: $(srcdir)/check_getdns_libev.c $(srcdir)/check_getdns_eventloop.h \ - ../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libev.h \ - ../getdns/getdns_extra.h $(srcdir)/check_getdns_common.h + ../config.h \ + ../getdns/getdns.h \ + $(srcdir)/../getdns/getdns_ext_libev.h \ + ../getdns/getdns_extra.h \ + $(srcdir)/check_getdns_common.h check_getdns_libevent.lo check_getdns_libevent.o: $(srcdir)/check_getdns_libevent.c $(srcdir)/check_getdns_eventloop.h \ - ../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libevent.h \ - ../getdns/getdns_extra.h $(srcdir)/check_getdns_libevent.h $(srcdir)/check_getdns_common.h + ../config.h \ + ../getdns/getdns.h \ + $(srcdir)/../getdns/getdns_ext_libevent.h \ + ../getdns/getdns_extra.h \ + $(srcdir)/check_getdns_libevent.h $(srcdir)/check_getdns_common.h check_getdns_libuv.lo check_getdns_libuv.o: $(srcdir)/check_getdns_libuv.c $(srcdir)/check_getdns_eventloop.h \ - ../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libuv.h \ - ../getdns/getdns_extra.h $(srcdir)/check_getdns_common.h + ../config.h \ + ../getdns/getdns.h \ + $(srcdir)/../getdns/getdns_ext_libuv.h \ + ../getdns/getdns_extra.h \ + $(srcdir)/check_getdns_common.h check_getdns_selectloop.lo check_getdns_selectloop.o: $(srcdir)/check_getdns_selectloop.c \ - $(srcdir)/check_getdns_eventloop.h ../config.h ../getdns/getdns.h \ + $(srcdir)/check_getdns_eventloop.h \ + ../config.h \ + ../getdns/getdns.h \ ../getdns/getdns_extra.h check_getdns_transport.lo check_getdns_transport.o: $(srcdir)/check_getdns_transport.c \ - $(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h ../getdns/getdns.h \ + $(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h \ + ../getdns/getdns.h \ ../getdns/getdns_extra.h -scratchpad.template.lo scratchpad.template.o: scratchpad.template.c ../getdns/getdns.h \ +scratchpad.template.lo scratchpad.template.o: scratchpad.template.c \ + ../getdns/getdns.h \ ../getdns/getdns_extra.h testmessages.lo testmessages.o: $(srcdir)/testmessages.c $(srcdir)/testmessages.h -tests_dict.lo tests_dict.o: $(srcdir)/tests_dict.c $(srcdir)/testmessages.h ../getdns/getdns.h -tests_list.lo tests_list.o: $(srcdir)/tests_list.c $(srcdir)/testmessages.h ../getdns/getdns.h -tests_namespaces.lo tests_namespaces.o: $(srcdir)/tests_namespaces.c $(srcdir)/testmessages.h ../getdns/getdns.h -tests_stub_async.lo tests_stub_async.o: $(srcdir)/tests_stub_async.c ../config.h $(srcdir)/testmessages.h \ - ../getdns/getdns.h ../getdns/getdns_extra.h -tests_stub_sync.lo tests_stub_sync.o: $(srcdir)/tests_stub_sync.c $(srcdir)/testmessages.h ../getdns/getdns.h \ +tests_dict.lo tests_dict.o: $(srcdir)/tests_dict.c $(srcdir)/testmessages.h \ + ../getdns/getdns.h +tests_list.lo tests_list.o: $(srcdir)/tests_list.c $(srcdir)/testmessages.h \ + ../getdns/getdns.h +tests_namespaces.lo tests_namespaces.o: $(srcdir)/tests_namespaces.c $(srcdir)/testmessages.h \ + ../getdns/getdns.h +tests_stub_async.lo tests_stub_async.o: $(srcdir)/tests_stub_async.c \ + ../config.h \ + $(srcdir)/testmessages.h \ + ../getdns/getdns.h \ + ../getdns/getdns_extra.h +tests_stub_sync.lo tests_stub_sync.o: $(srcdir)/tests_stub_sync.c $(srcdir)/testmessages.h \ + ../getdns/getdns.h \ ../getdns/getdns_extra.h diff --git a/src/tools/Makefile.in b/src/tools/Makefile.in index d98cf437..d066e824 100644 --- a/src/tools/Makefile.in +++ b/src/tools/Makefile.in @@ -113,5 +113,8 @@ depend: .PHONY: clean test # Dependencies for getdns_query -getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c ../config.h $(srcdir)/../debug.h ../config.h \ - ../getdns/getdns.h ../getdns/getdns_extra.h +getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c \ + ../config.h \ + $(srcdir)/../debug.h \ + ../getdns/getdns.h \ + ../getdns/getdns_extra.h