| 1 | /* | 
| 2 |  * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. | 
| 3 |  * | 
| 4 |  * Licensed under the OpenSSL license (the "License").  You may not use | 
| 5 |  * this file except in compliance with the License.  You can obtain a copy | 
| 6 |  * in the file LICENSE in the source distribution or at | 
| 7 |  * https://www.openssl.org/source/license.html | 
| 8 |  */ | 
| 9 |  | 
| 10 | /* | 
| 11 |  * Header for dynamic hash table routines Author - Eric Young | 
| 12 |  */ | 
| 13 |  | 
| 14 | #ifndef HEADER_LHASH_H | 
| 15 | # define  | 
| 16 |  | 
| 17 | # include <openssl/e_os2.h> | 
| 18 | # include <openssl/bio.h> | 
| 19 |  | 
| 20 | #ifdef  __cplusplus | 
| 21 | extern "C"  { | 
| 22 | #endif | 
| 23 |  | 
| 24 | typedef struct lhash_node_st OPENSSL_LH_NODE; | 
| 25 | typedef int (*OPENSSL_LH_COMPFUNC) (const void *, const void *); | 
| 26 | typedef unsigned long (*OPENSSL_LH_HASHFUNC) (const void *); | 
| 27 | typedef void (*OPENSSL_LH_DOALL_FUNC) (void *); | 
| 28 | typedef void (*OPENSSL_LH_DOALL_FUNCARG) (void *, void *); | 
| 29 | typedef struct lhash_st OPENSSL_LHASH; | 
| 30 |  | 
| 31 | /* | 
| 32 |  * Macros for declaring and implementing type-safe wrappers for LHASH | 
| 33 |  * callbacks. This way, callbacks can be provided to LHASH structures without | 
| 34 |  * function pointer casting and the macro-defined callbacks provide | 
| 35 |  * per-variable casting before deferring to the underlying type-specific | 
| 36 |  * callbacks. NB: It is possible to place a "static" in front of both the | 
| 37 |  * DECLARE and IMPLEMENT macros if the functions are strictly internal. | 
| 38 |  */ | 
| 39 |  | 
| 40 | /* First: "hash" functions */ | 
| 41 | # define DECLARE_LHASH_HASH_FN(name, o_type) \ | 
| 42 |         unsigned long name##_LHASH_HASH(const void *); | 
| 43 | # define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ | 
| 44 |         unsigned long name##_LHASH_HASH(const void *arg) { \ | 
| 45 |                 const o_type *a = arg; \ | 
| 46 |                 return name##_hash(a); } | 
| 47 | # define LHASH_HASH_FN(name) name##_LHASH_HASH | 
| 48 |  | 
| 49 | /* Second: "compare" functions */ | 
| 50 | # define DECLARE_LHASH_COMP_FN(name, o_type) \ | 
| 51 |         int name##_LHASH_COMP(const void *, const void *); | 
| 52 | # define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ | 
| 53 |         int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ | 
| 54 |                 const o_type *a = arg1;             \ | 
| 55 |                 const o_type *b = arg2; \ | 
| 56 |                 return name##_cmp(a,b); } | 
| 57 | # define LHASH_COMP_FN(name) name##_LHASH_COMP | 
| 58 |  | 
| 59 | /* Fourth: "doall_arg" functions */ | 
| 60 | # define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ | 
| 61 |         void name##_LHASH_DOALL_ARG(void *, void *); | 
| 62 | # define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ | 
| 63 |         void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ | 
| 64 |                 o_type *a = arg1; \ | 
| 65 |                 a_type *b = arg2; \ | 
| 66 |                 name##_doall_arg(a, b); } | 
| 67 | # define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG | 
| 68 |  | 
| 69 |  | 
| 70 | # define LH_LOAD_MULT    256 | 
| 71 |  | 
| 72 | int OPENSSL_LH_error(OPENSSL_LHASH *lh); | 
| 73 | OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c); | 
| 74 | void OPENSSL_LH_free(OPENSSL_LHASH *lh); | 
| 75 | void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data); | 
| 76 | void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data); | 
| 77 | void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data); | 
| 78 | void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func); | 
| 79 | void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg); | 
| 80 | unsigned long OPENSSL_LH_strhash(const char *c); | 
| 81 | unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh); | 
| 82 | unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh); | 
| 83 | void OPENSSL_LH_set_down_load(OPENSSL_LHASH *lh, unsigned long down_load); | 
| 84 |  | 
| 85 | # ifndef OPENSSL_NO_STDIO | 
| 86 | void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp); | 
| 87 | void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp); | 
| 88 | void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp); | 
| 89 | # endif | 
| 90 | void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out); | 
| 91 | void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out); | 
| 92 | void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out); | 
| 93 |  | 
| 94 | # if OPENSSL_API_COMPAT < 0x10100000L | 
| 95 | #  define _LHASH OPENSSL_LHASH | 
| 96 | #  define LHASH_NODE OPENSSL_LH_NODE | 
| 97 | #  define lh_error OPENSSL_LH_error | 
| 98 | #  define lh_new OPENSSL_LH_new | 
| 99 | #  define lh_free OPENSSL_LH_free | 
| 100 | #  define lh_insert OPENSSL_LH_insert | 
| 101 | #  define lh_delete OPENSSL_LH_delete | 
| 102 | #  define lh_retrieve OPENSSL_LH_retrieve | 
| 103 | #  define lh_doall OPENSSL_LH_doall | 
| 104 | #  define lh_doall_arg OPENSSL_LH_doall_arg | 
| 105 | #  define lh_strhash OPENSSL_LH_strhash | 
| 106 | #  define lh_num_items OPENSSL_LH_num_items | 
| 107 | #  ifndef OPENSSL_NO_STDIO | 
| 108 | #   define lh_stats OPENSSL_LH_stats | 
| 109 | #   define lh_node_stats OPENSSL_LH_node_stats | 
| 110 | #   define lh_node_usage_stats OPENSSL_LH_node_usage_stats | 
| 111 | #  endif | 
| 112 | #  define lh_stats_bio OPENSSL_LH_stats_bio | 
| 113 | #  define lh_node_stats_bio OPENSSL_LH_node_stats_bio | 
| 114 | #  define lh_node_usage_stats_bio OPENSSL_LH_node_usage_stats_bio | 
| 115 | # endif | 
| 116 |  | 
| 117 | /* Type checking... */ | 
| 118 |  | 
| 119 | # define LHASH_OF(type) struct lhash_st_##type | 
| 120 |  | 
| 121 | # define DEFINE_LHASH_OF(type) \ | 
| 122 |     LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \ | 
| 123 |     static ossl_inline LHASH_OF(type) * \ | 
| 124 |         lh_##type##_new(unsigned long (*hfn)(const type *), \ | 
| 125 |                         int (*cfn)(const type *, const type *)) \ | 
| 126 |     { \ | 
| 127 |         return (LHASH_OF(type) *) \ | 
| 128 |             OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \ | 
| 129 |     } \ | 
| 130 |     static ossl_unused ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \ | 
| 131 |     { \ | 
| 132 |         OPENSSL_LH_free((OPENSSL_LHASH *)lh); \ | 
| 133 |     } \ | 
| 134 |     static ossl_unused ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \ | 
| 135 |     { \ | 
| 136 |         return (type *)OPENSSL_LH_insert((OPENSSL_LHASH *)lh, d); \ | 
| 137 |     } \ | 
| 138 |     static ossl_unused ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \ | 
| 139 |     { \ | 
| 140 |         return (type *)OPENSSL_LH_delete((OPENSSL_LHASH *)lh, d); \ | 
| 141 |     } \ | 
| 142 |     static ossl_unused ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \ | 
| 143 |     { \ | 
| 144 |         return (type *)OPENSSL_LH_retrieve((OPENSSL_LHASH *)lh, d); \ | 
| 145 |     } \ | 
| 146 |     static ossl_unused ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \ | 
| 147 |     { \ | 
| 148 |         return OPENSSL_LH_error((OPENSSL_LHASH *)lh); \ | 
| 149 |     } \ | 
| 150 |     static ossl_unused ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \ | 
| 151 |     { \ | 
| 152 |         return OPENSSL_LH_num_items((OPENSSL_LHASH *)lh); \ | 
| 153 |     } \ | 
| 154 |     static ossl_unused ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ | 
| 155 |     { \ | 
| 156 |         OPENSSL_LH_node_stats_bio((const OPENSSL_LHASH *)lh, out); \ | 
| 157 |     } \ | 
| 158 |     static ossl_unused ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ | 
| 159 |     { \ | 
| 160 |         OPENSSL_LH_node_usage_stats_bio((const OPENSSL_LHASH *)lh, out); \ | 
| 161 |     } \ | 
| 162 |     static ossl_unused ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ | 
| 163 |     { \ | 
| 164 |         OPENSSL_LH_stats_bio((const OPENSSL_LHASH *)lh, out); \ | 
| 165 |     } \ | 
| 166 |     static ossl_unused ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \ | 
| 167 |     { \ | 
| 168 |         return OPENSSL_LH_get_down_load((OPENSSL_LHASH *)lh); \ | 
| 169 |     } \ | 
| 170 |     static ossl_unused ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \ | 
| 171 |     { \ | 
| 172 |         OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl); \ | 
| 173 |     } \ | 
| 174 |     static ossl_unused ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \ | 
| 175 |                                                           void (*doall)(type *)) \ | 
| 176 |     { \ | 
| 177 |         OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall); \ | 
| 178 |     } \ | 
| 179 |     LHASH_OF(type) | 
| 180 |  | 
| 181 | #define IMPLEMENT_LHASH_DOALL_ARG_CONST(type, argtype) \ | 
| 182 |     int_implement_lhash_doall(type, argtype, const type) | 
| 183 |  | 
| 184 | #define IMPLEMENT_LHASH_DOALL_ARG(type, argtype) \ | 
| 185 |     int_implement_lhash_doall(type, argtype, type) | 
| 186 |  | 
| 187 | #define int_implement_lhash_doall(type, argtype, cbargtype) \ | 
| 188 |     static ossl_unused ossl_inline void \ | 
| 189 |         lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \ | 
| 190 |                                    void (*fn)(cbargtype *, argtype *), \ | 
| 191 |                                    argtype *arg) \ | 
| 192 |     { \ | 
| 193 |         OPENSSL_LH_doall_arg((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNCARG)fn, (void *)arg); \ | 
| 194 |     } \ | 
| 195 |     LHASH_OF(type) | 
| 196 |  | 
| 197 | DEFINE_LHASH_OF(OPENSSL_STRING); | 
| 198 | # ifdef _MSC_VER | 
| 199 | /* | 
| 200 |  * push and pop this warning: | 
| 201 |  *   warning C4090: 'function': different 'const' qualifiers | 
| 202 |  */ | 
| 203 | #  pragma warning (push) | 
| 204 | #  pragma warning (disable: 4090) | 
| 205 | # endif | 
| 206 |  | 
| 207 | DEFINE_LHASH_OF(OPENSSL_CSTRING); | 
| 208 |  | 
| 209 | # ifdef _MSC_VER | 
| 210 | #  pragma warning (pop) | 
| 211 | # endif | 
| 212 |  | 
| 213 | /* | 
| 214 |  * If called without higher optimization (min. -xO3) the Oracle Developer | 
| 215 |  * Studio compiler generates code for the defined (static inline) functions | 
| 216 |  * above. | 
| 217 |  * This would later lead to the linker complaining about missing symbols when | 
| 218 |  * this header file is included but the resulting object is not linked against | 
| 219 |  * the Crypto library (openssl#6912). | 
| 220 |  */ | 
| 221 | # ifdef __SUNPRO_C | 
| 222 | #  pragma weak OPENSSL_LH_new | 
| 223 | #  pragma weak OPENSSL_LH_free | 
| 224 | #  pragma weak OPENSSL_LH_insert | 
| 225 | #  pragma weak OPENSSL_LH_delete | 
| 226 | #  pragma weak OPENSSL_LH_retrieve | 
| 227 | #  pragma weak OPENSSL_LH_error | 
| 228 | #  pragma weak OPENSSL_LH_num_items | 
| 229 | #  pragma weak OPENSSL_LH_node_stats_bio | 
| 230 | #  pragma weak OPENSSL_LH_node_usage_stats_bio | 
| 231 | #  pragma weak OPENSSL_LH_stats_bio | 
| 232 | #  pragma weak OPENSSL_LH_get_down_load | 
| 233 | #  pragma weak OPENSSL_LH_set_down_load | 
| 234 | #  pragma weak OPENSSL_LH_doall | 
| 235 | #  pragma weak OPENSSL_LH_doall_arg | 
| 236 | # endif /* __SUNPRO_C */ | 
| 237 |  | 
| 238 | #ifdef  __cplusplus | 
| 239 | } | 
| 240 | #endif | 
| 241 |  | 
| 242 | #endif | 
| 243 |  |