예제 #1
0
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;
}
예제 #2
0
파일: https.c 프로젝트: ViaSat/duo_unix
/* 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);
}
예제 #3
0
/*
 * 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);
    }
}