+static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
+ OCSP_REQUEST *req, int req_timeout)
+ {
+ int fd;
+ int rv;
+ OCSP_REQ_CTX *ctx = NULL;
+ OCSP_RESPONSE *rsp = NULL;
+ fd_set confds;
+ struct timeval tv;
+
+ if (req_timeout != -1)
+ BIO_set_nbio(cbio, 1);
+
+ rv = BIO_do_connect(cbio);
+
+ if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio)))
+ {
+ BIO_puts(err, "Error connecting BIO\n");
+ return NULL;
+ }
+
+ if (req_timeout == -1)
+ return OCSP_sendreq_bio(cbio, path, req);
+
+ if (BIO_get_fd(cbio, &fd) <= 0)
+ {
+ BIO_puts(err, "Can't get connection fd\n");
+ goto err;
+ }
+
+ ctx = OCSP_sendreq_new(cbio, path, req, -1);
+
+ if (!ctx)
+ return NULL;
+
+ for (;;)
+ {
+ rv = OCSP_sendreq_nbio(&rsp, ctx);
+ if (rv != -1)
+ break;
+ FD_ZERO(&confds);
+ FD_SET(fd, &confds);
+ tv.tv_usec = 0;
+ tv.tv_sec = req_timeout;
+ if (BIO_should_read(cbio) || BIO_should_io_special(cbio))
+ rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
+ else if (BIO_should_write(cbio))
+ rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
+ else
+ {
+ BIO_puts(err, "Unexpected retry condition\n");
+ goto err;
+ }
+ if (rv == 0)
+ {
+ BIO_puts(err, "Timeout on request\n");
+ break;
+ }
+ if (rv == -1)
+ {
+ BIO_puts(err, "Select error\n");
+ break;
+ }
+
+ }
+
+ err:
+
+ OCSP_REQ_CTX_free(ctx);
+
+ return rsp;
+ }
+