static void mowgli_epoll_eventloop_select(mowgli_eventloop_t *eventloop, int delay) { mowgli_epoll_eventloop_private_t *priv; int i, num, o_errno; return_if_fail(eventloop != NULL); priv = eventloop->poller; num = epoll_wait(priv->epoll_fd, priv->pfd, priv->pfd_size, delay); o_errno = errno; mowgli_eventloop_synchronize(eventloop); if (num < 0) { if (mowgli_eventloop_ignore_errno(errno)) return; mowgli_log("mowgli_epoll_eventloop_select(): epoll_wait failed: %d (%s)", o_errno, strerror(o_errno)); return; } for (i = 0; i < num; i++) { mowgli_eventloop_pollable_t *pollable = priv->pfd[i].data.ptr; if (priv->pfd[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR)) mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ); if (priv->pfd[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR)) mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE); } }
int mowgli_vio_openssl_default_connect(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr) { const int fd = mowgli_vio_getfd(vio); return_val_if_fail(fd != -1, -255); mowgli_ssl_connection_t *connection = vio->privdata; vio->error.op = MOWGLI_VIO_ERR_OP_CONNECT; if (connect(fd, (struct sockaddr *)&addr->addr, addr->addrlen) < 0) { if (!mowgli_eventloop_ignore_errno(errno)) return mowgli_vio_err_errcode(vio, strerror, errno); else { mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCONNECTING, true); mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISSSLCONNECTING, true); vio->error.op = MOWGLI_VIO_ERR_OP_NONE; return 0; } } memcpy(&vio->addr.addr, &addr->addr, addr->addrlen); vio->addr.addrlen = addr->addrlen; mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCLIENT, true); mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISSERVER, false); /* Non-blocking socket, begin handshake */ mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCONNECTING, false); return mowgli_vio_openssl_client_handshake(vio, connection); }
static void mowgli_epoll_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable) { mowgli_epoll_eventloop_private_t *priv; struct epoll_event ep_event; return_if_fail(eventloop != NULL); return_if_fail(pollable != NULL); priv = eventloop->poller; pollable->slot = 0; ep_event.events = pollable->slot; ep_event.data.ptr = pollable; if (epoll_ctl(priv->epoll_fd, EPOLL_CTL_DEL, pollable->fd, &ep_event) != 0) { if (mowgli_eventloop_ignore_errno(errno)) return; mowgli_log("mowgli_epoll_eventloop_destroy(): epoll_ctl failed: %d (%s)", errno, strerror(errno)); } }
static void mowgli_epoll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function) { mowgli_epoll_eventloop_private_t *priv; struct epoll_event ep_event; int op = -1; unsigned int old_flags; return_if_fail(eventloop != NULL); return_if_fail(pollable != NULL); priv = eventloop->poller; old_flags = pollable->slot; # ifdef DEBUG mowgli_log("setselect %p fd %d func %p", pollable, pollable->fd, event_function); # endif switch (dir) { case MOWGLI_EVENTLOOP_IO_READ: pollable->read_function = event_function; pollable->slot |= EPOLLIN; break; case MOWGLI_EVENTLOOP_IO_WRITE: pollable->write_function = event_function; pollable->slot |= EPOLLOUT; break; default: mowgli_log("unhandled pollable direction %d", dir); break; } # ifdef DEBUG mowgli_log("%p -> read %p : write %p", pollable, pollable->read_function, pollable->write_function); # endif if (pollable->read_function == NULL) pollable->slot &= ~EPOLLIN; if (pollable->write_function == NULL) pollable->slot &= ~EPOLLOUT; if ((old_flags == 0) && (pollable->slot == 0)) return; else if (pollable->slot <= 0) op = EPOLL_CTL_DEL; else if ((old_flags == 0) && (pollable->slot != 0)) op = EPOLL_CTL_ADD; else if (pollable->slot != old_flags) op = EPOLL_CTL_MOD; if (op == -1) return; ep_event.events = pollable->slot; ep_event.data.ptr = pollable; if (epoll_ctl(priv->epoll_fd, op, pollable->fd, &ep_event) != 0) { if (mowgli_eventloop_ignore_errno(errno)) return; mowgli_log("mowgli_epoll_eventloop_setselect(): epoll_ctl failed: %d (%s)", errno, strerror(errno)); } return; }
int mowgli_vio_openssl_default_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio) { const int fd = mowgli_vio_getfd(vio); int afd; int ret; return_val_if_fail(fd != -1, -255); mowgli_ssl_connection_t *connection = vio->privdata; mowgli_ssl_connection_t *newconnection; vio->error.op = MOWGLI_VIO_ERR_OP_ACCEPT; if (!newvio) { const char errstr[] = "accept not called with valid new VIO object"; vio->error.type = MOWGLI_VIO_ERR_API; mowgli_strlcpy(vio->error.string, errstr, sizeof(errstr)); return mowgli_vio_error(vio); } if ((afd = accept(fd, (struct sockaddr *) &newvio->addr.addr, &(newvio->addr.addrlen))) < 0) { if (!mowgli_eventloop_ignore_errno(errno)) return mowgli_vio_err_errcode(vio, strerror, errno); else return 0; } newvio->io.fd = afd; mowgli_vio_openssl_setssl(newvio, &connection->settings, vio->ops); newconnection = newvio->privdata; newconnection->ssl_context = connection->ssl_context; newconnection->ssl_handle = SSL_new(newconnection->ssl_context); if (!SSL_set_fd(newconnection->ssl_handle, afd)) return mowgli_vio_err_sslerrcode(newvio, ERR_get_error()); if ((ret = SSL_accept(newconnection->ssl_handle)) != 1) { unsigned long err; switch (SSL_get_error(newconnection->ssl_handle, ret)) { case SSL_ERROR_WANT_READ: mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDREAD, true); MOWGLI_VIO_SETREAD(vio) return 0; case SSL_ERROR_WANT_WRITE: mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, true); MOWGLI_VIO_SETWRITE(vio) return 0; case SSL_ERROR_ZERO_RETURN: return 0; case SSL_ERROR_SYSCALL: return mowgli_vio_err_errcode(newvio, strerror, errno); default: err = ERR_get_error(); break; } if (err > 0) { errno = EIO; return mowgli_vio_err_errcode(vio, strerror, errno); } return -1; }