+}
+
+void iohandler_ssl_client_accepted(struct IODescriptor *iofd, struct IODescriptor *client_iofd) {
+ struct IOSSLNode *sslnode = malloc(sizeof(*sslnode));
+ sslnode->sslHandle = SSL_new(sslnode->sslContext);
+ if(!sslnode->sslHandle) {
+ iohandler_ssl_error();
+ iohandler_log(IOLOG_ERROR, "SSL: could not create client SSL Handle");
+ goto ssl_accept_err;
+ }
+ if(!SSL_set_fd(sslnode->sslHandle, client_iofd->fd)) {
+ iohandler_ssl_error();
+ iohandler_log(IOLOG_ERROR, "SSL: could not set client fd in SSL Handle");
+ goto ssl_accept_err;
+ }
+ client_iofd->state = IO_SSLWAIT;
+ client_iofd->ssl_server_hs = 1;
+ client_iofd->ssl = 1;
+ client_iofd->sslnode = sslnode;
+ client_iofd->callback = iofd->callback;
+ client_iofd->data = iofd;
+ return;
+ssl_accept_err:
+ iohandler_close(client_iofd);
+ free(sslnode);
+}
+
+void iohandler_ssl_server_handshake(struct IODescriptor *iofd) {
+ // Perform an SSL handshake.
+ int ret = SSL_accept(iofd->sslnode->sslHandle);
+ iofd->ssl_hs_read = 0;
+ iofd->ssl_hs_write = 0;
+ switch(SSL_get_error(iofd->sslnode->sslHandle, ret)) {
+ case SSL_ERROR_NONE:
+ iofd->state = IO_CONNECTING;
+ iofd->ssl_active = 1;
+ iohandler_log(IOLOG_DEBUG, "SSL handshake for %s (fd: %d) successful", iohandler_iotype_name(iofd->type), iofd->fd);
+ iohandler_events(iofd, 0, 1); //perform IOEVENT_CONNECTED event
+ break;
+ case SSL_ERROR_WANT_READ:
+ iofd->ssl_hs_read = 1;
+ iohandler_log(IOLOG_DEBUG, "SSL_do_handshake for %s (fd: %d) returned SSL_ERROR_WANT_READ", iohandler_iotype_name(iofd->type), iofd->fd);
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ iofd->ssl_hs_write = 1;
+ iohandler_log(IOLOG_DEBUG, "SSL_do_handshake for %s (fd: %d) returned SSL_ERROR_WANT_WRITE", iohandler_iotype_name(iofd->type), iofd->fd);
+ break;
+ default:
+ iohandler_log(IOLOG_ERROR, "SSL_do_handshake for %s (fd: %d) failed with ", iohandler_iotype_name(iofd->type), iofd->fd);
+ iohandler_events(iofd, 0, 0);
+ break;
+ }