X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=demos%2Ftunala%2Fbuffer.c;h=dc26c88601dc8edbd6603d2c38b042df76010959;hp=e9a4e5b030cf73e9defc636d4d6944474797eff6;hb=9a0438736222ffc66cf6596e395385660695d96d;hpb=d1855cc7af56acb62407618711ee5e90a805e231;ds=sidebyside diff --git a/demos/tunala/buffer.c b/demos/tunala/buffer.c index e9a4e5b030..dc26c88601 100644 --- a/demos/tunala/buffer.c +++ b/demos/tunala/buffer.c @@ -5,12 +5,13 @@ 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 */ - buffer_init(buf); + /* Our data is static - nothing needs "release", just reset it */ + buf->used = 0; } /* Code these simple ones in compact form */ @@ -26,8 +27,17 @@ 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 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; @@ -37,10 +47,26 @@ unsigned int buffer_adddata(buffer_t *buf, const unsigned char *ptr, return 0; memcpy(buf->data + buf->used, ptr, added); buf->used += added; + buf->total_in += added; return added; } -unsigned int buffer_takedata(buffer_t *buf, unsigned char *ptr, +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; @@ -57,20 +83,6 @@ unsigned int buffer_takedata(buffer_t *buf, unsigned char *ptr, 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) @@ -80,8 +92,10 @@ int buffer_from_fd(buffer_t *buf, int fd) /* Shouldn't be called in this case! */ abort(); toread = read(fd, buf->data + buf->used, toread); - if(toread > 0) + if(toread > 0) { buf->used += toread; + buf->total_in += toread; + } return toread; } @@ -92,8 +106,10 @@ int buffer_to_fd(buffer_t *buf, int fd) /* Shouldn't be called in this case! */ abort(); towrite = write(fd, buf->data, towrite); - if(towrite > 0) + if(towrite > 0) { buffer_takedata(buf, NULL, towrite); + buf->total_out += towrite; + } return towrite; } @@ -101,14 +117,49 @@ int buffer_to_fd(buffer_t *buf, int fd) #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) + 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) @@ -117,8 +168,12 @@ void buffer_to_SSL(buffer_t *buf, SSL *ssl) if(!ssl || buffer_empty(buf)) return; ret = SSL_write(ssl, buf->data, buf->used); - if(ret > 0) + 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) @@ -127,8 +182,10 @@ void buffer_from_BIO(buffer_t *buf, BIO *bio) if(!bio || buffer_full(buf)) return; ret = BIO_read(bio, buf->data + buf->used, buffer_unused(buf)); - if(ret > 0) + if(ret > 0) { buf->used += ret; + buf->total_in += ret; + } } void buffer_to_BIO(buffer_t *buf, BIO *bio) @@ -137,8 +194,10 @@ void buffer_to_BIO(buffer_t *buf, BIO *bio) if(!bio || buffer_empty(buf)) return; ret = BIO_write(bio, buf->data, buf->used); - if(ret > 0) + if(ret > 0) { buffer_takedata(buf, NULL, ret); + buf->total_out += ret; + } } #endif /* !defined(NO_OPENSSL) */