aboutsummaryrefslogtreecommitdiff
path: root/contrib/unbound/services
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/unbound/services')
-rw-r--r--contrib/unbound/services/authzone.c90
-rw-r--r--contrib/unbound/services/authzone.h17
-rw-r--r--contrib/unbound/services/cache/rrset.c2
-rw-r--r--contrib/unbound/services/listen_dnsport.c117
-rw-r--r--contrib/unbound/services/listen_dnsport.h9
-rw-r--r--contrib/unbound/services/mesh.c1
-rw-r--r--contrib/unbound/services/mesh.h2
-rw-r--r--contrib/unbound/services/modstack.c4
-rw-r--r--contrib/unbound/services/modstack.h2
-rw-r--r--contrib/unbound/services/outside_network.c6
-rw-r--r--contrib/unbound/services/rpz.c20
11 files changed, 203 insertions, 67 deletions
diff --git a/contrib/unbound/services/authzone.c b/contrib/unbound/services/authzone.c
index 3c3dc9ad05d9..60ccc8698748 100644
--- a/contrib/unbound/services/authzone.c
+++ b/contrib/unbound/services/authzone.c
@@ -2413,14 +2413,12 @@ az_find_wildcard(struct auth_zone* z, struct query_info* qinfo,
if(!dname_subdomain_c(nm, z->name))
return NULL; /* out of zone */
while((node=az_find_wildcard_domain(z, nm, nmlen))==NULL) {
- /* see if we can go up to find the wildcard */
if(nmlen == z->namelen)
return NULL; /* top of zone reached */
if(ce && nmlen == ce->namelen)
return NULL; /* ce reached */
- if(dname_is_root(nm))
- return NULL; /* cannot go up */
- dname_remove_label(&nm, &nmlen);
+ if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen))
+ return NULL; /* can't go up */
}
return node;
}
@@ -2442,9 +2440,8 @@ az_find_candidate_ce(struct auth_zone* z, struct query_info* qinfo,
n = az_find_name(z, nm, nmlen);
/* delete labels and go up on name */
while(!n) {
- if(dname_is_root(nm))
- return NULL; /* cannot go up */
- dname_remove_label(&nm, &nmlen);
+ if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen))
+ return NULL; /* can't go up */
n = az_find_name(z, nm, nmlen);
}
return n;
@@ -2456,8 +2453,7 @@ az_domain_go_up(struct auth_zone* z, struct auth_data* n)
{
uint8_t* nm = n->name;
size_t nmlen = n->namelen;
- while(!dname_is_root(nm)) {
- dname_remove_label(&nm, &nmlen);
+ while(dname_remove_label_limit_len(&nm, &nmlen, z->namelen)) {
if((n=az_find_name(z, nm, nmlen)) != NULL)
return n;
}
@@ -2771,26 +2767,23 @@ az_change_dnames(struct dns_msg* msg, uint8_t* oldname, uint8_t* newname,
}
}
-/** find NSEC record covering the query */
+/** find NSEC record covering the query, with the given node in the zone */
static struct auth_rrset*
az_find_nsec_cover(struct auth_zone* z, struct auth_data** node)
{
- uint8_t* nm = (*node)->name;
- size_t nmlen = (*node)->namelen;
+ uint8_t* nm;
+ size_t nmlen;
struct auth_rrset* rrset;
+ log_assert(*node); /* we already have a node when calling this */
+ nm = (*node)->name;
+ nmlen = (*node)->namelen;
/* find the NSEC for the smallest-or-equal node */
- /* if node == NULL, we did not find a smaller name. But the zone
- * name is the smallest name and should have an NSEC. So there is
- * no NSEC to return (for a properly signed zone) */
- /* for empty nonterminals, the auth-data node should not exist,
- * and thus we don't need to go rbtree_previous here to find
- * a domain with an NSEC record */
- /* but there could be glue, and if this is node, then it has no NSEC.
+ /* But there could be glue, and then it has no NSEC.
* Go up to find nonglue (previous) NSEC-holding nodes */
while((rrset=az_domain_rrset(*node, LDNS_RR_TYPE_NSEC)) == NULL) {
- if(dname_is_root(nm)) return NULL;
if(nmlen == z->namelen) return NULL;
- dname_remove_label(&nm, &nmlen);
+ if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen))
+ return NULL; /* can't go up */
/* adjust *node for the nsec rrset to find in */
*node = az_find_name(z, nm, nmlen);
}
@@ -3018,12 +3011,9 @@ az_nsec3_find_ce(struct auth_zone* z, uint8_t** cenm, size_t* cenmlen,
struct auth_data* node;
while((node = az_nsec3_find_exact(z, *cenm, *cenmlen,
algo, iter, salt, saltlen)) == NULL) {
- if(*cenmlen == z->namelen) {
- /* next step up would take us out of the zone. fail */
- return NULL;
- }
+ if(!dname_remove_label_limit_len(cenm, cenmlen, z->namelen))
+ return NULL; /* can't go up */
*no_exact_ce = 1;
- dname_remove_label(cenm, cenmlen);
}
return node;
}
@@ -3340,7 +3330,8 @@ az_generate_wildcard_answer(struct auth_zone* z, struct query_info* qinfo,
} else if(ce) {
uint8_t* wildup = wildcard->name;
size_t wilduplen= wildcard->namelen;
- dname_remove_label(&wildup, &wilduplen);
+ if(!dname_remove_label_limit_len(&wildup, &wilduplen, z->namelen))
+ return 0; /* can't go up */
if(!az_add_nsec3_proof(z, region, msg, wildup,
wilduplen, msg->qinfo.qname,
msg->qinfo.qname_len, 0, insert_ce, 1, 0))
@@ -3399,7 +3390,7 @@ az_generate_answer_with_node(struct auth_zone* z, struct query_info* qinfo,
}
/** Generate answer without an existing-node that we can use.
- * So it'll be a referral, DNAME or nxdomain */
+ * So it'll be a referral, DNAME, notype, wildcard or nxdomain */
static int
az_generate_answer_nonexistnode(struct auth_zone* z, struct query_info* qinfo,
struct regional* region, struct dns_msg* msg, struct auth_data* ce,
@@ -3565,14 +3556,17 @@ auth_error_encode(struct query_info* qinfo, struct module_env* env,
sldns_buffer_read_u16_at(buf, 2), edns);
}
-int auth_zones_answer(struct auth_zones* az, struct module_env* env,
+int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns,
- struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp)
+ struct comm_reply* repinfo, struct sldns_buffer* buf,
+ struct regional* temp)
{
struct dns_msg* msg = NULL;
struct auth_zone* z;
int r;
int fallback = 0;
+ /* Copy the qinfo in case of cname aliasing from local-zone */
+ struct query_info zqinfo = *qinfo;
lock_rw_rdlock(&az->lock);
if(!az->have_downstream) {
@@ -3580,6 +3574,7 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
lock_rw_unlock(&az->lock);
return 0;
}
+
if(qinfo->qtype == LDNS_RR_TYPE_DS) {
uint8_t* delname = qinfo->qname;
size_t delnamelen = qinfo->qname_len;
@@ -3587,8 +3582,14 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
z = auth_zones_find_zone(az, delname, delnamelen,
qinfo->qclass);
} else {
- z = auth_zones_find_zone(az, qinfo->qname, qinfo->qname_len,
- qinfo->qclass);
+ if(zqinfo.local_alias && !local_alias_shallow_copy_qname(
+ zqinfo.local_alias, &zqinfo.qname,
+ &zqinfo.qname_len)) {
+ lock_rw_unlock(&az->lock);
+ return 0;
+ }
+ z = auth_zones_find_zone(az, zqinfo.qname, zqinfo.qname_len,
+ zqinfo.qclass);
}
if(!z) {
/* no zone above it */
@@ -3614,7 +3615,7 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
}
/* answer it from zone z */
- r = auth_zone_generate_answer(z, qinfo, temp, &msg, &fallback);
+ r = auth_zone_generate_answer(z, &zqinfo, temp, &msg, &fallback);
lock_rw_unlock(&z->lock);
if(!r && fallback) {
/* fallback to regular answering (recursive) */
@@ -5023,6 +5024,7 @@ apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
xfr->have_zone = 0;
xfr->serial = 0;
+ xfr->soa_zone_acquired = 0;
/* insert all RRs in to the zone */
/* insert the SOA only once, skip the last one */
@@ -5124,6 +5126,7 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
xfr->have_zone = 0;
xfr->serial = 0;
+ xfr->soa_zone_acquired = 0;
chunk = xfr->task_transfer->chunks_first;
chunk_pos = 0;
@@ -5334,6 +5337,8 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
" (or malformed RR)", xfr->task_transfer->master->host);
return 0;
}
+ z->soa_zone_acquired = *env->now;
+ xfr->soa_zone_acquired = *env->now;
/* release xfr lock while verifying zonemd because it may have
* to spawn lookups in the state machines */
@@ -7003,13 +7008,23 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
comm_timer_set(xfr->task_nextprobe->timer, &tv);
}
+void auth_zone_pickup_initial_zone(struct auth_zone* z, struct module_env* env)
+{
+ /* Set the time, because we now have timestamp in env,
+ * (not earlier during startup and apply_cfg), and this
+ * notes the start time when the data was acquired. */
+ z->soa_zone_acquired = *env->now;
+}
+
void auth_xfer_pickup_initial_zone(struct auth_xfer* x, struct module_env* env)
{
/* set lease_time, because we now have timestamp in env,
* (not earlier during startup and apply_cfg), and this
* notes the start time when the data was acquired */
- if(x->have_zone)
+ if(x->have_zone) {
x->lease_time = *env->now;
+ x->soa_zone_acquired = *env->now;
+ }
if(x->task_nextprobe && x->task_nextprobe->worker == NULL) {
xfr_set_timeout(x, env, 0, 1);
}
@@ -7020,7 +7035,13 @@ void
auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env)
{
struct auth_xfer* x;
+ struct auth_zone* z;
lock_rw_wrlock(&az->lock);
+ RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
+ lock_rw_wrlock(&z->lock);
+ auth_zone_pickup_initial_zone(z, env);
+ lock_rw_unlock(&z->lock);
+ }
RBTREE_FOR(x, struct auth_xfer*, &az->xtree) {
lock_basic_lock(&x->lock);
auth_xfer_pickup_initial_zone(x, env);
@@ -7105,6 +7126,7 @@ auth_xfer_new(struct auth_zone* z)
lock_protect(&xfr->lock, &xfr->notify_serial, sizeof(xfr->notify_serial));
lock_protect(&xfr->lock, &xfr->zone_expired, sizeof(xfr->zone_expired));
lock_protect(&xfr->lock, &xfr->have_zone, sizeof(xfr->have_zone));
+ lock_protect(&xfr->lock, &xfr->soa_zone_acquired, sizeof(xfr->soa_zone_acquired));
lock_protect(&xfr->lock, &xfr->serial, sizeof(xfr->serial));
lock_protect(&xfr->lock, &xfr->retry, sizeof(xfr->retry));
lock_protect(&xfr->lock, &xfr->refresh, sizeof(xfr->refresh));
diff --git a/contrib/unbound/services/authzone.h b/contrib/unbound/services/authzone.h
index 722781a063a8..d38cf9d26622 100644
--- a/contrib/unbound/services/authzone.h
+++ b/contrib/unbound/services/authzone.h
@@ -118,6 +118,8 @@ struct auth_zone {
char* zonefile;
/** fallback to the internet on failure or ttl-expiry of auth zone */
int fallback_enabled;
+ /** the time when zone was transferred from upstream */
+ time_t soa_zone_acquired;
/** the zone has expired (enabled by the xfer worker), fallback
* happens if that option is enabled. */
int zone_expired;
@@ -261,6 +263,8 @@ struct auth_xfer {
int zone_expired;
/** do we have a zone (if 0, no zone data at all) */
int have_zone;
+ /** the time when zone was transferred from upstream */
+ time_t soa_zone_acquired;
/** current serial (from SOA), if we have no zone, 0 */
uint32_t serial;
@@ -550,9 +554,10 @@ int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
* @param temp: temporary storage region.
* @return false if not answered
*/
-int auth_zones_answer(struct auth_zones* az, struct module_env* env,
+int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns,
- struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp);
+ struct comm_reply* repinfo, struct sldns_buffer* buf,
+ struct regional* temp);
/**
* Find the auth zone that is above the given qname.
@@ -800,6 +805,14 @@ void auth_xfer_pickup_initial_zone(struct auth_xfer* x,
struct module_env* env);
/**
+ * Initial pick up of the auth zone, it sets the acquired time.
+ * @param z: the zone, write locked by caller.
+ * @param env: environment of the worker, with current time.
+ */
+void auth_zone_pickup_initial_zone(struct auth_zone* z,
+ struct module_env* env);
+
+/**
* Delete auth xfer structure
* @param xfr: delete this xfer and its tasks.
*/
diff --git a/contrib/unbound/services/cache/rrset.c b/contrib/unbound/services/cache/rrset.c
index a05ae5a56b78..6d5c24f8053e 100644
--- a/contrib/unbound/services/cache/rrset.c
+++ b/contrib/unbound/services/cache/rrset.c
@@ -68,6 +68,8 @@ struct rrset_cache* rrset_cache_create(struct config_file* cfg,
struct rrset_cache *r = (struct rrset_cache*)slabhash_create(slabs,
startarray, maxmem, ub_rrset_sizefunc, ub_rrset_compare,
ub_rrset_key_delete, rrset_data_delete, alloc);
+ if(!r)
+ return NULL;
slabhash_setmarkdel(&r->table, &rrset_markdel);
return r;
}
diff --git a/contrib/unbound/services/listen_dnsport.c b/contrib/unbound/services/listen_dnsport.c
index 26efadc151a1..f7fcca194b40 100644
--- a/contrib/unbound/services/listen_dnsport.c
+++ b/contrib/unbound/services/listen_dnsport.c
@@ -90,10 +90,13 @@
#ifdef HAVE_NGTCP2
#include <ngtcp2/ngtcp2.h>
#include <ngtcp2/ngtcp2_crypto.h>
-#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H
+#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H
+#include <ngtcp2/ngtcp2_crypto_ossl.h>
+#elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H)
#include <ngtcp2/ngtcp2_crypto_quictls.h>
-#else
+#elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H)
#include <ngtcp2/ngtcp2_crypto_openssl.h>
+#define MAKE_QUIC_METHOD 1
#endif
#endif
@@ -447,7 +450,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
* /proc/sys/net/core/wmem_max or sysctl net.core.wmem_max */
if(setsockopt(s, SOL_SOCKET, SO_SNDBUFFORCE, (void*)&snd,
(socklen_t)sizeof(snd)) < 0) {
- if(errno != EPERM) {
+ if(errno != EPERM && errno != ENOBUFS) {
log_err("setsockopt(..., SO_SNDBUFFORCE, "
"...) failed: %s", sock_strerror(errno));
sock_close(s);
@@ -455,15 +458,23 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
*inuse = 0;
return -1;
}
+ if(errno != EPERM) {
+ verbose(VERB_ALGO, "setsockopt(..., SO_SNDBUFFORCE, "
+ "...) was not granted: %s", sock_strerror(errno));
+ }
# endif /* SO_SNDBUFFORCE */
if(setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*)&snd,
(socklen_t)sizeof(snd)) < 0) {
- log_err("setsockopt(..., SO_SNDBUF, "
- "...) failed: %s", sock_strerror(errno));
- sock_close(s);
- *noproto = 0;
- *inuse = 0;
- return -1;
+ if(errno != ENOSYS && errno != ENOBUFS) {
+ log_err("setsockopt(..., SO_SNDBUF, "
+ "...) failed: %s", sock_strerror(errno));
+ sock_close(s);
+ *noproto = 0;
+ *inuse = 0;
+ return -1;
+ }
+ log_warn("setsockopt(..., SO_SNDBUF, "
+ "...) was not granted: %s", sock_strerror(errno));
}
/* check if we got the right thing or if system
* reduced to some system max. Warn if so */
@@ -473,7 +484,8 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
"Got %u. To fix: start with "
"root permissions(linux) or sysctl "
"bigger net.core.wmem_max(linux) or "
- "kern.ipc.maxsockbuf(bsd) values.",
+ "kern.ipc.maxsockbuf(bsd) values. or "
+ "set so-sndbuf: 0 (use system value).",
(unsigned)snd, (unsigned)got);
}
# ifdef SO_SNDBUFFORCE
@@ -902,7 +914,7 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
against IP spoofing attacks as suggested in RFC7413 */
#ifdef __APPLE__
/* OS X implementation only supports qlen of 1 via this call. Actual
- value is configured by the net.inet.tcp.fastopen_backlog kernel parm. */
+ value is configured by the net.inet.tcp.fastopen_backlog kernel param. */
qlen = 1;
#else
/* 5 is recommended on linux */
@@ -1179,6 +1191,15 @@ set_recvtimestamp(int s)
return 0;
}
return 1;
+#elif defined(SO_TIMESTAMP) && defined(SCM_TIMESTAMP)
+ int on = 1;
+ /* FreeBSD and also Linux. */
+ if (setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, (void*)&on, (socklen_t)sizeof(on)) < 0) {
+ log_err("setsockopt(..., SO_TIMESTAMP, ...) failed: %s",
+ strerror(errno));
+ return 0;
+ }
+ return 1;
#else
log_err("packets timestamping is not supported on this platform");
(void)s;
@@ -1598,7 +1619,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
front->udp_buff, ports->pp2_enabled, cb,
cb_arg, ports->socket);
#else
- log_warn("This system does not support UDP ancilliary data.");
+ log_warn("This system does not support UDP ancillary data.");
#endif
}
if(!cp) {
@@ -3099,7 +3120,7 @@ static int http2_req_header_cb(nghttp2_session* session,
return 0;
}
/* Content type is a SHOULD (rfc7231#section-3.1.1.5) when using POST,
- * and not needed when using GET. Don't enfore.
+ * and not needed when using GET. Don't enforce.
* If set only allow lowercase "application/dns-message".
*
* Clients SHOULD (rfc8484#section-4.1) set an accept header, but MUST
@@ -3161,7 +3182,7 @@ static int http2_req_data_chunk_recv_cb(nghttp2_session* ATTR_UNUSED(session),
qlen = h2_stream->content_length;
} else if(len <= h2_session->c->http2_stream_max_qbuffer_size) {
/* setting this to msg-buffer-size can result in a lot
- * of memory consuption. Most queries should fit in a
+ * of memory consumption. Most queries should fit in a
* single DATA frame, and most POST queries will
* contain content-length which does not impose this
* limit. */
@@ -3187,7 +3208,7 @@ static int http2_req_data_chunk_recv_cb(nghttp2_session* ATTR_UNUSED(session),
if(!h2_stream->qbuffer ||
sldns_buffer_remaining(h2_stream->qbuffer) < len) {
- verbose(VERB_ALGO, "http2 data_chunck_recv failed. Not enough "
+ verbose(VERB_ALGO, "http2 data_chunk_recv failed. Not enough "
"buffer space for POST query. Can happen on multi "
"frame requests without content-length header");
h2_stream->query_too_large = 1;
@@ -3257,6 +3278,21 @@ doq_table_create(struct config_file* cfg, struct ub_randstate* rnd)
struct doq_table* table = calloc(1, sizeof(*table));
if(!table)
return NULL;
+#ifdef USE_NGTCP2_CRYPTO_OSSL
+ /* Initialize the ossl crypto, it is harmless to call twice,
+ * and this is before use of doq connections. */
+ if(ngtcp2_crypto_ossl_init() != 0) {
+ log_err("ngtcp2_crypto_oss_init failed");
+ free(table);
+ return NULL;
+ }
+#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_INIT)
+ if(ngtcp2_crypto_quictls_init() != 0) {
+ log_err("ngtcp2_crypto_quictls_init failed");
+ free(table);
+ return NULL;
+ }
+#endif
table->idle_timeout = ((uint64_t)cfg->tcp_idle_timeout)*
NGTCP2_MILLISECONDS;
table->sv_scidlen = 16;
@@ -3596,12 +3632,18 @@ doq_conn_delete(struct doq_conn* conn, struct doq_table* table)
lock_rw_wrlock(&conn->table->conid_lock);
doq_conn_clear_conids(conn);
lock_rw_unlock(&conn->table->conid_lock);
- ngtcp2_conn_del(conn->conn);
+ /* Remove the app data from ngtcp2 before SSL_free of conn->ssl,
+ * because the ngtcp2 conn is deleted. */
+ SSL_set_app_data(conn->ssl, NULL);
if(conn->stream_tree.count != 0) {
traverse_postorder(&conn->stream_tree, stream_tree_del, table);
}
free(conn->key.dcid);
SSL_free(conn->ssl);
+#ifdef USE_NGTCP2_CRYPTO_OSSL
+ ngtcp2_crypto_ossl_ctx_del(conn->ossl_ctx);
+#endif
+ ngtcp2_conn_del(conn->conn);
free(conn->close_pkt);
free(conn);
}
@@ -4459,7 +4501,7 @@ doq_log_printf_cb(void* ATTR_UNUSED(user_data), const char* fmt, ...)
va_end(ap);
}
-#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
+#ifdef MAKE_QUIC_METHOD
/** the doq application tx key callback, false on failure */
static int
doq_application_tx_key_cb(struct doq_conn* conn)
@@ -4493,7 +4535,9 @@ doq_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
ngtcp2_crypto_level
#endif
level =
-#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
+#ifdef USE_NGTCP2_CRYPTO_OSSL
+ ngtcp2_crypto_ossl_from_ossl_encryption_level(ossl_level);
+#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL)
ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
#else
ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
@@ -4539,7 +4583,9 @@ doq_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
ngtcp2_crypto_level
#endif
level =
-#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
+#ifdef USE_NGTCP2_CRYPTO_OSSL
+ ngtcp2_crypto_ossl_from_ossl_encryption_level(ossl_level);
+#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL)
ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
#else
ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
@@ -4574,7 +4620,7 @@ doq_send_alert(SSL *ssl, enum ssl_encryption_level_t ATTR_UNUSED(level),
doq_conn->tls_alert = alert;
return 1;
}
-#endif /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT */
+#endif /* MAKE_QUIC_METHOD */
/** ALPN select callback for the doq SSL context */
static int
@@ -4596,7 +4642,7 @@ void* quic_sslctx_create(char* key, char* pem, char* verifypem)
{
#ifdef HAVE_NGTCP2
char* sid_ctx = "unbound server";
-#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
+#ifdef MAKE_QUIC_METHOD
SSL_QUIC_METHOD* quic_method;
#endif
SSL_CTX* ctx = SSL_CTX_new(TLS_server_method());
@@ -4669,7 +4715,7 @@ void* quic_sslctx_create(char* key, char* pem, char* verifypem)
SSL_CTX_free(ctx);
return NULL;
}
-#else /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT */
+#elif defined(MAKE_QUIC_METHOD)
/* The quic_method needs to remain valid during the SSL_CTX
* lifetime, so we allocate it. It is freed with the
* doq_server_socket. */
@@ -4704,12 +4750,29 @@ static ngtcp2_conn* doq_conn_ref_get_conn(ngtcp2_crypto_conn_ref* conn_ref)
static SSL*
doq_ssl_server_setup(SSL_CTX* ctx, struct doq_conn* conn)
{
+#ifdef USE_NGTCP2_CRYPTO_OSSL
+ int ret;
+#endif
SSL* ssl = SSL_new(ctx);
if(!ssl) {
log_crypto_err("doq: SSL_new failed");
return NULL;
}
-#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
+#ifdef USE_NGTCP2_CRYPTO_OSSL
+ if((ret=ngtcp2_crypto_ossl_ctx_new(&conn->ossl_ctx, NULL)) != 0) {
+ log_err("doq: ngtcp2_crypto_ossl_ctx_new failed: %s",
+ ngtcp2_strerror(ret));
+ SSL_free(ssl);
+ return NULL;
+ }
+ ngtcp2_crypto_ossl_ctx_set_ssl(conn->ossl_ctx, ssl);
+ if(ngtcp2_crypto_ossl_configure_server_session(ssl) != 0) {
+ log_err("doq: ngtcp2_crypto_ossl_configure_server_session failed");
+ SSL_free(ssl);
+ return NULL;
+ }
+#endif
+#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT)
conn->conn_ref.get_conn = &doq_conn_ref_get_conn;
conn->conn_ref.user_data = conn;
SSL_set_app_data(ssl, &conn->conn_ref);
@@ -4717,7 +4780,11 @@ doq_ssl_server_setup(SSL_CTX* ctx, struct doq_conn* conn)
SSL_set_app_data(ssl, conn);
#endif
SSL_set_accept_state(ssl);
+#ifdef USE_NGTCP2_CRYPTO_OSSL
+ SSL_set_quic_tls_early_data_enabled(ssl, 1);
+#else
SSL_set_quic_early_data_enabled(ssl, 1);
+#endif
return ssl;
}
@@ -4838,7 +4905,11 @@ doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen,
log_err("doq_ssl_server_setup failed");
return 0;
}
+#ifdef USE_NGTCP2_CRYPTO_OSSL
+ ngtcp2_conn_set_tls_native_handle(conn->conn, conn->ossl_ctx);
+#else
ngtcp2_conn_set_tls_native_handle(conn->conn, conn->ssl);
+#endif
doq_conn_write_enable(conn);
return 1;
}
diff --git a/contrib/unbound/services/listen_dnsport.h b/contrib/unbound/services/listen_dnsport.h
index f6275f805fba..963595a1ccc5 100644
--- a/contrib/unbound/services/listen_dnsport.h
+++ b/contrib/unbound/services/listen_dnsport.h
@@ -52,6 +52,9 @@
#ifdef HAVE_NGTCP2
#include <ngtcp2/ngtcp2.h>
#include <ngtcp2/ngtcp2_crypto.h>
+#ifdef USE_NGTCP2_CRYPTO_OSSL
+struct ngtcp2_crypto_ossl_ctx;
+#endif
#endif
struct listen_list;
struct config_file;
@@ -606,10 +609,14 @@ struct doq_conn {
uint8_t tls_alert;
/** the ssl context, SSL* */
void* ssl;
-#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
+#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT)
/** the connection reference for ngtcp2_conn and userdata in ssl */
struct ngtcp2_crypto_conn_ref conn_ref;
#endif
+#ifdef USE_NGTCP2_CRYPTO_OSSL
+ /** the per-connection state for ngtcp2_crypto_ossl */
+ struct ngtcp2_crypto_ossl_ctx* ossl_ctx;
+#endif
/** closure packet, if any */
uint8_t* close_pkt;
/** length of closure packet. */
diff --git a/contrib/unbound/services/mesh.c b/contrib/unbound/services/mesh.c
index 8a52fe4a6466..3212a6abf4c6 100644
--- a/contrib/unbound/services/mesh.c
+++ b/contrib/unbound/services/mesh.c
@@ -2265,6 +2265,7 @@ mesh_stats_clear(struct mesh_area* mesh)
timehist_clear(mesh->histogram);
mesh->ans_secure = 0;
mesh->ans_bogus = 0;
+ mesh->val_ops = 0;
mesh->ans_expired = 0;
mesh->ans_cachedb = 0;
memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*UB_STATS_RCODE_NUM);
diff --git a/contrib/unbound/services/mesh.h b/contrib/unbound/services/mesh.h
index fd17c05da6d4..f19f423a8cd3 100644
--- a/contrib/unbound/services/mesh.h
+++ b/contrib/unbound/services/mesh.h
@@ -131,6 +131,8 @@ struct mesh_area {
size_t ans_secure;
/** (extended stats) bogus replies */
size_t ans_bogus;
+ /** (extended stats) number of validation operations */
+ size_t val_ops;
/** (extended stats) rcodes in replies */
size_t ans_rcode[UB_STATS_RCODE_NUM];
/** (extended stats) rcode nodata in replies */
diff --git a/contrib/unbound/services/modstack.c b/contrib/unbound/services/modstack.c
index fa68cc71d2ff..2bc79c4adfd7 100644
--- a/contrib/unbound/services/modstack.c
+++ b/contrib/unbound/services/modstack.c
@@ -138,8 +138,8 @@ modstack_config(struct module_stack* stack, const char* module_conf)
if(strchr(s, ' ')) *(strchr(s, ' ')) = 0;
if(strchr(s, '\t')) *(strchr(s, '\t')) = 0;
log_err("Unknown value in module-config, module: '%s'."
- " This module is not present (not compiled in),"
- " See the list of linked modules with unbound -V", s);
+ " This module is not present (not compiled in);"
+ " see the list of linked modules with unbound -V", s);
return 0;
}
}
diff --git a/contrib/unbound/services/modstack.h b/contrib/unbound/services/modstack.h
index 5674aefdd018..03a4c82c40cd 100644
--- a/contrib/unbound/services/modstack.h
+++ b/contrib/unbound/services/modstack.h
@@ -67,7 +67,7 @@ void modstack_init(struct module_stack* stack);
void modstack_free(struct module_stack* stack);
/**
- * Initialises modules and assignes ids. Calls module_startup().
+ * Initialises modules and assigns ids. Calls module_startup().
* @param stack: Expected empty, filled according to module_conf
* @param module_conf: string what modules to initialize
* @param env: module environment which is inited by the modules.
diff --git a/contrib/unbound/services/outside_network.c b/contrib/unbound/services/outside_network.c
index 0d7ec890573b..2b7f7d0a2f21 100644
--- a/contrib/unbound/services/outside_network.c
+++ b/contrib/unbound/services/outside_network.c
@@ -2827,7 +2827,7 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len)
random = ub_random(rnd);
bits = 30;
}
- if(random & 0x1) {
+ if((random & 0x1)) {
*d = (uint8_t)toupper((unsigned char)*d);
} else {
*d = (uint8_t)tolower((unsigned char)*d);
@@ -2890,9 +2890,9 @@ serviced_encode(struct serviced_query* sq, sldns_buffer* buff, int with_edns)
edns.opt_list_inplace_cb_out = NULL;
edns.udp_size = serviced_query_udp_size(sq, sq->status);
edns.bits = 0;
- if(sq->dnssec & EDNS_DO)
+ if((sq->dnssec & EDNS_DO))
edns.bits = EDNS_DO;
- if(sq->dnssec & BIT_CD)
+ if((sq->dnssec & BIT_CD))
LDNS_CD_SET(sldns_buffer_begin(buff));
if (sq->ssl_upstream && sq->padding_block_size) {
padding_option.opt_code = LDNS_EDNS_PADDING;
diff --git a/contrib/unbound/services/rpz.c b/contrib/unbound/services/rpz.c
index df39e75b0596..f45cf65420d7 100644
--- a/contrib/unbound/services/rpz.c
+++ b/contrib/unbound/services/rpz.c
@@ -2121,8 +2121,17 @@ rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms,
rpz_log_dname("nsdname local data", key.name, key.namelen);
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
+ if(ld == NULL && dname_is_wild(z->name)) {
+ key.name = z->name;
+ key.namelen = z->namelen;
+ key.namelabs = z->namelabs;
+ ld = (struct local_data*)rbtree_search(&z->data, &key.node);
+ /* rpz_synthesize_localdata_from_rrset is going to make
+ * the rrset source name equal to the query name. So no need
+ * to make the wildcard rrset here. */
+ }
if(ld == NULL) {
- verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found");
+ verbose(VERB_ALGO, "rpz: nsdname: qname not found");
return NULL;
}
@@ -2148,6 +2157,15 @@ rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms,
key.namelen = qinfo->qname_len;
key.namelabs = dname_count_labels(qinfo->qname);
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
+ if(ld == NULL && dname_is_wild(z->name)) {
+ key.name = z->name;
+ key.namelen = z->namelen;
+ key.namelabs = z->namelabs;
+ ld = (struct local_data*)rbtree_search(&z->data, &key.node);
+ /* rpz_synthesize_localdata_from_rrset is going to make
+ * the rrset source name equal to the query name. So no need
+ * to make the wildcard rrset here. */
+ }
if(ld == NULL) {
verbose(VERB_ALGO, "rpz: qname: name not found");
return NULL;