nghttpx: Clear OpenSSL error and handle limit change in read_tls
This commit is contained in:
parent
419c03daa2
commit
4a218f1b79
|
@ -178,6 +178,8 @@ int ClientHandler::write_clear() {
|
||||||
int ClientHandler::tls_handshake() {
|
int ClientHandler::tls_handshake() {
|
||||||
ev_timer_again(loop_, &rt_);
|
ev_timer_again(loop_, &rt_);
|
||||||
|
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
auto rv = SSL_do_handshake(ssl_);
|
auto rv = SSL_do_handshake(ssl_);
|
||||||
|
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
|
@ -225,6 +227,8 @@ int ClientHandler::tls_handshake() {
|
||||||
int ClientHandler::read_tls() {
|
int ClientHandler::read_tls() {
|
||||||
ev_timer_again(loop_, &rt_);
|
ev_timer_again(loop_, &rt_);
|
||||||
|
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// we should process buffered data first before we read EOF.
|
// we should process buffered data first before we read EOF.
|
||||||
if (rb_.rleft() && on_read() != 0) {
|
if (rb_.rleft() && on_read() != 0) {
|
||||||
|
@ -238,11 +242,19 @@ int ClientHandler::read_tls() {
|
||||||
auto iovcnt = rb_.wiovec(iov);
|
auto iovcnt = rb_.wiovec(iov);
|
||||||
// SSL_read requires the same arguments (buf pointer and its
|
// SSL_read requires the same arguments (buf pointer and its
|
||||||
// length) on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE.
|
// length) on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE.
|
||||||
// rlimit_.avail() does not change if we don't read anything, so
|
// rlimit_.avail() or rlimit_.avail() may return different length
|
||||||
// we don't do anything special here.
|
// than the length previously passed to SSL_read, which violates
|
||||||
iovcnt = limit_iovec(iov, iovcnt, rlimit_.avail());
|
// OpenSSL assumption. To avoid this, we keep last legnth passed
|
||||||
if (iovcnt == 0) {
|
// to SSL_read to tls_last_readlen_ if SSL_read indicated I/O
|
||||||
return 0;
|
// blocking.
|
||||||
|
if (tls_last_readlen_ == 0) {
|
||||||
|
iovcnt = limit_iovec(iov, iovcnt, rlimit_.avail());
|
||||||
|
if (iovcnt == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(iov[0].iov_len == tls_last_readlen_);
|
||||||
|
tls_last_readlen_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rv = SSL_read(ssl_, iov[0].iov_base, iov[0].iov_len);
|
auto rv = SSL_read(ssl_, iov[0].iov_base, iov[0].iov_len);
|
||||||
|
@ -255,11 +267,13 @@ int ClientHandler::read_tls() {
|
||||||
auto err = SSL_get_error(ssl_, rv);
|
auto err = SSL_get_error(ssl_, rv);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
goto fin;
|
tls_last_readlen_ = iov[0].iov_len;
|
||||||
|
return 0;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
tls_last_readlen_ = iov[0].iov_len;
|
||||||
wlimit_.startw();
|
wlimit_.startw();
|
||||||
ev_timer_again(loop_, &wt_);
|
ev_timer_again(loop_, &wt_);
|
||||||
goto fin;
|
return 0;
|
||||||
default:
|
default:
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
CLOG(INFO, this) << "SSL_read: SSL_get_error returned " << err;
|
CLOG(INFO, this) << "SSL_read: SSL_get_error returned " << err;
|
||||||
|
@ -271,14 +285,13 @@ int ClientHandler::read_tls() {
|
||||||
rb_.write(rv);
|
rb_.write(rv);
|
||||||
rlimit_.drain(rv);
|
rlimit_.drain(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
fin:
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ClientHandler::write_tls() {
|
int ClientHandler::write_tls() {
|
||||||
ev_timer_again(loop_, &rt_);
|
ev_timer_again(loop_, &rt_);
|
||||||
|
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (wb_.rleft() > 0) {
|
if (wb_.rleft() > 0) {
|
||||||
const void *p;
|
const void *p;
|
||||||
|
@ -477,8 +490,9 @@ ClientHandler::ClientHandler(struct ev_loop *loop, int fd, SSL *ssl,
|
||||||
http1_connect_blocker_(nullptr), ssl_(ssl), worker_stat_(worker_stat),
|
http1_connect_blocker_(nullptr), ssl_(ssl), worker_stat_(worker_stat),
|
||||||
last_write_time_(0), warmup_writelen_(0),
|
last_write_time_(0), warmup_writelen_(0),
|
||||||
left_connhd_len_(NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN),
|
left_connhd_len_(NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN),
|
||||||
tls_last_writelen_(0), fd_(fd), should_close_after_write_(false),
|
tls_last_writelen_(0), tls_last_readlen_(0), fd_(fd),
|
||||||
tls_handshake_(false), tls_renegotiation_(false) {
|
should_close_after_write_(false), tls_handshake_(false),
|
||||||
|
tls_renegotiation_(false) {
|
||||||
|
|
||||||
++worker_stat->num_connections;
|
++worker_stat->num_connections;
|
||||||
|
|
||||||
|
|
|
@ -174,6 +174,7 @@ private:
|
||||||
// The number of bytes of HTTP/2 client connection header to read
|
// The number of bytes of HTTP/2 client connection header to read
|
||||||
size_t left_connhd_len_;
|
size_t left_connhd_len_;
|
||||||
size_t tls_last_writelen_;
|
size_t tls_last_writelen_;
|
||||||
|
size_t tls_last_readlen_;
|
||||||
int fd_;
|
int fd_;
|
||||||
bool should_close_after_write_;
|
bool should_close_after_write_;
|
||||||
bool tls_handshake_;
|
bool tls_handshake_;
|
||||||
|
|
|
@ -1611,6 +1611,8 @@ int Http2Session::write_clear() {
|
||||||
int Http2Session::tls_handshake() {
|
int Http2Session::tls_handshake() {
|
||||||
ev_timer_again(loop_, &rt_);
|
ev_timer_again(loop_, &rt_);
|
||||||
|
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
auto rv = SSL_do_handshake(ssl_);
|
auto rv = SSL_do_handshake(ssl_);
|
||||||
|
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
|
@ -1664,6 +1666,8 @@ int Http2Session::tls_handshake() {
|
||||||
int Http2Session::read_tls() {
|
int Http2Session::read_tls() {
|
||||||
ev_timer_again(loop_, &rt_);
|
ev_timer_again(loop_, &rt_);
|
||||||
|
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// we should process buffered data first before we read EOF.
|
// we should process buffered data first before we read EOF.
|
||||||
if (rb_.rleft() && on_read() != 0) {
|
if (rb_.rleft() && on_read() != 0) {
|
||||||
|
@ -1709,6 +1713,8 @@ int Http2Session::read_tls() {
|
||||||
int Http2Session::write_tls() {
|
int Http2Session::write_tls() {
|
||||||
ev_timer_again(loop_, &rt_);
|
ev_timer_again(loop_, &rt_);
|
||||||
|
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (wb_.rleft() > 0) {
|
if (wb_.rleft() > 0) {
|
||||||
const void *p;
|
const void *p;
|
||||||
|
|
Loading…
Reference in New Issue