mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 14:07:59 +00:00
Fully implement callback sources, and add a test program to test it.
This commit is contained in:
@@ -10,6 +10,7 @@ db_test
|
||||
dispatch_tcp_test
|
||||
dispatch_test
|
||||
entropy_test
|
||||
entropy2_test
|
||||
fsaccess_test
|
||||
gxba_test
|
||||
gxbn_test
|
||||
|
@@ -50,6 +50,7 @@ XTARGETS = adb_test \
|
||||
dispatch_tcp_test \
|
||||
dispatch_test \
|
||||
entropy_test \
|
||||
entropy2_test \
|
||||
gxba_test \
|
||||
gxbn_test \
|
||||
hash_test \
|
||||
@@ -90,6 +91,7 @@ SRCS = adb_test.c \
|
||||
dispatch_tcp_test.c \
|
||||
dispatch_test.c \
|
||||
entropy_test.c \
|
||||
entropy2_test.c \
|
||||
gxba_test.c \
|
||||
gxbn_test.c \
|
||||
hash_test.c \
|
||||
@@ -171,6 +173,10 @@ entropy_test: entropy_test.@O@ ${ISCDEPLIBS}
|
||||
${LIBTOOL} ${CC} ${CFLAGS} -o $@ entropy_test.@O@ \
|
||||
${ISCLIBS} ${LIBS}
|
||||
|
||||
entropy2_test: entropy2_test.@O@ ${ISCDEPLIBS}
|
||||
${LIBTOOL} ${CC} ${CFLAGS} -o $@ entropy2_test.@O@ \
|
||||
${ISCLIBS} ${LIBS}
|
||||
|
||||
sock_test: sock_test.@O@ ${ISCDEPLIBS}
|
||||
${LIBTOOL} ${CC} ${CFLAGS} -o $@ sock_test.@O@ \
|
||||
${ISCLIBS} ${LIBS}
|
||||
|
152
bin/tests/entropy2_test.c
Normal file
152
bin/tests/entropy2_test.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2000 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <isc/entropy.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/util.h>
|
||||
#include <isc/string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static void
|
||||
hex_dump(const char *msg, void *data, unsigned int length) {
|
||||
unsigned int len;
|
||||
unsigned char *base;
|
||||
isc_boolean_t first = ISC_TRUE;
|
||||
|
||||
base = data;
|
||||
|
||||
printf("DUMP of %d bytes: %s\n\t", length, msg);
|
||||
for (len = 0 ; len < length ; len++) {
|
||||
if (len % 16 == 0 && !first)
|
||||
printf("\n\t");
|
||||
printf("%02x ", base[len]);
|
||||
first = ISC_FALSE;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
CHECK(const char *msg, isc_result_t result) {
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
printf("FAILURE: %s: %s\n", msg, isc_result_totext(result));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
start(isc_entropysource_t *source, void *arg, isc_boolean_t blocking)
|
||||
{
|
||||
printf("start called, non-blocking mode.\n");
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
stop(isc_entropysource_t *source, void *arg) {
|
||||
printf("stop called\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is by no way a good one to actually add entropy into
|
||||
* the system. It is intended to fool the entropy system into beliving
|
||||
* there are actual bits from us.
|
||||
*/
|
||||
static isc_result_t
|
||||
get(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) {
|
||||
isc_result_t result;
|
||||
static isc_uint32_t val = 1;
|
||||
static int count = 0;
|
||||
|
||||
/*
|
||||
* Here, we should check to see if we are in blocking mode or not.
|
||||
* If we will block and the application asked us not to,
|
||||
* we should return an error instead, rather than block.
|
||||
*/
|
||||
if (!blocking) {
|
||||
count++;
|
||||
if (count > 6)
|
||||
return (ISC_R_NOENTROPY);
|
||||
}
|
||||
|
||||
do {
|
||||
if (val == 0)
|
||||
val = 0x12345678;
|
||||
val <<= 3;
|
||||
val %= 100000;
|
||||
|
||||
result = isc_entropy_addcallbacksample(source, val, 0);
|
||||
} while (result == ISC_R_SUCCESS);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
isc_mem_t *mctx;
|
||||
unsigned char buffer[512];
|
||||
isc_entropy_t *ent;
|
||||
isc_entropysource_t *source;
|
||||
unsigned int returned;
|
||||
unsigned int flags;
|
||||
isc_result_t result;
|
||||
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
mctx = NULL;
|
||||
CHECK("isc_mem_create()",
|
||||
isc_mem_create(0, 0, &mctx));
|
||||
|
||||
ent = NULL;
|
||||
CHECK("isc_entropy_create()",
|
||||
isc_entropy_create(mctx, &ent));
|
||||
|
||||
isc_entropy_stats(ent, stderr);
|
||||
|
||||
source = NULL;
|
||||
result = isc_entropy_createcallbacksource(ent, start, get, stop, NULL,
|
||||
&source);
|
||||
CHECK("isc_entropy_createcallbacksource()", result);
|
||||
|
||||
fprintf(stderr,
|
||||
"Reading 32 bytes of GOOD random data only, partial OK\n");
|
||||
|
||||
flags = 0;
|
||||
flags |= ISC_ENTROPY_GOODONLY;
|
||||
flags |= ISC_ENTROPY_PARTIAL;
|
||||
#if 0
|
||||
flags |= ISC_ENTROPY_BLOCKING;
|
||||
#endif
|
||||
returned = 0;
|
||||
result = isc_entropy_getdata(ent, buffer, 32, &returned, flags);
|
||||
if (result == ISC_R_NOENTROPY) {
|
||||
fprintf(stderr, "No entropy.\n");
|
||||
}
|
||||
hex_dump("good data only:", buffer, returned);
|
||||
|
||||
isc_entropy_stats(ent, stderr);
|
||||
|
||||
isc_entropy_destroysource(&source);
|
||||
isc_entropy_detach(&ent);
|
||||
|
||||
isc_mem_stats(mctx, stderr);
|
||||
isc_mem_destroy(&mctx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@@ -67,15 +67,11 @@ ISC_LANG_BEGINDECLS
|
||||
/*
|
||||
* Entropy callback function.
|
||||
*/
|
||||
typedef isc_result_t (*isc_entropystart_t)(isc_entropy_t *ent,
|
||||
isc_entropysource_t *source,
|
||||
void *arg);
|
||||
typedef isc_result_t (*isc_entropyget_t)(isc_entropy_t *ent,
|
||||
isc_entropysource_t *source,
|
||||
void *arg);
|
||||
typedef void (*isc_entropystop_t)(isc_entropy_t *ent,
|
||||
isc_entropysource_t *source,
|
||||
void *arg);
|
||||
typedef isc_result_t (*isc_entropystart_t)(isc_entropysource_t *source,
|
||||
void *arg, isc_boolean_t blocking);
|
||||
typedef isc_result_t (*isc_entropyget_t)(isc_entropysource_t *source,
|
||||
void *arg, isc_boolean_t blocking);
|
||||
typedef void (*isc_entropystop_t)(isc_entropysource_t *source, void *arg);
|
||||
|
||||
/***
|
||||
*** Flags.
|
||||
@@ -179,12 +175,23 @@ isc_entropy_createcallbacksource(isc_entropy_t *ent,
|
||||
* Create an entropy source that is polled via a callback. This would
|
||||
* be used when keyboard input is used, or a GUI input method. It can
|
||||
* also be used to hook in any external entropy source.
|
||||
*
|
||||
* Samples are added via isc_entropy_addcallbacksample(), below.
|
||||
* _addcallbacksample() is the only function which may be called from
|
||||
* within an entropy API callback function.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_entropy_stopcallbacksources(isc_entropy_t *ent);
|
||||
/*
|
||||
* Call the stop functions for callback sources that have had their
|
||||
* start functions called.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_entropy_addcallbacksample(isc_entropysource_t *source, isc_uint32_t sample,
|
||||
isc_uint32_t extra);
|
||||
isc_result_t
|
||||
isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample,
|
||||
isc_uint32_t extra);
|
||||
/*
|
||||
@@ -195,6 +202,9 @@ isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample,
|
||||
*
|
||||
* The "extra" parameter is used only to add a bit more unpredictable
|
||||
* data. It is not used other than included in the hash of samples.
|
||||
*
|
||||
* When in an entropy API callback function, _addcallbacksource() must be
|
||||
* used. At all other times, _addsample() must be used.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
|
@@ -67,8 +67,8 @@
|
||||
#define ISC_R_MULTICAST 43 /* invalid use of multicast */
|
||||
#define ISC_R_NOTFILE 44 /* not a file */
|
||||
#define ISC_R_NOTDIRECTORY 45 /* not a directory */
|
||||
|
||||
#define ISC_R_NRESULTS 46 /* Number of results */
|
||||
#define ISC_R_QUEUEFULL 46 /* queue is full */
|
||||
#define ISC_R_NRESULTS 47 /* Number of results */
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
|
@@ -81,7 +81,8 @@ static const char *text[ISC_R_NRESULTS] = {
|
||||
"out of entropy", /* 42 */
|
||||
"invalid use of multicast address", /* 43 */
|
||||
"not a file", /* 44 */
|
||||
"not a directory" /* 45 */
|
||||
"not a directory", /* 45 */
|
||||
"queue is full" /* 46 */
|
||||
};
|
||||
|
||||
#define ISC_RESULT_RESULTSET 2
|
||||
|
@@ -177,6 +177,8 @@ samplesource_allocate(isc_entropy_t *ent, sample_queue_t *sq) {
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
sq->nsamples = 0;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -359,20 +361,35 @@ get_from_filesource(isc_entropysource_t *source, isc_uint32_t desired) {
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_from_callback(isc_entropysource_t *source, unsigned int desired) {
|
||||
get_from_callback(isc_entropysource_t *source, unsigned int desired,
|
||||
isc_boolean_t blocking)
|
||||
{
|
||||
isc_entropy_t *ent = source->ent;
|
||||
isc_cbsource_t *cbs = &source->sources.callback;
|
||||
unsigned int added;
|
||||
unsigned int got;
|
||||
isc_result_t result;
|
||||
|
||||
added = 0;
|
||||
while (desired > 0) {
|
||||
if (!cbs->start_called && cbs->startfunc != NULL)
|
||||
cbs->startfunc(ent, source, cbs->arg);
|
||||
result = cbs->getfunc(ent, source, cbs->arg);
|
||||
added += crunchsamples(ent, &cbs->samplequeue);
|
||||
if (desired == 0)
|
||||
return (0);
|
||||
|
||||
desired -= added;
|
||||
if (!cbs->start_called && cbs->startfunc != NULL) {
|
||||
result = cbs->startfunc(source, cbs->arg, blocking);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (0);
|
||||
cbs->start_called = ISC_TRUE;
|
||||
}
|
||||
|
||||
added = 0;
|
||||
result = ISC_R_SUCCESS;
|
||||
while (desired > 0 && result == ISC_R_SUCCESS) {
|
||||
result = cbs->getfunc(source, cbs->arg, blocking);
|
||||
if (result == ISC_R_QUEUEFULL) {
|
||||
got = crunchsamples(ent, &cbs->samplequeue);
|
||||
added += got;
|
||||
desired -= ISC_MIN(got, desired);
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return (added);
|
||||
@@ -415,22 +432,13 @@ fillpool(isc_entropy_t *ent, unsigned int desired, isc_boolean_t blocking) {
|
||||
* to build up.
|
||||
*/
|
||||
if (needed == 0) {
|
||||
isc_uint32_t needed_ent, needed_ps;
|
||||
|
||||
REQUIRE(!blocking);
|
||||
|
||||
if ((ent->pool.entropy >= RND_POOLBITS / 4)
|
||||
&& (ent->pool.pseudo <= RND_POOLBITS / 4))
|
||||
return;
|
||||
needed_ent = 0;
|
||||
needed_ps = 0;
|
||||
if (ent->pool.entropy < THRESHOLD_BITS)
|
||||
needed_ent = THRESHOLD_BITS;
|
||||
if (ent->pool.pseudo > RND_POOLBITS / 4)
|
||||
needed_ps = THRESHOLD_BITS;
|
||||
needed = ISC_MAX(needed_ent, needed_ps);
|
||||
if (needed == 0 && ent->initialized >= THRESHOLD_BITS)
|
||||
return;
|
||||
|
||||
needed = THRESHOLD_BITS * 4;
|
||||
} else {
|
||||
needed = ISC_MAX(needed, THRESHOLD_BITS);
|
||||
needed = ISC_MIN(needed, RND_POOLBITS);
|
||||
@@ -479,10 +487,7 @@ fillpool(isc_entropy_t *ent, unsigned int desired, isc_boolean_t blocking) {
|
||||
|
||||
added += got;
|
||||
|
||||
if (remaining > got)
|
||||
remaining -= got;
|
||||
else
|
||||
remaining = 0;
|
||||
remaining -= ISC_MIN(remaining, got);
|
||||
|
||||
source = ISC_LIST_NEXT(source, link);
|
||||
if (source == NULL)
|
||||
@@ -507,25 +512,19 @@ fillpool(isc_entropy_t *ent, unsigned int desired, isc_boolean_t blocking) {
|
||||
* check to see if we have a callback source. If so, call them.
|
||||
*/
|
||||
source = ISC_LIST_HEAD(ent->sources);
|
||||
while (remaining != 0 && source != NULL) {
|
||||
while ((remaining != 0) && (source != NULL)) {
|
||||
unsigned int got;
|
||||
|
||||
got = 0;
|
||||
|
||||
if (source->type == ENTROPY_SOURCETYPE_CALLBACK)
|
||||
got = get_from_callback(source, remaining);
|
||||
got = get_from_callback(source, remaining, blocking);
|
||||
|
||||
added += got;
|
||||
remaining -= ISC_MIN(remaining, got);
|
||||
|
||||
if (remaining > got)
|
||||
remaining -= got;
|
||||
else
|
||||
remaining = 0;
|
||||
|
||||
#if 0
|
||||
if (added >= needed)
|
||||
break;
|
||||
#endif
|
||||
|
||||
source = ISC_LIST_NEXT(source, link);
|
||||
}
|
||||
@@ -601,28 +600,6 @@ isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length,
|
||||
|
||||
LOCK(&ent->lock);
|
||||
|
||||
/*
|
||||
* If we are blocking, we will block when actually extracting data.
|
||||
* Otherwise, if we cannot block, there is a limit on how much data
|
||||
* we can actually extract if good data is required.
|
||||
*
|
||||
* Here, clamp length to be the amount of data we can extract
|
||||
* if goodonly and partial are both set, otherwise return an
|
||||
* error.
|
||||
*/
|
||||
if (goodonly && !blocking) {
|
||||
fillpool(ent, length * 8, ISC_FALSE);
|
||||
|
||||
/*
|
||||
* To extract good data, we need to have at least
|
||||
* enough entropy to fill our digest.
|
||||
*/
|
||||
if (ent->pool.entropy < THRESHOLD_BITS) {
|
||||
UNLOCK(&ent->lock);
|
||||
return (ISC_R_NOENTROPY);
|
||||
}
|
||||
}
|
||||
|
||||
remain = length;
|
||||
buf = data;
|
||||
total = 0;
|
||||
@@ -652,9 +629,12 @@ isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length,
|
||||
else
|
||||
fillpool(ent, fillcount, blocking);
|
||||
|
||||
if (!partial)
|
||||
if (ent->pool.entropy < THRESHOLD_BITS)
|
||||
if (ent->pool.entropy < THRESHOLD_BITS) {
|
||||
if (!blocking && !partial)
|
||||
goto zeroize;
|
||||
else if (partial)
|
||||
goto partial_output;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* If we've extracted half our pool size in bits
|
||||
@@ -696,6 +676,8 @@ isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length,
|
||||
add_pseudo(ent, count * 8);
|
||||
}
|
||||
|
||||
partial_output:
|
||||
|
||||
memset(digest, 0, sizeof(digest));
|
||||
|
||||
if (returned != NULL)
|
||||
@@ -809,8 +791,10 @@ destroysource(isc_entropysource_t **sourcep) {
|
||||
break;
|
||||
case ENTROPY_SOURCETYPE_CALLBACK:
|
||||
cbs = &source->sources.callback;
|
||||
if (cbs->start_called && cbs->stopfunc != NULL)
|
||||
cbs->stopfunc(ent, source, cbs->arg);
|
||||
if (cbs->start_called && cbs->stopfunc != NULL) {
|
||||
cbs->stopfunc(source, cbs->arg);
|
||||
cbs->start_called = ISC_FALSE;
|
||||
}
|
||||
samplequeue_release(ent, &cbs->samplequeue);
|
||||
break;
|
||||
}
|
||||
@@ -1049,6 +1033,8 @@ isc_entropy_createcallbacksource(isc_entropy_t *ent,
|
||||
ISC_LIST_APPEND(ent->sources, source, link);
|
||||
ent->nsources++;
|
||||
|
||||
*sourcep = source;
|
||||
|
||||
UNLOCK(&ent->lock);
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
@@ -1074,8 +1060,10 @@ isc_entropy_stopcallbacksources(isc_entropy_t *ent) {
|
||||
while (source != NULL) {
|
||||
if (source->type == ENTROPY_SOURCETYPE_CALLBACK) {
|
||||
cbs = &source->sources.callback;
|
||||
if (cbs->start_called && cbs->stopfunc != NULL)
|
||||
cbs->stopfunc(ent, source, cbs->arg);
|
||||
if (cbs->start_called && cbs->stopfunc != NULL) {
|
||||
cbs->stopfunc(source, cbs->arg);
|
||||
cbs->start_called = ISC_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
source = ISC_LIST_NEXT(source, link);
|
||||
@@ -1124,6 +1112,8 @@ isc_entropy_createsamplesource(isc_entropy_t *ent,
|
||||
ISC_LIST_APPEND(ent->sources, source, link);
|
||||
ent->nsources++;
|
||||
|
||||
*sourcep = source;
|
||||
|
||||
UNLOCK(&ent->lock);
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
@@ -1189,7 +1179,7 @@ crunchsamples(isc_entropy_t *ent, sample_queue_t *sq) {
|
||||
unsigned int ns;
|
||||
unsigned int added;
|
||||
|
||||
if (sq->nsamples < 5)
|
||||
if (sq->nsamples < 6)
|
||||
return (0);
|
||||
|
||||
added = 0;
|
||||
@@ -1210,6 +1200,17 @@ crunchsamples(isc_entropy_t *ent, sample_queue_t *sq) {
|
||||
entropypool_adddata(ent, sq->samples, sq->nsamples * 4, added);
|
||||
entropypool_adddata(ent, sq->extra, sq->nsamples * 4, 0);
|
||||
|
||||
/*
|
||||
* Move the last 4 samples into the first 4 positions, and start
|
||||
* adding new samples from that point.
|
||||
*/
|
||||
for (ns = 0 ; ns < 4 ; ns++) {
|
||||
sq->samples[ns] = sq->samples[sq->nsamples - 4 + ns];
|
||||
sq->extra[ns] = sq->extra[sq->nsamples - 4 + ns];
|
||||
}
|
||||
|
||||
sq->nsamples = 0;
|
||||
|
||||
return (added);
|
||||
}
|
||||
|
||||
@@ -1228,9 +1229,9 @@ addsample(sample_queue_t *sq, isc_uint32_t sample, isc_uint32_t extra) {
|
||||
sq->nsamples++;
|
||||
|
||||
if (sq->nsamples >= RND_EVENTQSIZE)
|
||||
return (ISC_R_SUCCESS);
|
||||
return (ISC_R_QUEUEFULL);
|
||||
|
||||
return (ISC_R_NOENTROPY);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@@ -1248,30 +1249,37 @@ isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample,
|
||||
|
||||
LOCK(&ent->lock);
|
||||
|
||||
switch (source->type) {
|
||||
case ENTROPY_SOURCETYPE_SAMPLE:
|
||||
sq = &source->sources.sample.samplequeue;
|
||||
result = addsample(sq, sample, extra);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (result == ISC_R_QUEUEFULL) {
|
||||
entropy = crunchsamples(ent, sq);
|
||||
add_entropy(ent, entropy);
|
||||
}
|
||||
break;
|
||||
case ENTROPY_SOURCETYPE_CALLBACK:
|
||||
sq = &source->sources.sample.samplequeue;
|
||||
result = addsample(sq, sample, extra);
|
||||
break;
|
||||
default:
|
||||
result = ISC_R_UNEXPECTED;
|
||||
REQUIRE(source->type == ENTROPY_SOURCETYPE_SAMPLE
|
||||
|| source->type == ENTROPY_SOURCETYPE_CALLBACK);
|
||||
}
|
||||
|
||||
UNLOCK(&ent->lock);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_entropy_addcallbacksample(isc_entropysource_t *source, isc_uint32_t sample,
|
||||
isc_uint32_t extra)
|
||||
{
|
||||
isc_entropy_t *ent;
|
||||
sample_queue_t *sq;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(VALID_SOURCE(source));
|
||||
REQUIRE(source->type == ENTROPY_SOURCETYPE_CALLBACK);
|
||||
|
||||
ent = source->ent;
|
||||
|
||||
sq = &source->sources.callback.samplequeue;
|
||||
result = addsample(sq, sample, extra);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length,
|
||||
isc_uint32_t entropy)
|
||||
|
Reference in New Issue
Block a user