rplan.h 5.74 KB
Newer Older
Marek Vavruša's avatar
Marek Vavruša committed
1
/*  Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2

Marek Vavruša's avatar
Marek Vavruša committed
3 4 5 6
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
7

Marek Vavruša's avatar
Marek Vavruša committed
8 9 10 11
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
12

Marek Vavruša's avatar
Marek Vavruša committed
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/>.
Marek Vavruša's avatar
Marek Vavruša committed
15
 */
16 17 18

#pragma once

Marek Vavruša's avatar
Marek Vavruša committed
19
#include <sys/time.h>
20
#include <libknot/dname.h>
21
#include <libknot/codes.h>
22

23
#include "lib/cache.h"
Marek Vavruša's avatar
Marek Vavruša committed
24
#include "lib/zonecut.h"
25
#include "lib/nsrep.h"
26

27
#define QUERY_FLAGS(X) \
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
	X(NO_MINIMIZE,     1 << 0) /**< Don't minimize QNAME. */ \
	X(NO_THROTTLE,     1 << 1) /**< No query/slow NS throttling. */ \
	X(NO_IPV6,         1 << 2) /**< Disable IPv6 */ \
	X(NO_IPV4,         1 << 3) /**< Disable IPv4 */ \
	X(TCP,             1 << 4) /**< Use TCP for this query. */ \
	X(RESOLVED,        1 << 5) /**< Query is resolved. */ \
	X(AWAIT_IPV4,      1 << 6) /**< Query is waiting for A address. */ \
	X(AWAIT_IPV6,      1 << 7) /**< Query is waiting for AAAA address. */ \
	X(AWAIT_CUT,       1 << 8) /**< Query is waiting for zone cut lookup */ \
	X(SAFEMODE,        1 << 9) /**< Don't use fancy stuff (EDNS...) */ \
	X(CACHED,          1 << 10) /**< Query response is cached. */ \
	X(NO_CACHE,        1 << 11) /**< Do not use expiring cache for lookup. */ \
	X(EXPIRING,        1 << 12) /**< Query response is cached, but expiring. */ \
	X(ALLOW_LOCAL,     1 << 13) /**< Allow queries to local or private address ranges. */ \
	X(DNSSEC_WANT,     1 << 14) /**< Want DNSSEC secured answer. */ \
	X(DNSSEC_BOGUS,    1 << 15) /**< Query response is DNSSEC bogus. */ \
	X(DNSSEC_INSECURE, 1 << 16) /**< Query response is DNSSEC insecure. */ \
45
	X(STUB,            1 << 17) /**< Stub resolution, accept received answer as solved. */ \
46
	X(ALWAYS_CUT,      1 << 18) /**< Always recover zone cut (even if cached). */ \
47
	X(DNSSEC_WEXPAND,  1 << 19) /**< Query response has wildcard expansion. */ \
48
	X(PERMISSIVE,      1 << 20) /**< Permissive resolver mode. */ \
49 50
	X(STRICT,          1 << 21) /**< Strict resolver mode. */ \
	X(BADCOOKIE_AGAIN, 1 << 22) /**< Query again because bad cookie returned. */
51

Marek Vavruša's avatar
Marek Vavruša committed
52
/** Query flags */
53
enum kr_query_flag {
54 55 56
	#define X(flag, val) QUERY_ ## flag = val,
	QUERY_FLAGS(X)
	#undef X
57 58
};

59
/** Query flag names table */
60
KR_EXPORT KR_CONST
61
const knot_lookup_t *kr_query_flag_names(void);
62

Marek Vavruša's avatar
Marek Vavruša committed
63 64
/**
 * Single query representation.
Marek Vavruša's avatar
Marek Vavruša committed
65
 */
66
struct kr_query {
67
	struct kr_query *parent;
68 69 70
	knot_dname_t *sname;
	uint16_t stype;
	uint16_t sclass;
Marek Vavruša's avatar
Marek Vavruša committed
71
	uint16_t id;
72
	uint32_t flags;
Marek Vavruša's avatar
Marek Vavruša committed
73
	uint32_t secret;
74
	uint16_t fails;
75 76
	struct timeval timestamp;
	struct kr_zonecut zone_cut;
77
	struct kr_nsrep ns;
78
	struct kr_layer_pickle *deferred;
79 80
};

81
/** @cond internal Array of queries. */
82
typedef array_t(struct kr_query *) kr_qarray_t;
83
/* @endcond */
84

Marek Vavruša's avatar
Marek Vavruša committed
85 86
/**
 * Query resolution plan structure.
Marek Vavruša's avatar
Marek Vavruša committed
87 88 89 90 91
 *
 * The structure most importantly holds the original query, answer and the
 * list of pending queries required to resolve the original query.
 * It also keeps a notion of current zone cut.
 */
92
struct kr_rplan {
93 94 95 96
	kr_qarray_t pending;        /**< List of pending queries. */
	kr_qarray_t resolved;       /**< List of resolved queries. */
	struct kr_request *request; /**< Parent resolution request. */
	knot_mm_t *pool;             /**< Temporary memory pool. */
97 98
};

Marek Vavruša's avatar
Marek Vavruša committed
99 100 101
/**
 * Initialize resolution plan (empty).
 * @param rplan plan instance
102
 * @param request resolution request
Marek Vavruša's avatar
Marek Vavruša committed
103
 * @param pool ephemeral memory pool for whole resolution
Marek Vavruša's avatar
Marek Vavruša committed
104
 */
105
KR_EXPORT
106
int kr_rplan_init(struct kr_rplan *rplan, struct kr_request *request, knot_mm_t *pool);
Marek Vavruša's avatar
Marek Vavruša committed
107

Marek Vavruša's avatar
Marek Vavruša committed
108 109 110
/**
 * Deinitialize resolution plan, aborting any uncommited transactions.
 * @param rplan plan instance
Marek Vavruša's avatar
Marek Vavruša committed
111
 */
112
KR_EXPORT
Marek Vavruša's avatar
Marek Vavruša committed
113 114
void kr_rplan_deinit(struct kr_rplan *rplan);

Marek Vavruša's avatar
Marek Vavruša committed
115 116 117
/**
 * Return true if the resolution plan is empty (i.e. finished or initialized)
 * @param rplan plan instance
118
 * @return true or false
Marek Vavruša's avatar
Marek Vavruša committed
119
 */
120
KR_EXPORT KR_PURE
Marek Vavruša's avatar
Marek Vavruša committed
121 122
bool kr_rplan_empty(struct kr_rplan *rplan);

123 124 125 126 127 128 129 130 131 132 133
/**
 * Push empty query to the top of the resolution plan.
 * @note This query serves as a cookie query only.
 * @param rplan plan instance
 * @param parent query parent (or NULL)
 * @return query instance or NULL
 */
KR_EXPORT
struct kr_query *kr_rplan_push_empty(struct kr_rplan *rplan,
                                     struct kr_query *parent);

Marek Vavruša's avatar
Marek Vavruša committed
134 135 136 137 138 139 140 141
/**
 * Push a query to the top of the resolution plan.
 * @note This means that this query takes precedence before all pending queries.
 * @param rplan plan instance
 * @param parent query parent (or NULL)
 * @param name resolved name
 * @param cls  resolved class
 * @param type resolved type
142
 * @return query instance or NULL
Marek Vavruša's avatar
Marek Vavruša committed
143
 */
144
KR_EXPORT
145 146
struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent,
                               const knot_dname_t *name, uint16_t cls, uint16_t type);
Marek Vavruša's avatar
Marek Vavruša committed
147

Marek Vavruša's avatar
Marek Vavruša committed
148 149 150 151 152
/**
 * Pop existing query from the resolution plan.
 * @note Popped queries are not discarded, but moved to the resolved list.
 * @param rplan plan instance
 * @param qry resolved query
153
 * @return 0 or an error
Marek Vavruša's avatar
Marek Vavruša committed
154
 */
155
KR_EXPORT
156 157
int kr_rplan_pop(struct kr_rplan *rplan, struct kr_query *qry);

Marek Vavruša's avatar
Marek Vavruša committed
158 159
/**
 * Return true if resolution chain satisfies given query.
160
 */
161
KR_EXPORT KR_PURE
162 163 164
bool kr_rplan_satisfies(struct kr_query *closure, const knot_dname_t *name, uint16_t cls, uint16_t type);

/** Return last resolved query. */
165
KR_EXPORT KR_PURE
166 167 168
struct kr_query *kr_rplan_resolved(struct kr_rplan *rplan);

/** Return query predecessor. */
169
KR_EXPORT KR_PURE
170
struct kr_query *kr_rplan_next(struct kr_query *qry);