comparison src/http/modules/ngx_http_ssl_module.c @ 973:e1ede83911ef

ssl_session_cache
author Igor Sysoev <igor@sysoev.ru>
date Tue, 02 Jan 2007 23:55:05 +0000
parents 948acd940145
children 8dfb3aa75de2
comparison
equal deleted inserted replaced
972:6e7a20529f53 973:e1ede83911ef
15 15
16 #define NGX_DEFLAUT_CERTIFICATE "cert.pem" 16 #define NGX_DEFLAUT_CERTIFICATE "cert.pem"
17 #define NGX_DEFLAUT_CERTIFICATE_KEY "cert.pem" 17 #define NGX_DEFLAUT_CERTIFICATE_KEY "cert.pem"
18 #define NGX_DEFLAUT_CIPHERS "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP" 18 #define NGX_DEFLAUT_CIPHERS "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
19 19
20
21 #define NGX_HTTP_SSL_MAX_SESSION_SIZE \
22 (4096 - offsetof(ngx_http_ssl_cached_sess_t, asn1))
23
24
25 #define NGX_HTTP_SSL_DFLT_BUILTIN_SCACHE -2
26 #define NGX_HTTP_SSL_NO_BUILTIN_SCACHE -3
27
28
29 static void ngx_http_ssl_expire_sessions(ngx_http_ssl_sesssion_cache_t *cache,
30 ngx_slab_pool_t *shpool, ngx_uint_t expire);
20 31
21 static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r, 32 static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
22 ngx_http_variable_value_t *v, uintptr_t data); 33 ngx_http_variable_value_t *v, uintptr_t data);
23 static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r, 34 static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r,
24 ngx_http_variable_value_t *v, uintptr_t data); 35 ngx_http_variable_value_t *v, uintptr_t data);
25 36
26 static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf); 37 static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf);
27 static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf); 38 static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf);
28 static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, 39 static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf,
29 void *parent, void *child); 40 void *parent, void *child);
41
42 static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
43 void *conf);
30 44
31 #if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE) 45 #if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
32 46
33 static char *ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, 47 static char *ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd,
34 void *conf); 48 void *conf);
112 offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers), 126 offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers),
113 NULL }, 127 NULL },
114 #else 128 #else
115 ngx_http_ssl_nosupported, 0, 0, ngx_http_ssl_openssl097 }, 129 ngx_http_ssl_nosupported, 0, 0, ngx_http_ssl_openssl097 },
116 #endif 130 #endif
131
132 { ngx_string("ssl_session_cache"),
133 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12,
134 ngx_http_ssl_session_cache,
135 NGX_HTTP_SRV_CONF_OFFSET,
136 0,
137 NULL },
117 138
118 { ngx_string("ssl_session_timeout"), 139 { ngx_string("ssl_session_timeout"),
119 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, 140 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
120 ngx_conf_set_sec_slot, 141 ngx_conf_set_sec_slot,
121 NGX_HTTP_SRV_CONF_OFFSET, 142 NGX_HTTP_SRV_CONF_OFFSET,
180 201
181 static u_char ngx_http_session_id_ctx[] = "HTTP"; 202 static u_char ngx_http_session_id_ctx[] = "HTTP";
182 203
183 204
184 static ngx_int_t 205 static ngx_int_t
206 ngx_http_ssl_session_cache_init(ngx_shm_zone_t *shm_zone)
207 {
208 ngx_slab_pool_t *shpool;
209 ngx_rbtree_node_t *sentinel;
210 ngx_http_ssl_sesssion_cache_t *cache;
211
212 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
213
214 cache = ngx_slab_alloc(shpool, sizeof(ngx_http_ssl_sesssion_cache_t));
215 if (cache == NULL) {
216 return NGX_ERROR;
217 }
218
219 cache->session_cache_head.prev = NULL;
220 cache->session_cache_head.next = &cache->session_cache_tail;
221
222 cache->session_cache_tail.prev = &cache->session_cache_head;
223 cache->session_cache_tail.next = NULL;
224
225 cache->session_rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t));
226 if (cache->session_rbtree == NULL) {
227 return NGX_ERROR;
228 }
229
230 sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t));
231 if (sentinel == NULL) {
232 return NGX_ERROR;
233 }
234
235 ngx_rbtree_sentinel_init(sentinel);
236
237 cache->session_rbtree->root = sentinel;
238 cache->session_rbtree->sentinel = sentinel;
239 cache->session_rbtree->insert = ngx_rbtree_insert_value;
240
241 shm_zone->data = cache;
242
243 return NGX_OK;
244 }
245
246
247 /*
248 * OpenSSL's i2d_SSL_SESSION() and d2i_SSL_SESSION are slow,
249 * so they are outside the code locked by shared pool mutex
250 */
251
252 static int
253 ngx_http_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
254 {
255 int len;
256 u_char *p, *id;
257 uint32_t hash;
258 ngx_time_t *tp;
259 ngx_slab_pool_t *shpool;
260 ngx_connection_t *c;
261 ngx_http_request_t *r;
262 ngx_http_ssl_sess_id_t *sess_id;
263 ngx_http_ssl_srv_conf_t *sscf;
264 ngx_http_ssl_cached_sess_t *cached_sess;
265 ngx_http_ssl_sesssion_cache_t *cache;
266 u_char buf[NGX_HTTP_SSL_MAX_SESSION_SIZE];
267
268 len = i2d_SSL_SESSION(sess, NULL);
269
270 /* do not cache too big session */
271
272 if (len > (int) NGX_HTTP_SSL_MAX_SESSION_SIZE) {
273 return 0;
274 }
275
276 c = ngx_ssl_get_connection(ssl_conn);
277 r = c->data;
278
279 p = buf;
280 i2d_SSL_SESSION(sess, &p);
281
282 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
283
284 cache = sscf->shm_zone->data;
285 shpool = (ngx_slab_pool_t *) sscf->shm_zone->shm.addr;
286
287 ngx_shmtx_lock(&shpool->mutex);
288
289 /* drop one or two expired sessions */
290 ngx_http_ssl_expire_sessions(cache, shpool, 1);
291
292 cached_sess = ngx_slab_alloc_locked(shpool,
293 offsetof(ngx_http_ssl_cached_sess_t, asn1) + len);
294
295 if (cached_sess == NULL) {
296
297 /* drop the oldest non-expired session and try once more */
298
299 ngx_http_ssl_expire_sessions(cache, shpool, 0);
300
301 cached_sess = ngx_slab_alloc_locked(shpool,
302 offsetof(ngx_http_ssl_cached_sess_t, asn1) + len);
303
304 if (cached_sess == NULL) {
305 id = NULL;
306 goto failed;
307 }
308 }
309
310 id = ngx_slab_alloc_locked(shpool, sess->session_id_length);
311 if (id == NULL) {
312 goto failed;
313 }
314
315 sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_http_ssl_sess_id_t));
316 if (sess_id == NULL) {
317 goto failed;
318 }
319
320 ngx_memcpy(&cached_sess->asn1[0], buf, len);
321
322 ngx_memcpy(id, sess->session_id, sess->session_id_length);
323
324 hash = ngx_crc32_short(sess->session_id, sess->session_id_length);
325
326 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
327 "http ssl new session: %08XD:%d:%d",
328 hash, sess->session_id_length, len);
329
330 sess_id->node.key = hash;
331 sess_id->node.data = (u_char) sess->session_id_length;
332 sess_id->id = id;
333 sess_id->len = len;
334 sess_id->session = cached_sess;
335
336 tp = ngx_timeofday();
337
338 cached_sess->expire = tp->sec + sscf->session_timeout;
339 cached_sess->sess_id = sess_id;
340
341 cached_sess->next = cache->session_cache_head.next;
342 cached_sess->next->prev = cached_sess;
343 cached_sess->prev = &cache->session_cache_head;
344 cache->session_cache_head.next = cached_sess;
345
346 ngx_rbtree_insert(cache->session_rbtree, &sess_id->node);
347
348 ngx_shmtx_unlock(&shpool->mutex);
349
350 return 0;
351
352 failed:
353
354 if (cached_sess) {
355 ngx_slab_free_locked(shpool, cached_sess);
356 }
357
358 if (id) {
359 ngx_slab_free_locked(shpool, id);
360 }
361
362 ngx_shmtx_unlock(&shpool->mutex);
363
364 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
365 "could not add new SSL session to the session cache");
366
367 return 0;
368 }
369
370
371 static ngx_ssl_session_t *
372 ngx_http_ssl_get_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
373 int *copy)
374 {
375 #if OPENSSL_VERSION_NUMBER >= 0x00908000
376 const
377 #endif
378 u_char *p;
379 uint32_t hash;
380 ngx_time_t *tp;
381 ngx_slab_pool_t *shpool;
382 ngx_connection_t *c;
383 ngx_rbtree_node_t *node, *sentinel;
384 ngx_ssl_session_t *sess;
385 ngx_http_request_t *r;
386 ngx_http_ssl_sess_id_t *sess_id;
387 ngx_http_ssl_srv_conf_t *sscf;
388 ngx_http_ssl_cached_sess_t *cached_sess;
389 ngx_http_ssl_sesssion_cache_t *cache;
390 u_char buf[NGX_HTTP_SSL_MAX_SESSION_SIZE];
391
392 c = ngx_ssl_get_connection(ssl_conn);
393 r = c->data;
394
395 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
396
397 hash = ngx_crc32_short(id, len);
398 *copy = 0;
399
400 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
401 "http ssl get session: %08XD:%d", hash, len);
402
403 cache = sscf->shm_zone->data;
404
405 if (cache->session_rbtree == NULL) {
406 return NULL;
407 }
408
409 sess = NULL;
410
411 shpool = (ngx_slab_pool_t *) sscf->shm_zone->shm.addr;
412
413 ngx_shmtx_lock(&shpool->mutex);
414
415 node = cache->session_rbtree->root;
416 sentinel = cache->session_rbtree->sentinel;
417
418 while (node != sentinel) {
419
420 if (hash < node->key) {
421 node = node->left;
422 continue;
423 }
424
425 if (hash > node->key) {
426 node = node->right;
427 continue;
428 }
429
430 if (hash == node->key && (u_char) len == node->data) {
431 sess_id = (ngx_http_ssl_sess_id_t *) node;
432
433 if (ngx_strncmp(id, sess_id->id, len) == 0) {
434
435 cached_sess = sess_id->session;
436
437 tp = ngx_timeofday();
438
439 if (cached_sess->expire > tp->sec) {
440 ngx_memcpy(buf, &cached_sess->asn1[0], sess_id->len);
441
442 ngx_shmtx_unlock(&shpool->mutex);
443
444 p = buf;
445 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
446
447 return sess;
448 }
449
450 cached_sess->next->prev = cached_sess->prev;
451 cached_sess->prev->next = cached_sess->next;
452
453 ngx_rbtree_delete(cache->session_rbtree, node);
454
455 ngx_slab_free_locked(shpool, cached_sess);
456 ngx_slab_free_locked(shpool, sess_id->id);
457 ngx_slab_free_locked(shpool, sess_id);
458
459 sess = NULL;
460
461 break;
462 }
463 }
464
465 node = node->right;
466 }
467
468 ngx_shmtx_unlock(&shpool->mutex);
469
470 return sess;
471 }
472
473
474 static void
475 ngx_http_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
476 {
477 u_char *id, len;
478 uint32_t hash;
479 ngx_slab_pool_t *shpool;
480 ngx_rbtree_node_t *node, *sentinel;
481 ngx_http_ssl_sess_id_t *sess_id;
482 ngx_http_ssl_srv_conf_t *sscf;
483 ngx_http_ssl_cached_sess_t *cached_sess;
484 ngx_http_ssl_sesssion_cache_t *cache;
485
486 sscf = ngx_ssl_get_server_conf(ssl);
487
488 cache = sscf->shm_zone->data;
489
490 id = sess->session_id;
491 len = (u_char) sess->session_id_length;
492
493 hash = ngx_crc32_short(id, (size_t) len);
494
495 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
496 "http ssl remove session: %08XD:%d", hash, len);
497
498 shpool = (ngx_slab_pool_t *) sscf->shm_zone->shm.addr;
499
500 ngx_shmtx_lock(&shpool->mutex);
501
502 node = cache->session_rbtree->root;
503 sentinel = cache->session_rbtree->sentinel;
504
505 while (node != sentinel) {
506
507 if (hash < node->key) {
508 node = node->left;
509 continue;
510 }
511
512 if (hash > node->key) {
513 node = node->right;
514 continue;
515 }
516
517 if (hash == node->key && len == node->data) {
518 sess_id = (ngx_http_ssl_sess_id_t *) node;
519
520 if (ngx_strncmp(id, sess_id->id, (size_t) len) == 0) {
521
522 cached_sess = sess_id->session;
523
524 cached_sess->next->prev = cached_sess->prev;
525 cached_sess->prev->next = cached_sess->next;
526
527 ngx_rbtree_delete(cache->session_rbtree, node);
528
529 ngx_slab_free_locked(shpool, cached_sess);
530 ngx_slab_free_locked(shpool, sess_id->id);
531 ngx_slab_free_locked(shpool, sess_id);
532
533 break;
534 }
535 }
536
537 node = node->right;
538 }
539
540 ngx_shmtx_unlock(&shpool->mutex);
541 }
542
543
544 static void
545 ngx_http_ssl_expire_sessions(ngx_http_ssl_sesssion_cache_t *cache,
546 ngx_slab_pool_t *shpool, ngx_uint_t n)
547 {
548 ngx_time_t *tp;
549 ngx_http_ssl_sess_id_t *sess_id;
550 ngx_http_ssl_cached_sess_t *sess;
551
552 tp = ngx_timeofday();
553
554 while (n < 3) {
555
556 sess = cache->session_cache_tail.prev;
557
558 if (sess == &cache->session_cache_head) {
559 return;
560 }
561
562 if (n++ != 0 && sess->expire > tp->sec) {
563 break;
564 }
565
566 sess->next->prev = sess->prev;
567 sess->prev->next = sess->next;
568
569 sess_id = sess->sess_id;
570
571 ngx_rbtree_delete(cache->session_rbtree, &sess_id->node);
572
573 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
574 "expire session: %08Xi", sess_id->node.key);
575
576 ngx_slab_free_locked(shpool, sess);
577 ngx_slab_free_locked(shpool, sess_id->id);
578 ngx_slab_free_locked(shpool, sess_id);
579 }
580 }
581
582
583 static ngx_int_t
185 ngx_http_ssl_static_variable(ngx_http_request_t *r, 584 ngx_http_ssl_static_variable(ngx_http_request_t *r,
186 ngx_http_variable_value_t *v, uintptr_t data) 585 ngx_http_variable_value_t *v, uintptr_t data)
187 { 586 {
188 ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data; 587 ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
189 588
274 * sscf->certificate_key.data = NULL; 673 * sscf->certificate_key.data = NULL;
275 * sscf->client_certificate.len = 0; 674 * sscf->client_certificate.len = 0;
276 * sscf->client_certificate.data = NULL; 675 * sscf->client_certificate.data = NULL;
277 * sscf->ciphers.len = 0; 676 * sscf->ciphers.len = 0;
278 * sscf->ciphers.data = NULL; 677 * sscf->ciphers.data = NULL;
678 * sscf->shm_zone = NULL;
279 */ 679 */
280 680
281 sscf->enable = NGX_CONF_UNSET; 681 sscf->enable = NGX_CONF_UNSET;
282 sscf->session_timeout = NGX_CONF_UNSET;
283 sscf->verify = NGX_CONF_UNSET; 682 sscf->verify = NGX_CONF_UNSET;
284 sscf->verify_depth = NGX_CONF_UNSET; 683 sscf->verify_depth = NGX_CONF_UNSET;
285 sscf->prefer_server_ciphers = NGX_CONF_UNSET; 684 sscf->prefer_server_ciphers = NGX_CONF_UNSET;
685 sscf->builtin_session_cache = NGX_CONF_UNSET;
686 sscf->session_timeout = NGX_CONF_UNSET;
286 687
287 return sscf; 688 return sscf;
288 } 689 }
289 690
290 691
292 ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) 693 ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
293 { 694 {
294 ngx_http_ssl_srv_conf_t *prev = parent; 695 ngx_http_ssl_srv_conf_t *prev = parent;
295 ngx_http_ssl_srv_conf_t *conf = child; 696 ngx_http_ssl_srv_conf_t *conf = child;
296 697
698 long cache_mode;
297 ngx_pool_cleanup_t *cln; 699 ngx_pool_cleanup_t *cln;
298 700
299 ngx_conf_merge_value(conf->enable, prev->enable, 0); 701 ngx_conf_merge_value(conf->enable, prev->enable, 0);
300 702
301 if (conf->enable == 0) { 703 if (conf->enable == 0) {
378 /* a temporary 512-bit RSA key is required for export versions of MSIE */ 780 /* a temporary 512-bit RSA key is required for export versions of MSIE */
379 if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) { 781 if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) {
380 return NGX_CONF_ERROR; 782 return NGX_CONF_ERROR;
381 } 783 }
382 784
383 SSL_CTX_set_session_cache_mode(conf->ssl.ctx, SSL_SESS_CACHE_SERVER); 785 ngx_conf_merge_value(conf->builtin_session_cache,
786 prev->builtin_session_cache,
787 NGX_HTTP_SSL_DFLT_BUILTIN_SCACHE);
788
789 if (conf->shm_zone == NULL) {
790 conf->shm_zone = prev->shm_zone;
791 }
792
793 cache_mode = SSL_SESS_CACHE_SERVER;
794
795 if (conf->shm_zone
796 && conf->builtin_session_cache == NGX_HTTP_SSL_NO_BUILTIN_SCACHE)
797 {
798 cache_mode |= SSL_SESS_CACHE_NO_INTERNAL;
799 }
800
801 SSL_CTX_set_session_cache_mode(conf->ssl.ctx, cache_mode);
384 802
385 SSL_CTX_set_session_id_context(conf->ssl.ctx, ngx_http_session_id_ctx, 803 SSL_CTX_set_session_id_context(conf->ssl.ctx, ngx_http_session_id_ctx,
386 sizeof(ngx_http_session_id_ctx) - 1); 804 sizeof(ngx_http_session_id_ctx) - 1);
387 805
388 SSL_CTX_set_timeout(conf->ssl.ctx, conf->session_timeout); 806 if (conf->builtin_session_cache != NGX_HTTP_SSL_NO_BUILTIN_SCACHE) {
807
808 if (conf->builtin_session_cache != NGX_HTTP_SSL_DFLT_BUILTIN_SCACHE) {
809 SSL_CTX_sess_set_cache_size(conf->ssl.ctx,
810 conf->builtin_session_cache);
811 }
812
813 SSL_CTX_set_timeout(conf->ssl.ctx, conf->session_timeout);
814 }
815
816 if (conf->shm_zone) {
817 SSL_CTX_sess_set_new_cb(conf->ssl.ctx, ngx_http_ssl_new_session);
818 SSL_CTX_sess_set_get_cb(conf->ssl.ctx, ngx_http_ssl_get_session);
819 SSL_CTX_sess_set_remove_cb(conf->ssl.ctx, ngx_http_ssl_remove_session);
820 }
389 821
390 return NGX_CONF_OK; 822 return NGX_CONF_OK;
823 }
824
825
826 static char *
827 ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
828 {
829 ngx_http_ssl_srv_conf_t *sscf = conf;
830
831 size_t len;
832 ngx_str_t *value, name, size;
833 ngx_int_t n;
834 ngx_uint_t i, j;
835
836 value = cf->args->elts;
837
838 for (i = 1; i < cf->args->nelts; i++) {
839
840 if (ngx_strcmp(value[i].data, "builtin") == 0) {
841 sscf->builtin_session_cache = NGX_HTTP_SSL_DFLT_BUILTIN_SCACHE;
842 continue;
843 }
844
845 if (value[i].len > sizeof("builtin:") - 1
846 && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
847 == 0)
848 {
849 n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
850 value[i].len - (sizeof("builtin:") - 1));
851
852 if (n == NGX_ERROR) {
853 goto invalid;
854 }
855
856 sscf->builtin_session_cache = n;
857
858 continue;
859 }
860
861 if (value[i].len > sizeof("shared:") - 1
862 && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
863 == 0)
864 {
865 len = 0;
866
867 for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
868 if (value[i].data[j] == ':') {
869 break;
870 }
871
872 len++;
873 }
874
875 if (len == 0) {
876 goto invalid;
877 }
878
879 name.len = len;
880 name.data = value[i].data + sizeof("shared:") - 1;
881
882 size.len = value[i].len - j - 1;
883 size.data = name.data + len + 1;
884
885 n = ngx_parse_size(&size);
886
887 if (n == NGX_ERROR) {
888 goto invalid;
889 }
890
891 if (n < (ngx_int_t) (8 * ngx_pagesize)) {
892 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
893 "session cache \"%V\" to small",
894 &value[i]);
895
896 return NGX_CONF_ERROR;
897 }
898
899 sscf->shm_zone = ngx_shared_memory_add(cf, &name, n,
900 &ngx_http_ssl_module);
901 if (sscf->shm_zone == NULL) {
902 return NGX_CONF_ERROR;
903 }
904
905 sscf->shm_zone->init = ngx_http_ssl_session_cache_init;
906
907 continue;
908 }
909
910 goto invalid;
911 }
912
913 if (sscf->shm_zone && sscf->builtin_session_cache == NGX_CONF_UNSET) {
914 sscf->builtin_session_cache = NGX_HTTP_SSL_NO_BUILTIN_SCACHE;
915 }
916
917 return NGX_CONF_OK;
918
919 invalid:
920
921 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
922 "invalid session cache \"%V\"", &value[i]);
923
924 return NGX_CONF_ERROR;
391 } 925 }
392 926
393 927
394 #if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE) 928 #if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
395 929