lwres_noop.c revision c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840e
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff/*
70e5a7403f0e0a3bd292b8287c5fed5772c15270Automatic Updater * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
499b34cea04a46823d003d4c0520c8b03e8513cbBrian Wellington * Copyright (C) 2000, 2001 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * Permission to use, copy, modify, and/or distribute this software for any
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff * purpose with or without fee is hereby granted, provided that the above
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
70e5a7403f0e0a3bd292b8287c5fed5772c15270Automatic Updater/* $Id: lwres_noop.c,v 1.19 2007/06/19 23:47:22 tbox Exp $ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*! \file */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/**
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * These are low-level routines for creating and parsing lightweight
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * resolver no-op request and response messages.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * The no-op message is analogous to a ping packet: a packet is sent to
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * the resolver daemon and is simply echoed back. The opcode is intended
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * to allow a client to determine if the server is operational or not.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * There are four main functions for the no-op opcode. One render
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * function converts a no-op request structure -- lwres_nooprequest_t --
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * to the lighweight resolver's canonical format. It is complemented by a
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * parse function that converts a packet in this canonical format to a
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * no-op request structure. Another render function converts the no-op
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * response structure -- lwres_noopresponse_t to the canonical format.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * This is complemented by a parse function which converts a packet in
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * canonical format to a no-op response structure.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * These structures are defined in \link lwres.h <lwres/lwres.h.> \endlink They are shown below.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * \code
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * #define LWRES_OPCODE_NOOP 0x00000000U
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * typedef struct {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_uint16_t datalength;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * unsigned char *data;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * } lwres_nooprequest_t;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * typedef struct {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_uint16_t datalength;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * unsigned char *data;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * } lwres_noopresponse_t;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * \endcode
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * Although the structures have different types, they are identical. This
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * is because the no-op opcode simply echos whatever data was sent: the
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * response is therefore identical to the request.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_nooprequest_render() uses resolver context ctx to convert no-op
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * request structure req to canonical format. The packet header structure
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * pkt is initialised and transferred to buffer b. The contents of *req
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * are then appended to the buffer in canonical format.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_noopresponse_render() performs the same task, except it converts
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * a no-op response structure lwres_noopresponse_t to the lightweight
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * resolver's canonical format.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_nooprequest_parse() uses context ctx to convert the contents of
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * packet pkt to a lwres_nooprequest_t structure. Buffer b provides space
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * to be used for storing this structure. When the function succeeds, the
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * resulting lwres_nooprequest_t is made available through *structp.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_noopresponse_parse() offers the same semantics as
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_nooprequest_parse() except it yields a lwres_noopresponse_t
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * structure.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_noopresponse_free() and lwres_nooprequest_free() release the
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * memory in resolver context ctx that was allocated to the
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_noopresponse_t or lwres_nooprequest_t structures referenced via
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * structp.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * \section lwres_noop_return Return Values
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * The no-op opcode functions lwres_nooprequest_render(),
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_noopresponse_render() lwres_nooprequest_parse() and
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_noopresponse_parse() all return #LWRES_R_SUCCESS on success. They
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * return #LWRES_R_NOMEMORY if memory allocation fails.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * #LWRES_R_UNEXPECTEDEND is returned if the available space in the buffer
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * b is too small to accommodate the packet header or the
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_nooprequest_t and lwres_noopresponse_t structures.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_nooprequest_parse() and lwres_noopresponse_parse() will return
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * #LWRES_R_UNEXPECTEDEND if the buffer is not empty after decoding the
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * received packet. These functions will return #LWRES_R_FAILURE if
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * pktflags in the packet header structure #lwres_lwpacket_t indicate that
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * the packet is not a response to an earlier query.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * \section lwres_noop_see See Also
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwpacket.c
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <config.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <assert.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <stdlib.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <string.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <lwres/lwbuffer.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <lwres/lwpacket.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <lwres/lwres.h>
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff#include <lwres/result.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include "context_p.h"
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include "assert_p.h"
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Uses resolver context ctx to convert no-op request structure req to canonical format. */
b81306ccd14066cb7378f7f74bbf3843b5a88985Michael Grafflwres_result_t
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req,
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff lwres_lwpacket_t *pkt, lwres_buffer_t *b)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff unsigned char *buf;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff size_t buflen;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff int ret;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff size_t payload_length;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(ctx != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(req != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(pkt != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(b != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff payload_length = sizeof(lwres_uint16_t) + req->datalength;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff buflen = LWRES_LWPACKET_LENGTH + payload_length;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff buf = CTXMALLOC(buflen);
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff if (buf == NULL)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_NOMEMORY);
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews lwres_buffer_init(b, buf, (unsigned int)buflen);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews pkt->length = (lwres_uint32_t)buflen;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff pkt->version = LWRES_LWPACKETVERSION_0;
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff pkt->opcode = LWRES_OPCODE_NOOP;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff pkt->result = 0;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff pkt->authtype = 0;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff pkt->authlength = 0;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff ret = lwres_lwpacket_renderheader(b, pkt);
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff if (ret != LWRES_R_SUCCESS) {
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff lwres_buffer_invalidate(b);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff CTXFREE(buf, buflen);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff return (ret);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff }
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff INSIST(SPACE_OK(b, payload_length));
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff /*
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff * Put the length and the data. We know this will fit because we
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff * just checked for it.
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff lwres_buffer_putuint16(b, req->datalength);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff lwres_buffer_putmem(b, req->data, req->datalength);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_SUCCESS);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Converts a no-op response structure lwres_noopresponse_t to the lightweight resolver's canonical format. */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
b81306ccd14066cb7378f7f74bbf3843b5a88985Michael Grafflwres_result_t
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req,
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff lwres_lwpacket_t *pkt, lwres_buffer_t *b)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff unsigned char *buf;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff size_t buflen;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff int ret;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff size_t payload_length;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(ctx != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(req != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(pkt != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(b != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff payload_length = sizeof(lwres_uint16_t) + req->datalength;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff buflen = LWRES_LWPACKET_LENGTH + payload_length;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff buf = CTXMALLOC(buflen);
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff if (buf == NULL)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_NOMEMORY);
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews lwres_buffer_init(b, buf, (unsigned int)buflen);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews pkt->length = (lwres_uint32_t)buflen;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff pkt->version = LWRES_LWPACKETVERSION_0;
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff pkt->opcode = LWRES_OPCODE_NOOP;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff pkt->authtype = 0;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff pkt->authlength = 0;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff ret = lwres_lwpacket_renderheader(b, pkt);
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff if (ret != LWRES_R_SUCCESS) {
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff lwres_buffer_invalidate(b);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff CTXFREE(buf, buflen);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff return (ret);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff }
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff INSIST(SPACE_OK(b, payload_length));
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff /*
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff * Put the length and the data. We know this will fit because we
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff * just checked for it.
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff lwres_buffer_putuint16(b, req->datalength);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff lwres_buffer_putmem(b, req->data, req->datalength);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_SUCCESS);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Uses context ctx to convert the contents of packet pkt to a lwres_nooprequest_t structure. */
b81306ccd14066cb7378f7f74bbf3843b5a88985Michael Grafflwres_result_t
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff int ret;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff lwres_nooprequest_t *req;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(ctx != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(b != NULL);
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff REQUIRE(pkt != NULL);
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff REQUIRE(structp != NULL && *structp == NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_FAILURE);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff req = CTXMALLOC(sizeof(lwres_nooprequest_t));
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff if (req == NULL)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_NOMEMORY);
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff if (!SPACE_REMAINING(b, sizeof(lwres_uint16_t))) {
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff ret = LWRES_R_UNEXPECTEDEND;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff goto out;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff }
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff req->datalength = lwres_buffer_getuint16(b);
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff if (!SPACE_REMAINING(b, req->datalength)) {
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff ret = LWRES_R_UNEXPECTEDEND;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff goto out;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff }
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff req->data = b->base + b->current;
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff lwres_buffer_forward(b, req->datalength);
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff if (LWRES_BUFFER_REMAINING(b) != 0) {
031ce3bc62d273c5bd99596e01aa95c7ed33bbd7Brian Wellington ret = LWRES_R_TRAILINGDATA;
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff goto out;
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff }
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff /* success! */
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff *structp = req;
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_SUCCESS);
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff /* Error return */
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff out:
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff CTXFREE(req, sizeof(lwres_nooprequest_t));
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff return (ret);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Offers the same semantics as lwres_nooprequest_parse() except it yields a lwres_noopresponse_t structure. */
b81306ccd14066cb7378f7f74bbf3843b5a88985Michael Grafflwres_result_t
658db10162f779c8a5ed4e40c77111a7e18492beMichael Grafflwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff lwres_lwpacket_t *pkt, lwres_noopresponse_t **structp)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff int ret;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff lwres_noopresponse_t *req;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(ctx != NULL);
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff REQUIRE(b != NULL);
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff REQUIRE(pkt != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(structp != NULL && *structp == NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_FAILURE);
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff req = CTXMALLOC(sizeof(lwres_noopresponse_t));
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff if (req == NULL)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_NOMEMORY);
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff if (!SPACE_REMAINING(b, sizeof(lwres_uint16_t))) {
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff ret = LWRES_R_UNEXPECTEDEND;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff goto out;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff }
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff req->datalength = lwres_buffer_getuint16(b);
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff if (!SPACE_REMAINING(b, req->datalength)) {
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff ret = LWRES_R_UNEXPECTEDEND;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff goto out;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff }
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff req->data = b->base + b->current;
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff lwres_buffer_forward(b, req->datalength);
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff if (LWRES_BUFFER_REMAINING(b) != 0) {
031ce3bc62d273c5bd99596e01aa95c7ed33bbd7Brian Wellington ret = LWRES_R_TRAILINGDATA;
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff goto out;
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff }
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff /* success! */
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff *structp = req;
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_SUCCESS);
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff /* Error return */
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff out:
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff CTXFREE(req, sizeof(lwres_noopresponse_t));
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff return (ret);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Release the memory in resolver context ctx. */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graffvoid
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff lwres_noopresponse_t *noop;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(ctx != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(structp != NULL && *structp != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff noop = *structp;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff *structp = NULL;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff CTXFREE(noop, sizeof(lwres_noopresponse_t));
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Release the memory in resolver context ctx. */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graffvoid
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_nooprequest_free(lwres_context_t *ctx, lwres_nooprequest_t **structp)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff lwres_nooprequest_t *noop;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(ctx != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff REQUIRE(structp != NULL && *structp != NULL);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff noop = *structp;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff *structp = NULL;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff CTXFREE(noop, sizeof(lwres_nooprequest_t));
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}