提交 739a1eb1 编写于 作者: R Rich Salz

Rename lh_xxx,sk_xxx tp OPENSSL_{LH,SK}_xxx

Rename sk_xxx to OPENSSL_sk_xxx and _STACK to OPENSSL_STACK
Rename lh_xxx API to OPENSSL_LH_xxx and LHASH_NODE to OPENSSL_LH_NODE
Make lhash stuff opaque.
Use typedefs for function pointers; makes the code simpler.
Remove CHECKED_xxx macros.
Add documentation; remove old X509-oriented doc.
Add API-compat names for entire old API
Reviewed-by: NDr. Stephen Henson <steve@openssl.org>
上级 06593767
...@@ -4,6 +4,11 @@ ...@@ -4,6 +4,11 @@
Changes between 1.0.2h and 1.1.0 [xx XXX 2016] Changes between 1.0.2h and 1.1.0 [xx XXX 2016]
*) The stack and lhash API's were renamed to start with OPENSSL_SK_
and OPENSSL_LH_, respectively. The old names are available
with API compatibility. They new names are now completely documented.
[Rich Salz]
*) Unify TYPE_up_ref(obj) methods signature. *) Unify TYPE_up_ref(obj) methods signature.
SSL_CTX_up_ref(), SSL_up_ref(), X509_up_ref(), EVP_PKEY_up_ref(), SSL_CTX_up_ref(), SSL_up_ref(), X509_up_ref(), EVP_PKEY_up_ref(),
X509_CRL_up_ref(), X509_OBJECT_up_ref_count() methods are now returning an X509_CRL_up_ref(), X509_OBJECT_up_ref_count() methods are now returning an
......
...@@ -1283,7 +1283,7 @@ static unsigned long index_serial_hash(const OPENSSL_CSTRING *a) ...@@ -1283,7 +1283,7 @@ static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
n = a[DB_serial]; n = a[DB_serial];
while (*n == '0') while (*n == '0')
n++; n++;
return (lh_strhash(n)); return OPENSSL_LH_strhash(n);
} }
static int index_serial_cmp(const OPENSSL_CSTRING *a, static int index_serial_cmp(const OPENSSL_CSTRING *a,
...@@ -1303,7 +1303,7 @@ static int index_name_qual(char **a) ...@@ -1303,7 +1303,7 @@ static int index_name_qual(char **a)
static unsigned long index_name_hash(const OPENSSL_CSTRING *a) static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
{ {
return (lh_strhash(a[DB_name])); return OPENSSL_LH_strhash(a[DB_name]);
} }
int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
......
...@@ -525,7 +525,7 @@ static int function_cmp(const FUNCTION * a, const FUNCTION * b) ...@@ -525,7 +525,7 @@ static int function_cmp(const FUNCTION * a, const FUNCTION * b)
static unsigned long function_hash(const FUNCTION * a) static unsigned long function_hash(const FUNCTION * a)
{ {
return lh_strhash(a->name); return OPENSSL_LH_strhash(a->name);
} }
static int SortFnByName(const void *_f1, const void *_f2) static int SortFnByName(const void *_f1, const void *_f2)
......
...@@ -535,7 +535,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, ...@@ -535,7 +535,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
} else if (ret == -1) } else if (ret == -1)
return -1; return -1;
if (!*val) if (!*val)
*val = (ASN1_VALUE *)sk_new_null(); *val = (ASN1_VALUE *)OPENSSL_sk_new_null();
else { else {
/* /*
* We've got a valid STACK: free up any items present * We've got a valid STACK: free up any items present
......
...@@ -100,7 +100,7 @@ char *_CONF_get_string(const CONF *conf, const char *section, ...@@ -100,7 +100,7 @@ char *_CONF_get_string(const CONF *conf, const char *section,
static unsigned long conf_value_hash(const CONF_VALUE *v) static unsigned long conf_value_hash(const CONF_VALUE *v)
{ {
return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name); return (OPENSSL_LH_strhash(v->section) << 2) ^ OPENSSL_LH_strhash(v->name);
} }
static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
......
...@@ -18,50 +18,48 @@ ...@@ -18,50 +18,48 @@
#include <openssl/bio.h> #include <openssl/bio.h>
#include <openssl/lhash.h> #include <openssl/lhash.h>
#include "lhash_lcl.h"
# ifndef OPENSSL_NO_STDIO # ifndef OPENSSL_NO_STDIO
void lh_stats(const _LHASH *lh, FILE *fp) void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp)
{ {
BIO *bp; BIO *bp;
bp = BIO_new(BIO_s_file()); bp = BIO_new(BIO_s_file());
if (bp == NULL) if (bp == NULL)
goto end; return;
BIO_set_fp(bp, fp, BIO_NOCLOSE); BIO_set_fp(bp, fp, BIO_NOCLOSE);
lh_stats_bio(lh, bp); OPENSSL_LH_stats_bio(lh, bp);
BIO_free(bp); BIO_free(bp);
end:;
} }
void lh_node_stats(const _LHASH *lh, FILE *fp) void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp)
{ {
BIO *bp; BIO *bp;
bp = BIO_new(BIO_s_file()); bp = BIO_new(BIO_s_file());
if (bp == NULL) if (bp == NULL)
goto end; return;
BIO_set_fp(bp, fp, BIO_NOCLOSE); BIO_set_fp(bp, fp, BIO_NOCLOSE);
lh_node_stats_bio(lh, bp); OPENSSL_LH_node_stats_bio(lh, bp);
BIO_free(bp); BIO_free(bp);
end:;
} }
void lh_node_usage_stats(const _LHASH *lh, FILE *fp) void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp)
{ {
BIO *bp; BIO *bp;
bp = BIO_new(BIO_s_file()); bp = BIO_new(BIO_s_file());
if (bp == NULL) if (bp == NULL)
goto end; return;
BIO_set_fp(bp, fp, BIO_NOCLOSE); BIO_set_fp(bp, fp, BIO_NOCLOSE);
lh_node_usage_stats_bio(lh, bp); OPENSSL_LH_node_usage_stats_bio(lh, bp);
BIO_free(bp); BIO_free(bp);
end:;
} }
# endif # endif
void lh_stats_bio(const _LHASH *lh, BIO *out) void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
{ {
BIO_printf(out, "num_items = %lu\n", lh->num_items); BIO_printf(out, "num_items = %lu\n", lh->num_items);
BIO_printf(out, "num_nodes = %u\n", lh->num_nodes); BIO_printf(out, "num_nodes = %u\n", lh->num_nodes);
...@@ -82,9 +80,9 @@ void lh_stats_bio(const _LHASH *lh, BIO *out) ...@@ -82,9 +80,9 @@ void lh_stats_bio(const _LHASH *lh, BIO *out)
BIO_printf(out, "num_hash_comps = %lu\n", lh->num_hash_comps); BIO_printf(out, "num_hash_comps = %lu\n", lh->num_hash_comps);
} }
void lh_node_stats_bio(const _LHASH *lh, BIO *out) void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
{ {
LHASH_NODE *n; OPENSSL_LH_NODE *n;
unsigned int i, num; unsigned int i, num;
for (i = 0; i < lh->num_nodes; i++) { for (i = 0; i < lh->num_nodes; i++) {
...@@ -94,9 +92,9 @@ void lh_node_stats_bio(const _LHASH *lh, BIO *out) ...@@ -94,9 +92,9 @@ void lh_node_stats_bio(const _LHASH *lh, BIO *out)
} }
} }
void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out) void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
{ {
LHASH_NODE *n; OPENSSL_LH_NODE *n;
unsigned long num; unsigned long num;
unsigned int i; unsigned int i;
unsigned long total = 0, n_used = 0; unsigned long total = 0, n_used = 0;
......
...@@ -7,70 +7,33 @@ ...@@ -7,70 +7,33 @@
* https://www.openssl.org/source/license.html * https://www.openssl.org/source/license.html
*/ */
/*-
* Code for dynamic hash table routines
* Author - Eric Young v 2.0
*
* 2.2 eay - added #include "crypto.h" so the memory leak checking code is
* present. eay 18-Jun-98
*
* 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98
*
* 2.0 eay - Fixed a bug that occurred when using lh_delete
* from inside lh_doall(). As entries were deleted,
* the 'table' was 'contract()ed', making some entries
* jump from the end of the table to the start, there by
* skipping the lh_doall() processing. eay - 4/12/95
*
* 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs
* were not being free()ed. 21/11/95
*
* 1.8 eay - Put the stats routines into a separate file, lh_stats.c
* 19/09/95
*
* 1.7 eay - Removed the fputs() for realloc failures - the code
* should silently tolerate them. I have also fixed things
* lint complained about 04/05/95
*
* 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92
*
* 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992
*
* 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91
*
* 1.3 eay - Fixed a few lint problems 19/3/1991
*
* 1.2 eay - Fixed lh_doall problem 13/3/1991
*
* 1.1 eay - Added lh_doall
*
* 1.0 eay - First version
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include <openssl/lhash.h> #include <openssl/lhash.h>
#include "lhash_lcl.h"
#undef MIN_NODES #undef MIN_NODES
#define MIN_NODES 16 #define MIN_NODES 16
#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ #define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */
#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ #define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */
static void expand(_LHASH *lh); static void expand(OPENSSL_LHASH *lh);
static void contract(_LHASH *lh); static void contract(OPENSSL_LHASH *lh);
static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh, const void *data, unsigned long *rhash);
_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c)
{ {
_LHASH *ret; OPENSSL_LHASH *ret;
if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
goto err0; goto err0;
if ((ret->b = OPENSSL_zalloc(sizeof(*ret->b) * MIN_NODES)) == NULL) if ((ret->b = OPENSSL_zalloc(sizeof(*ret->b) * MIN_NODES)) == NULL)
goto err1; goto err1;
ret->comp = ((c == NULL) ? (LHASH_COMP_FN_TYPE)strcmp : c); ret->comp = ((c == NULL) ? (OPENSSL_LH_COMPFUNC)strcmp : c);
ret->hash = ((h == NULL) ? (LHASH_HASH_FN_TYPE)lh_strhash : h); ret->hash = ((h == NULL) ? (OPENSSL_LH_HASHFUNC)OPENSSL_LH_strhash : h);
ret->num_nodes = MIN_NODES / 2; ret->num_nodes = MIN_NODES / 2;
ret->num_alloc_nodes = MIN_NODES; ret->num_alloc_nodes = MIN_NODES;
ret->pmax = MIN_NODES / 2; ret->pmax = MIN_NODES / 2;
...@@ -84,10 +47,10 @@ _LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) ...@@ -84,10 +47,10 @@ _LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
return (NULL); return (NULL);
} }
void lh_free(_LHASH *lh) void OPENSSL_LH_free(OPENSSL_LHASH *lh)
{ {
unsigned int i; unsigned int i;
LHASH_NODE *n, *nn; OPENSSL_LH_NODE *n, *nn;
if (lh == NULL) if (lh == NULL)
return; return;
...@@ -104,10 +67,10 @@ void lh_free(_LHASH *lh) ...@@ -104,10 +67,10 @@ void lh_free(_LHASH *lh)
OPENSSL_free(lh); OPENSSL_free(lh);
} }
void *lh_insert(_LHASH *lh, void *data) void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data)
{ {
unsigned long hash; unsigned long hash;
LHASH_NODE *nn, **rn; OPENSSL_LH_NODE *nn, **rn;
void *ret; void *ret;
lh->error = 0; lh->error = 0;
...@@ -137,10 +100,10 @@ void *lh_insert(_LHASH *lh, void *data) ...@@ -137,10 +100,10 @@ void *lh_insert(_LHASH *lh, void *data)
return (ret); return (ret);
} }
void *lh_delete(_LHASH *lh, const void *data) void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data)
{ {
unsigned long hash; unsigned long hash;
LHASH_NODE *nn, **rn; OPENSSL_LH_NODE *nn, **rn;
void *ret; void *ret;
lh->error = 0; lh->error = 0;
...@@ -165,10 +128,10 @@ void *lh_delete(_LHASH *lh, const void *data) ...@@ -165,10 +128,10 @@ void *lh_delete(_LHASH *lh, const void *data)
return (ret); return (ret);
} }
void *lh_retrieve(_LHASH *lh, const void *data) void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data)
{ {
unsigned long hash; unsigned long hash;
LHASH_NODE **rn; OPENSSL_LH_NODE **rn;
void *ret; void *ret;
lh->error = 0; lh->error = 0;
...@@ -184,11 +147,12 @@ void *lh_retrieve(_LHASH *lh, const void *data) ...@@ -184,11 +147,12 @@ void *lh_retrieve(_LHASH *lh, const void *data)
return (ret); return (ret);
} }
static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, static void doall_util_fn(OPENSSL_LHASH *lh, int use_arg,
LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg) OPENSSL_LH_DOALL_FUNC func,
OPENSSL_LH_DOALL_FUNCARG func_arg, void *arg)
{ {
int i; int i;
LHASH_NODE *a, *n; OPENSSL_LH_NODE *a, *n;
if (lh == NULL) if (lh == NULL)
return; return;
...@@ -200,13 +164,6 @@ static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, ...@@ -200,13 +164,6 @@ static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
for (i = lh->num_nodes - 1; i >= 0; i--) { for (i = lh->num_nodes - 1; i >= 0; i--) {
a = lh->b[i]; a = lh->b[i];
while (a != NULL) { while (a != NULL) {
/*
* 28/05/91 - eay - n added so items can be deleted via lh_doall
*/
/*
* 22/05/08 - ben - eh? since a is not passed, this should not be
* needed
*/
n = a->next; n = a->next;
if (use_arg) if (use_arg)
func_arg(a->data, arg); func_arg(a->data, arg);
...@@ -217,19 +174,19 @@ static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, ...@@ -217,19 +174,19 @@ static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
} }
} }
void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func) void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func)
{ {
doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL); doall_util_fn(lh, 0, func, (OPENSSL_LH_DOALL_FUNCARG)0, NULL);
} }
void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg)
{ {
doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); doall_util_fn(lh, 1, (OPENSSL_LH_DOALL_FUNC)0, func, arg);
} }
static void expand(_LHASH *lh) static void expand(OPENSSL_LHASH *lh)
{ {
LHASH_NODE **n, **n1, **n2, *np; OPENSSL_LH_NODE **n, **n1, **n2, *np;
unsigned int p, i, j; unsigned int p, i, j;
unsigned long hash, nni; unsigned long hash, nni;
...@@ -238,7 +195,7 @@ static void expand(_LHASH *lh) ...@@ -238,7 +195,7 @@ static void expand(_LHASH *lh)
p = (int)lh->p++; p = (int)lh->p++;
n1 = &(lh->b[p]); n1 = &(lh->b[p]);
n2 = &(lh->b[p + (int)lh->pmax]); n2 = &(lh->b[p + (int)lh->pmax]);
*n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */ *n2 = NULL;
nni = lh->num_alloc_nodes; nni = lh->num_alloc_nodes;
for (np = *n1; np != NULL;) { for (np = *n1; np != NULL;) {
...@@ -254,7 +211,7 @@ static void expand(_LHASH *lh) ...@@ -254,7 +211,7 @@ static void expand(_LHASH *lh)
if ((lh->p) >= lh->pmax) { if ((lh->p) >= lh->pmax) {
j = (int)lh->num_alloc_nodes * 2; j = (int)lh->num_alloc_nodes * 2;
n = OPENSSL_realloc(lh->b, (int)(sizeof(LHASH_NODE *) * j)); n = OPENSSL_realloc(lh->b, (int)(sizeof(OPENSSL_LH_NODE *) * j));
if (n == NULL) { if (n == NULL) {
/* fputs("realloc error in lhash",stderr); */ /* fputs("realloc error in lhash",stderr); */
lh->error++; lh->error++;
...@@ -271,15 +228,15 @@ static void expand(_LHASH *lh) ...@@ -271,15 +228,15 @@ static void expand(_LHASH *lh)
} }
} }
static void contract(_LHASH *lh) static void contract(OPENSSL_LHASH *lh)
{ {
LHASH_NODE **n, *n1, *np; OPENSSL_LH_NODE **n, *n1, *np;
np = lh->b[lh->p + lh->pmax - 1]; np = lh->b[lh->p + lh->pmax - 1];
lh->b[lh->p + lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */ lh->b[lh->p + lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */
if (lh->p == 0) { if (lh->p == 0) {
n = OPENSSL_realloc(lh->b, n = OPENSSL_realloc(lh->b,
(unsigned int)(sizeof(LHASH_NODE *) * lh->pmax)); (unsigned int)(sizeof(OPENSSL_LH_NODE *) * lh->pmax));
if (n == NULL) { if (n == NULL) {
/* fputs("realloc error in lhash",stderr); */ /* fputs("realloc error in lhash",stderr); */
lh->error++; lh->error++;
...@@ -306,11 +263,12 @@ static void contract(_LHASH *lh) ...@@ -306,11 +263,12 @@ static void contract(_LHASH *lh)
} }
} }
static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash) static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh,
const void *data, unsigned long *rhash)
{ {
LHASH_NODE **ret, *n1; OPENSSL_LH_NODE **ret, *n1;
unsigned long hash, nn; unsigned long hash, nn;
LHASH_COMP_FN_TYPE cf; OPENSSL_LH_COMPFUNC cf;
hash = (*(lh->hash)) (data); hash = (*(lh->hash)) (data);
lh->num_hash_calls++; lh->num_hash_calls++;
...@@ -341,7 +299,7 @@ static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash) ...@@ -341,7 +299,7 @@ static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash)
* collisions on /usr/dict/words and it distributes on %2^n quite well, not * collisions on /usr/dict/words and it distributes on %2^n quite well, not
* as good as MD5, but still good. * as good as MD5, but still good.
*/ */
unsigned long lh_strhash(const char *c) unsigned long OPENSSL_LH_strhash(const char *c)
{ {
unsigned long ret = 0; unsigned long ret = 0;
long n; long n;
...@@ -369,22 +327,22 @@ unsigned long lh_strhash(const char *c) ...@@ -369,22 +327,22 @@ unsigned long lh_strhash(const char *c)
return ((ret >> 16) ^ ret); return ((ret >> 16) ^ ret);
} }
unsigned long lh_num_items(const _LHASH *lh) unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh)
{ {
return lh ? lh->num_items : 0; return lh ? lh->num_items : 0;
} }
unsigned long lh_get_down_load(const _LHASH *lh) unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh)
{ {
return lh->down_load; return lh->down_load;
} }
void lh_set_down_load(_LHASH *lh, unsigned long down_load) void OPENSSL_LH_set_down_load(OPENSSL_LHASH *lh, unsigned long down_load)
{ {
lh->down_load = down_load; lh->down_load = down_load;
} }
int lh_error(_LHASH *lh) int OPENSSL_LH_error(OPENSSL_LHASH *lh)
{ {
return lh->error; return lh->error;
} }
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
struct lhash_node_st {
void *data;
struct lhash_node_st *next;
unsigned long hash;
};
struct lhash_st {
LHASH_NODE **b;
OPENSSL_LH_COMPFUNC comp;
OPENSSL_LH_HASHFUNC hash;
unsigned int num_nodes;
unsigned int num_alloc_nodes;
unsigned int p;
unsigned int pmax;
unsigned long up_load; /* load times 256 */
unsigned long down_load; /* load times 256 */
unsigned long num_items;
unsigned long num_expands;
unsigned long num_expand_reallocs;
unsigned long num_contracts;
unsigned long num_contract_reallocs;
unsigned long num_hash_calls;
unsigned long num_comp_calls;
unsigned long num_insert;
unsigned long num_replace;
unsigned long num_delete;
unsigned long num_no_delete;
unsigned long num_retrieve;
unsigned long num_retrieve_miss;
unsigned long num_hash_comps;
int error;
};
...@@ -99,7 +99,7 @@ int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), ...@@ -99,7 +99,7 @@ int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *),
OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE); OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE);
return (0); return (0);
} }
name_funcs->hash_func = lh_strhash; name_funcs->hash_func = OPENSSL_LH_strhash;
name_funcs->cmp_func = obj_strcmp; name_funcs->cmp_func = obj_strcmp;
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
sk_NAME_FUNCS_push(name_funcs_stack, name_funcs); sk_NAME_FUNCS_push(name_funcs_stack, name_funcs);
...@@ -141,7 +141,7 @@ static unsigned long obj_name_hash(const OBJ_NAME *a) ...@@ -141,7 +141,7 @@ static unsigned long obj_name_hash(const OBJ_NAME *a)
sk_NAME_FUNCS_value(name_funcs_stack, sk_NAME_FUNCS_value(name_funcs_stack,
a->type)->hash_func(a->name); a->type)->hash_func(a->name);
} else { } else {
ret = lh_strhash(a->name); ret = OPENSSL_LH_strhash(a->name);
} }
ret ^= a->type; ret ^= a->type;
return (ret); return (ret);
......
...@@ -68,10 +68,10 @@ static unsigned long added_obj_hash(const ADDED_OBJ *ca) ...@@ -68,10 +68,10 @@ static unsigned long added_obj_hash(const ADDED_OBJ *ca)
ret ^= p[i] << ((i * 3) % 24); ret ^= p[i] << ((i * 3) % 24);
break; break;
case ADDED_SNAME: case ADDED_SNAME:
ret = lh_strhash(a->sn); ret = OPENSSL_LH_strhash(a->sn);
break; break;
case ADDED_LNAME: case ADDED_LNAME:
ret = lh_strhash(a->ln); ret = OPENSSL_LH_strhash(a->ln);
break; break;
case ADDED_NID: case ADDED_NID:
ret = a->nid; ret = a->nid;
......
...@@ -17,7 +17,7 @@ struct stack_st { ...@@ -17,7 +17,7 @@ struct stack_st {
char **data; char **data;
int sorted; int sorted;
int num_alloc; int num_alloc;
int (*comp) (const void *, const void *); OPENSSL_sk_compfunc comp;
}; };
#undef MIN_NODES #undef MIN_NODES
...@@ -25,9 +25,9 @@ struct stack_st { ...@@ -25,9 +25,9 @@ struct stack_st {
#include <errno.h> #include <errno.h>
int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *))) OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_compfunc c)
(const void *, const void *) { {
int (*old) (const void *, const void *) = sk->comp; OPENSSL_sk_compfunc old = sk->comp;
if (sk->comp != c) if (sk->comp != c)
sk->sorted = 0; sk->sorted = 0;
...@@ -36,12 +36,12 @@ int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *))) ...@@ -36,12 +36,12 @@ int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *)))
return old; return old;
} }
_STACK *sk_dup(_STACK *sk) OPENSSL_STACK *OPENSSL_sk_dup(OPENSSL_STACK *sk)
{ {
_STACK *ret; OPENSSL_STACK *ret;
char **s; char **s;
if ((ret = sk_new(sk->comp)) == NULL) if ((ret = OPENSSL_sk_new(sk->comp)) == NULL)
goto err; goto err;
s = OPENSSL_realloc((char *)ret->data, s = OPENSSL_realloc((char *)ret->data,
(unsigned int)sizeof(char *) * sk->num_alloc); (unsigned int)sizeof(char *) * sk->num_alloc);
...@@ -56,17 +56,17 @@ _STACK *sk_dup(_STACK *sk) ...@@ -56,17 +56,17 @@ _STACK *sk_dup(_STACK *sk)
ret->comp = sk->comp; ret->comp = sk->comp;
return (ret); return (ret);
err: err:
sk_free(ret); OPENSSL_sk_free(ret);
return (NULL); return (NULL);
} }
_STACK *sk_deep_copy(_STACK *sk, void *(*copy_func) (void *), OPENSSL_STACK *OPENSSL_sk_deep_copy(OPENSSL_STACK *sk, OPENSSL_sk_copyfunc copy_func,
void (*free_func) (void *)) OPENSSL_sk_freefunc free_func)
{ {
_STACK *ret; OPENSSL_STACK *ret;
int i; int i;
if ((ret = OPENSSL_malloc(sizeof(_STACK))) == NULL) if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
return ret; return ret;
ret->comp = sk->comp; ret->comp = sk->comp;
ret->sorted = sk->sorted; ret->sorted = sk->sorted;
...@@ -87,23 +87,23 @@ _STACK *sk_deep_copy(_STACK *sk, void *(*copy_func) (void *), ...@@ -87,23 +87,23 @@ _STACK *sk_deep_copy(_STACK *sk, void *(*copy_func) (void *),
while (--i >= 0) while (--i >= 0)
if (ret->data[i] != NULL) if (ret->data[i] != NULL)
free_func(ret->data[i]); free_func(ret->data[i]);
sk_free(ret); OPENSSL_sk_free(ret);
return NULL; return NULL;
} }
} }
return ret; return ret;
} }
_STACK *sk_new_null(void) OPENSSL_STACK *OPENSSL_sk_new_null(void)
{ {
return sk_new((int (*)(const void *, const void *))0); return OPENSSL_sk_new((OPENSSL_sk_compfunc)NULL);
} }
_STACK *sk_new(int (*c) (const void *, const void *)) OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc c)
{ {
_STACK *ret; OPENSSL_STACK *ret;
if ((ret = OPENSSL_zalloc(sizeof(_STACK))) == NULL) if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
goto err; goto err;
if ((ret->data = OPENSSL_zalloc(sizeof(*ret->data) * MIN_NODES)) == NULL) if ((ret->data = OPENSSL_zalloc(sizeof(*ret->data) * MIN_NODES)) == NULL)
goto err; goto err;
...@@ -116,7 +116,7 @@ _STACK *sk_new(int (*c) (const void *, const void *)) ...@@ -116,7 +116,7 @@ _STACK *sk_new(int (*c) (const void *, const void *))
return (NULL); return (NULL);
} }
int sk_insert(_STACK *st, void *data, int loc) int OPENSSL_sk_insert(OPENSSL_STACK *st, void *data, int loc)
{ {
char **s; char **s;
...@@ -142,22 +142,22 @@ int sk_insert(_STACK *st, void *data, int loc) ...@@ -142,22 +142,22 @@ int sk_insert(_STACK *st, void *data, int loc)
return (st->num); return (st->num);
} }
void *sk_delete_ptr(_STACK *st, void *p) void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, void *p)
{ {
int i; int i;
for (i = 0; i < st->num; i++) for (i = 0; i < st->num; i++)
if (st->data[i] == p) if (st->data[i] == p)
return (sk_delete(st, i)); return (OPENSSL_sk_delete(st, i));
return (NULL); return (NULL);
} }
void *sk_delete(_STACK *st, int loc) void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc)
{ {
char *ret; char *ret;
int i, j; int i, j;
if (!st || (loc < 0) || (loc >= st->num)) if (st == NULL || loc < 0 || loc >= st->num)
return NULL; return NULL;
ret = st->data[loc]; ret = st->data[loc];
...@@ -174,7 +174,7 @@ void *sk_delete(_STACK *st, int loc) ...@@ -174,7 +174,7 @@ void *sk_delete(_STACK *st, int loc)
return (ret); return (ret);
} }
static int internal_find(_STACK *st, void *data, int ret_val_options) static int internal_find(OPENSSL_STACK *st, void *data, int ret_val_options)
{ {
const void *const *r; const void *const *r;
int i; int i;
...@@ -188,7 +188,7 @@ static int internal_find(_STACK *st, void *data, int ret_val_options) ...@@ -188,7 +188,7 @@ static int internal_find(_STACK *st, void *data, int ret_val_options)
return (i); return (i);
return (-1); return (-1);
} }
sk_sort(st); OPENSSL_sk_sort(st);
if (data == NULL) if (data == NULL)
return (-1); return (-1);
r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp, r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,
...@@ -198,45 +198,45 @@ static int internal_find(_STACK *st, void *data, int ret_val_options) ...@@ -198,45 +198,45 @@ static int internal_find(_STACK *st, void *data, int ret_val_options)
return (int)((char **)r - st->data); return (int)((char **)r - st->data);
} }
int sk_find(_STACK *st, void *data) int OPENSSL_sk_find(OPENSSL_STACK *st, void *data)
{ {
return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
} }
int sk_find_ex(_STACK *st, void *data) int OPENSSL_sk_find_ex(OPENSSL_STACK *st, void *data)
{ {
return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
} }
int sk_push(_STACK *st, void *data) int OPENSSL_sk_push(OPENSSL_STACK *st, void *data)
{ {
return (sk_insert(st, data, st->num)); return (OPENSSL_sk_insert(st, data, st->num));
} }
int sk_unshift(_STACK *st, void *data) int OPENSSL_sk_unshift(OPENSSL_STACK *st, void *data)
{ {
return (sk_insert(st, data, 0)); return (OPENSSL_sk_insert(st, data, 0));
} }
void *sk_shift(_STACK *st) void *OPENSSL_sk_shift(OPENSSL_STACK *st)
{ {
if (st == NULL) if (st == NULL)
return (NULL); return (NULL);
if (st->num <= 0) if (st->num <= 0)
return (NULL); return (NULL);
return (sk_delete(st, 0)); return (OPENSSL_sk_delete(st, 0));
} }
void *sk_pop(_STACK *st) void *OPENSSL_sk_pop(OPENSSL_STACK *st)
{ {
if (st == NULL) if (st == NULL)
return (NULL); return (NULL);
if (st->num <= 0) if (st->num <= 0)
return (NULL); return (NULL);
return (sk_delete(st, st->num - 1)); return (OPENSSL_sk_delete(st, st->num - 1));
} }
void sk_zero(_STACK *st) void OPENSSL_sk_zero(OPENSSL_STACK *st)
{ {
if (st == NULL) if (st == NULL)
return; return;
...@@ -246,7 +246,7 @@ void sk_zero(_STACK *st) ...@@ -246,7 +246,7 @@ void sk_zero(_STACK *st)
st->num = 0; st->num = 0;
} }
void sk_pop_free(_STACK *st, void (*func) (void *)) void OPENSSL_sk_pop_free(OPENSSL_STACK *st, OPENSSL_sk_freefunc func)
{ {
int i; int i;
...@@ -255,10 +255,10 @@ void sk_pop_free(_STACK *st, void (*func) (void *)) ...@@ -255,10 +255,10 @@ void sk_pop_free(_STACK *st, void (*func) (void *))
for (i = 0; i < st->num; i++) for (i = 0; i < st->num; i++)
if (st->data[i] != NULL) if (st->data[i] != NULL)
func(st->data[i]); func(st->data[i]);
sk_free(st); OPENSSL_sk_free(st);
} }
void sk_free(_STACK *st) void OPENSSL_sk_free(OPENSSL_STACK *st)
{ {
if (st == NULL) if (st == NULL)
return; return;
...@@ -266,48 +266,38 @@ void sk_free(_STACK *st) ...@@ -266,48 +266,38 @@ void sk_free(_STACK *st)
OPENSSL_free(st); OPENSSL_free(st);
} }
int sk_num(const _STACK *st) int OPENSSL_sk_num(const OPENSSL_STACK *st)
{ {
if (st == NULL) if (st == NULL)
return -1; return -1;
return st->num; return st->num;
} }
void *sk_value(const _STACK *st, int i) void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i)
{ {
if (!st || (i < 0) || (i >= st->num)) if (st == NULL || i < 0 || i >= st->num)
return NULL; return NULL;
return st->data[i]; return st->data[i];
} }
void *sk_set(_STACK *st, int i, void *value) void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, void *value)
{ {
if (!st || (i < 0) || (i >= st->num)) if (st == NULL || i < 0 || i >= st->num)
return NULL; return NULL;
return (st->data[i] = value); return (st->data[i] = value);
} }
void sk_sort(_STACK *st) void OPENSSL_sk_sort(OPENSSL_STACK *st)
{ {
if (st && !st->sorted && st->comp != NULL) { if (st && !st->sorted && st->comp != NULL) {
int (*comp_func) (const void *, const void *); qsort(st->data, st->num, sizeof(char *), st->comp);
/*
* same comment as in sk_find ... previously st->comp was declared as
* a (void*,void*) callback type, but this made the population of the
* callback pointer illogical - our callbacks compare type** with
* type**, so we leave the casting until absolutely necessary (ie.
* "now").
*/
comp_func = (int (*)(const void *, const void *))(st->comp);
qsort(st->data, st->num, sizeof(char *), comp_func);
st->sorted = 1; st->sorted = 1;
} }
} }
int sk_is_sorted(const _STACK *st) int OPENSSL_sk_is_sorted(const OPENSSL_STACK *st)
{ {
if (!st) if (st == NULL)
return 1; return 1;
return st->sorted; return st->sorted;
} }
...@@ -145,7 +145,7 @@ OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, ...@@ -145,7 +145,7 @@ OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx,
} }
int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp) OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC cmp)
{ {
LHASH_OF(OPENSSL_STRING) *idx; LHASH_OF(OPENSSL_STRING) *idx;
OPENSSL_STRING *r; OPENSSL_STRING *r;
...@@ -156,7 +156,7 @@ int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), ...@@ -156,7 +156,7 @@ int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
return (0); return (0);
} }
/* FIXME: we lose type checking at this point */ /* FIXME: we lose type checking at this point */
if ((idx = (LHASH_OF(OPENSSL_STRING) *)lh_new(hash, cmp)) == NULL) { if ((idx = (LHASH_OF(OPENSSL_STRING) *)OPENSSL_LH_new(hash, cmp)) == NULL) {
db->error = DB_ERROR_MALLOC; db->error = DB_ERROR_MALLOC;
return (0); return (0);
} }
......
...@@ -2,20 +2,21 @@ ...@@ -2,20 +2,21 @@
=head1 NAME =head1 NAME
lh_stats, lh_node_stats, lh_node_usage_stats, lh_stats_bio, OPENSSL_LH_stats, OPENSSL_LH_node_stats, OPENSSL_LH_node_usage_stats,
lh_node_stats_bio, lh_node_usage_stats_bio - LHASH statistics OPENSSL_LH_stats_bio,
OPENSSL_LH_node_stats_bio, OPENSSL_LH_node_usage_stats_bio - LHASH statistics
=head1 SYNOPSIS =head1 SYNOPSIS
#include <openssl/lhash.h> #include <openssl/lhash.h>
void lh_stats(LHASH *table, FILE *out); void OPENSSL_LH_stats(LHASH *table, FILE *out);
void lh_node_stats(LHASH *table, FILE *out); void OPENSSL_LH_node_stats(LHASH *table, FILE *out);
void lh_node_usage_stats(LHASH *table, FILE *out); void OPENSSL_LH_node_usage_stats(LHASH *table, FILE *out);
void lh_stats_bio(LHASH *table, BIO *out); void OPENSSL_LH_stats_bio(LHASH *table, BIO *out);
void lh_node_stats_bio(LHASH *table, BIO *out); void OPENSSL_LH_node_stats_bio(LHASH *table, BIO *out);
void lh_node_usage_stats_bio(LHASH *table, BIO *out); void OPENSSL_LH_node_usage_stats_bio(LHASH *table, BIO *out);
=head1 DESCRIPTION =head1 DESCRIPTION
...@@ -24,14 +25,14 @@ accessing the hash table. This is mostly a legacy of Eric Young ...@@ -24,14 +25,14 @@ accessing the hash table. This is mostly a legacy of Eric Young
writing this library for the reasons of implementing what looked like writing this library for the reasons of implementing what looked like
a nice algorithm rather than for a particular software product. a nice algorithm rather than for a particular software product.
lh_stats() prints out statistics on the size of the hash table, how OPENSSL_LH_stats() prints out statistics on the size of the hash table, how
many entries are in it, and the number and result of calls to the many entries are in it, and the number and result of calls to the
routines in this library. routines in this library.
lh_node_stats() prints the number of entries for each 'bucket' in the OPENSSL_LH_node_stats() prints the number of entries for each 'bucket' in the
hash table. hash table.
lh_node_usage_stats() prints out a short summary of the state of the OPENSSL_LH_node_usage_stats() prints out a short summary of the state of the
hash table. It prints the 'load' and the 'actual load'. The load is hash table. It prints the 'load' and the 'actual load'. The load is
the average number of data items per 'bucket' in the hash table. The the average number of data items per 'bucket' in the hash table. The
'actual load' is the average number of items per 'bucket', but only 'actual load' is the average number of items per 'bucket', but only
...@@ -40,7 +41,7 @@ average number of searches that will need to find an item in the hash ...@@ -40,7 +41,7 @@ average number of searches that will need to find an item in the hash
table, while the 'load' is the average number that will be done to table, while the 'load' is the average number that will be done to
record a miss. record a miss.
lh_stats_bio(), lh_node_stats_bio() and lh_node_usage_stats_bio() OPENSSL_LH_stats_bio(), OPENSSL_LH_node_stats_bio() and OPENSSL_LH_node_usage_stats_bio()
are the same as the above, except that the output goes to a B<BIO>. are the same as the above, except that the output goes to a B<BIO>.
=head1 RETURN VALUES =head1 RETURN VALUES
......
...@@ -2,39 +2,45 @@ ...@@ -2,39 +2,45 @@
=head1 NAME =head1 NAME
lh_new, lh_free, lh_insert, lh_delete, lh_retrieve, lh_doall, lh_doall_arg, lh_error - dynamic hash table DECLARE_LHASH_OF,
OPENSSL_LH_COMPFUNC, OPENSSL_LH_HASHFUNC, OPENSSL_LH_DOALL_FUNC,
LHASH_DOALL_ARG_FN_TYPE,
lh_TYPE_new, lh_TYPE_free,
lh_TYPE_insert, lh_TYPE_delete, lh_TYPE_retrieve,
lh_TYPE_doall, lh_TYPE_doall_arg, lh_TYPE_error - dynamic hash table
=head1 SYNOPSIS =head1 SYNOPSIS
#include <openssl/lhash.h> #include <openssl/lhash.h>
DECLARE_LHASH_OF(<type>); DECLARE_LHASH_OF(TYPE);
LHASH *lh_<type>_new(); LHASH *lh_TYPE_new();
void lh_<type>_free(LHASH_OF(<type> *table); void lh_TYPE_free(LHASH_OF(TYPE *table);
<type> *lh_<type>_insert(LHASH_OF(<type> *table, <type> *data); TYPE *lh_TYPE_insert(LHASH_OF(TYPE *table, TYPE *data);
<type> *lh_<type>_delete(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); TYPE *lh_retrieve(LHASH_OFTYPE *table, TYPE *data);
void lh_<type>_doall(LHASH_OF(<type> *table, LHASH_DOALL_FN_TYPE func); void lh_TYPE_doall(LHASH_OF(TYPE *table, OPENSSL_LH_DOALL_FUNC func);
void lh_<type>_doall_arg(LHASH_OF(<type> *table, LHASH_DOALL_ARG_FN_TYPE func, void lh_TYPE_doall_arg(LHASH_OF(TYPE) *table, OPENSSL_LH_DOALL_FUNCARG func,
<type2>, <type2> *arg); TYPE, TYPE *arg);
int lh_<type>_error(LHASH_OF(<type> *table); int lh_TYPE_error(LHASH_OF(TYPE) *table);
typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *); typedef int (*OPENSSL_LH_COMPFUNC)(const void *, const void *);
typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *); typedef unsigned long (*OPENSSL_LH_HASHFUNC)(const void *);
typedef void (*LHASH_DOALL_FN_TYPE)(const void *); typedef void (*OPENSSL_LH_DOALL_FUNC)(const void *);
typedef void (*LHASH_DOALL_ARG_FN_TYPE)(const void *, const void *); typedef void (*LHASH_DOALL_ARG_FN_TYPE)(const void *, const void *);
=head1 DESCRIPTION =head1 DESCRIPTION
This library implements type-checked dynamic hash tables. The hash This library implements type-checked dynamic hash tables. The hash
table entries can be arbitrary structures. Usually they consist of key table entries can be arbitrary structures. Usually they consist of key
and value fields. and value fields. In the description here, I<TYPE> is used a placeholder
for any of the OpenSSL datatypes, such as I<SSL_SESSION>.
lh_<type>_new() creates a new B<LHASH_OF(<type>> structure to store lh_TYPE_new() creates a new B<LHASH_OF(TYPE)> structure to store
arbitrary data entries, and provides the 'hash' and 'compare' arbitrary data entries, and provides the 'hash' and 'compare'
callbacks to be used in organising the table's entries. The B<hash> callbacks to be used in organising the table's entries. The B<hash>
callback takes a pointer to a table entry as its argument and returns callback takes a pointer to a table entry as its argument and returns
...@@ -47,7 +53,7 @@ will contain items of some particular type and the B<hash> and ...@@ -47,7 +53,7 @@ will contain items of some particular type and the B<hash> and
B<compare> callbacks hash/compare these types, then the B<compare> callbacks hash/compare these types, then the
B<DECLARE_LHASH_HASH_FN> and B<IMPLEMENT_LHASH_COMP_FN> macros can be B<DECLARE_LHASH_HASH_FN> and B<IMPLEMENT_LHASH_COMP_FN> macros can be
used to create callback wrappers of the prototypes required by used to create callback wrappers of the prototypes required by
lh_<type>_new(). These provide per-variable casts before calling the lh_TYPE_new(). These provide per-variable casts before calling the
type-specific callbacks written by the application author. These type-specific callbacks written by the application author. These
macros, as well as those used for the "doall" callbacks, are defined macros, as well as those used for the "doall" callbacks, are defined
as; as;
...@@ -104,25 +110,25 @@ as; ...@@ -104,25 +110,25 @@ as;
/* ... */ /* ... */
} }
lh_<type>_free() frees the B<LHASH_OF(<type>> structure lh_TYPE_free() frees the B<LHASH_OF(TYPE)> structure
B<table>. Allocated hash table entries will not be freed; consider B<table>. Allocated hash table entries will not be freed; consider
using lh_<type>_doall() to deallocate any remaining entries in the using lh_TYPE_doall() to deallocate any remaining entries in the
hash table (see below). hash table (see below).
lh_<type>_insert() inserts the structure pointed to by B<data> into lh_TYPE_insert() inserts the structure pointed to by B<data> into
B<table>. If there already is an entry with the same key, the old B<table>. If there already is an entry with the same key, the old
value is replaced. Note that lh_<type>_insert() stores pointers, the value is replaced. Note that lh_TYPE_insert() stores pointers, the
data are not copied. data are not copied.
lh_<type>_delete() deletes an entry from B<table>. lh_TYPE_delete() deletes an entry from B<table>.
lh_<type>_retrieve() looks up an entry in B<table>. Normally, B<data> lh_TYPE_retrieve() looks up an entry in B<table>. Normally, B<data>
is a structure with the key field(s) set; the function will return a is a structure with the key field(s) set; the function will return a
pointer to a fully populated structure. pointer to a fully populated structure.
lh_<type>_doall() will, for every entry in the hash table, call lh_TYPE_doall() will, for every entry in the hash table, call
B<func> with the data item as its parameter. For lh_<type>_doall() B<func> with the data item as its parameter. For lh_TYPE_doall()
and lh_<type>_doall_arg(), function pointer casting should be avoided and lh_TYPE_doall_arg(), function pointer casting should be avoided
in the callbacks (see B<NOTE>) - instead use the declare/implement in the callbacks (see B<NOTE>) - instead use the declare/implement
macros to create type-checked wrappers that cast variables prior to macros to create type-checked wrappers that cast variables prior to
calling your type-specific callbacks. An example of this is calling your type-specific callbacks. An example of this is
...@@ -149,7 +155,7 @@ you start (which will stop the hash table ever decreasing in size). ...@@ -149,7 +155,7 @@ you start (which will stop the hash table ever decreasing in size).
The best solution is probably to avoid deleting items from the hash The best solution is probably to avoid deleting items from the hash
table inside a "doall" callback! table inside a "doall" callback!
lh_<type>_doall_arg() is the same as lh_<type>_doall() except that lh_TYPE_doall_arg() is the same as lh_TYPE_doall() except that
B<func> will be called with B<arg> as the second argument and B<func> B<func> will be called with B<arg> as the second argument and B<func>
should be of type B<LHASH_DOALL_ARG_FN_TYPE> (a callback prototype should be of type B<LHASH_DOALL_ARG_FN_TYPE> (a callback prototype
that is passed both the table entry and an extra argument). As with that is passed both the table entry and an extra argument). As with
...@@ -169,27 +175,28 @@ that is provided by the caller): ...@@ -169,27 +175,28 @@ that is provided by the caller):
lh_STUFF_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), BIO, lh_STUFF_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), BIO,
logging_bio); logging_bio);
lh_<type>_error() can be used to determine if an error occurred in the last
operation. lh_<type>_error() is a macro. lh_TYPE_error() can be used to determine if an error occurred in the last
operation.
=head1 RETURN VALUES =head1 RETURN VALUES
lh_<type>_new() returns B<NULL> on error, otherwise a pointer to the new lh_TYPE_new() returns B<NULL> on error, otherwise a pointer to the new
B<LHASH> structure. B<LHASH> structure.
When a hash table entry is replaced, lh_<type>_insert() returns the value When a hash table entry is replaced, lh_TYPE_insert() returns the value
being replaced. B<NULL> is returned on normal operation and on error. being replaced. B<NULL> is returned on normal operation and on error.
lh_<type>_delete() returns the entry being deleted. B<NULL> is returned if lh_TYPE_delete() returns the entry being deleted. B<NULL> is returned if
there is no such value in the hash table. there is no such value in the hash table.
lh_<type>_retrieve() returns the hash table entry if it has been found, lh_TYPE_retrieve() returns the hash table entry if it has been found,
B<NULL> otherwise. B<NULL> otherwise.
lh_<type>_error() returns 1 if an error occurred in the last operation, 0 lh_TYPE_error() returns 1 if an error occurred in the last operation, 0
otherwise. otherwise.
lh_<type>_free(), lh_<type>_doall() and lh_<type>_doall_arg() return no values. lh_TYPE_free(), lh_TYPE_doall() and lh_TYPE_doall_arg() return no values.
=head1 NOTE =head1 NOTE
...@@ -232,17 +239,12 @@ without any "const" qualifiers. ...@@ -232,17 +239,12 @@ without any "const" qualifiers.
=head1 BUGS =head1 BUGS
lh_<type>_insert() returns B<NULL> both for success and error. lh_TYPE_insert() returns B<NULL> both for success and error.
=head1 SEE ALSO =head1 SEE ALSO
L<lh_stats(3)> L<lh_stats(3)>
=head1 HISTORY
In OpenSSL 1.0.0, the lhash interface was revamped for better
type checking.
=cut =cut
=head1 COPYRIGHT =head1 COPYRIGHT
......
...@@ -2,128 +2,150 @@ ...@@ -2,128 +2,150 @@
=head1 NAME =head1 NAME
sk_X509_num, sk_X509_value, sk_X509_new, sk_X509_new_null, sk_X509_free, DEFINE_STACK_OF, DEFINE_STACK_OF_CONST, DEFINE_SPECIAL_STACK_OF,
sk_X509_zero, sk_X509_delete, sk_X509_delete_ptr, sk_X509_push, sk_TYPE_num, sk_TYPE_value, sk_TYPE_new, sk_TYPE_new_null, sk_TYPE_free,
sk_X509_unshift, sk_X509_pop, sk_X509_shift, sk_X509_pop_free, sk_X509_insert, sk_TYPE_zero, sk_TYPE_delete, sk_TYPE_delete_ptr, sk_TYPE_push,
sk_X509_set, sk_X509_find, sk_X509_find_ex, sk_X509_sort, sk_X509_is_sorted, sk_TYPE_unshift, sk_TYPE_pop, sk_TYPE_shift, sk_TYPE_pop_free,
sk_X509_dup, sk_X509_deep_copy, sk_X509_set_cmp_func - X509 stack sk_TYPE_insert, sk_TYPE_set, sk_TYPE_find, sk_TYPE_find_ex, sk_TYPE_sort,
sk_TYPE_is_sorted, sk_TYPE_dup, sk_TYPE_deep_copy, sk_TYPE_set_cmp_func -
stack container
=head1 SYNOPSIS =head1 SYNOPSIS
#include <openssl/x509.h> #include <openssl/safestack.h>
int sk_X509_num(const STACK_OF(X509) *sk); #define STACK_OF(TYPE)
X509 *sk_X509_value(const STACK_OF(X509) *sk, int idx); #define DEFINE_STACK_OF
STACK_OF(X509) *sk_X509_new(int (*cmpf)(const X509 * const *a, #define DEFINE_STACK_OF_CONST
const X509 * const *b)); #define DEFINE_SPECIAL_STACK_OF
STACK_OF(X509) *sk_X509_new_null(void);
int (*sk_X509_set_cmp_func (STACK_OF(X509) *sk, typedef int (*sk_TYPE_compfunc)(const TYPE *const *a, const TYPE *const *b);
int (*cmpf) (const X509 * const *a, typedef TYPE * (*sk_TYPE_copyfunc)(const TYPE *a);
const X509 * const *b))) typedef void (*sk_TYPE_freefunc)(TYPE *a);
(const X509 * const *, const X509 * const *);
void sk_X509_free(const STACK_OF(X509) *sk); int sk_TYPE_num(const STACK_OF(TYPE) *sk);
void sk_X509_zero(const STACK_OF(X509) *sk); TYPE *sk_TYPE_value(const STACK_OF(TYPE) *sk, int idx);
void sk_X509_pop_free(STACK_OF(X509) *sk, void (*func) (X509 *a)); STACK_OF(TYPE) *sk_TYPE_new(sk_TYPE_compfunc compare);
X509 *sk_X509_delete(STACK_OF(X509) *sk, int i); STACK_OF(TYPE) *sk_TYPE_new_null(void);
X509 *sk_X509_delete_ptr(STACK_OF(X509) *sk, X509 *ptr); void sk_TYPE_free(const STACK_OF(TYPE) *sk);
int sk_X509_insert(STACK_OF(X509) *sk, X509 *ptr, int idx); void sk_TYPE_zero(const STACK_OF(TYPE) *sk);
int sk_X509_push(STACK_OF(X509) *sk, X509 *ptr); TYPE *sk_TYPE_delete(STACK_OF(TYPE) *sk, int i);
int sk_X509_unshift(STACK_OF(X509) *sk, X509 *ptr); TYPE *sk_TYPE_delete_ptr(STACK_OF(TYPE) *sk, TYPE *ptr);
X509 *sk_X509_pop(STACK_OF(X509) *sk); int sk_TYPE_push(STACK_OF(TYPE) *sk, TYPE *ptr);
X509 *sk_X509_shift(STACK_OF(X509) *sk); int sk_TYPE_unshift(STACK_OF(TYPE) *sk, TYPE *ptr);
X509 *sk_X509_set(STACK_OF(X509) *sk, int idx, X509 *ptr); TYPE *sk_TYPE_pop(STACK_OF(TYPE) *sk);
int sk_X509_find(STACK_OF(X509) *sk, X509 *ptr); TYPE *sk_TYPE_shift(STACK_OF(TYPE) *sk);
int sk_X509_find_ex(STACK_OF(X509) *sk, X509 *ptr); void sk_TYPE_pop_free(STACK_OF(TYPE) *sk, sk_TYPE_freefunc freefunc);
void sk_X509_sort(const STACK_OF(X509) *sk); int sk_TYPE_insert(STACK_OF(TYPE) *sk, TYPE *ptr, int idx);
int sk_X509_is_sorted(const STACK_OF(X509) *sk); TYPE *sk_TYPE_set(STACK_OF(TYPE) *sk, int idx, TYPE *ptr);
STACK_OF(X509) *sk_X509_dup(STACK_OF(X509) *sk); int sk_TYPE_find(STACK_OF(TYPE) *sk, TYPE *ptr);
STACK_OF(X509) *sk_X509_deep_copy(STACK_OF(X509) *sk, int sk_TYPE_find_ex(STACK_OF(TYPE) *sk, TYPE *ptr);
X509 * (*copyfn) (const X509 *), void sk_TYPE_sort(const STACK_OF(TYPE) *sk);
void (*freefn) (X509 *)); int sk_TYPE_is_sorted(const STACK_OF(TYPE) *sk);
STACK_OF(TYPE) *sk_TYPE_dup(STACK_OF(TYPE) *sk);
STACK_OF(TYPE) *sk_TYPE_deep_copy(STACK_OF(TYPE) *sk,
sk_TYPE_copyfunc copyfunc,
sk_TYPE_freefunc freefunc);
sk_TYPE_compfunc (*sk_TYPE_set_cmp_func(STACK_OF(TYPE) *sk, sk_TYPE_compfunc compare);
=head1 DESCRIPTION =head1 DESCRIPTION
sk_X509_num() returns the number of elements in B<sk> or -1 if B<sk> is Applications can create and use their own stacks by placing any of the macros
described below in a header file. In the description below, I<TYPE> is used
as a placeholder for any of the OpenSSL datatypes, such as I<X509>.
DEFINE_STACK_OF(TYPE) creates set of functions for a stack of B<TYPE>. This
will mean that type B<TYPE> is stored in each stack, the type is referenced by
STACK_OF(TYPE) and each function name begins with I<sk_TYPE_>. For example:
TYPE *sk_TYPE_value(STACK_OF(TYPE) *sk, int idx);
DEFINE_STACK_OF_CONST(TYPE) is identical to DEFINE_STACK_OF(TYPE) except
each element is constant. For example:
const TYPE *sk_TYPE_value(STACK_OF(TYPE) *sk, int idx);
DEFINE_SPECIAL_STACK_OF(FUNCNAME, TYPE) defines a stack of B<TYPE> but
each function uses B<FUNCNAME> in the function name. For example:
TYPE *sk_FUNCNAME_value(STACK_OF(TYPE) *sk, int idx);
sk_TYPE_num() returns the number of elements in B<sk> or -1 if B<sk> is
B<NULL>. B<NULL>.
sk_X509_value() returns element B<idx> in B<sk>. Where B<idx> runs from 0 sk_TYPE_value() returns element B<idx> in B<sk>, where B<idx> starts at
to sk_X509_num(sk) - 1 inclusive. If B<idx> is out of range then B<NULL> zero. If B<idx> is out of range then B<NULL> is returned.
is returned.
sk_X509_new() allocates a new empty stack using comparison function B<cmpf>. sk_TYPE_new() allocates a new empty stack using comparison function B<compar>.
If B<cmpf> is B<0> then no comparison function is used. If B<compar> is B<NULL> then no comparison function is used.
sk_X509_new_null() allocates a new empty stack with no comparison function. sk_TYPE_new_null() allocates a new empty stack with no comparison function.
sk_X509_set_cmp_func() sets the comparison function of B<sk> to B<cmpf>. sk_TYPE_set_cmp_func() sets the comparison function of B<sk> to B<compar>.
The previous comparison function is returned or B<0> if there was The previous comparison function is returned or B<NULL> if there was
no previous comparison function. no previous comparison function.
sk_X509_free() frees up the B<sk> structure. It does B<not> free up any sk_TYPE_free() frees up the B<sk> structure. It does B<not> free up any
elements of B<sk>. After this call B<sk> is no longer valid. elements of B<sk>. After this call B<sk> is no longer valid.
sk_X509_zero() sets the number of elements in B<sk> to zero. It does not free sk_TYPE_zero() sets the number of elements in B<sk> to zero. It does not free
B<sk> so after this call B<sk> is still valid. B<sk> so after this call B<sk> is still valid.
sk_X509_pop_free() frees up all elements of B<sk> and B<sk> itself. The sk_TYPE_pop_free() frees up all elements of B<sk> and B<sk> itself. The
free function func() is called on each element to free it. free function freefunc() is called on each element to free it.
sk_X509_delete() deletes element B<i> from B<sk>. It returns the deleted sk_TYPE_delete() deletes element B<i> from B<sk>. It returns the deleted
element or B<NULL> if B<i> is out of range. element or B<NULL> if B<i> is out of range.
sk_X509_delete_ptr() deletes element matching B<ptr> from B<sk>. It returns sk_TYPE_delete_ptr() deletes element matching B<ptr> from B<sk>. It returns
the deleted element or B<NULL> if no element matching B<ptr> was found. the deleted element or B<NULL> if no element matching B<ptr> was found.
sk_X509_insert() inserts B<ptr> into B<sk> at position B<idx>. Any existing sk_TYPE_insert() inserts B<ptr> into B<sk> at position B<idx>. Any existing
elements at or after B<idx> are moved downwards. If B<idx> is out of range elements at or after B<idx> are moved downwards. If B<idx> is out of range
the new element is appended to B<sk>. sk_X509_insert() either returns the the new element is appended to B<sk>. sk_TYPE_insert() either returns the
number of elements in B<sk> after the new element is inserted or zero if number of elements in B<sk> after the new element is inserted or zero if
an error occurred: which will happen if there is a memory allocation failure. an error (such as memory allocation failure) occurred.
sk_X509_push() appends B<ptr> to B<sk> it is equivalent to: sk_TYPE_push() appends B<ptr> to B<sk> it is equivalent to:
sk_X509_insert(sk, ptr, -1); sk_TYPE_insert(sk, ptr, -1);
sk_X509_unshift() inserts B<ptr> at the start of B<sk> it is equivalent to: sk_TYPE_unshift() inserts B<ptr> at the start of B<sk> it is equivalent to:
sk_X509_insert(sk, ptr, 0); sk_TYPE_insert(sk, ptr, 0);
sk_X509_pop() returns and removes the last element from B<sk>. sk_TYPE_pop() returns and removes the last element from B<sk>.
sk_X509_shift() returns and removes the first element from B<sk>. sk_TYPE_shift() returns and removes the first element from B<sk>.
sk_X509_set() sets element B<idx> of B<sk> to B<ptr> replacing the current sk_TYPE_set() sets element B<idx> of B<sk> to B<ptr> replacing the current
element. The new element value is returned or B<NULL> if an error occurred: element. The new element value is returned or B<NULL> if an error occurred:
this will only happen if B<sk> is B<NULL> or B<idx> is out of range. this will only happen if B<sk> is B<NULL> or B<idx> is out of range.
sk_X509_find() and int sk_X509_find_ex() search B<sk> using the supplied sk_TYPE_find() and sk_TYPE_find_ex() search B<sk> using the supplied
comparison function for an element matching B<ptr>. sk_X509_find() returns comparison function for an element matching B<ptr>. sk_TYPE_find() returns
the index of the first matching element or B<-1> if there is no match. the index of the first matching element or B<-1> if there is no match.
sk_X509_find_ex() returns a matching element or the nearest element that sk_TYPE_find_ex() returns a matching element or the nearest element that
does not match B<ptr>. Note: if a comparison function is set then B<sk> is does not match B<ptr>. Note: if a comparison function is set then B<sk> is
sorted before the search which may change its order. If no comparison sorted before the search which may change its order. If no comparison
function is set then a linear search is made for a pointer matching B<ptr> function is set then a linear search is made for a pointer matching B<ptr>
and the stack is not reordered. and the stack is not reordered.
sk_X509_sort() sorts B<sk> using the supplied comparison function. sk_TYPE_sort() sorts B<sk> using the supplied comparison function.
sk_X509_is_sorted() returns B<1> if B<sk> is sorted and B<0> otherwise. sk_TYPE_is_sorted() returns B<1> if B<sk> is sorted and B<0> otherwise.
sk_X509_dup() returns a copy of B<sk>. Note the pointers in the copy sk_TYPE_dup() returns a copy of B<sk>. Note the pointers in the copy
are identical to the original. are identical to the original.
sk_X509_deep_copy() returns a new stack where each element has been copied. sk_TYPE_deep_copy() returns a new stack where each element has been copied.
Copying is performed by the supplied copyfn() and freeing by freefn(). The Copying is performed by the supplied copyfunc() and freeing by freefunc(). The
function freefn() is only called if an error occurs. function freefunc() is only called if an error occurs.
=head1 NOTES =head1 NOTES
This manual page documents the functions which operate on a stack of
B<X509> pointers. A stack can contain pointers to any structure with B<X509>
replaced by the appropriate structure name.
Care should be taken when accessing stacks in multi-threaded environments. Care should be taken when accessing stacks in multi-threaded environments.
Any operation which increases the size of a stack such as sk_X509_insert() or Any operation which increases the size of a stack such as sk_TYPE_insert() or
sk_push() can "grow" the size of an internal array and cause race conditions sk_push() can "grow" the size of an internal array and cause race conditions
if the same stack is accessed in a different thread. Operations such as if the same stack is accessed in a different thread. Operations such as
sk_find() and sk_sort() can also reorder the stack. sk_find() and sk_sort() can also reorder the stack.
...@@ -134,76 +156,53 @@ positive or negative value if B<a> is equal to, greater than ...@@ -134,76 +156,53 @@ positive or negative value if B<a> is equal to, greater than
or less than B<b> respectively. or less than B<b> respectively.
Care should be taken when checking the return values of the functions Care should be taken when checking the return values of the functions
sk_X509_find() and sk_X509_find_ex(). They return an index to the sk_TYPE_find() and sk_TYPE_find_ex(). They return an index to the
matching element. In particular B<0> indicates a matching first element. matching element. In particular B<0> indicates a matching first element.
A failed search is indicated by a B<-1> return value. A failed search is indicated by a B<-1> return value.
=head1 APPLICATION DEFINED STACKS
Applications can create and use their own stacks by placing any of the macros
described below in a header file.
DEFINE_STACK_OF(NAME) creates set of functions for a stack of B<NAME>. This
will mean that type B<NAME> is stored in each stack, the type is referenced by
STACK_OF(NAME) and each function name begins with sk_NAME_. For example:
NAME *sk_NAME_value(STACK_OF(NAME) *sk, int idx);
DEFINE_STACK_OF_CONST(NAME) is identical to DEFINE_STACK_OF(NAME) except
each element is constant for example:
const NAME *sk_name_value(STACK_OF(NAME) *sk, int idx);
DEFINE_SPECIAL_STACK_OF(FNAME, STNAME) defines a stack of B<STNAME> but
each function uses B<FNAME>. For example:
STNAME *sk_FNAME_value(STACK_OF(STNAME) *sk, int idx);
=head1 RETURN VALUES =head1 RETURN VALUES
sk_X509_num() returns the number of elements in the stack or B<-1> if the sk_TYPE_num() returns the number of elements in the stack or B<-1> if the
passed stack is B<NULL>. passed stack is B<NULL>.
sk_X509_value() returns a pointer to a stack element or B<NULL> if the sk_TYPE_value() returns a pointer to a stack element or B<NULL> if the
index is out of range. index is out of range.
sk_X509_new() and sk_X509_new_null() return an empty stack or B<NULL> if sk_TYPE_new() and sk_TYPE_new_null() return an empty stack or B<NULL> if
an error occurs. an error occurs.
sk_X509_set_cmp_func() returns the old comparison function or B<NULL> if sk_TYPE_set_cmp_func() returns the old comparison function or B<NULL> if
there was no old comparison function. there was no old comparison function.
sk_X509_free(), sk_X509_zero(), sk_X509_pop_free() and sk_X509_sort() do sk_TYPE_free(), sk_TYPE_zero(), sk_TYPE_pop_free() and sk_TYPE_sort() do
not return values. not return values.
sk_X509_pop(), sk_X509_shift(), sk_X509_delete() and sk_X509_delete_ptr() sk_TYPE_pop(), sk_TYPE_shift(), sk_TYPE_delete() and sk_TYPE_delete_ptr()
return a pointer to the deleted element or B<NULL> on error. return a pointer to the deleted element or B<NULL> on error.
sk_X509_insert(), sk_X509_push() and sk_X509_unshift() return the total sk_TYPE_insert(), sk_TYPE_push() and sk_TYPE_unshift() return the total
number of elements in the stack and 0 if an error occurred. number of elements in the stack and 0 if an error occurred.
sk_X509_set() returns a pointer to the replacement element or B<NULL> on sk_TYPE_set() returns a pointer to the replacement element or B<NULL> on
error. error.
sk_X509_find() and sk_X509_find_ex() return an index to the found element sk_TYPE_find() and sk_TYPE_find_ex() return an index to the found element
or B<-1> on error. or B<-1> on error.
sk_X509_is_sorted() returns B<1> if the stack is sorted and B<0> if it is sk_TYPE_is_sorted() returns B<1> if the stack is sorted and B<0> if it is
not. not.
sk_X509_dup() and sk_X509_deep_copy() return a pointer to the copy of the sk_TYPE_dup() and sk_TYPE_deep_copy() return a pointer to the copy of the
stack. stack.
=head1 HISTORY =head1 HISTORY
Use of inline functions and application defined stacks first appeared in Before OpenSSL 1.1.0, this was implemented via macros and not inline functions
OpenSSL 1.1.0. Previous versions of OpenSSL implemented stacks as macros. and was not a public API.
=cut
=head1 COPYRIGHT =head1 COPYRIGHT
Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy this file except in compliance with the License. You can obtain a copy
......
...@@ -21,16 +21,12 @@ ...@@ -21,16 +21,12 @@
extern "C" { extern "C" {
#endif #endif
typedef struct lhash_node_st { typedef struct lhash_node_st OPENSSL_LH_NODE;
void *data; typedef int (*OPENSSL_LH_COMPFUNC) (const void *, const void *);
struct lhash_node_st *next; typedef unsigned long (*OPENSSL_LH_HASHFUNC) (const void *);
unsigned long hash; typedef void (*OPENSSL_LH_DOALL_FUNC) (void *);
} LHASH_NODE; typedef void (*OPENSSL_LH_DOALL_FUNCARG) (void *, void *);
typedef struct lhash_st OPENSSL_LHASH;
typedef int (*LHASH_COMP_FN_TYPE) (const void *, const void *);
typedef unsigned long (*LHASH_HASH_FN_TYPE) (const void *);
typedef void (*LHASH_DOALL_FN_TYPE) (void *);
typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *);
/* /*
* Macros for declaring and implementing type-safe wrappers for LHASH * Macros for declaring and implementing type-safe wrappers for LHASH
...@@ -70,62 +66,53 @@ typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *); ...@@ -70,62 +66,53 @@ typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *);
name##_doall_arg(a, b); } name##_doall_arg(a, b); }
# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG # define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
typedef struct lhash_st {
LHASH_NODE **b;
LHASH_COMP_FN_TYPE comp;
LHASH_HASH_FN_TYPE hash;
unsigned int num_nodes;
unsigned int num_alloc_nodes;
unsigned int p;
unsigned int pmax;
unsigned long up_load; /* load times 256 */
unsigned long down_load; /* load times 256 */
unsigned long num_items;
unsigned long num_expands;
unsigned long num_expand_reallocs;
unsigned long num_contracts;
unsigned long num_contract_reallocs;
unsigned long num_hash_calls;
unsigned long num_comp_calls;
unsigned long num_insert;
unsigned long num_replace;
unsigned long num_delete;
unsigned long num_no_delete;
unsigned long num_retrieve;
unsigned long num_retrieve_miss;
unsigned long num_hash_comps;
int error;
} _LHASH; /* Do not use _LHASH directly, use LHASH_OF
* and friends */
# define LH_LOAD_MULT 256 # define LH_LOAD_MULT 256
/* int OPENSSL_LH_error(OPENSSL_LHASH *lh);
* Indicates a malloc() error in the last call, this is only bad in OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c);
* lh_insert(). void OPENSSL_LH_free(OPENSSL_LHASH *lh);
*/ void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data);
int lh_error(_LHASH *lh); void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data);
void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data);
_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func);
void lh_free(_LHASH *lh); void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg);
void *lh_insert(_LHASH *lh, void *data); unsigned long OPENSSL_LH_strhash(const char *c);
void *lh_delete(_LHASH *lh, const void *data); unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh);
void *lh_retrieve(_LHASH *lh, const void *data); unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh);
void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func); void OPENSSL_LH_set_down_load(OPENSSL_LHASH *lh, unsigned long down_load);
void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
unsigned long lh_strhash(const char *c);
unsigned long lh_num_items(const _LHASH *lh);
unsigned long lh_get_down_load(const _LHASH *lh);
void lh_set_down_load(_LHASH *lh, unsigned long down_load);
# ifndef OPENSSL_NO_STDIO # ifndef OPENSSL_NO_STDIO
void lh_stats(const _LHASH *lh, FILE *fp); void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp);
void lh_node_stats(const _LHASH *lh, FILE *fp); void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp);
void lh_node_usage_stats(const _LHASH *lh, FILE *fp); void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp);
# endif
void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out);
void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out);
void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out);
# if OPENSSL_API_COMPAT < 0x10100000L
# define _LHASH OPENSSL_LHASH
# define LHASH_NODE OPENSSL_LH_NODE
# define lh_error OPENSSL_LH_error
# define lh_new OPENSSL_lh_new
# define lh_free OPENSSL_LH_free
# define lh_insert OPENSSL_LH_insert
# define lh_delete OPENSSL_LH_delete
# define lh_retrieve OPENSSL_LH_retrieve
# define lh_doall OPENSSL_LH_doall
# define lh_doall_arg OPENSSL_LH_doall_arg
# define lh_strhash OPENSSL_LH_strhash
# define lh_num_items OPENSSL_LH_num_items
# ifndef OPENSSL_NO_STDIO
# define lh_stats OPENSSL_LH_stats
# define lh_node_stats OPENSSL_LH_node_stats
# define lh_node_usage_stats OPENSSL_LH_node_usage_stats
# endif
# define lh_stats_bio OPENSSL_LH_stats_bio
# define lh_node_stats_bio OPENSSL_LH_node_stats_bio
# define lh_node_usage_stats_bio OPENSSL_LH_node_usage_stats_bio
# endif # endif
void lh_stats_bio(const _LHASH *lh, BIO *out);
void lh_node_stats_bio(const _LHASH *lh, BIO *out);
void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
/* Type checking... */ /* Type checking... */
...@@ -138,56 +125,56 @@ void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out); ...@@ -138,56 +125,56 @@ void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
int (*cfn)(const type *, const type *)) \ int (*cfn)(const type *, const type *)) \
{ \ { \
return (LHASH_OF(type) *) \ return (LHASH_OF(type) *) \
lh_new((LHASH_HASH_FN_TYPE) hfn, (LHASH_COMP_FN_TYPE)cfn); \ OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \
} \ } \
static ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \ static ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \
{ \ { \
lh_free((_LHASH *)lh); \ OPENSSL_LH_free((OPENSSL_LHASH *)lh); \
} \ } \
static ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \ static ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \
{ \ { \
return (type *)lh_insert((_LHASH *)lh, d); \ return (type *)OPENSSL_LH_insert((OPENSSL_LHASH *)lh, d); \
} \ } \
static ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \ static ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \
{ \ { \
return (type *)lh_delete((_LHASH *)lh, d); \ return (type *)OPENSSL_LH_delete((OPENSSL_LHASH *)lh, d); \
} \ } \
static ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \ static ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \
{ \ { \
return (type *)lh_retrieve((_LHASH *)lh, d); \ return (type *)OPENSSL_LH_retrieve((OPENSSL_LHASH *)lh, d); \
} \ } \
static ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \ static ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \
{ \ { \
return lh_error((_LHASH *)lh); \ return OPENSSL_LH_error((OPENSSL_LHASH *)lh); \
} \ } \
static ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \ static ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \
{ \ { \
return lh_num_items((_LHASH *)lh); \ return OPENSSL_LH_num_items((OPENSSL_LHASH *)lh); \
} \ } \
static ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ static ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \
{ \ { \
lh_node_stats_bio((_LHASH *)lh, out); \ OPENSSL_LH_node_stats_bio((OPENSSL_LHASH *)lh, out); \
} \ } \
static ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ static ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \
{ \ { \
lh_node_usage_stats_bio((_LHASH *)lh, out); \ OPENSSL_LH_node_usage_stats_bio((OPENSSL_LHASH *)lh, out); \
} \ } \
static ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ static ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \
{ \ { \
lh_stats_bio((_LHASH *)lh, out); \ OPENSSL_LH_stats_bio((OPENSSL_LHASH *)lh, out); \
} \ } \
static ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \ static ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \
{ \ { \
return lh_get_down_load((_LHASH *)lh); \ return OPENSSL_LH_get_down_load((OPENSSL_LHASH *)lh); \
} \ } \
static ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \ static ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \
{ \ { \
lh_set_down_load((_LHASH *)lh, dl); \ OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl); \
} \ } \
static ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \ static ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \
void (*doall)(type *)) \ void (*doall)(type *)) \
{ \ { \
lh_doall((_LHASH *)lh, (LHASH_DOALL_FN_TYPE)doall); \ OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall); \
} \ } \
LHASH_OF(type) LHASH_OF(type)
...@@ -203,17 +190,10 @@ void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out); ...@@ -203,17 +190,10 @@ void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
void (*fn)(cbargtype *, argtype *), \ void (*fn)(cbargtype *, argtype *), \
argtype *arg) \ argtype *arg) \
{ \ { \
lh_doall_arg((_LHASH *)lh, (LHASH_DOALL_ARG_FN_TYPE)fn, (void *)arg); \ OPENSSL_LH_doall_arg((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNCARG)fn, (void *)arg); \
} \ } \
LHASH_OF(type) LHASH_OF(type)
# define CHECKED_LHASH_OF(type,lh) \
((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh))
/* Define wrapper functions. */
# define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \
lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg))
DEFINE_LHASH_OF(OPENSSL_STRING); DEFINE_LHASH_OF(OPENSSL_STRING);
DEFINE_LHASH_OF(OPENSSL_CSTRING); DEFINE_LHASH_OF(OPENSSL_CSTRING);
......
...@@ -17,124 +17,104 @@ ...@@ -17,124 +17,104 @@
extern "C" { extern "C" {
#endif #endif
# ifndef CHECKED_PTR_OF
# define CHECKED_PTR_OF(type, p) ((void*) (1 ? p : (type*)0))
# endif
/*
* In C++ we get problems because an explicit cast is needed from (void *) we
* use CHECKED_STACK_OF to ensure the correct type is passed in the macros
* below.
*/
# define CHECKED_STACK_OF(type, p) \
((_STACK*) (1 ? p : (STACK_OF(type)*)0))
# define CHECKED_SK_COPY_FUNC(type, p) \
((void *(*)(void *)) ((1 ? p : (type *(*)(const type *))0)))
# define CHECKED_SK_FREE_FUNC(type, p) \
((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))
# define CHECKED_SK_CMP_FUNC(type, p) \
((int (*)(const void *, const void *)) \
((1 ? p : (int (*)(const type * const *, const type * const *))0)))
# define STACK_OF(type) struct stack_st_##type # define STACK_OF(type) struct stack_st_##type
# define SKM_DEFINE_STACK_OF(t1, t2, t3) \ # define SKM_DEFINE_STACK_OF(t1, t2, t3) \
STACK_OF(t1); \ STACK_OF(t1); \
typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \
typedef void (*sk_##t1##_freefunc)(t3 *a); \
typedef t3 * (*sk_##t1##_copyfunc)(const t3 *a); \
static ossl_inline int sk_##t1##_num(const STACK_OF(t1) *sk) \ static ossl_inline int sk_##t1##_num(const STACK_OF(t1) *sk) \
{ \ { \
return sk_num((const _STACK *)sk); \ return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \
} \ } \
static ossl_inline t2 *sk_##t1##_value(const STACK_OF(t1) *sk, int idx) \ static ossl_inline t2 *sk_##t1##_value(const STACK_OF(t1) *sk, int idx) \
{ \ { \
return (t2 *)sk_value((const _STACK *)sk, idx); \ return (t2 *)OPENSSL_sk_value((const OPENSSL_STACK *)sk, idx); \
} \ } \
static ossl_inline STACK_OF(t1) *sk_##t1##_new(int (*cmpf)(const t3 * const *a, const t3 * const *b)) \ static ossl_inline STACK_OF(t1) *sk_##t1##_new(sk_##t1##_compfunc compare) \
{ \ { \
return (STACK_OF(t1) *)sk_new((int (*)(const void *a, const void *b))cmpf); \ return (STACK_OF(t1) *)OPENSSL_sk_new((OPENSSL_sk_compfunc)compare); \
} \ } \
static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \
{ \ { \
return (STACK_OF(t1) *)sk_new_null(); \ return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \
} \ } \
static ossl_inline void sk_##t1##_free(STACK_OF(t1) *sk) \ static ossl_inline void sk_##t1##_free(STACK_OF(t1) *sk) \
{ \ { \
sk_free((_STACK *)sk); \ OPENSSL_sk_free((OPENSSL_STACK *)sk); \
} \ } \
static ossl_inline void sk_##t1##_zero(STACK_OF(t1) *sk) \ static ossl_inline void sk_##t1##_zero(STACK_OF(t1) *sk) \
{ \ { \
sk_zero((_STACK *)sk); \ OPENSSL_sk_zero((OPENSSL_STACK *)sk); \
} \ } \
static ossl_inline t2 *sk_##t1##_delete(STACK_OF(t1) *sk, int i) \ static ossl_inline t2 *sk_##t1##_delete(STACK_OF(t1) *sk, int i) \
{ \ { \
return (t2 *)sk_delete((_STACK *)sk, i); \ return (t2 *)OPENSSL_sk_delete((OPENSSL_STACK *)sk, i); \
} \ } \
static ossl_inline t2 *sk_##t1##_delete_ptr(STACK_OF(t1) *sk, t2 *ptr) \ static ossl_inline t2 *sk_##t1##_delete_ptr(STACK_OF(t1) *sk, t2 *ptr) \
{ \ { \
return (t2 *)sk_delete_ptr((_STACK *)sk, (void *)ptr); \ return (t2 *)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, (void *)ptr); \
} \ } \
static ossl_inline int sk_##t1##_push(STACK_OF(t1) *sk, t2 *ptr) \ static ossl_inline int sk_##t1##_push(STACK_OF(t1) *sk, t2 *ptr) \
{ \ { \
return sk_push((_STACK *)sk, (void *)ptr); \ return OPENSSL_sk_push((OPENSSL_STACK *)sk, (void *)ptr); \
} \ } \
static ossl_inline int sk_##t1##_unshift(STACK_OF(t1) *sk, t2 *ptr) \ static ossl_inline int sk_##t1##_unshift(STACK_OF(t1) *sk, t2 *ptr) \
{ \ { \
return sk_unshift((_STACK *)sk, (void *)ptr); \ return OPENSSL_sk_unshift((OPENSSL_STACK *)sk, (void *)ptr); \
} \ } \
static ossl_inline t2 *sk_##t1##_pop(STACK_OF(t1) *sk) \ static ossl_inline t2 *sk_##t1##_pop(STACK_OF(t1) *sk) \
{ \ { \
return (t2 *)sk_pop((_STACK *)sk); \ return (t2 *)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \
} \ } \
static ossl_inline t2 *sk_##t1##_shift(STACK_OF(t1) *sk) \ static ossl_inline t2 *sk_##t1##_shift(STACK_OF(t1) *sk) \
{ \ { \
return (t2 *)sk_shift((_STACK *)sk); \ return (t2 *)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \
} \ } \
static ossl_inline void sk_##t1##_pop_free(STACK_OF(t1) *sk, void (*func)(t3 *a)) \ static ossl_inline void sk_##t1##_pop_free(STACK_OF(t1) *sk, sk_##t1##_freefunc freefunc) \
{ \ { \
sk_pop_free((_STACK *)sk, (void (*)(void *))func); \ OPENSSL_sk_pop_free((OPENSSL_STACK *)sk, (OPENSSL_sk_freefunc)freefunc); \
} \ } \
static ossl_inline int sk_##t1##_insert(STACK_OF(t1) *sk, t2 *ptr, int idx) \ static ossl_inline int sk_##t1##_insert(STACK_OF(t1) *sk, t2 *ptr, int idx) \
{ \ { \
return sk_insert((_STACK *)sk, (void *)ptr, idx); \ return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (void *)ptr, idx); \
} \ } \
static ossl_inline t2 *sk_##t1##_set(STACK_OF(t1) *sk, int idx, t2 *ptr) \ static ossl_inline t2 *sk_##t1##_set(STACK_OF(t1) *sk, int idx, t2 *ptr) \
{ \ { \
return (t2 *)sk_set((_STACK *)sk, idx, (void *)ptr); \ return (t2 *)OPENSSL_sk_set((OPENSSL_STACK *)sk, idx, (void *)ptr); \
} \ } \
static ossl_inline int sk_##t1##_find(STACK_OF(t1) *sk, t2 *ptr) \ static ossl_inline int sk_##t1##_find(STACK_OF(t1) *sk, t2 *ptr) \
{ \ { \
return sk_find((_STACK *)sk, (void *)ptr); \ return OPENSSL_sk_find((OPENSSL_STACK *)sk, (void *)ptr); \
} \ } \
static ossl_inline int sk_##t1##_find_ex(STACK_OF(t1) *sk, t2 *ptr) \ static ossl_inline int sk_##t1##_find_ex(STACK_OF(t1) *sk, t2 *ptr) \
{ \ { \
return sk_find_ex((_STACK *)sk, (void *)ptr); \ return OPENSSL_sk_find_ex((OPENSSL_STACK *)sk, (void *)ptr); \
} \ } \
static ossl_inline void sk_##t1##_sort(STACK_OF(t1) *sk) \ static ossl_inline void sk_##t1##_sort(STACK_OF(t1) *sk) \
{ \ { \
sk_sort((_STACK *)sk); \ OPENSSL_sk_sort((OPENSSL_STACK *)sk); \
} \ } \
static ossl_inline int sk_##t1##_is_sorted(const STACK_OF(t1) *sk) \ static ossl_inline int sk_##t1##_is_sorted(const STACK_OF(t1) *sk) \
{ \ { \
return sk_is_sorted((const _STACK *)sk); \ return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \
} \ } \
static ossl_inline STACK_OF(t1) * sk_##t1##_dup(STACK_OF(t1) *sk) \ static ossl_inline STACK_OF(t1) * sk_##t1##_dup(STACK_OF(t1) *sk) \
{ \ { \
return (STACK_OF(t1) *)sk_dup((_STACK *)sk); \ return (STACK_OF(t1) *)OPENSSL_sk_dup((OPENSSL_STACK *)sk); \
} \ } \
static ossl_inline STACK_OF(t1) *sk_##t1##_deep_copy(STACK_OF(t1) *sk, \ static ossl_inline STACK_OF(t1) *sk_##t1##_deep_copy(STACK_OF(t1) *sk, \
t3 *(*copyfn)(const t3 *), \ sk_##t1##_copyfunc copyfunc, \
void (*freefn)(t3 *)) \ sk_##t1##_freefunc freefunc) \
{ \ { \
return (STACK_OF(t1) *)sk_deep_copy((_STACK *)sk, \ return (STACK_OF(t1) *)OPENSSL_sk_deep_copy((OPENSSL_STACK *)sk, \
(void * (*)(void *a))copyfn, \ (OPENSSL_sk_copyfunc)copyfunc, \
(void (*)(void *a))freefn); \ (OPENSSL_sk_freefunc)freefunc); \
} \ } \
static ossl_inline int (*sk_##t1##_set_cmp_func(STACK_OF(t1) *sk, int (*cmpf)(const t3 * const *a, const t3 * const *b)))(const t3 * const *, const t3 * const *) \ static ossl_inline sk_##t1##_compfunc sk_##t1##_set_cmp_func(STACK_OF(t1) *sk, sk_##t1##_compfunc compare) \
{ \ { \
return (int (*)(const t3 * const *,const t3 * const *))sk_set_cmp_func((_STACK *)sk, (int (*)(const void *a, const void *b))cmpf); \ return (sk_##t1##_compfunc)OPENSSL_sk_set_cmp_func((OPENSSL_STACK *)sk, (OPENSSL_sk_compfunc)compare); \
} }
# define DEFINE_SPECIAL_STACK_OF(t1, t2) SKM_DEFINE_STACK_OF(t1, t2, t2) # define DEFINE_SPECIAL_STACK_OF(t1, t2) SKM_DEFINE_STACK_OF(t1, t2, t2)
......
...@@ -14,33 +14,62 @@ ...@@ -14,33 +14,62 @@
extern "C" { extern "C" {
#endif #endif
typedef struct stack_st _STACK; /* Use STACK_OF(...) instead */ typedef struct stack_st OPENSSL_STACK; /* Use STACK_OF(...) instead */
int sk_num(const _STACK *); typedef int (*OPENSSL_sk_compfunc)(const void *, const void *);
void *sk_value(const _STACK *, int); typedef void (*OPENSSL_sk_freefunc)(void *);
typedef void *(*OPENSSL_sk_copyfunc)(const void *);
void *sk_set(_STACK *, int, void *);
int OPENSSL_sk_num(const OPENSSL_STACK *);
_STACK *sk_new(int (*cmp) (const void *, const void *)); void *OPENSSL_sk_value(const OPENSSL_STACK *, int);
_STACK *sk_new_null(void);
void sk_free(_STACK *); void *OPENSSL_sk_set(OPENSSL_STACK *, int, void *);
void sk_pop_free(_STACK *st, void (*func) (void *));
_STACK *sk_deep_copy(_STACK *, void *(*)(void *), void (*)(void *)); OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc cmp);
int sk_insert(_STACK *sk, void *data, int where); OPENSSL_STACK *OPENSSL_sk_new_null(void);
void *sk_delete(_STACK *st, int loc); void OPENSSL_sk_free(OPENSSL_STACK *);
void *sk_delete_ptr(_STACK *st, void *p); void OPENSSL_sk_pop_free(OPENSSL_STACK *st, void (*func) (void *));
int sk_find(_STACK *st, void *data); OPENSSL_STACK *OPENSSL_sk_deep_copy(OPENSSL_STACK *, OPENSSL_sk_copyfunc c, OPENSSL_sk_freefunc f);
int sk_find_ex(_STACK *st, void *data); int OPENSSL_sk_insert(OPENSSL_STACK *sk, void *data, int where);
int sk_push(_STACK *st, void *data); void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc);
int sk_unshift(_STACK *st, void *data); void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, void *p);
void *sk_shift(_STACK *st); int OPENSSL_sk_find(OPENSSL_STACK *st, void *data);
void *sk_pop(_STACK *st); int OPENSSL_sk_find_ex(OPENSSL_STACK *st, void *data);
void sk_zero(_STACK *st); int OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *))) int OPENSSL_sk_unshift(OPENSSL_STACK *st, void *data);
(const void *, const void *); void *OPENSSL_sk_shift(OPENSSL_STACK *st);
_STACK *sk_dup(_STACK *st); void *OPENSSL_sk_pop(OPENSSL_STACK *st);
void sk_sort(_STACK *st); void OPENSSL_sk_zero(OPENSSL_STACK *st);
int sk_is_sorted(const _STACK *st); OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_compfunc cmp);
OPENSSL_STACK *OPENSSL_sk_dup(OPENSSL_STACK *st);
void OPENSSL_sk_sort(OPENSSL_STACK *st);
int OPENSSL_sk_is_sorted(const OPENSSL_STACK *st);
# if OPENSSL_API_COMPAT < 0x10100000L
# define _STACK OPENSSL_STACK
# define sk_num OPENSSL_sk_num
# define sk_value OPENSSL_sk_value
# define sk_set OPENSSL_sk_set
# define sk_new OPENSSL_sk_new
# define sk_new_null OPENSSL_sk_new_null
# define sk_free OPENSSL_sk_free
# define sk_pop_free OPENSSL_sk_pop_free
# define sk_deep_copy OPENSSL_sk_deep_copy
# define sk_insert OPENSSL_sk_insert
# define sk_delete OPENSSL_sk_delete
# define sk_delete_ptr OPENSSL_sk_delete_ptr
# define sk_find OPENSSL_sk_find
# define sk_find_ex OPENSSL_sk_find_ex
# define sk_push OPENSSL_sk_push
# define sk_unshift OPENSSL_sk_unshift
# define sk_shift OPENSSL_sk_shift
# define sk_pop OPENSSL_sk_pop
# define sk_zero OPENSSL_sk_zero
# define sk_set_cmp_func OPENSSL_sk_set_cmp_func
# define sk_dup OPENSSL_sk_dup
# define sk_sort OPENSSL_sk_sort
# define sk_is_sorted OPENSSL_sk_is_sorted
# endif
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -44,7 +44,7 @@ typedef struct txt_db_st { ...@@ -44,7 +44,7 @@ typedef struct txt_db_st {
TXT_DB *TXT_DB_read(BIO *in, int num); TXT_DB *TXT_DB_read(BIO *in, int num);
long TXT_DB_write(BIO *out, TXT_DB *db); long TXT_DB_write(BIO *out, TXT_DB *db);
int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp); OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC cmp);
void TXT_DB_free(TXT_DB *db); void TXT_DB_free(TXT_DB *db);
OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx,
OPENSSL_STRING *value); OPENSSL_STRING *value);
......
...@@ -977,10 +977,10 @@ void SSL_CTX_flush_sessions(SSL_CTX *s, long t) ...@@ -977,10 +977,10 @@ void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
return; return;
tp.time = t; tp.time = t;
CRYPTO_THREAD_write_lock(s->lock); CRYPTO_THREAD_write_lock(s->lock);
i = CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; i = lh_SSL_SESSION_get_down_load(s->sessions);
CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = 0; lh_SSL_SESSION_set_down_load(s->sessions, 0);
lh_SSL_SESSION_doall_TIMEOUT_PARAM(tp.cache, timeout_cb, &tp); lh_SSL_SESSION_doall_TIMEOUT_PARAM(tp.cache, timeout_cb, &tp);
CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = i; lh_SSL_SESSION_set_down_load(s->sessions, i);
CRYPTO_THREAD_unlock(s->lock); CRYPTO_THREAD_unlock(s->lock);
} }
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册