]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
isccc: merge recv_message and recv_nonce into one function
authorWitold Kręcicki <wpk@isc.org>
Wed, 1 Jul 2020 17:07:04 +0000 (19:07 +0200)
committerEvan Hunt <each@isc.org>
Mon, 13 Jul 2020 20:17:08 +0000 (13:17 -0700)
- 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
lib/isccc/include/isccc/ccmsg.h

index 72e79cd9ca414c2fc456c11a243278a33c3e574a..5e80cf82da64e2c302f00ed7d636a85a6611a6b0 100644 (file)
 #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) {
+recv_data(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
+         void *arg) {
        isccc_ccmsg_t *ccmsg = arg;
-       isc_result_t result;
+       size_t size;
 
        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) {
+       } else if (region == NULL && eresult == ISC_R_SUCCESS) {
                ccmsg->result = ISC_R_EOF;
                goto done;
        } else if (eresult != ISC_R_SUCCESS) {
@@ -66,77 +60,37 @@ recv_nonce(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
                ccmsg->result = eresult;
        }
 
-       if (region->length < sizeof(uint32_t)) {
-               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;
-       }
+               ccmsg->size = ntohl(*(uint32_t *)region->base);
 
-       isc_region_consume(region, sizeof(uint32_t));
-       isc_buffer_allocate(ccmsg->mctx, &ccmsg->buffer, ccmsg->size);
+               if (ccmsg->size == 0) {
+                       ccmsg->result = ISC_R_UNEXPECTEDEND;
+                       goto done;
+               }
+               if (ccmsg->size > ccmsg->maxsize) {
+                       ccmsg->result = ISC_R_RANGE;
+                       goto done;
+               }
 
-       /*
-        * 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;
+               isc_region_consume(region, sizeof(uint32_t));
+               isc_buffer_allocate(ccmsg->mctx, &ccmsg->buffer, ccmsg->size);
+
+               ccmsg->length_received = true;
        }
 
        /*
-        * Otherwise, continue reading and handle it in
-        * recv_message().
+        * If there's no more data, wait for more
         */
-       result = isc_nm_read(handle, recv_message, ccmsg);
-       if (result == ISC_R_SUCCESS) {
+       if (region->length == 0) {
                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;
-       isccc_ccmsg_t *ccmsg = arg;
-       size_t size;
-
-       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 == 0) {
-               ccmsg->result = ISC_R_UNEXPECTEDEND;
-               goto done;
-       }
+       /* We have some data in the buffer, read it */
 
        size = ISC_MIN(isc_buffer_availablelength(ccmsg->buffer),
                       region->length);
@@ -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
index 3451007bf91440764ea6e75e7eac0a47953faffa..baa2c19bb301230efa27ad0d26971d69d7ee22b6 100644 (file)
@@ -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;