diff options
Diffstat (limited to 'contrib/unbound/services')
-rw-r--r-- | contrib/unbound/services/authzone.c | 90 | ||||
-rw-r--r-- | contrib/unbound/services/authzone.h | 17 | ||||
-rw-r--r-- | contrib/unbound/services/cache/rrset.c | 2 | ||||
-rw-r--r-- | contrib/unbound/services/listen_dnsport.c | 117 | ||||
-rw-r--r-- | contrib/unbound/services/listen_dnsport.h | 9 | ||||
-rw-r--r-- | contrib/unbound/services/mesh.c | 1 | ||||
-rw-r--r-- | contrib/unbound/services/mesh.h | 2 | ||||
-rw-r--r-- | contrib/unbound/services/modstack.c | 4 | ||||
-rw-r--r-- | contrib/unbound/services/modstack.h | 2 | ||||
-rw-r--r-- | contrib/unbound/services/outside_network.c | 6 | ||||
-rw-r--r-- | contrib/unbound/services/rpz.c | 20 |
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; |