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