Blame SOURCES/unbound-1.15-soversion2-compat.patch

601e9c
From 605d66f0b6b8f7c308010f455058299d25c1d2ee Mon Sep 17 00:00:00 2001
601e9c
From: Petr Mensik <pemensik@redhat.com>
601e9c
Date: Fri, 6 May 2022 16:36:39 +0200
601e9c
Subject: [PATCH] Rework ABI breaking change to compatible way
601e9c
601e9c
Upstream commit 749d1b9ebc6fcb79824afd0471a1cfc12ca861b1 introduced
601e9c
was_ratelimited variable to every async callback. Such change led to ABI
601e9c
break and increase of soname of libunbound.
601e9c
601e9c
Use rcode to pass that boolean inside rcode variable. Allows keeping
601e9c
original callback prototype, but does not lose data. Extra integer bit
601e9c
operations should be very small price. Much better than ABI break.
601e9c
601e9c
Make current version compatible back to .2 version.
601e9c
---
601e9c
 unbound-1.16.2/configure.ac               |  2 +-
601e9c
 unbound-1.16.2/daemon/worker.c            |  6 ++--
601e9c
 unbound-1.16.2/libunbound/libworker.c     | 34 +++++++++++++++--------
601e9c
 unbound-1.16.2/libunbound/unbound-event.h |  3 +-
601e9c
 unbound-1.16.2/libunbound/unbound.h       | 13 +++++----
601e9c
 unbound-1.16.2/libunbound/worker.h        |  6 ++--
601e9c
 unbound-1.16.2/services/authzone.c        | 11 ++++----
601e9c
 unbound-1.16.2/services/authzone.h        |  9 ++----
601e9c
 unbound-1.16.2/services/mesh.c            | 17 ++++++++----
601e9c
 unbound-1.16.2/services/mesh.h            |  9 +++++-
601e9c
 unbound-1.16.2/smallapp/worker_cb.c       |  6 ++--
601e9c
 unbound-1.16.2/validator/autotrust.c      |  2 +-
601e9c
 unbound-1.16.2/validator/autotrust.h      |  2 +-
601e9c
 13 files changed, 72 insertions(+), 48 deletions(-)
601e9c
601e9c
diff --git a/unbound-1.16.2/configure.ac b/unbound-1.16.2/configure.ac
601e9c
index 224501b..71f066c 100644
601e9c
--- a/unbound-1.16.2/configure.ac
601e9c
+++ b/unbound-1.16.2/configure.ac
601e9c
@@ -19,7 +19,7 @@ AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
601e9c
 
601e9c
 LIBUNBOUND_CURRENT=9
601e9c
 LIBUNBOUND_REVISION=18
601e9c
-LIBUNBOUND_AGE=1
601e9c
+LIBUNBOUND_AGE=7
601e9c
 # 1.0.0 had 0:12:0
601e9c
 # 1.0.1 had 0:13:0
601e9c
 # 1.0.2 had 0:14:0
601e9c
diff --git a/unbound-1.16.2/daemon/worker.c b/unbound-1.16.2/daemon/worker.c
601e9c
index 010c4dc..2b87a41 100644
601e9c
--- a/unbound-1.16.2/daemon/worker.c
601e9c
+++ b/unbound-1.16.2/daemon/worker.c
601e9c
@@ -2268,21 +2268,21 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
601e9c
 
601e9c
 void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
601e9c
 	sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
601e9c
-	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
601e9c
+	char* ATTR_UNUSED(why_bogus))
601e9c
 {
601e9c
 	log_assert(0);
601e9c
 }
601e9c
 
601e9c
 void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
601e9c
 	sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
601e9c
-	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
601e9c
+	char* ATTR_UNUSED(why_bogus))
601e9c
 {
601e9c
 	log_assert(0);
601e9c
 }
601e9c
 
601e9c
 void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
601e9c
 	sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
601e9c
-	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
601e9c
+	char* ATTR_UNUSED(why_bogus))
601e9c
 {
601e9c
 	log_assert(0);
601e9c
 }
601e9c
diff --git a/unbound-1.16.2/libunbound/libworker.c b/unbound-1.16.2/libunbound/libworker.c
601e9c
index 11bf5f9..6895119 100644
601e9c
--- a/unbound-1.16.2/libunbound/libworker.c
601e9c
+++ b/unbound-1.16.2/libunbound/libworker.c
601e9c
@@ -549,9 +549,10 @@ libworker_enter_result(struct ub_result* res, sldns_buffer* buf,
601e9c
 /** fillup fg results */
601e9c
 static void
601e9c
 libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf, 
601e9c
-	enum sec_status s, char* why_bogus, int was_ratelimited)
601e9c
+	enum sec_status s, char* why_bogus)
601e9c
 {
601e9c
-	q->res->was_ratelimited = was_ratelimited;
601e9c
+	q->res->was_ratelimited = RCODE_IS_RATELIMITED(rcode);
601e9c
+	rcode = RCODE_NOT_RATELIMITED(rcode);
601e9c
 	if(why_bogus)
601e9c
 		q->res->why_bogus = strdup(why_bogus);
601e9c
 	if(rcode != 0) {
601e9c
@@ -575,13 +576,13 @@ libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf,
601e9c
 
601e9c
 void
601e9c
 libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
601e9c
-	char* why_bogus, int was_ratelimited)
601e9c
+	char* why_bogus)
601e9c
 {
601e9c
 	struct ctx_query* q = (struct ctx_query*)arg;
601e9c
 	/* fg query is done; exit comm base */
601e9c
 	comm_base_exit(q->w->base);
601e9c
 
601e9c
-	libworker_fillup_fg(q, rcode, buf, s, why_bogus, was_ratelimited);
601e9c
+	libworker_fillup_fg(q, rcode, buf, s, why_bogus);
601e9c
 }
601e9c
 
601e9c
 /** setup qinfo and edns */
601e9c
@@ -634,7 +635,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
601e9c
 		NULL, 0, NULL, 0, NULL)) {
601e9c
 		regional_free_all(w->env->scratch);
601e9c
 		libworker_fillup_fg(q, LDNS_RCODE_NOERROR, 
601e9c
-			w->back->udp_buff, sec_status_insecure, NULL, 0);
601e9c
+			w->back->udp_buff, sec_status_insecure, NULL);
601e9c
 		libworker_delete(w);
601e9c
 		free(qinfo.qname);
601e9c
 		return UB_NOERROR;
601e9c
@@ -643,7 +644,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
601e9c
 		w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
601e9c
 		regional_free_all(w->env->scratch);
601e9c
 		libworker_fillup_fg(q, LDNS_RCODE_NOERROR, 
601e9c
-			w->back->udp_buff, sec_status_insecure, NULL, 0);
601e9c
+			w->back->udp_buff, sec_status_insecure, NULL);
601e9c
 		libworker_delete(w);
601e9c
 		free(qinfo.qname);
601e9c
 		return UB_NOERROR;
601e9c
@@ -665,7 +666,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
601e9c
 
601e9c
 void
601e9c
 libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
601e9c
-	enum sec_status s, char* why_bogus, int was_ratelimited)
601e9c
+	enum sec_status s, char* why_bogus)
601e9c
 {
601e9c
 	struct ctx_query* q = (struct ctx_query*)arg;
601e9c
 	ub_event_callback_type cb = q->cb_event;
601e9c
@@ -688,7 +689,7 @@ libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
601e9c
 		else if(s == sec_status_secure)
601e9c
 			sec = 2;
601e9c
 		(*cb)(cb_arg, rcode, (buf?(void*)sldns_buffer_begin(buf):NULL),
601e9c
-			(buf?(int)sldns_buffer_limit(buf):0), sec, why_bogus, was_ratelimited);
601e9c
+			(buf?(int)sldns_buffer_limit(buf):0), sec, why_bogus);
601e9c
 	}
601e9c
 }
601e9c
 
601e9c
@@ -715,7 +716,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
601e9c
 		regional_free_all(w->env->scratch);
601e9c
 		free(qinfo.qname);
601e9c
 		libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
601e9c
-			w->back->udp_buff, sec_status_insecure, NULL, 0);
601e9c
+			w->back->udp_buff, sec_status_insecure, NULL);
601e9c
 		return UB_NOERROR;
601e9c
 	}
601e9c
 	if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
601e9c
@@ -723,7 +724,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
601e9c
 		regional_free_all(w->env->scratch);
601e9c
 		free(qinfo.qname);
601e9c
 		libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
601e9c
-			w->back->udp_buff, sec_status_insecure, NULL, 0);
601e9c
+			w->back->udp_buff, sec_status_insecure, NULL);
601e9c
 		return UB_NOERROR;
601e9c
 	}
601e9c
 	/* process new query */
601e9c
@@ -788,12 +789,23 @@ add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
601e9c
 	}
601e9c
 }
601e9c
 
601e9c
+
601e9c
+void
601e9c
+libworker_bg_done_cb_compat(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
601e9c
+	char* why_bogus)
601e9c
+{
601e9c
+	rcode = RCODE_NOT_RATELIMITED(rcode);
601e9c
+	libworker_bg_done_cb(arg, rcode, buf, s, why_bogus);
601e9c
+}
601e9c
+
601e9c
 void
601e9c
 libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
601e9c
-	char* why_bogus, int was_ratelimited)
601e9c
+	char* why_bogus)
601e9c
 {
601e9c
+	int was_ratelimited = RCODE_IS_RATELIMITED(rcode);
601e9c
 	struct ctx_query* q = (struct ctx_query*)arg;
601e9c
 
601e9c
+	rcode = RCODE_NOT_RATELIMITED(rcode);
601e9c
 	if(q->cancelled || q->w->back->want_to_quit) {
601e9c
 		if(q->w->is_bg_thread) {
601e9c
 			/* delete it now */
601e9c
diff --git a/unbound-1.16.2/libunbound/unbound-event.h b/unbound-1.16.2/libunbound/unbound-event.h
601e9c
index a5d5c03..70aa4c8 100644
601e9c
--- a/unbound-1.16.2/libunbound/unbound-event.h
601e9c
+++ b/unbound-1.16.2/libunbound/unbound-event.h
601e9c
@@ -170,7 +170,8 @@ struct ub_event {
601e9c
 	struct ub_event_vmt* vmt;
601e9c
 };
601e9c
 
601e9c
-typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*, int);
601e9c
+/* Uses define LDNS_RCODE_RATELIMITED from services/mesh.h */
601e9c
+typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*);
601e9c
 
601e9c
 /**
601e9c
  * Create a resolving and validation context.
601e9c
diff --git a/unbound-1.16.2/libunbound/unbound.h b/unbound-1.16.2/libunbound/unbound.h
601e9c
index c779d18..f6d5c7c 100644
601e9c
--- a/unbound-1.16.2/libunbound/unbound.h
601e9c
+++ b/unbound-1.16.2/libunbound/unbound.h
601e9c
@@ -203,18 +203,19 @@ struct ub_result {
601e9c
 	 */
601e9c
 	char* why_bogus;
601e9c
 
601e9c
+	/**
601e9c
+	 * TTL for the result, in seconds.  If the security is bogus, then
601e9c
+	 * you also cannot trust this value.
601e9c
+	 */
601e9c
+	int ttl;
601e9c
+
601e9c
 	/**
601e9c
 	 * If the query or one of its subqueries was ratelimited.  Useful if
601e9c
 	 * ratelimiting is enabled and answer to the client is SERVFAIL as a
601e9c
 	 * result.
601e9c
+	 * RHEL8 Change, moved after ttl.
601e9c
 	 */
601e9c
 	int was_ratelimited;
601e9c
-
601e9c
-	/**
601e9c
-	 * TTL for the result, in seconds.  If the security is bogus, then
601e9c
-	 * you also cannot trust this value.
601e9c
-	 */
601e9c
-	int ttl;
601e9c
 };
601e9c
 
601e9c
 /**
601e9c
diff --git a/unbound-1.16.2/libunbound/worker.h b/unbound-1.16.2/libunbound/worker.h
601e9c
index 0fa5bfa..8b64b4d 100644
601e9c
--- a/unbound-1.16.2/libunbound/worker.h
601e9c
+++ b/unbound-1.16.2/libunbound/worker.h
601e9c
@@ -90,15 +90,15 @@ void libworker_handle_control_cmd(struct tube* tube, uint8_t* msg, size_t len,
601e9c
 
601e9c
 /** mesh callback with fg results */
601e9c
 void libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf, 
601e9c
-	enum sec_status s, char* why_bogus, int was_ratelimited);
601e9c
+	enum sec_status s, char* why_bogus);
601e9c
 
601e9c
 /** mesh callback with bg results */
601e9c
 void libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, 
601e9c
-	enum sec_status s, char* why_bogus, int was_ratelimited);
601e9c
+	enum sec_status s, char* why_bogus);
601e9c
 
601e9c
 /** mesh callback with event results */
601e9c
 void libworker_event_done_cb(void* arg, int rcode, struct sldns_buffer* buf, 
601e9c
-	enum sec_status s, char* why_bogus, int was_ratelimited);
601e9c
+	enum sec_status s, char* why_bogus);
601e9c
 
601e9c
 /**
601e9c
  * Worker signal handler function. User argument is the worker itself.
601e9c
diff --git a/unbound-1.16.2/services/authzone.c b/unbound-1.16.2/services/authzone.c
601e9c
index b9e0b11..c72949f 100644
601e9c
--- a/unbound-1.16.2/services/authzone.c
601e9c
+++ b/unbound-1.16.2/services/authzone.c
601e9c
@@ -5656,8 +5656,7 @@ xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset,
601e9c
 
601e9c
 /** callback for task_transfer lookup of host name, of A or AAAA */
601e9c
 void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
601e9c
-	enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus),
601e9c
-	int ATTR_UNUSED(was_ratelimited))
601e9c
+	enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus))
601e9c
 {
601e9c
 	struct auth_xfer* xfr = (struct auth_xfer*)arg;
601e9c
 	struct module_env* env;
601e9c
@@ -5669,6 +5668,7 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
601e9c
 		return; /* stop on quit */
601e9c
 	}
601e9c
 
601e9c
+	rcode = RCODE_NOT_RATELIMITED(rcode);
601e9c
 	/* process result */
601e9c
 	if(rcode == LDNS_RCODE_NOERROR) {
601e9c
 		uint16_t wanted_qtype = LDNS_RR_TYPE_A;
601e9c
@@ -6717,8 +6717,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
601e9c
 
601e9c
 /** callback for task_probe lookup of host name, of A or AAAA */
601e9c
 void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
601e9c
-	enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus),
601e9c
-	int ATTR_UNUSED(was_ratelimited))
601e9c
+	enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus))
601e9c
 {
601e9c
 	struct auth_xfer* xfr = (struct auth_xfer*)arg;
601e9c
 	struct module_env* env;
601e9c
@@ -6730,6 +6729,7 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
601e9c
 		return; /* stop on quit */
601e9c
 	}
601e9c
 
601e9c
+	rcode = RCODE_NOT_RATELIMITED(rcode);
601e9c
 	/* process result */
601e9c
 	if(rcode == LDNS_RCODE_NOERROR) {
601e9c
 		uint16_t wanted_qtype = LDNS_RR_TYPE_A;
601e9c
@@ -8212,7 +8212,7 @@ auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
601e9c
 
601e9c
 /** callback for ZONEMD lookup of DNSKEY */
601e9c
 void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
601e9c
-	enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited))
601e9c
+	enum sec_status sec, char* why_bogus)
601e9c
 {
601e9c
 	struct auth_zone* z = (struct auth_zone*)arg;
601e9c
 	struct module_env* env;
601e9c
@@ -8234,6 +8234,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
601e9c
 	if(z->zonemd_callback_qtype == LDNS_RR_TYPE_DS)
601e9c
 		typestr = "DS";
601e9c
 	downprot = env->cfg->harden_algo_downgrade;
601e9c
+	rcode = RCODE_NOT_RATELIMITED(rcode);
601e9c
 
601e9c
 	/* process result */
601e9c
 	if(sec == sec_status_bogus) {
601e9c
diff --git a/unbound-1.16.2/services/authzone.h b/unbound-1.16.2/services/authzone.h
601e9c
index 07614ed..b339fc1 100644
601e9c
--- a/unbound-1.16.2/services/authzone.h
601e9c
+++ b/unbound-1.16.2/services/authzone.h
601e9c
@@ -690,12 +690,10 @@ void auth_xfer_probe_timer_callback(void* arg);
601e9c
 void auth_xfer_transfer_timer_callback(void* arg);
601e9c
 /** mesh callback for task_probe on lookup of host names */
601e9c
 void auth_xfer_probe_lookup_callback(void* arg, int rcode,
601e9c
-	struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
601e9c
-	int was_ratelimited);
601e9c
+	struct sldns_buffer* buf, enum sec_status sec, char* why_bogus);
601e9c
 /** mesh callback for task_transfer on lookup of host names */
601e9c
 void auth_xfer_transfer_lookup_callback(void* arg, int rcode,
601e9c
-	struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
601e9c
-	int was_ratelimited);
601e9c
+	struct sldns_buffer* buf, enum sec_status sec, char* why_bogus);
601e9c
 
601e9c
 /*
601e9c
  * Compares two 32-bit serial numbers as defined in RFC1982.  Returns
601e9c
@@ -774,8 +772,7 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
601e9c
 
601e9c
 /** mesh callback for zonemd on lookup of dnskey */
601e9c
 void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode,
601e9c
-	struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
601e9c
-	int was_ratelimited);
601e9c
+	struct sldns_buffer* buf, enum sec_status sec, char* why_bogus);
601e9c
 
601e9c
 /**
601e9c
  * Check the ZONEMD records that need online DNSSEC chain lookups,
601e9c
diff --git a/unbound-1.16.2/services/mesh.c b/unbound-1.16.2/services/mesh.c
601e9c
index 30bcf7c..fc3c690 100644
601e9c
--- a/unbound-1.16.2/services/mesh.c
601e9c
+++ b/unbound-1.16.2/services/mesh.c
601e9c
@@ -63,6 +63,7 @@
601e9c
 #include "util/data/dname.h"
601e9c
 #include "respip/respip.h"
601e9c
 #include "services/listen_dnsport.h"
601e9c
+#include "libunbound/unbound-event.h"
601e9c
 
601e9c
 #ifdef CLIENT_SUBNET
601e9c
 #include "edns-subnet/subnetmod.h"
601e9c
@@ -1012,7 +1013,7 @@ mesh_state_cleanup(struct mesh_state* mstate)
601e9c
 			mstate->cb_list = cb->next;
601e9c
 			fptr_ok(fptr_whitelist_mesh_cb(cb->cb));
601e9c
 			(*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL,
601e9c
-				sec_status_unchecked, NULL, 0);
601e9c
+				sec_status_unchecked, NULL);
601e9c
 			log_assert(mesh->num_reply_addrs > 0);
601e9c
 			mesh->num_reply_addrs--;
601e9c
 		}
601e9c
@@ -1268,8 +1269,9 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
601e9c
 					r->edns.opt_list_inplace_cb_out = NULL;
601e9c
 		}
601e9c
 		fptr_ok(fptr_whitelist_mesh_cb(r->cb));
601e9c
-		(*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL,
601e9c
-			was_ratelimited);
601e9c
+		if (was_ratelimited)
601e9c
+			rcode |= LDNS_RCODE_RATELIMITED;
601e9c
+		(*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL);
601e9c
 	} else {
601e9c
 		size_t udp_size = r->edns.udp_size;
601e9c
 		sldns_buffer_clear(r->buf);
601e9c
@@ -1287,11 +1289,14 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
601e9c
 		{
601e9c
 			fptr_ok(fptr_whitelist_mesh_cb(r->cb));
601e9c
 			(*r->cb)(r->cb_arg, LDNS_RCODE_SERVFAIL, r->buf,
601e9c
-				sec_status_unchecked, NULL, 0);
601e9c
+				sec_status_unchecked, NULL);
601e9c
 		} else {
601e9c
 			fptr_ok(fptr_whitelist_mesh_cb(r->cb));
601e9c
-			(*r->cb)(r->cb_arg, LDNS_RCODE_NOERROR, r->buf,
601e9c
-				rep->security, reason, was_ratelimited);
601e9c
+			rcode = LDNS_RCODE_NOERROR;
601e9c
+			if (was_ratelimited)
601e9c
+				rcode |= LDNS_RCODE_RATELIMITED;
601e9c
+			(*r->cb)(r->cb_arg, rcode, r->buf,
601e9c
+				rep->security, reason);
601e9c
 		}
601e9c
 	}
601e9c
 	free(reason);
601e9c
diff --git a/unbound-1.16.2/services/mesh.h b/unbound-1.16.2/services/mesh.h
601e9c
index 3be9b63..5050d6c 100644
601e9c
--- a/unbound-1.16.2/services/mesh.h
601e9c
+++ b/unbound-1.16.2/services/mesh.h
601e9c
@@ -234,13 +234,20 @@ struct mesh_reply {
601e9c
 	struct http2_stream* h2_stream;
601e9c
 };
601e9c
 
601e9c
+/* RHEL 8 compatibility layer.
601e9c
+ * Special rcode to send was_ratelimited to callback without adding
601e9c
+ * extra parameter. It is ORed to the rcode parameter of the callback. */
601e9c
+#define LDNS_RCODE_RATELIMITED 0x100
601e9c
+#define RCODE_IS_RATELIMITED(rcode) ((rcode & LDNS_RCODE_RATELIMITED) != 0)
601e9c
+#define RCODE_NOT_RATELIMITED(rcode) (rcode & ~LDNS_RCODE_RATELIMITED)
601e9c
+
601e9c
 /** 
601e9c
  * Mesh result callback func.
601e9c
  * called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus,
601e9c
  *		was_ratelimited);
601e9c
  */
601e9c
 typedef void (*mesh_cb_func_type)(void* cb_arg, int rcode, struct sldns_buffer*,
601e9c
-	enum sec_status, char* why_bogus, int was_ratelimited);
601e9c
+	enum sec_status, char* why_bogus);
601e9c
 
601e9c
 /**
601e9c
  * Callback to result routine
601e9c
diff --git a/unbound-1.16.2/smallapp/worker_cb.c b/unbound-1.16.2/smallapp/worker_cb.c
601e9c
index c689817..c7b1653 100644
601e9c
--- a/unbound-1.16.2/smallapp/worker_cb.c
601e9c
+++ b/unbound-1.16.2/smallapp/worker_cb.c
601e9c
@@ -159,21 +159,21 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
601e9c
 
601e9c
 void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), 
601e9c
 	struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
601e9c
-	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
601e9c
+	char* ATTR_UNUSED(why_bogus))
601e9c
 {
601e9c
 	log_assert(0);
601e9c
 }
601e9c
 
601e9c
 void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), 
601e9c
 	struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
601e9c
-	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
601e9c
+	char* ATTR_UNUSED(why_bogus))
601e9c
 {
601e9c
 	log_assert(0);
601e9c
 }
601e9c
 
601e9c
 void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), 
601e9c
 	struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
601e9c
-	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
601e9c
+	char* ATTR_UNUSED(why_bogus))
601e9c
 {
601e9c
 	log_assert(0);
601e9c
 }
601e9c
diff --git a/unbound-1.16.2/validator/autotrust.c b/unbound-1.16.2/validator/autotrust.c
601e9c
index 3cdf9ce..40b3e35 100644
601e9c
--- a/unbound-1.16.2/validator/autotrust.c
601e9c
+++ b/unbound-1.16.2/validator/autotrust.c
601e9c
@@ -2331,7 +2331,7 @@ autr_debug_print(struct val_anchors* anchors)
601e9c
 
601e9c
 void probe_answer_cb(void* arg, int ATTR_UNUSED(rcode), 
601e9c
 	sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(sec),
601e9c
-	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
601e9c
+	char* ATTR_UNUSED(why_bogus))
601e9c
 {
601e9c
 	/* retry was set before the query was done,
601e9c
 	 * re-querytime is set when query succeeded, but that may not
601e9c
diff --git a/unbound-1.16.2/validator/autotrust.h b/unbound-1.16.2/validator/autotrust.h
601e9c
index 057f2b6..c549798 100644
601e9c
--- a/unbound-1.16.2/validator/autotrust.h
601e9c
+++ b/unbound-1.16.2/validator/autotrust.h
601e9c
@@ -206,6 +206,6 @@ void autr_debug_print(struct val_anchors* anchors);
601e9c
 
601e9c
 /** callback for query answer to 5011 probe */
601e9c
 void probe_answer_cb(void* arg, int rcode, struct sldns_buffer* buf, 
601e9c
-	enum sec_status sec, char* errinf, int was_ratelimited);
601e9c
+	enum sec_status sec, char* errinf);
601e9c
 
601e9c
 #endif /* VALIDATOR_AUTOTRUST_H */
601e9c
-- 
601e9c
2.37.1
601e9c