]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/unbound/util/data/dname.h
Upgrade Unbound to 1.6.2. More to follow.
[FreeBSD/FreeBSD.git] / contrib / unbound / util / data / dname.h
1 /*
2  * util/data/dname.h - domain name routines
3  *
4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * 
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  * 
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  * 
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 /**
37  * \file
38  *
39  * This file contains functions to deal with domain names (dnames).
40  *
41  * Some of the functions deal with domain names as a wireformat buffer,
42  * with a length.
43  */
44
45 #ifndef UTIL_DATA_DNAME_H
46 #define UTIL_DATA_DNAME_H
47 #include "util/storage/lruhash.h"
48 struct sldns_buffer;
49
50 /** max number of compression ptrs to follow */
51 #define MAX_COMPRESS_PTRS 256
52
53 /** 
54  * Determine length of dname in buffer, no compression ptrs allowed, 
55  * @param query: the ldns buffer, current position at start of dname.
56  *      at end, position is at end of the dname.
57  * @return: 0 on parse failure, or length including ending 0 of dname. 
58  */
59 size_t query_dname_len(struct sldns_buffer* query);
60
61 /**
62  * Determine if dname in memory is correct. no compression ptrs allowed.
63  * @param dname: where dname starts in memory.
64  * @param len: dname is not allowed to exceed this length (i.e. of allocation).
65  * @return length of dname if dname is ok, 0 on a parse error.
66  */
67 size_t dname_valid(uint8_t* dname, size_t len);
68
69 /** lowercase query dname */
70 void query_dname_tolower(uint8_t* dname);
71
72 /** 
73  * lowercase pkt dname (follows compression pointers)
74  * @param pkt: the packet, used to follow compression pointers. Position 
75  *      is unchanged.
76  * @param dname: start of dname in packet.
77  */
78 void pkt_dname_tolower(struct sldns_buffer* pkt, uint8_t* dname);
79
80 /**
81  * Compare query dnames (uncompressed storage). The Dnames passed do not
82  * have to be lowercased, comparison routine does this.
83  *
84  * This routine is special, in that the comparison that it does corresponds
85  * with the canonical comparison needed when comparing dnames inside rdata
86  * for RR types that need canonicalization. That means that the first byte
87  * that is smaller (possibly after lowercasing) makes an RR smaller, or the
88  * shortest name makes an RR smaller.
89  *
90  * This routine does not compute the canonical order needed for NSEC 
91  * processing.
92  *
93  * Dnames have to be valid format.
94  * @param d1: dname to compare
95  * @param d2: dname to compare
96  * @return: -1, 0, or +1 depending on comparison results.
97  *      Sort order is first difference found. not the canonical ordering.
98  */
99 int query_dname_compare(uint8_t* d1, uint8_t* d2);
100
101 /**
102  * Determine correct, compressed, dname present in packet.
103  * Checks for parse errors.
104  * @param pkt: packet to read from (from current start position).
105  * @return: 0 on parse error.
106  *      At exit the position is right after the (compressed) dname.
107  *      Compression pointers are followed and checked for loops.
108  *      The uncompressed wireformat length is returned.
109  */
110 size_t pkt_dname_len(struct sldns_buffer* pkt);
111
112 /**
113  * Compare dnames in packet (compressed). Dnames must be valid.
114  * routine performs lowercasing, so the packet casing is preserved.
115  * @param pkt: packet, used to resolve compression pointers.
116  * @param d1: dname to compare
117  * @param d2: dname to compare
118  * @return: -1, 0, or +1 depending on comparison results.
119  *      Sort order is first difference found. not the canonical ordering.
120  */
121 int dname_pkt_compare(struct sldns_buffer* pkt, uint8_t* d1, uint8_t* d2);
122
123 /**
124  * Hash dname, label by label, lowercasing, into hashvalue.
125  * Dname in query format (not compressed).
126  * @param dname: dname to hash.
127  * @param h: initial hash value.
128  * @return: result hash value.
129  */
130 hashvalue_type dname_query_hash(uint8_t* dname, hashvalue_type h);
131
132 /**
133  * Hash dname, label by label, lowercasing, into hashvalue.
134  * Dname in pkt format (compressed).
135  * @param pkt: packet, for resolving compression pointers.
136  * @param dname: dname to hash, pointer to the pkt buffer.
137  *      Must be valid format. No loops, etc.
138  * @param h: initial hash value.
139  * @return: result hash value.
140  *      Result is the same as dname_query_hash, even if compression is used.
141  */
142 hashvalue_type dname_pkt_hash(struct sldns_buffer* pkt, uint8_t* dname,
143         hashvalue_type h);
144
145 /**
146  * Copy over a valid dname and decompress it.
147  * @param pkt: packet to resolve compression pointers.
148  * @param to: buffer of size from pkt_len function to hold result.
149  * @param dname: pointer into packet where dname starts.
150  */
151 void dname_pkt_copy(struct sldns_buffer* pkt, uint8_t* to, uint8_t* dname);
152
153 /**
154  * Copy over a valid dname to a packet.
155  * @param pkt: packet to copy to.
156  * @param dname: dname to copy.
157  * @return: 0 if not enough space in buffer.
158  */
159 int dname_buffer_write(struct sldns_buffer* pkt, uint8_t* dname);
160
161 /**
162  * Count the number of labels in an uncompressed dname in memory.
163  * @param dname: pointer to uncompressed dname.
164  * @return: count of labels, including root label, "com." has 2 labels.
165  */
166 int dname_count_labels(uint8_t* dname);
167
168 /**
169  * Count labels and dname length both, for uncompressed dname in memory.
170  * @param dname: pointer to uncompressed dname.
171  * @param size: length of dname, including root label.
172  * @return: count of labels, including root label, "com." has 2 labels.
173  */
174 int dname_count_size_labels(uint8_t* dname, size_t* size);
175
176 /**
177  * Compare dnames, sorted not canonical, but by label.
178  * Such that zone contents follows zone apex.
179  * @param d1: first dname. pointer to uncompressed wireformat.
180  * @param labs1: number of labels in first dname.
181  * @param d2: second dname. pointer to uncompressed wireformat.
182  * @param labs2: number of labels in second dname.
183  * @param mlabs: number of labels that matched exactly (the shared topdomain).
184  * @return: 0 for equal, -1 smaller, or +1 d1 larger than d2.
185  */
186 int dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs);
187
188 /**
189  * See if domain name d1 is a strict subdomain of d2.
190  * That is a subdomain, but not equal. 
191  * @param d1: domain name, uncompressed wireformat
192  * @param labs1: number of labels in d1, including root label.
193  * @param d2: domain name, uncompressed wireformat
194  * @param labs2: number of labels in d2, including root label.
195  * @return true if d1 is a subdomain of d2, but not equal to d2.
196  */
197 int dname_strict_subdomain(uint8_t* d1, int labs1, uint8_t* d2, int labs2);
198
199 /**
200  * Like dname_strict_subdomain but counts labels 
201  * @param d1: domain name, uncompressed wireformat
202  * @param d2: domain name, uncompressed wireformat
203  * @return true if d1 is a subdomain of d2, but not equal to d2.
204  */
205 int dname_strict_subdomain_c(uint8_t* d1, uint8_t* d2);
206
207 /**
208  * Counts labels. Tests is d1 is a subdomain of d2.
209  * @param d1: domain name, uncompressed wireformat
210  * @param d2: domain name, uncompressed wireformat
211  * @return true if d1 is a subdomain of d2.
212  */
213 int dname_subdomain_c(uint8_t* d1, uint8_t* d2);
214
215 /** 
216  * Debug helper. Print wireformat dname to output. 
217  * @param out: like stdout or a file.
218  * @param pkt: if not NULL, the packet for resolving compression ptrs.
219  * @param dname: pointer to (start of) dname.
220  */
221 void dname_print(FILE* out, struct sldns_buffer* pkt, uint8_t* dname);
222
223 /** 
224  * Debug helper. Print dname to given string buffer (string buffer must
225  * be at least 255 chars + 1 for the 0, in printable form.
226  * This may lose information (? for nonprintable characters, or & if
227  * the name is too long, # for a bad label length).
228  * @param dname: uncompressed wireformat.
229  * @param str: buffer of 255+1 length.
230  */
231 void dname_str(uint8_t* dname, char* str);
232
233 /**
234  * Returns true if the uncompressed wireformat dname is the root "."
235  * @param dname: the dname to check
236  * @return true if ".", false if not.
237  */
238 int dname_is_root(uint8_t* dname);
239
240 /**
241  * Snip off first label from a dname, returning the parent zone.
242  * @param dname: from what to strip off. uncompressed wireformat.
243  * @param len: length, adjusted to become less.
244  * @return stripped off, or "." if input was ".".
245  */
246 void dname_remove_label(uint8_t** dname, size_t* len);
247
248 /**
249  * Snip off first N labels from a dname, returning the parent zone.
250  * @param dname: from what to strip off. uncompressed wireformat.
251  * @param len: length, adjusted to become less.
252  * @param n: number of labels to strip off (from the left).
253  *      if 0, nothing happens.
254  * @return stripped off, or "." if input was ".".
255  */
256 void dname_remove_labels(uint8_t** dname, size_t* len, int n);
257
258 /**
259  * Count labels for the RRSIG signature label field.
260  * Like a normal labelcount, but "*" wildcard and "." root are not counted.
261  * @param dname: valid uncompressed wireformat.
262  * @return number of labels like in RRSIG; '*' and '.' are not counted.
263  */
264 int dname_signame_label_count(uint8_t* dname);
265
266 /**
267  * Return true if the label is a wildcard, *.example.com.
268  * @param dname: valid uncompressed wireformat.
269  * @return true if wildcard, or false.
270  */
271 int dname_is_wild(uint8_t* dname);
272
273 /**
274  * Compare dnames, Canonical in rfc4034 sense, but by label.
275  * Such that zone contents follows zone apex.
276  *
277  * @param d1: first dname. pointer to uncompressed wireformat.
278  * @param labs1: number of labels in first dname.
279  * @param d2: second dname. pointer to uncompressed wireformat.
280  * @param labs2: number of labels in second dname.
281  * @param mlabs: number of labels that matched exactly (the shared topdomain).
282  * @return: 0 for equal, -1 smaller, or +1 d1 larger than d2.
283  */
284 int dname_canon_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, 
285         int* mlabs);
286
287 /**
288  * Canonical dname compare. Takes care of counting labels.
289  * Per rfc 4034 canonical order.
290  *
291  * @param d1: first dname. pointer to uncompressed wireformat.
292  * @param d2: second dname. pointer to uncompressed wireformat.
293  * @return: 0 for equal, -1 smaller, or +1 d1 larger than d2.
294  */
295 int dname_canonical_compare(uint8_t* d1, uint8_t* d2);
296
297 /**
298  * Get the shared topdomain between two names. Root "." or longer.
299  * @param d1: first dname. pointer to uncompressed wireformat.
300  * @param d2: second dname. pointer to uncompressed wireformat.
301  * @return pointer to shared topdomain. Ptr to a part of d1.
302  */
303 uint8_t* dname_get_shared_topdomain(uint8_t* d1, uint8_t* d2);
304
305 #endif /* UTIL_DATA_DNAME_H */