LavaRnd application interface - API
===================================

    for LavaRnd version 0.1.3


QUICK START:
-----------

    C programmers need to determine what they want to do if their
    applications are unable to communicate with the lavapool daemon.
    The several base libs differ on how they handle errors.  They
    can also replace the pseudo-random number libc functions with
    the lava_libc library as well.  See the examples found at the
    bottom of the 'C API' section.

    Perl programmers should use the perldoc command:

	perldoc LavaRnd::Exit
	perldoc LavaRnd::Retry
	perldoc LavaRnd::Return
	perldoc LavaRnd::S100_Any
	perldoc LavaRnd::TryOnce_Any
	perldoc LavaRnd::Try_Any

    to learn how to use the Perl interface.

=-=-=

Overview:
---------

    LavaRnd currently as APIs for C and Perl.  A language API consists
    of several client APIs and perhaps a utility API.

    The client APIs perform LavaRnd permit a client program to communicate
    with a lavapool daemon.  They handle error conditions in one way
    or another.  They sometimes convert LavaRnd random numbers into
    a particular format.

    The utility APIs perform special functions that are usually only
    of interest to a LavaRnd developer.

    The C APIs contain replacement calls to the common libc pseudo-random
    number generators.  An application that was written to use libc random
    number facilities can link with a LavaRnd C library and make use of
    the LavaRnd facility without a need to modify the application source.

=-=-=

RTFS:
----

    For those who are best served by example, take a look at the
    following tool and perllib sources:

	tool/tryrnd.c
	tool/test_tryrnd    (notice how tryrnd_* are formed in tool/Makefile)
	tool/poolout.c

    For Perl users, try the following modules:

	for i in Exit Retry Return S100_Any TryOnce_Any Try_Any; do
	    perldoc perllib/LavaRnd/$i/$i.pm
	    less perllib/LavaRnd/$i/$i.pm
	    less perllib/LavaRnd/$i/$i.xs
	    less perllib/LavaRnd/$i/t/1.t
	done

    NOTE: A number of the other tool programs make special use of internal
	  LavaRnd facilities not intended for general use.  They are
	  provided / were written for testing and support purposes.
	  The same goes for the LavaRnd::Util module.  Using those as
	  examples may not be the best thing to do.

=-=-=

C API:
-----

    The C API is implemented by 13 main libraries:

	-l lava_exit
	-l lava_retry
	-l lava_return
	-l lava_s100_any
	-l lava_s100_high
	-l lava_s100_med
	-l lava_try_any
	-l lava_try_high
	-l lava_try_med
	-l lava_tryonce_any
	-l lava_tryonce_high
	-l lava_tryonce_med

    Each library provides the same set of functions.  The only difference
    is how the library handles error conditions (i.e., default callback).

    The 13 LavaRnd libraries mention above (but not lava_libc)
    implement number of non-libc LavaRnd facilities:

	/* return an 8 bit random value */
    	u_int8_t random8(void);

	/* return an 16 bit random value */
	u_int16_t random16(void);

	/* return an 32 bit random value */
	u_int32_t random32(void);

	/* return an 64 bit random value */
	u_int64_t random64(void);

	/*
	 * randomcpy - fill a buffer with random data
	 *
	 * given:
	 *      ptr     where to place random data
	 *      len     octets to copy
	 *
	 * returns:
	 *      number of octets returned, or
	 *	< 0 ==> error, or
	 *	0 ==> no data returned
	 */
	int randomcpy(u_int8_t *ptr, int len);

	/* returns random double in the open interval [0.0, 1.0) */
	double drandom(void);		/* will not return 1.0 */

	/* returns random double in the closed interval [0.0, 1.0] */
	double dcrandom(void);		/* can return 1.0 */

	/* returns random long double in the open interval [0.0, 1.0) */
	long double ldrandom(void);	/* will not return 1.0 */

	/* returns random double in the closed interval [0.0, 1.0] */
	long double ldcrandom(void);	/* can return 1.0 */

	/* roll a die and return a value from [0,n)  (32 bit max) */
	u_int32_t random_val(u_int32_t limit);	/* will not return limit */

	/* roll a die and return a value from [0,n)  (64 bit max) */
	u_int64_t random_lval(u_int64_t limit);	/* will not return limit */

    In addition, the library:

	-l lava_libc

    implements the LavaRnd interface in the form of a number common
    libc functions.  The common libc random number functions implemented
    in the lava_libc library include:

	/* return a [0,2^31) random value */
	int rand(void);

	/* return a [0,2^31) random value */
	long int random(void);

	/* return a [0.0, 1.0) random value */
	double drand48(void);

	/* return a [0.0, 1.0) random value */
	double erand48(unsigned short int xsubi[3]);	/* arg ignored */

	/* return a [0.0, 1.0) random value */
	long int lrand48(void);

	/* return a [0,2^31) random value */
	long int nrand48(unsigned short int xsubi[3]);	/* arg ignored */

	/* return a [-2^31,2^31) random value */
	long int mrand48(void);

	/* return a [-2^31,2^31) random value */
	long int jrand48(unsigned short int xsubi[3]);	/* arg ignored */

    These functions return LavaRnd data in the same format as the libc
    function.  See the man page for libc random number functions for
    details on how they work.

    The libc-'seed' functions:

	/* fake stubs for libc seed functions - all args are ignored */
	void srand(unsigned int seed);
	void srandom(unsigned int seed);
	char *initstate(unsigned int seed, char *state, size_t n);
	void char *setstate(char *state);
	void srand48(long int seedval);
	unsigned short int *seed48(unsigned short int seed16v[3]);
	void lcong48(unsigned short int param[7]);

    do not actually seed LavaRnd.  LavaRnd is random number generator,
    not a pseudo-random number generator.  There is no LavaRnd seed.
    Calls to such seed functions are no-ops.  There is no harm in calling
    these seed functions.  There is no need to when using LavaRnd either.

    A pseudo-random number function that as been seeded with the value
    will return the same values.  This is how the normal libc functions
    work.  Because LavaRnd is NOT a pseudo-random number generator,
    seeding has not effect and LavaRnd will not return the same
    values unless you are very lucky.  :-)

    A problem with the pseudo-random number generator interfaces provided
    by libc is that they have no facility for reporting an error.  Those
    libc interfaces assume everything will work correctly all the time.
    One cannot assume this is true when dealing with a hardware-based
    random number generator.

    The LavaRnd client APIs use a callback facility when a error
    occurs.  These callbacks can cause the client to do a number
    of different things in the face of an error:

   	* exit
	* retry
	* return non-random data
	* attempt to return values from the s100 pseudo-random number generator
	* call a user-defined function

    Applications that have been written with the libc pseudo-random number
    generators in mind simply expect their random functions to always work.
    To help these existing applications, a number of different LavaRnd
    libraries are created.  The error behavior will depend on which
    library is used.

    The following liblava libraries exist in static and dynamic form.
    Each implements the libc-functions as well as the new LavaRnd
    random number facilities previously discussed:

	-l lava_exit		(uses LAVACALL_LAVA_EXIT callback)

	    Only return LavaRnd data.

	    If service is down, retry a few times, pausing in between tries.
	    If all else fails, exit.

	-l lava_retry		(uses LAVACALL_LAVA_RETRY callback)

	    Only return LavaRnd data.

	    If service is down, try again after a pause.  Keep trying
	    until the service is back up.

       -l lava_return		(uses LAVACALL_LAVA_RETURN callback)

	    Only return LavaRnd data.

	    If service is down, retry a few times, pausing in between tries.
	    If all else fails, return an error.

       -l lava_try_high		(uses LAVACALL_TRY_HIGH callback)
       -l lava_try_med		(uses LAVACALL_TRY_MED callback)
       -l lava_try_any		(uses LAVACALL_TRY_ANY callback)

	    Try to return LavaRnd data, but if you cannot, return a certain
	    quality (HIGH, MEDium or ANY quality) s100 data instead.

	    See below for discussion about the s100 pseudo-random number
	    generator.

	    If the lavapool times out/fails, use the s100 data instead.
	    Thus in the case of a dead lavapool daemon, there will always
	    by a delay before data is returned.  You might want to use
	    one of the LAVACALL_TRYONCE_XYZ types below instead.

	-l lava_tryonce_high		(uses LAVACALL_TRYONCE_HIGH callback)
	-l lava_tryonce_med		(uses LAVACALL_TRYONCE_MED callback)
	-l lava_tryonce_any		(uses LAVACALL_TRYONCE_ANY callback)

	    Try to return LavaRnd data, but if ever fail to communicate
	    with the daemon, then from then on, just use s100 instead ...
	    or at least keep using s100 until some other callback (such
	    as LAVACALL_TRY_XYZ) manages to successfully communicate with
	    the daemon.

	    See below for discussion about the s100 pseudo-random number
	    generator.

	    When returning s100 data, return s100 data that is of a given
	    quality (HIGH, MEDium or ANY quality).

	-l lava_s100_high		(uses LAVACALL_S100_HIGH callback)
	-l lava_s100_med		(uses LAVACALL_S100_MED callback)
	-l lava_s100_any		(uses LAVACALL_S100_ANY callback)

	    Only return s100 data.  When returning s100 data, return s100
	    data that is of a given quality (HIGH, MEDium or ANY quality).
	    LavaRnd is only used to seed the s100 generator.

	    See below for discussion about the s100 pseudo-random number
	    generator.

	    Use these interfaces when cryptographically strong random
	    numbers are not a requirement.  Applications that do not
	    have such a requirement will non-the-less find a properly
	    seeded s100 generator to produce a good pseudo-random number
	    sequence.

	    The s100 generator produces data faster than the pure LavaRnd
	    facilities.  While LavaRnd is not slow, applications that value
	    speed over cryptographic quality may want to use this interface.

    NOTE: All libraries come in both static and dynamic shared form.

    An application that was designed to use libc-like random number
    functions can be made to use LavaRnd by linking with the correct
    libraries.

    Example: app uses libc interface, wants error retried until they work:

	cc app.o -llava_retry -llava_libc -o app

    Example: app uses libc interface, wants to degrade on error and never fail:

	cc app.o -llava_s100_any -llava_libc -o app

    Example: app uses libc interface, exit on error:

	cc app.o -llava_exit -llava_libc -o app

    Example: app uses libc interface, exit on error:

	cc app.o -llava_exit -llava_libc -o app

    Example: app does not want libc touched, wants any errors to return
    	     and will use the LavaRnd error facility (see below) to
	     check for problems:

	cc app.o -llava_return -o app

    NOTE: If you do not use the lava_libc library, then calls to
    	  libc functions will NOT use the LavaRnd facility.

=-=-=

LavaRnd error indicators:
------------------------

    Whenever LavaRnd is unable to satisfy a request, a value <0 is stored
    in lavarnd_errno:

	#include <LavaRnd/random.h>

	extern int lavarnd_errno;	/* most recent LavaRnd error code */

    An application may consult this value.  A 0 value indicates that
    no error has been encountered.  The symbol LAVAERR_OK, which as a
    0 value, may also be used.  The application may clear lavarnd_errno
    any any time.

    The intent of lavarnd_errno is to allow a caller to determine
    when a random number interface as returned bad data.  For example,
    the libc emulation interface function random() has no direct means
    if indicating that it was unable to return data of sufficient quality.
    A caller can get around this interface limitation by checking the
    lavarnd_errno value for a negative value.  Whenever lavarnd_errno < 0,
    the return value from such interfaces should be considered unreliable
    and should not be used.

    LavaRnd errors vary depending on which callback interface is used.
    For example, if LAVACALL_LAVA_RETURN is used when there is failure
    to contact the lavapool daemon.  If LAVACALL_S100_MED is used and the
    s100 generator goes too long without a reseed (say, because of inability
    to contact the lavapool daemon) then lavarnd_errno will be set to a
    value < 0.

    What can one do when lavarnd_errno becomes < 0?  First, the
    data from of the previous random number call should not be used.
    Second, one should clear the lavarnd_errno by setting it to
    LAVAERR_OK (0).  Third, one could consider either retrying the
    call (perhaps at a later time) or change the callback to a less
    stringent level (via the set_lava_callback() function) if the
    application permits.  For example one could go from
    LAVACALL_S100_HIGH to LAVACALL_S100_MED.

    The status of the most recent libc-like call is found in:

    	#include <LavaRnd/random.h>

	extern int lastop_errno;

    While the user is free to clear this value as well, there is little
    point in doing so because the next random or libc-like call will
    clear it.  Unlike lavarnd_errno that records the most recent error,
    the lastop_errno records the success (0) or failure (<0) of the
    most recent random or libc-like call.

    The meaning of a lavarnd_errno value <= 0, or the lastop_errno value <= 0,
    or a randomcpy() return value < 0 can be obtained from:

    	#include <LavaRnd/random.h>

	extern const char *lava_err_name(int err);

    Example:

    	foo = random32();
	if (lastop_errno < 0) {
	   fprintf(stderr, "Ouch, foo is bogus: %s\n",
	   	   lava_err_name(lastop_errno));
	}

	lavarnd_errno = LAVAERR_OK;
	sum = 0.0;
	for (i=0; i < 100; ++i) {
	   sum += drandom();
	}
	if (lavarnd_errno < 0) {
	   fprintf(stderr, "Ouch, sum is bogus: %s\n",
	   	   lava_err_name(lavarnd_errno));
	}

=-=-=

C callbacks:
-----------

    A callback is used when the random number service encounters an error.
    Usually this error is a failure to communicate with the lavapool
    daemon in a specified amount of time.  Other errors include malloc
    failures and system call errors.  See <LavaRnd/lavaerr.h> for details
    on possible errors.

    An application may set a callback at any time:

	#include <LavaRnd/random.h>

	/*
	 * set_lava_callback - change the default callback for random.c &
	 *							   random_libc.c
	 *
	 * given:
	 *      callback        call to set, or NULL to just return
	 *
	 * returns:
	 *      previous callback
	 *
	 * NOTE: Call with a NULL ptr to just inquire about the callback.
	 */
	extern lavaback set_lava_callback(lavaback callback);

    The <LavaRnd/lavaerr.h> (included when <LavaRnd/random.h> is included)
    contains some pre-defined callbacks:

	LAVACALL_LAVA_EXIT

	    Only return LavaRnd data.

	    If service is down, retry a few times, pausing in between tries.
	    If all else fails, exit.

	LAVACALL_LAVA_RETRY

	    Only return LavaRnd data.

	    If service is down, try again after a pause.  Keep trying
	    until the service is back up.

	LAVACALL_LAVA_RETURN

	    Only return LavaRnd data.

	    If service is down, retry a few times, pausing in between tries.
	    If all else fails, return an error.

	LAVACALL_TRY_HIGH
	LAVACALL_TRY_MED
	LAVACALL_TRY_ANY

	    Try to return LavaRnd data, but if you cannot, return a certain
	    quality (HIGH, MEDium or ANY quality) s100 data instead.

	    If the lavapool times out/fails, use the s100 data instead.
	    Thus in the case of a dead lavapool daemon, there will always
	    by a delay before data is returned.  You might want to use
	    one of the LAVACALL_TRYONCE_XYZ types below instead.

	LAVACALL_TRYONCE_HIGH
	LAVACALL_TRYONCE_MED
	LAVACALL_TRYONCE_ANY

	    Try to return LavaRnd data, but if ever fail to communicate
	    with the daemon, then from then on, just use s100 instead ...
	    or at least keep using s100 until some other callback (such
	    as LAVACALL_TRY_XYZ) manages to successfully communicate with
	    the daemon.

	    When returning s100 data, return s100 data that is of a given
	    quality (HIGH, MEDium or ANY quality).

	LAVACALL_S100_HIGH
	LAVACALL_S100_MED
	LAVACALL_S100_ANY

	    Only return s100 data.  When returning s100 data, return s100
	    data that is of a given quality (HIGH, MEDium or ANY quality).


    The application may supply their own callback function.  Call
    back functions must be of the following typedef:

	/*
	 * The callback function, when called, is given the following
	 * information:
	 *
	 *      buf - pointer to where data is being written
	 *      len - size of the initial request / size of buf in octets
	 *      offset - amount of data already written
	 *      err - error code (LAVAERR_TIMEOUT, LAVAERR_IOERR, ...)
	 *		(see <LavaRnd/lavaerr.h>)
	 *      ret - FALSE ==> calling function will ignore errors you return
	 *            TRUE ==> calling function will receive a status code
	 */
	typedef double (*lavaback) (u_int8_t * buf, int len, int offset,
				    int err, int ret);

    The return value of a callback function, if >0, is the timeout value
    (in seconds) for a retry.  This if your callback function returns
    a 4.5, then a retry ~4.5 seconds later will be attempted.  Callback
    returns <= 0 have special meaning:

	LAVA_CALLBACK_EXIT

	    The callback function is requisition that the internal
	    routine exit.

	LAVA_CALLBACK_RETURN

	    The callback function is requesting that the internal function
	    return it its caller.  Here the caller is the public interface
	    that the user code called to obtain random data.

	    The callback function should consider the 'ret' argument before
	    returning this value.  If 'ret' is FALSE, the caller (via a public
	    interface) is ignoring status codes.  The callback function may
	    want to return LAVA_CALLBACK_S100LOW, when 'ret' is FALSE to
	    avoid returning highly non-random bogus values.

	    For example, the libc-like public interface function random()
	    simply returns a long (4 octets with sign bit masked off).  The
	    random() function has no concept of an error.  If in the course
	    of obtaining random()'s 4 random octets some error occurs, then
	    the callback function will be called with a ret value of FALSE.
	    If the callback returns LAVA_CALLBACK_RETURN forcing the internal
	    function to return, then some undefined and likely highly non-random
	    bogus value will be returned by random().

	LAVA_CALLBACK_S100LOW

	    The internal function should use the s100 function to return
	    the best s100 data that it can.  Any quality of data of
	    is acceptable.

	    If 'ret' is FALSE, then the the caller (via a public interface)
	    ignoring status codes.  By the callback function returning this
	    value in that case, some pseudo-random data is returned instead
	    of highly non-random bogus value.

	LAVA_CALLBACK_S100MED

	    The internal function should use the s100 function to return the
	    best s100 data that it can.   The quality of data must be
	    LAVA_QUAL_S100MED or better.  If the quality is not up to
	    LAVA_QUAL_S100MED standards, then the LAVAERR_POORQUAL error
	    code is returned.

	    The callback function should consider the 'ret' argument before
	    returning this value.  If 'ret' is FALSE, the caller (via a public
	    interface) is ignoring status codes.  The callback function may
	    want to return LAVA_CALLBACK_S100LOW, when 'ret' is FALSE to
	    avoid returning highly non-random bogus values.

	LAVA_CALLBACK_S100HIGH

	    The internal function should use the s100 function to return
	    the best s100 data that it can.   The quality of data must
	    be LAVA_QUAL_S100HIGH or better.  If the quality is not up
	    to LAVA_QUAL_S100HIGH standards, then the LAVAERR_POORQUAL
	    error code is returned.

	    The callback function should consider the 'ret' argument
	    before returning this value.  If 'ret' is FALSE, the caller
	    (via a public interface) is ignoring status codes.	The
	    callback function may want to return LAVA_CALLBACK_S100LOW,
	    when 'ret' is FALSE to avoid returning highly non-random
	    bogus values.


    NOTE: The effect of linking in a library such as:

    	-l lava_retry

    is to initialize the default callback to LAVACALL_LAVA_RETRY.
    The application could have the same effect by directly calling:

	(void) set_lava_callback(LAVACALL_LAVA_RETRY);

=-=-=

s100 generator:
--------------

    The s100 pseudo-random number generator is a high quality
    pseudo-random number generator.  The output of this generator,
    while good if given reasonable seed data, is NOT cryptographically
    strong.  The s100 pseudo-random number generator is provided for those
    applications that must have something returned no matter what happens.
    This generator is intended as a last resort for those applications
    that link to the appropriate library or use the appropriate callback.
    See the file:

	lib/s100.c

    for a detailed discussion on how s100 works.

    NOTE: Do not directly call s100.c functions.  The function interface
    	  may change at any time.  To use only s100 generator facilities,
	  link in the appropriate library below or set the appropriate
	  callback (see above).

    When there is a potential for s100 use, LavaRnd will attempt to
    see the generator with LavaRnd data.  The quality of s100
    depends on if and when it was seeded LavaRnd data:

	high quality	seeded LavaRnd data recently
	medium quality	seeded LavaRnd data, but not recently
	low quality	seeded with a junk seed of system state junk

    These libraries can return HIGH quality s100 data:

	-l lava_s100_high		(uses LAVACALL_S100_HIGH callback)

	when LavaRnd fails:

	-l lava_try_high		(uses LAVACALL_TRY_HIGH callback)
	-l lava_tryonce_high		(uses LAVACALL_TRYONCE_HIGH callback)

	will only return high quality data that was recently seeded with
	LavaRnd data.  Such returns may be suitable for a wide number of
	applications where security is needed.  The s100 seed is huge, making
	an exhaustive seed search attack intractable.  When the s100 seed
	is securely produced by LavaRnd, guessing the s100 seed becomes an
	intractable problem.

	One can produce about 97 megabytes of s100 data before a reseed is
	needed.  When the limit has been reached, LavaRnd is used to reseed.
	As long as the lavapool daemon is available, the s100 generator
	can continue to produce high quality data.

	The HIGH quality s100 interface will only return data if the
	lavapool daemon is available for the initial seed and is
	available during reseeding.

    These libraries can return HIGH or MEDium quality s100 data:

	-l lava_s100_med		(uses LAVACALL_S100_MED callback)

	when LavaRnd fails:

	-l lava_try_med			(uses LAVACALL_TRY_MED callback)
	-l lava_tryonce_med		(uses LAVACALL_TRYONCE_MED callback)

	The s100 data returned by these interfaces has been seeded by
	LavaRnd at one time.  One can produce about 97 megabytes of s100
	data before a reseed is needed.  If the lavapool daemon is not
	available for reseeding, these libraries will continue to use
	the s100 in a somewhat degraded state.	This degraded state is
	called medium quality.	If lavapool daemon is available, then
	these libraries will return high quality s100 data.

	If a s100 reseed fails because the lavapool daemon is not
	available, then the existing s100 state is used to produce another
	~97 megabytes of data.  Another reseed attempt is made after that.

	The MEDium quality s100 interface will only return data if the
	lavapool daemon is available for the initial s100 seed.

    These libraries can return s100 data of any quality:

	-l lava_s100_any		(uses LAVACALL_S100_ANY callback)

	when LavaRnd fails:

	-l lava_try_any			(uses LAVACALL_TRY_ANY callback)
	-l lava_tryonce_any		(uses LAVACALL_TRYONCE_ANY callback)

	If the lavapool daemon is not available to produce an initial s100
	seed, then a system state will be used form a non-random junk seed.
	The quality of the s100 data is said to be of low quality.

	If the lavapool daemon is available an initial seed, then these
	libraries will return HIGH or MEDium quality data, depending on
	if the lavapool daemon was available and needed for a reseed.

	The low quality system state junk seed could permit a sophisticated
	attack on the s100 output to be performed.  Applications that have
	some level of security should not use these libraries.

	The advantage of these libraries is that they always return data.
	The lava_try_any and lava_tryonce_any, in particular will return
	LavaRnd data if the lavapool daemon is available.

	Applications where cryptographic security is not an issue can
	use these facilities.  Furthermore where maximum speed is
	important (but cryptographic security is not), the lava_s100_any
	libraries should be used.

=-=-=

LAVA_DEBUG:
----------

    If the libraries were compiled with -DLAVA_DEBUG (see the LAVA_DEBUG
    Makefile variable), then a special debugging facility becomes
    available.

    When compiled in, the $LAVA_DEBUG environment variable may be
    used to control the debugging facility:

    The environment variable $LAVA_DEBUG must be of the form:

	flags:type[=option]

    where flags is one or more of:

	0   display this usage message and exit

	a   enable all debugging except f, h, and t
	A   enable all debugging, including f, h and t
	b   display lavapool buffering activity
	c   display random calls and callback activity
	e   display errors and warnings
	f   print calling file, line and function with debug messages
	h   display random data returned as hex strings
	i   display initialization and configuration information
	l   display setting of lavarnd_errno
	p   display lavapool activity
	q   display current quality level
	r   display amount of returned data
	s   display external & internal service calls
	t   print time with debug messages
	v   display callback argument value
	z   display sleeps

    and type is either:

	syslog=name 	send messages to syslog, tag with name_lavalib
	stderr          send messages to stderr
	file=filename   append messages to the file 'filename' if uid>=MIN_UID

    $LAVA_DEBUG must be empty or missing to disable all debugging.

    If the library and tool was compiled with -DLAVA_DEBUG, try:

	LAVA_DEBUG=a:stderr tool/lavaop_i /tmp/out

    Try giving input such as:

    	1 10
	2 10
	3 10

    See:

    	doc/README-tool

   for more information on lavaop_i.

=-=-=

special C libraries:
-------------------

    There are a few other special libraries:

	-l LavaRnd_cam
	-l LavaRnd_raw
	-l LavaRnd_util

    These libraries are used by the LavaRnd lavapool daemon, other
    daemons or special tool / testing facilities.  Normally one will
    not need these libraries.  For the curious, there is the source!  :-)

=-=-=

Perl API:
--------

    Several of the previously discussed callback facilities are
    available to the Perl application:

	use LavaRnd::Exit;		# uses LAVACALL_LAVA_EXIT callback
	use LavaRnd::Retry;		# uses LAVACALL_LAVA_RETRY callback
	use LavaRnd::Return;		# uses LAVACALL_LAVA_RETURN callback
	use LavaRnd::S100_Any;		# uses LAVACALL_S100_ANY callback
	use LavaRnd::TryOnce_Any;	# uses LAVACALL_TRYONCE_ANY callback
	use LavaRnd::Try_Any;		# uses LAVACALL_TRY_ANY callback

    The perldoc facility can provide documentation on these modules.
    For example:

	perldoc LavaRnd::Exit

    You will find that most of the non-libc C API calls are available,
    along with a few interfaces special to Perl.  The lavarnd_errno and
    lastop_errno error indicators work like they do in the C API.

    These Perl modules all provide:

         ####
         # Integer random values
         ####

         # return a 8 bit random value
         #
         $integer = random8();

         # return a 16 bit random value
         #
         $integer = random16();

         # return a 32 bit random value
         #
         $integer = random32();

         # return random data, $len octets (bytes) long
         #
         # The $len size must be an integer > 0 or
         # undef is returned.
         #
         $data = random_data($len);

         # return an integer value >= 0 and < $beyond.
         #
         # The $beyond value must fit into a 32 bit integer.
         # Also $beyond >= 0 or 0 is returned.
         #
         $integer = random_val($beyond);

         # return integer value >= $low and < $beyond
         #
         # The $low and $beyond must be 32 bit integers.
         # Also $low < $beyond or $low is returned.
         #
         $integer = range_random($low, $beyond);

         # return integer value value >= $low and <= $high
         #
         # The $low and $high must be 32 bit integers.
         # Also $low <= $high or $low is returned.
         #
         $integer = range_crandom($low, $high);

         # return a true (1) or false (0) value
         #
         $boolean = random_coin();

         ####
         # Floating point random values
         ####

         # return a random floating point value >= 0.0 and < 1.0.
         #
         $float = drandom();

         # return a random floating point value >= 0.0 and <= 1.0.
         #
         $float = dcrandom();

         # return floating point value >= $low and < $beyond
         #
         # Note that: $low < $beyond or $low is returned.
         #
         $float = range_drandom($low, $beyond);

         # return floating point value value >= $low and <= $high
         #
         # Note that: $low <= $high or $low is returned.
         #
         $float = range_dcrandom($low, $high);

         ####
         # Error checking
         #
         # NOTE: This LavaRnd::Exit module will exit instead of returning
         #       bad data, so this call is less useful than it is in
         #       other LavaRnd modules.  The lavarnd_errno() and
         #       lastop_errno() interfaces are provided to make this
         #       module's interface similar to the other LavaRnd modules.
         ####

         # Determine if some previous LavaRnd call encountered an error
         #
         if (lavarnd_errno() < 0) {
           die "some previous LavaRnd call failed";
         }

         # Clear previous error condition
         #
         $old_code = lavarnd_errno(0);

         # Determine if the most recent LavaRnd call encountered an error
         #
         if (lastop_errno() < 0) {
           die "the most recent LavaRnd call failed";
         }

    For additional details, see use the perldoc command.

=-=-=

lavapool wire protocol:
----------------------

   For those who want to roll their own APIs (perhaps to build an API
   for one of the missing languages (see doc/TODO)), communicating
   with the lavapool daemon represents the majority of what you need
   to do.

   The code in lib/fetchlava.c can serve as an example of a more
   extensive interface model that includes callbacks, config file
   parsing, pre-loading, s100 generator fallback, etc.

   The fundamental lavapool protocol is very simple:

	0) determine where the lavapool TCP socket reside
   	1) connect to the lavapool TCP socket
	2) send the number of octets (as ASCII decimal digits)
	   followed by a newline
	3) read that number of octets returned on the same socket
	4) close socket

    You should look for the file /etc/LavaRnd/cfg.random.  If that
    exists, then use it to determine things like the lavapool TCP
    socket location and the maximum request.  If that file does
    not exist, then you should use compiled in default values.

    The default values you should use may be found in the file
    /etc/LavaRnd/cfg.random-def.  Do not parse the cfg.random-def file!
    Compile / pre-define its values into your API and override
    them of /etc/LavaRnd/cfg.random exists.

    Pay attention to:

    	lavapool	(lavapool TCP socket host:port)
	maxrequest	(largest request allowed)
	exit_*		(if exiting on error, how much to retry/wait first)
	retry_*		(if retying on error, how often to retry)
	return_*	(if returning on error, how much to retry/wait first)
	s100_*		(s100 reseeding retries)
	def_callback_wait	(how long a callback should wait by default)
	preload_wait	(how long to wait if pre-loading data from LavaRnd)

    You may want to create an internal buffer of lavapool data to
    reduce the number of connections to lavapool.  There is a trade-off
    between buffering lots of data that is potentially wasted, and
    making too many connections with small requests.

=-=-=

FOR MORE INFO:
-------------

To learn how to compile, install and test LavaRnd, read:

	doc/README-compile
	doc/README-install
	doc/README-test

For more info on LavaRnd see:

	http://www.LavaRnd.org/index.html

To contact us / send us EMail related to LavaRnd see:

	http://www.LavaRnd.org/about-us/contact-us.html
