New macro BIO_set_shutdown_wr().
[openssl.git] / crypto / bio / bss_bio.c
index ad8079495f827e20cca068140b3cadf1effaad27..78c6ab4fdd97ec2af93188ac69b6df04af9c0de3 100644 (file)
 
 #include <openssl/bio.h>
 #include <openssl/err.h>
+#include <openssl/err.h>
 #include <openssl/crypto.h>
 
+#include "openssl/e_os.h"
+#ifndef SSIZE_MAX
+# define SSIZE_MAX INT_MAX
+#endif
+
 static int bio_new(BIO *bio);
 static int bio_free(BIO *bio);
 static int bio_read(BIO *bio, char *buf, int size);
-static int bio_write(BIO *bio, char *buf, int num);
+static int bio_write(BIO *bio, const char *buf, int num);
 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
-static int bio_puts(BIO *bio, char *str);
+static int bio_puts(BIO *bio, const char *str);
 
 static int bio_make_pair(BIO *bio1, BIO *bio2);
 static void bio_destroy_pair(BIO *bio);
@@ -41,7 +47,8 @@ static BIO_METHOD methods_biop =
        NULL /* no bio_gets */,
        bio_ctrl,
        bio_new,
-       bio_free
+       bio_free,
+       NULL /* no bio_callback_ctrl */
 };
 
 BIO_METHOD *BIO_s_bio(void)
@@ -65,7 +72,7 @@ struct bio_bio_st
 
        size_t request; /* valid iff peer != NULL; 0 if len != 0,
                         * otherwise set by peer to number of bytes
-                        * it (unsuccesfully) tried to read,
+                        * it (unsuccessfully) tried to read,
                         * never more than buffer space (size-len) warrants. */
 };
 
@@ -73,7 +80,7 @@ static int bio_new(BIO *bio)
        {
        struct bio_bio_st *b;
        
-       b = Malloc(sizeof *b);
+       b = OPENSSL_malloc(sizeof *b);
        if (b == NULL)
                return 0;
 
@@ -101,10 +108,10 @@ static int bio_free(BIO *bio)
        
        if (b->buf != NULL)
                {
-               Free(b->buf);
+               OPENSSL_free(b->buf);
                }
 
-       Free(b);
+       OPENSSL_free(b);
 
        return 1;
        }
@@ -202,13 +209,12 @@ static int bio_read(BIO *bio, char *buf, int size_)
  * (example usage:  bio_nread0(), read from buffer, bio_nread()
  *  or just         bio_nread(), read from buffer)
  */
-/* WARNING: The non-copying interface is totally untested as of yet --
- * I wrote it, but have not yet read it; and surely it still is full
- * of bugs. */
-static size_t bio_nread0(BIO *bio, char **buf)
+/* WARNING: The non-copying interface is largely untested as of yet
+ * and may contain bugs. */
+static ssize_t bio_nread0(BIO *bio, char **buf)
        {
        struct bio_bio_st *b, *peer_b;
-       size_t num;
+       ssize_t num;
        
        BIO_clear_retry_flags(bio);
 
@@ -229,7 +235,7 @@ static size_t bio_nread0(BIO *bio, char **buf)
                char dummy;
                
                /* avoid code duplication -- nothing available for reading */
-               return bio_read(bio, &dummy, num); /* returns 0 or -1 */
+               return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
                }
 
        num = peer_b->len;
@@ -243,10 +249,15 @@ static size_t bio_nread0(BIO *bio, char **buf)
        return num;
        }
 
-static size_t bio_nread(BIO *bio, char **buf, size_t num)
+static ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
        {
        struct bio_bio_st *b, *peer_b;
-       size_t available;
+       ssize_t num, available;
+
+       if (num_ > SSIZE_MAX)
+               num = SSIZE_MAX;
+       else
+               num = (ssize_t)num_;
 
        available = bio_nread0(bio, buf);
        if (num > available)
@@ -272,7 +283,7 @@ static size_t bio_nread(BIO *bio, char **buf, size_t num)
        }
 
 
-static int bio_write(BIO *bio, char *buf, int num_)
+static int bio_write(BIO *bio, const char *buf, int num_)
        {
        size_t num = num_;
        size_t rest;
@@ -351,7 +362,7 @@ static int bio_write(BIO *bio, char *buf, int num_)
  * (example usage:  bio_nwrite0(), write to buffer, bio_nwrite()
  *  or just         bio_nwrite(), write to buffer)
  */
-static size_t bio_nwrite0(BIO *bio, char **buf)
+static ssize_t bio_nwrite0(BIO *bio, char **buf)
        {
        struct bio_bio_st *b;
        size_t num;
@@ -399,16 +410,23 @@ static size_t bio_nwrite0(BIO *bio, char **buf)
        return num;
        }
 
-static size_t bio_nwrite(BIO *bio, char **buf, size_t num)
+static ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
        {
        struct bio_bio_st *b;
-       size_t space;
+       ssize_t num, space;
+
+       if (num_ > SSIZE_MAX)
+               num = SSIZE_MAX;
+       else
+               num = (ssize_t)num_;
 
        space = bio_nwrite0(bio, buf);
        if (num > space)
                num = space;
        if (num <= 0)
                return num;
+       b = bio->ptr;
+       assert(b != NULL);
        b->len += num;
        assert(b->len <= b->size);
 
@@ -446,7 +464,7 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
                                {
                                if (b->buf) 
                                        {
-                                       Free(b->buf);
+                                       OPENSSL_free(b->buf);
                                        b->buf = NULL;
                                        }
                                b->size = new_size;
@@ -478,7 +496,7 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
 
        case BIO_C_GET_WRITE_GUARANTEE:
                /* How many bytes can the caller feed to the next write
-                * withouth having to keep any? */
+                * without having to keep any? */
                if (b->peer == NULL || b->closed)
                        ret = 0;
                else
@@ -486,18 +504,32 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
                break;
 
        case BIO_C_GET_READ_REQUEST:
-               /* If the peer unsuccesfully tried to read, how many bytes
+               /* If the peer unsuccessfully tried to read, how many bytes
                 * were requested?  (As with BIO_CTRL_PENDING, that number
                 * can usually be treated as boolean.) */
                ret = (long) b->request;
                break;
 
+       case BIO_C_RESET_READ_REQUEST:
+               /* Reset request.  (Can be useful after read attempts
+                * at the other side that are meant to be non-blocking,
+                * e.g. when probing SSL_read to see if any data is
+                * available.) */
+               b->request = 0;
+               ret = 1;
+               break;
+
        case BIO_C_SHUTDOWN_WR:
                /* similar to shutdown(..., SHUT_WR) */
                b->closed = 1;
                ret = 1;
                break;
 
+       case BIO_C_NREAD0:
+               /* prepare for non-copying read */
+               ret = (long) bio_nread0(bio, ptr);
+               break;
+               
        case BIO_C_NREAD:
                /* non-copying read */
                ret = (long) bio_nread(bio, ptr, (size_t) num);
@@ -596,7 +628,7 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
        return ret;
        }
 
-static int bio_puts(BIO *bio, char *str)
+static int bio_puts(BIO *bio, const char *str)
        {
        return bio_write(bio, str, strlen(str));
        }
@@ -620,7 +652,7 @@ static int bio_make_pair(BIO *bio1, BIO *bio2)
        
        if (b1->buf == NULL)
                {
-               b1->buf = Malloc(b1->size);
+               b1->buf = OPENSSL_malloc(b1->size);
                if (b1->buf == NULL)
                        {
                        BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
@@ -632,7 +664,7 @@ static int bio_make_pair(BIO *bio1, BIO *bio2)
        
        if (b2->buf == NULL)
                {
-               b2->buf = Malloc(b2->size);
+               b2->buf = OPENSSL_malloc(b2->size);
                if (b2->buf == NULL)
                        {
                        BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
@@ -749,8 +781,13 @@ size_t BIO_ctrl_get_read_request(BIO *bio)
        return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
        }
 
+int BIO_ctrl_reset_read_request(BIO *bio)
+       {
+       return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
+       }
+
 
-/* BIO_nread0/nread/nwrite0/nwrite are availabe only for BIO pairs for now
+/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
  * (conceivably some other BIOs could allow non-copying reads and writes too.)
  */
 int BIO_nread0(BIO *bio, char **buf)