OSSP CVS Repository

ossp - ossp-pkg/sio/BRAINSTORM/openssl-bio.txt
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/sio/BRAINSTORM/openssl-bio.txt

BIO Routines

This documentation is rather sparse, you are probably best 
off looking at the code for specific details.

The BIO library is a IO abstraction that was originally 
inspired by the need to have callbacks to perform IO to FILE 
pointers when using Windows 3.1 DLLs.  There are two types 
of BIO; a source/sink type and a filter type.
The source/sink methods are as follows:
-	BIO_s_mem()  memory buffer - a read/write byte array that
	grows until memory runs out :-).
-	BIO_s_file()  FILE pointer - A wrapper around the normal 
	'FILE *' commands, good for use with stdin/stdout.
-	BIO_s_fd()  File descriptor - A wrapper around file 
	descriptors, often used with pipes.
-	BIO_s_socket()  Socket - Used around sockets.  It is 
	mostly in the Microsoft world that sockets are different 
	from file descriptors and there are all those ugly winsock 
	commands.
-	BIO_s_null()  Null - read nothing and write nothing.; a 
	useful endpoint for filter type BIO's specifically things 
	like the message digest BIO.

The filter types are
-	BIO_f_buffer()  IO buffering - does output buffering into 
	larger chunks and performs input buffering to allow gets() 
	type functions.
-	BIO_f_md()  Message digest - a transparent filter that can 
	be asked to return a message digest for the data that has 
	passed through it.
-	BIO_f_cipher()  Encrypt or decrypt all data passing 
	through the filter.
-	BIO_f_base64()  Base64 decode on read and encode on write.
-	BIO_f_ssl()  A filter that performs SSL encryption on the 
	data sent through it.

Base BIO functions.
The BIO library has a set of base functions that are 
implemented for each particular type.  Filter BIOs will 
normally call the equivalent function on the source/sink BIO 
that they are layered on top of after they have performed 
some modification to the data stream.  Multiple filter BIOs 
can be 'push' into a stack of modifers, so to read from a 
file, unbase64 it, then decrypt it, a BIO_f_cipher, 
BIO_f_base64 and a BIO_s_file would probably be used.  If a 
sha-1 and md5 message digest needed to be generated, a stack 
two BIO_f_md() BIOs and a BIO_s_null() BIO could be used.
The base functions are
-	BIO *BIO_new(BIO_METHOD *type); Create  a new BIO of  type 'type'.
-	int BIO_free(BIO *a); Free a BIO structure.  Depending on 
	the configuration, this will free the underlying data 
	object for a source/sink BIO.
-	int BIO_read(BIO *b, char *data, int len); Read upto 'len' 
	bytes into 'data'. 
-	int BIO_gets(BIO *bp,char *buf, int size); Depending on 
	the BIO, this can either be a 'get special' or a get one 
	line of data, as per fgets();
-	int BIO_write(BIO *b, char *data, int len); Write 'len' 
	bytes from 'data' to the 'b' BIO.
-	int BIO_puts(BIO *bp,char *buf); Either a 'put special' or 
	a write null terminated string as per fputs().
-	long BIO_ctrl(BIO *bp,int cmd,long larg,char *parg);  A 
	control function which is used to manipulate the BIO 
	structure and modify it's state and or report on it.  This 
	function is just about never used directly, rather it 
	should be used in conjunction with BIO_METHOD specific 
	macros.
-	BIO *BIO_push(BIO *new_top, BIO *old); new_top is apped to the
	top of the 'old' BIO list.  new_top should be a filter BIO.
	All writes will go through 'new_top' first and last on read.
	'old' is returned.
-	BIO *BIO_pop(BIO *bio); the new topmost BIO is returned, NULL if
	there are no more.

If a particular low level BIO method is not supported 
(normally BIO_gets()), -2 will be returned if that method is 
called.  Otherwise the IO methods (read, write, gets, puts) 
will return the number of bytes read or written, and 0 or -1 
for error (or end of input).  For the -1 case, 
BIO_should_retry(bio) can be called to determine if it was a 
genuine error or a temporary problem.  -2 will also be 
returned if the BIO has not been initalised yet, in all 
cases, the correct error codes are set (accessible via the 
ERR library).


The following functions are convenience functions:
-	int BIO_printf(BIO *bio, char * format, ..);  printf but 
	to a BIO handle.
-	long BIO_ctrl_int(BIO *bp,int cmd,long larg,int iarg); a 
	convenience function to allow a different argument types 
	to be passed to BIO_ctrl().
-	int BIO_dump(BIO *b,char *bytes,int len); output 'len' 
	bytes from 'bytes' in a hex dump debug format.
-	long BIO_debug_callback(BIO *bio, int cmd, char *argp, int 
	argi, long argl, long ret) - a default debug BIO callback, 
	this is mentioned below.  To use this one normally has to 
	use the BIO_set_callback_arg() function to assign an 
	output BIO for the callback to use.
-	BIO *BIO_find_type(BIO *bio,int type); when there is a 'stack'
	of BIOs, this function scan the list and returns the first
	that is of type 'type', as listed in buffer.h under BIO_TYPE_XXX.
-	void BIO_free_all(BIO *bio); Free the bio and all other BIOs
	in the list.  It walks the bio->next_bio list.



Extra commands are normally implemented as macros calling BIO_ctrl().
-	BIO_number_read(BIO *bio) - the number of bytes processed 
	by BIO_read(bio,.).
-	BIO_number_written(BIO *bio) - the number of bytes written 
	by BIO_write(bio,.).
-	BIO_reset(BIO *bio) - 'reset' the BIO.
-	BIO_eof(BIO *bio) - non zero if we are at the current end 
	of input.
-	BIO_set_close(BIO *bio, int close_flag) - set the close flag.
-	BIO_get_close(BIO *bio) - return the close flag.
	BIO_pending(BIO *bio) - return the number of bytes waiting 
	to be read (normally buffered internally).
-	BIO_flush(BIO *bio) - output any data waiting to be output.
-	BIO_should_retry(BIO *io) - after a BIO_read/BIO_write 
	operation returns 0 or -1, a call to this function will 
	return non zero if you should retry the call later (this 
	is for non-blocking IO).
-	BIO_should_read(BIO *io) - we should retry when data can 
	be read.
-	BIO_should_write(BIO *io) - we should retry when data can 
	be written.
-	BIO_method_name(BIO *io) - return a string for the method name.
-	BIO_method_type(BIO *io) - return the unique ID of the BIO method.
-	BIO_set_callback(BIO *io,  long (*callback)(BIO *io, int 
	cmd, char *argp, int argi, long argl, long ret); - sets 
	the debug callback.
-	BIO_get_callback(BIO *io) - return the assigned function 
	as mentioned above.
-	BIO_set_callback_arg(BIO *io, char *arg)  - assign some 
	data against the BIO.  This is normally used by the debug 
	callback but could in reality be used for anything.  To 
	get an idea of how all this works, have a look at the code 
	in the default debug callback mentioned above.  The 
	callback can modify the return values.

Details of the BIO_METHOD structure.
typedef struct bio_method_st
        {
	int type;
	char *name;
	int (*bwrite)();
	int (*bread)();
	int (*bputs)();
	int (*bgets)();
	long (*ctrl)();
	int (*create)();
	int (*destroy)();
	} BIO_METHOD;

The 'type' is the numeric type of the BIO, these are listed in buffer.h;
'Name' is a textual representation of the BIO 'type'.
The 7 function pointers point to the respective function 
methods, some of which can be NULL if not implemented.
The BIO structure
typedef struct bio_st
	{
	BIO_METHOD *method;
	long (*callback)(BIO * bio, int mode, char *argp, int 
		argi, long argl, long ret);
	char *cb_arg; /* first argument for the callback */
	int init;
	int shutdown;
	int flags;      /* extra storage */
	int num;
	char *ptr;
	struct bio_st *next_bio; /* used by filter BIOs */
	int references;
	unsigned long num_read;
	unsigned long num_write;
	} BIO;

-	'Method' is the BIO method.
-	'callback', when configured, is called before and after 
	each BIO method is called for that particular BIO.  This 
	is intended primarily for debugging and of informational feedback.
-	'init' is 0 when the BIO can be used for operation.  
	Often, after a BIO is created, a number of operations may 
	need to be performed before it is available for use.  An 
	example is for BIO_s_sock().  A socket needs to be 
	assigned to the BIO before it can be used.
-	'shutdown', this flag indicates if the underlying 
	comunication primative being used should be closed/freed 
	when the BIO is closed.
-	'flags' is used to hold extra state.  It is primarily used 
	to hold information about why a non-blocking operation 
	failed and to record startup protocol information for the 
	SSL BIO.
-	'num' and 'ptr' are used to hold instance specific state 
	like file descriptors or local data structures.
-	'next_bio' is used by filter BIOs to hold the pointer of the
	next BIO in the chain. written data is sent to this BIO and
	data read is taken from it.
-	'references' is used to indicate the number of pointers to 
	this structure.  This needs to be '1' before a call to 
	BIO_free() is made if the BIO_free() function is to 
	actually free() the structure, otherwise the reference 
	count is just decreased.  The actual BIO subsystem does 
	not really use this functionality but it is useful when 
	used in more advanced applicaion.
-	num_read and num_write are the total number of bytes 
	read/written via the 'read()' and 'write()' methods.

BIO_ctrl operations.
The following is the list of standard commands passed as the 
second parameter to BIO_ctrl() and should be supported by 
all BIO as best as possible.  Some are optional, some are 
manditory, in any case, where is makes sense, a filter BIO 
should pass such requests to underlying BIO's.
-	BIO_CTRL_RESET	- Reset the BIO back to an initial state.
-	BIO_CTRL_EOF	- return 0 if we are not at the end of input, 
	non 0 if we are.
-	BIO_CTRL_INFO	- BIO specific special command, normal
	information return.
-	BIO_CTRL_SET	- set IO specific parameter.
-	BIO_CTRL_GET	- get IO specific parameter.
-	BIO_CTRL_GET_CLOSE - Get the close on BIO_free() flag, one 
	of BIO_CLOSE or BIO_NOCLOSE.
-	BIO_CTRL_SET_CLOSE - Set the close on BIO_free() flag.
-	BIO_CTRL_PENDING - Return the number of bytes available 
	for instant reading
-	BIO_CTRL_FLUSH	- Output pending data, return number of bytes output.
-	BIO_CTRL_SHOULD_RETRY - After an IO error (-1 returned) 
	should we 'retry' when IO is possible on the underlying IO object.
-	BIO_CTRL_RETRY_TYPE - What kind of IO are we waiting on.

The following command is a special BIO_s_file() specific option.
-	BIO_CTRL_SET_FILENAME - specify a file to open for IO.

The BIO_CTRL_RETRY_TYPE needs a little more explanation.  
When performing non-blocking IO, or say reading on a memory 
BIO, when no data is present (or cannot be written), 
BIO_read() and/or BIO_write() will return -1.  
BIO_should_retry(bio) will return true if this is due to an 
IO condition rather than an actual error.  In the case of 
BIO_s_mem(), a read when there is no data will return -1 and 
a should retry when there is more 'read' data.
The retry type is deduced from 2 macros
BIO_should_read(bio) and BIO_should_write(bio).
Now while it may appear obvious that a BIO_read() failure 
should indicate that a retry should be performed when more 
read data is available, this is often not true when using 
things like an SSL BIO.  During the SSL protocol startup 
multiple reads and writes are performed, triggered by any 
SSL_read or SSL_write.
So to write code that will transparently handle either a 
socket or SSL BIO,
	i=BIO_read(bio,..)
	if (I == -1)
		{
		if (BIO_should_retry(bio))
			{
			if (BIO_should_read(bio))
				{
				/* call us again when BIO can be read */
				}
			if (BIO_should_write(bio))
				{
				/* call us again when BIO can be written */
				}
			}
		}

At this point in time only read and write conditions can be 
used but in the future I can see the situation for other 
conditions, specifically with SSL there could be a condition 
of a X509 certificate lookup taking place and so the non-
blocking BIO_read would require a retry when the certificate 
lookup subsystem has finished it's lookup.  This is all 
makes more sense and is easy to use in a event loop type 
setup.
When using the SSL BIO, either SSL_read() or SSL_write()s 
can be called during the protocol startup and things will 
still work correctly.
The nice aspect of the use of the BIO_should_retry() macro 
is that all the errno codes that indicate a non-fatal error 
are encapsulated in one place.  The Windows specific error 
codes and WSAGetLastError() calls are also hidden from the 
application.

Notes on each BIO method.
Normally buffer.h is just required but depending on the 
BIO_METHOD, ssl.h or evp.h will also be required.

BIO_METHOD *BIO_s_mem(void);
-	BIO_set_mem_buf(BIO *bio, BUF_MEM *bm, int close_flag) - 
	set the underlying BUF_MEM structure for the BIO to use.
-	BIO_get_mem_ptr(BIO *bio, char **pp) - if pp is not NULL, 
	set it to point to the memory array and return the number 
	of bytes available.
A read/write BIO.  Any data written is appended to the 
memory array and any read is read from the front.  This BIO 
can be used for read/write at the same time. BIO_gets() is 
supported in the fgets() sense.
BIO_CTRL_INFO can be used to retrieve pointers to the memory 
buffer and it's length.

BIO_METHOD *BIO_s_file(void);
-	BIO_set_fp(BIO *bio, FILE *fp, int close_flag) - set 'FILE *' to use.
-	BIO_get_fp(BIO *bio, FILE **fp) - get the 'FILE *' in use.
-	BIO_read_filename(BIO *bio, char *name) - read from file.
-	BIO_write_filename(BIO *bio, char *name) - write to file.
-	BIO_append_filename(BIO *bio, char *name) - append to file.
This BIO sits over the normal system fread()/fgets() type 
functions. Gets() is supported.  This BIO in theory could be 
used for read and write but it is best to think of each BIO 
of this type as either a read or a write BIO, not both.

BIO_METHOD *BIO_s_socket(void);
BIO_METHOD *BIO_s_fd(void);
-	BIO_sock_should_retry(int i) - the underlying function 
	used to determine if a call should be retried; the 
	argument is the '0' or '-1' returned by the previous BIO 
	operation.
-	BIO_fd_should_retry(int i) - same as the 
-	BIO_sock_should_retry() except that it is different internally.
-	BIO_set_fd(BIO *bio, int fd, int close_flag) - set the 
	file descriptor to use
-	BIO_get_fd(BIO *bio, int *fd) - get the file descriptor.
These two methods are very similar.  Gets() is not 
supported, if you want this functionality, put a 
BIO_f_buffer() onto it.  This BIO is bi-directional if the 
underlying file descriptor is.  This is normally the case 
for sockets but not the case for stdio descriptors.

BIO_METHOD *BIO_s_null(void);
Read and write as much data as you like, it all disappears 
into this BIO.

BIO_METHOD *BIO_f_buffer(void);
-	BIO_get_buffer_num_lines(BIO *bio) - return the number of 
	complete lines in the buffer.
-	BIO_set_buffer_size(BIO *bio, long size) - set the size of 
	the buffers.
This type performs input and output buffering.  It performs 
both at the same time.  The size of the buffer can be set 
via the set buffer size option.  Data buffered for output is 
only written when the buffer fills.

BIO_METHOD *BIO_f_ssl(void);
-	BIO_set_ssl(BIO *bio, SSL *ssl, int close_flag) - the SSL 
	structure to use.
-	BIO_get_ssl(BIO *bio, SSL **ssl) - get the SSL structure 
	in use.
The SSL bio is a little different from normal BIOs because 
the underlying SSL structure is a little different.  A SSL 
structure performs IO via a read and write BIO.  These can 
be different and are normally set via the
SSL_set_rbio()/SSL_set_wbio() calls.  The SSL_set_fd() calls 
are just wrappers that create socket BIOs and then call 
SSL_set_bio() where the read and write BIOs are the same.  
The BIO_push() operation makes the SSLs IO BIOs the same, so 
make sure the BIO pushed is capable of two directional 
traffic.  If it is not, you will have to install the BIOs 
via the more conventional SSL_set_bio() call.  BIO_pop() will retrieve
the 'SSL read' BIO.

BIO_METHOD *BIO_f_md(void);
-	BIO_set_md(BIO *bio, EVP_MD *md) - set the message digest 
	to use.
-	BIO_get_md(BIO *bio, EVP_MD **mdp) - return the digest 
	method in use in mdp, return 0 if not set yet.
-	BIO_reset() reinitializes the digest (EVP_DigestInit()) 
	and passes the reset to the underlying BIOs.
All data read or written via BIO_read() or BIO_write() to 
this BIO will be added to the calculated digest.  This 
implies that this BIO is only one directional.  If read and 
write operations are performed, two separate BIO_f_md() BIOs 
are reuqired to generate digests on both the input and the 
output.  BIO_gets(BIO *bio, char *md, int size) will place the 
generated digest into 'md' and return the number of bytes.  
The EVP_MAX_MD_SIZE should probably be used to size the 'md' 
array.  Reading the digest will also reset it.

BIO_METHOD *BIO_f_cipher(void);
-	BIO_reset() reinitializes the cipher.
-	BIO_flush() should be called when the last bytes have been 
	output to flush the final block of block ciphers.
-	BIO_get_cipher_status(BIO *b), when called after the last 
	read from a cipher BIO, returns non-zero if the data 
	decrypted correctly, otherwise, 0.
-	BIO_set_cipher(BIO *b, EVP_CIPHER *c, unsigned char *key, 
	unsigned char *iv, int encrypt)   This function is used to 
	setup a cipher BIO.  The length of key and iv are 
	specified by the choice of EVP_CIPHER.  Encrypt is 1 to 
	encrypt and 0 to decrypt.

BIO_METHOD *BIO_f_base64(void);
-	BIO_flush() should be called when the last bytes have been output.
This BIO base64 encodes when writing and base64 decodes when 
reading.  It will scan the input until a suitable begin line 
is found.  After reading data, BIO_reset() will reset the 
BIO to start scanning again.  Do not mix reading and writing 
on the same base64 BIO.  It is meant as a single stream BIO.

Directions	type
both		BIO_s_mem()
one/both	BIO_s_file()
both		BIO_s_fd()
both		BIO_s_socket() 
both		BIO_s_null()
both		BIO_f_buffer()
one		BIO_f_md()  
one		BIO_f_cipher()  
one		BIO_f_base64()  
both		BIO_f_ssl()

It is easy to mix one and two directional BIOs, all one has 
to do is to keep two separate BIO pointers for reading and 
writing and be careful about usage of underlying BIOs.  The 
SSL bio by it's very nature has to be two directional but 
the BIO_push() command will push the one BIO into the SSL 
BIO for both reading and writing.

The best example program to look at is apps/enc.c and/or perhaps apps/dgst.c.


/* crypto/bio/bio.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_BIO_H
#define HEADER_BIO_H

#ifdef  __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <stdlib.h>
#include <openssl/crypto.h>

/* These are the 'types' of BIOs */
#define BIO_TYPE_NONE		0
#define BIO_TYPE_MEM		(1|0x0400)
#define BIO_TYPE_FILE		(2|0x0400)

#define BIO_TYPE_FD		(4|0x0400|0x0100)
#define BIO_TYPE_SOCKET		(5|0x0400|0x0100)
#define BIO_TYPE_NULL		(6|0x0400)
#define BIO_TYPE_SSL		(7|0x0200)
#define BIO_TYPE_MD		(8|0x0200)		/* pasive filter */
#define BIO_TYPE_BUFFER		(9|0x0200)		/* filter */
#define BIO_TYPE_CIPHER		(10|0x0200)		/* filter */
#define BIO_TYPE_BASE64		(11|0x0200)		/* filter */
#define BIO_TYPE_CONNECT	(12|0x0400|0x0100)	/* socket - connect */
#define BIO_TYPE_ACCEPT		(13|0x0400|0x0100)	/* socket for accept */
#define BIO_TYPE_PROXY_CLIENT	(14|0x0200)		/* client proxy BIO */
#define BIO_TYPE_PROXY_SERVER	(15|0x0200)		/* server proxy BIO */
#define BIO_TYPE_NBIO_TEST	(16|0x0200)		/* server proxy BIO */
#define BIO_TYPE_NULL_FILTER	(17|0x0200)
#define BIO_TYPE_BER		(18|0x0200)		/* BER -> bin filter */
#define BIO_TYPE_BIO		(19|0x0400)		/* (half a) BIO pair */

#define BIO_TYPE_DESCRIPTOR	0x0100	/* socket, fd, connect or accept */
#define BIO_TYPE_FILTER		0x0200
#define BIO_TYPE_SOURCE_SINK	0x0400

/* BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
 * BIO_set_fp(in,stdin,BIO_NOCLOSE); */
#define BIO_NOCLOSE		0x00
#define BIO_CLOSE		0x01

/* These are used in the following macros and are passed to
 * BIO_ctrl() */
#define BIO_CTRL_RESET		1  /* opt - rewind/zero etc */
#define BIO_CTRL_EOF		2  /* opt - are we at the eof */
#define BIO_CTRL_INFO		3  /* opt - extra tit-bits */
#define BIO_CTRL_SET		4  /* man - set the 'IO' type */
#define BIO_CTRL_GET		5  /* man - get the 'IO' type */
#define BIO_CTRL_PUSH		6  /* opt - internal, used to signify change */
#define BIO_CTRL_POP		7  /* opt - internal, used to signify change */
#define BIO_CTRL_GET_CLOSE	8  /* man - set the 'close' on free */
#define BIO_CTRL_SET_CLOSE	9  /* man - set the 'close' on free */
#define BIO_CTRL_PENDING	10  /* opt - is their more data buffered */
#define BIO_CTRL_FLUSH		11  /* opt - 'flush' buffered output */
#define BIO_CTRL_DUP		12  /* man - extra stuff for 'duped' BIO */
#define BIO_CTRL_WPENDING	13  /* opt - number of bytes still to write */
/* callback is int cb(BIO *bio,state,ret); */
#define BIO_CTRL_SET_CALLBACK	14  /* opt - set callback function */
#define BIO_CTRL_GET_CALLBACK	15  /* opt - set callback function */

#define BIO_CTRL_SET_FILENAME	30	/* BIO_s_file special */

/* modifiers */
#define BIO_FP_READ		0x02
#define BIO_FP_WRITE		0x04
#define BIO_FP_APPEND		0x08
#define BIO_FP_TEXT		0x10

#define BIO_FLAGS_READ		0x01
#define BIO_FLAGS_WRITE		0x02
#define BIO_FLAGS_IO_SPECIAL	0x04
#define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
#define BIO_FLAGS_SHOULD_RETRY	0x08

/* Used in BIO_gethostbyname() */
#define BIO_GHBN_CTRL_HITS		1
#define BIO_GHBN_CTRL_MISSES		2
#define BIO_GHBN_CTRL_CACHE_SIZE	3
#define BIO_GHBN_CTRL_GET_ENTRY		4
#define BIO_GHBN_CTRL_FLUSH		5

/* Mostly used in the SSL BIO */
/* Not used anymore
 * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10
 * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20
 * #define BIO_FLAGS_PROTOCOL_STARTUP	0x40
 */

#define BIO_FLAGS_BASE64_NO_NL	0x100

/* This is used with memory BIOs: it means we shouldn't free up or change the
 * data in any way.
 */
#define BIO_FLAGS_MEM_RDONLY	0x200

#define BIO_set_flags(b,f) ((b)->flags|=(f))
#define BIO_get_flags(b) ((b)->flags)
#define BIO_set_retry_special(b) \
		((b)->flags|=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
#define BIO_set_retry_read(b) \
		((b)->flags|=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
#define BIO_set_retry_write(b) \
		((b)->flags|=(BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))

/* These are normally used internally in BIOs */
#define BIO_clear_flags(b,f) ((b)->flags&= ~(f))
#define BIO_clear_retry_flags(b) \
		((b)->flags&= ~(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
#define BIO_get_retry_flags(b) \
		((b)->flags&(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))

/* These shouldbe used by the application to tell why we should retry */
#define BIO_should_read(a)		((a)->flags & BIO_FLAGS_READ)
#define BIO_should_write(a)		((a)->flags & BIO_FLAGS_WRITE)
#define BIO_should_io_special(a)	((a)->flags & BIO_FLAGS_IO_SPECIAL)
#define BIO_retry_type(a)		((a)->flags & BIO_FLAGS_RWS)
#define BIO_should_retry(a)		((a)->flags & BIO_FLAGS_SHOULD_RETRY)

/* The next two are used in conjunction with the
 * BIO_should_io_special() condition.  After this returns true,
 * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO 
 * stack and return the 'reason' for the special and the offending BIO.
 * Given a BIO, BIO_get_retry_reason(bio) will return the code. */
/* Returned from the SSL bio when the certificate retrieval code had an error */
#define BIO_RR_SSL_X509_LOOKUP		0x01
/* Returned from the connect BIO when a connect would have blocked */
#define BIO_RR_CONNECT			0x02

/* These are passed by the BIO callback */
#define BIO_CB_FREE	0x01
#define BIO_CB_READ	0x02
#define BIO_CB_WRITE	0x03
#define BIO_CB_PUTS	0x04
#define BIO_CB_GETS	0x05
#define BIO_CB_CTRL	0x06

/* The callback is called before and after the underling operation,
 * The BIO_CB_RETURN flag indicates if it is after the call */
#define BIO_CB_RETURN	0x80
#define BIO_CB_return(a) ((a)|BIO_CB_RETURN))
#define BIO_cb_pre(a)	(!((a)&BIO_CB_RETURN))
#define BIO_cb_post(a)	((a)&BIO_CB_RETURN)

#define BIO_set_callback(b,cb)		((b)->callback=(cb))
#define BIO_set_callback_arg(b,arg)	((b)->cb_arg=(char *)(arg))
#define BIO_get_callback_arg(b)		((b)->cb_arg)
#define BIO_get_callback(b)		((b)->callback)
#define BIO_method_name(b)		((b)->method->name)
#define BIO_method_type(b)		((b)->method->type)

#ifndef WIN16
typedef struct bio_method_st
	{
	int type;
	const char *name;
	int (*bwrite)();
	int (*bread)();
	int (*bputs)();
	int (*bgets)();
	long (*ctrl)();
	int (*create)();
	int (*destroy)();
	} BIO_METHOD;
#else
typedef struct bio_method_st
	{
	int type;
	const char *name;
	int (_far *bwrite)();
	int (_far *bread)();
	int (_far *bputs)();
	int (_far *bgets)();
	long (_far *ctrl)();
	int (_far *create)();
	int (_far *destroy)();
	} BIO_METHOD;
#endif

typedef struct bio_st
	{
	BIO_METHOD *method;
	/* bio, mode, argp, argi, argl, ret */
	long (*callback)(struct bio_st *,int,const char *,int, long,long);
	char *cb_arg; /* first argument for the callback */

	int init;
	int shutdown;
	int flags;	/* extra storage */
	int retry_reason;
	int num;
	void *ptr;
	struct bio_st *next_bio;	/* used by filter BIOs */
	struct bio_st *prev_bio;	/* used by filter BIOs */
	int references;
	unsigned long num_read;
	unsigned long num_write;

	CRYPTO_EX_DATA ex_data;
	} BIO;

typedef struct bio_f_buffer_ctx_struct
	{
	/* BIO *bio; */ /* this is now in the BIO struct */
	int ibuf_size;	/* how big is the input buffer */
	int obuf_size;	/* how big is the output buffer */

	char *ibuf;		/* the char array */
	int ibuf_len;		/* how many bytes are in it */
	int ibuf_off;		/* write/read offset */

	char *obuf;		/* the char array */
	int obuf_len;		/* how many bytes are in it */
	int obuf_off;		/* write/read offset */
	} BIO_F_BUFFER_CTX;

/* connect BIO stuff */
#define BIO_CONN_S_BEFORE		1
#define BIO_CONN_S_GET_IP		2
#define BIO_CONN_S_GET_PORT		3
#define BIO_CONN_S_CREATE_SOCKET	4
#define BIO_CONN_S_CONNECT		5
#define BIO_CONN_S_OK			6
#define BIO_CONN_S_BLOCKED_CONNECT	7
#define BIO_CONN_S_NBIO			8
/*#define BIO_CONN_get_param_hostname	BIO_ctrl */

#define BIO_number_read(b)	((b)->num_read)
#define BIO_number_written(b)	((b)->num_write)

#define BIO_C_SET_CONNECT			100
#define BIO_C_DO_STATE_MACHINE			101
#define BIO_C_SET_NBIO				102
#define BIO_C_SET_PROXY_PARAM			103
#define BIO_C_SET_FD				104
#define BIO_C_GET_FD				105
#define BIO_C_SET_FILE_PTR			106
#define BIO_C_GET_FILE_PTR			107
#define BIO_C_SET_FILENAME			108
#define BIO_C_SET_SSL				109
#define BIO_C_GET_SSL				110
#define BIO_C_SET_MD				111
#define BIO_C_GET_MD				112
#define BIO_C_GET_CIPHER_STATUS			113
#define BIO_C_SET_BUF_MEM			114
#define BIO_C_GET_BUF_MEM_PTR			115
#define BIO_C_GET_BUFF_NUM_LINES		116
#define BIO_C_SET_BUFF_SIZE			117
#define BIO_C_SET_ACCEPT			118
#define BIO_C_SSL_MODE				119
#define BIO_C_GET_MD_CTX			120
#define BIO_C_GET_PROXY_PARAM			121
#define BIO_C_SET_BUFF_READ_DATA		122 /* data to read first */
#define BIO_C_GET_CONNECT			123
#define BIO_C_GET_ACCEPT			124
#define BIO_C_SET_SSL_RENEGOTIATE_BYTES		125
#define BIO_C_GET_SSL_NUM_RENEGOTIATES		126
#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT	127
#define BIO_C_FILE_SEEK				128
#define BIO_C_GET_CIPHER_CTX			129
#define BIO_C_SET_BUF_MEM_EOF_RETURN		130/*return end of input value*/
#define BIO_C_SET_BIND_MODE			131
#define BIO_C_GET_BIND_MODE			132
#define BIO_C_FILE_TELL				133
#define BIO_C_GET_SOCKS				134
#define BIO_C_SET_SOCKS				135

#define BIO_C_SET_WRITE_BUF_SIZE		136/* for BIO_s_bio */
#define BIO_C_GET_WRITE_BUF_SIZE		137
#define BIO_C_MAKE_BIO_PAIR			138
#define BIO_C_DESTROY_BIO_PAIR			139
#define BIO_C_GET_WRITE_GUARANTEE		140
#define BIO_C_GET_READ_REQUEST			141
#define BIO_C_SHUTDOWN_WR			142
#define BIO_C_NREAD0				143
#define BIO_C_NREAD				144
#define BIO_C_NWRITE0				145
#define BIO_C_NWRITE				146
#define BIO_C_RESET_READ_REQUEST		147


#define BIO_set_app_data(s,arg)		BIO_set_ex_data(s,0,(char *)arg)
#define BIO_get_app_data(s)		BIO_get_ex_data(s,0)

/* BIO_s_connect() and BIO_s_socks4a_connect() */
#define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
#define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
#define BIO_set_conn_ip(b,ip)	  BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
#define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
#define BIO_get_conn_hostname(b)  BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
#define BIO_get_conn_port(b)      BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
#define BIO_get_conn_ip(b,ip) BIO_ptr_ctrl(b,BIO_C_SET_CONNECT,2)
#define BIO_get_conn_int_port(b,port) BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,port)


#define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)

/* BIO_s_accept_socket() */
#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
#define BIO_get_accept_port(b)	BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
/* #define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?"a":NULL)
#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)

#define BIO_BIND_NORMAL			0
#define BIO_BIND_REUSEADDR_IF_UNUSED	1
#define BIO_BIND_REUSEADDR		2
#define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
#define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)

#define BIO_do_connect(b)	BIO_do_handshake(b)
#define BIO_do_accept(b)	BIO_do_handshake(b)
#define BIO_do_handshake(b)	BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)

/* BIO_s_proxy_client() */
#define BIO_set_url(b,url)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url))
#define BIO_set_proxies(b,p)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p))
/* BIO_set_nbio(b,n) */
#define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
/* BIO *BIO_get_filter_bio(BIO *bio); */
#define BIO_set_proxy_cb(b,cb) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(char *)(cb))
#define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
#define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)

#define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp)
#define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p))
#define BIO_get_url(b,url)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url))
#define BIO_get_no_connect_return(b)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL)

#define BIO_set_fd(b,fd,c)	BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
#define BIO_get_fd(b,c)		BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)

#define BIO_set_fp(b,fp,c)	BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
#define BIO_get_fp(b,fpp)	BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)

#define BIO_seek(b,ofs)	(int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
#define BIO_tell(b)	(int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)

/* name is cast to lose const, but might be better to route through a function
   so we can do it safely */
#ifdef CONST_STRICT
/* If you are wondering why this isn't defined, its because CONST_STRICT is
 * purely a compile-time kludge to allow const to be checked.
 */
int BIO_read_filename(BIO *b,const char *name);
#else
#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
		BIO_CLOSE|BIO_FP_READ,(char *)name)
#endif
#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
		BIO_CLOSE|BIO_FP_WRITE,name)
#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
		BIO_CLOSE|BIO_FP_APPEND,name)
#define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
		BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)

/* WARNING WARNING, this ups the reference count on the read bio of the
 * SSL structure.  This is because the ssl read BIO is now pointed to by
 * the next_bio field in the bio.  So when you free the BIO, make sure
 * you are doing a BIO_free_all() to catch the underlying BIO. */
#define BIO_set_ssl(b,ssl,c)	BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
#define BIO_get_ssl(b,sslp)	BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
#define BIO_set_ssl_mode(b,client)	BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
#define BIO_set_ssl_renegotiate_bytes(b,num) \
	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
#define BIO_get_num_renegotiates(b) \
	BIO_ctrl(b,BIO_C_SET_SSL_NUM_RENEGOTIATES,0,NULL);
#define BIO_set_ssl_renegotiate_timeout(b,seconds) \
	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);

/* defined in evp.h */
/* #define BIO_set_md(b,md)	BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */

#define BIO_get_mem_data(b,pp)	BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
#define BIO_set_mem_buf(b,bm,c)	BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
#define BIO_get_mem_ptr(b,pp)	BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
#define BIO_set_mem_eof_return(b,v) \
				BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)

/* For the BIO_f_buffer() type */
#define BIO_get_buffer_num_lines(b)	BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
#define BIO_set_buffer_size(b,size)	BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
#define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
#define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
#define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)

/* Don't use the next one unless you know what you are doing :-) */
#define BIO_dup_state(b,ret)	BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))

#define BIO_reset(b)		(int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
#define BIO_eof(b)		(int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
#define BIO_set_close(b,c)	(int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
#define BIO_get_close(b)	(int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
#define BIO_pending(b)		(int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
#define BIO_wpending(b)		(int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
/* ...pending macros have inappropriate return type */
size_t BIO_ctrl_pending(BIO *b);
size_t BIO_ctrl_wpending(BIO *b);
#define BIO_flush(b)		(int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0,(char *)cbp)
#define BIO_set_info_callback(b,cb) (int)BIO_ctrl(b,BIO_CTRL_SET_CALLBACK,0,(char *)cb)

/* For the BIO_f_buffer() type */
#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)

/* For BIO_s_bio() */
#define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
#define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
#define BIO_make_bio_pair(b1,b2)   (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
#define BIO_destroy_bio_pair(b)    (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
/* macros with inappropriate type -- but ...pending macros use int too: */
#define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
#define BIO_get_read_request(b)    (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
size_t BIO_ctrl_get_write_guarantee(BIO *b);
size_t BIO_ctrl_get_read_request(BIO *b);
int BIO_ctrl_reset_read_request(BIO *b);

#ifdef NO_STDIO
#define NO_FP_API
#endif


/* These two aren't currently implemented */
/* int BIO_get_ex_num(BIO *bio); */
/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */
int BIO_set_ex_data(BIO *bio,int idx,char *data);
char *BIO_get_ex_data(BIO *bio,int idx);
int BIO_get_ex_new_index(long argl, char *argp, int (*new_func)(),
	int (*dup_func)(), void (*free_func)());

#  if defined(WIN16) && defined(_WINDLL)
BIO_METHOD *BIO_s_file_internal(void);
BIO *BIO_new_file_internal(char *filename, char *mode);
BIO *BIO_new_fp_internal(FILE *stream, int close_flag);
#    define BIO_s_file	BIO_s_file_internal
#    define BIO_new_file	BIO_new_file_internal
#    define BIO_new_fp	BIO_new_fp_internal
#  else /* FP_API */
BIO_METHOD *BIO_s_file(void );
BIO *BIO_new_file(const char *filename, const char *mode);
BIO *BIO_new_fp(FILE *stream, int close_flag);
#    define BIO_s_file_internal		BIO_s_file
#    define BIO_new_file_internal	BIO_new_file
#    define BIO_new_fp_internal		BIO_s_file
#  endif /* FP_API */
BIO *	BIO_new(BIO_METHOD *type);
int	BIO_set(BIO *a,BIO_METHOD *type);
int	BIO_free(BIO *a);
int	BIO_read(BIO *b, void *data, int len);
int	BIO_gets(BIO *bp,char *buf, int size);
int	BIO_write(BIO *b, const char *data, int len);
int	BIO_puts(BIO *bp,const char *buf);
long	BIO_ctrl(BIO *bp,int cmd,long larg,void *parg);
char *	BIO_ptr_ctrl(BIO *bp,int cmd,long larg);
long	BIO_int_ctrl(BIO *bp,int cmd,long larg,int iarg);
BIO *	BIO_push(BIO *b,BIO *append);
BIO *	BIO_pop(BIO *b);
void	BIO_free_all(BIO *a);
BIO *	BIO_find_type(BIO *b,int bio_type);
BIO *	BIO_get_retry_BIO(BIO *bio, int *reason);
int	BIO_get_retry_reason(BIO *bio);
BIO *	BIO_dup_chain(BIO *in);

int BIO_nread0(BIO *bio, char **buf);
int BIO_nread(BIO *bio, char **buf, int num);
int BIO_nwrite0(BIO *bio, char **buf);
int BIO_nwrite(BIO *bio, char **buf, int num);

#ifndef WIN16
long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
	long argl,long ret);
#else
long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
	long argl,long ret);
#endif

BIO_METHOD *BIO_s_mem(void);
BIO *BIO_new_mem_buf(void *buf, int len);
BIO_METHOD *BIO_s_socket(void);
BIO_METHOD *BIO_s_connect(void);
BIO_METHOD *BIO_s_accept(void);
BIO_METHOD *BIO_s_fd(void);
BIO_METHOD *BIO_s_log(void);
BIO_METHOD *BIO_s_bio(void);
BIO_METHOD *BIO_s_null(void);
BIO_METHOD *BIO_f_null(void);
BIO_METHOD *BIO_f_buffer(void);
BIO_METHOD *BIO_f_nbio_test(void);
/* BIO_METHOD *BIO_f_ber(void); */

int BIO_sock_should_retry(int i);
int BIO_sock_non_fatal_error(int error);
int BIO_fd_should_retry(int i);
int BIO_fd_non_fatal_error(int error);
int BIO_dump(BIO *b,const char *bytes,int len);

struct hostent *BIO_gethostbyname(const char *name);
/* We might want a thread-safe interface too:
 * struct hostent *BIO_gethostbyname_r(const char *name,
 *     struct hostent *result, void *buffer, size_t buflen);
 * or something similar (caller allocates a struct hostent,
 * pointed to by "result", and additional buffer space for the various
 * substructures; if the buffer does not suffice, NULL is returned
 * and an appropriate error code is set).
 */
int BIO_sock_error(int sock);
int BIO_socket_ioctl(int fd, long type, unsigned long *arg);
int BIO_socket_nbio(int fd,int mode);
int BIO_get_port(const char *str, unsigned short *port_ptr);
int BIO_get_host_ip(const char *str, unsigned char *ip);
int BIO_get_accept_socket(char *host_port,int mode);
int BIO_accept(int sock,char **ip_port);
int BIO_sock_init(void );
void BIO_sock_cleanup(void);
int BIO_set_tcp_ndelay(int sock,int turn_on);

void ERR_load_BIO_strings(void );

BIO *BIO_new_socket(int sock, int close_flag);
BIO *BIO_new_fd(int fd, int close_flag);
BIO *BIO_new_connect(char *host_port);
BIO *BIO_new_accept(char *host_port);

int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
	BIO **bio2, size_t writebuf2);
/* If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
 * Otherwise returns 0 and sets *bio1 and *bio2 to NULL.
 * Size 0 uses default value.
 */

void BIO_copy_next_retry(BIO *b);

long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);

int BIO_printf(BIO *bio, ...);

/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */

/* Error codes for the BIO functions. */

/* Function codes. */
#define BIO_F_ACPT_STATE				 100
#define BIO_F_BIO_ACCEPT				 101
#define BIO_F_BIO_BER_GET_HEADER			 102
#define BIO_F_BIO_CTRL					 103
#define BIO_F_BIO_GETHOSTBYNAME				 120
#define BIO_F_BIO_GETS					 104
#define BIO_F_BIO_GET_ACCEPT_SOCKET			 105
#define BIO_F_BIO_GET_HOST_IP				 106
#define BIO_F_BIO_GET_PORT				 107
#define BIO_F_BIO_MAKE_PAIR				 121
#define BIO_F_BIO_NEW					 108
#define BIO_F_BIO_NEW_FILE				 109
#define BIO_F_BIO_NEW_MEM_BUF				 126
#define BIO_F_BIO_NREAD					 123
#define BIO_F_BIO_NREAD0				 124
#define BIO_F_BIO_NWRITE				 125
#define BIO_F_BIO_NWRITE0				 122
#define BIO_F_BIO_PUTS					 110
#define BIO_F_BIO_READ					 111
#define BIO_F_BIO_SOCK_INIT				 112
#define BIO_F_BIO_WRITE					 113
#define BIO_F_BUFFER_CTRL				 114
#define BIO_F_CONN_STATE				 115
#define BIO_F_FILE_CTRL					 116
#define BIO_F_MEM_WRITE					 117
#define BIO_F_SSL_NEW					 118
#define BIO_F_WSASTARTUP				 119

/* Reason codes. */
#define BIO_R_ACCEPT_ERROR				 100
#define BIO_R_BAD_FOPEN_MODE				 101
#define BIO_R_BAD_HOSTNAME_LOOKUP			 102
#define BIO_R_BROKEN_PIPE				 124
#define BIO_R_CONNECT_ERROR				 103
#define BIO_R_ERROR_SETTING_NBIO			 104
#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET	 105
#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET	 106
#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET		 107
#define BIO_R_INVALID_ARGUMENT				 125
#define BIO_R_INVALID_IP_ADDRESS			 108
#define BIO_R_IN_USE					 123
#define BIO_R_KEEPALIVE					 109
#define BIO_R_NBIO_CONNECT_ERROR			 110
#define BIO_R_NO_ACCEPT_PORT_SPECIFIED			 111
#define BIO_R_NO_HOSTNAME_SPECIFIED			 112
#define BIO_R_NO_PORT_DEFINED				 113
#define BIO_R_NO_PORT_SPECIFIED				 114
#define BIO_R_NULL_PARAMETER				 115
#define BIO_R_TAG_MISMATCH				 116
#define BIO_R_UNABLE_TO_BIND_SOCKET			 117
#define BIO_R_UNABLE_TO_CREATE_SOCKET			 118
#define BIO_R_UNABLE_TO_LISTEN_SOCKET			 119
#define BIO_R_UNINITIALIZED				 120
#define BIO_R_UNSUPPORTED_METHOD			 121
#define BIO_R_WRITE_TO_READ_ONLY_BIO			 126
#define BIO_R_WSASTARTUP				 122

#ifdef  __cplusplus
}
#endif
#endif


CVSTrac 2.0.1