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