diff options
Diffstat (limited to 'src/ssl_timeout.c')
-rw-r--r-- | src/ssl_timeout.c | 125 |
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; +} |