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

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