Initial Commit
This commit is contained in:
236
openssl-1.0.2f/demos/tunala/buffer.c
Normal file
236
openssl-1.0.2f/demos/tunala/buffer.c
Normal file
@@ -0,0 +1,236 @@
|
||||
#include "tunala.h"
|
||||
|
||||
#ifndef NO_BUFFER
|
||||
|
||||
void buffer_init(buffer_t * buf)
|
||||
{
|
||||
buf->used = 0;
|
||||
buf->total_in = buf->total_out = 0;
|
||||
}
|
||||
|
||||
void buffer_close(buffer_t * buf)
|
||||
{
|
||||
/* Our data is static - nothing needs "release", just reset it */
|
||||
buf->used = 0;
|
||||
}
|
||||
|
||||
/* Code these simple ones in compact form */
|
||||
unsigned int buffer_used(buffer_t * buf)
|
||||
{
|
||||
return buf->used;
|
||||
}
|
||||
|
||||
unsigned int buffer_unused(buffer_t * buf)
|
||||
{
|
||||
return (MAX_DATA_SIZE - buf->used);
|
||||
}
|
||||
|
||||
int buffer_full(buffer_t * buf)
|
||||
{
|
||||
return (buf->used == MAX_DATA_SIZE ? 1 : 0);
|
||||
}
|
||||
|
||||
int buffer_notfull(buffer_t * buf)
|
||||
{
|
||||
return (buf->used < MAX_DATA_SIZE ? 1 : 0);
|
||||
}
|
||||
|
||||
int buffer_empty(buffer_t * buf)
|
||||
{
|
||||
return (buf->used == 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
int buffer_notempty(buffer_t * buf)
|
||||
{
|
||||
return (buf->used > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
unsigned long buffer_total_in(buffer_t * buf)
|
||||
{
|
||||
return buf->total_in;
|
||||
}
|
||||
|
||||
unsigned long buffer_total_out(buffer_t * buf)
|
||||
{
|
||||
return buf->total_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* These 3 static (internal) functions don't adjust the "total" variables as
|
||||
* it's not sure when they're called how it should be interpreted. Only the
|
||||
* higher-level "buffer_[to|from]_[fd|SSL|BIO]" functions should alter these
|
||||
* values.
|
||||
*/
|
||||
# if 0 /* To avoid "unused" warnings */
|
||||
static unsigned int buffer_adddata(buffer_t * buf, const unsigned char *ptr,
|
||||
unsigned int size)
|
||||
{
|
||||
unsigned int added = MAX_DATA_SIZE - buf->used;
|
||||
if (added > size)
|
||||
added = size;
|
||||
if (added == 0)
|
||||
return 0;
|
||||
memcpy(buf->data + buf->used, ptr, added);
|
||||
buf->used += added;
|
||||
buf->total_in += added;
|
||||
return added;
|
||||
}
|
||||
|
||||
static unsigned int buffer_tobuffer(buffer_t * to, buffer_t * from, int cap)
|
||||
{
|
||||
unsigned int moved, tomove = from->used;
|
||||
if ((int)tomove > cap)
|
||||
tomove = cap;
|
||||
if (tomove == 0)
|
||||
return 0;
|
||||
moved = buffer_adddata(to, from->data, tomove);
|
||||
if (moved == 0)
|
||||
return 0;
|
||||
buffer_takedata(from, NULL, moved);
|
||||
return moved;
|
||||
}
|
||||
# endif
|
||||
|
||||
static unsigned int buffer_takedata(buffer_t * buf, unsigned char *ptr,
|
||||
unsigned int size)
|
||||
{
|
||||
unsigned int taken = buf->used;
|
||||
if (taken > size)
|
||||
taken = size;
|
||||
if (taken == 0)
|
||||
return 0;
|
||||
if (ptr)
|
||||
memcpy(ptr, buf->data, taken);
|
||||
buf->used -= taken;
|
||||
/* Do we have to scroll? */
|
||||
if (buf->used > 0)
|
||||
memmove(buf->data, buf->data + taken, buf->used);
|
||||
return taken;
|
||||
}
|
||||
|
||||
# ifndef NO_IP
|
||||
|
||||
int buffer_from_fd(buffer_t * buf, int fd)
|
||||
{
|
||||
int toread = buffer_unused(buf);
|
||||
if (toread == 0)
|
||||
/* Shouldn't be called in this case! */
|
||||
abort();
|
||||
toread = read(fd, buf->data + buf->used, toread);
|
||||
if (toread > 0) {
|
||||
buf->used += toread;
|
||||
buf->total_in += toread;
|
||||
}
|
||||
return toread;
|
||||
}
|
||||
|
||||
int buffer_to_fd(buffer_t * buf, int fd)
|
||||
{
|
||||
int towrite = buffer_used(buf);
|
||||
if (towrite == 0)
|
||||
/* Shouldn't be called in this case! */
|
||||
abort();
|
||||
towrite = write(fd, buf->data, towrite);
|
||||
if (towrite > 0) {
|
||||
buffer_takedata(buf, NULL, towrite);
|
||||
buf->total_out += towrite;
|
||||
}
|
||||
return towrite;
|
||||
}
|
||||
|
||||
# endif /* !defined(NO_IP) */
|
||||
|
||||
# ifndef NO_OPENSSL
|
||||
|
||||
static void int_ssl_check(SSL *s, int ret)
|
||||
{
|
||||
int e = SSL_get_error(s, ret);
|
||||
switch (e) {
|
||||
/*
|
||||
* These seem to be harmless and already "dealt with" by our
|
||||
* non-blocking environment. NB: "ZERO_RETURN" is the clean "error"
|
||||
* indicating a successfully closed SSL tunnel. We let this happen
|
||||
* because our IO loop should not appear to have broken on this
|
||||
* condition - and outside the IO loop, the "shutdown" state is
|
||||
* checked.
|
||||
*/
|
||||
case SSL_ERROR_NONE:
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
return;
|
||||
/*
|
||||
* These seem to be indications of a genuine error that should result
|
||||
* in the SSL tunnel being regarded as "dead".
|
||||
*/
|
||||
case SSL_ERROR_SYSCALL:
|
||||
case SSL_ERROR_SSL:
|
||||
SSL_set_app_data(s, (char *)1);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* For any other errors that (a) exist, and (b) crop up - we need to
|
||||
* interpret what to do with them - so "politely inform" the caller that
|
||||
* the code needs updating here.
|
||||
*/
|
||||
abort();
|
||||
}
|
||||
|
||||
void buffer_from_SSL(buffer_t * buf, SSL *ssl)
|
||||
{
|
||||
int ret;
|
||||
if (!ssl || buffer_full(buf))
|
||||
return;
|
||||
ret = SSL_read(ssl, buf->data + buf->used, buffer_unused(buf));
|
||||
if (ret > 0) {
|
||||
buf->used += ret;
|
||||
buf->total_in += ret;
|
||||
}
|
||||
if (ret < 0)
|
||||
int_ssl_check(ssl, ret);
|
||||
}
|
||||
|
||||
void buffer_to_SSL(buffer_t * buf, SSL *ssl)
|
||||
{
|
||||
int ret;
|
||||
if (!ssl || buffer_empty(buf))
|
||||
return;
|
||||
ret = SSL_write(ssl, buf->data, buf->used);
|
||||
if (ret > 0) {
|
||||
buffer_takedata(buf, NULL, ret);
|
||||
buf->total_out += ret;
|
||||
}
|
||||
if (ret < 0)
|
||||
int_ssl_check(ssl, ret);
|
||||
}
|
||||
|
||||
void buffer_from_BIO(buffer_t * buf, BIO *bio)
|
||||
{
|
||||
int ret;
|
||||
if (!bio || buffer_full(buf))
|
||||
return;
|
||||
ret = BIO_read(bio, buf->data + buf->used, buffer_unused(buf));
|
||||
if (ret > 0) {
|
||||
buf->used += ret;
|
||||
buf->total_in += ret;
|
||||
}
|
||||
}
|
||||
|
||||
void buffer_to_BIO(buffer_t * buf, BIO *bio)
|
||||
{
|
||||
int ret;
|
||||
if (!bio || buffer_empty(buf))
|
||||
return;
|
||||
ret = BIO_write(bio, buf->data, buf->used);
|
||||
if (ret > 0) {
|
||||
buffer_takedata(buf, NULL, ret);
|
||||
buf->total_out += ret;
|
||||
}
|
||||
}
|
||||
|
||||
# endif /* !defined(NO_OPENSSL) */
|
||||
|
||||
#endif /* !defined(NO_BUFFER) */
|
||||
Reference in New Issue
Block a user