summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2008-01-08 17:30:39 +0000
committerIgor Sysoev <igor@sysoev.ru>2008-01-08 17:30:39 +0000
commit7e4bd281f916ac2e4a5b40c4210724d28635194b (patch)
tree2e28a70f184c30fb7fa7fb96dc6272583dec3d0d
parentfd391ced61a2b86656f4657b310f2435e4f83275 (diff)
downloadnginx-7e4bd281f916ac2e4a5b40c4210724d28635194b.tar.gz
r1755, r1756, r1757 merge:
*) SSL_shutdown() never returns -1, on error it returns 0. This fixes incidental "bad write retry" errors. *) cleaning stale global SSL error *) remove SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, we never need it
-rw-r--r--src/event/ngx_event_openssl.c63
1 files changed, 35 insertions, 28 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index dc90c9eb2..26411cb89 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -22,6 +22,7 @@ static void ngx_ssl_read_handler(ngx_event_t *rev);
static void ngx_ssl_shutdown_handler(ngx_event_t *ev);
static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
ngx_err_t err, char *text);
+static void ngx_ssl_clear_error(ngx_log_t *log);
static ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone,
void *data);
@@ -186,8 +187,6 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]);
}
- SSL_CTX_set_mode(ssl->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
-
SSL_CTX_set_read_ahead(ssl->ctx, 1);
return NGX_OK;
@@ -404,6 +403,8 @@ ngx_ssl_handshake(ngx_connection_t *c)
int n, sslerr;
ngx_err_t err;
+ ngx_ssl_clear_error(c->log);
+
n = SSL_do_handshake(c->ssl->connection);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
@@ -602,6 +603,8 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
bytes = 0;
+ ngx_ssl_clear_error(c->log);
+
/*
* SSL_read() may return data in parts, so try to read
* until SSL_read() would return no data
@@ -882,6 +885,8 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
int n, sslerr;
ngx_err_t err;
+ ngx_ssl_clear_error(c->log);
+
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size);
n = SSL_write(c->ssl->connection, data, size);
@@ -965,9 +970,8 @@ ngx_ssl_read_handler(ngx_event_t *rev)
ngx_int_t
ngx_ssl_shutdown(ngx_connection_t *c)
{
- int n, sslerr, mode;
- ngx_err_t err;
- ngx_uint_t again;
+ int n, sslerr, mode;
+ ngx_err_t err;
if (c->timedout) {
mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
@@ -986,40 +990,34 @@ ngx_ssl_shutdown(ngx_connection_t *c)
SSL_set_shutdown(c->ssl->connection, mode);
- again = 0;
- sslerr = 0;
+ ngx_ssl_clear_error(c->log);
- for ( ;; ) {
- n = SSL_shutdown(c->ssl->connection);
+ n = SSL_shutdown(c->ssl->connection);
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
- if (n == 1 || (n == 0 && c->timedout)) {
- SSL_free(c->ssl->connection);
- c->ssl = NULL;
-
- return NGX_OK;
- }
-
- if (n == 0) {
- again = 1;
- break;
- }
+ sslerr = 0;
- break;
- }
+ /* SSL_shutdown() never return -1, on error it return 0 */
- if (!again) {
+ if (n != 1) {
sslerr = SSL_get_error(c->ssl->connection, n);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL_get_error: %d", sslerr);
}
- if (again
- || sslerr == SSL_ERROR_WANT_READ
- || sslerr == SSL_ERROR_WANT_WRITE)
+ if (n == 1
+ || sslerr == SSL_ERROR_ZERO_RETURN
+ || (sslerr == 0 && c->timedout))
{
+ SSL_free(c->ssl->connection);
+ c->ssl = NULL;
+
+ return NGX_OK;
+ }
+
+ if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
c->read->handler = ngx_ssl_shutdown_handler;
c->write->handler = ngx_ssl_shutdown_handler;
@@ -1031,7 +1029,7 @@ ngx_ssl_shutdown(ngx_connection_t *c)
return NGX_ERROR;
}
- if (again || sslerr == SSL_ERROR_WANT_READ) {
+ if (sslerr == SSL_ERROR_WANT_READ) {
ngx_add_timer(c->read, 30000);
}
@@ -1112,6 +1110,15 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
}
+static void
+ngx_ssl_clear_error(ngx_log_t *log)
+{
+ if (ERR_peek_error()) {
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error");
+ }
+}
+
+
void ngx_cdecl
ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
{