Mercurial > hg > nginx-ranges
comparison src/event/ngx_event_openssl.c @ 358:9121a0a91f47 NGINX_0_6_23
nginx 0.6.23
*) Change: the "off" parameter in the "ssl_session_cache" directive;
now this is default parameter.
*) Change: the "open_file_cache_retest" directive was renamed to the
"open_file_cache_valid".
*) Feature: the "open_file_cache_min_uses" directive.
*) Feature: the ngx_http_gzip_static_module.
*) Feature: the "gzip_disable" directive.
*) Feature: the "memcached_pass" directive may be used inside the "if"
block.
*) Bugfix: a segmentation fault occurred in worker process, if the
"memcached_pass" and "if" directives were used in the same location.
*) Bugfix: if a "satisfy_any on" directive was used and not all access
and auth modules directives were set, then other given access and
auth directives were not tested;
*) Bugfix: regex parameters in a "valid_referers" directive were not
inherited from previous level.
*) Bugfix: a "post_action" directive did run if a request was completed
with 499 status code.
*) Bugfix: optimization of 16K buffer usage in a SSL connection.
Thanks to Ben Maurer.
*) Bugfix: the STARTTLS in SMTP mode did not work.
Thanks to Oleg Motienko.
*) Bugfix: in HTTPS mode requests might fail with the "bad write retry"
error; bug appeared in 0.5.13.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Thu, 27 Dec 2007 00:00:00 +0300 |
parents | b743d290eb3b |
children | 2b41fbc2e39e |
comparison
equal
deleted
inserted
replaced
357:16d557a75356 | 358:9121a0a91f47 |
---|---|
20 static void ngx_ssl_write_handler(ngx_event_t *wev); | 20 static void ngx_ssl_write_handler(ngx_event_t *wev); |
21 static void ngx_ssl_read_handler(ngx_event_t *rev); | 21 static void ngx_ssl_read_handler(ngx_event_t *rev); |
22 static void ngx_ssl_shutdown_handler(ngx_event_t *ev); | 22 static void ngx_ssl_shutdown_handler(ngx_event_t *ev); |
23 static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, | 23 static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, |
24 ngx_err_t err, char *text); | 24 ngx_err_t err, char *text); |
25 static void ngx_ssl_clear_error(ngx_log_t *log); | |
25 | 26 |
26 static ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, | 27 static ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, |
27 void *data); | 28 void *data); |
28 static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, | 29 static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, |
29 ngx_ssl_session_t *sess); | 30 ngx_ssl_session_t *sess); |
184 | 185 |
185 if (ngx_ssl_protocols[protocols >> 1] != 0) { | 186 if (ngx_ssl_protocols[protocols >> 1] != 0) { |
186 SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]); | 187 SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]); |
187 } | 188 } |
188 | 189 |
189 SSL_CTX_set_mode(ssl->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); | |
190 | |
191 SSL_CTX_set_read_ahead(ssl->ctx, 1); | 190 SSL_CTX_set_read_ahead(ssl->ctx, 1); |
192 | 191 |
193 return NGX_OK; | 192 return NGX_OK; |
194 } | 193 } |
195 | 194 |
343 sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t)); | 342 sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t)); |
344 if (sc == NULL) { | 343 if (sc == NULL) { |
345 return NGX_ERROR; | 344 return NGX_ERROR; |
346 } | 345 } |
347 | 346 |
348 if (flags & NGX_SSL_BUFFER) { | 347 sc->buffer = ((flags & NGX_SSL_BUFFER) != 0); |
349 sc->buffer = 1; | |
350 | |
351 sc->buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE); | |
352 if (sc->buf == NULL) { | |
353 return NGX_ERROR; | |
354 } | |
355 } | |
356 | 348 |
357 sc->connection = SSL_new(ssl->ctx); | 349 sc->connection = SSL_new(ssl->ctx); |
358 | 350 |
359 if (sc->connection == NULL) { | 351 if (sc->connection == NULL) { |
360 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed"); | 352 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed"); |
402 ngx_ssl_handshake(ngx_connection_t *c) | 394 ngx_ssl_handshake(ngx_connection_t *c) |
403 { | 395 { |
404 int n, sslerr; | 396 int n, sslerr; |
405 ngx_err_t err; | 397 ngx_err_t err; |
406 | 398 |
399 ngx_ssl_clear_error(c->log); | |
400 | |
407 n = SSL_do_handshake(c->ssl->connection); | 401 n = SSL_do_handshake(c->ssl->connection); |
408 | 402 |
409 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); | 403 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); |
410 | 404 |
411 if (n == 1) { | 405 if (n == 1) { |
602 c->read->eof = 1; | 596 c->read->eof = 1; |
603 return 0; | 597 return 0; |
604 } | 598 } |
605 | 599 |
606 bytes = 0; | 600 bytes = 0; |
601 | |
602 ngx_ssl_clear_error(c->log); | |
607 | 603 |
608 /* | 604 /* |
609 * SSL_read() may return data in parts, so try to read | 605 * SSL_read() may return data in parts, so try to read |
610 * until SSL_read() would return no data | 606 * until SSL_read() would return no data |
611 */ | 607 */ |
799 | 795 |
800 if (limit == 0 || limit > (off_t) (NGX_MAX_UINT32_VALUE - ngx_pagesize)) { | 796 if (limit == 0 || limit > (off_t) (NGX_MAX_UINT32_VALUE - ngx_pagesize)) { |
801 limit = NGX_MAX_UINT32_VALUE - ngx_pagesize; | 797 limit = NGX_MAX_UINT32_VALUE - ngx_pagesize; |
802 } | 798 } |
803 | 799 |
804 | |
805 buf = c->ssl->buf; | 800 buf = c->ssl->buf; |
801 | |
802 if (buf == NULL) { | |
803 buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE); | |
804 if (buf == NULL) { | |
805 return NGX_CHAIN_ERROR; | |
806 } | |
807 | |
808 c->ssl->buf = buf; | |
809 } | |
810 | |
811 if (buf->start == NULL) { | |
812 buf->start = ngx_palloc(c->pool, NGX_SSL_BUFSIZE); | |
813 if (buf->start == NULL) { | |
814 return NGX_CHAIN_ERROR; | |
815 } | |
816 | |
817 buf->pos = buf->start; | |
818 buf->last = buf->start; | |
819 buf->end = buf->start + NGX_SSL_BUFSIZE; | |
820 } | |
821 | |
806 send = 0; | 822 send = 0; |
807 flush = (in == NULL) ? 1 : 0; | 823 flush = (in == NULL) ? 1 : 0; |
808 | 824 |
809 for ( ;; ) { | 825 for ( ;; ) { |
810 | 826 |
893 ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) | 909 ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) |
894 { | 910 { |
895 int n, sslerr; | 911 int n, sslerr; |
896 ngx_err_t err; | 912 ngx_err_t err; |
897 | 913 |
914 ngx_ssl_clear_error(c->log); | |
915 | |
898 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size); | 916 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size); |
899 | 917 |
900 n = SSL_write(c->ssl->connection, data, size); | 918 n = SSL_write(c->ssl->connection, data, size); |
901 | 919 |
902 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); | 920 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); |
973 | 991 |
974 c->write->handler(c->write); | 992 c->write->handler(c->write); |
975 } | 993 } |
976 | 994 |
977 | 995 |
996 void | |
997 ngx_ssl_free_buffer(ngx_connection_t *c) | |
998 { | |
999 if (ngx_pfree(c->pool, c->ssl->buf->start) == NGX_OK) { | |
1000 c->ssl->buf->start = NULL; | |
1001 } | |
1002 } | |
1003 | |
1004 | |
978 ngx_int_t | 1005 ngx_int_t |
979 ngx_ssl_shutdown(ngx_connection_t *c) | 1006 ngx_ssl_shutdown(ngx_connection_t *c) |
980 { | 1007 { |
981 int n, sslerr, mode; | 1008 int n, sslerr, mode; |
982 ngx_err_t err; | 1009 ngx_err_t err; |
983 ngx_uint_t again; | |
984 | 1010 |
985 if (c->timedout) { | 1011 if (c->timedout) { |
986 mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN; | 1012 mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN; |
987 | 1013 |
988 } else { | 1014 } else { |
997 } | 1023 } |
998 } | 1024 } |
999 | 1025 |
1000 SSL_set_shutdown(c->ssl->connection, mode); | 1026 SSL_set_shutdown(c->ssl->connection, mode); |
1001 | 1027 |
1002 again = 0; | 1028 ngx_ssl_clear_error(c->log); |
1029 | |
1030 n = SSL_shutdown(c->ssl->connection); | |
1031 | |
1032 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); | |
1033 | |
1003 sslerr = 0; | 1034 sslerr = 0; |
1004 | 1035 |
1005 for ( ;; ) { | 1036 /* SSL_shutdown() never return -1, on error it return 0 */ |
1006 n = SSL_shutdown(c->ssl->connection); | 1037 |
1007 | 1038 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); | 1039 sslerr = SSL_get_error(c->ssl->connection, n); |
1027 | 1040 |
1028 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | 1041 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
1029 "SSL_get_error: %d", sslerr); | 1042 "SSL_get_error: %d", sslerr); |
1030 } | 1043 } |
1031 | 1044 |
1032 if (again | 1045 if (n == 1 |
1033 || sslerr == SSL_ERROR_WANT_READ | 1046 || sslerr == SSL_ERROR_ZERO_RETURN |
1034 || sslerr == SSL_ERROR_WANT_WRITE) | 1047 || (sslerr == 0 && c->timedout)) |
1035 { | 1048 { |
1049 SSL_free(c->ssl->connection); | |
1050 c->ssl = NULL; | |
1051 | |
1052 return NGX_OK; | |
1053 } | |
1054 | |
1055 if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) { | |
1036 c->read->handler = ngx_ssl_shutdown_handler; | 1056 c->read->handler = ngx_ssl_shutdown_handler; |
1037 c->write->handler = ngx_ssl_shutdown_handler; | 1057 c->write->handler = ngx_ssl_shutdown_handler; |
1038 | 1058 |
1039 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { | 1059 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { |
1040 return NGX_ERROR; | 1060 return NGX_ERROR; |
1042 | 1062 |
1043 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | 1063 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { |
1044 return NGX_ERROR; | 1064 return NGX_ERROR; |
1045 } | 1065 } |
1046 | 1066 |
1047 if (again || sslerr == SSL_ERROR_WANT_READ) { | 1067 if (sslerr == SSL_ERROR_WANT_READ) { |
1048 ngx_add_timer(c->read, 30000); | 1068 ngx_add_timer(c->read, 30000); |
1049 } | 1069 } |
1050 | 1070 |
1051 return NGX_AGAIN; | 1071 return NGX_AGAIN; |
1052 } | 1072 } |
1123 | 1143 |
1124 ngx_ssl_error(level, c->log, err, text); | 1144 ngx_ssl_error(level, c->log, err, text); |
1125 } | 1145 } |
1126 | 1146 |
1127 | 1147 |
1148 static void | |
1149 ngx_ssl_clear_error(ngx_log_t *log) | |
1150 { | |
1151 if (ERR_peek_error()) { | |
1152 ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error"); | |
1153 } | |
1154 } | |
1155 | |
1156 | |
1128 void ngx_cdecl | 1157 void ngx_cdecl |
1129 ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...) | 1158 ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...) |
1130 { | 1159 { |
1131 u_long n; | 1160 u_long n; |
1132 va_list args; | 1161 va_list args; |
1164 ngx_int_t | 1193 ngx_int_t |
1165 ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx, | 1194 ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx, |
1166 ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout) | 1195 ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout) |
1167 { | 1196 { |
1168 long cache_mode; | 1197 long cache_mode; |
1198 | |
1199 if (builtin_session_cache == NGX_SSL_NO_SCACHE) { | |
1200 SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF); | |
1201 return NGX_OK; | |
1202 } | |
1169 | 1203 |
1170 cache_mode = SSL_SESS_CACHE_SERVER; | 1204 cache_mode = SSL_SESS_CACHE_SERVER; |
1171 | 1205 |
1172 if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) { | 1206 if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) { |
1173 cache_mode |= SSL_SESS_CACHE_NO_INTERNAL; | 1207 cache_mode |= SSL_SESS_CACHE_NO_INTERNAL; |
1208 | 1242 |
1209 static ngx_int_t | 1243 static ngx_int_t |
1210 ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data) | 1244 ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data) |
1211 { | 1245 { |
1212 ngx_slab_pool_t *shpool; | 1246 ngx_slab_pool_t *shpool; |
1213 ngx_rbtree_node_t *sentinel; | |
1214 ngx_ssl_session_cache_t *cache; | 1247 ngx_ssl_session_cache_t *cache; |
1215 | 1248 |
1216 if (data) { | 1249 if (data) { |
1217 shm_zone->data = data; | 1250 shm_zone->data = data; |
1218 return NGX_OK; | 1251 return NGX_OK; |
1223 cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t)); | 1256 cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t)); |
1224 if (cache == NULL) { | 1257 if (cache == NULL) { |
1225 return NGX_ERROR; | 1258 return NGX_ERROR; |
1226 } | 1259 } |
1227 | 1260 |
1228 cache->session_cache_head.prev = NULL; | 1261 ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel, |
1229 cache->session_cache_head.next = &cache->session_cache_tail; | |
1230 | |
1231 cache->session_cache_tail.prev = &cache->session_cache_head; | |
1232 cache->session_cache_tail.next = NULL; | |
1233 | |
1234 cache->session_rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t)); | |
1235 if (cache->session_rbtree == NULL) { | |
1236 return NGX_ERROR; | |
1237 } | |
1238 | |
1239 sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t)); | |
1240 if (sentinel == NULL) { | |
1241 return NGX_ERROR; | |
1242 } | |
1243 | |
1244 ngx_rbtree_init(cache->session_rbtree, sentinel, | |
1245 ngx_ssl_session_rbtree_insert_value); | 1262 ngx_ssl_session_rbtree_insert_value); |
1263 | |
1264 ngx_queue_init(&cache->expire_queue); | |
1246 | 1265 |
1247 shm_zone->data = cache; | 1266 shm_zone->data = cache; |
1248 | 1267 |
1249 return NGX_OK; | 1268 return NGX_OK; |
1250 } | 1269 } |
1272 { | 1291 { |
1273 int len; | 1292 int len; |
1274 u_char *p, *id, *cached_sess; | 1293 u_char *p, *id, *cached_sess; |
1275 uint32_t hash; | 1294 uint32_t hash; |
1276 SSL_CTX *ssl_ctx; | 1295 SSL_CTX *ssl_ctx; |
1277 ngx_time_t *tp; | |
1278 ngx_shm_zone_t *shm_zone; | 1296 ngx_shm_zone_t *shm_zone; |
1279 ngx_connection_t *c; | 1297 ngx_connection_t *c; |
1280 ngx_slab_pool_t *shpool; | 1298 ngx_slab_pool_t *shpool; |
1281 ngx_ssl_sess_id_t *sess_id; | 1299 ngx_ssl_sess_id_t *sess_id; |
1282 ngx_ssl_session_cache_t *cache; | 1300 ngx_ssl_session_cache_t *cache; |
1348 | 1366 |
1349 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | 1367 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, |
1350 "http ssl new session: %08XD:%d:%d", | 1368 "http ssl new session: %08XD:%d:%d", |
1351 hash, sess->session_id_length, len); | 1369 hash, sess->session_id_length, len); |
1352 | 1370 |
1353 tp = ngx_timeofday(); | |
1354 | |
1355 sess_id->node.key = hash; | 1371 sess_id->node.key = hash; |
1356 sess_id->node.data = (u_char) sess->session_id_length; | 1372 sess_id->node.data = (u_char) sess->session_id_length; |
1357 sess_id->id = id; | 1373 sess_id->id = id; |
1358 sess_id->len = len; | 1374 sess_id->len = len; |
1359 sess_id->session = cached_sess; | 1375 sess_id->session = cached_sess; |
1360 | 1376 |
1361 sess_id->expire = tp->sec + SSL_CTX_get_timeout(ssl_ctx); | 1377 sess_id->expire = ngx_time() + SSL_CTX_get_timeout(ssl_ctx); |
1362 | 1378 |
1363 sess_id->next = cache->session_cache_head.next; | 1379 ngx_queue_insert_head(&cache->expire_queue, &sess_id->queue); |
1364 sess_id->next->prev = sess_id; | 1380 |
1365 sess_id->prev = &cache->session_cache_head; | 1381 ngx_rbtree_insert(&cache->session_rbtree, &sess_id->node); |
1366 cache->session_cache_head.next = sess_id; | |
1367 | |
1368 ngx_rbtree_insert(cache->session_rbtree, &sess_id->node); | |
1369 | 1382 |
1370 ngx_shmtx_unlock(&shpool->mutex); | 1383 ngx_shmtx_unlock(&shpool->mutex); |
1371 | 1384 |
1372 return 0; | 1385 return 0; |
1373 | 1386 |
1398 const | 1411 const |
1399 #endif | 1412 #endif |
1400 u_char *p; | 1413 u_char *p; |
1401 uint32_t hash; | 1414 uint32_t hash; |
1402 ngx_int_t rc; | 1415 ngx_int_t rc; |
1403 ngx_time_t *tp; | |
1404 ngx_shm_zone_t *shm_zone; | 1416 ngx_shm_zone_t *shm_zone; |
1405 ngx_slab_pool_t *shpool; | 1417 ngx_slab_pool_t *shpool; |
1406 ngx_connection_t *c; | 1418 ngx_connection_t *c; |
1407 ngx_rbtree_node_t *node, *sentinel; | 1419 ngx_rbtree_node_t *node, *sentinel; |
1408 ngx_ssl_session_t *sess; | 1420 ngx_ssl_session_t *sess; |
1421 shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn), | 1433 shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn), |
1422 ngx_ssl_session_cache_index); | 1434 ngx_ssl_session_cache_index); |
1423 | 1435 |
1424 cache = shm_zone->data; | 1436 cache = shm_zone->data; |
1425 | 1437 |
1426 if (cache->session_rbtree == NULL) { | |
1427 return NULL; | |
1428 } | |
1429 | |
1430 sess = NULL; | 1438 sess = NULL; |
1431 | 1439 |
1432 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; | 1440 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; |
1433 | 1441 |
1434 ngx_shmtx_lock(&shpool->mutex); | 1442 ngx_shmtx_lock(&shpool->mutex); |
1435 | 1443 |
1436 node = cache->session_rbtree->root; | 1444 node = cache->session_rbtree.root; |
1437 sentinel = cache->session_rbtree->sentinel; | 1445 sentinel = cache->session_rbtree.sentinel; |
1438 | 1446 |
1439 while (node != sentinel) { | 1447 while (node != sentinel) { |
1440 | 1448 |
1441 if (hash < node->key) { | 1449 if (hash < node->key) { |
1442 node = node->left; | 1450 node = node->left; |
1455 | 1463 |
1456 rc = ngx_memn2cmp(id, sess_id->id, | 1464 rc = ngx_memn2cmp(id, sess_id->id, |
1457 (size_t) len, (size_t) node->data); | 1465 (size_t) len, (size_t) node->data); |
1458 if (rc == 0) { | 1466 if (rc == 0) { |
1459 | 1467 |
1460 tp = ngx_timeofday(); | 1468 if (sess_id->expire > ngx_time()) { |
1461 | |
1462 if (sess_id->expire > tp->sec) { | |
1463 ngx_memcpy(buf, sess_id->session, sess_id->len); | 1469 ngx_memcpy(buf, sess_id->session, sess_id->len); |
1464 | 1470 |
1465 ngx_shmtx_unlock(&shpool->mutex); | 1471 ngx_shmtx_unlock(&shpool->mutex); |
1466 | 1472 |
1467 p = buf; | 1473 p = buf; |
1468 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len); | 1474 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len); |
1469 | 1475 |
1470 return sess; | 1476 return sess; |
1471 } | 1477 } |
1472 | 1478 |
1473 sess_id->next->prev = sess_id->prev; | 1479 ngx_queue_remove(&sess_id->queue); |
1474 sess_id->prev->next = sess_id->next; | 1480 |
1475 | 1481 ngx_rbtree_delete(&cache->session_rbtree, node); |
1476 ngx_rbtree_delete(cache->session_rbtree, node); | |
1477 | 1482 |
1478 ngx_slab_free_locked(shpool, sess_id->session); | 1483 ngx_slab_free_locked(shpool, sess_id->session); |
1479 #if (NGX_PTR_SIZE == 4) | 1484 #if (NGX_PTR_SIZE == 4) |
1480 ngx_slab_free_locked(shpool, sess_id->id); | 1485 ngx_slab_free_locked(shpool, sess_id->id); |
1481 #endif | 1486 #endif |
1528 | 1533 |
1529 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; | 1534 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; |
1530 | 1535 |
1531 ngx_shmtx_lock(&shpool->mutex); | 1536 ngx_shmtx_lock(&shpool->mutex); |
1532 | 1537 |
1533 node = cache->session_rbtree->root; | 1538 node = cache->session_rbtree.root; |
1534 sentinel = cache->session_rbtree->sentinel; | 1539 sentinel = cache->session_rbtree.sentinel; |
1535 | 1540 |
1536 while (node != sentinel) { | 1541 while (node != sentinel) { |
1537 | 1542 |
1538 if (hash < node->key) { | 1543 if (hash < node->key) { |
1539 node = node->left; | 1544 node = node->left; |
1551 sess_id = (ngx_ssl_sess_id_t *) node; | 1556 sess_id = (ngx_ssl_sess_id_t *) node; |
1552 | 1557 |
1553 rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data); | 1558 rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data); |
1554 | 1559 |
1555 if (rc == 0) { | 1560 if (rc == 0) { |
1556 sess_id->next->prev = sess_id->prev; | 1561 |
1557 sess_id->prev->next = sess_id->next; | 1562 ngx_queue_remove(&sess_id->queue); |
1558 | 1563 |
1559 ngx_rbtree_delete(cache->session_rbtree, node); | 1564 ngx_rbtree_delete(&cache->session_rbtree, node); |
1560 | 1565 |
1561 ngx_slab_free_locked(shpool, sess_id->session); | 1566 ngx_slab_free_locked(shpool, sess_id->session); |
1562 #if (NGX_PTR_SIZE == 4) | 1567 #if (NGX_PTR_SIZE == 4) |
1563 ngx_slab_free_locked(shpool, sess_id->id); | 1568 ngx_slab_free_locked(shpool, sess_id->id); |
1564 #endif | 1569 #endif |
1582 | 1587 |
1583 static void | 1588 static void |
1584 ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache, | 1589 ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache, |
1585 ngx_slab_pool_t *shpool, ngx_uint_t n) | 1590 ngx_slab_pool_t *shpool, ngx_uint_t n) |
1586 { | 1591 { |
1587 ngx_time_t *tp; | 1592 time_t now; |
1593 ngx_queue_t *q; | |
1588 ngx_ssl_sess_id_t *sess_id; | 1594 ngx_ssl_sess_id_t *sess_id; |
1589 | 1595 |
1590 tp = ngx_timeofday(); | 1596 now = ngx_time(); |
1591 | 1597 |
1592 while (n < 3) { | 1598 while (n < 3) { |
1593 | 1599 |
1594 sess_id = cache->session_cache_tail.prev; | 1600 if (ngx_queue_empty(&cache->expire_queue)) { |
1595 | |
1596 if (sess_id == &cache->session_cache_head) { | |
1597 return; | 1601 return; |
1598 } | 1602 } |
1599 | 1603 |
1600 if (n++ != 0 && sess_id->expire > tp->sec) { | 1604 q = ngx_queue_last(&cache->expire_queue); |
1605 | |
1606 sess_id = ngx_queue_data(q, ngx_ssl_sess_id_t, queue); | |
1607 | |
1608 if (n++ != 0 && sess_id->expire > now) { | |
1601 return; | 1609 return; |
1602 } | 1610 } |
1603 | 1611 |
1604 sess_id->next->prev = sess_id->prev; | 1612 ngx_queue_remove(q); |
1605 sess_id->prev->next = sess_id->next; | |
1606 | |
1607 ngx_rbtree_delete(cache->session_rbtree, &sess_id->node); | |
1608 | 1613 |
1609 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, | 1614 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, |
1610 "expire session: %08Xi", sess_id->node.key); | 1615 "expire session: %08Xi", sess_id->node.key); |
1616 | |
1617 ngx_rbtree_delete(&cache->session_rbtree, &sess_id->node); | |
1611 | 1618 |
1612 ngx_slab_free_locked(shpool, sess_id->session); | 1619 ngx_slab_free_locked(shpool, sess_id->session); |
1613 #if (NGX_PTR_SIZE == 4) | 1620 #if (NGX_PTR_SIZE == 4) |
1614 ngx_slab_free_locked(shpool, sess_id->id); | 1621 ngx_slab_free_locked(shpool, sess_id->id); |
1615 #endif | 1622 #endif |