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