Home | History | Annotate | Line # | Download | only in dist
bufferevent_openssl.c revision 1.1.1.1.16.1
      1  1.1.1.1.16.1  pgoyette /*	$NetBSD: bufferevent_openssl.c,v 1.1.1.1.16.1 2017/03/20 06:52:21 pgoyette Exp $	*/
      2           1.1  christos /*
      3           1.1  christos  * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
      4           1.1  christos  *
      5           1.1  christos  * Redistribution and use in source and binary forms, with or without
      6           1.1  christos  * modification, are permitted provided that the following conditions
      7           1.1  christos  * are met:
      8           1.1  christos  * 1. Redistributions of source code must retain the above copyright
      9           1.1  christos  *    notice, this list of conditions and the following disclaimer.
     10           1.1  christos  * 2. Redistributions in binary form must reproduce the above copyright
     11           1.1  christos  *    notice, this list of conditions and the following disclaimer in the
     12           1.1  christos  *    documentation and/or other materials provided with the distribution.
     13           1.1  christos  * 3. The name of the author may not be used to endorse or promote products
     14           1.1  christos  *    derived from this software without specific prior written permission.
     15           1.1  christos  *
     16           1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17           1.1  christos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18           1.1  christos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19           1.1  christos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20           1.1  christos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21           1.1  christos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22           1.1  christos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23           1.1  christos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24           1.1  christos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25           1.1  christos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26           1.1  christos  */
     27           1.1  christos 
     28  1.1.1.1.16.1  pgoyette // Get rid of OSX 10.7 and greater deprecation warnings.
     29  1.1.1.1.16.1  pgoyette #if defined(__APPLE__) && defined(__clang__)
     30  1.1.1.1.16.1  pgoyette #pragma clang diagnostic ignored "-Wdeprecated-declarations"
     31  1.1.1.1.16.1  pgoyette #endif
     32           1.1  christos 
     33           1.1  christos #include "event2/event-config.h"
     34           1.1  christos #include <sys/cdefs.h>
     35  1.1.1.1.16.1  pgoyette __RCSID("$NetBSD: bufferevent_openssl.c,v 1.1.1.1.16.1 2017/03/20 06:52:21 pgoyette Exp $");
     36  1.1.1.1.16.1  pgoyette #include "evconfig-private.h"
     37  1.1.1.1.16.1  pgoyette 
     38  1.1.1.1.16.1  pgoyette #include <sys/types.h>
     39           1.1  christos 
     40  1.1.1.1.16.1  pgoyette #ifdef EVENT__HAVE_SYS_TIME_H
     41           1.1  christos #include <sys/time.h>
     42           1.1  christos #endif
     43           1.1  christos 
     44           1.1  christos #include <errno.h>
     45           1.1  christos #include <stdio.h>
     46           1.1  christos #include <stdlib.h>
     47           1.1  christos #include <string.h>
     48  1.1.1.1.16.1  pgoyette #ifdef EVENT__HAVE_STDARG_H
     49           1.1  christos #include <stdarg.h>
     50           1.1  christos #endif
     51  1.1.1.1.16.1  pgoyette #ifdef EVENT__HAVE_UNISTD_H
     52           1.1  christos #include <unistd.h>
     53           1.1  christos #endif
     54           1.1  christos 
     55  1.1.1.1.16.1  pgoyette #ifdef _WIN32
     56           1.1  christos #include <winsock2.h>
     57           1.1  christos #endif
     58           1.1  christos 
     59           1.1  christos #include "event2/bufferevent.h"
     60           1.1  christos #include "event2/bufferevent_struct.h"
     61           1.1  christos #include "event2/bufferevent_ssl.h"
     62           1.1  christos #include "event2/buffer.h"
     63           1.1  christos #include "event2/event.h"
     64           1.1  christos 
     65           1.1  christos #include "mm-internal.h"
     66           1.1  christos #include "bufferevent-internal.h"
     67           1.1  christos #include "log-internal.h"
     68           1.1  christos 
     69           1.1  christos #include <openssl/bio.h>
     70           1.1  christos #include <openssl/ssl.h>
     71           1.1  christos #include <openssl/err.h>
     72  1.1.1.1.16.1  pgoyette #include "openssl-compat.h"
     73           1.1  christos 
     74           1.1  christos /*
     75           1.1  christos  * Define an OpenSSL bio that targets a bufferevent.
     76           1.1  christos  */
     77           1.1  christos 
     78           1.1  christos /* --------------------
     79           1.1  christos    A BIO is an OpenSSL abstraction that handles reading and writing data.  The
     80           1.1  christos    library will happily speak SSL over anything that implements a BIO
     81           1.1  christos    interface.
     82           1.1  christos 
     83           1.1  christos    Here we define a BIO implementation that directs its output to a
     84           1.1  christos    bufferevent.  We'll want to use this only when none of OpenSSL's built-in
     85           1.1  christos    IO mechanisms work for us.
     86           1.1  christos    -------------------- */
     87           1.1  christos 
     88           1.1  christos /* every BIO type needs its own integer type value. */
     89           1.1  christos #define BIO_TYPE_LIBEVENT 57
     90           1.1  christos /* ???? Arguably, we should set BIO_TYPE_FILTER or BIO_TYPE_SOURCE_SINK on
     91           1.1  christos  * this. */
     92           1.1  christos 
     93           1.1  christos #if 0
     94           1.1  christos static void
     95           1.1  christos print_err(int val)
     96           1.1  christos {
     97           1.1  christos 	int err;
     98           1.1  christos 	printf("Error was %d\n", val);
     99           1.1  christos 
    100           1.1  christos 	while ((err = ERR_get_error())) {
    101           1.1  christos 		const char *msg = (const char*)ERR_reason_error_string(err);
    102           1.1  christos 		const char *lib = (const char*)ERR_lib_error_string(err);
    103           1.1  christos 		const char *func = (const char*)ERR_func_error_string(err);
    104           1.1  christos 
    105           1.1  christos 		printf("%s in %s %s\n", msg, lib, func);
    106           1.1  christos 	}
    107           1.1  christos }
    108           1.1  christos #else
    109           1.1  christos #define print_err(v) ((void)0)
    110           1.1  christos #endif
    111           1.1  christos 
    112           1.1  christos /* Called to initialize a new BIO */
    113           1.1  christos static int
    114           1.1  christos bio_bufferevent_new(BIO *b)
    115           1.1  christos {
    116  1.1.1.1.16.1  pgoyette 	BIO_set_init(b, 0);
    117  1.1.1.1.16.1  pgoyette 	BIO_set_data(b, NULL); /* We'll be putting the bufferevent in this field.*/
    118           1.1  christos 	return 1;
    119           1.1  christos }
    120           1.1  christos 
    121           1.1  christos /* Called to uninitialize the BIO. */
    122           1.1  christos static int
    123           1.1  christos bio_bufferevent_free(BIO *b)
    124           1.1  christos {
    125           1.1  christos 	if (!b)
    126           1.1  christos 		return 0;
    127  1.1.1.1.16.1  pgoyette 	if (BIO_get_shutdown(b)) {
    128  1.1.1.1.16.1  pgoyette 		if (BIO_get_init(b) && BIO_get_data(b))
    129  1.1.1.1.16.1  pgoyette 			bufferevent_free(BIO_get_data(b));
    130  1.1.1.1.16.1  pgoyette 		BIO_free(b);
    131           1.1  christos 	}
    132           1.1  christos 	return 1;
    133           1.1  christos }
    134           1.1  christos 
    135           1.1  christos /* Called to extract data from the BIO. */
    136           1.1  christos static int
    137           1.1  christos bio_bufferevent_read(BIO *b, char *out, int outlen)
    138           1.1  christos {
    139           1.1  christos 	int r = 0;
    140           1.1  christos 	struct evbuffer *input;
    141           1.1  christos 
    142           1.1  christos 	BIO_clear_retry_flags(b);
    143           1.1  christos 
    144           1.1  christos 	if (!out)
    145           1.1  christos 		return 0;
    146  1.1.1.1.16.1  pgoyette 	if (!BIO_get_data(b))
    147           1.1  christos 		return -1;
    148           1.1  christos 
    149  1.1.1.1.16.1  pgoyette 	input = bufferevent_get_input(BIO_get_data(b));
    150           1.1  christos 	if (evbuffer_get_length(input) == 0) {
    151           1.1  christos 		/* If there's no data to read, say so. */
    152           1.1  christos 		BIO_set_retry_read(b);
    153           1.1  christos 		return -1;
    154           1.1  christos 	} else {
    155           1.1  christos 		r = evbuffer_remove(input, out, outlen);
    156           1.1  christos 	}
    157           1.1  christos 
    158           1.1  christos 	return r;
    159           1.1  christos }
    160           1.1  christos 
    161           1.1  christos /* Called to write data info the BIO */
    162           1.1  christos static int
    163           1.1  christos bio_bufferevent_write(BIO *b, const char *in, int inlen)
    164           1.1  christos {
    165  1.1.1.1.16.1  pgoyette 	struct bufferevent *bufev = BIO_get_data(b);
    166           1.1  christos 	struct evbuffer *output;
    167           1.1  christos 	size_t outlen;
    168           1.1  christos 
    169           1.1  christos 	BIO_clear_retry_flags(b);
    170           1.1  christos 
    171  1.1.1.1.16.1  pgoyette 	if (!BIO_get_data(b))
    172           1.1  christos 		return -1;
    173           1.1  christos 
    174           1.1  christos 	output = bufferevent_get_output(bufev);
    175           1.1  christos 	outlen = evbuffer_get_length(output);
    176           1.1  christos 
    177           1.1  christos 	/* Copy only as much data onto the output buffer as can fit under the
    178           1.1  christos 	 * high-water mark. */
    179           1.1  christos 	if (bufev->wm_write.high && bufev->wm_write.high <= (outlen+inlen)) {
    180           1.1  christos 		if (bufev->wm_write.high <= outlen) {
    181           1.1  christos 			/* If no data can fit, we'll need to retry later. */
    182           1.1  christos 			BIO_set_retry_write(b);
    183           1.1  christos 			return -1;
    184           1.1  christos 		}
    185           1.1  christos 		inlen = bufev->wm_write.high - outlen;
    186           1.1  christos 	}
    187           1.1  christos 
    188           1.1  christos 	EVUTIL_ASSERT(inlen > 0);
    189           1.1  christos 	evbuffer_add(output, in, inlen);
    190           1.1  christos 	return inlen;
    191           1.1  christos }
    192           1.1  christos 
    193           1.1  christos /* Called to handle various requests */
    194           1.1  christos static long
    195           1.1  christos bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr)
    196           1.1  christos {
    197  1.1.1.1.16.1  pgoyette 	struct bufferevent *bufev = BIO_get_data(b);
    198           1.1  christos 	long ret = 1;
    199           1.1  christos 
    200           1.1  christos 	switch (cmd) {
    201           1.1  christos 	case BIO_CTRL_GET_CLOSE:
    202  1.1.1.1.16.1  pgoyette 		ret = BIO_get_shutdown(b);
    203           1.1  christos 		break;
    204           1.1  christos 	case BIO_CTRL_SET_CLOSE:
    205  1.1.1.1.16.1  pgoyette 		BIO_set_shutdown(b, (int)num);
    206           1.1  christos 		break;
    207           1.1  christos 	case BIO_CTRL_PENDING:
    208           1.1  christos 		ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0;
    209           1.1  christos 		break;
    210           1.1  christos 	case BIO_CTRL_WPENDING:
    211           1.1  christos 		ret = evbuffer_get_length(bufferevent_get_output(bufev)) != 0;
    212           1.1  christos 		break;
    213           1.1  christos 	/* XXXX These two are given a special-case treatment because
    214           1.1  christos 	 * of cargo-cultism.  I should come up with a better reason. */
    215           1.1  christos 	case BIO_CTRL_DUP:
    216           1.1  christos 	case BIO_CTRL_FLUSH:
    217           1.1  christos 		ret = 1;
    218           1.1  christos 		break;
    219           1.1  christos 	default:
    220           1.1  christos 		ret = 0;
    221           1.1  christos 		break;
    222           1.1  christos 	}
    223           1.1  christos 	return ret;
    224           1.1  christos }
    225           1.1  christos 
    226           1.1  christos /* Called to write a string to the BIO */
    227           1.1  christos static int
    228           1.1  christos bio_bufferevent_puts(BIO *b, const char *s)
    229           1.1  christos {
    230           1.1  christos 	return bio_bufferevent_write(b, s, strlen(s));
    231           1.1  christos }
    232           1.1  christos 
    233           1.1  christos /* Method table for the bufferevent BIO */
    234  1.1.1.1.16.1  pgoyette static BIO_METHOD *methods_bufferevent;
    235           1.1  christos 
    236           1.1  christos /* Return the method table for the bufferevents BIO */
    237           1.1  christos static BIO_METHOD *
    238           1.1  christos BIO_s_bufferevent(void)
    239           1.1  christos {
    240  1.1.1.1.16.1  pgoyette 	if (methods_bufferevent == NULL) {
    241  1.1.1.1.16.1  pgoyette 		methods_bufferevent = BIO_meth_new(BIO_TYPE_LIBEVENT, "bufferevent");
    242  1.1.1.1.16.1  pgoyette 		if (methods_bufferevent == NULL)
    243  1.1.1.1.16.1  pgoyette 			return NULL;
    244  1.1.1.1.16.1  pgoyette 		BIO_meth_set_write(methods_bufferevent, bio_bufferevent_write);
    245  1.1.1.1.16.1  pgoyette 		BIO_meth_set_read(methods_bufferevent, bio_bufferevent_read);
    246  1.1.1.1.16.1  pgoyette 		BIO_meth_set_puts(methods_bufferevent, bio_bufferevent_puts);
    247  1.1.1.1.16.1  pgoyette 		BIO_meth_set_ctrl(methods_bufferevent, bio_bufferevent_ctrl);
    248  1.1.1.1.16.1  pgoyette 		BIO_meth_set_create(methods_bufferevent, bio_bufferevent_new);
    249  1.1.1.1.16.1  pgoyette 		BIO_meth_set_destroy(methods_bufferevent, bio_bufferevent_free);
    250  1.1.1.1.16.1  pgoyette 	}
    251  1.1.1.1.16.1  pgoyette 	return methods_bufferevent;
    252           1.1  christos }
    253           1.1  christos 
    254           1.1  christos /* Create a new BIO to wrap communication around a bufferevent.  If close_flag
    255           1.1  christos  * is true, the bufferevent will be freed when the BIO is closed. */
    256           1.1  christos static BIO *
    257           1.1  christos BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag)
    258           1.1  christos {
    259           1.1  christos 	BIO *result;
    260           1.1  christos 	if (!bufferevent)
    261           1.1  christos 		return NULL;
    262           1.1  christos 	if (!(result = BIO_new(BIO_s_bufferevent())))
    263           1.1  christos 		return NULL;
    264  1.1.1.1.16.1  pgoyette 	BIO_set_init(result, 1);
    265  1.1.1.1.16.1  pgoyette 	BIO_set_data(result, bufferevent);
    266  1.1.1.1.16.1  pgoyette 	BIO_set_shutdown(result, close_flag ? 1 : 0);
    267           1.1  christos 	return result;
    268           1.1  christos }
    269           1.1  christos 
    270           1.1  christos /* --------------------
    271           1.1  christos    Now, here's the OpenSSL-based implementation of bufferevent.
    272           1.1  christos 
    273           1.1  christos    The implementation comes in two flavors: one that connects its SSL object
    274           1.1  christos    to an underlying bufferevent using a BIO_bufferevent, and one that has the
    275           1.1  christos    SSL object connect to a socket directly.  The latter should generally be
    276           1.1  christos    faster, except on Windows, where your best bet is using a
    277           1.1  christos    bufferevent_async.
    278           1.1  christos 
    279           1.1  christos    (OpenSSL supports many other BIO types, too.  But we can't use any unless
    280           1.1  christos    we have a good way to get notified when they become readable/writable.)
    281           1.1  christos    -------------------- */
    282           1.1  christos 
    283           1.1  christos struct bio_data_counts {
    284           1.1  christos 	unsigned long n_written;
    285           1.1  christos 	unsigned long n_read;
    286           1.1  christos };
    287           1.1  christos 
    288           1.1  christos struct bufferevent_openssl {
    289           1.1  christos 	/* Shared fields with common bufferevent implementation code.
    290           1.1  christos 	   If we were set up with an underlying bufferevent, we use the
    291           1.1  christos 	   events here as timers only.  If we have an SSL, then we use
    292           1.1  christos 	   the events as socket events.
    293           1.1  christos 	 */
    294           1.1  christos 	struct bufferevent_private bev;
    295           1.1  christos 	/* An underlying bufferevent that we're directing our output to.
    296           1.1  christos 	   If it's NULL, then we're connected to an fd, not an evbuffer. */
    297           1.1  christos 	struct bufferevent *underlying;
    298           1.1  christos 	/* The SSL object doing our encryption. */
    299           1.1  christos 	SSL *ssl;
    300           1.1  christos 
    301           1.1  christos 	/* A callback that's invoked when data arrives on our outbuf so we
    302           1.1  christos 	   know to write data to the SSL. */
    303           1.1  christos 	struct evbuffer_cb_entry *outbuf_cb;
    304           1.1  christos 
    305           1.1  christos 	/* A count of how much data the bios have read/written total.  Used
    306           1.1  christos 	   for rate-limiting. */
    307           1.1  christos 	struct bio_data_counts counts;
    308           1.1  christos 
    309           1.1  christos 	/* If this value is greater than 0, then the last SSL_write blocked,
    310           1.1  christos 	 * and we need to try it again with this many bytes. */
    311           1.1  christos 	ev_ssize_t last_write;
    312           1.1  christos 
    313           1.1  christos #define NUM_ERRORS 3
    314           1.1  christos 	ev_uint32_t errors[NUM_ERRORS];
    315           1.1  christos 
    316           1.1  christos 	/* When we next get available space, we should say "read" instead of
    317           1.1  christos 	   "write". This can happen if there's a renegotiation during a read
    318           1.1  christos 	   operation. */
    319           1.1  christos 	unsigned read_blocked_on_write : 1;
    320           1.1  christos 	/* When we next get data, we should say "write" instead of "read". */
    321           1.1  christos 	unsigned write_blocked_on_read : 1;
    322  1.1.1.1.16.1  pgoyette 	/* Treat TCP close before SSL close on SSL >= v3 as clean EOF. */
    323           1.1  christos 	unsigned allow_dirty_shutdown : 1;
    324           1.1  christos 	/* XXX */
    325           1.1  christos 	unsigned n_errors : 2;
    326           1.1  christos 
    327           1.1  christos 	/* Are we currently connecting, accepting, or doing IO? */
    328           1.1  christos 	unsigned state : 2;
    329  1.1.1.1.16.1  pgoyette 	/* If we reset fd, we sould reset state too */
    330  1.1.1.1.16.1  pgoyette 	unsigned old_state : 2;
    331           1.1  christos };
    332           1.1  christos 
    333           1.1  christos static int be_openssl_enable(struct bufferevent *, short);
    334           1.1  christos static int be_openssl_disable(struct bufferevent *, short);
    335  1.1.1.1.16.1  pgoyette static void be_openssl_unlink(struct bufferevent *);
    336           1.1  christos static void be_openssl_destruct(struct bufferevent *);
    337           1.1  christos static int be_openssl_adj_timeouts(struct bufferevent *);
    338           1.1  christos static int be_openssl_flush(struct bufferevent *bufev,
    339           1.1  christos     short iotype, enum bufferevent_flush_mode mode);
    340           1.1  christos static int be_openssl_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *);
    341           1.1  christos 
    342           1.1  christos const struct bufferevent_ops bufferevent_ops_openssl = {
    343           1.1  christos 	"ssl",
    344           1.1  christos 	evutil_offsetof(struct bufferevent_openssl, bev.bev),
    345           1.1  christos 	be_openssl_enable,
    346           1.1  christos 	be_openssl_disable,
    347  1.1.1.1.16.1  pgoyette 	be_openssl_unlink,
    348           1.1  christos 	be_openssl_destruct,
    349           1.1  christos 	be_openssl_adj_timeouts,
    350           1.1  christos 	be_openssl_flush,
    351           1.1  christos 	be_openssl_ctrl,
    352           1.1  christos };
    353           1.1  christos 
    354           1.1  christos /* Given a bufferevent, return a pointer to the bufferevent_openssl that
    355           1.1  christos  * contains it, if any. */
    356           1.1  christos static inline struct bufferevent_openssl *
    357           1.1  christos upcast(struct bufferevent *bev)
    358           1.1  christos {
    359           1.1  christos 	struct bufferevent_openssl *bev_o;
    360           1.1  christos 	if (bev->be_ops != &bufferevent_ops_openssl)
    361           1.1  christos 		return NULL;
    362           1.1  christos 	bev_o = (void*)( ((char*)bev) -
    363           1.1  christos 			 evutil_offsetof(struct bufferevent_openssl, bev.bev));
    364           1.1  christos 	EVUTIL_ASSERT(bev_o->bev.bev.be_ops == &bufferevent_ops_openssl);
    365           1.1  christos 	return bev_o;
    366           1.1  christos }
    367           1.1  christos 
    368           1.1  christos static inline void
    369           1.1  christos put_error(struct bufferevent_openssl *bev_ssl, unsigned long err)
    370           1.1  christos {
    371           1.1  christos 	if (bev_ssl->n_errors == NUM_ERRORS)
    372           1.1  christos 		return;
    373           1.1  christos 	/* The error type according to openssl is "unsigned long", but
    374           1.1  christos 	   openssl never uses more than 32 bits of it.  It _can't_ use more
    375           1.1  christos 	   than 32 bits of it, since it needs to report errors on systems
    376           1.1  christos 	   where long is only 32 bits.
    377           1.1  christos 	 */
    378           1.1  christos 	bev_ssl->errors[bev_ssl->n_errors++] = (ev_uint32_t) err;
    379           1.1  christos }
    380           1.1  christos 
    381           1.1  christos /* Have the base communications channel (either the underlying bufferevent or
    382           1.1  christos  * ev_read and ev_write) start reading.  Take the read-blocked-on-write flag
    383           1.1  christos  * into account. */
    384           1.1  christos static int
    385           1.1  christos start_reading(struct bufferevent_openssl *bev_ssl)
    386           1.1  christos {
    387           1.1  christos 	if (bev_ssl->underlying) {
    388  1.1.1.1.16.1  pgoyette 		bufferevent_unsuspend_read_(bev_ssl->underlying,
    389           1.1  christos 		    BEV_SUSPEND_FILT_READ);
    390           1.1  christos 		return 0;
    391           1.1  christos 	} else {
    392           1.1  christos 		struct bufferevent *bev = &bev_ssl->bev.bev;
    393           1.1  christos 		int r;
    394  1.1.1.1.16.1  pgoyette 		r = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read);
    395           1.1  christos 		if (r == 0 && bev_ssl->read_blocked_on_write)
    396  1.1.1.1.16.1  pgoyette 			r = bufferevent_add_event_(&bev->ev_write,
    397           1.1  christos 			    &bev->timeout_write);
    398           1.1  christos 		return r;
    399           1.1  christos 	}
    400           1.1  christos }
    401           1.1  christos 
    402           1.1  christos /* Have the base communications channel (either the underlying bufferevent or
    403           1.1  christos  * ev_read and ev_write) start writing.  Take the write-blocked-on-read flag
    404           1.1  christos  * into account. */
    405           1.1  christos static int
    406           1.1  christos start_writing(struct bufferevent_openssl *bev_ssl)
    407           1.1  christos {
    408           1.1  christos 	int r = 0;
    409           1.1  christos 	if (bev_ssl->underlying) {
    410  1.1.1.1.16.1  pgoyette 		if (bev_ssl->write_blocked_on_read) {
    411  1.1.1.1.16.1  pgoyette 			bufferevent_unsuspend_read_(bev_ssl->underlying,
    412  1.1.1.1.16.1  pgoyette 			    BEV_SUSPEND_FILT_READ);
    413  1.1.1.1.16.1  pgoyette 		}
    414           1.1  christos 	} else {
    415           1.1  christos 		struct bufferevent *bev = &bev_ssl->bev.bev;
    416  1.1.1.1.16.1  pgoyette 		r = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write);
    417           1.1  christos 		if (!r && bev_ssl->write_blocked_on_read)
    418  1.1.1.1.16.1  pgoyette 			r = bufferevent_add_event_(&bev->ev_read,
    419           1.1  christos 			    &bev->timeout_read);
    420           1.1  christos 	}
    421           1.1  christos 	return r;
    422           1.1  christos }
    423           1.1  christos 
    424           1.1  christos static void
    425           1.1  christos stop_reading(struct bufferevent_openssl *bev_ssl)
    426           1.1  christos {
    427           1.1  christos 	if (bev_ssl->write_blocked_on_read)
    428           1.1  christos 		return;
    429           1.1  christos 	if (bev_ssl->underlying) {
    430  1.1.1.1.16.1  pgoyette 		bufferevent_suspend_read_(bev_ssl->underlying,
    431           1.1  christos 		    BEV_SUSPEND_FILT_READ);
    432           1.1  christos 	} else {
    433           1.1  christos 		struct bufferevent *bev = &bev_ssl->bev.bev;
    434           1.1  christos 		event_del(&bev->ev_read);
    435           1.1  christos 	}
    436           1.1  christos }
    437           1.1  christos 
    438           1.1  christos static void
    439           1.1  christos stop_writing(struct bufferevent_openssl *bev_ssl)
    440           1.1  christos {
    441           1.1  christos 	if (bev_ssl->read_blocked_on_write)
    442           1.1  christos 		return;
    443           1.1  christos 	if (bev_ssl->underlying) {
    444  1.1.1.1.16.1  pgoyette 		bufferevent_unsuspend_read_(bev_ssl->underlying,
    445  1.1.1.1.16.1  pgoyette 		    BEV_SUSPEND_FILT_READ);
    446           1.1  christos 	} else {
    447           1.1  christos 		struct bufferevent *bev = &bev_ssl->bev.bev;
    448           1.1  christos 		event_del(&bev->ev_write);
    449           1.1  christos 	}
    450           1.1  christos }
    451           1.1  christos 
    452           1.1  christos static int
    453           1.1  christos set_rbow(struct bufferevent_openssl *bev_ssl)
    454           1.1  christos {
    455           1.1  christos 	if (!bev_ssl->underlying)
    456           1.1  christos 		stop_reading(bev_ssl);
    457           1.1  christos 	bev_ssl->read_blocked_on_write = 1;
    458           1.1  christos 	return start_writing(bev_ssl);
    459           1.1  christos }
    460           1.1  christos 
    461           1.1  christos static int
    462           1.1  christos set_wbor(struct bufferevent_openssl *bev_ssl)
    463           1.1  christos {
    464           1.1  christos 	if (!bev_ssl->underlying)
    465           1.1  christos 		stop_writing(bev_ssl);
    466           1.1  christos 	bev_ssl->write_blocked_on_read = 1;
    467           1.1  christos 	return start_reading(bev_ssl);
    468           1.1  christos }
    469           1.1  christos 
    470           1.1  christos static int
    471           1.1  christos clear_rbow(struct bufferevent_openssl *bev_ssl)
    472           1.1  christos {
    473           1.1  christos 	struct bufferevent *bev = &bev_ssl->bev.bev;
    474           1.1  christos 	int r = 0;
    475           1.1  christos 	bev_ssl->read_blocked_on_write = 0;
    476           1.1  christos 	if (!(bev->enabled & EV_WRITE))
    477           1.1  christos 		stop_writing(bev_ssl);
    478           1.1  christos 	if (bev->enabled & EV_READ)
    479           1.1  christos 		r = start_reading(bev_ssl);
    480           1.1  christos 	return r;
    481           1.1  christos }
    482           1.1  christos 
    483           1.1  christos 
    484           1.1  christos static int
    485           1.1  christos clear_wbor(struct bufferevent_openssl *bev_ssl)
    486           1.1  christos {
    487           1.1  christos 	struct bufferevent *bev = &bev_ssl->bev.bev;
    488           1.1  christos 	int r = 0;
    489           1.1  christos 	bev_ssl->write_blocked_on_read = 0;
    490           1.1  christos 	if (!(bev->enabled & EV_READ))
    491           1.1  christos 		stop_reading(bev_ssl);
    492           1.1  christos 	if (bev->enabled & EV_WRITE)
    493           1.1  christos 		r = start_writing(bev_ssl);
    494           1.1  christos 	return r;
    495           1.1  christos }
    496           1.1  christos 
    497           1.1  christos static void
    498  1.1.1.1.16.1  pgoyette conn_closed(struct bufferevent_openssl *bev_ssl, int when, int errcode, int ret)
    499           1.1  christos {
    500           1.1  christos 	int event = BEV_EVENT_ERROR;
    501           1.1  christos 	int dirty_shutdown = 0;
    502           1.1  christos 	unsigned long err;
    503           1.1  christos 
    504           1.1  christos 	switch (errcode) {
    505           1.1  christos 	case SSL_ERROR_ZERO_RETURN:
    506           1.1  christos 		/* Possibly a clean shutdown. */
    507           1.1  christos 		if (SSL_get_shutdown(bev_ssl->ssl) & SSL_RECEIVED_SHUTDOWN)
    508           1.1  christos 			event = BEV_EVENT_EOF;
    509           1.1  christos 		else
    510           1.1  christos 			dirty_shutdown = 1;
    511           1.1  christos 		break;
    512           1.1  christos 	case SSL_ERROR_SYSCALL:
    513           1.1  christos 		/* IO error; possibly a dirty shutdown. */
    514  1.1.1.1.16.1  pgoyette 		if ((ret == 0 || ret == -1) && ERR_peek_error() == 0)
    515           1.1  christos 			dirty_shutdown = 1;
    516           1.1  christos 		break;
    517           1.1  christos 	case SSL_ERROR_SSL:
    518           1.1  christos 		/* Protocol error. */
    519           1.1  christos 		break;
    520           1.1  christos 	case SSL_ERROR_WANT_X509_LOOKUP:
    521           1.1  christos 		/* XXXX handle this. */
    522           1.1  christos 		break;
    523           1.1  christos 	case SSL_ERROR_NONE:
    524           1.1  christos 	case SSL_ERROR_WANT_READ:
    525           1.1  christos 	case SSL_ERROR_WANT_WRITE:
    526           1.1  christos 	case SSL_ERROR_WANT_CONNECT:
    527           1.1  christos 	case SSL_ERROR_WANT_ACCEPT:
    528           1.1  christos 	default:
    529           1.1  christos 		/* should be impossible; treat as normal error. */
    530           1.1  christos 		event_warnx("BUG: Unexpected OpenSSL error code %d", errcode);
    531           1.1  christos 		break;
    532           1.1  christos 	}
    533           1.1  christos 
    534           1.1  christos 	while ((err = ERR_get_error())) {
    535           1.1  christos 		put_error(bev_ssl, err);
    536           1.1  christos 	}
    537           1.1  christos 
    538           1.1  christos 	if (dirty_shutdown && bev_ssl->allow_dirty_shutdown)
    539           1.1  christos 		event = BEV_EVENT_EOF;
    540           1.1  christos 
    541           1.1  christos 	stop_reading(bev_ssl);
    542           1.1  christos 	stop_writing(bev_ssl);
    543           1.1  christos 
    544  1.1.1.1.16.1  pgoyette 	/* when is BEV_EVENT_{READING|WRITING} */
    545  1.1.1.1.16.1  pgoyette 	event = when | event;
    546  1.1.1.1.16.1  pgoyette 	bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
    547           1.1  christos }
    548           1.1  christos 
    549           1.1  christos static void
    550           1.1  christos init_bio_counts(struct bufferevent_openssl *bev_ssl)
    551           1.1  christos {
    552  1.1.1.1.16.1  pgoyette 	BIO *rbio, *wbio;
    553  1.1.1.1.16.1  pgoyette 
    554  1.1.1.1.16.1  pgoyette 	wbio = SSL_get_wbio(bev_ssl->ssl);
    555  1.1.1.1.16.1  pgoyette 	bev_ssl->counts.n_written = wbio ? BIO_number_written(wbio) : 0;
    556  1.1.1.1.16.1  pgoyette 	rbio = SSL_get_rbio(bev_ssl->ssl);
    557  1.1.1.1.16.1  pgoyette 	bev_ssl->counts.n_read = rbio ? BIO_number_read(rbio) : 0;
    558           1.1  christos }
    559           1.1  christos 
    560           1.1  christos static inline void
    561           1.1  christos decrement_buckets(struct bufferevent_openssl *bev_ssl)
    562           1.1  christos {
    563           1.1  christos 	unsigned long num_w = BIO_number_written(SSL_get_wbio(bev_ssl->ssl));
    564           1.1  christos 	unsigned long num_r = BIO_number_read(SSL_get_rbio(bev_ssl->ssl));
    565           1.1  christos 	/* These next two subtractions can wrap around. That's okay. */
    566           1.1  christos 	unsigned long w = num_w - bev_ssl->counts.n_written;
    567           1.1  christos 	unsigned long r = num_r - bev_ssl->counts.n_read;
    568           1.1  christos 	if (w)
    569  1.1.1.1.16.1  pgoyette 		bufferevent_decrement_write_buckets_(&bev_ssl->bev, w);
    570           1.1  christos 	if (r)
    571  1.1.1.1.16.1  pgoyette 		bufferevent_decrement_read_buckets_(&bev_ssl->bev, r);
    572           1.1  christos 	bev_ssl->counts.n_written = num_w;
    573           1.1  christos 	bev_ssl->counts.n_read = num_r;
    574           1.1  christos }
    575           1.1  christos 
    576           1.1  christos #define OP_MADE_PROGRESS 1
    577           1.1  christos #define OP_BLOCKED 2
    578           1.1  christos #define OP_ERR 4
    579           1.1  christos 
    580           1.1  christos /* Return a bitmask of OP_MADE_PROGRESS (if we read anything); OP_BLOCKED (if
    581           1.1  christos    we're now blocked); and OP_ERR (if an error occurred). */
    582           1.1  christos static int
    583           1.1  christos do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) {
    584           1.1  christos 	/* Requires lock */
    585           1.1  christos 	struct bufferevent *bev = &bev_ssl->bev.bev;
    586           1.1  christos 	struct evbuffer *input = bev->input;
    587           1.1  christos 	int r, n, i, n_used = 0, atmost;
    588           1.1  christos 	struct evbuffer_iovec space[2];
    589           1.1  christos 	int result = 0;
    590           1.1  christos 
    591           1.1  christos 	if (bev_ssl->bev.read_suspended)
    592           1.1  christos 		return 0;
    593           1.1  christos 
    594  1.1.1.1.16.1  pgoyette 	atmost = bufferevent_get_read_max_(&bev_ssl->bev);
    595           1.1  christos 	if (n_to_read > atmost)
    596           1.1  christos 		n_to_read = atmost;
    597           1.1  christos 
    598           1.1  christos 	n = evbuffer_reserve_space(input, n_to_read, space, 2);
    599           1.1  christos 	if (n < 0)
    600           1.1  christos 		return OP_ERR;
    601           1.1  christos 
    602           1.1  christos 	for (i=0; i<n; ++i) {
    603           1.1  christos 		if (bev_ssl->bev.read_suspended)
    604           1.1  christos 			break;
    605  1.1.1.1.16.1  pgoyette 		ERR_clear_error();
    606           1.1  christos 		r = SSL_read(bev_ssl->ssl, space[i].iov_base, space[i].iov_len);
    607           1.1  christos 		if (r>0) {
    608           1.1  christos 			result |= OP_MADE_PROGRESS;
    609           1.1  christos 			if (bev_ssl->read_blocked_on_write)
    610           1.1  christos 				if (clear_rbow(bev_ssl) < 0)
    611           1.1  christos 					return OP_ERR | result;
    612           1.1  christos 			++n_used;
    613           1.1  christos 			space[i].iov_len = r;
    614           1.1  christos 			decrement_buckets(bev_ssl);
    615           1.1  christos 		} else {
    616           1.1  christos 			int err = SSL_get_error(bev_ssl->ssl, r);
    617           1.1  christos 			print_err(err);
    618           1.1  christos 			switch (err) {
    619           1.1  christos 			case SSL_ERROR_WANT_READ:
    620           1.1  christos 				/* Can't read until underlying has more data. */
    621           1.1  christos 				if (bev_ssl->read_blocked_on_write)
    622           1.1  christos 					if (clear_rbow(bev_ssl) < 0)
    623           1.1  christos 						return OP_ERR | result;
    624           1.1  christos 				break;
    625           1.1  christos 			case SSL_ERROR_WANT_WRITE:
    626           1.1  christos 				/* This read operation requires a write, and the
    627           1.1  christos 				 * underlying is full */
    628           1.1  christos 				if (!bev_ssl->read_blocked_on_write)
    629           1.1  christos 					if (set_rbow(bev_ssl) < 0)
    630           1.1  christos 						return OP_ERR | result;
    631           1.1  christos 				break;
    632           1.1  christos 			default:
    633  1.1.1.1.16.1  pgoyette 				conn_closed(bev_ssl, BEV_EVENT_READING, err, r);
    634           1.1  christos 				break;
    635           1.1  christos 			}
    636           1.1  christos 			result |= OP_BLOCKED;
    637           1.1  christos 			break; /* out of the loop */
    638           1.1  christos 		}
    639           1.1  christos 	}
    640           1.1  christos 
    641           1.1  christos 	if (n_used) {
    642           1.1  christos 		evbuffer_commit_space(input, space, n_used);
    643           1.1  christos 		if (bev_ssl->underlying)
    644           1.1  christos 			BEV_RESET_GENERIC_READ_TIMEOUT(bev);
    645           1.1  christos 	}
    646           1.1  christos 
    647           1.1  christos 	return result;
    648           1.1  christos }
    649           1.1  christos 
    650           1.1  christos /* Return a bitmask of OP_MADE_PROGRESS (if we wrote anything); OP_BLOCKED (if
    651           1.1  christos    we're now blocked); and OP_ERR (if an error occurred). */
    652           1.1  christos static int
    653           1.1  christos do_write(struct bufferevent_openssl *bev_ssl, int atmost)
    654           1.1  christos {
    655           1.1  christos 	int i, r, n, n_written = 0;
    656           1.1  christos 	struct bufferevent *bev = &bev_ssl->bev.bev;
    657           1.1  christos 	struct evbuffer *output = bev->output;
    658           1.1  christos 	struct evbuffer_iovec space[8];
    659           1.1  christos 	int result = 0;
    660           1.1  christos 
    661           1.1  christos 	if (bev_ssl->last_write > 0)
    662           1.1  christos 		atmost = bev_ssl->last_write;
    663           1.1  christos 	else
    664  1.1.1.1.16.1  pgoyette 		atmost = bufferevent_get_write_max_(&bev_ssl->bev);
    665           1.1  christos 
    666           1.1  christos 	n = evbuffer_peek(output, atmost, NULL, space, 8);
    667           1.1  christos 	if (n < 0)
    668           1.1  christos 		return OP_ERR | result;
    669           1.1  christos 
    670           1.1  christos 	if (n > 8)
    671           1.1  christos 		n = 8;
    672           1.1  christos 	for (i=0; i < n; ++i) {
    673           1.1  christos 		if (bev_ssl->bev.write_suspended)
    674           1.1  christos 			break;
    675           1.1  christos 
    676           1.1  christos 		/* SSL_write will (reasonably) return 0 if we tell it to
    677           1.1  christos 		   send 0 data.  Skip this case so we don't interpret the
    678           1.1  christos 		   result as an error */
    679           1.1  christos 		if (space[i].iov_len == 0)
    680           1.1  christos 			continue;
    681           1.1  christos 
    682  1.1.1.1.16.1  pgoyette 		ERR_clear_error();
    683           1.1  christos 		r = SSL_write(bev_ssl->ssl, space[i].iov_base,
    684           1.1  christos 		    space[i].iov_len);
    685           1.1  christos 		if (r > 0) {
    686           1.1  christos 			result |= OP_MADE_PROGRESS;
    687           1.1  christos 			if (bev_ssl->write_blocked_on_read)
    688           1.1  christos 				if (clear_wbor(bev_ssl) < 0)
    689           1.1  christos 					return OP_ERR | result;
    690           1.1  christos 			n_written += r;
    691           1.1  christos 			bev_ssl->last_write = -1;
    692           1.1  christos 			decrement_buckets(bev_ssl);
    693           1.1  christos 		} else {
    694           1.1  christos 			int err = SSL_get_error(bev_ssl->ssl, r);
    695           1.1  christos 			print_err(err);
    696           1.1  christos 			switch (err) {
    697           1.1  christos 			case SSL_ERROR_WANT_WRITE:
    698           1.1  christos 				/* Can't read until underlying has more data. */
    699           1.1  christos 				if (bev_ssl->write_blocked_on_read)
    700           1.1  christos 					if (clear_wbor(bev_ssl) < 0)
    701           1.1  christos 						return OP_ERR | result;
    702           1.1  christos 				bev_ssl->last_write = space[i].iov_len;
    703           1.1  christos 				break;
    704           1.1  christos 			case SSL_ERROR_WANT_READ:
    705           1.1  christos 				/* This read operation requires a write, and the
    706           1.1  christos 				 * underlying is full */
    707           1.1  christos 				if (!bev_ssl->write_blocked_on_read)
    708           1.1  christos 					if (set_wbor(bev_ssl) < 0)
    709           1.1  christos 						return OP_ERR | result;
    710           1.1  christos 				bev_ssl->last_write = space[i].iov_len;
    711           1.1  christos 				break;
    712           1.1  christos 			default:
    713  1.1.1.1.16.1  pgoyette 				conn_closed(bev_ssl, BEV_EVENT_WRITING, err, r);
    714           1.1  christos 				bev_ssl->last_write = -1;
    715           1.1  christos 				break;
    716           1.1  christos 			}
    717           1.1  christos 			result |= OP_BLOCKED;
    718           1.1  christos 			break;
    719           1.1  christos 		}
    720           1.1  christos 	}
    721           1.1  christos 	if (n_written) {
    722           1.1  christos 		evbuffer_drain(output, n_written);
    723           1.1  christos 		if (bev_ssl->underlying)
    724           1.1  christos 			BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
    725           1.1  christos 
    726  1.1.1.1.16.1  pgoyette 		bufferevent_trigger_nolock_(bev, EV_WRITE, BEV_OPT_DEFER_CALLBACKS);
    727           1.1  christos 	}
    728           1.1  christos 	return result;
    729           1.1  christos }
    730           1.1  christos 
    731           1.1  christos #define WRITE_FRAME 15000
    732           1.1  christos 
    733           1.1  christos #define READ_DEFAULT 4096
    734           1.1  christos 
    735           1.1  christos /* Try to figure out how many bytes to read; return 0 if we shouldn't be
    736           1.1  christos  * reading. */
    737           1.1  christos static int
    738           1.1  christos bytes_to_read(struct bufferevent_openssl *bev)
    739           1.1  christos {
    740           1.1  christos 	struct evbuffer *input = bev->bev.bev.input;
    741           1.1  christos 	struct event_watermark *wm = &bev->bev.bev.wm_read;
    742           1.1  christos 	int result = READ_DEFAULT;
    743           1.1  christos 	ev_ssize_t limit;
    744           1.1  christos 	/* XXX 99% of this is generic code that nearly all bufferevents will
    745           1.1  christos 	 * want. */
    746           1.1  christos 
    747           1.1  christos 	if (bev->write_blocked_on_read) {
    748           1.1  christos 		return 0;
    749           1.1  christos 	}
    750           1.1  christos 
    751           1.1  christos 	if (! (bev->bev.bev.enabled & EV_READ)) {
    752           1.1  christos 		return 0;
    753           1.1  christos 	}
    754           1.1  christos 
    755           1.1  christos 	if (bev->bev.read_suspended) {
    756           1.1  christos 		return 0;
    757           1.1  christos 	}
    758           1.1  christos 
    759           1.1  christos 	if (wm->high) {
    760           1.1  christos 		if (evbuffer_get_length(input) >= wm->high) {
    761           1.1  christos 			return 0;
    762           1.1  christos 		}
    763           1.1  christos 
    764           1.1  christos 		result = wm->high - evbuffer_get_length(input);
    765           1.1  christos 	} else {
    766           1.1  christos 		result = READ_DEFAULT;
    767           1.1  christos 	}
    768           1.1  christos 
    769           1.1  christos 	/* Respect the rate limit */
    770  1.1.1.1.16.1  pgoyette 	limit = bufferevent_get_read_max_(&bev->bev);
    771           1.1  christos 	if (result > limit) {
    772           1.1  christos 		result = limit;
    773           1.1  christos 	}
    774           1.1  christos 
    775           1.1  christos 	return result;
    776           1.1  christos }
    777           1.1  christos 
    778           1.1  christos 
    779           1.1  christos /* Things look readable.  If write is blocked on read, write till it isn't.
    780           1.1  christos  * Read from the underlying buffer until we block or we hit our high-water
    781           1.1  christos  * mark.
    782           1.1  christos  */
    783           1.1  christos static void
    784           1.1  christos consider_reading(struct bufferevent_openssl *bev_ssl)
    785           1.1  christos {
    786           1.1  christos 	int r;
    787           1.1  christos 	int n_to_read;
    788           1.1  christos 	int all_result_flags = 0;
    789           1.1  christos 
    790           1.1  christos 	while (bev_ssl->write_blocked_on_read) {
    791           1.1  christos 		r = do_write(bev_ssl, WRITE_FRAME);
    792           1.1  christos 		if (r & (OP_BLOCKED|OP_ERR))
    793           1.1  christos 			break;
    794           1.1  christos 	}
    795           1.1  christos 	if (bev_ssl->write_blocked_on_read)
    796           1.1  christos 		return;
    797           1.1  christos 
    798           1.1  christos 	n_to_read = bytes_to_read(bev_ssl);
    799           1.1  christos 
    800           1.1  christos 	while (n_to_read) {
    801           1.1  christos 		r = do_read(bev_ssl, n_to_read);
    802           1.1  christos 		all_result_flags |= r;
    803           1.1  christos 
    804           1.1  christos 		if (r & (OP_BLOCKED|OP_ERR))
    805           1.1  christos 			break;
    806           1.1  christos 
    807           1.1  christos 		if (bev_ssl->bev.read_suspended)
    808           1.1  christos 			break;
    809           1.1  christos 
    810           1.1  christos 		/* Read all pending data.  This won't hit the network
    811           1.1  christos 		 * again, and will (most importantly) put us in a state
    812           1.1  christos 		 * where we don't need to read anything else until the
    813           1.1  christos 		 * socket is readable again.  It'll potentially make us
    814           1.1  christos 		 * overrun our read high-watermark (somewhat
    815           1.1  christos 		 * regrettable).  The damage to the rate-limit has
    816           1.1  christos 		 * already been done, since OpenSSL went and read a
    817           1.1  christos 		 * whole SSL record anyway. */
    818           1.1  christos 		n_to_read = SSL_pending(bev_ssl->ssl);
    819           1.1  christos 
    820           1.1  christos 		/* XXX This if statement is actually a bad bug, added to avoid
    821           1.1  christos 		 * XXX a worse bug.
    822           1.1  christos 		 *
    823           1.1  christos 		 * The bad bug: It can potentially cause resource unfairness
    824           1.1  christos 		 * by reading too much data from the underlying bufferevent;
    825           1.1  christos 		 * it can potentially cause read looping if the underlying
    826           1.1  christos 		 * bufferevent is a bufferevent_pair and deferred callbacks
    827           1.1  christos 		 * aren't used.
    828           1.1  christos 		 *
    829           1.1  christos 		 * The worse bug: If we didn't do this, then we would
    830           1.1  christos 		 * potentially not read any more from bev_ssl->underlying
    831           1.1  christos 		 * until more data arrived there, which could lead to us
    832           1.1  christos 		 * waiting forever.
    833           1.1  christos 		 */
    834           1.1  christos 		if (!n_to_read && bev_ssl->underlying)
    835           1.1  christos 			n_to_read = bytes_to_read(bev_ssl);
    836           1.1  christos 	}
    837           1.1  christos 
    838           1.1  christos 	if (all_result_flags & OP_MADE_PROGRESS) {
    839           1.1  christos 		struct bufferevent *bev = &bev_ssl->bev.bev;
    840           1.1  christos 
    841  1.1.1.1.16.1  pgoyette 		bufferevent_trigger_nolock_(bev, EV_READ, 0);
    842           1.1  christos 	}
    843           1.1  christos 
    844           1.1  christos 	if (!bev_ssl->underlying) {
    845           1.1  christos 		/* Should be redundant, but let's avoid busy-looping */
    846           1.1  christos 		if (bev_ssl->bev.read_suspended ||
    847           1.1  christos 		    !(bev_ssl->bev.bev.enabled & EV_READ)) {
    848           1.1  christos 			event_del(&bev_ssl->bev.bev.ev_read);
    849           1.1  christos 		}
    850           1.1  christos 	}
    851           1.1  christos }
    852           1.1  christos 
    853           1.1  christos static void
    854           1.1  christos consider_writing(struct bufferevent_openssl *bev_ssl)
    855           1.1  christos {
    856           1.1  christos 	int r;
    857           1.1  christos 	struct evbuffer *output = bev_ssl->bev.bev.output;
    858           1.1  christos 	struct evbuffer *target = NULL;
    859           1.1  christos 	struct event_watermark *wm = NULL;
    860           1.1  christos 
    861           1.1  christos 	while (bev_ssl->read_blocked_on_write) {
    862           1.1  christos 		r = do_read(bev_ssl, 1024); /* XXXX 1024 is a hack */
    863           1.1  christos 		if (r & OP_MADE_PROGRESS) {
    864           1.1  christos 			struct bufferevent *bev = &bev_ssl->bev.bev;
    865           1.1  christos 
    866  1.1.1.1.16.1  pgoyette 			bufferevent_trigger_nolock_(bev, EV_READ, 0);
    867           1.1  christos 		}
    868           1.1  christos 		if (r & (OP_ERR|OP_BLOCKED))
    869           1.1  christos 			break;
    870           1.1  christos 	}
    871           1.1  christos 	if (bev_ssl->read_blocked_on_write)
    872           1.1  christos 		return;
    873           1.1  christos 	if (bev_ssl->underlying) {
    874           1.1  christos 		target = bev_ssl->underlying->output;
    875           1.1  christos 		wm = &bev_ssl->underlying->wm_write;
    876           1.1  christos 	}
    877           1.1  christos 	while ((bev_ssl->bev.bev.enabled & EV_WRITE) &&
    878           1.1  christos 	    (! bev_ssl->bev.write_suspended) &&
    879           1.1  christos 	    evbuffer_get_length(output) &&
    880           1.1  christos 	    (!target || (! wm->high || evbuffer_get_length(target) < wm->high))) {
    881           1.1  christos 		int n_to_write;
    882           1.1  christos 		if (wm && wm->high)
    883           1.1  christos 			n_to_write = wm->high - evbuffer_get_length(target);
    884           1.1  christos 		else
    885           1.1  christos 			n_to_write = WRITE_FRAME;
    886           1.1  christos 		r = do_write(bev_ssl, n_to_write);
    887           1.1  christos 		if (r & (OP_BLOCKED|OP_ERR))
    888           1.1  christos 			break;
    889           1.1  christos 	}
    890           1.1  christos 
    891           1.1  christos 	if (!bev_ssl->underlying) {
    892           1.1  christos 		if (evbuffer_get_length(output) == 0) {
    893           1.1  christos 			event_del(&bev_ssl->bev.bev.ev_write);
    894           1.1  christos 		} else if (bev_ssl->bev.write_suspended ||
    895           1.1  christos 		    !(bev_ssl->bev.bev.enabled & EV_WRITE)) {
    896           1.1  christos 			/* Should be redundant, but let's avoid busy-looping */
    897           1.1  christos 			event_del(&bev_ssl->bev.bev.ev_write);
    898           1.1  christos 		}
    899           1.1  christos 	}
    900           1.1  christos }
    901           1.1  christos 
    902           1.1  christos static void
    903           1.1  christos be_openssl_readcb(struct bufferevent *bev_base, void *ctx)
    904           1.1  christos {
    905           1.1  christos 	struct bufferevent_openssl *bev_ssl = ctx;
    906           1.1  christos 	consider_reading(bev_ssl);
    907           1.1  christos }
    908           1.1  christos 
    909           1.1  christos static void
    910           1.1  christos be_openssl_writecb(struct bufferevent *bev_base, void *ctx)
    911           1.1  christos {
    912           1.1  christos 	struct bufferevent_openssl *bev_ssl = ctx;
    913           1.1  christos 	consider_writing(bev_ssl);
    914           1.1  christos }
    915           1.1  christos 
    916           1.1  christos static void
    917           1.1  christos be_openssl_eventcb(struct bufferevent *bev_base, short what, void *ctx)
    918           1.1  christos {
    919           1.1  christos 	struct bufferevent_openssl *bev_ssl = ctx;
    920           1.1  christos 	int event = 0;
    921           1.1  christos 
    922           1.1  christos 	if (what & BEV_EVENT_EOF) {
    923           1.1  christos 		if (bev_ssl->allow_dirty_shutdown)
    924           1.1  christos 			event = BEV_EVENT_EOF;
    925           1.1  christos 		else
    926           1.1  christos 			event = BEV_EVENT_ERROR;
    927           1.1  christos 	} else if (what & BEV_EVENT_TIMEOUT) {
    928           1.1  christos 		/* We sure didn't set this.  Propagate it to the user. */
    929           1.1  christos 		event = what;
    930           1.1  christos 	} else if (what & BEV_EVENT_ERROR) {
    931           1.1  christos 		/* An error occurred on the connection.  Propagate it to the user. */
    932           1.1  christos 		event = what;
    933           1.1  christos 	} else if (what & BEV_EVENT_CONNECTED) {
    934           1.1  christos 		/* Ignore it.  We're saying SSL_connect() already, which will
    935           1.1  christos 		   eat it. */
    936           1.1  christos 	}
    937           1.1  christos 	if (event)
    938  1.1.1.1.16.1  pgoyette 		bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
    939           1.1  christos }
    940           1.1  christos 
    941           1.1  christos static void
    942           1.1  christos be_openssl_readeventcb(evutil_socket_t fd, short what, void *ptr)
    943           1.1  christos {
    944           1.1  christos 	struct bufferevent_openssl *bev_ssl = ptr;
    945  1.1.1.1.16.1  pgoyette 	bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
    946           1.1  christos 	if (what == EV_TIMEOUT) {
    947  1.1.1.1.16.1  pgoyette 		bufferevent_run_eventcb_(&bev_ssl->bev.bev,
    948  1.1.1.1.16.1  pgoyette 		    BEV_EVENT_TIMEOUT|BEV_EVENT_READING, 0);
    949           1.1  christos 	} else {
    950           1.1  christos 		consider_reading(bev_ssl);
    951           1.1  christos 	}
    952  1.1.1.1.16.1  pgoyette 	bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
    953           1.1  christos }
    954           1.1  christos 
    955           1.1  christos static void
    956           1.1  christos be_openssl_writeeventcb(evutil_socket_t fd, short what, void *ptr)
    957           1.1  christos {
    958           1.1  christos 	struct bufferevent_openssl *bev_ssl = ptr;
    959  1.1.1.1.16.1  pgoyette 	bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
    960           1.1  christos 	if (what == EV_TIMEOUT) {
    961  1.1.1.1.16.1  pgoyette 		bufferevent_run_eventcb_(&bev_ssl->bev.bev,
    962  1.1.1.1.16.1  pgoyette 		    BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING, 0);
    963           1.1  christos 	} else {
    964           1.1  christos 		consider_writing(bev_ssl);
    965           1.1  christos 	}
    966  1.1.1.1.16.1  pgoyette 	bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
    967  1.1.1.1.16.1  pgoyette }
    968  1.1.1.1.16.1  pgoyette 
    969  1.1.1.1.16.1  pgoyette static int
    970  1.1.1.1.16.1  pgoyette be_openssl_auto_fd(struct bufferevent_openssl *bev_ssl, int fd)
    971  1.1.1.1.16.1  pgoyette {
    972  1.1.1.1.16.1  pgoyette 	if (!bev_ssl->underlying) {
    973  1.1.1.1.16.1  pgoyette 		struct bufferevent *bev = &bev_ssl->bev.bev;
    974  1.1.1.1.16.1  pgoyette 		if (event_initialized(&bev->ev_read) && fd < 0) {
    975  1.1.1.1.16.1  pgoyette 			fd = event_get_fd(&bev->ev_read);
    976  1.1.1.1.16.1  pgoyette 		}
    977  1.1.1.1.16.1  pgoyette 	}
    978  1.1.1.1.16.1  pgoyette 	return fd;
    979           1.1  christos }
    980           1.1  christos 
    981           1.1  christos static int
    982           1.1  christos set_open_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
    983           1.1  christos {
    984           1.1  christos 	if (bev_ssl->underlying) {
    985           1.1  christos 		bufferevent_setcb(bev_ssl->underlying,
    986           1.1  christos 		    be_openssl_readcb, be_openssl_writecb, be_openssl_eventcb,
    987           1.1  christos 		    bev_ssl);
    988           1.1  christos 		return 0;
    989           1.1  christos 	} else {
    990           1.1  christos 		struct bufferevent *bev = &bev_ssl->bev.bev;
    991           1.1  christos 		int rpending=0, wpending=0, r1=0, r2=0;
    992  1.1.1.1.16.1  pgoyette 
    993  1.1.1.1.16.1  pgoyette 		if (event_initialized(&bev->ev_read)) {
    994           1.1  christos 			rpending = event_pending(&bev->ev_read, EV_READ, NULL);
    995           1.1  christos 			wpending = event_pending(&bev->ev_write, EV_WRITE, NULL);
    996  1.1.1.1.16.1  pgoyette 
    997           1.1  christos 			event_del(&bev->ev_read);
    998           1.1  christos 			event_del(&bev->ev_write);
    999           1.1  christos 		}
   1000  1.1.1.1.16.1  pgoyette 
   1001           1.1  christos 		event_assign(&bev->ev_read, bev->ev_base, fd,
   1002  1.1.1.1.16.1  pgoyette 		    EV_READ|EV_PERSIST|EV_FINALIZE,
   1003  1.1.1.1.16.1  pgoyette 		    be_openssl_readeventcb, bev_ssl);
   1004           1.1  christos 		event_assign(&bev->ev_write, bev->ev_base, fd,
   1005  1.1.1.1.16.1  pgoyette 		    EV_WRITE|EV_PERSIST|EV_FINALIZE,
   1006  1.1.1.1.16.1  pgoyette 		    be_openssl_writeeventcb, bev_ssl);
   1007  1.1.1.1.16.1  pgoyette 
   1008           1.1  christos 		if (rpending)
   1009  1.1.1.1.16.1  pgoyette 			r1 = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read);
   1010           1.1  christos 		if (wpending)
   1011  1.1.1.1.16.1  pgoyette 			r2 = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write);
   1012  1.1.1.1.16.1  pgoyette 
   1013           1.1  christos 		return (r1<0 || r2<0) ? -1 : 0;
   1014           1.1  christos 	}
   1015           1.1  christos }
   1016           1.1  christos 
   1017           1.1  christos static int
   1018           1.1  christos do_handshake(struct bufferevent_openssl *bev_ssl)
   1019           1.1  christos {
   1020           1.1  christos 	int r;
   1021           1.1  christos 
   1022           1.1  christos 	switch (bev_ssl->state) {
   1023           1.1  christos 	default:
   1024           1.1  christos 	case BUFFEREVENT_SSL_OPEN:
   1025           1.1  christos 		EVUTIL_ASSERT(0);
   1026           1.1  christos 		return -1;
   1027           1.1  christos 	case BUFFEREVENT_SSL_CONNECTING:
   1028           1.1  christos 	case BUFFEREVENT_SSL_ACCEPTING:
   1029  1.1.1.1.16.1  pgoyette 		ERR_clear_error();
   1030           1.1  christos 		r = SSL_do_handshake(bev_ssl->ssl);
   1031           1.1  christos 		break;
   1032           1.1  christos 	}
   1033           1.1  christos 	decrement_buckets(bev_ssl);
   1034           1.1  christos 
   1035           1.1  christos 	if (r==1) {
   1036  1.1.1.1.16.1  pgoyette 		int fd = event_get_fd(&bev_ssl->bev.bev.ev_read);
   1037           1.1  christos 		/* We're done! */
   1038           1.1  christos 		bev_ssl->state = BUFFEREVENT_SSL_OPEN;
   1039  1.1.1.1.16.1  pgoyette 		set_open_callbacks(bev_ssl, fd); /* XXXX handle failure */
   1040           1.1  christos 		/* Call do_read and do_write as needed */
   1041           1.1  christos 		bufferevent_enable(&bev_ssl->bev.bev, bev_ssl->bev.bev.enabled);
   1042  1.1.1.1.16.1  pgoyette 		bufferevent_run_eventcb_(&bev_ssl->bev.bev,
   1043  1.1.1.1.16.1  pgoyette 		    BEV_EVENT_CONNECTED, 0);
   1044           1.1  christos 		return 1;
   1045           1.1  christos 	} else {
   1046           1.1  christos 		int err = SSL_get_error(bev_ssl->ssl, r);
   1047           1.1  christos 		print_err(err);
   1048           1.1  christos 		switch (err) {
   1049           1.1  christos 		case SSL_ERROR_WANT_WRITE:
   1050  1.1.1.1.16.1  pgoyette 			stop_reading(bev_ssl);
   1051  1.1.1.1.16.1  pgoyette 			return start_writing(bev_ssl);
   1052           1.1  christos 		case SSL_ERROR_WANT_READ:
   1053  1.1.1.1.16.1  pgoyette 			stop_writing(bev_ssl);
   1054  1.1.1.1.16.1  pgoyette 			return start_reading(bev_ssl);
   1055           1.1  christos 		default:
   1056  1.1.1.1.16.1  pgoyette 			conn_closed(bev_ssl, BEV_EVENT_READING, err, r);
   1057           1.1  christos 			return -1;
   1058           1.1  christos 		}
   1059           1.1  christos 	}
   1060           1.1  christos }
   1061           1.1  christos 
   1062           1.1  christos static void
   1063           1.1  christos be_openssl_handshakecb(struct bufferevent *bev_base, void *ctx)
   1064           1.1  christos {
   1065           1.1  christos 	struct bufferevent_openssl *bev_ssl = ctx;
   1066           1.1  christos 	do_handshake(bev_ssl);/* XXX handle failure */
   1067           1.1  christos }
   1068           1.1  christos 
   1069           1.1  christos static void
   1070           1.1  christos be_openssl_handshakeeventcb(evutil_socket_t fd, short what, void *ptr)
   1071           1.1  christos {
   1072           1.1  christos 	struct bufferevent_openssl *bev_ssl = ptr;
   1073           1.1  christos 
   1074  1.1.1.1.16.1  pgoyette 	bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
   1075           1.1  christos 	if (what & EV_TIMEOUT) {
   1076  1.1.1.1.16.1  pgoyette 		bufferevent_run_eventcb_(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT, 0);
   1077           1.1  christos 	} else
   1078           1.1  christos 		do_handshake(bev_ssl);/* XXX handle failure */
   1079  1.1.1.1.16.1  pgoyette 	bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
   1080           1.1  christos }
   1081           1.1  christos 
   1082           1.1  christos static int
   1083           1.1  christos set_handshake_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
   1084           1.1  christos {
   1085           1.1  christos 	if (bev_ssl->underlying) {
   1086           1.1  christos 		bufferevent_setcb(bev_ssl->underlying,
   1087           1.1  christos 		    be_openssl_handshakecb, be_openssl_handshakecb,
   1088           1.1  christos 		    be_openssl_eventcb,
   1089           1.1  christos 		    bev_ssl);
   1090  1.1.1.1.16.1  pgoyette 
   1091  1.1.1.1.16.1  pgoyette 		if (fd < 0)
   1092  1.1.1.1.16.1  pgoyette 			return 0;
   1093  1.1.1.1.16.1  pgoyette 
   1094  1.1.1.1.16.1  pgoyette 		if (bufferevent_setfd(bev_ssl->underlying, fd))
   1095  1.1.1.1.16.1  pgoyette 			return 1;
   1096  1.1.1.1.16.1  pgoyette 
   1097           1.1  christos 		return do_handshake(bev_ssl);
   1098           1.1  christos 	} else {
   1099           1.1  christos 		struct bufferevent *bev = &bev_ssl->bev.bev;
   1100  1.1.1.1.16.1  pgoyette 
   1101  1.1.1.1.16.1  pgoyette 		if (event_initialized(&bev->ev_read)) {
   1102           1.1  christos 			event_del(&bev->ev_read);
   1103           1.1  christos 			event_del(&bev->ev_write);
   1104           1.1  christos 		}
   1105  1.1.1.1.16.1  pgoyette 
   1106           1.1  christos 		event_assign(&bev->ev_read, bev->ev_base, fd,
   1107  1.1.1.1.16.1  pgoyette 		    EV_READ|EV_PERSIST|EV_FINALIZE,
   1108  1.1.1.1.16.1  pgoyette 		    be_openssl_handshakeeventcb, bev_ssl);
   1109           1.1  christos 		event_assign(&bev->ev_write, bev->ev_base, fd,
   1110  1.1.1.1.16.1  pgoyette 		    EV_WRITE|EV_PERSIST|EV_FINALIZE,
   1111  1.1.1.1.16.1  pgoyette 		    be_openssl_handshakeeventcb, bev_ssl);
   1112  1.1.1.1.16.1  pgoyette 		if (fd >= 0)
   1113  1.1.1.1.16.1  pgoyette 			bufferevent_enable(bev, bev->enabled);
   1114  1.1.1.1.16.1  pgoyette 		return 0;
   1115           1.1  christos 	}
   1116           1.1  christos }
   1117           1.1  christos 
   1118           1.1  christos int
   1119           1.1  christos bufferevent_ssl_renegotiate(struct bufferevent *bev)
   1120           1.1  christos {
   1121           1.1  christos 	struct bufferevent_openssl *bev_ssl = upcast(bev);
   1122           1.1  christos 	if (!bev_ssl)
   1123           1.1  christos 		return -1;
   1124           1.1  christos 	if (SSL_renegotiate(bev_ssl->ssl) < 0)
   1125           1.1  christos 		return -1;
   1126           1.1  christos 	bev_ssl->state = BUFFEREVENT_SSL_CONNECTING;
   1127  1.1.1.1.16.1  pgoyette 	if (set_handshake_callbacks(bev_ssl, be_openssl_auto_fd(bev_ssl, -1)) < 0)
   1128           1.1  christos 		return -1;
   1129           1.1  christos 	if (!bev_ssl->underlying)
   1130           1.1  christos 		return do_handshake(bev_ssl);
   1131           1.1  christos 	return 0;
   1132           1.1  christos }
   1133           1.1  christos 
   1134           1.1  christos static void
   1135           1.1  christos be_openssl_outbuf_cb(struct evbuffer *buf,
   1136           1.1  christos     const struct evbuffer_cb_info *cbinfo, void *arg)
   1137           1.1  christos {
   1138           1.1  christos 	struct bufferevent_openssl *bev_ssl = arg;
   1139           1.1  christos 	int r = 0;
   1140           1.1  christos 	/* XXX need to hold a reference here. */
   1141           1.1  christos 
   1142           1.1  christos 	if (cbinfo->n_added && bev_ssl->state == BUFFEREVENT_SSL_OPEN) {
   1143           1.1  christos 		if (cbinfo->orig_size == 0)
   1144  1.1.1.1.16.1  pgoyette 			r = bufferevent_add_event_(&bev_ssl->bev.bev.ev_write,
   1145           1.1  christos 			    &bev_ssl->bev.bev.timeout_write);
   1146  1.1.1.1.16.1  pgoyette 
   1147  1.1.1.1.16.1  pgoyette 		if (bev_ssl->underlying)
   1148  1.1.1.1.16.1  pgoyette 			consider_writing(bev_ssl);
   1149           1.1  christos 	}
   1150           1.1  christos 	/* XXX Handle r < 0 */
   1151  1.1.1.1.16.1  pgoyette 	(void)r;
   1152           1.1  christos }
   1153           1.1  christos 
   1154           1.1  christos 
   1155           1.1  christos static int
   1156           1.1  christos be_openssl_enable(struct bufferevent *bev, short events)
   1157           1.1  christos {
   1158           1.1  christos 	struct bufferevent_openssl *bev_ssl = upcast(bev);
   1159           1.1  christos 	int r1 = 0, r2 = 0;
   1160           1.1  christos 
   1161           1.1  christos 	if (events & EV_READ)
   1162           1.1  christos 		r1 = start_reading(bev_ssl);
   1163           1.1  christos 	if (events & EV_WRITE)
   1164           1.1  christos 		r2 = start_writing(bev_ssl);
   1165           1.1  christos 
   1166           1.1  christos 	if (bev_ssl->underlying) {
   1167           1.1  christos 		if (events & EV_READ)
   1168           1.1  christos 			BEV_RESET_GENERIC_READ_TIMEOUT(bev);
   1169           1.1  christos 		if (events & EV_WRITE)
   1170           1.1  christos 			BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
   1171           1.1  christos 
   1172           1.1  christos 		if (events & EV_READ)
   1173           1.1  christos 			consider_reading(bev_ssl);
   1174           1.1  christos 		if (events & EV_WRITE)
   1175           1.1  christos 			consider_writing(bev_ssl);
   1176           1.1  christos 	}
   1177           1.1  christos 	return (r1 < 0 || r2 < 0) ? -1 : 0;
   1178           1.1  christos }
   1179           1.1  christos 
   1180           1.1  christos static int
   1181           1.1  christos be_openssl_disable(struct bufferevent *bev, short events)
   1182           1.1  christos {
   1183           1.1  christos 	struct bufferevent_openssl *bev_ssl = upcast(bev);
   1184           1.1  christos 
   1185           1.1  christos 	if (events & EV_READ)
   1186           1.1  christos 		stop_reading(bev_ssl);
   1187           1.1  christos 	if (events & EV_WRITE)
   1188           1.1  christos 		stop_writing(bev_ssl);
   1189           1.1  christos 
   1190           1.1  christos 	if (bev_ssl->underlying) {
   1191           1.1  christos 		if (events & EV_READ)
   1192           1.1  christos 			BEV_DEL_GENERIC_READ_TIMEOUT(bev);
   1193           1.1  christos 		if (events & EV_WRITE)
   1194           1.1  christos 			BEV_DEL_GENERIC_WRITE_TIMEOUT(bev);
   1195           1.1  christos 	}
   1196           1.1  christos 	return 0;
   1197           1.1  christos }
   1198           1.1  christos 
   1199           1.1  christos static void
   1200  1.1.1.1.16.1  pgoyette be_openssl_unlink(struct bufferevent *bev)
   1201           1.1  christos {
   1202           1.1  christos 	struct bufferevent_openssl *bev_ssl = upcast(bev);
   1203           1.1  christos 
   1204           1.1  christos 	if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
   1205           1.1  christos 		if (bev_ssl->underlying) {
   1206           1.1  christos 			if (BEV_UPCAST(bev_ssl->underlying)->refcnt < 2) {
   1207           1.1  christos 				event_warnx("BEV_OPT_CLOSE_ON_FREE set on an "
   1208           1.1  christos 				    "bufferevent with too few references");
   1209           1.1  christos 			} else {
   1210           1.1  christos 				bufferevent_free(bev_ssl->underlying);
   1211  1.1.1.1.16.1  pgoyette 				/* We still have a reference to it, via our
   1212  1.1.1.1.16.1  pgoyette 				 * BIO. So we don't drop this. */
   1213  1.1.1.1.16.1  pgoyette 				// bev_ssl->underlying = NULL;
   1214           1.1  christos 			}
   1215           1.1  christos 		}
   1216           1.1  christos 	} else {
   1217           1.1  christos 		if (bev_ssl->underlying) {
   1218           1.1  christos 			if (bev_ssl->underlying->errorcb == be_openssl_eventcb)
   1219           1.1  christos 				bufferevent_setcb(bev_ssl->underlying,
   1220           1.1  christos 				    NULL,NULL,NULL,NULL);
   1221  1.1.1.1.16.1  pgoyette 			bufferevent_unsuspend_read_(bev_ssl->underlying,
   1222           1.1  christos 			    BEV_SUSPEND_FILT_READ);
   1223           1.1  christos 		}
   1224           1.1  christos 	}
   1225           1.1  christos }
   1226           1.1  christos 
   1227  1.1.1.1.16.1  pgoyette static void
   1228  1.1.1.1.16.1  pgoyette be_openssl_destruct(struct bufferevent *bev)
   1229  1.1.1.1.16.1  pgoyette {
   1230  1.1.1.1.16.1  pgoyette 	struct bufferevent_openssl *bev_ssl = upcast(bev);
   1231  1.1.1.1.16.1  pgoyette 
   1232  1.1.1.1.16.1  pgoyette 	if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
   1233  1.1.1.1.16.1  pgoyette 		if (! bev_ssl->underlying) {
   1234  1.1.1.1.16.1  pgoyette 			evutil_socket_t fd = -1;
   1235  1.1.1.1.16.1  pgoyette 			BIO *bio = SSL_get_wbio(bev_ssl->ssl);
   1236  1.1.1.1.16.1  pgoyette 			if (bio)
   1237  1.1.1.1.16.1  pgoyette 				fd = BIO_get_fd(bio, NULL);
   1238  1.1.1.1.16.1  pgoyette 			if (fd >= 0)
   1239  1.1.1.1.16.1  pgoyette 				evutil_closesocket(fd);
   1240  1.1.1.1.16.1  pgoyette 		}
   1241  1.1.1.1.16.1  pgoyette 		SSL_free(bev_ssl->ssl);
   1242  1.1.1.1.16.1  pgoyette 	}
   1243  1.1.1.1.16.1  pgoyette }
   1244  1.1.1.1.16.1  pgoyette 
   1245           1.1  christos static int
   1246           1.1  christos be_openssl_adj_timeouts(struct bufferevent *bev)
   1247           1.1  christos {
   1248           1.1  christos 	struct bufferevent_openssl *bev_ssl = upcast(bev);
   1249           1.1  christos 
   1250  1.1.1.1.16.1  pgoyette 	if (bev_ssl->underlying) {
   1251  1.1.1.1.16.1  pgoyette 		return bufferevent_generic_adj_timeouts_(bev);
   1252  1.1.1.1.16.1  pgoyette 	} else {
   1253  1.1.1.1.16.1  pgoyette 		return bufferevent_generic_adj_existing_timeouts_(bev);
   1254           1.1  christos 	}
   1255           1.1  christos }
   1256           1.1  christos 
   1257           1.1  christos static int
   1258           1.1  christos be_openssl_flush(struct bufferevent *bufev,
   1259           1.1  christos     short iotype, enum bufferevent_flush_mode mode)
   1260           1.1  christos {
   1261           1.1  christos 	/* XXXX Implement this. */
   1262           1.1  christos 	return 0;
   1263           1.1  christos }
   1264           1.1  christos 
   1265           1.1  christos static int
   1266  1.1.1.1.16.1  pgoyette be_openssl_set_fd(struct bufferevent_openssl *bev_ssl,
   1267  1.1.1.1.16.1  pgoyette     enum bufferevent_ssl_state state, int fd)
   1268  1.1.1.1.16.1  pgoyette {
   1269  1.1.1.1.16.1  pgoyette 	bev_ssl->state = state;
   1270  1.1.1.1.16.1  pgoyette 
   1271  1.1.1.1.16.1  pgoyette 	switch (state) {
   1272  1.1.1.1.16.1  pgoyette 	case BUFFEREVENT_SSL_ACCEPTING:
   1273  1.1.1.1.16.1  pgoyette 		SSL_set_accept_state(bev_ssl->ssl);
   1274  1.1.1.1.16.1  pgoyette 		if (set_handshake_callbacks(bev_ssl, fd) < 0)
   1275  1.1.1.1.16.1  pgoyette 			return -1;
   1276  1.1.1.1.16.1  pgoyette 		break;
   1277  1.1.1.1.16.1  pgoyette 	case BUFFEREVENT_SSL_CONNECTING:
   1278  1.1.1.1.16.1  pgoyette 		SSL_set_connect_state(bev_ssl->ssl);
   1279  1.1.1.1.16.1  pgoyette 		if (set_handshake_callbacks(bev_ssl, fd) < 0)
   1280  1.1.1.1.16.1  pgoyette 			return -1;
   1281  1.1.1.1.16.1  pgoyette 		break;
   1282  1.1.1.1.16.1  pgoyette 	case BUFFEREVENT_SSL_OPEN:
   1283  1.1.1.1.16.1  pgoyette 		if (set_open_callbacks(bev_ssl, fd) < 0)
   1284  1.1.1.1.16.1  pgoyette 			return -1;
   1285  1.1.1.1.16.1  pgoyette 		break;
   1286  1.1.1.1.16.1  pgoyette 	default:
   1287  1.1.1.1.16.1  pgoyette 		return -1;
   1288  1.1.1.1.16.1  pgoyette 	}
   1289  1.1.1.1.16.1  pgoyette 
   1290  1.1.1.1.16.1  pgoyette 	return 0;
   1291  1.1.1.1.16.1  pgoyette }
   1292  1.1.1.1.16.1  pgoyette 
   1293  1.1.1.1.16.1  pgoyette static int
   1294           1.1  christos be_openssl_ctrl(struct bufferevent *bev,
   1295           1.1  christos     enum bufferevent_ctrl_op op, union bufferevent_ctrl_data *data)
   1296           1.1  christos {
   1297           1.1  christos 	struct bufferevent_openssl *bev_ssl = upcast(bev);
   1298           1.1  christos 	switch (op) {
   1299           1.1  christos 	case BEV_CTRL_SET_FD:
   1300  1.1.1.1.16.1  pgoyette 		if (!bev_ssl->underlying) {
   1301           1.1  christos 			BIO *bio;
   1302           1.1  christos 			bio = BIO_new_socket(data->fd, 0);
   1303           1.1  christos 			SSL_set_bio(bev_ssl->ssl, bio, bio);
   1304  1.1.1.1.16.1  pgoyette 		} else {
   1305  1.1.1.1.16.1  pgoyette 			BIO *bio;
   1306  1.1.1.1.16.1  pgoyette 			if (!(bio = BIO_new_bufferevent(bev_ssl->underlying, 0)))
   1307  1.1.1.1.16.1  pgoyette 				return -1;
   1308  1.1.1.1.16.1  pgoyette 			SSL_set_bio(bev_ssl->ssl, bio, bio);
   1309           1.1  christos 		}
   1310  1.1.1.1.16.1  pgoyette 
   1311  1.1.1.1.16.1  pgoyette 		return be_openssl_set_fd(bev_ssl, bev_ssl->old_state, data->fd);
   1312           1.1  christos 	case BEV_CTRL_GET_FD:
   1313  1.1.1.1.16.1  pgoyette 		if (bev_ssl->underlying) {
   1314  1.1.1.1.16.1  pgoyette 			data->fd = event_get_fd(&bev_ssl->underlying->ev_read);
   1315  1.1.1.1.16.1  pgoyette 		} else {
   1316  1.1.1.1.16.1  pgoyette 			data->fd = event_get_fd(&bev->ev_read);
   1317  1.1.1.1.16.1  pgoyette 		}
   1318           1.1  christos 		return 0;
   1319           1.1  christos 	case BEV_CTRL_GET_UNDERLYING:
   1320           1.1  christos 		data->ptr = bev_ssl->underlying;
   1321           1.1  christos 		return 0;
   1322           1.1  christos 	case BEV_CTRL_CANCEL_ALL:
   1323           1.1  christos 	default:
   1324           1.1  christos 		return -1;
   1325           1.1  christos 	}
   1326           1.1  christos }
   1327           1.1  christos 
   1328           1.1  christos SSL *
   1329           1.1  christos bufferevent_openssl_get_ssl(struct bufferevent *bufev)
   1330           1.1  christos {
   1331           1.1  christos 	struct bufferevent_openssl *bev_ssl = upcast(bufev);
   1332           1.1  christos 	if (!bev_ssl)
   1333           1.1  christos 		return NULL;
   1334           1.1  christos 	return bev_ssl->ssl;
   1335           1.1  christos }
   1336           1.1  christos 
   1337           1.1  christos static struct bufferevent *
   1338           1.1  christos bufferevent_openssl_new_impl(struct event_base *base,
   1339           1.1  christos     struct bufferevent *underlying,
   1340           1.1  christos     evutil_socket_t fd,
   1341           1.1  christos     SSL *ssl,
   1342           1.1  christos     enum bufferevent_ssl_state state,
   1343           1.1  christos     int options)
   1344           1.1  christos {
   1345           1.1  christos 	struct bufferevent_openssl *bev_ssl = NULL;
   1346           1.1  christos 	struct bufferevent_private *bev_p = NULL;
   1347           1.1  christos 	int tmp_options = options & ~BEV_OPT_THREADSAFE;
   1348           1.1  christos 
   1349           1.1  christos 	if (underlying != NULL && fd >= 0)
   1350           1.1  christos 		return NULL; /* Only one can be set. */
   1351           1.1  christos 
   1352           1.1  christos 	if (!(bev_ssl = mm_calloc(1, sizeof(struct bufferevent_openssl))))
   1353           1.1  christos 		goto err;
   1354           1.1  christos 
   1355           1.1  christos 	bev_p = &bev_ssl->bev;
   1356           1.1  christos 
   1357  1.1.1.1.16.1  pgoyette 	if (bufferevent_init_common_(bev_p, base,
   1358           1.1  christos 		&bufferevent_ops_openssl, tmp_options) < 0)
   1359           1.1  christos 		goto err;
   1360           1.1  christos 
   1361           1.1  christos 	/* Don't explode if we decide to realloc a chunk we're writing from in
   1362           1.1  christos 	 * the output buffer. */
   1363           1.1  christos 	SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
   1364           1.1  christos 
   1365           1.1  christos 	bev_ssl->underlying = underlying;
   1366           1.1  christos 	bev_ssl->ssl = ssl;
   1367           1.1  christos 
   1368           1.1  christos 	bev_ssl->outbuf_cb = evbuffer_add_cb(bev_p->bev.output,
   1369           1.1  christos 	    be_openssl_outbuf_cb, bev_ssl);
   1370           1.1  christos 
   1371           1.1  christos 	if (options & BEV_OPT_THREADSAFE)
   1372  1.1.1.1.16.1  pgoyette 		bufferevent_enable_locking_(&bev_ssl->bev.bev, NULL);
   1373           1.1  christos 
   1374           1.1  christos 	if (underlying) {
   1375  1.1.1.1.16.1  pgoyette 		bufferevent_init_generic_timeout_cbs_(&bev_ssl->bev.bev);
   1376  1.1.1.1.16.1  pgoyette 		bufferevent_incref_(underlying);
   1377           1.1  christos 	}
   1378           1.1  christos 
   1379  1.1.1.1.16.1  pgoyette 	bev_ssl->old_state = state;
   1380           1.1  christos 	bev_ssl->last_write = -1;
   1381           1.1  christos 
   1382           1.1  christos 	init_bio_counts(bev_ssl);
   1383           1.1  christos 
   1384  1.1.1.1.16.1  pgoyette 	fd = be_openssl_auto_fd(bev_ssl, fd);
   1385  1.1.1.1.16.1  pgoyette 	if (be_openssl_set_fd(bev_ssl, state, fd))
   1386           1.1  christos 		goto err;
   1387           1.1  christos 
   1388           1.1  christos 	if (underlying) {
   1389           1.1  christos 		bufferevent_setwatermark(underlying, EV_READ, 0, 0);
   1390           1.1  christos 		bufferevent_enable(underlying, EV_READ|EV_WRITE);
   1391           1.1  christos 		if (state == BUFFEREVENT_SSL_OPEN)
   1392  1.1.1.1.16.1  pgoyette 			bufferevent_suspend_read_(underlying,
   1393           1.1  christos 			    BEV_SUSPEND_FILT_READ);
   1394           1.1  christos 	}
   1395           1.1  christos 
   1396           1.1  christos 	return &bev_ssl->bev.bev;
   1397           1.1  christos err:
   1398           1.1  christos 	if (bev_ssl)
   1399           1.1  christos 		bufferevent_free(&bev_ssl->bev.bev);
   1400           1.1  christos 	return NULL;
   1401           1.1  christos }
   1402           1.1  christos 
   1403           1.1  christos struct bufferevent *
   1404           1.1  christos bufferevent_openssl_filter_new(struct event_base *base,
   1405           1.1  christos     struct bufferevent *underlying,
   1406           1.1  christos     SSL *ssl,
   1407           1.1  christos     enum bufferevent_ssl_state state,
   1408           1.1  christos     int options)
   1409           1.1  christos {
   1410           1.1  christos 	/* We don't tell the BIO to close the bufferevent; we do it ourselves
   1411           1.1  christos 	 * on be_openssl_destruct */
   1412           1.1  christos 	int close_flag = 0; /* options & BEV_OPT_CLOSE_ON_FREE; */
   1413           1.1  christos 	BIO *bio;
   1414           1.1  christos 	if (!underlying)
   1415           1.1  christos 		return NULL;
   1416           1.1  christos 	if (!(bio = BIO_new_bufferevent(underlying, close_flag)))
   1417           1.1  christos 		return NULL;
   1418           1.1  christos 
   1419           1.1  christos 	SSL_set_bio(ssl, bio, bio);
   1420           1.1  christos 
   1421           1.1  christos 	return bufferevent_openssl_new_impl(
   1422           1.1  christos 		base, underlying, -1, ssl, state, options);
   1423           1.1  christos }
   1424           1.1  christos 
   1425           1.1  christos struct bufferevent *
   1426           1.1  christos bufferevent_openssl_socket_new(struct event_base *base,
   1427           1.1  christos     evutil_socket_t fd,
   1428           1.1  christos     SSL *ssl,
   1429           1.1  christos     enum bufferevent_ssl_state state,
   1430           1.1  christos     int options)
   1431           1.1  christos {
   1432           1.1  christos 	/* Does the SSL already have an fd? */
   1433           1.1  christos 	BIO *bio = SSL_get_wbio(ssl);
   1434           1.1  christos 	long have_fd = -1;
   1435           1.1  christos 
   1436           1.1  christos 	if (bio)
   1437           1.1  christos 		have_fd = BIO_get_fd(bio, NULL);
   1438           1.1  christos 
   1439           1.1  christos 	if (have_fd >= 0) {
   1440           1.1  christos 		/* The SSL is already configured with an fd. */
   1441           1.1  christos 		if (fd < 0) {
   1442           1.1  christos 			/* We should learn the fd from the SSL. */
   1443           1.1  christos 			fd = (evutil_socket_t) have_fd;
   1444           1.1  christos 		} else if (have_fd == (long)fd) {
   1445           1.1  christos 			/* We already know the fd from the SSL; do nothing */
   1446           1.1  christos 		} else {
   1447           1.1  christos 			/* We specified an fd different from that of the SSL.
   1448           1.1  christos 			   This is probably an error on our part.  Fail. */
   1449           1.1  christos 			return NULL;
   1450           1.1  christos 		}
   1451           1.1  christos 		(void) BIO_set_close(bio, 0);
   1452           1.1  christos 	} else {
   1453           1.1  christos 		/* The SSL isn't configured with a BIO with an fd. */
   1454           1.1  christos 		if (fd >= 0) {
   1455           1.1  christos 			/* ... and we have an fd we want to use. */
   1456           1.1  christos 			bio = BIO_new_socket(fd, 0);
   1457           1.1  christos 			SSL_set_bio(ssl, bio, bio);
   1458           1.1  christos 		} else {
   1459           1.1  christos 			/* Leave the fd unset. */
   1460           1.1  christos 		}
   1461           1.1  christos 	}
   1462           1.1  christos 
   1463           1.1  christos 	return bufferevent_openssl_new_impl(
   1464           1.1  christos 		base, NULL, fd, ssl, state, options);
   1465           1.1  christos }
   1466           1.1  christos 
   1467  1.1.1.1.16.1  pgoyette int
   1468  1.1.1.1.16.1  pgoyette bufferevent_openssl_get_allow_dirty_shutdown(struct bufferevent *bev)
   1469  1.1.1.1.16.1  pgoyette {
   1470  1.1.1.1.16.1  pgoyette 	int allow_dirty_shutdown = -1;
   1471  1.1.1.1.16.1  pgoyette 	struct bufferevent_openssl *bev_ssl;
   1472  1.1.1.1.16.1  pgoyette 	BEV_LOCK(bev);
   1473  1.1.1.1.16.1  pgoyette 	bev_ssl = upcast(bev);
   1474  1.1.1.1.16.1  pgoyette 	if (bev_ssl)
   1475  1.1.1.1.16.1  pgoyette 		allow_dirty_shutdown = bev_ssl->allow_dirty_shutdown;
   1476  1.1.1.1.16.1  pgoyette 	BEV_UNLOCK(bev);
   1477  1.1.1.1.16.1  pgoyette 	return allow_dirty_shutdown;
   1478  1.1.1.1.16.1  pgoyette }
   1479  1.1.1.1.16.1  pgoyette 
   1480  1.1.1.1.16.1  pgoyette void
   1481  1.1.1.1.16.1  pgoyette bufferevent_openssl_set_allow_dirty_shutdown(struct bufferevent *bev,
   1482  1.1.1.1.16.1  pgoyette     int allow_dirty_shutdown)
   1483  1.1.1.1.16.1  pgoyette {
   1484  1.1.1.1.16.1  pgoyette 	struct bufferevent_openssl *bev_ssl;
   1485  1.1.1.1.16.1  pgoyette 	BEV_LOCK(bev);
   1486  1.1.1.1.16.1  pgoyette 	bev_ssl = upcast(bev);
   1487  1.1.1.1.16.1  pgoyette 	if (bev_ssl)
   1488  1.1.1.1.16.1  pgoyette 		bev_ssl->allow_dirty_shutdown = !!allow_dirty_shutdown;
   1489  1.1.1.1.16.1  pgoyette 	BEV_UNLOCK(bev);
   1490  1.1.1.1.16.1  pgoyette }
   1491  1.1.1.1.16.1  pgoyette 
   1492           1.1  christos unsigned long
   1493           1.1  christos bufferevent_get_openssl_error(struct bufferevent *bev)
   1494           1.1  christos {
   1495           1.1  christos 	unsigned long err = 0;
   1496           1.1  christos 	struct bufferevent_openssl *bev_ssl;
   1497           1.1  christos 	BEV_LOCK(bev);
   1498           1.1  christos 	bev_ssl = upcast(bev);
   1499           1.1  christos 	if (bev_ssl && bev_ssl->n_errors) {
   1500           1.1  christos 		err = bev_ssl->errors[--bev_ssl->n_errors];
   1501           1.1  christos 	}
   1502           1.1  christos 	BEV_UNLOCK(bev);
   1503           1.1  christos 	return err;
   1504           1.1  christos }
   1505