diff options
Diffstat (limited to 'src/lib/libcrypto/man/lh_new.3')
-rw-r--r-- | src/lib/libcrypto/man/lh_new.3 | 554 |
1 files changed, 0 insertions, 554 deletions
diff --git a/src/lib/libcrypto/man/lh_new.3 b/src/lib/libcrypto/man/lh_new.3 deleted file mode 100644 index 2550a7d2e7..0000000000 --- a/src/lib/libcrypto/man/lh_new.3 +++ /dev/null | |||
@@ -1,554 +0,0 @@ | |||
1 | .\" $OpenBSD: lh_new.3,v 1.13 2024/03/05 22:15:29 tb Exp $ | ||
2 | .\" full merge up to: | ||
3 | .\" OpenSSL doc/crypto/lhash.pod 1bc74519 May 20 08:11:46 2016 -0400 | ||
4 | .\" selective merge up to: | ||
5 | .\" OpenSSL doc/man3/OPENSSL_LH_COMPFUNC.pod 24a535ea Sep 22 13:14:20 2020 +0100 | ||
6 | .\" | ||
7 | .\" -------------------------------------------------------------------------- | ||
8 | .\" Major patches to this file were contributed by | ||
9 | .\" Ulf Moeller <ulf@openssl.org>, Geoff Thorpe <geoff@openssl.org>, | ||
10 | .\" and Ben Laurie <ben@openssl.org>. | ||
11 | .\" -------------------------------------------------------------------------- | ||
12 | .\" Copyright (c) 2000, 2001, 2002, 2008, 2009 The OpenSSL Project. | ||
13 | .\" All rights reserved. | ||
14 | .\" | ||
15 | .\" Redistribution and use in source and binary forms, with or without | ||
16 | .\" modification, are permitted provided that the following conditions | ||
17 | .\" are met: | ||
18 | .\" | ||
19 | .\" 1. Redistributions of source code must retain the above copyright | ||
20 | .\" notice, this list of conditions and the following disclaimer. | ||
21 | .\" | ||
22 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
23 | .\" notice, this list of conditions and the following disclaimer in | ||
24 | .\" the documentation and/or other materials provided with the | ||
25 | .\" distribution. | ||
26 | .\" | ||
27 | .\" 3. All advertising materials mentioning features or use of this | ||
28 | .\" software must display the following acknowledgment: | ||
29 | .\" "This product includes software developed by the OpenSSL Project | ||
30 | .\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
31 | .\" | ||
32 | .\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
33 | .\" endorse or promote products derived from this software without | ||
34 | .\" prior written permission. For written permission, please contact | ||
35 | .\" openssl-core@openssl.org. | ||
36 | .\" | ||
37 | .\" 5. Products derived from this software may not be called "OpenSSL" | ||
38 | .\" nor may "OpenSSL" appear in their names without prior written | ||
39 | .\" permission of the OpenSSL Project. | ||
40 | .\" | ||
41 | .\" 6. Redistributions of any form whatsoever must retain the following | ||
42 | .\" acknowledgment: | ||
43 | .\" "This product includes software developed by the OpenSSL Project | ||
44 | .\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
45 | .\" | ||
46 | .\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
47 | .\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
48 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
49 | .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
50 | .\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
51 | .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
52 | .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
53 | .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
54 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
55 | .\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
56 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
57 | .\" OF THE POSSIBILITY OF SUCH DAMAGE. | ||
58 | .\" | ||
59 | .\" -------------------------------------------------------------------------- | ||
60 | .\" Parts of this file are derived from SSLeay documentation, | ||
61 | .\" which is covered by the following Copyright and license: | ||
62 | .\" -------------------------------------------------------------------------- | ||
63 | .\" | ||
64 | .\" Copyright (C) 1995-1998 Tim Hudson (tjh@cryptsoft.com) | ||
65 | .\" All rights reserved. | ||
66 | .\" | ||
67 | .\" This package is an SSL implementation written | ||
68 | .\" by Eric Young (eay@cryptsoft.com). | ||
69 | .\" The implementation was written so as to conform with Netscapes SSL. | ||
70 | .\" | ||
71 | .\" This library is free for commercial and non-commercial use as long as | ||
72 | .\" the following conditions are aheared to. The following conditions | ||
73 | .\" apply to all code found in this distribution, be it the RC4, RSA, | ||
74 | .\" lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
75 | .\" included with this distribution is covered by the same copyright terms | ||
76 | .\" except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
77 | .\" | ||
78 | .\" Copyright remains Eric Young's, and as such any Copyright notices in | ||
79 | .\" the code are not to be removed. | ||
80 | .\" If this package is used in a product, Eric Young should be given | ||
81 | .\" attribution as the author of the parts of the library used. | ||
82 | .\" This can be in the form of a textual message at program startup or | ||
83 | .\" in documentation (online or textual) provided with the package. | ||
84 | .\" | ||
85 | .\" Redistribution and use in source and binary forms, with or without | ||
86 | .\" modification, are permitted provided that the following conditions | ||
87 | .\" are met: | ||
88 | .\" 1. Redistributions of source code must retain the copyright | ||
89 | .\" notice, this list of conditions and the following disclaimer. | ||
90 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
91 | .\" notice, this list of conditions and the following disclaimer in the | ||
92 | .\" documentation and/or other materials provided with the distribution. | ||
93 | .\" 3. All advertising materials mentioning features or use of this software | ||
94 | .\" must display the following acknowledgement: | ||
95 | .\" "This product includes cryptographic software written by | ||
96 | .\" Eric Young (eay@cryptsoft.com)" | ||
97 | .\" The word 'cryptographic' can be left out if the rouines from the | ||
98 | .\" library being used are not cryptographic related :-). | ||
99 | .\" 4. If you include any Windows specific code (or a derivative thereof) | ||
100 | .\" from the apps directory (application code) you must include an | ||
101 | .\" acknowledgement: "This product includes software written by | ||
102 | .\" Tim Hudson (tjh@cryptsoft.com)" | ||
103 | .\" | ||
104 | .\" THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
105 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
106 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
107 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
108 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
109 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
110 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
111 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
112 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
113 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
114 | .\" SUCH DAMAGE. | ||
115 | .\" | ||
116 | .\" The licence and distribution terms for any publically available version or | ||
117 | .\" derivative of this code cannot be changed. i.e. this code cannot simply be | ||
118 | .\" copied and put under another distribution licence | ||
119 | .\" [including the GNU Public Licence.] | ||
120 | .\" | ||
121 | .Dd $Mdocdate: March 5 2024 $ | ||
122 | .Dt LH_NEW 3 | ||
123 | .Os | ||
124 | .Sh NAME | ||
125 | .Nm lh_new , | ||
126 | .Nm lh_free , | ||
127 | .Nm lh_insert , | ||
128 | .Nm lh_delete , | ||
129 | .Nm lh_retrieve , | ||
130 | .Nm lh_doall , | ||
131 | .Nm lh_doall_arg , | ||
132 | .Nm lh_error , | ||
133 | .Nm LHASH_COMP_FN_TYPE , | ||
134 | .Nm LHASH_HASH_FN_TYPE , | ||
135 | .Nm LHASH_DOALL_FN_TYPE , | ||
136 | .Nm LHASH_DOALL_ARG_FN_TYPE , | ||
137 | .Nm lh_strhash | ||
138 | .Nd dynamic hash table | ||
139 | .Sh SYNOPSIS | ||
140 | .In openssl/lhash.h | ||
141 | .Fn DECLARE_LHASH_OF <type> | ||
142 | .Ft LHASH * | ||
143 | .Fn lh_<type>_new void | ||
144 | .Ft void | ||
145 | .Fo lh_<type>_free | ||
146 | .Fa "LHASH_OF(<type>) *table" | ||
147 | .Fc | ||
148 | .Ft <type> * | ||
149 | .Fo lh_<type>_insert | ||
150 | .Fa "LHASH_OF(<type>) *table" | ||
151 | .Fa "<type> *data" | ||
152 | .Fc | ||
153 | .Ft <type> * | ||
154 | .Fo lh_<type>_delete | ||
155 | .Fa "LHASH_OF(<type>) *table" | ||
156 | .Fa "<type> *data" | ||
157 | .Fc | ||
158 | .Ft <type> * | ||
159 | .Fo lh_<type>_retrieve | ||
160 | .Fa "LHASH_OF(<type>) *table" | ||
161 | .Fa "<type> *data" | ||
162 | .Fc | ||
163 | .Ft void | ||
164 | .Fo lh_<type>_doall | ||
165 | .Fa "LHASH_OF(<type>) *table" | ||
166 | .Fa "LHASH_DOALL_FN_TYPE func" | ||
167 | .Fc | ||
168 | .Ft void | ||
169 | .Fo lh_<type>_doall_arg | ||
170 | .Fa "LHASH_OF(<type>) *table" | ||
171 | .Fa "LHASH_DOALL_ARG_FN_TYPE func" | ||
172 | .Fa "<type2>" | ||
173 | .Fa "<type2> *arg" | ||
174 | .Fc | ||
175 | .Ft int | ||
176 | .Fo lh_<type>_error | ||
177 | .Fa "LHASH_OF(<type>) *table" | ||
178 | .Fc | ||
179 | .Ft typedef int | ||
180 | .Fo (*LHASH_COMP_FN_TYPE) | ||
181 | .Fa "const void *" | ||
182 | .Fa "const void *" | ||
183 | .Fc | ||
184 | .Ft typedef unsigned long | ||
185 | .Fo (*LHASH_HASH_FN_TYPE) | ||
186 | .Fa "const void *" | ||
187 | .Fc | ||
188 | .Ft typedef void | ||
189 | .Fo (*LHASH_DOALL_FN_TYPE) | ||
190 | .Fa "const void *" | ||
191 | .Fc | ||
192 | .Ft typedef void | ||
193 | .Fo (*LHASH_DOALL_ARG_FN_TYPE) | ||
194 | .Fa "const void *" | ||
195 | .Fa "const void *" | ||
196 | .Fc | ||
197 | .Ft unsigned long | ||
198 | .Fo lh_strhash | ||
199 | .Fa "const char *c" | ||
200 | .Fc | ||
201 | .Sh DESCRIPTION | ||
202 | This library implements type-checked dynamic hash tables. | ||
203 | The hash table entries can be arbitrary structures. | ||
204 | Usually they consist of key and value fields. | ||
205 | .Pp | ||
206 | .Fn lh_<type>_new | ||
207 | creates a new | ||
208 | .Vt LHASH_OF(<type>) | ||
209 | structure to store arbitrary data entries, and provides the hash and | ||
210 | compare callbacks to be used in organising the table's entries. | ||
211 | The hash callback takes a pointer to a table entry as its argument | ||
212 | and returns an unsigned long hash value for its key field. | ||
213 | The hash value is normally truncated to a power of 2, so make sure that | ||
214 | your hash function returns well mixed low order bits. | ||
215 | The compare callback takes two arguments (pointers to two hash table | ||
216 | entries), and returns 0 if their keys are equal, non-zero otherwise. | ||
217 | If your hash table will contain items of some particular type and the | ||
218 | hash and compare callbacks hash and compare these types, then the | ||
219 | .Fn DECLARE_LHASH_HASH_FN | ||
220 | and | ||
221 | .Fn IMPLEMENT_LHASH_COMP_FN | ||
222 | macros can be used to create callback wrappers of the prototypes | ||
223 | required by | ||
224 | .Fn lh_<type>_new . | ||
225 | These provide per-variable casts before calling the type-specific | ||
226 | callbacks written by the application author. | ||
227 | These macros, as well as those used for the doall callbacks, are | ||
228 | defined as; | ||
229 | .Bd -literal -offset 2n | ||
230 | #define DECLARE_LHASH_HASH_FN(name, o_type) \e | ||
231 | unsigned long name##_LHASH_HASH(const void *); | ||
232 | #define IMPLEMENT_LHASH_HASH_FN(name, o_type) \e | ||
233 | unsigned long name##_LHASH_HASH(const void *arg) { \e | ||
234 | const o_type *a = arg; \e | ||
235 | return name##_hash(a); } | ||
236 | #define LHASH_HASH_FN(name) name##_LHASH_HASH | ||
237 | |||
238 | #define DECLARE_LHASH_COMP_FN(name, o_type) \e | ||
239 | int name##_LHASH_COMP(const void *, const void *); | ||
240 | #define IMPLEMENT_LHASH_COMP_FN(name, o_type) \e | ||
241 | int name##_LHASH_COMP(const void *arg1, const void *arg2) { \e | ||
242 | const o_type *a = arg1; \e | ||
243 | const o_type *b = arg2; \e | ||
244 | return name##_cmp(a,b); } | ||
245 | #define LHASH_COMP_FN(name) name##_LHASH_COMP | ||
246 | |||
247 | #define DECLARE_LHASH_DOALL_FN(name, o_type) \e | ||
248 | void name##_LHASH_DOALL(void *); | ||
249 | #define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \e | ||
250 | void name##_LHASH_DOALL(void *arg) { \e | ||
251 | o_type *a = arg; \e | ||
252 | name##_doall(a); } | ||
253 | #define LHASH_DOALL_FN(name) name##_LHASH_DOALL | ||
254 | |||
255 | #define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \e | ||
256 | void name##_LHASH_DOALL_ARG(void *, void *); | ||
257 | #define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \e | ||
258 | void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \e | ||
259 | o_type *a = arg1; \e | ||
260 | a_type *b = arg2; \e | ||
261 | name##_doall_arg(a, b); } | ||
262 | #define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG | ||
263 | .Ed | ||
264 | .Pp | ||
265 | An example of a hash table storing (pointers to) structures of type | ||
266 | \&'STUFF' could be defined as follows; | ||
267 | .Bd -literal -offset 2n | ||
268 | /* Calculate the hash value of 'tohash' (implemented elsewhere) */ | ||
269 | unsigned long STUFF_hash(const STUFF *tohash); | ||
270 | /* Order 'arg1' and 'arg2' (implemented elsewhere) */ | ||
271 | int stuff_cmp(const STUFF *arg1, const STUFF *arg2); | ||
272 | /* Create type-safe wrapper functions for use in the LHASH internals */ | ||
273 | static IMPLEMENT_LHASH_HASH_FN(stuff, STUFF); | ||
274 | static IMPLEMENT_LHASH_COMP_FN(stuff, STUFF); | ||
275 | /* ... */ | ||
276 | int main(int argc, char *argv[]) { | ||
277 | /* Create the new hash table using the hash/compare wrappers */ | ||
278 | LHASH_OF(STUFF) *hashtable = | ||
279 | lh_STUFF_new(LHASH_HASH_FN(STUFF_hash), | ||
280 | LHASH_COMP_FN(STUFF_cmp)); | ||
281 | /* ... */ | ||
282 | } | ||
283 | .Ed | ||
284 | .Pp | ||
285 | .Fn lh_<type>_free | ||
286 | frees the | ||
287 | .Vt LHASH_OF(<type>) | ||
288 | structure | ||
289 | .Fa table . | ||
290 | Allocated hash table entries will not be freed; consider using | ||
291 | .Fn lh_<type>_doall | ||
292 | to deallocate any remaining entries in the hash table (see below). | ||
293 | .Pp | ||
294 | .Fn lh_<type>_insert | ||
295 | inserts the structure pointed to by | ||
296 | .Fa data | ||
297 | into | ||
298 | .Fa table . | ||
299 | If there already is an entry with the same key, the old value is | ||
300 | replaced. | ||
301 | Note that | ||
302 | .Fn lh_<type>_insert | ||
303 | stores pointers, the data are not copied. | ||
304 | .Pp | ||
305 | .Fn lh_<type>_delete | ||
306 | deletes an entry from | ||
307 | .Fa table . | ||
308 | .Pp | ||
309 | .Fn lh_<type>_retrieve | ||
310 | looks up an entry in | ||
311 | .Fa table . | ||
312 | Normally, | ||
313 | .Fa data | ||
314 | is a structure with the key field(s) set; the function will return a | ||
315 | pointer to a fully populated structure. | ||
316 | .Pp | ||
317 | .Fn lh_<type>_doall | ||
318 | will, for every entry in the hash table, call | ||
319 | .Fa func | ||
320 | with the data item as its parameter. | ||
321 | For | ||
322 | .Fn lh_<type>_doall | ||
323 | and | ||
324 | .Fn lh_<type>_doall_arg , | ||
325 | function pointer casting should be avoided in the callbacks (see | ||
326 | .Sx NOTES ) | ||
327 | \(em instead use the declare/implement macros to create type-checked | ||
328 | wrappers that cast variables prior to calling your type-specific | ||
329 | callbacks. | ||
330 | An example of this is illustrated here where the callback is used to | ||
331 | cleanup resources for items in the hash table prior to the hashtable | ||
332 | itself being deallocated: | ||
333 | .Bd -literal -offset 2n | ||
334 | /* Clean up resources belonging to 'a' (this is implemented elsewhere) */ | ||
335 | void STUFF_cleanup_doall(STUFF *a); | ||
336 | /* Implement a prototype-compatible wrapper for "STUFF_cleanup" */ | ||
337 | IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF) | ||
338 | /* ... then later in the code ... */ | ||
339 | /* So to run "STUFF_cleanup" against all items in a hash table ... */ | ||
340 | lh_STUFF_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup)); | ||
341 | /* Then the hash table itself can be deallocated */ | ||
342 | lh_STUFF_free(hashtable); | ||
343 | .Ed | ||
344 | .Pp | ||
345 | A callback may delete entries from the hash table, however, it is | ||
346 | not safe to insert new entries. | ||
347 | .Pp | ||
348 | .Fn lh_<type>_doall_arg | ||
349 | is the same as | ||
350 | .Fn lh_<type>_doall | ||
351 | except that | ||
352 | .Fa func | ||
353 | will be called with | ||
354 | .Fa arg | ||
355 | as the second argument and | ||
356 | .Fa func | ||
357 | should be of type | ||
358 | .Vt LHASH_DOALL_ARG_FN_TYPE | ||
359 | (a callback prototype that is passed both the table entry and an extra | ||
360 | argument). | ||
361 | As with | ||
362 | .Fn lh_<type>_doall , | ||
363 | you can instead choose to declare your callback with a prototype | ||
364 | matching the types you are dealing with and use the declare/implement | ||
365 | macros to create compatible wrappers that cast variables before calling | ||
366 | your type-specific callbacks. | ||
367 | An example of this is demonstrated here (printing all hash table entries | ||
368 | to a BIO that is provided by the caller): | ||
369 | .Bd -literal -offset 2n | ||
370 | /* Print item 'a' to 'output_bio' (this is implemented elsewhere) */ | ||
371 | void STUFF_print_doall_arg(const STUFF *a, BIO *output_bio); | ||
372 | /* Implement a prototype-compatible wrapper for "STUFF_print" */ | ||
373 | static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF, const STUFF, BIO) | ||
374 | /* ... then later in the code ... */ | ||
375 | /* Print out the entire hashtable to a particular BIO */ | ||
376 | lh_STUFF_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), BIO, | ||
377 | logging_bio); | ||
378 | .Ed | ||
379 | .Pp | ||
380 | .Fn lh_<type>_error | ||
381 | can be used to determine if an error occurred in the last operation. | ||
382 | .Sh RETURN VALUES | ||
383 | .Fn lh_<type>_new | ||
384 | returns | ||
385 | .Dv NULL | ||
386 | on error, otherwise a pointer to the new | ||
387 | .Vt LHASH | ||
388 | structure. | ||
389 | .Pp | ||
390 | When a hash table entry is replaced, | ||
391 | .Fn lh_<type>_insert | ||
392 | returns the value being replaced. | ||
393 | .Dv NULL | ||
394 | is returned on normal operation and on error. | ||
395 | .Pp | ||
396 | .Fn lh_<type>_delete | ||
397 | returns the entry being deleted. | ||
398 | .Dv NULL | ||
399 | is returned if there is no such value in the hash table. | ||
400 | .Pp | ||
401 | .Fn lh_<type>_retrieve | ||
402 | returns the hash table entry if it has been found, or | ||
403 | .Dv NULL | ||
404 | otherwise. | ||
405 | .Pp | ||
406 | .Fn lh_<type>_error | ||
407 | returns 1 if an error occurred in the last operation, or 0 otherwise. | ||
408 | .Sh NOTES | ||
409 | The various LHASH macros and callback types exist to make it possible to | ||
410 | write type-checked code without resorting to function-prototype casting | ||
411 | \(em an evil that makes application code much harder to audit/verify and | ||
412 | also opens the window of opportunity for stack corruption and other | ||
413 | hard-to-find bugs. | ||
414 | It also, apparently, violates ANSI-C. | ||
415 | .Pp | ||
416 | The LHASH code regards table entries as constant data. | ||
417 | As such, it internally represents | ||
418 | .Fn lh_<type>_insert Ap ed | ||
419 | items with a | ||
420 | .Vt const void * | ||
421 | pointer type. | ||
422 | This is why callbacks such as those used by | ||
423 | .Fn lh_<type>_doall | ||
424 | and | ||
425 | .Fn lh_<type>_doall_arg | ||
426 | declare their prototypes with "const", even for the parameters that pass | ||
427 | back the table items' data pointers \(em for consistency, user-provided | ||
428 | data is "const" at all times as far as the LHASH code is concerned. | ||
429 | However, as callers are themselves providing these pointers, they can | ||
430 | choose whether they too should be treating all such parameters as | ||
431 | constant. | ||
432 | .Pp | ||
433 | As an example, a hash table may be maintained by code that, for | ||
434 | reasons of encapsulation, has only "const" access to the data being | ||
435 | indexed in the hash table (i.e. it is returned as "const" from | ||
436 | elsewhere in their code) \(em in this case the LHASH prototypes are | ||
437 | appropriate as-is. | ||
438 | Conversely, if the caller is responsible for the life-time of the data | ||
439 | in question, then they may well wish to make modifications to table item | ||
440 | passed back in the | ||
441 | .Fn lh_<type>_doall | ||
442 | or | ||
443 | .Fn lh_<type>_doall_arg | ||
444 | callbacks (see the "STUFF_cleanup" example above). | ||
445 | If so, the caller can either cast the "const" away (if they're providing | ||
446 | the raw callbacks themselves) or use the macros to declare/implement the | ||
447 | wrapper functions without "const" types. | ||
448 | .Pp | ||
449 | Callers that only have "const" access to data they are indexing in a | ||
450 | table, yet declare callbacks without constant types (or cast the "const" | ||
451 | away themselves), are therefore creating their own risks/bugs without | ||
452 | being encouraged to do so by the API. | ||
453 | On a related note, those auditing code should pay special attention | ||
454 | to any instances of DECLARE/IMPLEMENT_LHASH_DOALL_[ARG_]_FN macros | ||
455 | that provide types without any "const" qualifiers. | ||
456 | .Sh INTERNALS | ||
457 | The following description is based on the SSLeay documentation: | ||
458 | .Pp | ||
459 | The lhash library implements a hash table described in the | ||
460 | .Em Communications of the ACM | ||
461 | in 1991. | ||
462 | What makes this hash table different is that as the table fills, | ||
463 | the hash table is increased (or decreased) in size via | ||
464 | .Xr reallocarray 3 . | ||
465 | When a 'resize' is done, instead of all hashes being redistributed over | ||
466 | twice as many 'buckets', one bucket is split. | ||
467 | So when an 'expand' is done, there is only a minimal cost to | ||
468 | redistribute some values. | ||
469 | Subsequent inserts will cause more single 'bucket' redistributions but | ||
470 | there will never be a sudden large cost due to redistributing all the | ||
471 | \&'buckets'. | ||
472 | .Pp | ||
473 | The state for a particular hash table is kept in the | ||
474 | .Vt LHASH | ||
475 | structure. | ||
476 | The decision to increase or decrease the hash table size is made | ||
477 | depending on the 'load' of the hash table. | ||
478 | The load is the number of items in the hash table divided by the size of | ||
479 | the hash table. | ||
480 | The default values are as follows. | ||
481 | If (hash->up_load < load) => expand. | ||
482 | If (hash->down_load > load) => contract. | ||
483 | The | ||
484 | .Fa up_load | ||
485 | has a default value of 1 and | ||
486 | .Fa down_load | ||
487 | has a default value of 2. | ||
488 | These numbers can be modified by the application by just playing | ||
489 | with the | ||
490 | .Fa up_load | ||
491 | and | ||
492 | .Fa down_load | ||
493 | variables. | ||
494 | The 'load' is kept in a form which is multiplied by 256. | ||
495 | So hash->up_load=8*256 will cause a load of 8 to be set. | ||
496 | .Pp | ||
497 | If you are interested in performance, the field to watch is | ||
498 | .Fa num_comp_calls . | ||
499 | The hash library keeps track of the 'hash' value for each item so when a | ||
500 | lookup is done, the 'hashes' are compared, if there is a match, then a | ||
501 | full compare is done, and hash->num_comp_calls is incremented. | ||
502 | If num_comp_calls is not equal to num_delete plus num_retrieve, it means | ||
503 | that your hash function is generating hashes that are the same for | ||
504 | different values. | ||
505 | It is probably worth changing your hash function if this is the case | ||
506 | because even if your hash table has 10 items in a 'bucket', it can be | ||
507 | searched with 10 | ||
508 | .Vt unsigned long | ||
509 | compares and 10 linked list traverses. | ||
510 | This will be much less expensive that 10 calls to your compare function. | ||
511 | .Pp | ||
512 | .Fn lh_strhash | ||
513 | is a demo string hashing function. | ||
514 | Since the LHASH routines would normally be passed structures, this | ||
515 | routine would not normally be passed to | ||
516 | .Fn lh_<type>_new , | ||
517 | rather it would be used in the function passed to | ||
518 | .Fn lh_<type>_new . | ||
519 | .Sh SEE ALSO | ||
520 | .Xr crypto 3 | ||
521 | .Sh HISTORY | ||
522 | .Fn lh_new , | ||
523 | .Fn lh_free , | ||
524 | .Fn lh_insert , | ||
525 | .Fn lh_delete , | ||
526 | .Fn lh_retrieve , | ||
527 | .Fn lh_doall , | ||
528 | and | ||
529 | .Fn lh_strhash | ||
530 | appeared in SSLeay 0.4 or earlier. | ||
531 | .Fn lh_doall_arg | ||
532 | first appeared in SSLeay 0.5.1. | ||
533 | These functions have been available since | ||
534 | .Ox 2.4 . | ||
535 | .Pp | ||
536 | .Fn lh_<type>_error | ||
537 | was added in SSLeay 0.9.1b. | ||
538 | .Pp | ||
539 | In OpenSSL 0.9.7, all lhash functions that were passed function pointers | ||
540 | were changed for better type safety, and the function types | ||
541 | .Vt LHASH_COMP_FN_TYPE , | ||
542 | .Vt LHASH_HASH_FN_TYPE , | ||
543 | .Vt LHASH_DOALL_FN_TYPE , | ||
544 | and | ||
545 | .Vt LHASH_DOALL_ARG_FN_TYPE | ||
546 | became available. | ||
547 | .Pp | ||
548 | In OpenSSL 1.0.0, the lhash interface was revamped for even better type | ||
549 | checking. | ||
550 | .Sh BUGS | ||
551 | .Fn lh_<type>_insert | ||
552 | returns | ||
553 | .Dv NULL | ||
554 | both for success and error. | ||