Implement asynchronous message signature verification

Add support for using the offload threadpool to perform message
signature verifications. This should allow check SIG(0)-signed
messages without affecting the worker threads.
This commit is contained in:
Aram Sargsyan 2024-03-06 11:06:27 +00:00 committed by Nicki Křížek
parent 7f013ad05d
commit 710bf9b938
No known key found for this signature in database
GPG key ID: 01623B9B652A20A7
2 changed files with 76 additions and 0 deletions

View file

@ -352,6 +352,8 @@ struct dns_ednsopt {
unsigned char *value;
};
typedef void (*dns_message_cb_t)(void *arg, isc_result_t result);
/***
*** Functions
***/
@ -1327,6 +1329,26 @@ dns_message_checksig(dns_message_t *msg, dns_view_t *view);
*\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
*/
isc_result_t
dns_message_checksig_async(dns_message_t *msg, dns_view_t *view,
isc_loop_t *loop, dns_message_cb_t cb, void *cbarg);
/*%<
* Run dns_message_checksig() in an offloaded thread and return its result
* using the 'cb' callback function, running on the 'loop'.
*
* Requires:
*
*\li msg is a valid parsed message.
*\li view is a valid view or NULL.
*\li loop is a valid loop.
*\li cb is a valid callback function.
*
* Returns:
*
*\li #DNS_R_WAIT
*
*/
void
dns_message_resetsig(dns_message_t *msg);
/*%<

View file

@ -29,6 +29,7 @@
#include <isc/string.h>
#include <isc/utf8.h>
#include <isc/util.h>
#include <isc/work.h>
#include <dns/dnssec.h>
#include <dns/keyvalues.h>
@ -180,6 +181,18 @@ msgblock_allocate(isc_mem_t *, unsigned int, unsigned int);
#define msgblock_get(block, type) \
((type *)msgblock_internalget(block, sizeof(type)))
/*
* A context type to pass information when checking a message signature
* asynchronously.
*/
typedef struct checksig_ctx {
dns_message_t *msg;
dns_view_t *view;
dns_message_cb_t cb;
void *cbarg;
isc_result_t result;
} checksig_ctx_t;
/*
* This function differs from public dns_message_puttemprdataset() that it
* requires the *rdatasetp to be associated, and it will disassociate and
@ -3205,6 +3218,47 @@ dns_message_dumpsig(dns_message_t *msg, char *txt1) {
}
#endif /* ifdef SKAN_MSG_DEBUG */
static void
checksig_run(void *arg) {
checksig_ctx_t *chsigctx = arg;
chsigctx->result = dns_message_checksig(chsigctx->msg, chsigctx->view);
}
static void
checksig_cb(void *arg) {
checksig_ctx_t *chsigctx = arg;
dns_message_t *msg = chsigctx->msg;
chsigctx->cb(chsigctx->cbarg, chsigctx->result);
dns_view_detach(&chsigctx->view);
isc_mem_put(msg->mctx, chsigctx, sizeof(*chsigctx));
dns_message_detach(&msg);
}
isc_result_t
dns_message_checksig_async(dns_message_t *msg, dns_view_t *view,
isc_loop_t *loop, dns_message_cb_t cb, void *cbarg) {
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(view != NULL);
REQUIRE(loop != NULL);
REQUIRE(cb != NULL);
checksig_ctx_t *chsigctx = isc_mem_get(msg->mctx, sizeof(*chsigctx));
*chsigctx = (checksig_ctx_t){
.cb = cb,
.cbarg = cbarg,
.result = ISC_R_UNSET,
};
dns_message_attach(msg, &chsigctx->msg);
dns_view_attach(view, &chsigctx->view);
isc_work_enqueue(loop, checksig_run, checksig_cb, chsigctx);
return (DNS_R_WAIT);
}
isc_result_t
dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
isc_buffer_t b, msgb;