nghttpx: Remove last write/read fields for TLS
It seems that we don't care about this since we don't change buffer pointer between would-block write/read and next write/read. Somehow we decided we need these fields. As a precaution, we set SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER in SSL_set_mode() for both server and client contexts.
This commit is contained in:
parent
41e266181e
commit
585af93828
|
@ -151,22 +151,14 @@ void Connection::update_tls_warmup_writelen(size_t n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t Connection::write_tls(const void *data, size_t len) {
|
ssize_t Connection::write_tls(const void *data, size_t len) {
|
||||||
// SSL_write requires the same arguments (buf pointer and its
|
// We set SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, so we don't have to
|
||||||
// length) on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE.
|
// care about parameters after SSL_ERROR_WANT_READ or
|
||||||
// get_write_limit() may return smaller length than previously
|
// SSL_ERROR_WANT_WRITE.
|
||||||
// passed to SSL_write, which violates OpenSSL assumption. To avoid
|
|
||||||
// this, we keep last legnth passed to SSL_write to
|
|
||||||
// tls.last_writelen if SSL_write indicated I/O blocking.
|
|
||||||
if (tls.last_writelen == 0) {
|
|
||||||
len = std::min(len, wlimit.avail());
|
len = std::min(len, wlimit.avail());
|
||||||
len = std::min(len, get_tls_write_limit());
|
len = std::min(len, get_tls_write_limit());
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
len = tls.last_writelen;
|
|
||||||
tls.last_writelen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rv = SSL_write(tls.ssl, data, len);
|
auto rv = SSL_write(tls.ssl, data, len);
|
||||||
|
|
||||||
|
@ -185,7 +177,6 @@ ssize_t Connection::write_tls(const void *data, size_t len) {
|
||||||
}
|
}
|
||||||
return SHRPX_ERR_NETWORK;
|
return SHRPX_ERR_NETWORK;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
tls.last_writelen = len;
|
|
||||||
wlimit.startw();
|
wlimit.startw();
|
||||||
ev_timer_again(loop, &wt);
|
ev_timer_again(loop, &wt);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -205,22 +196,14 @@ ssize_t Connection::write_tls(const void *data, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t Connection::read_tls(void *data, size_t len) {
|
ssize_t Connection::read_tls(void *data, size_t len) {
|
||||||
// SSL_read requires the same arguments (buf pointer and its
|
// Although SSL_read manual says it requires the same arguments (buf
|
||||||
// length) on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE.
|
// pointer and its length) on SSL_ERROR_WANT_READ or
|
||||||
// rlimit_.avail() or rlimit_.avail() may return different length
|
// SSL_ERROR_WANT_WRITE. But after reading OpenSSL source code,
|
||||||
// than the length previously passed to SSL_read, which violates
|
// there is no such requirement.
|
||||||
// OpenSSL assumption. To avoid this, we keep last legnth passed
|
|
||||||
// to SSL_read to tls_last_readlen_ if SSL_read indicated I/O
|
|
||||||
// blocking.
|
|
||||||
if (tls.last_readlen == 0) {
|
|
||||||
len = std::min(len, rlimit.avail());
|
len = std::min(len, rlimit.avail());
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
len = tls.last_readlen;
|
|
||||||
tls.last_readlen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rv = SSL_read(tls.ssl, data, len);
|
auto rv = SSL_read(tls.ssl, data, len);
|
||||||
|
|
||||||
|
@ -228,7 +211,6 @@ ssize_t Connection::read_tls(void *data, size_t len) {
|
||||||
auto err = SSL_get_error(tls.ssl, rv);
|
auto err = SSL_get_error(tls.ssl, rv);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
tls.last_readlen = len;
|
|
||||||
return 0;
|
return 0;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
|
|
@ -42,10 +42,6 @@ struct TLSConnection {
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
ev_tstamp last_write_time;
|
ev_tstamp last_write_time;
|
||||||
size_t warmup_writelen;
|
size_t warmup_writelen;
|
||||||
// length passed to SSL_write and SSL_read last time. This is
|
|
||||||
// required since these functions require the exact same parameters
|
|
||||||
// on non-blocking I/O.
|
|
||||||
size_t last_writelen, last_readlen;
|
|
||||||
bool initial_handshake_done;
|
bool initial_handshake_done;
|
||||||
bool reneg_started;
|
bool reneg_started;
|
||||||
};
|
};
|
||||||
|
|
|
@ -366,6 +366,7 @@ SSL_CTX *create_ssl_context(const char *private_key_file,
|
||||||
|
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||||
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||||
if (get_config()->private_key_passwd) {
|
if (get_config()->private_key_passwd) {
|
||||||
SSL_CTX_set_default_passwd_cb(ssl_ctx, ssl_pem_passwd_cb);
|
SSL_CTX_set_default_passwd_cb(ssl_ctx, ssl_pem_passwd_cb);
|
||||||
SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, (void *)get_config());
|
SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, (void *)get_config());
|
||||||
|
@ -467,6 +468,7 @@ SSL_CTX *create_ssl_client_context() {
|
||||||
|
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||||
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||||
|
|
||||||
if (SSL_CTX_set_default_verify_paths(ssl_ctx) != 1) {
|
if (SSL_CTX_set_default_verify_paths(ssl_ctx) != 1) {
|
||||||
LOG(WARN) << "Could not load system trusted ca certificates: "
|
LOG(WARN) << "Could not load system trusted ca certificates: "
|
||||||
|
|
Loading…
Reference in New Issue