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