xref: /freebsd/contrib/ldns/ldns/edns.h (revision 5afab0e5)
1*5afab0e5SDag-Erling Smørgrav /*
2*5afab0e5SDag-Erling Smørgrav  * edns.h
3*5afab0e5SDag-Erling Smørgrav  *
4*5afab0e5SDag-Erling Smørgrav  *
5*5afab0e5SDag-Erling Smørgrav  * a Net::DNS like library for C
6*5afab0e5SDag-Erling Smørgrav  *
7*5afab0e5SDag-Erling Smørgrav  * (c) NLnet Labs, 2004-2022
8*5afab0e5SDag-Erling Smørgrav  *
9*5afab0e5SDag-Erling Smørgrav  * See the file LICENSE for the license
10*5afab0e5SDag-Erling Smørgrav  */
11*5afab0e5SDag-Erling Smørgrav 
12*5afab0e5SDag-Erling Smørgrav #ifndef LDNS_EDNS_H
13*5afab0e5SDag-Erling Smørgrav #define LDNS_EDNS_H
14*5afab0e5SDag-Erling Smørgrav 
15*5afab0e5SDag-Erling Smørgrav #include <ldns/common.h>
16*5afab0e5SDag-Erling Smørgrav 
17*5afab0e5SDag-Erling Smørgrav #ifdef __cplusplus
18*5afab0e5SDag-Erling Smørgrav extern "C" {
19*5afab0e5SDag-Erling Smørgrav #endif
20*5afab0e5SDag-Erling Smørgrav 
21*5afab0e5SDag-Erling Smørgrav 
22*5afab0e5SDag-Erling Smørgrav 
23*5afab0e5SDag-Erling Smørgrav /**
24*5afab0e5SDag-Erling Smørgrav  * EDNS option codes
25*5afab0e5SDag-Erling Smørgrav  */
26*5afab0e5SDag-Erling Smørgrav enum ldns_enum_edns_option
27*5afab0e5SDag-Erling Smørgrav {
28*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_LLQ = 1, /* RFC8764 */
29*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_UL = 2, /* http://files.dns-sd.org/draft-sekar-dns-ul.txt */
30*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_NSID = 3, /* RFC5001 */
31*5afab0e5SDag-Erling Smørgrav 	/* 4 draft-cheshire-edns0-owner-option */
32*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_DAU = 5, /* RFC6975 */
33*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_DHU = 6, /* RFC6975 */
34*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_N3U = 7, /* RFC6975 */
35*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
36*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_EXPIRE = 9, /* RFC7314 */
37*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_COOKIE = 10, /* RFC7873 */
38*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_KEEPALIVE = 11, /* RFC7828*/
39*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_PADDING = 12, /* RFC7830 */
40*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_CHAIN = 13, /* RFC7901 */
41*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_KEY_TAG = 14, /* RFC8145 */
42*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_EDE = 15, /* RFC8914 */
43*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_CLIENT_TAG = 16, /* draft-bellis-dnsop-edns-tags-01 */
44*5afab0e5SDag-Erling Smørgrav 	LDNS_EDNS_SERVER_TAG = 17 /* draft-bellis-dnsop-edns-tags-01 */
45*5afab0e5SDag-Erling Smørgrav };
46*5afab0e5SDag-Erling Smørgrav typedef enum ldns_enum_edns_option ldns_edns_option_code;
47*5afab0e5SDag-Erling Smørgrav 
48*5afab0e5SDag-Erling Smørgrav /**
49*5afab0e5SDag-Erling Smørgrav  * Extended DNS Error (RFC 8914) codes
50*5afab0e5SDag-Erling Smørgrav  */
51*5afab0e5SDag-Erling Smørgrav enum ldns_edns_enum_ede_code
52*5afab0e5SDag-Erling Smørgrav {
53*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_OTHER = 0,
54*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_UNSUPPORTED_DNSKEY_ALG = 1,
55*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_UNSUPPORTED_DS_DIGEST = 2,
56*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_STALE_ANSWER = 3,
57*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_FORGED_ANSWER = 4,
58*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_DNSSEC_INDETERMINATE = 5,
59*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_DNSSEC_BOGUS = 6,
60*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_SIGNATURE_EXPIRED = 7,
61*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_SIGNATURE_NOT_YET_VALID = 8,
62*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_DNSKEY_MISSING = 9,
63*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_RRSIGS_MISSING = 10,
64*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_NO_ZONE_KEY_BIT_SET = 11,
65*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_NSEC_MISSING = 12,
66*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_CACHED_ERROR = 13,
67*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_NOT_READY = 14,
68*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_BLOCKED = 15,
69*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_CENSORED = 16,
70*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_FILTERED = 17,
71*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_PROHIBITED = 18,
72*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_STALE_NXDOMAIN_ANSWER = 19,
73*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_NOT_AUTHORITATIVE = 20,
74*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_NOT_SUPPORTED = 21,
75*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
76*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_NETWORK_ERROR = 23,
77*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_INVALID_DATA = 24,
78*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID = 25,
79*5afab0e5SDag-Erling Smørgrav 	LDNS_EDE_TOO_EARLY = 26
80*5afab0e5SDag-Erling Smørgrav };
81*5afab0e5SDag-Erling Smørgrav typedef enum ldns_edns_enum_ede_code ldns_edns_ede_code;
82*5afab0e5SDag-Erling Smørgrav 
83*5afab0e5SDag-Erling Smørgrav /**
84*5afab0e5SDag-Erling Smørgrav  * The struct that stores an ordered EDNS option.
85*5afab0e5SDag-Erling Smørgrav  * An EDNS option is structed as follows:
86*5afab0e5SDag-Erling Smørgrav   +0 (MSB)                            +1 (LSB)
87*5afab0e5SDag-Erling Smørgrav      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
88*5afab0e5SDag-Erling Smørgrav   0: |                          OPTION-CODE                          |
89*5afab0e5SDag-Erling Smørgrav      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
90*5afab0e5SDag-Erling Smørgrav   2: |                         OPTION-LENGTH                         |
91*5afab0e5SDag-Erling Smørgrav      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
92*5afab0e5SDag-Erling Smørgrav   4: |                                                               |
93*5afab0e5SDag-Erling Smørgrav      /                          OPTION-DATA                          /
94*5afab0e5SDag-Erling Smørgrav      /                                                               /
95*5afab0e5SDag-Erling Smørgrav      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
96*5afab0e5SDag-Erling Smørgrav  */
97*5afab0e5SDag-Erling Smørgrav struct ldns_struct_edns_option {
98*5afab0e5SDag-Erling Smørgrav 	ldns_edns_option_code _code;
99*5afab0e5SDag-Erling Smørgrav 	size_t                _size;
100*5afab0e5SDag-Erling Smørgrav 	void                 *_data;
101*5afab0e5SDag-Erling Smørgrav };
102*5afab0e5SDag-Erling Smørgrav typedef struct ldns_struct_edns_option ldns_edns_option;
103*5afab0e5SDag-Erling Smørgrav 
104*5afab0e5SDag-Erling Smørgrav 
105*5afab0e5SDag-Erling Smørgrav /*
106*5afab0e5SDag-Erling Smørgrav  * Array structure to store multiple EDNS options
107*5afab0e5SDag-Erling Smørgrav  */
108*5afab0e5SDag-Erling Smørgrav struct ldns_struct_edns_option_list
109*5afab0e5SDag-Erling Smørgrav {
110*5afab0e5SDag-Erling Smørgrav 	size_t _option_count; /* the number of EDNS options in the list */
111*5afab0e5SDag-Erling Smørgrav    size_t _option_capacity; /* the amount of options that fit into the list */
112*5afab0e5SDag-Erling Smørgrav 	size_t _options_size; /* the total size of the options serialized */
113*5afab0e5SDag-Erling Smørgrav 	ldns_edns_option **_options;
114*5afab0e5SDag-Erling Smørgrav };
115*5afab0e5SDag-Erling Smørgrav typedef struct ldns_struct_edns_option_list ldns_edns_option_list;
116*5afab0e5SDag-Erling Smørgrav 
117*5afab0e5SDag-Erling Smørgrav /*
118*5afab0e5SDag-Erling Smørgrav  * Access functions
119*5afab0e5SDag-Erling Smørgrav  * do this as functions to get type checking
120*5afab0e5SDag-Erling Smørgrav  */
121*5afab0e5SDag-Erling Smørgrav 
122*5afab0e5SDag-Erling Smørgrav /**
123*5afab0e5SDag-Erling Smørgrav  * returns the size of the EDNS data.
124*5afab0e5SDag-Erling Smørgrav  * \param[in] *edns the EDNS struct to read from
125*5afab0e5SDag-Erling Smørgrav  * \return uint16_t with the size
126*5afab0e5SDag-Erling Smørgrav  */
127*5afab0e5SDag-Erling Smørgrav size_t ldns_edns_get_size(const ldns_edns_option *edns);
128*5afab0e5SDag-Erling Smørgrav 
129*5afab0e5SDag-Erling Smørgrav /**
130*5afab0e5SDag-Erling Smørgrav  * returns the option code of the EDNS data.
131*5afab0e5SDag-Erling Smørgrav  * \param[in] *edns the EDNS struct to read from
132*5afab0e5SDag-Erling Smørgrav  * \return uint16_t with the size
133*5afab0e5SDag-Erling Smørgrav  */
134*5afab0e5SDag-Erling Smørgrav ldns_edns_option_code ldns_edns_get_code(const ldns_edns_option *edns);
135*5afab0e5SDag-Erling Smørgrav 
136*5afab0e5SDag-Erling Smørgrav /**
137*5afab0e5SDag-Erling Smørgrav  * returns the EDNS option data.
138*5afab0e5SDag-Erling Smørgrav  * \param[in] *edns the EDNS option to read from
139*5afab0e5SDag-Erling Smørgrav  * \return uint8_t* pointer to the EDNS option's data
140*5afab0e5SDag-Erling Smørgrav  */
141*5afab0e5SDag-Erling Smørgrav uint8_t *ldns_edns_get_data(const ldns_edns_option *edns);
142*5afab0e5SDag-Erling Smørgrav 
143*5afab0e5SDag-Erling Smørgrav 
144*5afab0e5SDag-Erling Smørgrav /**
145*5afab0e5SDag-Erling Smørgrav  * serialise the EDNS option into wireformat.
146*5afab0e5SDag-Erling Smørgrav  * \param[in] *edns the EDNS option to read from
147*5afab0e5SDag-Erling Smørgrav  * \return ldns_buffer* the buffer containing the data
148*5afab0e5SDag-Erling Smørgrav  */
149*5afab0e5SDag-Erling Smørgrav ldns_buffer *ldns_edns_get_wireformat_buffer(const ldns_edns_option *edns);
150*5afab0e5SDag-Erling Smørgrav 
151*5afab0e5SDag-Erling Smørgrav /* Constructors and destructors*/
152*5afab0e5SDag-Erling Smørgrav 
153*5afab0e5SDag-Erling Smørgrav /**
154*5afab0e5SDag-Erling Smørgrav  * allocates a new EDNS structure and fills it. This function *DOES NOT* copy
155*5afab0e5SDag-Erling Smørgrav  * the contents from the data parameter.
156*5afab0e5SDag-Erling Smørgrav  * \param[in] code the EDNS code
157*5afab0e5SDag-Erling Smørgrav  * \param[in] size size of the buffer
158*5afab0e5SDag-Erling Smørgrav  * \param[in] data pointer to the buffer to be assigned
159*5afab0e5SDag-Erling Smørgrav  * \return the new EDNS structure or NULL on failure
160*5afab0e5SDag-Erling Smørgrav  */
161*5afab0e5SDag-Erling Smørgrav ldns_edns_option *ldns_edns_new(ldns_edns_option_code code, size_t size, void *data);
162*5afab0e5SDag-Erling Smørgrav 
163*5afab0e5SDag-Erling Smørgrav /**
164*5afab0e5SDag-Erling Smørgrav  * allocates a new EDNS structure and fills it. This function *DOES* copy
165*5afab0e5SDag-Erling Smørgrav  * the contents from the data parameter.
166*5afab0e5SDag-Erling Smørgrav  * \param[in] code the EDNS code
167*5afab0e5SDag-Erling Smørgrav  * \param[in] size size of the buffer
168*5afab0e5SDag-Erling Smørgrav  * \param[in] data pointer to the buffer to be assigned
169*5afab0e5SDag-Erling Smørgrav  * \return the new EDNS structure or NULL on failure
170*5afab0e5SDag-Erling Smørgrav  */
171*5afab0e5SDag-Erling Smørgrav ldns_edns_option *ldns_edns_new_from_data(ldns_edns_option_code code, size_t size, const void *data);
172*5afab0e5SDag-Erling Smørgrav 
173*5afab0e5SDag-Erling Smørgrav /**
174*5afab0e5SDag-Erling Smørgrav  * clone an EDNS option
175*5afab0e5SDag-Erling Smørgrav  * \param[in] edns the EDNS option
176*5afab0e5SDag-Erling Smørgrav  * \return the new EDNS structure
177*5afab0e5SDag-Erling Smørgrav  */
178*5afab0e5SDag-Erling Smørgrav ldns_edns_option *ldns_edns_clone(ldns_edns_option *edns);
179*5afab0e5SDag-Erling Smørgrav 
180*5afab0e5SDag-Erling Smørgrav /**
181*5afab0e5SDag-Erling Smørgrav  * free the EDNS option. Use deep_free if the _data member is allocated.
182*5afab0e5SDag-Erling Smørgrav  * \param[in] edns the EDNS option to free
183*5afab0e5SDag-Erling Smørgrav  */
184*5afab0e5SDag-Erling Smørgrav void ldns_edns_deep_free(ldns_edns_option *edns);
185*5afab0e5SDag-Erling Smørgrav void ldns_edns_free(ldns_edns_option *edns);
186*5afab0e5SDag-Erling Smørgrav 
187*5afab0e5SDag-Erling Smørgrav /**
188*5afab0e5SDag-Erling Smørgrav  * allocates space for a new list of EDNS options
189*5afab0e5SDag-Erling Smørgrav  * \return the new EDNS option list or NULL on failure
190*5afab0e5SDag-Erling Smørgrav  */
191*5afab0e5SDag-Erling Smørgrav ldns_edns_option_list* ldns_edns_option_list_new(void);
192*5afab0e5SDag-Erling Smørgrav 
193*5afab0e5SDag-Erling Smørgrav /**
194*5afab0e5SDag-Erling Smørgrav  * clone the EDNS options list and it's contents
195*5afab0e5SDag-Erling Smørgrav  * \param[in] options_list  the EDNS options_list to read from
196*5afab0e5SDag-Erling Smørgrav  * \return the new EDNS option list
197*5afab0e5SDag-Erling Smørgrav  */
198*5afab0e5SDag-Erling Smørgrav ldns_edns_option_list *ldns_edns_option_list_clone(ldns_edns_option_list *options_list);
199*5afab0e5SDag-Erling Smørgrav 
200*5afab0e5SDag-Erling Smørgrav /**
201*5afab0e5SDag-Erling Smørgrav  * free the EDNS option list. Use deep_free to free the options options
202*5afab0e5SDag-Erling Smørgrav  * in the list as well.
203*5afab0e5SDag-Erling Smørgrav  * \param[in] options_list the EDNS option to free
204*5afab0e5SDag-Erling Smørgrav  */
205*5afab0e5SDag-Erling Smørgrav void ldns_edns_option_list_free(ldns_edns_option_list *options_list);
206*5afab0e5SDag-Erling Smørgrav void ldns_edns_option_list_deep_free(ldns_edns_option_list *options_list);
207*5afab0e5SDag-Erling Smørgrav 
208*5afab0e5SDag-Erling Smørgrav /* edns_option_list functions */
209*5afab0e5SDag-Erling Smørgrav 
210*5afab0e5SDag-Erling Smørgrav /**
211*5afab0e5SDag-Erling Smørgrav  * returns the number of options in the EDNS options list.
212*5afab0e5SDag-Erling Smørgrav  * \param[in] options_list  the EDNS options_list to read from
213*5afab0e5SDag-Erling Smørgrav  * \return the number of EDNS options
214*5afab0e5SDag-Erling Smørgrav  */
215*5afab0e5SDag-Erling Smørgrav size_t ldns_edns_option_list_get_count(const ldns_edns_option_list *options_list);
216*5afab0e5SDag-Erling Smørgrav 
217*5afab0e5SDag-Erling Smørgrav /**
218*5afab0e5SDag-Erling Smørgrav  * returns the EDNS option as the specified index in the list of EDNS options.
219*5afab0e5SDag-Erling Smørgrav  * \param[in] options_list  the EDNS options_list to read from
220*5afab0e5SDag-Erling Smørgrav  * \param[in] index         the location of the EDNS option to get in the list
221*5afab0e5SDag-Erling Smørgrav  * \return the EDNS option located at the index or NULL on failure
222*5afab0e5SDag-Erling Smørgrav  */
223*5afab0e5SDag-Erling Smørgrav ldns_edns_option* ldns_edns_option_list_get_option(const ldns_edns_option_list *options_list,
224*5afab0e5SDag-Erling Smørgrav 	size_t index);
225*5afab0e5SDag-Erling Smørgrav 
226*5afab0e5SDag-Erling Smørgrav 
227*5afab0e5SDag-Erling Smørgrav /**
228*5afab0e5SDag-Erling Smørgrav  * returns the total size of all the individual EDNS options in the EDNS list.
229*5afab0e5SDag-Erling Smørgrav  * \param[in] options_list  the EDNS options_list to read from
230*5afab0e5SDag-Erling Smørgrav  * \return the total size of the options combined
231*5afab0e5SDag-Erling Smørgrav  */
232*5afab0e5SDag-Erling Smørgrav size_t ldns_edns_option_list_get_options_size(const ldns_edns_option_list *options_list);
233*5afab0e5SDag-Erling Smørgrav 
234*5afab0e5SDag-Erling Smørgrav /**
235*5afab0e5SDag-Erling Smørgrav  * adds an EDNS option to the list of options at the specified index. Also
236*5afab0e5SDag-Erling Smørgrav  * returns the option that was previously at that index.
237*5afab0e5SDag-Erling Smørgrav  * \param[in] options_list  the EDNS options_list to add to
238*5afab0e5SDag-Erling Smørgrav  * \param[in] option        the EDNS option to add to the list
239*5afab0e5SDag-Erling Smørgrav  * \param[in] index         the index in the list where to set the option
240*5afab0e5SDag-Erling Smørgrav  * \return the EDNS option previously located at the index
241*5afab0e5SDag-Erling Smørgrav  */
242*5afab0e5SDag-Erling Smørgrav ldns_edns_option *ldns_edns_option_list_set_option(ldns_edns_option_list *options_list,
243*5afab0e5SDag-Erling Smørgrav 	ldns_edns_option *option, size_t index);
244*5afab0e5SDag-Erling Smørgrav 
245*5afab0e5SDag-Erling Smørgrav /**
246*5afab0e5SDag-Erling Smørgrav  * adds an EDNS option at the end of the list of options.
247*5afab0e5SDag-Erling Smørgrav  * \param[in] options_list  the EDNS options_list to add to
248*5afab0e5SDag-Erling Smørgrav  * \param[in] option        the (non-NULL) EDNS option to add to the list
249*5afab0e5SDag-Erling Smørgrav  * \return true on success and false of failure
250*5afab0e5SDag-Erling Smørgrav  */
251*5afab0e5SDag-Erling Smørgrav bool ldns_edns_option_list_push(ldns_edns_option_list *options_list,
252*5afab0e5SDag-Erling Smørgrav 	ldns_edns_option *option);
253*5afab0e5SDag-Erling Smørgrav 
254*5afab0e5SDag-Erling Smørgrav /**
255*5afab0e5SDag-Erling Smørgrav  * removes and returns the EDNS option at the end of the list of options.
256*5afab0e5SDag-Erling Smørgrav  * \param[in] options_list  the EDNS options_list to add to
257*5afab0e5SDag-Erling Smørgrav  * \return the EDNS option at the end of the list, or NULL on failure
258*5afab0e5SDag-Erling Smørgrav  */
259*5afab0e5SDag-Erling Smørgrav ldns_edns_option* ldns_edns_option_list_pop(ldns_edns_option_list *options_list);
260*5afab0e5SDag-Erling Smørgrav 
261*5afab0e5SDag-Erling Smørgrav /**
262*5afab0e5SDag-Erling Smørgrav  * serializes all the EDNS options into a single wireformat buffer
263*5afab0e5SDag-Erling Smørgrav  * \param[in] option_list  the EDNS options_list to combine into one wireformat
264*5afab0e5SDag-Erling Smørgrav  * \return the filled buffer or NULL on failure
265*5afab0e5SDag-Erling Smørgrav  */
266*5afab0e5SDag-Erling Smørgrav ldns_buffer *ldns_edns_option_list2wireformat_buffer(const ldns_edns_option_list *option_list);
267*5afab0e5SDag-Erling Smørgrav 
268*5afab0e5SDag-Erling Smørgrav #ifdef __cplusplus
269*5afab0e5SDag-Erling Smørgrav }
270*5afab0e5SDag-Erling Smørgrav #endif
271*5afab0e5SDag-Erling Smørgrav 
272*5afab0e5SDag-Erling Smørgrav #endif /* LDNS_EDNS_H */
273