1OPENSSL_LH_COMPFUNC(3ossl) OpenSSL OPENSSL_LH_COMPFUNC(3ossl)
2
3
4
6 LHASH, LHASH_OF, DEFINE_LHASH_OF_EX, DEFINE_LHASH_OF,
7 OPENSSL_LH_COMPFUNC, OPENSSL_LH_HASHFUNC, OPENSSL_LH_DOALL_FUNC,
8 LHASH_DOALL_ARG_FN_TYPE, IMPLEMENT_LHASH_HASH_FN,
9 IMPLEMENT_LHASH_COMP_FN, lh_TYPE_new, lh_TYPE_free, lh_TYPE_flush,
10 lh_TYPE_insert, lh_TYPE_delete, lh_TYPE_retrieve, lh_TYPE_doall,
11 lh_TYPE_doall_arg, lh_TYPE_error, OPENSSL_LH_new, OPENSSL_LH_free,
12 OPENSSL_LH_flush, OPENSSL_LH_insert, OPENSSL_LH_delete,
13 OPENSSL_LH_retrieve, OPENSSL_LH_doall, OPENSSL_LH_doall_arg,
14 OPENSSL_LH_error - dynamic hash table
15
17 #include <openssl/lhash.h>
18
19 LHASH_OF(TYPE)
20
21 DEFINE_LHASH_OF_EX(TYPE);
22
23 LHASH_OF(TYPE) *lh_TYPE_new(OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC compare);
24 void lh_TYPE_free(LHASH_OF(TYPE) *table);
25 void lh_TYPE_flush(LHASH_OF(TYPE) *table);
26
27 TYPE *lh_TYPE_insert(LHASH_OF(TYPE) *table, TYPE *data);
28 TYPE *lh_TYPE_delete(LHASH_OF(TYPE) *table, TYPE *data);
29 TYPE *lh_TYPE_retrieve(LHASH_OF(TYPE) *table, TYPE *data);
30
31 void lh_TYPE_doall(LHASH_OF(TYPE) *table, OPENSSL_LH_DOALL_FUNC func);
32 void lh_TYPE_doall_arg(LHASH_OF(TYPE) *table, OPENSSL_LH_DOALL_FUNCARG func,
33 TYPE *arg);
34
35 int lh_TYPE_error(LHASH_OF(TYPE) *table);
36
37 typedef int (*OPENSSL_LH_COMPFUNC)(const void *, const void *);
38 typedef unsigned long (*OPENSSL_LH_HASHFUNC)(const void *);
39 typedef void (*OPENSSL_LH_DOALL_FUNC)(const void *);
40 typedef void (*LHASH_DOALL_ARG_FN_TYPE)(const void *, const void *);
41
42 OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c);
43 void OPENSSL_LH_free(OPENSSL_LHASH *lh);
44 void OPENSSL_LH_flush(OPENSSL_LHASH *lh);
45
46 void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data);
47 void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data);
48 void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data);
49
50 void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func);
51 void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg);
52
53 int OPENSSL_LH_error(OPENSSL_LHASH *lh);
54
55 The following macro is deprecated:
56
57 DEFINE_LHASH_OF(TYPE);
58
60 This library implements type-checked dynamic hash tables. The hash
61 table entries can be arbitrary structures. Usually they consist of key
62 and value fields. In the description here, TYPE is used a placeholder
63 for any of the OpenSSL datatypes, such as SSL_SESSION.
64
65 To define a new type-checked dynamic hash table, use
66 DEFINE_LHASH_OF_EX(). DEFINE_LHASH_OF() was previously used for this
67 purpose, but is now deprecated. The DEFINE_LHASH_OF_EX() macro provides
68 all functionality of DEFINE_LHASH_OF() except for certain deprecated
69 statistics functions (see OPENSSL_LH_stats(3)).
70
71 lh_TYPE_new() creates a new LHASH_OF(TYPE) structure to store arbitrary
72 data entries, and specifies the 'hash' and 'compare' callbacks to be
73 used in organising the table's entries. The hash callback takes a
74 pointer to a table entry as its argument and returns an unsigned long
75 hash value for its key field. The hash value is normally truncated to
76 a power of 2, so make sure that your hash function returns well mixed
77 low order bits. The compare callback takes two arguments (pointers to
78 two hash table entries), and returns 0 if their keys are equal, nonzero
79 otherwise.
80
81 If your hash table will contain items of some particular type and the
82 hash and compare callbacks hash/compare these types, then the
83 IMPLEMENT_LHASH_HASH_FN and IMPLEMENT_LHASH_COMP_FN macros can be used
84 to create callback wrappers of the prototypes required by lh_TYPE_new()
85 as shown in this example:
86
87 /*
88 * Implement the hash and compare functions; "stuff" can be any word.
89 */
90 static unsigned long stuff_hash(const TYPE *a)
91 {
92 ...
93 }
94 static int stuff_cmp(const TYPE *a, const TYPE *b)
95 {
96 ...
97 }
98
99 /*
100 * Implement the wrapper functions.
101 */
102 static IMPLEMENT_LHASH_HASH_FN(stuff, TYPE)
103 static IMPLEMENT_LHASH_COMP_FN(stuff, TYPE)
104
105 If the type is going to be used in several places, the following macros
106 can be used in a common header file to declare the function wrappers:
107
108 DECLARE_LHASH_HASH_FN(stuff, TYPE)
109 DECLARE_LHASH_COMP_FN(stuff, TYPE)
110
111 Then a hash table of TYPE objects can be created using this:
112
113 LHASH_OF(TYPE) *htable;
114
115 htable = B<lh_I<TYPE>_new>(LHASH_HASH_FN(stuff), LHASH_COMP_FN(stuff));
116
117 lh_TYPE_free() frees the LHASH_OF(TYPE) structure table. Allocated hash
118 table entries will not be freed; consider using lh_TYPE_doall() to
119 deallocate any remaining entries in the hash table (see below).
120
121 lh_TYPE_flush() empties the LHASH_OF(TYPE) structure table. New entries
122 can be added to the flushed table. Allocated hash table entries will
123 not be freed; consider using lh_TYPE_doall() to deallocate any
124 remaining entries in the hash table (see below).
125
126 lh_TYPE_insert() inserts the structure pointed to by data into table.
127 If there already is an entry with the same key, the old value is
128 replaced. Note that lh_TYPE_insert() stores pointers, the data are not
129 copied.
130
131 lh_TYPE_delete() deletes an entry from table.
132
133 lh_TYPE_retrieve() looks up an entry in table. Normally, data is a
134 structure with the key field(s) set; the function will return a pointer
135 to a fully populated structure.
136
137 lh_TYPE_doall() will, for every entry in the hash table, call func with
138 the data item as its parameter. For example:
139
140 /* Cleans up resources belonging to 'a' (this is implemented elsewhere) */
141 void TYPE_cleanup_doall(TYPE *a);
142
143 /* Implement a prototype-compatible wrapper for "TYPE_cleanup" */
144 IMPLEMENT_LHASH_DOALL_FN(TYPE_cleanup, TYPE)
145
146 /* Call "TYPE_cleanup" against all items in a hash table. */
147 lh_TYPE_doall(hashtable, LHASH_DOALL_FN(TYPE_cleanup));
148
149 /* Then the hash table itself can be deallocated */
150 lh_TYPE_free(hashtable);
151
152 When doing this, be careful if you delete entries from the hash table
153 in your callbacks: the table may decrease in size, moving the item that
154 you are currently on down lower in the hash table - this could cause
155 some entries to be skipped during the iteration. The second best
156 solution to this problem is to set hash->down_load=0 before you start
157 (which will stop the hash table ever decreasing in size). The best
158 solution is probably to avoid deleting items from the hash table inside
159 a "doall" callback!
160
161 lh_TYPE_doall_arg() is the same as lh_TYPE_doall() except that func
162 will be called with arg as the second argument and func should be of
163 type LHASH_DOALL_ARG_FN(TYPE) (a callback prototype that is passed both
164 the table entry and an extra argument). As with lh_doall(), you can
165 instead choose to declare your callback with a prototype matching the
166 types you are dealing with and use the declare/implement macros to
167 create compatible wrappers that cast variables before calling your
168 type-specific callbacks. An example of this is demonstrated here
169 (printing all hash table entries to a BIO that is provided by the
170 caller):
171
172 /* Prints item 'a' to 'output_bio' (this is implemented elsewhere) */
173 void TYPE_print_doall_arg(const TYPE *a, BIO *output_bio);
174
175 /* Implement a prototype-compatible wrapper for "TYPE_print" */
176 static IMPLEMENT_LHASH_DOALL_ARG_FN(TYPE, const TYPE, BIO)
177
178 /* Print out the entire hashtable to a particular BIO */
179 lh_TYPE_doall_arg(hashtable, LHASH_DOALL_ARG_FN(TYPE_print), BIO,
180 logging_bio);
181
182 lh_TYPE_error() can be used to determine if an error occurred in the
183 last operation.
184
185 OPENSSL_LH_new() is the same as the lh_TYPE_new() except that it is not
186 type specific. So instead of returning an LHASH_OF(TYPE) value it
187 returns a void *. In the same way the functions OPENSSL_LH_free(),
188 OPENSSL_LH_flush(), OPENSSL_LH_insert(), OPENSSL_LH_delete(),
189 OPENSSL_LH_retrieve(), OPENSSL_LH_doall(), OPENSSL_LH_doall_arg(), and
190 OPENSSL_LH_error() are equivalent to the similarly named lh_TYPE
191 functions except that they return or use a void * where the equivalent
192 lh_TYPE function returns or uses a TYPE * or LHASH_OF(TYPE) *. lh_TYPE
193 functions are implemented as type checked wrappers around the
194 OPENSSL_LH functions. Most applications should not call the OPENSSL_LH
195 functions directly.
196
198 lh_TYPE_new() and OPENSSL_LH_new() return NULL on error, otherwise a
199 pointer to the new LHASH structure.
200
201 When a hash table entry is replaced, lh_TYPE_insert() or
202 OPENSSL_LH_insert() return the value being replaced. NULL is returned
203 on normal operation and on error.
204
205 lh_TYPE_delete() and OPENSSL_LH_delete() return the entry being
206 deleted. NULL is returned if there is no such value in the hash table.
207
208 lh_TYPE_retrieve() and OPENSSL_LH_retrieve() return the hash table
209 entry if it has been found, NULL otherwise.
210
211 lh_TYPE_error() and OPENSSL_LH_error() return 1 if an error occurred in
212 the last operation, 0 otherwise. It's meaningful only after non-
213 retrieve operations.
214
215 lh_TYPE_free(), OPENSSL_LH_free(), lh_TYPE_flush(), OPENSSL_LH_flush(),
216 lh_TYPE_doall() OPENSSL_LH_doall(), lh_TYPE_doall_arg() and
217 OPENSSL_LH_doall_arg() return no values.
218
220 The LHASH code is not thread safe. All updating operations, as well as
221 lh_TYPE_error() or OPENSSL_LH_error() calls must be performed under a
222 write lock. All retrieve operations should be performed under a read
223 lock, unless accurate usage statistics are desired. In which case, a
224 write lock should be used for retrieve operations as well. For output
225 of the usage statistics, using the functions from OPENSSL_LH_stats(3),
226 a read lock suffices.
227
228 The LHASH code regards table entries as constant data. As such, it
229 internally represents lh_insert()'d items with a "const void *" pointer
230 type. This is why callbacks such as those used by lh_doall() and
231 lh_doall_arg() declare their prototypes with "const", even for the
232 parameters that pass back the table items' data pointers - for
233 consistency, user-provided data is "const" at all times as far as the
234 LHASH code is concerned. However, as callers are themselves providing
235 these pointers, they can choose whether they too should be treating all
236 such parameters as constant.
237
238 As an example, a hash table may be maintained by code that, for reasons
239 of encapsulation, has only "const" access to the data being indexed in
240 the hash table (i.e. it is returned as "const" from elsewhere in their
241 code) - in this case the LHASH prototypes are appropriate as-is.
242 Conversely, if the caller is responsible for the life-time of the data
243 in question, then they may well wish to make modifications to table
244 item passed back in the lh_doall() or lh_doall_arg() callbacks (see the
245 "TYPE_cleanup" example above). If so, the caller can either cast the
246 "const" away (if they're providing the raw callbacks themselves) or use
247 the macros to declare/implement the wrapper functions without "const"
248 types.
249
250 Callers that only have "const" access to data they're indexing in a
251 table, yet declare callbacks without constant types (or cast the
252 "const" away themselves), are therefore creating their own risks/bugs
253 without being encouraged to do so by the API. On a related note, those
254 auditing code should pay special attention to any instances of
255 DECLARE/IMPLEMENT_LHASH_DOALL_[ARG_]_FN macros that provide types
256 without any "const" qualifiers.
257
259 lh_TYPE_insert() and OPENSSL_LH_insert() return NULL both for success
260 and error.
261
263 OPENSSL_LH_stats(3)
264
266 In OpenSSL 1.0.0, the lhash interface was revamped for better type
267 checking.
268
269 In OpenSSL 3.1, DEFINE_LHASH_OF_EX() was introduced and
270 DEFINE_LHASH_OF() was deprecated.
271
273 Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
274
275 Licensed under the Apache License 2.0 (the "License"). You may not use
276 this file except in compliance with the License. You can obtain a copy
277 in the file LICENSE in the source distribution or at
278 <https://www.openssl.org/source/license.html>.
279
280
281
2823.1.1 2023-08-31 OPENSSL_LH_COMPFUNC(3ossl)