static LUA_FUNCTION(openssl_bio_retry) { BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); int retry = BIO_should_retry(bio); if (retry) { lua_pushboolean(L, 1); lua_pushboolean(L, BIO_should_read(bio)); lua_pushboolean(L, BIO_should_write(bio)); lua_pushboolean(L, BIO_should_io_special(bio)); return 4; } else lua_pushboolean(L, 0); return 1; }
/* Return -1 on hard error (abort), 0 on timeout, >= 1 on successful wakeup */ static int _BIO_wait(BIO *cbio, int msecs) { int result; if (!BIO_should_retry(cbio)) { return (-1); } struct pollfd pfd; BIO_get_fd(cbio, &pfd.fd); pfd.events = 0; pfd.revents = 0; if (BIO_should_io_special(cbio)) { pfd.events = POLLOUT | POLLWRBAND; } else if (BIO_should_read(cbio)) { pfd.events = POLLIN | POLLPRI | POLLRDBAND; } else if (BIO_should_write(cbio)) { pfd.events = POLLOUT | POLLWRBAND; } else { return (-1); } if (msecs < 0) { /* POSIX requires -1 for "no timeout" although some libcs accept any negative value. */ msecs = -1; } do { result = poll(&pfd, 1, msecs); } while (result == -1 && errno == EINTR); /* Timeout or poll internal error */ if (result <= 0) { return (result); } if (pfd.revents & POLLERR) { return -1; } /* Return 1 if the event was not an error */ return (pfd.revents & pfd.events ? 1 : -1); }
/* * Handle errors raised by BIO functions. * * Arguments: bio - The BIO object * ret - The return value of the BIO_ function. * Returns: None, the calling function should return NULL; */ static void handle_bio_errors(BIO* bio, int ret) { if (BIO_should_retry(bio)) { if (BIO_should_read(bio)) { PyErr_SetNone(ssl_WantReadError); } else if (BIO_should_write(bio)) { PyErr_SetNone(ssl_WantWriteError); } else if (BIO_should_io_special(bio)) { /* * It's somewhat unclear what this means. From the OpenSSL source, * it seems like it should not be triggered by the memory BIO, so * for the time being, this case shouldn't come up. The SSL BIO * (which I think should be named the socket BIO) may trigger this * case if its socket is not yet connected or it is busy doing * something related to x509. */ PyErr_SetString(PyExc_ValueError, "BIO_should_io_special"); } else { /* * I hope this is dead code. The BIO documentation suggests that * one of the above three checks should always be true. */ PyErr_SetString(PyExc_ValueError, "unknown bio failure"); } } else { /* * If we aren't to retry, it's really an error, so fall back to the * normal error reporting code. However, the BIO interface does not * specify a uniform error reporting mechanism. We can only hope that * the code which triggered the error also kindly pushed something onto * the error stack. */ exception_from_error_queue(ssl_Error); } }