ipc/chromium/src/third_party/libevent/bufferevent_openssl.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/third_party/libevent/bufferevent_openssl.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1454 @@
     1.4 +/*
     1.5 + * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
     1.6 + *
     1.7 + * Redistribution and use in source and binary forms, with or without
     1.8 + * modification, are permitted provided that the following conditions
     1.9 + * are met:
    1.10 + * 1. Redistributions of source code must retain the above copyright
    1.11 + *    notice, this list of conditions and the following disclaimer.
    1.12 + * 2. Redistributions in binary form must reproduce the above copyright
    1.13 + *    notice, this list of conditions and the following disclaimer in the
    1.14 + *    documentation and/or other materials provided with the distribution.
    1.15 + * 3. The name of the author may not be used to endorse or promote products
    1.16 + *    derived from this software without specific prior written permission.
    1.17 + *
    1.18 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    1.19 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    1.20 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    1.21 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    1.22 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    1.23 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.24 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.25 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.26 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    1.27 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.28 + */
    1.29 +
    1.30 +#include <sys/types.h>
    1.31 +
    1.32 +#include "event2/event-config.h"
    1.33 +
    1.34 +#ifdef _EVENT_HAVE_SYS_TIME_H
    1.35 +#include <sys/time.h>
    1.36 +#endif
    1.37 +
    1.38 +#include <errno.h>
    1.39 +#include <stdio.h>
    1.40 +#include <stdlib.h>
    1.41 +#include <string.h>
    1.42 +#ifdef _EVENT_HAVE_STDARG_H
    1.43 +#include <stdarg.h>
    1.44 +#endif
    1.45 +#ifdef _EVENT_HAVE_UNISTD_H
    1.46 +#include <unistd.h>
    1.47 +#endif
    1.48 +
    1.49 +#ifdef WIN32
    1.50 +#include <winsock2.h>
    1.51 +#endif
    1.52 +
    1.53 +#include "event2/bufferevent.h"
    1.54 +#include "event2/bufferevent_struct.h"
    1.55 +#include "event2/bufferevent_ssl.h"
    1.56 +#include "event2/buffer.h"
    1.57 +#include "event2/event.h"
    1.58 +
    1.59 +#include "mm-internal.h"
    1.60 +#include "bufferevent-internal.h"
    1.61 +#include "log-internal.h"
    1.62 +
    1.63 +#include <openssl/bio.h>
    1.64 +#include <openssl/ssl.h>
    1.65 +#include <openssl/err.h>
    1.66 +
    1.67 +/*
    1.68 + * Define an OpenSSL bio that targets a bufferevent.
    1.69 + */
    1.70 +
    1.71 +/* --------------------
    1.72 +   A BIO is an OpenSSL abstraction that handles reading and writing data.  The
    1.73 +   library will happily speak SSL over anything that implements a BIO
    1.74 +   interface.
    1.75 +
    1.76 +   Here we define a BIO implementation that directs its output to a
    1.77 +   bufferevent.  We'll want to use this only when none of OpenSSL's built-in
    1.78 +   IO mechanisms work for us.
    1.79 +   -------------------- */
    1.80 +
    1.81 +/* every BIO type needs its own integer type value. */
    1.82 +#define BIO_TYPE_LIBEVENT 57
    1.83 +/* ???? Arguably, we should set BIO_TYPE_FILTER or BIO_TYPE_SOURCE_SINK on
    1.84 + * this. */
    1.85 +
    1.86 +#if 0
    1.87 +static void
    1.88 +print_err(int val)
    1.89 +{
    1.90 +	int err;
    1.91 +	printf("Error was %d\n", val);
    1.92 +
    1.93 +	while ((err = ERR_get_error())) {
    1.94 +		const char *msg = (const char*)ERR_reason_error_string(err);
    1.95 +		const char *lib = (const char*)ERR_lib_error_string(err);
    1.96 +		const char *func = (const char*)ERR_func_error_string(err);
    1.97 +
    1.98 +		printf("%s in %s %s\n", msg, lib, func);
    1.99 +	}
   1.100 +}
   1.101 +#else
   1.102 +#define print_err(v) ((void)0)
   1.103 +#endif
   1.104 +
   1.105 +/* Called to initialize a new BIO */
   1.106 +static int
   1.107 +bio_bufferevent_new(BIO *b)
   1.108 +{
   1.109 +	b->init = 0;
   1.110 +	b->num = -1;
   1.111 +	b->ptr = NULL; /* We'll be putting the bufferevent in this field.*/
   1.112 +	b->flags = 0;
   1.113 +	return 1;
   1.114 +}
   1.115 +
   1.116 +/* Called to uninitialize the BIO. */
   1.117 +static int
   1.118 +bio_bufferevent_free(BIO *b)
   1.119 +{
   1.120 +	if (!b)
   1.121 +		return 0;
   1.122 +	if (b->shutdown) {
   1.123 +		if (b->init && b->ptr)
   1.124 +			bufferevent_free(b->ptr);
   1.125 +		b->init = 0;
   1.126 +		b->flags = 0;
   1.127 +		b->ptr = NULL;
   1.128 +	}
   1.129 +	return 1;
   1.130 +}
   1.131 +
   1.132 +/* Called to extract data from the BIO. */
   1.133 +static int
   1.134 +bio_bufferevent_read(BIO *b, char *out, int outlen)
   1.135 +{
   1.136 +	int r = 0;
   1.137 +	struct evbuffer *input;
   1.138 +
   1.139 +	BIO_clear_retry_flags(b);
   1.140 +
   1.141 +	if (!out)
   1.142 +		return 0;
   1.143 +	if (!b->ptr)
   1.144 +		return -1;
   1.145 +
   1.146 +	input = bufferevent_get_input(b->ptr);
   1.147 +	if (evbuffer_get_length(input) == 0) {
   1.148 +		/* If there's no data to read, say so. */
   1.149 +		BIO_set_retry_read(b);
   1.150 +		return -1;
   1.151 +	} else {
   1.152 +		r = evbuffer_remove(input, out, outlen);
   1.153 +	}
   1.154 +
   1.155 +	return r;
   1.156 +}
   1.157 +
   1.158 +/* Called to write data info the BIO */
   1.159 +static int
   1.160 +bio_bufferevent_write(BIO *b, const char *in, int inlen)
   1.161 +{
   1.162 +	struct bufferevent *bufev = b->ptr;
   1.163 +	struct evbuffer *output;
   1.164 +	size_t outlen;
   1.165 +
   1.166 +	BIO_clear_retry_flags(b);
   1.167 +
   1.168 +	if (!b->ptr)
   1.169 +		return -1;
   1.170 +
   1.171 +	output = bufferevent_get_output(bufev);
   1.172 +	outlen = evbuffer_get_length(output);
   1.173 +
   1.174 +	/* Copy only as much data onto the output buffer as can fit under the
   1.175 +	 * high-water mark. */
   1.176 +	if (bufev->wm_write.high && bufev->wm_write.high <= (outlen+inlen)) {
   1.177 +		if (bufev->wm_write.high <= outlen) {
   1.178 +			/* If no data can fit, we'll need to retry later. */
   1.179 +			BIO_set_retry_write(b);
   1.180 +			return -1;
   1.181 +		}
   1.182 +		inlen = bufev->wm_write.high - outlen;
   1.183 +	}
   1.184 +
   1.185 +	EVUTIL_ASSERT(inlen > 0);
   1.186 +	evbuffer_add(output, in, inlen);
   1.187 +	return inlen;
   1.188 +}
   1.189 +
   1.190 +/* Called to handle various requests */
   1.191 +static long
   1.192 +bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr)
   1.193 +{
   1.194 +	struct bufferevent *bufev = b->ptr;
   1.195 +	long ret = 1;
   1.196 +
   1.197 +	switch (cmd) {
   1.198 +	case BIO_CTRL_GET_CLOSE:
   1.199 +		ret = b->shutdown;
   1.200 +		break;
   1.201 +	case BIO_CTRL_SET_CLOSE:
   1.202 +		b->shutdown = (int)num;
   1.203 +		break;
   1.204 +	case BIO_CTRL_PENDING:
   1.205 +		ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0;
   1.206 +		break;
   1.207 +	case BIO_CTRL_WPENDING:
   1.208 +		ret = evbuffer_get_length(bufferevent_get_output(bufev)) != 0;
   1.209 +		break;
   1.210 +	/* XXXX These two are given a special-case treatment because
   1.211 +	 * of cargo-cultism.  I should come up with a better reason. */
   1.212 +	case BIO_CTRL_DUP:
   1.213 +	case BIO_CTRL_FLUSH:
   1.214 +		ret = 1;
   1.215 +		break;
   1.216 +	default:
   1.217 +		ret = 0;
   1.218 +		break;
   1.219 +	}
   1.220 +	return ret;
   1.221 +}
   1.222 +
   1.223 +/* Called to write a string to the BIO */
   1.224 +static int
   1.225 +bio_bufferevent_puts(BIO *b, const char *s)
   1.226 +{
   1.227 +	return bio_bufferevent_write(b, s, strlen(s));
   1.228 +}
   1.229 +
   1.230 +/* Method table for the bufferevent BIO */
   1.231 +static BIO_METHOD methods_bufferevent = {
   1.232 +	BIO_TYPE_LIBEVENT, "bufferevent",
   1.233 +	bio_bufferevent_write,
   1.234 +	bio_bufferevent_read,
   1.235 +	bio_bufferevent_puts,
   1.236 +	NULL /* bio_bufferevent_gets */,
   1.237 +	bio_bufferevent_ctrl,
   1.238 +	bio_bufferevent_new,
   1.239 +	bio_bufferevent_free,
   1.240 +	NULL /* callback_ctrl */,
   1.241 +};
   1.242 +
   1.243 +/* Return the method table for the bufferevents BIO */
   1.244 +static BIO_METHOD *
   1.245 +BIO_s_bufferevent(void)
   1.246 +{
   1.247 +	return &methods_bufferevent;
   1.248 +}
   1.249 +
   1.250 +/* Create a new BIO to wrap communication around a bufferevent.  If close_flag
   1.251 + * is true, the bufferevent will be freed when the BIO is closed. */
   1.252 +static BIO *
   1.253 +BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag)
   1.254 +{
   1.255 +	BIO *result;
   1.256 +	if (!bufferevent)
   1.257 +		return NULL;
   1.258 +	if (!(result = BIO_new(BIO_s_bufferevent())))
   1.259 +		return NULL;
   1.260 +	result->init = 1;
   1.261 +	result->ptr = bufferevent;
   1.262 +	result->shutdown = close_flag ? 1 : 0;
   1.263 +	return result;
   1.264 +}
   1.265 +
   1.266 +/* --------------------
   1.267 +   Now, here's the OpenSSL-based implementation of bufferevent.
   1.268 +
   1.269 +   The implementation comes in two flavors: one that connects its SSL object
   1.270 +   to an underlying bufferevent using a BIO_bufferevent, and one that has the
   1.271 +   SSL object connect to a socket directly.  The latter should generally be
   1.272 +   faster, except on Windows, where your best bet is using a
   1.273 +   bufferevent_async.
   1.274 +
   1.275 +   (OpenSSL supports many other BIO types, too.  But we can't use any unless
   1.276 +   we have a good way to get notified when they become readable/writable.)
   1.277 +   -------------------- */
   1.278 +
   1.279 +struct bio_data_counts {
   1.280 +	unsigned long n_written;
   1.281 +	unsigned long n_read;
   1.282 +};
   1.283 +
   1.284 +struct bufferevent_openssl {
   1.285 +	/* Shared fields with common bufferevent implementation code.
   1.286 +	   If we were set up with an underlying bufferevent, we use the
   1.287 +	   events here as timers only.  If we have an SSL, then we use
   1.288 +	   the events as socket events.
   1.289 +	 */
   1.290 +	struct bufferevent_private bev;
   1.291 +	/* An underlying bufferevent that we're directing our output to.
   1.292 +	   If it's NULL, then we're connected to an fd, not an evbuffer. */
   1.293 +	struct bufferevent *underlying;
   1.294 +	/* The SSL object doing our encryption. */
   1.295 +	SSL *ssl;
   1.296 +
   1.297 +	/* A callback that's invoked when data arrives on our outbuf so we
   1.298 +	   know to write data to the SSL. */
   1.299 +	struct evbuffer_cb_entry *outbuf_cb;
   1.300 +
   1.301 +	/* A count of how much data the bios have read/written total.  Used
   1.302 +	   for rate-limiting. */
   1.303 +	struct bio_data_counts counts;
   1.304 +
   1.305 +	/* If this value is greater than 0, then the last SSL_write blocked,
   1.306 +	 * and we need to try it again with this many bytes. */
   1.307 +	ev_ssize_t last_write;
   1.308 +
   1.309 +#define NUM_ERRORS 3
   1.310 +	ev_uint32_t errors[NUM_ERRORS];
   1.311 +
   1.312 +	/* When we next get available space, we should say "read" instead of
   1.313 +	   "write". This can happen if there's a renegotiation during a read
   1.314 +	   operation. */
   1.315 +	unsigned read_blocked_on_write : 1;
   1.316 +	/* When we next get data, we should say "write" instead of "read". */
   1.317 +	unsigned write_blocked_on_read : 1;
   1.318 +	/* XXX */
   1.319 +	unsigned allow_dirty_shutdown : 1;
   1.320 +	/* XXXX */
   1.321 +	unsigned fd_is_set : 1;
   1.322 +	/* XXX */
   1.323 +	unsigned n_errors : 2;
   1.324 +
   1.325 +	/* Are we currently connecting, accepting, or doing IO? */
   1.326 +	unsigned state : 2;
   1.327 +};
   1.328 +
   1.329 +static int be_openssl_enable(struct bufferevent *, short);
   1.330 +static int be_openssl_disable(struct bufferevent *, short);
   1.331 +static void be_openssl_destruct(struct bufferevent *);
   1.332 +static int be_openssl_adj_timeouts(struct bufferevent *);
   1.333 +static int be_openssl_flush(struct bufferevent *bufev,
   1.334 +    short iotype, enum bufferevent_flush_mode mode);
   1.335 +static int be_openssl_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *);
   1.336 +
   1.337 +const struct bufferevent_ops bufferevent_ops_openssl = {
   1.338 +	"ssl",
   1.339 +	evutil_offsetof(struct bufferevent_openssl, bev.bev),
   1.340 +	be_openssl_enable,
   1.341 +	be_openssl_disable,
   1.342 +	be_openssl_destruct,
   1.343 +	be_openssl_adj_timeouts,
   1.344 +	be_openssl_flush,
   1.345 +	be_openssl_ctrl,
   1.346 +};
   1.347 +
   1.348 +/* Given a bufferevent, return a pointer to the bufferevent_openssl that
   1.349 + * contains it, if any. */
   1.350 +static inline struct bufferevent_openssl *
   1.351 +upcast(struct bufferevent *bev)
   1.352 +{
   1.353 +	struct bufferevent_openssl *bev_o;
   1.354 +	if (bev->be_ops != &bufferevent_ops_openssl)
   1.355 +		return NULL;
   1.356 +	bev_o = (void*)( ((char*)bev) -
   1.357 +			 evutil_offsetof(struct bufferevent_openssl, bev.bev));
   1.358 +	EVUTIL_ASSERT(bev_o->bev.bev.be_ops == &bufferevent_ops_openssl);
   1.359 +	return bev_o;
   1.360 +}
   1.361 +
   1.362 +static inline void
   1.363 +put_error(struct bufferevent_openssl *bev_ssl, unsigned long err)
   1.364 +{
   1.365 +	if (bev_ssl->n_errors == NUM_ERRORS)
   1.366 +		return;
   1.367 +	/* The error type according to openssl is "unsigned long", but
   1.368 +	   openssl never uses more than 32 bits of it.  It _can't_ use more
   1.369 +	   than 32 bits of it, since it needs to report errors on systems
   1.370 +	   where long is only 32 bits.
   1.371 +	 */
   1.372 +	bev_ssl->errors[bev_ssl->n_errors++] = (ev_uint32_t) err;
   1.373 +}
   1.374 +
   1.375 +/* Have the base communications channel (either the underlying bufferevent or
   1.376 + * ev_read and ev_write) start reading.  Take the read-blocked-on-write flag
   1.377 + * into account. */
   1.378 +static int
   1.379 +start_reading(struct bufferevent_openssl *bev_ssl)
   1.380 +{
   1.381 +	if (bev_ssl->underlying) {
   1.382 +		bufferevent_unsuspend_read(bev_ssl->underlying,
   1.383 +		    BEV_SUSPEND_FILT_READ);
   1.384 +		return 0;
   1.385 +	} else {
   1.386 +		struct bufferevent *bev = &bev_ssl->bev.bev;
   1.387 +		int r;
   1.388 +		r = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
   1.389 +		if (r == 0 && bev_ssl->read_blocked_on_write)
   1.390 +			r = _bufferevent_add_event(&bev->ev_write,
   1.391 +			    &bev->timeout_write);
   1.392 +		return r;
   1.393 +	}
   1.394 +}
   1.395 +
   1.396 +/* Have the base communications channel (either the underlying bufferevent or
   1.397 + * ev_read and ev_write) start writing.  Take the write-blocked-on-read flag
   1.398 + * into account. */
   1.399 +static int
   1.400 +start_writing(struct bufferevent_openssl *bev_ssl)
   1.401 +{
   1.402 +	int r = 0;
   1.403 +	if (bev_ssl->underlying) {
   1.404 +		;
   1.405 +	} else {
   1.406 +		struct bufferevent *bev = &bev_ssl->bev.bev;
   1.407 +		r = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
   1.408 +		if (!r && bev_ssl->write_blocked_on_read)
   1.409 +			r = _bufferevent_add_event(&bev->ev_read,
   1.410 +			    &bev->timeout_read);
   1.411 +	}
   1.412 +	return r;
   1.413 +}
   1.414 +
   1.415 +static void
   1.416 +stop_reading(struct bufferevent_openssl *bev_ssl)
   1.417 +{
   1.418 +	if (bev_ssl->write_blocked_on_read)
   1.419 +		return;
   1.420 +	if (bev_ssl->underlying) {
   1.421 +		bufferevent_suspend_read(bev_ssl->underlying,
   1.422 +		    BEV_SUSPEND_FILT_READ);
   1.423 +	} else {
   1.424 +		struct bufferevent *bev = &bev_ssl->bev.bev;
   1.425 +		event_del(&bev->ev_read);
   1.426 +	}
   1.427 +}
   1.428 +
   1.429 +static void
   1.430 +stop_writing(struct bufferevent_openssl *bev_ssl)
   1.431 +{
   1.432 +	if (bev_ssl->read_blocked_on_write)
   1.433 +		return;
   1.434 +	if (bev_ssl->underlying) {
   1.435 +		;
   1.436 +	} else {
   1.437 +		struct bufferevent *bev = &bev_ssl->bev.bev;
   1.438 +		event_del(&bev->ev_write);
   1.439 +	}
   1.440 +}
   1.441 +
   1.442 +static int
   1.443 +set_rbow(struct bufferevent_openssl *bev_ssl)
   1.444 +{
   1.445 +	if (!bev_ssl->underlying)
   1.446 +		stop_reading(bev_ssl);
   1.447 +	bev_ssl->read_blocked_on_write = 1;
   1.448 +	return start_writing(bev_ssl);
   1.449 +}
   1.450 +
   1.451 +static int
   1.452 +set_wbor(struct bufferevent_openssl *bev_ssl)
   1.453 +{
   1.454 +	if (!bev_ssl->underlying)
   1.455 +		stop_writing(bev_ssl);
   1.456 +	bev_ssl->write_blocked_on_read = 1;
   1.457 +	return start_reading(bev_ssl);
   1.458 +}
   1.459 +
   1.460 +static int
   1.461 +clear_rbow(struct bufferevent_openssl *bev_ssl)
   1.462 +{
   1.463 +	struct bufferevent *bev = &bev_ssl->bev.bev;
   1.464 +	int r = 0;
   1.465 +	bev_ssl->read_blocked_on_write = 0;
   1.466 +	if (!(bev->enabled & EV_WRITE))
   1.467 +		stop_writing(bev_ssl);
   1.468 +	if (bev->enabled & EV_READ)
   1.469 +		r = start_reading(bev_ssl);
   1.470 +	return r;
   1.471 +}
   1.472 +
   1.473 +
   1.474 +static int
   1.475 +clear_wbor(struct bufferevent_openssl *bev_ssl)
   1.476 +{
   1.477 +	struct bufferevent *bev = &bev_ssl->bev.bev;
   1.478 +	int r = 0;
   1.479 +	bev_ssl->write_blocked_on_read = 0;
   1.480 +	if (!(bev->enabled & EV_READ))
   1.481 +		stop_reading(bev_ssl);
   1.482 +	if (bev->enabled & EV_WRITE)
   1.483 +		r = start_writing(bev_ssl);
   1.484 +	return r;
   1.485 +}
   1.486 +
   1.487 +static void
   1.488 +conn_closed(struct bufferevent_openssl *bev_ssl, int errcode, int ret)
   1.489 +{
   1.490 +	int event = BEV_EVENT_ERROR;
   1.491 +	int dirty_shutdown = 0;
   1.492 +	unsigned long err;
   1.493 +
   1.494 +	switch (errcode) {
   1.495 +	case SSL_ERROR_ZERO_RETURN:
   1.496 +		/* Possibly a clean shutdown. */
   1.497 +		if (SSL_get_shutdown(bev_ssl->ssl) & SSL_RECEIVED_SHUTDOWN)
   1.498 +			event = BEV_EVENT_EOF;
   1.499 +		else
   1.500 +			dirty_shutdown = 1;
   1.501 +		break;
   1.502 +	case SSL_ERROR_SYSCALL:
   1.503 +		/* IO error; possibly a dirty shutdown. */
   1.504 +		if (ret == 0 && ERR_peek_error() == 0)
   1.505 +			dirty_shutdown = 1;
   1.506 +		break;
   1.507 +	case SSL_ERROR_SSL:
   1.508 +		/* Protocol error. */
   1.509 +		break;
   1.510 +	case SSL_ERROR_WANT_X509_LOOKUP:
   1.511 +		/* XXXX handle this. */
   1.512 +		break;
   1.513 +	case SSL_ERROR_NONE:
   1.514 +	case SSL_ERROR_WANT_READ:
   1.515 +	case SSL_ERROR_WANT_WRITE:
   1.516 +	case SSL_ERROR_WANT_CONNECT:
   1.517 +	case SSL_ERROR_WANT_ACCEPT:
   1.518 +	default:
   1.519 +		/* should be impossible; treat as normal error. */
   1.520 +		event_warnx("BUG: Unexpected OpenSSL error code %d", errcode);
   1.521 +		break;
   1.522 +	}
   1.523 +
   1.524 +	while ((err = ERR_get_error())) {
   1.525 +		put_error(bev_ssl, err);
   1.526 +	}
   1.527 +
   1.528 +	if (dirty_shutdown && bev_ssl->allow_dirty_shutdown)
   1.529 +		event = BEV_EVENT_EOF;
   1.530 +
   1.531 +	stop_reading(bev_ssl);
   1.532 +	stop_writing(bev_ssl);
   1.533 +
   1.534 +	_bufferevent_run_eventcb(&bev_ssl->bev.bev, event);
   1.535 +}
   1.536 +
   1.537 +static void
   1.538 +init_bio_counts(struct bufferevent_openssl *bev_ssl)
   1.539 +{
   1.540 +	bev_ssl->counts.n_written =
   1.541 +	    BIO_number_written(SSL_get_wbio(bev_ssl->ssl));
   1.542 +	bev_ssl->counts.n_read =
   1.543 +	    BIO_number_read(SSL_get_rbio(bev_ssl->ssl));
   1.544 +}
   1.545 +
   1.546 +static inline void
   1.547 +decrement_buckets(struct bufferevent_openssl *bev_ssl)
   1.548 +{
   1.549 +	unsigned long num_w = BIO_number_written(SSL_get_wbio(bev_ssl->ssl));
   1.550 +	unsigned long num_r = BIO_number_read(SSL_get_rbio(bev_ssl->ssl));
   1.551 +	/* These next two subtractions can wrap around. That's okay. */
   1.552 +	unsigned long w = num_w - bev_ssl->counts.n_written;
   1.553 +	unsigned long r = num_r - bev_ssl->counts.n_read;
   1.554 +	if (w)
   1.555 +		_bufferevent_decrement_write_buckets(&bev_ssl->bev, w);
   1.556 +	if (r)
   1.557 +		_bufferevent_decrement_read_buckets(&bev_ssl->bev, r);
   1.558 +	bev_ssl->counts.n_written = num_w;
   1.559 +	bev_ssl->counts.n_read = num_r;
   1.560 +}
   1.561 +
   1.562 +#define OP_MADE_PROGRESS 1
   1.563 +#define OP_BLOCKED 2
   1.564 +#define OP_ERR 4
   1.565 +
   1.566 +/* Return a bitmask of OP_MADE_PROGRESS (if we read anything); OP_BLOCKED (if
   1.567 +   we're now blocked); and OP_ERR (if an error occurred). */
   1.568 +static int
   1.569 +do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) {
   1.570 +	/* Requires lock */
   1.571 +	struct bufferevent *bev = &bev_ssl->bev.bev;
   1.572 +	struct evbuffer *input = bev->input;
   1.573 +	int r, n, i, n_used = 0, atmost;
   1.574 +	struct evbuffer_iovec space[2];
   1.575 +	int result = 0;
   1.576 +
   1.577 +	if (bev_ssl->bev.read_suspended)
   1.578 +		return 0;
   1.579 +
   1.580 +	atmost = _bufferevent_get_read_max(&bev_ssl->bev);
   1.581 +	if (n_to_read > atmost)
   1.582 +		n_to_read = atmost;
   1.583 +
   1.584 +	n = evbuffer_reserve_space(input, n_to_read, space, 2);
   1.585 +	if (n < 0)
   1.586 +		return OP_ERR;
   1.587 +
   1.588 +	for (i=0; i<n; ++i) {
   1.589 +		if (bev_ssl->bev.read_suspended)
   1.590 +			break;
   1.591 +		r = SSL_read(bev_ssl->ssl, space[i].iov_base, space[i].iov_len);
   1.592 +		if (r>0) {
   1.593 +			result |= OP_MADE_PROGRESS;
   1.594 +			if (bev_ssl->read_blocked_on_write)
   1.595 +				if (clear_rbow(bev_ssl) < 0)
   1.596 +					return OP_ERR | result;
   1.597 +			++n_used;
   1.598 +			space[i].iov_len = r;
   1.599 +			decrement_buckets(bev_ssl);
   1.600 +		} else {
   1.601 +			int err = SSL_get_error(bev_ssl->ssl, r);
   1.602 +			print_err(err);
   1.603 +			switch (err) {
   1.604 +			case SSL_ERROR_WANT_READ:
   1.605 +				/* Can't read until underlying has more data. */
   1.606 +				if (bev_ssl->read_blocked_on_write)
   1.607 +					if (clear_rbow(bev_ssl) < 0)
   1.608 +						return OP_ERR | result;
   1.609 +				break;
   1.610 +			case SSL_ERROR_WANT_WRITE:
   1.611 +				/* This read operation requires a write, and the
   1.612 +				 * underlying is full */
   1.613 +				if (!bev_ssl->read_blocked_on_write)
   1.614 +					if (set_rbow(bev_ssl) < 0)
   1.615 +						return OP_ERR | result;
   1.616 +				break;
   1.617 +			default:
   1.618 +				conn_closed(bev_ssl, err, r);
   1.619 +				break;
   1.620 +			}
   1.621 +			result |= OP_BLOCKED;
   1.622 +			break; /* out of the loop */
   1.623 +		}
   1.624 +	}
   1.625 +
   1.626 +	if (n_used) {
   1.627 +		evbuffer_commit_space(input, space, n_used);
   1.628 +		if (bev_ssl->underlying)
   1.629 +			BEV_RESET_GENERIC_READ_TIMEOUT(bev);
   1.630 +	}
   1.631 +
   1.632 +	return result;
   1.633 +}
   1.634 +
   1.635 +/* Return a bitmask of OP_MADE_PROGRESS (if we wrote anything); OP_BLOCKED (if
   1.636 +   we're now blocked); and OP_ERR (if an error occurred). */
   1.637 +static int
   1.638 +do_write(struct bufferevent_openssl *bev_ssl, int atmost)
   1.639 +{
   1.640 +	int i, r, n, n_written = 0;
   1.641 +	struct bufferevent *bev = &bev_ssl->bev.bev;
   1.642 +	struct evbuffer *output = bev->output;
   1.643 +	struct evbuffer_iovec space[8];
   1.644 +	int result = 0;
   1.645 +
   1.646 +	if (bev_ssl->last_write > 0)
   1.647 +		atmost = bev_ssl->last_write;
   1.648 +	else
   1.649 +		atmost = _bufferevent_get_write_max(&bev_ssl->bev);
   1.650 +
   1.651 +	n = evbuffer_peek(output, atmost, NULL, space, 8);
   1.652 +	if (n < 0)
   1.653 +		return OP_ERR | result;
   1.654 +
   1.655 +	if (n > 8)
   1.656 +		n = 8;
   1.657 +	for (i=0; i < n; ++i) {
   1.658 +		if (bev_ssl->bev.write_suspended)
   1.659 +			break;
   1.660 +
   1.661 +		/* SSL_write will (reasonably) return 0 if we tell it to
   1.662 +		   send 0 data.  Skip this case so we don't interpret the
   1.663 +		   result as an error */
   1.664 +		if (space[i].iov_len == 0)
   1.665 +			continue;
   1.666 +
   1.667 +		r = SSL_write(bev_ssl->ssl, space[i].iov_base,
   1.668 +		    space[i].iov_len);
   1.669 +		if (r > 0) {
   1.670 +			result |= OP_MADE_PROGRESS;
   1.671 +			if (bev_ssl->write_blocked_on_read)
   1.672 +				if (clear_wbor(bev_ssl) < 0)
   1.673 +					return OP_ERR | result;
   1.674 +			n_written += r;
   1.675 +			bev_ssl->last_write = -1;
   1.676 +			decrement_buckets(bev_ssl);
   1.677 +		} else {
   1.678 +			int err = SSL_get_error(bev_ssl->ssl, r);
   1.679 +			print_err(err);
   1.680 +			switch (err) {
   1.681 +			case SSL_ERROR_WANT_WRITE:
   1.682 +				/* Can't read until underlying has more data. */
   1.683 +				if (bev_ssl->write_blocked_on_read)
   1.684 +					if (clear_wbor(bev_ssl) < 0)
   1.685 +						return OP_ERR | result;
   1.686 +				bev_ssl->last_write = space[i].iov_len;
   1.687 +				break;
   1.688 +			case SSL_ERROR_WANT_READ:
   1.689 +				/* This read operation requires a write, and the
   1.690 +				 * underlying is full */
   1.691 +				if (!bev_ssl->write_blocked_on_read)
   1.692 +					if (set_wbor(bev_ssl) < 0)
   1.693 +						return OP_ERR | result;
   1.694 +				bev_ssl->last_write = space[i].iov_len;
   1.695 +				break;
   1.696 +			default:
   1.697 +				conn_closed(bev_ssl, err, r);
   1.698 +				bev_ssl->last_write = -1;
   1.699 +				break;
   1.700 +			}
   1.701 +			result |= OP_BLOCKED;
   1.702 +			break;
   1.703 +		}
   1.704 +	}
   1.705 +	if (n_written) {
   1.706 +		evbuffer_drain(output, n_written);
   1.707 +		if (bev_ssl->underlying)
   1.708 +			BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
   1.709 +
   1.710 +		if (evbuffer_get_length(output) <= bev->wm_write.low)
   1.711 +			_bufferevent_run_writecb(bev);
   1.712 +	}
   1.713 +	return result;
   1.714 +}
   1.715 +
   1.716 +#define WRITE_FRAME 15000
   1.717 +
   1.718 +#define READ_DEFAULT 4096
   1.719 +
   1.720 +/* Try to figure out how many bytes to read; return 0 if we shouldn't be
   1.721 + * reading. */
   1.722 +static int
   1.723 +bytes_to_read(struct bufferevent_openssl *bev)
   1.724 +{
   1.725 +	struct evbuffer *input = bev->bev.bev.input;
   1.726 +	struct event_watermark *wm = &bev->bev.bev.wm_read;
   1.727 +	int result = READ_DEFAULT;
   1.728 +	ev_ssize_t limit;
   1.729 +	/* XXX 99% of this is generic code that nearly all bufferevents will
   1.730 +	 * want. */
   1.731 +
   1.732 +	if (bev->write_blocked_on_read) {
   1.733 +		return 0;
   1.734 +	}
   1.735 +
   1.736 +	if (! (bev->bev.bev.enabled & EV_READ)) {
   1.737 +		return 0;
   1.738 +	}
   1.739 +
   1.740 +	if (bev->bev.read_suspended) {
   1.741 +		return 0;
   1.742 +	}
   1.743 +
   1.744 +	if (wm->high) {
   1.745 +		if (evbuffer_get_length(input) >= wm->high) {
   1.746 +			return 0;
   1.747 +		}
   1.748 +
   1.749 +		result = wm->high - evbuffer_get_length(input);
   1.750 +	} else {
   1.751 +		result = READ_DEFAULT;
   1.752 +	}
   1.753 +
   1.754 +	/* Respect the rate limit */
   1.755 +	limit = _bufferevent_get_read_max(&bev->bev);
   1.756 +	if (result > limit) {
   1.757 +		result = limit;
   1.758 +	}
   1.759 +
   1.760 +	return result;
   1.761 +}
   1.762 +
   1.763 +
   1.764 +/* Things look readable.  If write is blocked on read, write till it isn't.
   1.765 + * Read from the underlying buffer until we block or we hit our high-water
   1.766 + * mark.
   1.767 + */
   1.768 +static void
   1.769 +consider_reading(struct bufferevent_openssl *bev_ssl)
   1.770 +{
   1.771 +	int r;
   1.772 +	int n_to_read;
   1.773 +	int all_result_flags = 0;
   1.774 +
   1.775 +	while (bev_ssl->write_blocked_on_read) {
   1.776 +		r = do_write(bev_ssl, WRITE_FRAME);
   1.777 +		if (r & (OP_BLOCKED|OP_ERR))
   1.778 +			break;
   1.779 +	}
   1.780 +	if (bev_ssl->write_blocked_on_read)
   1.781 +		return;
   1.782 +
   1.783 +	n_to_read = bytes_to_read(bev_ssl);
   1.784 +
   1.785 +	while (n_to_read) {
   1.786 +		r = do_read(bev_ssl, n_to_read);
   1.787 +		all_result_flags |= r;
   1.788 +
   1.789 +		if (r & (OP_BLOCKED|OP_ERR))
   1.790 +			break;
   1.791 +
   1.792 +		if (bev_ssl->bev.read_suspended)
   1.793 +			break;
   1.794 +        
   1.795 +		/* Read all pending data.  This won't hit the network
   1.796 +		 * again, and will (most importantly) put us in a state
   1.797 +		 * where we don't need to read anything else until the
   1.798 +		 * socket is readable again.  It'll potentially make us
   1.799 +		 * overrun our read high-watermark (somewhat
   1.800 +		 * regrettable).  The damage to the rate-limit has
   1.801 +		 * already been done, since OpenSSL went and read a
   1.802 +		 * whole SSL record anyway. */
   1.803 +		n_to_read = SSL_pending(bev_ssl->ssl);
   1.804 +
   1.805 +		/* XXX This if statement is actually a bad bug, added to avoid
   1.806 +		 * XXX a worse bug.
   1.807 +		 *
   1.808 +		 * The bad bug: It can potentially cause resource unfairness
   1.809 +		 * by reading too much data from the underlying bufferevent;
   1.810 +		 * it can potentially cause read looping if the underlying
   1.811 +		 * bufferevent is a bufferevent_pair and deferred callbacks
   1.812 +		 * aren't used.
   1.813 +		 *
   1.814 +		 * The worse bug: If we didn't do this, then we would
   1.815 +		 * potentially not read any more from bev_ssl->underlying
   1.816 +		 * until more data arrived there, which could lead to us
   1.817 +		 * waiting forever.
   1.818 +		 */
   1.819 +		if (!n_to_read && bev_ssl->underlying)
   1.820 +			n_to_read = bytes_to_read(bev_ssl);
   1.821 +	}
   1.822 +
   1.823 +	if (all_result_flags & OP_MADE_PROGRESS) {
   1.824 +		struct bufferevent *bev = &bev_ssl->bev.bev;
   1.825 +		struct evbuffer *input = bev->input;
   1.826 +
   1.827 +		if (evbuffer_get_length(input) >= bev->wm_read.low) {
   1.828 +			_bufferevent_run_readcb(bev);
   1.829 +		}
   1.830 +	}
   1.831 +
   1.832 +	if (!bev_ssl->underlying) {
   1.833 +		/* Should be redundant, but let's avoid busy-looping */
   1.834 +		if (bev_ssl->bev.read_suspended ||
   1.835 +		    !(bev_ssl->bev.bev.enabled & EV_READ)) {
   1.836 +			event_del(&bev_ssl->bev.bev.ev_read);
   1.837 +		}
   1.838 +	}
   1.839 +}
   1.840 +
   1.841 +static void
   1.842 +consider_writing(struct bufferevent_openssl *bev_ssl)
   1.843 +{
   1.844 +	int r;
   1.845 +	struct evbuffer *output = bev_ssl->bev.bev.output;
   1.846 +	struct evbuffer *target = NULL;
   1.847 +	struct event_watermark *wm = NULL;
   1.848 +
   1.849 +	while (bev_ssl->read_blocked_on_write) {
   1.850 +		r = do_read(bev_ssl, 1024); /* XXXX 1024 is a hack */
   1.851 +		if (r & OP_MADE_PROGRESS) {
   1.852 +			struct bufferevent *bev = &bev_ssl->bev.bev;
   1.853 +			struct evbuffer *input = bev->input;
   1.854 +
   1.855 +			if (evbuffer_get_length(input) >= bev->wm_read.low) {
   1.856 +				_bufferevent_run_readcb(bev);
   1.857 +			}
   1.858 +		}
   1.859 +		if (r & (OP_ERR|OP_BLOCKED))
   1.860 +			break;
   1.861 +	}
   1.862 +	if (bev_ssl->read_blocked_on_write)
   1.863 +		return;
   1.864 +	if (bev_ssl->underlying) {
   1.865 +		target = bev_ssl->underlying->output;
   1.866 +		wm = &bev_ssl->underlying->wm_write;
   1.867 +	}
   1.868 +	while ((bev_ssl->bev.bev.enabled & EV_WRITE) &&
   1.869 +	    (! bev_ssl->bev.write_suspended) &&
   1.870 +	    evbuffer_get_length(output) &&
   1.871 +	    (!target || (! wm->high || evbuffer_get_length(target) < wm->high))) {
   1.872 +		int n_to_write;
   1.873 +		if (wm && wm->high)
   1.874 +			n_to_write = wm->high - evbuffer_get_length(target);
   1.875 +		else
   1.876 +			n_to_write = WRITE_FRAME;
   1.877 +		r = do_write(bev_ssl, n_to_write);
   1.878 +		if (r & (OP_BLOCKED|OP_ERR))
   1.879 +			break;
   1.880 +	}
   1.881 +
   1.882 +	if (!bev_ssl->underlying) {
   1.883 +		if (evbuffer_get_length(output) == 0) {
   1.884 +			event_del(&bev_ssl->bev.bev.ev_write);
   1.885 +		} else if (bev_ssl->bev.write_suspended ||
   1.886 +		    !(bev_ssl->bev.bev.enabled & EV_WRITE)) {
   1.887 +			/* Should be redundant, but let's avoid busy-looping */
   1.888 +			event_del(&bev_ssl->bev.bev.ev_write);
   1.889 +		}
   1.890 +	}
   1.891 +}
   1.892 +
   1.893 +static void
   1.894 +be_openssl_readcb(struct bufferevent *bev_base, void *ctx)
   1.895 +{
   1.896 +	struct bufferevent_openssl *bev_ssl = ctx;
   1.897 +	consider_reading(bev_ssl);
   1.898 +}
   1.899 +
   1.900 +static void
   1.901 +be_openssl_writecb(struct bufferevent *bev_base, void *ctx)
   1.902 +{
   1.903 +	struct bufferevent_openssl *bev_ssl = ctx;
   1.904 +	consider_writing(bev_ssl);
   1.905 +}
   1.906 +
   1.907 +static void
   1.908 +be_openssl_eventcb(struct bufferevent *bev_base, short what, void *ctx)
   1.909 +{
   1.910 +	struct bufferevent_openssl *bev_ssl = ctx;
   1.911 +	int event = 0;
   1.912 +
   1.913 +	if (what & BEV_EVENT_EOF) {
   1.914 +		if (bev_ssl->allow_dirty_shutdown)
   1.915 +			event = BEV_EVENT_EOF;
   1.916 +		else
   1.917 +			event = BEV_EVENT_ERROR;
   1.918 +	} else if (what & BEV_EVENT_TIMEOUT) {
   1.919 +		/* We sure didn't set this.  Propagate it to the user. */
   1.920 +		event = what;
   1.921 +	} else if (what & BEV_EVENT_ERROR) {
   1.922 +		/* An error occurred on the connection.  Propagate it to the user. */
   1.923 +		event = what;
   1.924 +	} else if (what & BEV_EVENT_CONNECTED) {
   1.925 +		/* Ignore it.  We're saying SSL_connect() already, which will
   1.926 +		   eat it. */
   1.927 +	}
   1.928 +	if (event)
   1.929 +		_bufferevent_run_eventcb(&bev_ssl->bev.bev, event);
   1.930 +}
   1.931 +
   1.932 +static void
   1.933 +be_openssl_readeventcb(evutil_socket_t fd, short what, void *ptr)
   1.934 +{
   1.935 +	struct bufferevent_openssl *bev_ssl = ptr;
   1.936 +	_bufferevent_incref_and_lock(&bev_ssl->bev.bev);
   1.937 +	if (what == EV_TIMEOUT) {
   1.938 +		_bufferevent_run_eventcb(&bev_ssl->bev.bev,
   1.939 +		    BEV_EVENT_TIMEOUT|BEV_EVENT_READING);
   1.940 +	} else {
   1.941 +		consider_reading(bev_ssl);
   1.942 +	}
   1.943 +	_bufferevent_decref_and_unlock(&bev_ssl->bev.bev);
   1.944 +}
   1.945 +
   1.946 +static void
   1.947 +be_openssl_writeeventcb(evutil_socket_t fd, short what, void *ptr)
   1.948 +{
   1.949 +	struct bufferevent_openssl *bev_ssl = ptr;
   1.950 +	_bufferevent_incref_and_lock(&bev_ssl->bev.bev);
   1.951 +	if (what == EV_TIMEOUT) {
   1.952 +		_bufferevent_run_eventcb(&bev_ssl->bev.bev,
   1.953 +		    BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING);
   1.954 +	} else {
   1.955 +		consider_writing(bev_ssl);
   1.956 +	}
   1.957 +	_bufferevent_decref_and_unlock(&bev_ssl->bev.bev);
   1.958 +}
   1.959 +
   1.960 +static int
   1.961 +set_open_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
   1.962 +{
   1.963 +	if (bev_ssl->underlying) {
   1.964 +		bufferevent_setcb(bev_ssl->underlying,
   1.965 +		    be_openssl_readcb, be_openssl_writecb, be_openssl_eventcb,
   1.966 +		    bev_ssl);
   1.967 +		return 0;
   1.968 +	} else {
   1.969 +		struct bufferevent *bev = &bev_ssl->bev.bev;
   1.970 +		int rpending=0, wpending=0, r1=0, r2=0;
   1.971 +		if (fd < 0 && bev_ssl->fd_is_set)
   1.972 +			fd = event_get_fd(&bev->ev_read);
   1.973 +		if (bev_ssl->fd_is_set) {
   1.974 +			rpending = event_pending(&bev->ev_read, EV_READ, NULL);
   1.975 +			wpending = event_pending(&bev->ev_write, EV_WRITE, NULL);
   1.976 +			event_del(&bev->ev_read);
   1.977 +			event_del(&bev->ev_write);
   1.978 +		}
   1.979 +		event_assign(&bev->ev_read, bev->ev_base, fd,
   1.980 +		    EV_READ|EV_PERSIST, be_openssl_readeventcb, bev_ssl);
   1.981 +		event_assign(&bev->ev_write, bev->ev_base, fd,
   1.982 +		    EV_WRITE|EV_PERSIST, be_openssl_writeeventcb, bev_ssl);
   1.983 +		if (rpending)
   1.984 +			r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
   1.985 +		if (wpending)
   1.986 +			r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
   1.987 +		if (fd >= 0) {
   1.988 +			bev_ssl->fd_is_set = 1;
   1.989 +		}
   1.990 +		return (r1<0 || r2<0) ? -1 : 0;
   1.991 +	}
   1.992 +}
   1.993 +
   1.994 +static int
   1.995 +do_handshake(struct bufferevent_openssl *bev_ssl)
   1.996 +{
   1.997 +	int r;
   1.998 +
   1.999 +	switch (bev_ssl->state) {
  1.1000 +	default:
  1.1001 +	case BUFFEREVENT_SSL_OPEN:
  1.1002 +		EVUTIL_ASSERT(0);
  1.1003 +		return -1;
  1.1004 +	case BUFFEREVENT_SSL_CONNECTING:
  1.1005 +	case BUFFEREVENT_SSL_ACCEPTING:
  1.1006 +		r = SSL_do_handshake(bev_ssl->ssl);
  1.1007 +		break;
  1.1008 +	}
  1.1009 +	decrement_buckets(bev_ssl);
  1.1010 +
  1.1011 +	if (r==1) {
  1.1012 +		/* We're done! */
  1.1013 +		bev_ssl->state = BUFFEREVENT_SSL_OPEN;
  1.1014 +		set_open_callbacks(bev_ssl, -1); /* XXXX handle failure */
  1.1015 +		/* Call do_read and do_write as needed */
  1.1016 +		bufferevent_enable(&bev_ssl->bev.bev, bev_ssl->bev.bev.enabled);
  1.1017 +		_bufferevent_run_eventcb(&bev_ssl->bev.bev,
  1.1018 +		    BEV_EVENT_CONNECTED);
  1.1019 +		return 1;
  1.1020 +	} else {
  1.1021 +		int err = SSL_get_error(bev_ssl->ssl, r);
  1.1022 +		print_err(err);
  1.1023 +		switch (err) {
  1.1024 +		case SSL_ERROR_WANT_WRITE:
  1.1025 +			if (!bev_ssl->underlying) {
  1.1026 +				stop_reading(bev_ssl);
  1.1027 +				return start_writing(bev_ssl);
  1.1028 +			}
  1.1029 +			return 0;
  1.1030 +		case SSL_ERROR_WANT_READ:
  1.1031 +			if (!bev_ssl->underlying) {
  1.1032 +				stop_writing(bev_ssl);
  1.1033 +				return start_reading(bev_ssl);
  1.1034 +			}
  1.1035 +			return 0;
  1.1036 +		default:
  1.1037 +			conn_closed(bev_ssl, err, r);
  1.1038 +			return -1;
  1.1039 +		}
  1.1040 +	}
  1.1041 +}
  1.1042 +
  1.1043 +static void
  1.1044 +be_openssl_handshakecb(struct bufferevent *bev_base, void *ctx)
  1.1045 +{
  1.1046 +	struct bufferevent_openssl *bev_ssl = ctx;
  1.1047 +	do_handshake(bev_ssl);/* XXX handle failure */
  1.1048 +}
  1.1049 +
  1.1050 +static void
  1.1051 +be_openssl_handshakeeventcb(evutil_socket_t fd, short what, void *ptr)
  1.1052 +{
  1.1053 +	struct bufferevent_openssl *bev_ssl = ptr;
  1.1054 +
  1.1055 +	_bufferevent_incref_and_lock(&bev_ssl->bev.bev);
  1.1056 +	if (what & EV_TIMEOUT) {
  1.1057 +		_bufferevent_run_eventcb(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT);
  1.1058 +	} else
  1.1059 +		do_handshake(bev_ssl);/* XXX handle failure */
  1.1060 +	_bufferevent_decref_and_unlock(&bev_ssl->bev.bev);
  1.1061 +}
  1.1062 +
  1.1063 +static int
  1.1064 +set_handshake_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
  1.1065 +{
  1.1066 +	if (bev_ssl->underlying) {
  1.1067 +		bufferevent_setcb(bev_ssl->underlying,
  1.1068 +		    be_openssl_handshakecb, be_openssl_handshakecb,
  1.1069 +		    be_openssl_eventcb,
  1.1070 +		    bev_ssl);
  1.1071 +		return do_handshake(bev_ssl);
  1.1072 +	} else {
  1.1073 +		struct bufferevent *bev = &bev_ssl->bev.bev;
  1.1074 +		int r1=0, r2=0;
  1.1075 +		if (fd < 0 && bev_ssl->fd_is_set)
  1.1076 +			fd = event_get_fd(&bev->ev_read);
  1.1077 +		if (bev_ssl->fd_is_set) {
  1.1078 +			event_del(&bev->ev_read);
  1.1079 +			event_del(&bev->ev_write);
  1.1080 +		}
  1.1081 +		event_assign(&bev->ev_read, bev->ev_base, fd,
  1.1082 +		    EV_READ|EV_PERSIST, be_openssl_handshakeeventcb, bev_ssl);
  1.1083 +		event_assign(&bev->ev_write, bev->ev_base, fd,
  1.1084 +		    EV_WRITE|EV_PERSIST, be_openssl_handshakeeventcb, bev_ssl);
  1.1085 +		if (fd >= 0) {
  1.1086 +			r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
  1.1087 +			r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
  1.1088 +			bev_ssl->fd_is_set = 1;
  1.1089 +		}
  1.1090 +		return (r1<0 || r2<0) ? -1 : 0;
  1.1091 +	}
  1.1092 +}
  1.1093 +
  1.1094 +int
  1.1095 +bufferevent_ssl_renegotiate(struct bufferevent *bev)
  1.1096 +{
  1.1097 +	struct bufferevent_openssl *bev_ssl = upcast(bev);
  1.1098 +	if (!bev_ssl)
  1.1099 +		return -1;
  1.1100 +	if (SSL_renegotiate(bev_ssl->ssl) < 0)
  1.1101 +		return -1;
  1.1102 +	bev_ssl->state = BUFFEREVENT_SSL_CONNECTING;
  1.1103 +	if (set_handshake_callbacks(bev_ssl, -1) < 0)
  1.1104 +		return -1;
  1.1105 +	if (!bev_ssl->underlying)
  1.1106 +		return do_handshake(bev_ssl);
  1.1107 +	return 0;
  1.1108 +}
  1.1109 +
  1.1110 +static void
  1.1111 +be_openssl_outbuf_cb(struct evbuffer *buf,
  1.1112 +    const struct evbuffer_cb_info *cbinfo, void *arg)
  1.1113 +{
  1.1114 +	struct bufferevent_openssl *bev_ssl = arg;
  1.1115 +	int r = 0;
  1.1116 +	/* XXX need to hold a reference here. */
  1.1117 +
  1.1118 +	if (cbinfo->n_added && bev_ssl->state == BUFFEREVENT_SSL_OPEN) {
  1.1119 +		if (cbinfo->orig_size == 0)
  1.1120 +			r = _bufferevent_add_event(&bev_ssl->bev.bev.ev_write,
  1.1121 +			    &bev_ssl->bev.bev.timeout_write);
  1.1122 +		consider_writing(bev_ssl);
  1.1123 +	}
  1.1124 +	/* XXX Handle r < 0 */
  1.1125 +        (void)r;
  1.1126 +}
  1.1127 +
  1.1128 +
  1.1129 +static int
  1.1130 +be_openssl_enable(struct bufferevent *bev, short events)
  1.1131 +{
  1.1132 +	struct bufferevent_openssl *bev_ssl = upcast(bev);
  1.1133 +	int r1 = 0, r2 = 0;
  1.1134 +
  1.1135 +	if (bev_ssl->state != BUFFEREVENT_SSL_OPEN)
  1.1136 +		return 0;
  1.1137 +
  1.1138 +	if (events & EV_READ)
  1.1139 +		r1 = start_reading(bev_ssl);
  1.1140 +	if (events & EV_WRITE)
  1.1141 +		r2 = start_writing(bev_ssl);
  1.1142 +
  1.1143 +	if (bev_ssl->underlying) {
  1.1144 +		if (events & EV_READ)
  1.1145 +			BEV_RESET_GENERIC_READ_TIMEOUT(bev);
  1.1146 +		if (events & EV_WRITE)
  1.1147 +			BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
  1.1148 +
  1.1149 +		if (events & EV_READ)
  1.1150 +			consider_reading(bev_ssl);
  1.1151 +		if (events & EV_WRITE)
  1.1152 +			consider_writing(bev_ssl);
  1.1153 +	}
  1.1154 +	return (r1 < 0 || r2 < 0) ? -1 : 0;
  1.1155 +}
  1.1156 +
  1.1157 +static int
  1.1158 +be_openssl_disable(struct bufferevent *bev, short events)
  1.1159 +{
  1.1160 +	struct bufferevent_openssl *bev_ssl = upcast(bev);
  1.1161 +	if (bev_ssl->state != BUFFEREVENT_SSL_OPEN)
  1.1162 +		return 0;
  1.1163 +
  1.1164 +	if (events & EV_READ)
  1.1165 +		stop_reading(bev_ssl);
  1.1166 +	if (events & EV_WRITE)
  1.1167 +		stop_writing(bev_ssl);
  1.1168 +
  1.1169 +	if (bev_ssl->underlying) {
  1.1170 +		if (events & EV_READ)
  1.1171 +			BEV_DEL_GENERIC_READ_TIMEOUT(bev);
  1.1172 +		if (events & EV_WRITE)
  1.1173 +			BEV_DEL_GENERIC_WRITE_TIMEOUT(bev);
  1.1174 +	}
  1.1175 +	return 0;
  1.1176 +}
  1.1177 +
  1.1178 +static void
  1.1179 +be_openssl_destruct(struct bufferevent *bev)
  1.1180 +{
  1.1181 +	struct bufferevent_openssl *bev_ssl = upcast(bev);
  1.1182 +
  1.1183 +	if (bev_ssl->underlying) {
  1.1184 +		_bufferevent_del_generic_timeout_cbs(bev);
  1.1185 +	} else {
  1.1186 +		event_del(&bev->ev_read);
  1.1187 +		event_del(&bev->ev_write);
  1.1188 +	}
  1.1189 +
  1.1190 +	if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
  1.1191 +		if (bev_ssl->underlying) {
  1.1192 +			if (BEV_UPCAST(bev_ssl->underlying)->refcnt < 2) {
  1.1193 +				event_warnx("BEV_OPT_CLOSE_ON_FREE set on an "
  1.1194 +				    "bufferevent with too few references");
  1.1195 +			} else {
  1.1196 +				bufferevent_free(bev_ssl->underlying);
  1.1197 +				bev_ssl->underlying = NULL;
  1.1198 +			}
  1.1199 +		} else {
  1.1200 +			evutil_socket_t fd = -1;
  1.1201 +			BIO *bio = SSL_get_wbio(bev_ssl->ssl);
  1.1202 +			if (bio)
  1.1203 +				fd = BIO_get_fd(bio, NULL);
  1.1204 +			if (fd >= 0)
  1.1205 +				evutil_closesocket(fd);
  1.1206 +		}
  1.1207 +		SSL_free(bev_ssl->ssl);
  1.1208 +	} else {
  1.1209 +		if (bev_ssl->underlying) {
  1.1210 +			if (bev_ssl->underlying->errorcb == be_openssl_eventcb)
  1.1211 +				bufferevent_setcb(bev_ssl->underlying,
  1.1212 +				    NULL,NULL,NULL,NULL);
  1.1213 +			bufferevent_unsuspend_read(bev_ssl->underlying,
  1.1214 +			    BEV_SUSPEND_FILT_READ);
  1.1215 +		}
  1.1216 +	}
  1.1217 +}
  1.1218 +
  1.1219 +static int
  1.1220 +be_openssl_adj_timeouts(struct bufferevent *bev)
  1.1221 +{
  1.1222 +	struct bufferevent_openssl *bev_ssl = upcast(bev);
  1.1223 +
  1.1224 +	if (bev_ssl->underlying)
  1.1225 +		return _bufferevent_generic_adj_timeouts(bev);
  1.1226 +	else {
  1.1227 +		int r1=0, r2=0;
  1.1228 +		if (event_pending(&bev->ev_read, EV_READ, NULL))
  1.1229 +			r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
  1.1230 +		if (event_pending(&bev->ev_write, EV_WRITE, NULL))
  1.1231 +			r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
  1.1232 +		return (r1<0 || r2<0) ? -1 : 0;
  1.1233 +	}
  1.1234 +}
  1.1235 +
  1.1236 +static int
  1.1237 +be_openssl_flush(struct bufferevent *bufev,
  1.1238 +    short iotype, enum bufferevent_flush_mode mode)
  1.1239 +{
  1.1240 +	/* XXXX Implement this. */
  1.1241 +	return 0;
  1.1242 +}
  1.1243 +
  1.1244 +static int
  1.1245 +be_openssl_ctrl(struct bufferevent *bev,
  1.1246 +    enum bufferevent_ctrl_op op, union bufferevent_ctrl_data *data)
  1.1247 +{
  1.1248 +	struct bufferevent_openssl *bev_ssl = upcast(bev);
  1.1249 +	switch (op) {
  1.1250 +	case BEV_CTRL_SET_FD:
  1.1251 +		if (bev_ssl->underlying)
  1.1252 +			return -1;
  1.1253 +		{
  1.1254 +			BIO *bio;
  1.1255 +			bio = BIO_new_socket(data->fd, 0);
  1.1256 +			SSL_set_bio(bev_ssl->ssl, bio, bio);
  1.1257 +			bev_ssl->fd_is_set = 1;
  1.1258 +		}
  1.1259 +		if (bev_ssl->state == BUFFEREVENT_SSL_OPEN)
  1.1260 +			return set_open_callbacks(bev_ssl, data->fd);
  1.1261 +		else {
  1.1262 +			return set_handshake_callbacks(bev_ssl, data->fd);
  1.1263 +		}
  1.1264 +	case BEV_CTRL_GET_FD:
  1.1265 +		if (bev_ssl->underlying)
  1.1266 +			return -1;
  1.1267 +		if (!bev_ssl->fd_is_set)
  1.1268 +			return -1;
  1.1269 +		data->fd = event_get_fd(&bev->ev_read);
  1.1270 +		return 0;
  1.1271 +	case BEV_CTRL_GET_UNDERLYING:
  1.1272 +		if (!bev_ssl->underlying)
  1.1273 +			return -1;
  1.1274 +		data->ptr = bev_ssl->underlying;
  1.1275 +		return 0;
  1.1276 +	case BEV_CTRL_CANCEL_ALL:
  1.1277 +	default:
  1.1278 +		return -1;
  1.1279 +	}
  1.1280 +}
  1.1281 +
  1.1282 +SSL *
  1.1283 +bufferevent_openssl_get_ssl(struct bufferevent *bufev)
  1.1284 +{
  1.1285 +	struct bufferevent_openssl *bev_ssl = upcast(bufev);
  1.1286 +	if (!bev_ssl)
  1.1287 +		return NULL;
  1.1288 +	return bev_ssl->ssl;
  1.1289 +}
  1.1290 +
  1.1291 +static struct bufferevent *
  1.1292 +bufferevent_openssl_new_impl(struct event_base *base,
  1.1293 +    struct bufferevent *underlying,
  1.1294 +    evutil_socket_t fd,
  1.1295 +    SSL *ssl,
  1.1296 +    enum bufferevent_ssl_state state,
  1.1297 +    int options)
  1.1298 +{
  1.1299 +	struct bufferevent_openssl *bev_ssl = NULL;
  1.1300 +	struct bufferevent_private *bev_p = NULL;
  1.1301 +	int tmp_options = options & ~BEV_OPT_THREADSAFE;
  1.1302 +
  1.1303 +	if (underlying != NULL && fd >= 0)
  1.1304 +		return NULL; /* Only one can be set. */
  1.1305 +
  1.1306 +	if (!(bev_ssl = mm_calloc(1, sizeof(struct bufferevent_openssl))))
  1.1307 +		goto err;
  1.1308 +
  1.1309 +	bev_p = &bev_ssl->bev;
  1.1310 +
  1.1311 +	if (bufferevent_init_common(bev_p, base,
  1.1312 +		&bufferevent_ops_openssl, tmp_options) < 0)
  1.1313 +		goto err;
  1.1314 +
  1.1315 +	/* Don't explode if we decide to realloc a chunk we're writing from in
  1.1316 +	 * the output buffer. */
  1.1317 +	SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  1.1318 +
  1.1319 +	bev_ssl->underlying = underlying;
  1.1320 +	bev_ssl->ssl = ssl;
  1.1321 +
  1.1322 +	bev_ssl->outbuf_cb = evbuffer_add_cb(bev_p->bev.output,
  1.1323 +	    be_openssl_outbuf_cb, bev_ssl);
  1.1324 +
  1.1325 +	if (options & BEV_OPT_THREADSAFE)
  1.1326 +		bufferevent_enable_locking(&bev_ssl->bev.bev, NULL);
  1.1327 +
  1.1328 +	if (underlying) {
  1.1329 +		_bufferevent_init_generic_timeout_cbs(&bev_ssl->bev.bev);
  1.1330 +		bufferevent_incref(underlying);
  1.1331 +	}
  1.1332 +
  1.1333 +	bev_ssl->state = state;
  1.1334 +	bev_ssl->last_write = -1;
  1.1335 +
  1.1336 +	init_bio_counts(bev_ssl);
  1.1337 +
  1.1338 +	switch (state) {
  1.1339 +	case BUFFEREVENT_SSL_ACCEPTING:
  1.1340 +		SSL_set_accept_state(bev_ssl->ssl);
  1.1341 +		if (set_handshake_callbacks(bev_ssl, fd) < 0)
  1.1342 +			goto err;
  1.1343 +		break;
  1.1344 +	case BUFFEREVENT_SSL_CONNECTING:
  1.1345 +		SSL_set_connect_state(bev_ssl->ssl);
  1.1346 +		if (set_handshake_callbacks(bev_ssl, fd) < 0)
  1.1347 +			goto err;
  1.1348 +		break;
  1.1349 +	case BUFFEREVENT_SSL_OPEN:
  1.1350 +		if (set_open_callbacks(bev_ssl, fd) < 0)
  1.1351 +			goto err;
  1.1352 +		break;
  1.1353 +	default:
  1.1354 +		goto err;
  1.1355 +	}
  1.1356 +
  1.1357 +	if (underlying) {
  1.1358 +		bufferevent_setwatermark(underlying, EV_READ, 0, 0);
  1.1359 +		bufferevent_enable(underlying, EV_READ|EV_WRITE);
  1.1360 +		if (state == BUFFEREVENT_SSL_OPEN)
  1.1361 +			bufferevent_suspend_read(underlying,
  1.1362 +			    BEV_SUSPEND_FILT_READ);
  1.1363 +	} else {
  1.1364 +		bev_ssl->bev.bev.enabled = EV_READ|EV_WRITE;
  1.1365 +		if (bev_ssl->fd_is_set) {
  1.1366 +			if (state != BUFFEREVENT_SSL_OPEN)
  1.1367 +				if (event_add(&bev_ssl->bev.bev.ev_read, NULL) < 0)
  1.1368 +					goto err;
  1.1369 +			if (event_add(&bev_ssl->bev.bev.ev_write, NULL) < 0)
  1.1370 +				goto err;
  1.1371 +		}
  1.1372 +	}
  1.1373 +
  1.1374 +	return &bev_ssl->bev.bev;
  1.1375 +err:
  1.1376 +	if (bev_ssl)
  1.1377 +		bufferevent_free(&bev_ssl->bev.bev);
  1.1378 +	return NULL;
  1.1379 +}
  1.1380 +
  1.1381 +struct bufferevent *
  1.1382 +bufferevent_openssl_filter_new(struct event_base *base,
  1.1383 +    struct bufferevent *underlying,
  1.1384 +    SSL *ssl,
  1.1385 +    enum bufferevent_ssl_state state,
  1.1386 +    int options)
  1.1387 +{
  1.1388 +	/* We don't tell the BIO to close the bufferevent; we do it ourselves
  1.1389 +	 * on be_openssl_destruct */
  1.1390 +	int close_flag = 0; /* options & BEV_OPT_CLOSE_ON_FREE; */
  1.1391 +	BIO *bio;
  1.1392 +	if (!underlying)
  1.1393 +		return NULL;
  1.1394 +	if (!(bio = BIO_new_bufferevent(underlying, close_flag)))
  1.1395 +		return NULL;
  1.1396 +
  1.1397 +	SSL_set_bio(ssl, bio, bio);
  1.1398 +
  1.1399 +	return bufferevent_openssl_new_impl(
  1.1400 +		base, underlying, -1, ssl, state, options);
  1.1401 +}
  1.1402 +
  1.1403 +struct bufferevent *
  1.1404 +bufferevent_openssl_socket_new(struct event_base *base,
  1.1405 +    evutil_socket_t fd,
  1.1406 +    SSL *ssl,
  1.1407 +    enum bufferevent_ssl_state state,
  1.1408 +    int options)
  1.1409 +{
  1.1410 +	/* Does the SSL already have an fd? */
  1.1411 +	BIO *bio = SSL_get_wbio(ssl);
  1.1412 +	long have_fd = -1;
  1.1413 +
  1.1414 +	if (bio)
  1.1415 +		have_fd = BIO_get_fd(bio, NULL);
  1.1416 +
  1.1417 +	if (have_fd >= 0) {
  1.1418 +		/* The SSL is already configured with an fd. */
  1.1419 +		if (fd < 0) {
  1.1420 +			/* We should learn the fd from the SSL. */
  1.1421 +			fd = (evutil_socket_t) have_fd;
  1.1422 +		} else if (have_fd == (long)fd) {
  1.1423 +			/* We already know the fd from the SSL; do nothing */
  1.1424 +		} else {
  1.1425 +			/* We specified an fd different from that of the SSL.
  1.1426 +			   This is probably an error on our part.  Fail. */
  1.1427 +			return NULL;
  1.1428 +		}
  1.1429 +		(void) BIO_set_close(bio, 0);
  1.1430 +	} else {
  1.1431 +		/* The SSL isn't configured with a BIO with an fd. */
  1.1432 +		if (fd >= 0) {
  1.1433 +			/* ... and we have an fd we want to use. */
  1.1434 +			bio = BIO_new_socket(fd, 0);
  1.1435 +			SSL_set_bio(ssl, bio, bio);
  1.1436 +		} else {
  1.1437 +			/* Leave the fd unset. */
  1.1438 +		}
  1.1439 +	}
  1.1440 +
  1.1441 +	return bufferevent_openssl_new_impl(
  1.1442 +		base, NULL, fd, ssl, state, options);
  1.1443 +}
  1.1444 +
  1.1445 +unsigned long
  1.1446 +bufferevent_get_openssl_error(struct bufferevent *bev)
  1.1447 +{
  1.1448 +	unsigned long err = 0;
  1.1449 +	struct bufferevent_openssl *bev_ssl;
  1.1450 +	BEV_LOCK(bev);
  1.1451 +	bev_ssl = upcast(bev);
  1.1452 +	if (bev_ssl && bev_ssl->n_errors) {
  1.1453 +		err = bev_ssl->errors[--bev_ssl->n_errors];
  1.1454 +	}
  1.1455 +	BEV_UNLOCK(bev);
  1.1456 +	return err;
  1.1457 +}

mercurial