comparison src/event/ngx_event_openssl.c @ 1754:427d442e1ad8

SSL_shutdown() never returns -1, on error it returns 0. This fixes incidental "bad write retry" errors.
author Igor Sysoev <igor@sysoev.ru>
date Thu, 20 Dec 2007 12:59:05 +0000
parents 4fc402c3ec73
children 59e36c1c6296
comparison
equal deleted inserted replaced
1753:dd278570bdd2 1754:427d442e1ad8
976 976
977 977
978 ngx_int_t 978 ngx_int_t
979 ngx_ssl_shutdown(ngx_connection_t *c) 979 ngx_ssl_shutdown(ngx_connection_t *c)
980 { 980 {
981 int n, sslerr, mode; 981 int n, sslerr, mode;
982 ngx_err_t err; 982 ngx_err_t err;
983 ngx_uint_t again;
984 983
985 if (c->timedout) { 984 if (c->timedout) {
986 mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN; 985 mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
987 986
988 } else { 987 } else {
997 } 996 }
998 } 997 }
999 998
1000 SSL_set_shutdown(c->ssl->connection, mode); 999 SSL_set_shutdown(c->ssl->connection, mode);
1001 1000
1002 again = 0; 1001 n = SSL_shutdown(c->ssl->connection);
1002
1003 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
1004
1003 sslerr = 0; 1005 sslerr = 0;
1004 1006
1005 for ( ;; ) { 1007 /* SSL_shutdown() never return -1, on error it return 0 */
1006 n = SSL_shutdown(c->ssl->connection); 1008
1007 1009 if (n != 1) {
1008 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
1009
1010 if (n == 1 || (n == 0 && c->timedout)) {
1011 SSL_free(c->ssl->connection);
1012 c->ssl = NULL;
1013
1014 return NGX_OK;
1015 }
1016
1017 if (n == 0) {
1018 again = 1;
1019 break;
1020 }
1021
1022 break;
1023 }
1024
1025 if (!again) {
1026 sslerr = SSL_get_error(c->ssl->connection, n); 1010 sslerr = SSL_get_error(c->ssl->connection, n);
1027 1011
1028 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, 1012 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
1029 "SSL_get_error: %d", sslerr); 1013 "SSL_get_error: %d", sslerr);
1030 } 1014 }
1031 1015
1032 if (again 1016 if (n == 1
1033 || sslerr == SSL_ERROR_WANT_READ 1017 || sslerr == SSL_ERROR_ZERO_RETURN
1034 || sslerr == SSL_ERROR_WANT_WRITE) 1018 || (sslerr == 0 && c->timedout))
1035 { 1019 {
1020 SSL_free(c->ssl->connection);
1021 c->ssl = NULL;
1022
1023 return NGX_OK;
1024 }
1025
1026 if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
1036 c->read->handler = ngx_ssl_shutdown_handler; 1027 c->read->handler = ngx_ssl_shutdown_handler;
1037 c->write->handler = ngx_ssl_shutdown_handler; 1028 c->write->handler = ngx_ssl_shutdown_handler;
1038 1029
1039 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { 1030 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
1040 return NGX_ERROR; 1031 return NGX_ERROR;
1042 1033
1043 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { 1034 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
1044 return NGX_ERROR; 1035 return NGX_ERROR;
1045 } 1036 }
1046 1037
1047 if (again || sslerr == SSL_ERROR_WANT_READ) { 1038 if (sslerr == SSL_ERROR_WANT_READ) {
1048 ngx_add_timer(c->read, 30000); 1039 ngx_add_timer(c->read, 30000);
1049 } 1040 }
1050 1041
1051 return NGX_AGAIN; 1042 return NGX_AGAIN;
1052 } 1043 }