"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/isccc/ccmsg.c" (7 Sep 2020, 5606 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ccmsg.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.17.3_vs_9.17.4.

    1 /*
    2  * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  *
   11  * Portions Copyright (C) 2001 Nominum, Inc.
   12  *
   13  * Permission to use, copy, modify, and/or distribute this software for any
   14  * purpose with or without fee is hereby granted, provided that the above
   15  * copyright notice and this permission notice appear in all copies.
   16  *
   17  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL
   18  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY
   20  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   21  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   22  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   23  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   24  */
   25 
   26 
   27 /*! \file */
   28 
   29 #include <config.h>
   30 
   31 #include <inttypes.h>
   32 
   33 #include <isc/mem.h>
   34 #include <isc/result.h>
   35 #include <isc/task.h>
   36 #include <isc/util.h>
   37 
   38 #include <isccc/events.h>
   39 #include <isccc/ccmsg.h>
   40 
   41 #define CCMSG_MAGIC     ISC_MAGIC('C', 'C', 'm', 's')
   42 #define VALID_CCMSG(foo)    ISC_MAGIC_VALID(foo, CCMSG_MAGIC)
   43 
   44 static void recv_length(isc_task_t *, isc_event_t *);
   45 static void recv_message(isc_task_t *, isc_event_t *);
   46 
   47 
   48 static void
   49 recv_length(isc_task_t *task, isc_event_t *ev_in) {
   50     isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
   51     isc_event_t *dev;
   52     isccc_ccmsg_t *ccmsg = ev_in->ev_arg;
   53     isc_region_t region;
   54     isc_result_t result;
   55 
   56     INSIST(VALID_CCMSG(ccmsg));
   57 
   58     dev = &ccmsg->event;
   59 
   60     if (ev->result != ISC_R_SUCCESS) {
   61         ccmsg->result = ev->result;
   62         goto send_and_free;
   63     }
   64 
   65     /*
   66      * Success.
   67      */
   68     ccmsg->size = ntohl(ccmsg->size);
   69     if (ccmsg->size == 0) {
   70         ccmsg->result = ISC_R_UNEXPECTEDEND;
   71         goto send_and_free;
   72     }
   73     if (ccmsg->size > ccmsg->maxsize) {
   74         ccmsg->result = ISC_R_RANGE;
   75         goto send_and_free;
   76     }
   77 
   78     region.base = isc_mem_get(ccmsg->mctx, ccmsg->size);
   79     region.length = ccmsg->size;
   80     if (region.base == NULL) {
   81         ccmsg->result = ISC_R_NOMEMORY;
   82         goto send_and_free;
   83     }
   84 
   85     isc_buffer_init(&ccmsg->buffer, region.base, region.length);
   86     result = isc_socket_recv(ccmsg->sock, &region, 0,
   87                  task, recv_message, ccmsg);
   88     if (result != ISC_R_SUCCESS) {
   89         ccmsg->result = result;
   90         goto send_and_free;
   91     }
   92 
   93     isc_event_free(&ev_in);
   94     return;
   95 
   96  send_and_free:
   97     isc_task_send(ccmsg->task, &dev);
   98     ccmsg->task = NULL;
   99     isc_event_free(&ev_in);
  100     return;
  101 }
  102 
  103 static void
  104 recv_message(isc_task_t *task, isc_event_t *ev_in) {
  105     isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
  106     isc_event_t *dev;
  107     isccc_ccmsg_t *ccmsg = ev_in->ev_arg;
  108 
  109     (void)task;
  110 
  111     INSIST(VALID_CCMSG(ccmsg));
  112 
  113     dev = &ccmsg->event;
  114 
  115     if (ev->result != ISC_R_SUCCESS) {
  116         ccmsg->result = ev->result;
  117         goto send_and_free;
  118     }
  119 
  120     ccmsg->result = ISC_R_SUCCESS;
  121     isc_buffer_add(&ccmsg->buffer, ev->n);
  122     ccmsg->address = ev->address;
  123 
  124  send_and_free:
  125     isc_task_send(ccmsg->task, &dev);
  126     ccmsg->task = NULL;
  127     isc_event_free(&ev_in);
  128 }
  129 
  130 void
  131 isccc_ccmsg_init(isc_mem_t *mctx, isc_socket_t *sock, isccc_ccmsg_t *ccmsg) {
  132     REQUIRE(mctx != NULL);
  133     REQUIRE(sock != NULL);
  134     REQUIRE(ccmsg != NULL);
  135 
  136     ccmsg->magic = CCMSG_MAGIC;
  137     ccmsg->size = 0;
  138     ccmsg->buffer.base = NULL;
  139     ccmsg->buffer.length = 0;
  140     ccmsg->maxsize = 4294967295U;   /* Largest message possible. */
  141     ccmsg->mctx = mctx;
  142     ccmsg->sock = sock;
  143     ccmsg->task = NULL;         /* None yet. */
  144     ccmsg->result = ISC_R_UNEXPECTED;   /* None yet. */
  145     /*
  146      * Should probably initialize the event here, but it can wait.
  147      */
  148 }
  149 
  150 
  151 void
  152 isccc_ccmsg_setmaxsize(isccc_ccmsg_t *ccmsg, unsigned int maxsize) {
  153     REQUIRE(VALID_CCMSG(ccmsg));
  154 
  155     ccmsg->maxsize = maxsize;
  156 }
  157 
  158 
  159 isc_result_t
  160 isccc_ccmsg_readmessage(isccc_ccmsg_t *ccmsg,
  161                isc_task_t *task, isc_taskaction_t action, void *arg)
  162 {
  163     isc_result_t result;
  164     isc_region_t region;
  165 
  166     REQUIRE(VALID_CCMSG(ccmsg));
  167     REQUIRE(task != NULL);
  168     REQUIRE(ccmsg->task == NULL);  /* not currently in use */
  169 
  170     if (ccmsg->buffer.base != NULL) {
  171         isc_mem_put(ccmsg->mctx, ccmsg->buffer.base,
  172                 ccmsg->buffer.length);
  173         ccmsg->buffer.base = NULL;
  174         ccmsg->buffer.length = 0;
  175     }
  176 
  177     ccmsg->task = task;
  178     ccmsg->action = action;
  179     ccmsg->arg = arg;
  180     ccmsg->result = ISC_R_UNEXPECTED;  /* unknown right now */
  181 
  182     ISC_EVENT_INIT(&ccmsg->event, sizeof(isc_event_t), 0, 0,
  183                ISCCC_EVENT_CCMSG, action, arg, ccmsg,
  184                NULL, NULL);
  185 
  186     region.base = (unsigned char *)&ccmsg->size;
  187     region.length = 4;  /* uint32_t */
  188     result = isc_socket_recv(ccmsg->sock, &region, 0,
  189                  ccmsg->task, recv_length, ccmsg);
  190 
  191     if (result != ISC_R_SUCCESS)
  192         ccmsg->task = NULL;
  193 
  194     return (result);
  195 }
  196 
  197 void
  198 isccc_ccmsg_cancelread(isccc_ccmsg_t *ccmsg) {
  199     REQUIRE(VALID_CCMSG(ccmsg));
  200 
  201     isc_socket_cancel(ccmsg->sock, NULL, ISC_SOCKCANCEL_RECV);
  202 }
  203 
  204 #if 0
  205 void
  206 isccc_ccmsg_freebuffer(isccc_ccmsg_t *ccmsg) {
  207     REQUIRE(VALID_CCMSG(ccmsg));
  208 
  209     if (ccmsg->buffer.base == NULL)
  210         return;
  211 
  212     isc_mem_put(ccmsg->mctx, ccmsg->buffer.base, ccmsg->buffer.length);
  213     ccmsg->buffer.base = NULL;
  214     ccmsg->buffer.length = 0;
  215 }
  216 #endif
  217 
  218 void
  219 isccc_ccmsg_invalidate(isccc_ccmsg_t *ccmsg) {
  220     REQUIRE(VALID_CCMSG(ccmsg));
  221 
  222     ccmsg->magic = 0;
  223 
  224     if (ccmsg->buffer.base != NULL) {
  225         isc_mem_put(ccmsg->mctx, ccmsg->buffer.base,
  226                 ccmsg->buffer.length);
  227         ccmsg->buffer.base = NULL;
  228         ccmsg->buffer.length = 0;
  229     }
  230 }