lwres_noop.c revision c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840e
70e5a7403f0e0a3bd292b8287c5fed5772c15270Automatic Updater * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
499b34cea04a46823d003d4c0520c8b03e8513cbBrian Wellington * Copyright (C) 2000, 2001 Internet Software Consortium.
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.
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.
70e5a7403f0e0a3bd292b8287c5fed5772c15270Automatic Updater/* $Id: lwres_noop.c,v 1.19 2007/06/19 23:47:22 tbox Exp $ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * These are low-level routines for creating and parsing lightweight
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * resolver no-op request and response messages.
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 * 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 * These structures are defined in \link lwres.h <lwres/lwres.h.> \endlink They are shown below.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * #define LWRES_OPCODE_NOOP 0x00000000U
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * typedef struct {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_uint16_t datalength;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * unsigned char *data;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * } lwres_nooprequest_t;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * typedef struct {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * lwres_uint16_t datalength;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * unsigned char *data;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * } lwres_noopresponse_t;
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 * 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 * 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 * 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 * \section lwres_noop_return Return Values
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 * \section lwres_noop_see See Also
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Uses resolver context ctx to convert no-op request structure req to canonical format. */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req,
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff unsigned char *buf;
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff payload_length = sizeof(lwres_uint16_t) + req->datalength;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff buflen = LWRES_LWPACKET_LENGTH + payload_length;
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews lwres_buffer_init(b, buf, (unsigned int)buflen);
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff * Put the length and the data. We know this will fit because we
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff * just checked for it.
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff lwres_buffer_putmem(b, req->data, req->datalength);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Converts a no-op response structure lwres_noopresponse_t to the lightweight resolver's canonical format. */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req,
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff unsigned char *buf;
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff payload_length = sizeof(lwres_uint16_t) + req->datalength;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff buflen = LWRES_LWPACKET_LENGTH + payload_length;
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews lwres_buffer_init(b, buf, (unsigned int)buflen);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff * Put the length and the data. We know this will fit because we
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff * just checked for it.
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff lwres_buffer_putmem(b, req->data, req->datalength);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Uses context ctx to convert the contents of packet pkt to a lwres_nooprequest_t structure. */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp)
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff if (!SPACE_REMAINING(b, sizeof(lwres_uint16_t))) {
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff /* success! */
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff /* Error return */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Offers the same semantics as lwres_nooprequest_parse() except it yields a lwres_noopresponse_t structure. */
658db10162f779c8a5ed4e40c77111a7e18492beMichael Grafflwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff lwres_lwpacket_t *pkt, lwres_noopresponse_t **structp)
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff req = CTXMALLOC(sizeof(lwres_noopresponse_t));
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff if (!SPACE_REMAINING(b, sizeof(lwres_uint16_t))) {
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff /* success! */
658db10162f779c8a5ed4e40c77111a7e18492beMichael Graff /* Error return */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Release the memory in resolver context ctx. */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp)
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Release the memory in resolver context ctx. */