/* * Setup the necessary events as required by the current io state, * honouring duplex mode and i/o pauses. */ void io_reload(struct io *io) { short events; /* io will be reloaded at release time */ if (io->flags & IO_HELD) return; #ifdef IO_SSL if (io->ssl) { io_reload_ssl(io); return; } #endif io_debug("io_reload(%p)\n", io); events = 0; if (IO_READING(io) && !(io->flags & IO_PAUSE_IN)) events = EV_READ; if (IO_WRITING(io) && !(io->flags & IO_PAUSE_OUT) && io_queued(io)) events |= EV_WRITE; io_reset(io, events, io_dispatch); }
void io_reload_ssl(struct io *io) { short ev = 0; void (*dispatch)(int, short, void*) = NULL; switch (io->state) { case IO_STATE_CONNECT_SSL: ev = EV_WRITE; dispatch = io_dispatch_connect_ssl; break; case IO_STATE_ACCEPT_SSL: ev = EV_READ; dispatch = io_dispatch_accept_ssl; break; case IO_STATE_UP: ev = 0; if (IO_READING(io) && !(io->flags & IO_PAUSE_IN)) { ev = EV_READ; dispatch = io_dispatch_read_ssl; } else if (IO_WRITING(io) && !(io->flags & IO_PAUSE_OUT) && io_queued(io)) { ev = EV_WRITE; dispatch = io_dispatch_write_ssl; } if (!ev) return; /* paused */ break; default: errx(1, "io_reload_ssl(): bad state"); } io_reset(io, ev, dispatch); }
void io_dispatch_read_ssl(int fd, short event, void *humppa) { struct io *io = humppa; int n, saved_errno; io_frame_enter("io_dispatch_read_ssl", io, event); if (event == EV_TIMEOUT) { io_callback(io, IO_TIMEOUT); goto leave; } again: iobuf_normalize(&io->iobuf); switch ((n = iobuf_read_ssl(&io->iobuf, (SSL*)io->ssl))) { case IOBUF_WANT_READ: io_reset(io, EV_READ, io_dispatch_read_ssl); break; case IOBUF_WANT_WRITE: io_reset(io, EV_WRITE, io_dispatch_read_ssl); break; case IOBUF_CLOSED: io_callback(io, IO_DISCONNECTED); break; case IOBUF_ERROR: saved_errno = errno; io->error = strerror(errno); errno = saved_errno; io_callback(io, IO_ERROR); break; case IOBUF_SSLERROR: io->error = io_ssl_error(); ssl_error("io_dispatch_read_ssl:SSL_read"); io_callback(io, IO_ERROR); break; default: io_debug("io_dispatch_read_ssl(...) -> r=%d\n", n); io_callback(io, IO_DATAIN); if (current == io && IO_READING(io) && SSL_pending(io->ssl)) goto again; } leave: io_frame_leave(io); }