Mercurial > hg > nginx-vendor-0-8
diff src/event/ngx_event_openssl.c @ 364:a39aab45a53f NGINX_0_6_26
nginx 0.6.26
*) Bugfix: the "proxy_store" and "fastcgi_store" directives did not
check a response length.
*) Bugfix: a segmentation fault occurred in worker process, if big
value was used in a "expires" directive.
Thanks to Joaquin Cuenca Abela.
*) Bugfix: nginx incorrectly detected cache line size on Pentium 4.
Thanks to Gena Makhomed.
*) Bugfix: in proxied or FastCGI subrequests a client original method
was used instead of the GET method.
*) Bugfix: socket leak in HTTPS mode if deferred accept was used.
Thanks to Ben Maurer.
*) Bugfix: nginx issued the bogus error message "SSL_shutdown() failed
(SSL: )"; bug appeared in 0.6.23.
*) Bugfix: in HTTPS mode requests might fail with the "bad write retry"
error; bug appeared in 0.6.23.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 11 Feb 2008 00:00:00 +0300 |
parents | 2b41fbc2e39e |
children | babd3d9efb62 |
line wrap: on
line diff
--- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -187,6 +187,13 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_ SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]); } + /* + * we need this option because in ngx_ssl_send_chain() + * we may switch to a buffered write and may copy leftover part of + * previously unbuffered data to our internal buffer + */ + SSL_CTX_set_mode(ssl->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + SSL_CTX_set_read_ahead(ssl->ctx, 1); return NGX_OK; @@ -1035,19 +1042,16 @@ ngx_ssl_shutdown(ngx_connection_t *c) sslerr = 0; - /* SSL_shutdown() never return -1, on error it return 0 */ - - if (n != 1) { + /* SSL_shutdown() never returns -1, on error it returns 0 */ + + if (n != 1 && ERR_peek_error()) { sslerr = SSL_get_error(c->ssl->connection, n); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); } - if (n == 1 - || sslerr == SSL_ERROR_ZERO_RETURN - || (sslerr == 0 && c->timedout)) - { + if (n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN) { SSL_free(c->ssl->connection); c->ssl = NULL; @@ -1111,6 +1115,7 @@ static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err, char *text) { + int n; ngx_uint_t level; level = NGX_LOG_CRIT; @@ -1124,6 +1129,9 @@ ngx_ssl_connection_error(ngx_connection_ || err == NGX_ETIMEDOUT #endif || err == NGX_ECONNREFUSED + || err == NGX_ENETDOWN + || err == NGX_ENETUNREACH + || err == NGX_EHOSTDOWN || err == NGX_EHOSTUNREACH) { switch (c->log_error) { @@ -1141,6 +1149,35 @@ ngx_ssl_connection_error(ngx_connection_ break; } } + + } else if (sslerr == SSL_ERROR_SSL) { + + n = ERR_GET_REASON(ERR_peek_error()); + + /* handshake failures */ + if (n == SSL_R_NO_SHARED_CIPHER + || n == SSL_R_UNEXPECTED_MESSAGE + || n == SSL_R_WRONG_VERSION_NUMBER + || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */ + || n == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED + || n == SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER + || n == SSL_R_TLSV1_ALERT_UNKNOWN_CA) + { + switch (c->log_error) { + + case NGX_ERROR_IGNORE_ECONNRESET: + case NGX_ERROR_INFO: + level = NGX_LOG_INFO; + break; + + case NGX_ERROR_ERR: + level = NGX_LOG_ERR; + break; + + default: + break; + } + } } ngx_ssl_error(level, c->log, err, text); @@ -1150,18 +1187,21 @@ ngx_ssl_connection_error(ngx_connection_ static void ngx_ssl_clear_error(ngx_log_t *log) { - if (ERR_peek_error()) { + while (ERR_peek_error()) { ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error"); } + + ERR_clear_error(); } void ngx_cdecl ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...) { - u_long n; - va_list args; - u_char errstr[NGX_MAX_CONF_ERRSTR], *p, *last; + u_long n; + va_list args; + u_char *p, *last; + u_char errstr[NGX_MAX_CONF_ERRSTR]; last = errstr + NGX_MAX_CONF_ERRSTR; @@ -1171,7 +1211,7 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_ p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p); - while (p < last) { + for ( ;; ) { n = ERR_get_error(); @@ -1179,6 +1219,10 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_ break; } + if (p >= last) { + continue; + } + *p++ = ' '; ERR_error_string_n(n, (char *) p, last - p);