Mercurial > hg > nginx
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 } |