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