From ae5d316f649cf2db6d133f9e036f3528ab934aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= Date: Wed, 1 Jul 2020 19:07:04 +0200 Subject: [PATCH] isccc: merge recv_message and recv_nonce into one function - make isccc message receiving code clearer by merging recv_nonce and recv_message into a single recv_data function and adding a boolean state field. --- lib/isccc/ccmsg.c | 138 ++++++++++++-------------------- lib/isccc/include/isccc/ccmsg.h | 2 + 2 files changed, 52 insertions(+), 88 deletions(-) diff --git a/lib/isccc/ccmsg.c b/lib/isccc/ccmsg.c index 72e79cd9ca..5e80cf82da 100644 --- a/lib/isccc/ccmsg.c +++ b/lib/isccc/ccmsg.c @@ -40,79 +40,8 @@ #define VALID_CCMSG(foo) ISC_MAGIC_VALID(foo, CCMSG_MAGIC) static void -recv_message(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, - void *arg); - -static void -recv_nonce(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, - void *arg) { - isccc_ccmsg_t *ccmsg = arg; - isc_result_t result; - - INSIST(VALID_CCMSG(ccmsg)); - - if (eresult == ISC_R_CANCELED || eresult == ISC_R_EOF) { - ccmsg->result = eresult; - goto done; - } - - if (region == NULL && eresult == ISC_R_SUCCESS) { - ccmsg->result = ISC_R_EOF; - goto done; - } else if (eresult != ISC_R_SUCCESS) { - ccmsg->result = eresult; - goto done; - } else { - ccmsg->result = eresult; - } - - if (region->length < sizeof(uint32_t)) { - ccmsg->result = ISC_R_UNEXPECTEDEND; - goto done; - } - - ccmsg->size = ntohl(*(uint32_t *)region->base); - if (ccmsg->size == 0) { - ccmsg->result = ISC_R_UNEXPECTEDEND; - goto done; - } - if (ccmsg->size > ccmsg->maxsize) { - ccmsg->result = ISC_R_RANGE; - goto done; - } - - isc_region_consume(region, sizeof(uint32_t)); - isc_buffer_allocate(ccmsg->mctx, &ccmsg->buffer, ccmsg->size); - - /* - * If there's more of the message waiting, pass it to - * recv_message() directly. - */ - if (region->length != 0) { - recv_message(handle, ISC_R_SUCCESS, region, ccmsg); - return; - } - - /* - * Otherwise, continue reading and handle it in - * recv_message(). - */ - result = isc_nm_read(handle, recv_message, ccmsg); - if (result == ISC_R_SUCCESS) { - return; - } - - ccmsg->result = result; - -done: - ccmsg->cb(handle, ccmsg->result, ccmsg->cbarg); - isc_nmhandle_unref(handle); -} - -static void -recv_message(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, - void *arg) { - isc_result_t result; +recv_data(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, + void *arg) { isccc_ccmsg_t *ccmsg = arg; size_t size; @@ -121,9 +50,7 @@ recv_message(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, if (eresult == ISC_R_CANCELED || eresult == ISC_R_EOF) { ccmsg->result = eresult; goto done; - } - - if (region == NULL && eresult == ISC_R_SUCCESS) { + } else if (region == NULL && eresult == ISC_R_SUCCESS) { ccmsg->result = ISC_R_EOF; goto done; } else if (eresult != ISC_R_SUCCESS) { @@ -133,11 +60,38 @@ recv_message(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, ccmsg->result = eresult; } - if (region->length == 0) { - ccmsg->result = ISC_R_UNEXPECTEDEND; - goto done; + if (!ccmsg->length_received) { + if (region->length < sizeof(uint32_t)) { + ccmsg->result = ISC_R_UNEXPECTEDEND; + goto done; + } + + ccmsg->size = ntohl(*(uint32_t *)region->base); + + if (ccmsg->size == 0) { + ccmsg->result = ISC_R_UNEXPECTEDEND; + goto done; + } + if (ccmsg->size > ccmsg->maxsize) { + ccmsg->result = ISC_R_RANGE; + goto done; + } + + isc_region_consume(region, sizeof(uint32_t)); + isc_buffer_allocate(ccmsg->mctx, &ccmsg->buffer, ccmsg->size); + + ccmsg->length_received = true; } + /* + * If there's no more data, wait for more + */ + if (region->length == 0) { + return; + } + + /* We have some data in the buffer, read it */ + size = ISC_MIN(isc_buffer_availablelength(ccmsg->buffer), region->length); isc_buffer_putmem(ccmsg->buffer, region->base, size); @@ -148,14 +102,11 @@ recv_message(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, goto done; } - result = isc_nm_read(handle, recv_message, ccmsg); - if (result == ISC_R_SUCCESS) { - return; - } - - ccmsg->result = result; + /* Wait for more data to come */ + return; done: + isc_nm_pauseread(handle); ccmsg->cb(handle, ccmsg->result, ccmsg->cbarg); isc_nmhandle_unref(handle); } @@ -196,10 +147,19 @@ isccc_ccmsg_readmessage(isccc_ccmsg_t *ccmsg, isc_nm_cb_t cb, void *cbarg) { ccmsg->cb = cb; ccmsg->cbarg = cbarg; ccmsg->result = ISC_R_UNEXPECTED; /* unknown right now */ + ccmsg->length_received = false; isc_nmhandle_ref(ccmsg->handle); - result = isc_nm_read(ccmsg->handle, recv_nonce, ccmsg); - if (result != ISC_R_SUCCESS) { + if (ccmsg->reading) { + result = isc_nm_resumeread(ccmsg->handle); + } else { + result = isc_nm_read(ccmsg->handle, recv_data, ccmsg); + ccmsg->reading = true; + } + if (result == ISC_R_CANCELED) { + ccmsg->reading = false; + } else if (result != ISC_R_SUCCESS) { + ccmsg->reading = false; isc_nmhandle_unref(ccmsg->handle); } @@ -210,7 +170,9 @@ void isccc_ccmsg_cancelread(isccc_ccmsg_t *ccmsg) { REQUIRE(VALID_CCMSG(ccmsg)); - isc_nm_cancelread(ccmsg->handle); + if (ccmsg->reading) { + isc_nm_cancelread(ccmsg->handle); + } } void diff --git a/lib/isccc/include/isccc/ccmsg.h b/lib/isccc/include/isccc/ccmsg.h index 3451007bf9..baa2c19bb3 100644 --- a/lib/isccc/include/isccc/ccmsg.h +++ b/lib/isccc/include/isccc/ccmsg.h @@ -40,12 +40,14 @@ typedef struct isccc_ccmsg { /* private (don't touch!) */ unsigned int magic; uint32_t size; + bool length_received; isc_buffer_t * buffer; unsigned int maxsize; isc_mem_t * mctx; isc_nmhandle_t *handle; isc_nm_cb_t cb; void * cbarg; + bool reading; /* public (read-only) */ isc_result_t result; } isccc_ccmsg_t;