summaryrefslogtreecommitdiff
path: root/src/ssl_timeout.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssl_timeout.c')
-rw-r--r--src/ssl_timeout.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/ssl_timeout.c b/src/ssl_timeout.c
new file mode 100644
index 0000000..737f72f
--- /dev/null
+++ b/src/ssl_timeout.c
@@ -0,0 +1,125 @@
+#include "ucspissl.h"
+#include "iopause.h"
+#include "logmsg.h"
+
+#define WHO "ssl_timeout"
+
+int ssl_timeoutaccept(SSL *ssl,unsigned int timeout)
+{
+ struct taia now;
+ struct taia deadline;
+ iopause_fd x;
+ int r;
+ int rfd;
+ int wfd;
+
+ if (taia_now(&now) == -1) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ taia_uint(&deadline,timeout);
+ taia_add(&deadline,&now,&deadline);
+
+ rfd = SSL_get_fd(ssl); /* XXX */
+ wfd = SSL_get_fd(ssl); /* XXX */
+
+ SSL_set_accept_state(ssl);
+
+ for (;;) {
+ r = SSL_accept(ssl);
+ if (r == 1) return 0;
+ ssl_errno = SSL_get_error(ssl,r);
+ errno = EPROTO;
+ if ((ssl_errno != SSL_ERROR_WANT_READ) && (ssl_errno != SSL_ERROR_WANT_WRITE))
+ return -1;
+ if (ssl_errno == SSL_ERROR_WANT_READ) {
+ x.events = IOPAUSE_READ;
+ x.fd = rfd;
+ if (x.fd == -1) return -1;
+ }
+ else {
+ x.events = IOPAUSE_WRITE;
+ x.fd = wfd;
+ if (x.fd == -1) return -1;
+ }
+ for (;;) {
+ if (taia_now(&now) == -1) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ iopause(&x,1,&deadline,&now);
+ if (x.revents) break;
+ if (taia_less(&deadline,&now)) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ }
+ }
+}
+
+int ssl_timeoutconn(SSL *ssl,unsigned int timeout)
+{
+ struct taia now;
+ struct taia deadline;
+ iopause_fd x;
+ int r;
+ int rfd;
+ int wfd;
+
+ taia_now(&now);
+ taia_uint(&deadline,timeout);
+ taia_add(&deadline,&now,&deadline);
+
+ rfd = SSL_get_fd(ssl); /* XXX */
+ wfd = SSL_get_fd(ssl); /* XXX */
+
+ SSL_set_connect_state(ssl);
+
+ for (;;) {
+ r = SSL_connect(ssl);
+ errno = EPROTO;
+ if (r == 1) return 0;
+ ssl_errno = SSL_get_error(ssl,r);
+ if ((ssl_errno != SSL_ERROR_WANT_READ) && (ssl_errno != SSL_ERROR_WANT_WRITE))
+ return -1;
+ if (ssl_errno == SSL_ERROR_WANT_READ) {
+ x.events = IOPAUSE_READ;
+ x.fd = rfd;
+ if (x.fd == -1) return -1;
+ }
+ else {
+ x.events = IOPAUSE_WRITE;
+ x.fd = wfd;
+ if (x.fd == -1) return -1;
+ }
+ for (;;) {
+ if (taia_now(&now) == -1) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ iopause(&x,1,&deadline,&now);
+ if (x.revents) break;
+ if (taia_less(&deadline,&now)) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ }
+ }
+}
+
+stralloc sslerror = {0};
+
+int ssl_verberror(void)
+{
+ char buf[256];
+ unsigned long err;
+
+ if (!stralloc_copys(&sslerror,"")) return -1;
+
+ while ((err = ERR_get_error()) != 0) {
+ ERR_error_string_n(err,buf,sizeof(buf));
+ if (!stralloc_cats(&sslerror,buf)) return -1;
+ if (!stralloc_cats(&sslerror," ")) return -1;
+ }
+ return err;
+}