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