buffer.c revision 296465
1139743Simp#include "tunala.h" 239212Sgibbs 339212Sgibbs#ifndef NO_BUFFER 439212Sgibbs 539212Sgibbsvoid buffer_init(buffer_t * buf) 639212Sgibbs{ 739212Sgibbs buf->used = 0; 839212Sgibbs buf->total_in = buf->total_out = 0; 939212Sgibbs} 1039212Sgibbs 1139212Sgibbsvoid buffer_close(buffer_t * buf) 1239212Sgibbs{ 1339212Sgibbs /* Our data is static - nothing needs "release", just reset it */ 1439212Sgibbs buf->used = 0; 1539212Sgibbs} 1639212Sgibbs 1739212Sgibbs/* Code these simple ones in compact form */ 1839212Sgibbsunsigned int buffer_used(buffer_t * buf) 1939212Sgibbs{ 2039212Sgibbs return buf->used; 2139212Sgibbs} 2239212Sgibbs 2339212Sgibbsunsigned int buffer_unused(buffer_t * buf) 2439212Sgibbs{ 2539212Sgibbs return (MAX_DATA_SIZE - buf->used); 2639212Sgibbs} 2739212Sgibbs 2850477Speterint buffer_full(buffer_t * buf) 2939212Sgibbs{ 3039212Sgibbs return (buf->used == MAX_DATA_SIZE ? 1 : 0); 3139212Sgibbs} 3239212Sgibbs 3339212Sgibbsint buffer_notfull(buffer_t * buf) 3455206Speter{ 3539212Sgibbs return (buf->used < MAX_DATA_SIZE ? 1 : 0); 3639212Sgibbs} 3739212Sgibbs 3839212Sgibbsint buffer_empty(buffer_t * buf) 3939212Sgibbs{ 4039212Sgibbs return (buf->used == 0 ? 1 : 0); 4139212Sgibbs} 4239212Sgibbs 4339212Sgibbsint buffer_notempty(buffer_t * buf) 4439212Sgibbs{ 4539212Sgibbs return (buf->used > 0 ? 1 : 0); 4639212Sgibbs} 4739212Sgibbs 4839212Sgibbsunsigned long buffer_total_in(buffer_t * buf) 4939212Sgibbs{ 5039212Sgibbs return buf->total_in; 5139212Sgibbs} 5239212Sgibbs 5360938Sjakeunsigned long buffer_total_out(buffer_t * buf) 5460938Sjake{ 5560938Sjake return buf->total_out; 5639212Sgibbs} 5739212Sgibbs 5839212Sgibbs/* 5939212Sgibbs * These 3 static (internal) functions don't adjust the "total" variables as 6039212Sgibbs * it's not sure when they're called how it should be interpreted. Only the 6139212Sgibbs * higher-level "buffer_[to|from]_[fd|SSL|BIO]" functions should alter these 6239212Sgibbs * values. 6341813Sgibbs */ 6439212Sgibbs# if 0 /* To avoid "unused" warnings */ 6539212Sgibbsstatic unsigned int buffer_adddata(buffer_t * buf, const unsigned char *ptr, 6639212Sgibbs unsigned int size) 6739212Sgibbs{ 6839212Sgibbs unsigned int added = MAX_DATA_SIZE - buf->used; 6939212Sgibbs if (added > size) 7039212Sgibbs added = size; 7139212Sgibbs if (added == 0) 7239212Sgibbs return 0; 7339212Sgibbs memcpy(buf->data + buf->used, ptr, added); 7439212Sgibbs buf->used += added; 7539212Sgibbs buf->total_in += added; 7639212Sgibbs return added; 7739212Sgibbs} 7839212Sgibbs 7939212Sgibbsstatic unsigned int buffer_tobuffer(buffer_t * to, buffer_t * from, int cap) 8039212Sgibbs{ 8139212Sgibbs unsigned int moved, tomove = from->used; 8239212Sgibbs if ((int)tomove > cap) 8339212Sgibbs tomove = cap; 8439212Sgibbs if (tomove == 0) 8539212Sgibbs return 0; 8639212Sgibbs moved = buffer_adddata(to, from->data, tomove); 8739212Sgibbs if (moved == 0) 8839212Sgibbs return 0; 8939212Sgibbs buffer_takedata(from, NULL, moved); 9039212Sgibbs return moved; 9139212Sgibbs} 9239212Sgibbs# endif 9339212Sgibbs 9439212Sgibbsstatic unsigned int buffer_takedata(buffer_t * buf, unsigned char *ptr, 9539212Sgibbs unsigned int size) 9639212Sgibbs{ 9739212Sgibbs unsigned int taken = buf->used; 9839212Sgibbs if (taken > size) 9939212Sgibbs taken = size; 10039212Sgibbs if (taken == 0) 10139212Sgibbs return 0; 10239212Sgibbs if (ptr) 10339212Sgibbs memcpy(ptr, buf->data, taken); 10439212Sgibbs buf->used -= taken; 10539212Sgibbs /* Do we have to scroll? */ 10639212Sgibbs if (buf->used > 0) 10739212Sgibbs memmove(buf->data, buf->data + taken, buf->used); 10839212Sgibbs return taken; 10939212Sgibbs} 11039212Sgibbs 11139212Sgibbs# ifndef NO_IP 11239212Sgibbs 11339212Sgibbsint buffer_from_fd(buffer_t * buf, int fd) 11439212Sgibbs{ 11539212Sgibbs int toread = buffer_unused(buf); 11639212Sgibbs if (toread == 0) 11739212Sgibbs /* Shouldn't be called in this case! */ 11839212Sgibbs abort(); 11939212Sgibbs toread = read(fd, buf->data + buf->used, toread); 12039212Sgibbs if (toread > 0) { 12139212Sgibbs buf->used += toread; 12239212Sgibbs buf->total_in += toread; 12339212Sgibbs } 12439212Sgibbs return toread; 12539212Sgibbs} 12639212Sgibbs 12739212Sgibbsint buffer_to_fd(buffer_t * buf, int fd) 12839212Sgibbs{ 12939212Sgibbs int towrite = buffer_used(buf); 13039212Sgibbs if (towrite == 0) 13139212Sgibbs /* Shouldn't be called in this case! */ 13239212Sgibbs abort(); 13339212Sgibbs towrite = write(fd, buf->data, towrite); 13439212Sgibbs if (towrite > 0) { 13539212Sgibbs buffer_takedata(buf, NULL, towrite); 13639212Sgibbs buf->total_out += towrite; 13739212Sgibbs } 13839212Sgibbs return towrite; 13945844Sgibbs} 14039212Sgibbs 14145844Sgibbs# endif /* !defined(NO_IP) */ 14245844Sgibbs 14345844Sgibbs# ifndef NO_OPENSSL 14439212Sgibbs 14539212Sgibbsstatic void int_ssl_check(SSL *s, int ret) 14639212Sgibbs{ 14739212Sgibbs int e = SSL_get_error(s, ret); 14839212Sgibbs switch (e) { 14939212Sgibbs /* 15039212Sgibbs * These seem to be harmless and already "dealt with" by our 15139212Sgibbs * non-blocking environment. NB: "ZERO_RETURN" is the clean "error" 15239212Sgibbs * indicating a successfully closed SSL tunnel. We let this happen 15339212Sgibbs * because our IO loop should not appear to have broken on this 15439212Sgibbs * condition - and outside the IO loop, the "shutdown" state is 15539212Sgibbs * checked. 15639212Sgibbs */ 15739212Sgibbs case SSL_ERROR_NONE: 15839212Sgibbs case SSL_ERROR_WANT_READ: 15939212Sgibbs case SSL_ERROR_WANT_WRITE: 16039212Sgibbs case SSL_ERROR_WANT_X509_LOOKUP: 16139212Sgibbs case SSL_ERROR_ZERO_RETURN: 16239212Sgibbs return; 16339212Sgibbs /* 16439212Sgibbs * These seem to be indications of a genuine error that should result 16539212Sgibbs * in the SSL tunnel being regarded as "dead". 16639212Sgibbs */ 16739212Sgibbs case SSL_ERROR_SYSCALL: 16839212Sgibbs case SSL_ERROR_SSL: 16939212Sgibbs SSL_set_app_data(s, (char *)1); 17039212Sgibbs return; 17139212Sgibbs default: 17239212Sgibbs break; 17339212Sgibbs } 17439212Sgibbs /* 17539212Sgibbs * For any other errors that (a) exist, and (b) crop up - we need to 17639212Sgibbs * interpret what to do with them - so "politely inform" the caller that 17739212Sgibbs * the code needs updating here. 17839212Sgibbs */ 17939212Sgibbs abort(); 18039212Sgibbs} 18139212Sgibbs 18239212Sgibbsvoid buffer_from_SSL(buffer_t * buf, SSL *ssl) 18339212Sgibbs{ 18439212Sgibbs int ret; 18539212Sgibbs if (!ssl || buffer_full(buf)) 18639212Sgibbs return; 18739212Sgibbs ret = SSL_read(ssl, buf->data + buf->used, buffer_unused(buf)); 18839212Sgibbs if (ret > 0) { 18939212Sgibbs buf->used += ret; 19039212Sgibbs buf->total_in += ret; 19139212Sgibbs } 19239212Sgibbs if (ret < 0) 19339212Sgibbs int_ssl_check(ssl, ret); 19439212Sgibbs} 19539212Sgibbs 19639212Sgibbsvoid buffer_to_SSL(buffer_t * buf, SSL *ssl) 19739212Sgibbs{ 19839212Sgibbs int ret; 19939212Sgibbs if (!ssl || buffer_empty(buf)) 20039212Sgibbs return; 20139212Sgibbs ret = SSL_write(ssl, buf->data, buf->used); 20239212Sgibbs if (ret > 0) { 20339212Sgibbs buffer_takedata(buf, NULL, ret); 20439212Sgibbs buf->total_out += ret; 20539212Sgibbs } 20639212Sgibbs if (ret < 0) 20739212Sgibbs int_ssl_check(ssl, ret); 20839212Sgibbs} 20939212Sgibbs 21039212Sgibbsvoid buffer_from_BIO(buffer_t * buf, BIO *bio) 21139212Sgibbs{ 21239212Sgibbs int ret; 21339212Sgibbs if (!bio || buffer_full(buf)) 21439212Sgibbs return; 21539212Sgibbs ret = BIO_read(bio, buf->data + buf->used, buffer_unused(buf)); 21639212Sgibbs if (ret > 0) { 21739212Sgibbs buf->used += ret; 21839212Sgibbs buf->total_in += ret; 21939212Sgibbs } 22039212Sgibbs} 22139212Sgibbs 22239212Sgibbsvoid buffer_to_BIO(buffer_t * buf, BIO *bio) 22339212Sgibbs{ 22439212Sgibbs int ret; 22539212Sgibbs if (!bio || buffer_empty(buf)) 22639212Sgibbs return; 22739212Sgibbs ret = BIO_write(bio, buf->data, buf->used); 22839212Sgibbs if (ret > 0) { 22939212Sgibbs buffer_takedata(buf, NULL, ret); 23039212Sgibbs buf->total_out += ret; 23139212Sgibbs } 23239212Sgibbs} 23339212Sgibbs 23439212Sgibbs# endif /* !defined(NO_OPENSSL) */ 23539212Sgibbs 23639212Sgibbs#endif /* !defined(NO_BUFFER) */ 23755206Speter