
built using an abstracted state machine with a non-blocking IP wrapper around it. README will follow in the next commit.
147 lines
3.1 KiB
C
147 lines
3.1 KiB
C
#include "tunala.h"
|
|
|
|
#ifndef NO_BUFFER
|
|
|
|
void buffer_init(buffer_t *buf)
|
|
{
|
|
buf->used = 0;
|
|
}
|
|
|
|
void buffer_close(buffer_t *buf)
|
|
{
|
|
/* Our data is static - nothing needs "release", just reset */
|
|
buffer_init(buf);
|
|
}
|
|
|
|
/* 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 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;
|
|
return added;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
#ifndef NO_IP
|
|
|
|
int buffer_from_fd(buffer_t *buf, int fd)
|
|
{
|
|
unsigned 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;
|
|
return toread;
|
|
}
|
|
|
|
int buffer_to_fd(buffer_t *buf, int fd)
|
|
{
|
|
unsigned 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);
|
|
return towrite;
|
|
}
|
|
|
|
#endif /* !defined(NO_IP) */
|
|
|
|
#ifndef NO_OPENSSL
|
|
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
#endif /* !defined(NO_OPENSSL) */
|
|
|
|
#endif /* !defined(NO_BUFFER) */
|