* Fix a slight bug in the state-machine. This caused the client end of a
[openssl.git] / demos / tunala / buffer.c
index e9a4e5b030cf73e9defc636d4d6944474797eff6..2915f2c67bf1c43118dad0f8f7a764fc2051c383 100644 (file)
@@ -101,6 +101,37 @@ 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;
@@ -109,6 +140,8 @@ void buffer_from_SSL(buffer_t *buf, SSL *ssl)
        ret = SSL_read(ssl, buf->data + buf->used, buffer_unused(buf));
        if(ret > 0)
                buf->used += ret;
+       if(ret < 0)
+               int_ssl_check(ssl, ret);
 }
 
 void buffer_to_SSL(buffer_t *buf, SSL *ssl)
@@ -119,6 +152,8 @@ void buffer_to_SSL(buffer_t *buf, SSL *ssl)
        ret = SSL_write(ssl, buf->data, buf->used);
        if(ret > 0)
                buffer_takedata(buf, NULL, ret);
+       if(ret < 0)
+               int_ssl_check(ssl, ret);
 }
 
 void buffer_from_BIO(buffer_t *buf, BIO *bio)