Attachment 'resolve.h'

Download

   1 /*  Copyright (C) 2014-2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
   2 
   3     This program is free software: you can redistribute it and/or modify
   4     it under the terms of the GNU General Public License as published by
   5     the Free Software Foundation, either version 3 of the License, or
   6     (at your option) any later version.
   7 
   8     This program is distributed in the hope that it will be useful,
   9     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11     GNU General Public License for more details.
  12 
  13     You should have received a copy of the GNU General Public License
  14     along with this program.  If not, see <https://www.gnu.org/licenses/>.
  15  */
  16 
  17 #pragma once
  18 
  19 #include <netinet/in.h>
  20 #include <sys/socket.h>
  21 #include <libknot/packet/pkt.h>
  22 
  23 #include "lib/cookies/control.h"
  24 #include "lib/cookies/lru_cache.h"
  25 #include "lib/layer.h"
  26 #include "lib/generic/map.h"
  27 #include "lib/generic/array.h"
  28 #include "lib/nsrep.h"
  29 #include "lib/rplan.h"
  30 #include "lib/module.h"
  31 #include "lib/cache.h"
  32 
  33 /**
  34  * @file resolve.h
  35  * @brief The API provides an API providing a "consumer-producer"-like interface to enable
  36  * user to plug it into existing event loop or I/O code.
  37  *
  38  * # Example usage of the iterative API:
  39  *
  40  * @code{.c}
  41  *
  42  * // Create request and its memory pool
  43  * struct kr_request req = {
  44  * 	.pool = {
  45  * 		.ctx = mp_new (4096),
  46  * 		.alloc = (mm_alloc_t) mp_alloc
  47  * 	}
  48  * };
  49  *
  50  * // Setup and provide input query
  51  * int state = kr_resolve_begin(&req, ctx, final_answer);
  52  * state = kr_resolve_consume(&req, query);
  53  *
  54  * // Generate answer
  55  * while (state == KR_STATE_PRODUCE) {
  56  *
  57  *     // Additional query generate, do the I/O and pass back answer
  58  *     state = kr_resolve_produce(&req, &addr, &type, query);
  59  *     while (state == KR_STATE_CONSUME) {
  60  *         int ret = sendrecv(addr, proto, query, resp);
  61  *
  62  *         // If I/O fails, make "resp" empty
  63  *         state = kr_resolve_consume(&request, addr, resp);
  64  *         knot_pkt_clear(resp);
  65  *     }
  66  *     knot_pkt_clear(query);
  67  * }
  68  *
  69  * // "state" is either DONE or FAIL
  70  * kr_resolve_finish(&request, state);
  71  *
  72  * @endcode
  73  */
  74 
  75 /** Validation rank */
  76 typedef enum kr_validation_rank {
  77 	KR_VLDRANK_INITIAL   = 0,   /* Entry was just added; not validated yet. */
  78 	KR_VLDRANK_INSECURE  = 1,   /* Entry is DNSSEC insecure (e.g. RRSIG not exists). */
  79 	KR_VLDRANK_BAD	     = 2,   /* Matching RRSIG found, but validation fails. */
  80 	KR_VLDRANK_MISMATCH  = 3,   /* RRSIG signer name is */
  81 	KR_VLDRANK_UNKNOWN   = 4,   /* Unknown */
  82 	KR_VLDRANK_SECURE    = 5    /* Entry is DNSSEC valid (e.g. RRSIG exists). */
  83 } kr_validation_rank_t;
  84 
  85 /** @cond internal Array of modules. */
  86 typedef array_t(struct kr_module *) module_array_t;
  87 /* @endcond */
  88 
  89 /**
  90  * Name resolution context.
  91  *
  92  * Resolution context provides basic services like cache, configuration and options.
  93  *
  94  * @note This structure is persistent between name resolutions and may
  95  *       be shared between threads.
  96  */
  97 struct kr_context
  98 {	
  99 	uint32_t options;
 100 	knot_rrset_t *opt_rr;
 101 	map_t trust_anchors;
 102 	map_t negative_anchors;
 103 	struct kr_zonecut root_hints;
 104 	struct kr_cache cache;
 105 	kr_nsrep_lru_t *cache_rtt;
 106 	kr_nsrep_lru_t *cache_rep;
 107 	module_array_t *modules;
 108 	/* The cookie context structure should not be held within the cookies
 109 	 * module because of better access. */
 110 	struct kr_cookie_ctx cookie_ctx;
 111 	kr_cookie_lru_t *cache_cookie;
 112 	uint32_t tls_padding; /**< See net.tls_padding in ../daemon/README.rst */
 113 	knot_mm_t *pool;
 114 };
 115 
 116 /**
 117  * Name resolution request.
 118  *
 119  * Keeps information about current query processing between calls to
 120  * processing APIs, i.e. current resolved query, resolution plan, ...
 121  * Use this instead of the simple interface if you want to implement
 122  * multiplexing or custom I/O.
 123  *
 124  * @note All data for this request must be allocated from the given pool.
 125  */
 126 struct kr_request {
 127 	struct kr_context *ctx;
 128 	knot_pkt_t *answer;
 129 	struct kr_query *current_query;    /**< Current evaluated query. */
 130 	struct {
 131 		const knot_rrset_t *key;
 132 		const struct sockaddr *addr;
 133 		const struct sockaddr *dst_addr;
 134 		const knot_pkt_t *packet;
 135 		const knot_rrset_t *opt;
 136 		bool tcp; /**< true if the request is on tcp; only meaningful if (dst_addr) */
 137 	} qsource;
 138 	struct {
 139 		unsigned rtt;                  /**< Current upstream RTT */
 140 		const struct sockaddr *addr;   /**< Current upstream address */
 141 	} upstream;                        /**< Upstream information, valid only in consume() phase */
 142 	uint32_t options;
 143 	int state;
 144 	ranked_rr_array_t answ_selected;
 145 	ranked_rr_array_t auth_selected;
 146 	rr_array_t additional;
 147 	bool answ_validated;
 148 	bool auth_validated;
 149 	struct kr_rplan rplan;
 150 	int has_tls;
 151 	knot_mm_t pool;
 152 };
 153 
 154 /**
 155  * Begin name resolution.
 156  *
 157  * @note Expects a request to have an initialized mempool, the "answer" packet will
 158  *       be kept during the resolution and will contain the final answer at the end.
 159  *
 160  * @param request request state with initialized mempool
 161  * @param ctx     resolution context
 162  * @param answer  allocated packet for final answer
 163  * @return        CONSUME (expecting query)
 164  */
 165 KR_EXPORT
 166 int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pkt_t *answer);
 167 
 168 /**
 169  * Consume input packet (may be either first query or answer to query originated from kr_resolve_produce())
 170  *
 171  * @note If the I/O fails, provide an empty or NULL packet, this will make iterator recognize nameserver failure.
 172  * 
 173  * @param  request request state (awaiting input)
 174  * @param  src     [in] packet source address
 175  * @param  packet  [in] input packet
 176  * @return         any state
 177  */
 178 KR_EXPORT
 179 int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, knot_pkt_t *packet);
 180 
 181 /**
 182  * Produce either next additional query or finish.
 183  *
 184  * If the CONSUME is returned then dst, type and packet will be filled with
 185  * appropriate values and caller is responsible to send them and receive answer.
 186  * If it returns any other state, then content of the variables is undefined.
 187  * 
 188  * @param  request request state (in PRODUCE state)
 189  * @param  dst     [out] possible address of the next nameserver
 190  * @param  type    [out] possible used socket type (SOCK_STREAM, SOCK_DGRAM)
 191  * @param  packet  [out] packet to be filled with additional query
 192  * @return         any state
 193  */
 194 KR_EXPORT
 195 int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *type, knot_pkt_t *packet);
 196 
 197 /**
 198  * Finalises the outbound query packet with the knowledge of the IP addresses.
 199  *
 200  * @note The function must be called before actual sending of the request packet.
 201  *
 202  * @param  request request state (in PRODUCE state)
 203  * @param  src     address from which the query is going to be sent
 204  * @param  dst     address of the name server
 205  * @param  type    used socket type (SOCK_STREAM, SOCK_DGRAM)
 206  * @param  packet  [in,out] query packet to be finalised
 207  * @return         kr_ok() or error code
 208  */
 209 KR_EXPORT
 210 int kr_resolve_checkout(struct kr_request *request, struct sockaddr *src,
 211                         struct sockaddr *dst, int type, knot_pkt_t *packet);
 212 
 213 /**
 214  * Finish resolution and commit results if the state is DONE.
 215  *
 216  * @note The structures will be deinitialized, but the assigned memory pool is not going to
 217  *       be destroyed, as it's owned by caller.
 218  *
 219  * @param  request request state
 220  * @param  state   either DONE or FAIL state
 221  * @return         DONE
 222  */
 223 KR_EXPORT
 224 int kr_resolve_finish(struct kr_request *request, int state);
 225 
 226 /**
 227  * Return resolution plan.
 228  * @param  request request state
 229  * @return         pointer to rplan
 230  */
 231 KR_EXPORT KR_PURE
 232 struct kr_rplan *kr_resolve_plan(struct kr_request *request);
 233 
 234 /**
 235  * Return memory pool associated with request.
 236  * @param  request request state
 237  * @return         mempool
 238  */
 239 KR_EXPORT KR_PURE
 240 knot_mm_t *kr_resolve_pool(struct kr_request *request);

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2020-08-12 06:11:28, 41.7 KB) [[attachment:resolve.c]]
  • [get | view] (2020-08-12 06:11:28, 7.7 KB) [[attachment:resolve.h]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.