diff options
Diffstat (limited to 'secure/lib/libcrypto/man/lhash.3')
-rw-r--r-- | secure/lib/libcrypto/man/lhash.3 | 242 |
1 files changed, 124 insertions, 118 deletions
diff --git a/secure/lib/libcrypto/man/lhash.3 b/secure/lib/libcrypto/man/lhash.3 index b53637b..d673cd0 100644 --- a/secure/lib/libcrypto/man/lhash.3 +++ b/secure/lib/libcrypto/man/lhash.3 @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "lhash 3" -.TH lhash 3 "2012-05-10" "0.9.8x" "OpenSSL" +.TH lhash 3 "2012-05-10" "1.0.1c" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -136,18 +136,20 @@ lh_new, lh_free, lh_insert, lh_delete, lh_retrieve, lh_doall, lh_doall_arg, lh_e .Vb 1 \& #include <openssl/lhash.h> \& -\& LHASH *lh_new(LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE compare); -\& void lh_free(LHASH *table); +\& DECLARE_LHASH_OF(<type>); \& -\& void *lh_insert(LHASH *table, void *data); -\& void *lh_delete(LHASH *table, void *data); -\& void *lh_retrieve(LHASH *table, void *data); +\& LHASH *lh_<type>_new(); +\& void lh_<type>_free(LHASH_OF(<type> *table); \& -\& void lh_doall(LHASH *table, LHASH_DOALL_FN_TYPE func); -\& void lh_doall_arg(LHASH *table, LHASH_DOALL_ARG_FN_TYPE func, -\& void *arg); +\& <type> *lh_<type>_insert(LHASH_OF(<type> *table, <type> *data); +\& <type> *lh_<type>_delete(LHASH_OF(<type> *table, <type> *data); +\& <type> *lh_retrieve(LHASH_OF<type> *table, <type> *data); \& -\& int lh_error(LHASH *table); +\& void lh_<type>_doall(LHASH_OF(<type> *table, LHASH_DOALL_FN_TYPE func); +\& void lh_<type>_doall_arg(LHASH_OF(<type> *table, LHASH_DOALL_ARG_FN_TYPE func, +\& <type2>, <type2> *arg); +\& +\& int lh_<type>_error(LHASH_OF(<type> *table); \& \& typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *); \& typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *); @@ -156,118 +158,118 @@ lh_new, lh_free, lh_insert, lh_delete, lh_retrieve, lh_doall, lh_doall_arg, lh_e .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" -This library implements dynamic hash tables. The hash table entries -can be arbitrary structures. Usually they consist of key and value -fields. +This library implements type-checked dynamic hash tables. The hash +table entries can be arbitrary structures. Usually they consist of key +and value fields. .PP -\&\fIlh_new()\fR creates a new \fB\s-1LHASH\s0\fR structure to store arbitrary data -entries, and provides the 'hash' and 'compare' callbacks to be used in -organising the table's entries. The \fBhash\fR callback takes a pointer -to a table entry as its argument and returns an unsigned long hash -value for its key field. The hash value is normally truncated to a -power of 2, so make sure that your hash function returns well mixed -low order bits. The \fBcompare\fR callback takes two arguments (pointers -to two hash table entries), and returns 0 if their keys are equal, -non-zero otherwise. If your hash table will contain items of some -particular type and the \fBhash\fR and \fBcompare\fR callbacks hash/compare -these types, then the \fB\s-1DECLARE_LHASH_HASH_FN\s0\fR and -\&\fB\s-1IMPLEMENT_LHASH_COMP_FN\s0\fR macros can be used to create callback -wrappers of the prototypes required by \fIlh_new()\fR. These provide -per-variable casts before calling the type-specific callbacks written -by the application author. These macros, as well as those used for -the \*(L"doall\*(R" callbacks, are defined as; +lh_<type>\fI_new()\fR creates a new \fB\s-1LHASH_OF\s0(<type\fR> structure to store +arbitrary data entries, and provides the 'hash' and 'compare' +callbacks to be used in organising the table's entries. The \fBhash\fR +callback takes a pointer to a table entry as its argument and returns +an unsigned long hash value for its key field. The hash value is +normally truncated to a power of 2, so make sure that your hash +function returns well mixed low order bits. The \fBcompare\fR callback +takes two arguments (pointers to two hash table entries), and returns +0 if their keys are equal, non-zero otherwise. If your hash table +will contain items of some particular type and the \fBhash\fR and +\&\fBcompare\fR callbacks hash/compare these types, then the +\&\fB\s-1DECLARE_LHASH_HASH_FN\s0\fR and \fB\s-1IMPLEMENT_LHASH_COMP_FN\s0\fR macros can be +used to create callback wrappers of the prototypes required by +lh_<type>\fI_new()\fR. These provide per-variable casts before calling the +type-specific callbacks written by the application author. These +macros, as well as those used for the \*(L"doall\*(R" callbacks, are defined +as; .PP .Vb 7 -\& #define DECLARE_LHASH_HASH_FN(f_name,o_type) \e -\& unsigned long f_name##_LHASH_HASH(const void *); -\& #define IMPLEMENT_LHASH_HASH_FN(f_name,o_type) \e -\& unsigned long f_name##_LHASH_HASH(const void *arg) { \e -\& o_type a = (o_type)arg; \e -\& return f_name(a); } -\& #define LHASH_HASH_FN(f_name) f_name##_LHASH_HASH +\& #define DECLARE_LHASH_HASH_FN(name, o_type) \e +\& unsigned long name##_LHASH_HASH(const void *); +\& #define IMPLEMENT_LHASH_HASH_FN(name, o_type) \e +\& unsigned long name##_LHASH_HASH(const void *arg) { \e +\& const o_type *a = arg; \e +\& return name##_hash(a); } +\& #define LHASH_HASH_FN(name) name##_LHASH_HASH \& -\& #define DECLARE_LHASH_COMP_FN(f_name,o_type) \e -\& int f_name##_LHASH_COMP(const void *, const void *); -\& #define IMPLEMENT_LHASH_COMP_FN(f_name,o_type) \e -\& int f_name##_LHASH_COMP(const void *arg1, const void *arg2) { \e -\& o_type a = (o_type)arg1; \e -\& o_type b = (o_type)arg2; \e -\& return f_name(a,b); } -\& #define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP +\& #define DECLARE_LHASH_COMP_FN(name, o_type) \e +\& int name##_LHASH_COMP(const void *, const void *); +\& #define IMPLEMENT_LHASH_COMP_FN(name, o_type) \e +\& int name##_LHASH_COMP(const void *arg1, const void *arg2) { \e +\& const o_type *a = arg1; \e +\& const o_type *b = arg2; \e +\& return name##_cmp(a,b); } +\& #define LHASH_COMP_FN(name) name##_LHASH_COMP \& -\& #define DECLARE_LHASH_DOALL_FN(f_name,o_type) \e -\& void f_name##_LHASH_DOALL(const void *); -\& #define IMPLEMENT_LHASH_DOALL_FN(f_name,o_type) \e -\& void f_name##_LHASH_DOALL(const void *arg) { \e -\& o_type a = (o_type)arg; \e -\& f_name(a); } -\& #define LHASH_DOALL_FN(f_name) f_name##_LHASH_DOALL +\& #define DECLARE_LHASH_DOALL_FN(name, o_type) \e +\& void name##_LHASH_DOALL(void *); +\& #define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \e +\& void name##_LHASH_DOALL(void *arg) { \e +\& o_type *a = arg; \e +\& name##_doall(a); } +\& #define LHASH_DOALL_FN(name) name##_LHASH_DOALL +\& +\& #define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \e +\& void name##_LHASH_DOALL_ARG(void *, void *); +\& #define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \e +\& void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \e +\& o_type *a = arg1; \e +\& a_type *b = arg2; \e +\& name##_doall_arg(a, b); } +\& #define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG +\& +\& An example of a hash table storing (pointers to) structures of type \*(AqSTUFF\*(Aq +\& could be defined as follows; \& -\& #define DECLARE_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \e -\& void f_name##_LHASH_DOALL_ARG(const void *, const void *); -\& #define IMPLEMENT_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \e -\& void f_name##_LHASH_DOALL_ARG(const void *arg1, const void *arg2) { \e -\& o_type a = (o_type)arg1; \e -\& a_type b = (a_type)arg2; \e -\& f_name(a,b); } -\& #define LHASH_DOALL_ARG_FN(f_name) f_name##_LHASH_DOALL_ARG -.Ve -.PP -An example of a hash table storing (pointers to) structures of type '\s-1STUFF\s0' -could be defined as follows; -.PP -.Vb 10 \& /* Calculates the hash value of \*(Aqtohash\*(Aq (implemented elsewhere) */ \& unsigned long STUFF_hash(const STUFF *tohash); \& /* Orders \*(Aqarg1\*(Aq and \*(Aqarg2\*(Aq (implemented elsewhere) */ -\& int STUFF_cmp(const STUFF *arg1, const STUFF *arg2); +\& int stuff_cmp(const STUFF *arg1, const STUFF *arg2); \& /* Create the type\-safe wrapper functions for use in the LHASH internals */ -\& static IMPLEMENT_LHASH_HASH_FN(STUFF_hash, const STUFF *) -\& static IMPLEMENT_LHASH_COMP_FN(STUFF_cmp, const STUFF *); +\& static IMPLEMENT_LHASH_HASH_FN(stuff, STUFF); +\& static IMPLEMENT_LHASH_COMP_FN(stuff, STUFF); \& /* ... */ \& int main(int argc, char *argv[]) { \& /* Create the new hash table using the hash/compare wrappers */ -\& LHASH *hashtable = lh_new(LHASH_HASH_FN(STUFF_hash), +\& LHASH_OF(STUFF) *hashtable = lh_STUFF_new(LHASH_HASH_FN(STUFF_hash), \& LHASH_COMP_FN(STUFF_cmp)); \& /* ... */ \& } .Ve .PP -\&\fIlh_free()\fR frees the \fB\s-1LHASH\s0\fR structure \fBtable\fR. Allocated hash table -entries will not be freed; consider using \fIlh_doall()\fR to deallocate any -remaining entries in the hash table (see below). +lh_<type>\fI_free()\fR frees the \fB\s-1LHASH_OF\s0(<type\fR> structure +\&\fBtable\fR. Allocated hash table entries will not be freed; consider +using lh_<type>\fI_doall()\fR to deallocate any remaining entries in the +hash table (see below). .PP -\&\fIlh_insert()\fR inserts the structure pointed to by \fBdata\fR into \fBtable\fR. -If there already is an entry with the same key, the old value is -replaced. Note that \fIlh_insert()\fR stores pointers, the data are not -copied. +lh_<type>\fI_insert()\fR inserts the structure pointed to by \fBdata\fR into +\&\fBtable\fR. If there already is an entry with the same key, the old +value is replaced. Note that lh_<type>\fI_insert()\fR stores pointers, the +data are not copied. .PP -\&\fIlh_delete()\fR deletes an entry from \fBtable\fR. +lh_<type>\fI_delete()\fR deletes an entry from \fBtable\fR. .PP -\&\fIlh_retrieve()\fR looks up an entry in \fBtable\fR. Normally, \fBdata\fR is -a structure with the key field(s) set; the function will return a +lh_<type>\fI_retrieve()\fR looks up an entry in \fBtable\fR. Normally, \fBdata\fR +is a structure with the key field(s) set; the function will return a pointer to a fully populated structure. .PP -\&\fIlh_doall()\fR will, for every entry in the hash table, call \fBfunc\fR with -the data item as its parameter. For \fIlh_doall()\fR and \fIlh_doall_arg()\fR, -function pointer casting should be avoided in the callbacks (see -\&\fB\s-1NOTE\s0\fR) \- instead, either declare the callbacks to match the -prototype required in \fIlh_new()\fR or use the declare/implement macros to -create type-safe wrappers that cast variables prior to calling your -type-specific callbacks. An example of this is illustrated here where -the callback is used to cleanup resources for items in the hash table -prior to the hashtable itself being deallocated: +lh_<type>\fI_doall()\fR will, for every entry in the hash table, call +\&\fBfunc\fR with the data item as its parameter. For lh_<type>\fI_doall()\fR +and lh_<type>\fI_doall_arg()\fR, function pointer casting should be avoided +in the callbacks (see \fB\s-1NOTE\s0\fR) \- instead use the declare/implement +macros to create type-checked wrappers that cast variables prior to +calling your type-specific callbacks. An example of this is +illustrated here where the callback is used to cleanup resources for +items in the hash table prior to the hashtable itself being +deallocated: .PP .Vb 9 \& /* Cleans up resources belonging to \*(Aqa\*(Aq (this is implemented elsewhere) */ -\& void STUFF_cleanup(STUFF *a); +\& void STUFF_cleanup_doall(STUFF *a); \& /* Implement a prototype\-compatible wrapper for "STUFF_cleanup" */ -\& IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF *) +\& IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF) \& /* ... then later in the code ... */ \& /* So to run "STUFF_cleanup" against all items in a hash table ... */ -\& lh_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup)); +\& lh_STUFF_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup)); \& /* Then the hash table itself can be deallocated */ -\& lh_free(hashtable); +\& lh_STUFF_free(hashtable); .Ve .PP When doing this, be careful if you delete entries from the hash table @@ -279,51 +281,52 @@ you start (which will stop the hash table ever decreasing in size). The best solution is probably to avoid deleting items from the hash table inside a \*(L"doall\*(R" callback! .PP -\&\fIlh_doall_arg()\fR is the same as \fIlh_doall()\fR except that \fBfunc\fR will be -called with \fBarg\fR as the second argument and \fBfunc\fR should be of -type \fB\s-1LHASH_DOALL_ARG_FN_TYPE\s0\fR (a callback prototype that is passed -both the table entry and an extra argument). As with \fIlh_doall()\fR, you -can instead choose to declare your callback with a prototype matching -the types you are dealing with and use the declare/implement macros to -create compatible wrappers that cast variables before calling your -type-specific callbacks. An example of this is demonstrated here -(printing all hash table entries to a \s-1BIO\s0 that is provided by the -caller): +lh_<type>\fI_doall_arg()\fR is the same as lh_<type>\fI_doall()\fR except that +\&\fBfunc\fR will be called with \fBarg\fR as the second argument and \fBfunc\fR +should be of type \fB\s-1LHASH_DOALL_ARG_FN_TYPE\s0\fR (a callback prototype +that is passed both the table entry and an extra argument). As with +\&\fIlh_doall()\fR, you can instead choose to declare your callback with a +prototype matching the types you are dealing with and use the +declare/implement macros to create compatible wrappers that cast +variables before calling your type-specific callbacks. An example of +this is demonstrated here (printing all hash table entries to a \s-1BIO\s0 +that is provided by the caller): .PP -.Vb 7 +.Vb 8 \& /* Prints item \*(Aqa\*(Aq to \*(Aqoutput_bio\*(Aq (this is implemented elsewhere) */ -\& void STUFF_print(const STUFF *a, BIO *output_bio); +\& void STUFF_print_doall_arg(const STUFF *a, BIO *output_bio); \& /* Implement a prototype\-compatible wrapper for "STUFF_print" */ -\& static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF_print, const STUFF *, BIO *) +\& static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF, const STUFF, BIO) \& /* ... then later in the code ... */ \& /* Print out the entire hashtable to a particular BIO */ -\& lh_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), logging_bio); +\& lh_STUFF_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), BIO, +\& logging_bio); .Ve .PP -\&\fIlh_error()\fR can be used to determine if an error occurred in the last -operation. \fIlh_error()\fR is a macro. +lh_<type>\fI_error()\fR can be used to determine if an error occurred in the last +operation. lh_<type>\fI_error()\fR is a macro. .SH "RETURN VALUES" .IX Header "RETURN VALUES" -\&\fIlh_new()\fR returns \fB\s-1NULL\s0\fR on error, otherwise a pointer to the new +lh_<type>\fI_new()\fR returns \fB\s-1NULL\s0\fR on error, otherwise a pointer to the new \&\fB\s-1LHASH\s0\fR structure. .PP -When a hash table entry is replaced, \fIlh_insert()\fR returns the value +When a hash table entry is replaced, lh_<type>\fI_insert()\fR returns the value being replaced. \fB\s-1NULL\s0\fR is returned on normal operation and on error. .PP -\&\fIlh_delete()\fR returns the entry being deleted. \fB\s-1NULL\s0\fR is returned if +lh_<type>\fI_delete()\fR returns the entry being deleted. \fB\s-1NULL\s0\fR is returned if there is no such value in the hash table. .PP -\&\fIlh_retrieve()\fR returns the hash table entry if it has been found, +lh_<type>\fI_retrieve()\fR returns the hash table entry if it has been found, \&\fB\s-1NULL\s0\fR otherwise. .PP -\&\fIlh_error()\fR returns 1 if an error occurred in the last operation, 0 +lh_<type>\fI_error()\fR returns 1 if an error occurred in the last operation, 0 otherwise. .PP -\&\fIlh_free()\fR, \fIlh_doall()\fR and \fIlh_doall_arg()\fR return no values. +lh_<type>\fI_free()\fR, lh_<type>\fI_doall()\fR and lh_<type>\fI_doall_arg()\fR return no values. .SH "NOTE" .IX Header "NOTE" The various \s-1LHASH\s0 macros and callback types exist to make it possible -to write type-safe code without resorting to function-prototype +to write type-checked code without resorting to function-prototype casting \- an evil that makes application code much harder to audit/verify and also opens the window of opportunity for stack corruption and other hard-to-find bugs. It also, apparently, violates @@ -360,7 +363,7 @@ DECLARE/IMPLEMENT_LHASH_DOALL_[\s-1ARG_\s0]_FN macros that provide types without any \*(L"const\*(R" qualifiers. .SH "BUGS" .IX Header "BUGS" -\&\fIlh_insert()\fR returns \fB\s-1NULL\s0\fR both for success and error. +lh_<type>\fI_insert()\fR returns \fB\s-1NULL\s0\fR both for success and error. .SH "INTERNALS" .IX Header "INTERNALS" The following description is based on the SSLeay documentation: @@ -406,8 +409,8 @@ will be much less expensive that 10 calls to your compare function. .Ve .PP Since the \fB\s-1LHASH\s0\fR routines would normally be passed structures, this -routine would not normally be passed to \fIlh_new()\fR, rather it would be -used in the function passed to \fIlh_new()\fR. +routine would not normally be passed to lh_<type>\fI_new()\fR, rather it would be +used in the function passed to lh_<type>\fI_new()\fR. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIlh_stats\fR\|(3) @@ -422,3 +425,6 @@ In OpenSSL 0.9.7, all lhash functions that were passed function pointers were changed for better type safety, and the function types \s-1LHASH_COMP_FN_TYPE\s0, \&\s-1LHASH_HASH_FN_TYPE\s0, \s-1LHASH_DOALL_FN_TYPE\s0 and \s-1LHASH_DOALL_ARG_FN_TYPE\s0 became available. +.PP +In OpenSSL 1.0.0, the lhash interface was revamped for even better +type checking. |