Doc nits cleanup, round 2
[openssl.git] / doc / crypto / lhash.pod
1 =pod
2
3 =head1 NAME
4
5 DECLARE_LHASH_OF,
6 OPENSSL_LH_COMPFUNC, OPENSSL_LH_HASHFUNC, OPENSSL_LH_DOALL_FUNC,
7 LHASH_DOALL_ARG_FN_TYPE,
8 lh_TYPE_new, lh_TYPE_free,
9 lh_TYPE_insert, lh_TYPE_delete, lh_TYPE_retrieve,
10 lh_TYPE_doall, lh_TYPE_doall_arg, lh_TYPE_error - dynamic hash table
11
12 =head1 SYNOPSIS
13
14  #include <openssl/lhash.h>
15
16  DECLARE_LHASH_OF(TYPE);
17
18  LHASH *lh_TYPE_new();
19  void lh_TYPE_free(LHASH_OF(TYPE *table);
20
21  TYPE *lh_TYPE_insert(LHASH_OF(TYPE *table, TYPE *data);
22  TYPE *lh_TYPE_delete(LHASH_OF(TYPE *table, TYPE *data);
23  TYPE *lh_retrieve(LHASH_OFTYPE *table, TYPE *data);
24
25  void lh_TYPE_doall(LHASH_OF(TYPE *table, OPENSSL_LH_DOALL_FUNC func);
26  void lh_TYPE_doall_arg(LHASH_OF(TYPE) *table, OPENSSL_LH_DOALL_FUNCARG func,
27           TYPE, TYPE *arg);
28
29  int lh_TYPE_error(LHASH_OF(TYPE) *table);
30
31  typedef int (*OPENSSL_LH_COMPFUNC)(const void *, const void *);
32  typedef unsigned long (*OPENSSL_LH_HASHFUNC)(const void *);
33  typedef void (*OPENSSL_LH_DOALL_FUNC)(const void *);
34  typedef void (*LHASH_DOALL_ARG_FN_TYPE)(const void *, const void *);
35
36 =head1 DESCRIPTION
37
38 This library implements type-checked dynamic hash tables. The hash
39 table entries can be arbitrary structures. Usually they consist of key
40 and value fields.  In the description here, I<TYPE> is used a placeholder
41 for any of the OpenSSL datatypes, such as I<SSL_SESSION>.
42
43 lh_TYPE_new() creates a new B<LHASH_OF(TYPE)> structure to store
44 arbitrary data entries, and provides the 'hash' and 'compare'
45 callbacks to be used in organising the table's entries.  The B<hash>
46 callback takes a pointer to a table entry as its argument and returns
47 an unsigned long hash value for its key field.  The hash value is
48 normally truncated to a power of 2, so make sure that your hash
49 function returns well mixed low order bits.  The B<compare> callback
50 takes two arguments (pointers to two hash table entries), and returns
51 0 if their keys are equal, non-zero otherwise.  If your hash table
52 will contain items of some particular type and the B<hash> and
53 B<compare> callbacks hash/compare these types, then the
54 B<DECLARE_LHASH_HASH_FN> and B<IMPLEMENT_LHASH_COMP_FN> macros can be
55 used to create callback wrappers of the prototypes required by
56 lh_TYPE_new().  These provide per-variable casts before calling the
57 type-specific callbacks written by the application author.  These
58 macros, as well as those used for the "doall" callbacks, are defined
59 as;
60
61  #define DECLARE_LHASH_HASH_FN(name, o_type) \
62          unsigned long name##_LHASH_HASH(const void *);
63  #define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
64          unsigned long name##_LHASH_HASH(const void *arg) { \
65                  const o_type *a = arg; \
66                  return name##_hash(a); }
67  #define LHASH_HASH_FN(name) name##_LHASH_HASH
68
69  #define DECLARE_LHASH_COMP_FN(name, o_type) \
70          int name##_LHASH_COMP(const void *, const void *);
71  #define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
72          int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
73                  const o_type *a = arg1;                    \
74                  const o_type *b = arg2; \
75                  return name##_cmp(a,b); }
76  #define LHASH_COMP_FN(name) name##_LHASH_COMP
77
78  #define DECLARE_LHASH_DOALL_FN(name, o_type) \
79          void name##_LHASH_DOALL(void *);
80  #define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \
81          void name##_LHASH_DOALL(void *arg) { \
82                  o_type *a = arg; \
83                  name##_doall(a); }
84  #define LHASH_DOALL_FN(name) name##_LHASH_DOALL
85
86  #define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
87          void name##_LHASH_DOALL_ARG(void *, void *);
88  #define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
89          void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
90                  o_type *a = arg1; \
91                  a_type *b = arg2; \
92                  name##_doall_arg(a, b); }
93  #define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
94
95  An example of a hash table storing (pointers to) structures of type 'STUFF'
96  could be defined as follows;
97
98  /* Calculates the hash value of 'tohash' (implemented elsewhere) */
99  unsigned long STUFF_hash(const STUFF *tohash);
100  /* Orders 'arg1' and 'arg2' (implemented elsewhere) */
101  int stuff_cmp(const STUFF *arg1, const STUFF *arg2);
102  /* Create the type-safe wrapper functions for use in the LHASH internals */
103  static IMPLEMENT_LHASH_HASH_FN(stuff, STUFF);
104  static IMPLEMENT_LHASH_COMP_FN(stuff, STUFF);
105  /* ... */
106  int main(int argc, char *argv[]) {
107          /* Create the new hash table using the hash/compare wrappers */
108          LHASH_OF(STUFF) *hashtable = lh_STUFF_new(LHASH_HASH_FN(STUFF_hash),
109                                    LHASH_COMP_FN(STUFF_cmp));
110          /* ... */
111  }
112
113 lh_TYPE_free() frees the B<LHASH_OF(TYPE)> structure
114 B<table>. Allocated hash table entries will not be freed; consider
115 using lh_TYPE_doall() to deallocate any remaining entries in the
116 hash table (see below).
117
118 lh_TYPE_insert() inserts the structure pointed to by B<data> into
119 B<table>.  If there already is an entry with the same key, the old
120 value is replaced. Note that lh_TYPE_insert() stores pointers, the
121 data are not copied.
122
123 lh_TYPE_delete() deletes an entry from B<table>.
124
125 lh_TYPE_retrieve() looks up an entry in B<table>. Normally, B<data>
126 is a structure with the key field(s) set; the function will return a
127 pointer to a fully populated structure.
128
129 lh_TYPE_doall() will, for every entry in the hash table, call
130 B<func> with the data item as its parameter.  For lh_TYPE_doall()
131 and lh_TYPE_doall_arg(), function pointer casting should be avoided
132 in the callbacks (see B<NOTE>) - instead use the declare/implement
133 macros to create type-checked wrappers that cast variables prior to
134 calling your type-specific callbacks.  An example of this is
135 illustrated here where the callback is used to cleanup resources for
136 items in the hash table prior to the hashtable itself being
137 deallocated:
138
139  /* Cleans up resources belonging to 'a' (this is implemented elsewhere) */
140  void STUFF_cleanup_doall(STUFF *a);
141  /* Implement a prototype-compatible wrapper for "STUFF_cleanup" */
142  IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF)
143          /* ... then later in the code ... */
144  /* So to run "STUFF_cleanup" against all items in a hash table ... */
145  lh_STUFF_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup));
146  /* Then the hash table itself can be deallocated */
147  lh_STUFF_free(hashtable);
148
149 When doing this, be careful if you delete entries from the hash table
150 in your callbacks: the table may decrease in size, moving the item
151 that you are currently on down lower in the hash table - this could
152 cause some entries to be skipped during the iteration.  The second
153 best solution to this problem is to set hash-E<gt>down_load=0 before
154 you start (which will stop the hash table ever decreasing in size).
155 The best solution is probably to avoid deleting items from the hash
156 table inside a "doall" callback!
157
158 lh_TYPE_doall_arg() is the same as lh_TYPE_doall() except that
159 B<func> will be called with B<arg> as the second argument and B<func>
160 should be of type B<LHASH_DOALL_ARG_FN_TYPE> (a callback prototype
161 that is passed both the table entry and an extra argument).  As with
162 lh_doall(), you can instead choose to declare your callback with a
163 prototype matching the types you are dealing with and use the
164 declare/implement macros to create compatible wrappers that cast
165 variables before calling your type-specific callbacks.  An example of
166 this is demonstrated here (printing all hash table entries to a BIO
167 that is provided by the caller):
168
169  /* Prints item 'a' to 'output_bio' (this is implemented elsewhere) */
170  void STUFF_print_doall_arg(const STUFF *a, BIO *output_bio);
171  /* Implement a prototype-compatible wrapper for "STUFF_print" */
172  static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF, const STUFF, BIO)
173          /* ... then later in the code ... */
174  /* Print out the entire hashtable to a particular BIO */
175  lh_STUFF_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), BIO,
176                     logging_bio);
177
178
179 lh_TYPE_error() can be used to determine if an error occurred in the last
180 operation.
181
182 =head1 RETURN VALUES
183
184 lh_TYPE_new() returns B<NULL> on error, otherwise a pointer to the new
185 B<LHASH> structure.
186
187 When a hash table entry is replaced, lh_TYPE_insert() returns the value
188 being replaced. B<NULL> is returned on normal operation and on error.
189
190 lh_TYPE_delete() returns the entry being deleted.  B<NULL> is returned if
191 there is no such value in the hash table.
192
193 lh_TYPE_retrieve() returns the hash table entry if it has been found,
194 B<NULL> otherwise.
195
196 lh_TYPE_error() returns 1 if an error occurred in the last operation, 0
197 otherwise.
198
199 lh_TYPE_free(), lh_TYPE_doall() and lh_TYPE_doall_arg() return no values.
200
201 =head1 NOTE
202
203 The various LHASH macros and callback types exist to make it possible
204 to write type-checked code without resorting to function-prototype
205 casting - an evil that makes application code much harder to
206 audit/verify and also opens the window of opportunity for stack
207 corruption and other hard-to-find bugs.  It also, apparently, violates
208 ANSI-C.
209
210 The LHASH code regards table entries as constant data.  As such, it
211 internally represents lh_insert()'d items with a "const void *"
212 pointer type.  This is why callbacks such as those used by lh_doall()
213 and lh_doall_arg() declare their prototypes with "const", even for the
214 parameters that pass back the table items' data pointers - for
215 consistency, user-provided data is "const" at all times as far as the
216 LHASH code is concerned.  However, as callers are themselves providing
217 these pointers, they can choose whether they too should be treating
218 all such parameters as constant.
219
220 As an example, a hash table may be maintained by code that, for
221 reasons of encapsulation, has only "const" access to the data being
222 indexed in the hash table (ie. it is returned as "const" from
223 elsewhere in their code) - in this case the LHASH prototypes are
224 appropriate as-is.  Conversely, if the caller is responsible for the
225 life-time of the data in question, then they may well wish to make
226 modifications to table item passed back in the lh_doall() or
227 lh_doall_arg() callbacks (see the "STUFF_cleanup" example above).  If
228 so, the caller can either cast the "const" away (if they're providing
229 the raw callbacks themselves) or use the macros to declare/implement
230 the wrapper functions without "const" types.
231
232 Callers that only have "const" access to data they're indexing in a
233 table, yet declare callbacks without constant types (or cast the
234 "const" away themselves), are therefore creating their own risks/bugs
235 without being encouraged to do so by the API.  On a related note,
236 those auditing code should pay special attention to any instances of
237 DECLARE/IMPLEMENT_LHASH_DOALL_[ARG_]_FN macros that provide types
238 without any "const" qualifiers.
239
240 =head1 BUGS
241
242 lh_TYPE_insert() returns B<NULL> both for success and error.
243
244 =head1 SEE ALSO
245
246 L<lh_stats(3)>
247
248 =head1 HISTORY
249
250 In OpenSSL 1.0.0, the lhash interface was revamped for better
251 type checking.
252
253 =head1 COPYRIGHT
254
255 Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
256
257 Licensed under the OpenSSL license (the "License").  You may not use
258 this file except in compliance with the License.  You can obtain a copy
259 in the file LICENSE in the source distribution or at
260 L<https://www.openssl.org/source/license.html>.
261
262 =cut