mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4014e2aec4 | ||
|
|
f3c9be889f | ||
|
|
cd3ebb7e72 | ||
|
|
f531faf163 | ||
|
|
c0c9acccfd | ||
|
|
17e5dd6131 | ||
|
|
e9107907e5 | ||
|
|
ba8642aeb7 | ||
|
|
5ffa4d7232 | ||
|
|
2571d00535 | ||
|
|
f9a563d495 | ||
|
|
08dcae0dab | ||
|
|
5ac1bc13cb | ||
|
|
f5e1ef650d | ||
|
|
4f27799456 | ||
|
|
97d1cff315 |
@@ -390,6 +390,15 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
|
||||
if(!qstate->return_msg || !qstate->return_msg->rep)
|
||||
return 0;
|
||||
/* do not store failures like SERVFAIL in the cachedb, this avoids
|
||||
* overwriting expired, valid, content with broken content. */
|
||||
if(FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
|
||||
LDNS_RCODE_NOERROR &&
|
||||
FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
|
||||
LDNS_RCODE_NXDOMAIN &&
|
||||
FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
|
||||
LDNS_RCODE_YXDOMAIN)
|
||||
return 0;
|
||||
/* We don't store the reply if its TTL is 0 unless serve-expired is
|
||||
* enabled. Such a reply won't be reusable and simply be a waste for
|
||||
* the backend. It's also compatible with the default behavior of
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.17.0.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.17.1.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
|
||||
#
|
||||
@@ -591,8 +591,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.17.0'
|
||||
PACKAGE_STRING='unbound 1.17.0'
|
||||
PACKAGE_VERSION='1.17.1'
|
||||
PACKAGE_STRING='unbound 1.17.1'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1477,7 +1477,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures unbound 1.17.0 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.17.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1543,7 +1543,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.17.0:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.17.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1785,7 +1785,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.17.0
|
||||
unbound configure 1.17.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2494,7 +2494,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by unbound $as_me 1.17.0, which was
|
||||
It was created by unbound $as_me 1.17.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -2846,11 +2846,11 @@ UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=17
|
||||
|
||||
UNBOUND_VERSION_MICRO=0
|
||||
UNBOUND_VERSION_MICRO=1
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=20
|
||||
LIBUNBOUND_REVISION=21
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -2938,6 +2938,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.16.2 had 9:18:1
|
||||
# 1.16.3 had 9:19:1
|
||||
# 1.17.0 had 9:20:1
|
||||
# 1.17.1 had 9:21:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -22085,7 +22086,7 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
version=1.17.0
|
||||
version=1.17.1
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
@@ -22604,7 +22605,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by unbound $as_me 1.17.0, which was
|
||||
This file was extended by unbound $as_me 1.17.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -22670,7 +22671,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
unbound config.status 1.17.0
|
||||
unbound config.status 1.17.1
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+3
-2
@@ -11,14 +11,14 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[17])
|
||||
m4_define([VERSION_MICRO],[0])
|
||||
m4_define([VERSION_MICRO],[1])
|
||||
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=20
|
||||
LIBUNBOUND_REVISION=21
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -106,6 +106,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.16.2 had 9:18:1
|
||||
# 1.16.3 had 9:19:1
|
||||
# 1.17.0 had 9:20:1
|
||||
# 1.17.1 had 9:21:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
|
||||
@@ -1,7 +1,31 @@
|
||||
21 October 2022: George
|
||||
- Merge #767 from jonathangray: consistently use IPv4/IPv6 in
|
||||
unbound.conf.5.
|
||||
|
||||
21 October 2022: Wouter
|
||||
- Fix that cachedb does not store failures in the external cache.
|
||||
|
||||
18 October 2022: George
|
||||
- Clarify the use of MAX_SENT_COUNT in the iterator code.
|
||||
|
||||
17 October 2022: Wouter
|
||||
- testcode/dohclient sets log identity to its name.
|
||||
|
||||
14 October 2022: Wouter
|
||||
- Merge #768 from fobser: Arithmetic on a pointer to void is a GNU
|
||||
extension.
|
||||
- In unit test, print python script name list correctly.
|
||||
|
||||
13 October 2022: Wouter
|
||||
- Tag for 1.17.0 release. The code repository continues with 1.17.1.
|
||||
|
||||
11 October 2022: George
|
||||
- Fix PROXYv2 header read for TCP connections when no proxied addresses
|
||||
are provided.
|
||||
|
||||
7 October 2022: Wouter
|
||||
- Tag for 1.17.0rc1 release.
|
||||
|
||||
7 October 2022: George
|
||||
- Fix to stop possible loops in the tcp reuse code (write_wait list
|
||||
and tcp_wait list). Based on analysis and patch from Prad Seniappan
|
||||
|
||||
@@ -349,7 +349,7 @@ ip\-transparent option is also available.
|
||||
The value of the Differentiated Services Codepoint (DSCP) in the
|
||||
differentiated services field (DS) of the outgoing IP packet headers.
|
||||
The field replaces the outdated IPv4 Type-Of-Service field and the
|
||||
IPV6 traffic class field.
|
||||
IPv6 traffic class field.
|
||||
.TP
|
||||
.B rrset\-cache\-size: \fI<number>
|
||||
Number of bytes size of the RRset cache. Default is 4 megabytes.
|
||||
@@ -416,7 +416,7 @@ Enable or disable whether ip4 queries are answered or issued. Default is yes.
|
||||
Enable or disable whether ip6 queries are answered or issued. Default is yes.
|
||||
If disabled, queries are not answered on IPv6, and queries are not sent on
|
||||
IPv6 to the internet nameservers. With this option you can disable the
|
||||
ipv6 transport for sending DNS traffic, it does not impact the contents of
|
||||
IPv6 transport for sending DNS traffic, it does not impact the contents of
|
||||
the DNS traffic, which may have ip4 and ip6 addresses in it.
|
||||
.TP
|
||||
.B prefer\-ip4: \fI<yes or no>
|
||||
@@ -1671,7 +1671,7 @@ This specifies the action data for \fIresponse-ip\fR with action being
|
||||
to redirect as specified by "\fIresource record string\fR". "Resource
|
||||
record string" is similar to that of \fIaccess-control-tag-action\fR,
|
||||
but it must be of either AAAA, A or CNAME types.
|
||||
If the IP-netblock is an IPv6/IPV4 prefix, the record
|
||||
If the IP-netblock is an IPv6/IPv4 prefix, the record
|
||||
must be AAAA/A respectively, unless it is a CNAME (which can be used
|
||||
for both versions of IP netblocks). If it is CNAME there must not be
|
||||
more than one \fIresponse-ip-data\fR for the same IP-netblock.
|
||||
|
||||
@@ -2276,7 +2276,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->num_current_queries, iq->sent_count);
|
||||
|
||||
/* Make sure that we haven't run away */
|
||||
/* FIXME: is this check even necessary? */
|
||||
if(iq->referral_count > MAX_REFERRAL_COUNT) {
|
||||
verbose(VERB_QUERY, "request has exceeded the maximum "
|
||||
"number of referrrals with %d", iq->referral_count);
|
||||
|
||||
+2
-1
@@ -67,7 +67,8 @@ struct rbtree_type;
|
||||
#define MAX_RESTART_COUNT 11
|
||||
/** max number of referrals. Makes sure resolver does not run away */
|
||||
#define MAX_REFERRAL_COUNT 130
|
||||
/** max number of queries-sent-out. Make sure large NS set does not loop */
|
||||
/** max number of queries-sent-out. Make sure large NS set does not loop.
|
||||
* Resets on query restarts (e.g., CNAMES) and referrals. */
|
||||
#define MAX_SENT_COUNT 32
|
||||
/** max number of queries for which to perform dnsseclameness detection,
|
||||
* (rrsigs missing detection) after that, just pick up that response */
|
||||
|
||||
+36
-1
@@ -53,6 +53,7 @@
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/edns.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/wire2str.h"
|
||||
|
||||
int
|
||||
context_finalize(struct ub_ctx* ctx)
|
||||
@@ -144,9 +145,17 @@ find_id(struct ub_ctx* ctx, int* id)
|
||||
|
||||
struct ctx_query*
|
||||
context_new(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass,
|
||||
ub_callback_type cb, ub_event_callback_type cb_event, void* cbarg)
|
||||
ub_callback_type cb, ub_event_callback_type cb_event, void* cbarg,
|
||||
const uint8_t* qbuf, size_t qbuf_len)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q));
|
||||
char qname_str_buf[1024];
|
||||
char *qname_str = qname_str_buf;
|
||||
size_t qname_str_len = sizeof(qname_str_buf);
|
||||
uint8_t *qname;
|
||||
size_t qname_len;
|
||||
int comprloop;
|
||||
|
||||
if(!q) return NULL;
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(!find_id(ctx, &q->querynum)) {
|
||||
@@ -165,6 +174,32 @@ context_new(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass,
|
||||
free(q);
|
||||
return NULL;
|
||||
}
|
||||
if(!name && qbuf) {
|
||||
if(qbuf_len < 12) {
|
||||
free(q->res);
|
||||
free(q);
|
||||
return NULL;
|
||||
}
|
||||
qname = (uint8_t* )qbuf + 12;
|
||||
qname_len = qbuf_len - 12;
|
||||
comprloop = 0;
|
||||
|
||||
/* get query name from the input buffer */
|
||||
sldns_wire2str_dname_scan(
|
||||
&qname, &qname_len,
|
||||
&qname_str, &qname_str_len,
|
||||
(uint8_t *)qbuf, qbuf_len,
|
||||
&comprloop);
|
||||
*qname_str = 0;
|
||||
name = qname_str_buf;
|
||||
if (qname_len < 4) {
|
||||
free(q->res);
|
||||
free(q);
|
||||
return NULL;
|
||||
}
|
||||
rrtype = sldns_read_uint16(qname);
|
||||
rrclass = sldns_read_uint16(qname + 2);
|
||||
}
|
||||
q->res->qname = strdup(name);
|
||||
if(!q->res->qname) {
|
||||
free(q->res);
|
||||
|
||||
@@ -171,6 +171,11 @@ struct ctx_query {
|
||||
/** store libworker that is handling this query */
|
||||
struct libworker* w;
|
||||
|
||||
/** raw query packet */
|
||||
const uint8_t *qbuf;
|
||||
/** length of raw query packet */
|
||||
size_t qbuf_len;
|
||||
|
||||
/** result structure, also contains original query, type, class.
|
||||
* malloced ptr ready to hand to the client. */
|
||||
struct ub_result* res;
|
||||
@@ -224,7 +229,7 @@ void context_query_delete(struct ctx_query* q);
|
||||
*/
|
||||
struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
int rrclass, ub_callback_type cb, ub_event_callback_type cb_event,
|
||||
void* cbarg);
|
||||
void* cbarg, const uint8_t* qbuf, size_t qbuf_len);
|
||||
|
||||
/**
|
||||
* Get a new alloc. Creates a new one or uses a cached one.
|
||||
|
||||
+116
-3
@@ -714,7 +714,8 @@ ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
}
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
q = context_new(ctx, name, rrtype, rrclass, NULL, NULL, NULL);
|
||||
q = context_new(ctx, name, rrtype, rrclass,
|
||||
NULL, NULL, NULL, NULL, 0);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
/* become a resolver thread for a bit */
|
||||
@@ -771,7 +772,8 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
ub_comm_base_now(ctx->event_worker->base);
|
||||
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
q = context_new(ctx, name, rrtype, rrclass, NULL, callback, mydata);
|
||||
q = context_new(ctx, name, rrtype, rrclass,
|
||||
NULL, callback, mydata, NULL, 0);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
|
||||
@@ -816,7 +818,8 @@ ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
}
|
||||
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
q = context_new(ctx, name, rrtype, rrclass, callback, NULL, mydata);
|
||||
q = context_new(ctx, name, rrtype, rrclass,
|
||||
callback, NULL, mydata, NULL, 0);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
|
||||
@@ -845,6 +848,116 @@ ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
int
|
||||
ub_send(struct ub_ctx* ctx, const char* packet, int length,
|
||||
struct ub_result** result)
|
||||
{
|
||||
struct ctx_query* q;
|
||||
int r;
|
||||
*result = NULL;
|
||||
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(!ctx->finalized) {
|
||||
r = context_finalize(ctx);
|
||||
if(r) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
q = context_new(ctx, NULL, 0, 0,
|
||||
NULL, NULL, NULL, (const uint8_t *)packet, length);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
/* become a resolver thread for a bit */
|
||||
|
||||
r = libworker_fg(ctx, q);
|
||||
if(r) {
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
(void)rbtree_delete(&ctx->queries, q->node.key);
|
||||
context_query_delete(q);
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return r;
|
||||
}
|
||||
q->res->answer_packet = q->msg;
|
||||
q->res->answer_len = (int)q->msg_len;
|
||||
q->msg = NULL;
|
||||
*result = q->res;
|
||||
q->res = NULL;
|
||||
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
(void)rbtree_delete(&ctx->queries, q->node.key);
|
||||
context_query_delete(q);
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
int
|
||||
ub_send_async(struct ub_ctx* ctx, const char* packet, int length,
|
||||
void* mydata, ub_callback_type callback, int* async_id)
|
||||
{
|
||||
struct ctx_query* q;
|
||||
uint8_t* msg = NULL;
|
||||
uint32_t len = 0;
|
||||
|
||||
if(async_id)
|
||||
*async_id = 0;
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(!ctx->finalized) {
|
||||
int r = context_finalize(ctx);
|
||||
if(r) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if(!ctx->created_bg) {
|
||||
int r;
|
||||
ctx->created_bg = 1;
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
r = libworker_bg(ctx);
|
||||
if(r) {
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
ctx->created_bg = 0;
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
q = context_new(ctx, NULL, 0, 0, callback, NULL,
|
||||
mydata, (const uint8_t*)packet, length);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
|
||||
/* write over pipe to background worker */
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
msg = context_serialize_new_query(q, &len);
|
||||
if(!msg) {
|
||||
(void)rbtree_delete(&ctx->queries, q->node.key);
|
||||
ctx->num_async--;
|
||||
context_query_delete(q);
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
if(async_id)
|
||||
*async_id = q->querynum;
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
|
||||
lock_basic_lock(&ctx->qqpipe_lock);
|
||||
if(!tube_write_msg(ctx->qq_pipe, msg, len, 0)) {
|
||||
lock_basic_unlock(&ctx->qqpipe_lock);
|
||||
free(msg);
|
||||
return UB_PIPE;
|
||||
}
|
||||
lock_basic_unlock(&ctx->qqpipe_lock);
|
||||
free(msg);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ub_cancel(struct ub_ctx* ctx, int async_id)
|
||||
{
|
||||
|
||||
@@ -596,6 +596,8 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
|
||||
if(!qinfo->qname) {
|
||||
return 0;
|
||||
}
|
||||
qinfo->qbuf = q->qbuf;
|
||||
qinfo->qbuf_len = q->qbuf_len;
|
||||
edns->edns_present = 1;
|
||||
edns->ext_rcode = 0;
|
||||
edns->edns_version = 0;
|
||||
|
||||
@@ -31,6 +31,8 @@ ub_resolve
|
||||
ub_resolve_async
|
||||
ub_resolve_event
|
||||
ub_resolve_free
|
||||
ub_send
|
||||
ub_send_async
|
||||
ub_strerror
|
||||
ub_version
|
||||
ub_wait
|
||||
|
||||
@@ -568,6 +568,50 @@ int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
int ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
int rrclass, void* mydata, ub_callback_type callback, int* async_id);
|
||||
|
||||
/**
|
||||
* Transmit a wire-encoded query packet directly to a nameserver.
|
||||
* @param ctx: context.
|
||||
* The context is finalized, and can no longer accept config changes.
|
||||
* @param packet: wire-encoded query packet.
|
||||
* @param length: length of encoded query packet.
|
||||
* @param result: the reply packet, together with its validation status,
|
||||
* is returned in a newly allocated result structure.
|
||||
* May be NULL on return, in which case an error code is returned.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_send(struct ub_ctx* ctx, const char* packet, int length,
|
||||
struct ub_result** result);
|
||||
|
||||
/**
|
||||
* Transmit a wire-encoded query packet directly to a nameserver.
|
||||
* Asynchronous, after a while, the callback will be called with your
|
||||
* data and the result.
|
||||
* @param ctx: context.
|
||||
* If no thread or process has been created yet to perform the
|
||||
* work in the background, it is created now.
|
||||
* The context is finalized, and can no longer accept config changes.
|
||||
* @param packet: wire-encoded query packet.
|
||||
* @param length: length of encoded query packet.
|
||||
* @param mydata: this data is your own data (you can pass NULL),
|
||||
* and is passed on to the callback function.
|
||||
* @param callback: this is called on completion of the resolution.
|
||||
* It is called as:
|
||||
* void callback(void* mydata, int err, struct ub_result* result)
|
||||
* with mydata: the same as passed here, you may pass NULL,
|
||||
* with err: is 0 when a result has been found.
|
||||
* with result: a newly allocated result structure.
|
||||
* The result may be NULL, in that case err is set.
|
||||
*
|
||||
* If an error happens during processing, your callback will be called
|
||||
* with error set to a nonzero value (and result==NULL).
|
||||
* @param async_id: if you pass a non-NULL value, an identifier number is
|
||||
* returned for the query as it is in progress. It can be used to
|
||||
* cancel the query.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_send_async(struct ub_ctx* ctx, const char* packet, int length,
|
||||
void* mydata, ub_callback_type callback, int* async_id);
|
||||
|
||||
/**
|
||||
* Cancel an async query in progress.
|
||||
* Its callback will not be called.
|
||||
|
||||
@@ -2574,6 +2574,7 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream,
|
||||
char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, int qtype, struct edns_option* opt_list,
|
||||
const uint8_t* raw_qbuf, size_t raw_qbuf_len,
|
||||
size_t pad_queries_block_size, struct alloc_cache* alloc,
|
||||
struct regional* region)
|
||||
{
|
||||
@@ -2597,6 +2598,8 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
return NULL;
|
||||
}
|
||||
sq->qbuflen = sldns_buffer_limit(buff);
|
||||
sq->raw_qbuf = raw_qbuf;
|
||||
sq->raw_qbuf_len = raw_qbuf_len;
|
||||
sq->zone = regional_alloc_init(region, zone, zonelen);
|
||||
if(!sq->zone) {
|
||||
alloc_reg_release(alloc, region);
|
||||
@@ -2800,6 +2803,13 @@ serviced_encode(struct serviced_query* sq, sldns_buffer* buff, int with_edns)
|
||||
if(sq->outnet->use_caps_for_id && !sq->nocaps) {
|
||||
serviced_perturb_qname(sq->outnet->rnd, sq->qbuf, sq->qbuflen);
|
||||
}
|
||||
if (sq->raw_qbuf) {
|
||||
/* use the raw packet from libunbound's ub_send */
|
||||
sldns_buffer_clear(buff);
|
||||
sldns_buffer_write(buff, sq->raw_qbuf, sq->raw_qbuf_len);
|
||||
sldns_buffer_flip(buff);
|
||||
return;
|
||||
}
|
||||
/* generate query */
|
||||
sldns_buffer_clear(buff);
|
||||
sldns_buffer_write_u16(buff, 0); /* id placeholder */
|
||||
@@ -3439,6 +3449,7 @@ outnet_serviced_query(struct outside_network* outnet,
|
||||
tcp_upstream, ssl_upstream, tls_auth_name, addr,
|
||||
addrlen, zone, zonelen, (int)qinfo->qtype,
|
||||
per_upstream_opt_list,
|
||||
qinfo->qbuf, qinfo->qbuf_len,
|
||||
( ssl_upstream && env->cfg->pad_queries
|
||||
? env->cfg->pad_queries_block_size : 0 ),
|
||||
env->alloc, region);
|
||||
|
||||
@@ -456,6 +456,10 @@ struct serviced_query {
|
||||
uint8_t* qbuf;
|
||||
/** length of qbuf. */
|
||||
size_t qbuflen;
|
||||
/** raw_qbuf for sending precreated packets */
|
||||
const uint8_t *raw_qbuf;
|
||||
/** Precreated packet length */
|
||||
size_t raw_qbuf_len;
|
||||
/** If an EDNS section is included, the DO/CD bit will be turned on. */
|
||||
int dnssec;
|
||||
/** We want signatures, or else the answer is likely useless */
|
||||
|
||||
@@ -573,6 +573,7 @@ int main(int argc, char** argv)
|
||||
#endif
|
||||
checklock_start();
|
||||
log_init(0, 0, 0);
|
||||
log_ident_set("dohclient");
|
||||
|
||||
h2_session = http2_session_create();
|
||||
if(!h2_session) fatal_exit("out of memory");
|
||||
|
||||
@@ -103,6 +103,15 @@ for input in $PRE/testdata/*.rpl $PRE/testdata/*.crpl; do
|
||||
fi
|
||||
fi
|
||||
|
||||
# detect if cachedb is needed
|
||||
if echo $cleaninput | grep cachedb >/dev/null 2>&1; then
|
||||
if grep "define USE_CACHEDB 1" $PRE/config.h >/dev/null 2>&1; then
|
||||
: # CACHEDB is supported
|
||||
else
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $do_valgrind = "yes"; then
|
||||
echo
|
||||
if (valgrind $VALGRIND_FLAGS $PRE/testbound -p $input >tmpout 2>&1;); then
|
||||
|
||||
Vendored
+181
@@ -0,0 +1,181 @@
|
||||
; config options
|
||||
server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: no
|
||||
minimal-responses: no
|
||||
;serve-expired: yes
|
||||
module-config: "cachedb iterator"
|
||||
|
||||
cachedb:
|
||||
backend: "testframe"
|
||||
secret-seed: "testvalue"
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test cachedb store and servfail reply from cname.
|
||||
; the servfail reply should not overwrite the cache contents.
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns2.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns2.example.com. IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
foo.com. IN NS
|
||||
SECTION AUTHORITY
|
||||
foo.com. IN NS ns.example.com.
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns2.example.com.
|
||||
RANGE_BEGIN 0 20
|
||||
ADDRESS 1.2.3.5
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns2.example.com., now failing
|
||||
RANGE_BEGIN 20 100
|
||||
ADDRESS 1.2.3.5
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN CNAME foo.example.com.
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
REPLY QR AA SERVFAIL
|
||||
SECTION QUESTION
|
||||
foo.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
REPLY QR AA SERVFAIL
|
||||
SECTION QUESTION
|
||||
ns2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
REPLY QR AA SERVFAIL
|
||||
SECTION QUESTION
|
||||
ns2.example.com. IN AAAA
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; get and entry in cache, to make it expired.
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; get the answer for it
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; it is now expired
|
||||
STEP 20 TIME_PASSES ELAPSE 20
|
||||
|
||||
; get a servfail in cache for the destination
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
foo.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
SECTION QUESTION
|
||||
foo.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; the query is now a CNAME to servfail.
|
||||
; there is a valid, but expired, entry in cache.
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 60 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN CNAME foo.example.com.
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+6
-1
@@ -37,7 +37,12 @@
|
||||
import os
|
||||
|
||||
def init(id, cfg):
|
||||
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
|
||||
scripts=[]
|
||||
s = cfg.python_script
|
||||
while s != None:
|
||||
scripts.append(s.str)
|
||||
s = s.next
|
||||
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, scripts))
|
||||
return True
|
||||
|
||||
def deinit(id):
|
||||
|
||||
@@ -97,6 +97,11 @@ struct query_info {
|
||||
* have to be generated if it has to be kept during iterative
|
||||
* resolution. */
|
||||
struct local_rrset* local_alias;
|
||||
|
||||
/** raw query packet */
|
||||
const uint8_t *qbuf;
|
||||
/** length of raw query packet */
|
||||
size_t qbuf_len;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -810,7 +810,7 @@ done:
|
||||
/* We are reading a whole packet;
|
||||
* Move the rest of the data to overwrite the PROXYv2 header */
|
||||
/* XXX can we do better to avoid memmove? */
|
||||
memmove(header, ((void*)header)+size,
|
||||
memmove(header, ((char*)header)+size,
|
||||
sldns_buffer_limit(buf)-size);
|
||||
sldns_buffer_set_limit(buf, sldns_buffer_limit(buf)-size);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user