Mercurial > hg > nginx-mail
comparison src/event/ngx_event_openssl.c @ 272:29a6403156b0 NGINX_0_5_6
nginx 0.5.6
*) Change: now the ngx_http_index_module ignores all methods except the
GET, HEAD, and POST methods.
*) Feature: the ngx_http_limit_zone_module.
*) Feature: the $binary_remote_addr variable.
*) Feature: the "ssl_session_cache" directives of the
ngx_http_ssl_module and ngx_imap_ssl_module.
*) Feature: the DELETE method supports recursive removal.
*) Bugfix: the byte-ranges were transferred incorrectly if the
$r->sendfile() was used.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 09 Jan 2007 00:00:00 +0300 |
parents | 559bc7ec214e |
children | 052a7b1d40e5 |
comparison
equal
deleted
inserted
replaced
271:fcbee7dacf2b | 272:29a6403156b0 |
---|---|
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 | |
26 static ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, | |
27 void *data); | |
28 static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, | |
29 ngx_ssl_session_t *sess); | |
30 static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, | |
31 u_char *id, int len, int *copy); | |
32 static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess); | |
33 static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache, | |
34 ngx_slab_pool_t *shpool, ngx_uint_t n); | |
35 | |
25 static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); | 36 static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); |
26 static char *ngx_openssl_init_conf(ngx_cycle_t *cycle, void *conf); | 37 static char *ngx_openssl_init_conf(ngx_cycle_t *cycle, void *conf); |
27 static void ngx_openssl_exit(ngx_cycle_t *cycle); | 38 static void ngx_openssl_exit(ngx_cycle_t *cycle); |
28 | 39 |
29 #if !(NGX_SSL_ENGINE) | 40 #if !(NGX_SSL_ENGINE) |
82 SSL_OP_NO_SSLv2, | 93 SSL_OP_NO_SSLv2, |
83 0, | 94 0, |
84 }; | 95 }; |
85 | 96 |
86 | 97 |
87 int ngx_connection_index; | 98 int ngx_ssl_connection_index; |
99 int ngx_ssl_server_conf_index; | |
100 int ngx_ssl_session_cache_index; | |
88 | 101 |
89 | 102 |
90 ngx_int_t | 103 ngx_int_t |
91 ngx_ssl_init(ngx_log_t *log) | 104 ngx_ssl_init(ngx_log_t *log) |
92 { | 105 { |
106 #if OPENSSL_VERSION_NUMBER >= 0x00907000 | |
107 OPENSSL_config(NULL); | |
108 #endif | |
109 | |
93 SSL_library_init(); | 110 SSL_library_init(); |
94 SSL_load_error_strings(); | 111 SSL_load_error_strings(); |
95 | 112 |
96 #if (NGX_SSL_ENGINE) | 113 #if (NGX_SSL_ENGINE) |
97 ENGINE_load_builtin_engines(); | 114 ENGINE_load_builtin_engines(); |
98 #endif | 115 #endif |
99 | 116 |
100 ngx_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); | 117 ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); |
101 | 118 |
102 if (ngx_connection_index == -1) { | 119 if (ngx_ssl_connection_index == -1) { |
103 ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed"); | 120 ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed"); |
104 return NGX_ERROR; | 121 return NGX_ERROR; |
105 } | 122 } |
106 | 123 |
124 ngx_ssl_server_conf_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, | |
125 NULL); | |
126 if (ngx_ssl_server_conf_index == -1) { | |
127 ngx_ssl_error(NGX_LOG_ALERT, log, 0, | |
128 "SSL_CTX_get_ex_new_index() failed"); | |
129 return NGX_ERROR; | |
130 } | |
131 | |
132 ngx_ssl_session_cache_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, | |
133 NULL); | |
134 if (ngx_ssl_session_cache_index == -1) { | |
135 ngx_ssl_error(NGX_LOG_ALERT, log, 0, | |
136 "SSL_CTX_get_ex_new_index() failed"); | |
137 return NGX_ERROR; | |
138 } | |
139 | |
107 return NGX_OK; | 140 return NGX_OK; |
108 } | 141 } |
109 | 142 |
110 | 143 |
111 ngx_int_t | 144 ngx_int_t |
112 ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols) | 145 ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data) |
113 { | 146 { |
114 ssl->ctx = SSL_CTX_new(SSLv23_method()); | 147 ssl->ctx = SSL_CTX_new(SSLv23_method()); |
115 | 148 |
116 if (ssl->ctx == NULL) { | 149 if (ssl->ctx == NULL) { |
117 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed"); | 150 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed"); |
151 return NGX_ERROR; | |
152 } | |
153 | |
154 if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_server_conf_index, data) == 0) { | |
155 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, | |
156 "SSL_CTX_set_ex_data() failed"); | |
118 return NGX_ERROR; | 157 return NGX_ERROR; |
119 } | 158 } |
120 | 159 |
121 /* client side options */ | 160 /* client side options */ |
122 | 161 |
258 subject = name ? X509_NAME_oneline(name, NULL, 0) : "(none)"; | 297 subject = name ? X509_NAME_oneline(name, NULL, 0) : "(none)"; |
259 | 298 |
260 name = X509_get_issuer_name(cert); | 299 name = X509_get_issuer_name(cert); |
261 issuer = name ? X509_NAME_oneline(name, NULL, 0) : "(none)"; | 300 issuer = name ? X509_NAME_oneline(name, NULL, 0) : "(none)"; |
262 | 301 |
263 ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0, | 302 ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0, |
264 "verify:%d, error:%d, depth:%d, " | 303 "verify:%d, error:%d, depth:%d, " |
265 "subject:\"%s\",issuer: \"%s\"", | 304 "subject:\"%s\",issuer: \"%s\"", |
266 ok, err, depth, subject, issuer); | 305 ok, err, depth, subject, issuer); |
267 | 306 |
268 return 1; | 307 return 1; |
330 | 369 |
331 } else { | 370 } else { |
332 SSL_set_accept_state(sc->connection); | 371 SSL_set_accept_state(sc->connection); |
333 } | 372 } |
334 | 373 |
335 if (SSL_set_ex_data(sc->connection, ngx_connection_index, c) == 0) { | 374 if (SSL_set_ex_data(sc->connection, ngx_ssl_connection_index, c) == 0) { |
336 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed"); | 375 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed"); |
337 return NGX_ERROR; | 376 return NGX_ERROR; |
338 } | 377 } |
339 | 378 |
340 c->ssl = sc; | 379 c->ssl = sc; |
1012 | 1051 |
1013 if (ev->timedout) { | 1052 if (ev->timedout) { |
1014 c->timedout = 1; | 1053 c->timedout = 1; |
1015 } | 1054 } |
1016 | 1055 |
1017 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, "SSL shutdown handler"); | 1056 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "SSL shutdown handler"); |
1018 | 1057 |
1019 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | 1058 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { |
1020 return; | 1059 return; |
1021 } | 1060 } |
1022 | 1061 |
1098 | 1137 |
1099 ngx_log_error(level, log, err, "%s)", errstr); | 1138 ngx_log_error(level, log, err, "%s)", errstr); |
1100 } | 1139 } |
1101 | 1140 |
1102 | 1141 |
1142 ngx_int_t | |
1143 ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx, | |
1144 ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout) | |
1145 { | |
1146 long cache_mode; | |
1147 | |
1148 cache_mode = SSL_SESS_CACHE_SERVER; | |
1149 | |
1150 if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) { | |
1151 cache_mode |= SSL_SESS_CACHE_NO_INTERNAL; | |
1152 } | |
1153 | |
1154 SSL_CTX_set_session_cache_mode(ssl->ctx, cache_mode); | |
1155 | |
1156 SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len); | |
1157 | |
1158 if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) { | |
1159 | |
1160 if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) { | |
1161 SSL_CTX_sess_set_cache_size(ssl->ctx, builtin_session_cache); | |
1162 } | |
1163 | |
1164 SSL_CTX_set_timeout(ssl->ctx, timeout); | |
1165 } | |
1166 | |
1167 if (shm_zone) { | |
1168 shm_zone->init = ngx_ssl_session_cache_init; | |
1169 | |
1170 SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_session); | |
1171 SSL_CTX_sess_set_get_cb(ssl->ctx, ngx_ssl_get_cached_session); | |
1172 SSL_CTX_sess_set_remove_cb(ssl->ctx, ngx_ssl_remove_session); | |
1173 | |
1174 if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_cache_index, shm_zone) | |
1175 == 0) | |
1176 { | |
1177 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, | |
1178 "SSL_CTX_set_ex_data() failed"); | |
1179 return NGX_ERROR; | |
1180 } | |
1181 } | |
1182 | |
1183 return NGX_OK; | |
1184 } | |
1185 | |
1186 | |
1187 static ngx_int_t | |
1188 ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data) | |
1189 { | |
1190 ngx_slab_pool_t *shpool; | |
1191 ngx_rbtree_node_t *sentinel; | |
1192 ngx_ssl_session_cache_t *cache; | |
1193 | |
1194 if (data) { | |
1195 shm_zone->data = data; | |
1196 return NGX_OK; | |
1197 } | |
1198 | |
1199 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; | |
1200 | |
1201 cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t)); | |
1202 if (cache == NULL) { | |
1203 return NGX_ERROR; | |
1204 } | |
1205 | |
1206 cache->session_cache_head.prev = NULL; | |
1207 cache->session_cache_head.next = &cache->session_cache_tail; | |
1208 | |
1209 cache->session_cache_tail.prev = &cache->session_cache_head; | |
1210 cache->session_cache_tail.next = NULL; | |
1211 | |
1212 cache->session_rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t)); | |
1213 if (cache->session_rbtree == NULL) { | |
1214 return NGX_ERROR; | |
1215 } | |
1216 | |
1217 sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t)); | |
1218 if (sentinel == NULL) { | |
1219 return NGX_ERROR; | |
1220 } | |
1221 | |
1222 ngx_rbtree_sentinel_init(sentinel); | |
1223 | |
1224 cache->session_rbtree->root = sentinel; | |
1225 cache->session_rbtree->sentinel = sentinel; | |
1226 cache->session_rbtree->insert = ngx_rbtree_insert_value; | |
1227 | |
1228 shm_zone->data = cache; | |
1229 | |
1230 return NGX_OK; | |
1231 } | |
1232 | |
1233 | |
1234 /* | |
1235 * OpenSSL's i2d_SSL_SESSION() and d2i_SSL_SESSION are slow, | |
1236 * so they are outside the code locked by shared pool mutex | |
1237 */ | |
1238 | |
1239 static int | |
1240 ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess) | |
1241 { | |
1242 int len; | |
1243 u_char *p, *id; | |
1244 uint32_t hash; | |
1245 SSL_CTX *ssl_ctx; | |
1246 ngx_time_t *tp; | |
1247 ngx_shm_zone_t *shm_zone; | |
1248 ngx_connection_t *c; | |
1249 ngx_slab_pool_t *shpool; | |
1250 ngx_ssl_sess_id_t *sess_id; | |
1251 ngx_ssl_cached_sess_t *cached_sess; | |
1252 ngx_ssl_session_cache_t *cache; | |
1253 u_char buf[NGX_SSL_MAX_SESSION_SIZE]; | |
1254 | |
1255 len = i2d_SSL_SESSION(sess, NULL); | |
1256 | |
1257 /* do not cache too big session */ | |
1258 | |
1259 if (len > (int) NGX_SSL_MAX_SESSION_SIZE) { | |
1260 return 0; | |
1261 } | |
1262 | |
1263 p = buf; | |
1264 i2d_SSL_SESSION(sess, &p); | |
1265 | |
1266 c = ngx_ssl_get_connection(ssl_conn); | |
1267 | |
1268 ssl_ctx = SSL_get_SSL_CTX(ssl_conn); | |
1269 shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index); | |
1270 | |
1271 cache = shm_zone->data; | |
1272 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; | |
1273 | |
1274 ngx_shmtx_lock(&shpool->mutex); | |
1275 | |
1276 /* drop one or two expired sessions */ | |
1277 ngx_ssl_expire_sessions(cache, shpool, 1); | |
1278 | |
1279 cached_sess = ngx_slab_alloc_locked(shpool, | |
1280 offsetof(ngx_ssl_cached_sess_t, asn1) + len); | |
1281 | |
1282 if (cached_sess == NULL) { | |
1283 | |
1284 /* drop the oldest non-expired session and try once more */ | |
1285 | |
1286 ngx_ssl_expire_sessions(cache, shpool, 0); | |
1287 | |
1288 cached_sess = ngx_slab_alloc_locked(shpool, | |
1289 offsetof(ngx_ssl_cached_sess_t, asn1) + len); | |
1290 | |
1291 if (cached_sess == NULL) { | |
1292 id = NULL; | |
1293 goto failed; | |
1294 } | |
1295 } | |
1296 | |
1297 id = ngx_slab_alloc_locked(shpool, sess->session_id_length); | |
1298 if (id == NULL) { | |
1299 goto failed; | |
1300 } | |
1301 | |
1302 sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t)); | |
1303 if (sess_id == NULL) { | |
1304 goto failed; | |
1305 } | |
1306 | |
1307 ngx_memcpy(&cached_sess->asn1[0], buf, len); | |
1308 | |
1309 ngx_memcpy(id, sess->session_id, sess->session_id_length); | |
1310 | |
1311 hash = ngx_crc32_short(sess->session_id, sess->session_id_length); | |
1312 | |
1313 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1314 "http ssl new session: %08XD:%d:%d", | |
1315 hash, sess->session_id_length, len); | |
1316 | |
1317 sess_id->node.key = hash; | |
1318 sess_id->node.data = (u_char) sess->session_id_length; | |
1319 sess_id->id = id; | |
1320 sess_id->len = len; | |
1321 sess_id->session = cached_sess; | |
1322 | |
1323 tp = ngx_timeofday(); | |
1324 | |
1325 cached_sess->expire = tp->sec + SSL_CTX_get_timeout(ssl_ctx); | |
1326 cached_sess->sess_id = sess_id; | |
1327 | |
1328 cached_sess->next = cache->session_cache_head.next; | |
1329 cached_sess->next->prev = cached_sess; | |
1330 cached_sess->prev = &cache->session_cache_head; | |
1331 cache->session_cache_head.next = cached_sess; | |
1332 | |
1333 ngx_rbtree_insert(cache->session_rbtree, &sess_id->node); | |
1334 | |
1335 ngx_shmtx_unlock(&shpool->mutex); | |
1336 | |
1337 return 0; | |
1338 | |
1339 failed: | |
1340 | |
1341 if (cached_sess) { | |
1342 ngx_slab_free_locked(shpool, cached_sess); | |
1343 } | |
1344 | |
1345 if (id) { | |
1346 ngx_slab_free_locked(shpool, id); | |
1347 } | |
1348 | |
1349 ngx_shmtx_unlock(&shpool->mutex); | |
1350 | |
1351 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | |
1352 "could not add new SSL session to the session cache"); | |
1353 | |
1354 return 0; | |
1355 } | |
1356 | |
1357 | |
1358 static ngx_ssl_session_t * | |
1359 ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len, | |
1360 int *copy) | |
1361 { | |
1362 #if OPENSSL_VERSION_NUMBER >= 0x0090707fL | |
1363 const | |
1364 #endif | |
1365 u_char *p; | |
1366 uint32_t hash; | |
1367 ngx_time_t *tp; | |
1368 ngx_shm_zone_t *shm_zone; | |
1369 ngx_slab_pool_t *shpool; | |
1370 ngx_connection_t *c; | |
1371 ngx_rbtree_node_t *node, *sentinel; | |
1372 ngx_ssl_session_t *sess; | |
1373 ngx_ssl_sess_id_t *sess_id; | |
1374 ngx_ssl_cached_sess_t *cached_sess; | |
1375 ngx_ssl_session_cache_t *cache; | |
1376 u_char buf[NGX_SSL_MAX_SESSION_SIZE]; | |
1377 | |
1378 c = ngx_ssl_get_connection(ssl_conn); | |
1379 | |
1380 hash = ngx_crc32_short(id, len); | |
1381 *copy = 0; | |
1382 | |
1383 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1384 "http ssl get session: %08XD:%d", hash, len); | |
1385 | |
1386 shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn), | |
1387 ngx_ssl_session_cache_index); | |
1388 | |
1389 cache = shm_zone->data; | |
1390 | |
1391 if (cache->session_rbtree == NULL) { | |
1392 return NULL; | |
1393 } | |
1394 | |
1395 sess = NULL; | |
1396 | |
1397 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; | |
1398 | |
1399 ngx_shmtx_lock(&shpool->mutex); | |
1400 | |
1401 node = cache->session_rbtree->root; | |
1402 sentinel = cache->session_rbtree->sentinel; | |
1403 | |
1404 while (node != sentinel) { | |
1405 | |
1406 if (hash < node->key) { | |
1407 node = node->left; | |
1408 continue; | |
1409 } | |
1410 | |
1411 if (hash > node->key) { | |
1412 node = node->right; | |
1413 continue; | |
1414 } | |
1415 | |
1416 if (hash == node->key && (u_char) len == node->data) { | |
1417 sess_id = (ngx_ssl_sess_id_t *) node; | |
1418 | |
1419 if (ngx_strncmp(id, sess_id->id, len) == 0) { | |
1420 | |
1421 cached_sess = sess_id->session; | |
1422 | |
1423 tp = ngx_timeofday(); | |
1424 | |
1425 if (cached_sess->expire > tp->sec) { | |
1426 ngx_memcpy(buf, &cached_sess->asn1[0], sess_id->len); | |
1427 | |
1428 ngx_shmtx_unlock(&shpool->mutex); | |
1429 | |
1430 p = buf; | |
1431 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len); | |
1432 | |
1433 return sess; | |
1434 } | |
1435 | |
1436 cached_sess->next->prev = cached_sess->prev; | |
1437 cached_sess->prev->next = cached_sess->next; | |
1438 | |
1439 ngx_rbtree_delete(cache->session_rbtree, node); | |
1440 | |
1441 ngx_slab_free_locked(shpool, cached_sess); | |
1442 ngx_slab_free_locked(shpool, sess_id->id); | |
1443 ngx_slab_free_locked(shpool, sess_id); | |
1444 | |
1445 sess = NULL; | |
1446 | |
1447 break; | |
1448 } | |
1449 } | |
1450 | |
1451 node = node->right; | |
1452 } | |
1453 | |
1454 ngx_shmtx_unlock(&shpool->mutex); | |
1455 | |
1456 return sess; | |
1457 } | |
1458 | |
1459 | |
1460 static void | |
1461 ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess) | |
1462 { | |
1463 u_char *id, len; | |
1464 uint32_t hash; | |
1465 ngx_shm_zone_t *shm_zone; | |
1466 ngx_slab_pool_t *shpool; | |
1467 ngx_rbtree_node_t *node, *sentinel; | |
1468 ngx_ssl_sess_id_t *sess_id; | |
1469 ngx_ssl_cached_sess_t *cached_sess; | |
1470 ngx_ssl_session_cache_t *cache; | |
1471 | |
1472 shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index); | |
1473 | |
1474 cache = shm_zone->data; | |
1475 | |
1476 id = sess->session_id; | |
1477 len = (u_char) sess->session_id_length; | |
1478 | |
1479 hash = ngx_crc32_short(id, (size_t) len); | |
1480 | |
1481 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, | |
1482 "http ssl remove session: %08XD:%d", hash, len); | |
1483 | |
1484 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; | |
1485 | |
1486 ngx_shmtx_lock(&shpool->mutex); | |
1487 | |
1488 node = cache->session_rbtree->root; | |
1489 sentinel = cache->session_rbtree->sentinel; | |
1490 | |
1491 while (node != sentinel) { | |
1492 | |
1493 if (hash < node->key) { | |
1494 node = node->left; | |
1495 continue; | |
1496 } | |
1497 | |
1498 if (hash > node->key) { | |
1499 node = node->right; | |
1500 continue; | |
1501 } | |
1502 | |
1503 if (hash == node->key && len == node->data) { | |
1504 sess_id = (ngx_ssl_sess_id_t *) node; | |
1505 | |
1506 if (ngx_strncmp(id, sess_id->id, (size_t) len) == 0) { | |
1507 | |
1508 cached_sess = sess_id->session; | |
1509 | |
1510 cached_sess->next->prev = cached_sess->prev; | |
1511 cached_sess->prev->next = cached_sess->next; | |
1512 | |
1513 ngx_rbtree_delete(cache->session_rbtree, node); | |
1514 | |
1515 ngx_slab_free_locked(shpool, cached_sess); | |
1516 ngx_slab_free_locked(shpool, sess_id->id); | |
1517 ngx_slab_free_locked(shpool, sess_id); | |
1518 | |
1519 break; | |
1520 } | |
1521 } | |
1522 | |
1523 node = node->right; | |
1524 } | |
1525 | |
1526 ngx_shmtx_unlock(&shpool->mutex); | |
1527 } | |
1528 | |
1529 | |
1530 static void | |
1531 ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache, | |
1532 ngx_slab_pool_t *shpool, ngx_uint_t n) | |
1533 { | |
1534 ngx_time_t *tp; | |
1535 ngx_ssl_sess_id_t *sess_id; | |
1536 ngx_ssl_cached_sess_t *sess; | |
1537 | |
1538 tp = ngx_timeofday(); | |
1539 | |
1540 while (n < 3) { | |
1541 | |
1542 sess = cache->session_cache_tail.prev; | |
1543 | |
1544 if (sess == &cache->session_cache_head) { | |
1545 return; | |
1546 } | |
1547 | |
1548 if (n++ != 0 && sess->expire > tp->sec) { | |
1549 break; | |
1550 } | |
1551 | |
1552 sess->next->prev = sess->prev; | |
1553 sess->prev->next = sess->next; | |
1554 | |
1555 sess_id = sess->sess_id; | |
1556 | |
1557 ngx_rbtree_delete(cache->session_rbtree, &sess_id->node); | |
1558 | |
1559 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, | |
1560 "expire session: %08Xi", sess_id->node.key); | |
1561 | |
1562 ngx_slab_free_locked(shpool, sess); | |
1563 ngx_slab_free_locked(shpool, sess_id->id); | |
1564 ngx_slab_free_locked(shpool, sess_id); | |
1565 } | |
1566 } | |
1567 | |
1568 | |
1103 void | 1569 void |
1104 ngx_ssl_cleanup_ctx(void *data) | 1570 ngx_ssl_cleanup_ctx(void *data) |
1105 { | 1571 { |
1106 ngx_ssl_t *ssl = data; | 1572 ngx_ssl_t *ssl = data; |
1107 | 1573 |