564 changes: 390 additions & 174 deletions src/event/ngx_event_openssl.c

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion src/event/ngx_event_openssl.h
Expand Up @@ -49,6 +49,14 @@ typedef struct {
} ngx_ssl_connection_t;


typedef struct {
ngx_shm_zone_t *shm_zone;
ngx_str_t memcache_name;
ngx_str_t memcache_host;
ngx_int_t memcache_port;
} ngx_ssl_session_cache_cfg_t;


#define NGX_SSL_NO_SCACHE -2
#define NGX_SSL_NONE_SCACHE -3
#define NGX_SSL_NO_BUILTIN_SCACHE -4
Expand Down Expand Up @@ -102,7 +110,7 @@ ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl);
ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout);
ssize_t builtin_session_cache, ngx_ssl_session_cache_cfg_t *sc_cfg, time_t timeout);
ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
ngx_uint_t flags);

Expand Down
115 changes: 100 additions & 15 deletions src/http/modules/ngx_http_ssl_module.c
Expand Up @@ -8,7 +8,6 @@
#include <ngx_core.h>
#include <ngx_http.h>


typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
ngx_pool_t *pool, ngx_str_t *s);

Expand Down Expand Up @@ -315,7 +314,10 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
* sscf->client_certificate = { 0, NULL };
* sscf->crl = { 0, NULL };
* sscf->ciphers = { 0, NULL };
* sscf->shm_zone = NULL;
* sscf->ext_session_cache.shm_zone = NULL;
* sscf->ext_session_cache.memcache_name = { 0, NULL };
* sscf->ext_session_cache.memcache_host = { 0, NULL };
* sscf->ext_session_cache.memcache_port = 0;
*/

sscf->enable = NGX_CONF_UNSET;
Expand Down Expand Up @@ -476,13 +478,26 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->builtin_session_cache,
prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);

if (conf->shm_zone == NULL) {
conf->shm_zone = prev->shm_zone;
if (conf->ext_session_cache.shm_zone == NULL) {
conf->ext_session_cache.shm_zone = prev->ext_session_cache.shm_zone;
}

#ifdef MEMCACHE_SSL_SESSION_STORE
if (conf->ext_session_cache.memcache_name.len == 0) {
/* None of these can have been set without memcache_name being set to
* something, and if memcache_name has been set to something, then
* all of these will have been set to the correct values
*/
conf->ext_session_cache.memcache_name = prev->ext_session_cache.memcache_name;
conf->ext_session_cache.memcache_host = prev->ext_session_cache.memcache_host;
conf->ext_session_cache.memcache_port = prev->ext_session_cache.memcache_port;
}
#endif

if (ngx_ssl_session_cache(&conf->ssl, &ngx_http_ssl_sess_id_ctx,
conf->builtin_session_cache,
conf->shm_zone, conf->session_timeout)
&conf->ext_session_cache,
conf->session_timeout)
!= NGX_OK)
{
return NGX_CONF_ERROR;
Expand Down Expand Up @@ -518,7 +533,7 @@ ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_ssl_srv_conf_t *sscf = conf;

size_t len;
ngx_str_t *value, name, size;
ngx_str_t *value, shm_name, shm_size;
ngx_int_t n;
ngx_uint_t i, j;

Expand Down Expand Up @@ -576,13 +591,13 @@ ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
goto invalid;
}

name.len = len;
name.data = value[i].data + sizeof("shared:") - 1;
shm_name.len = len;
shm_name.data = value[i].data + sizeof("shared:") - 1;

size.len = value[i].len - j - 1;
size.data = name.data + len + 1;
shm_size.len = value[i].len - j - 1;
shm_size.data = shm_name.data + len + 1;

n = ngx_parse_size(&size);
n = ngx_parse_size(&shm_size);

if (n == NGX_ERROR) {
goto invalid;
Expand All @@ -596,19 +611,89 @@ ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}

sscf->shm_zone = ngx_shared_memory_add(cf, &name, n,
&ngx_http_ssl_module);
if (sscf->shm_zone == NULL) {
sscf->ext_session_cache.shm_zone =
ngx_shared_memory_add(cf, &shm_name, n,
&ngx_http_ssl_module);
if (sscf->ext_session_cache.shm_zone == NULL) {
return NGX_CONF_ERROR;
}

continue;
}

#ifdef MEMCACHE_SSL_SESSION_STORE
if (value[i].len > sizeof("memcached:") - 1
&& ngx_strncmp(value[i].data, "memcached:", sizeof("memcached:") - 1)
== 0)
{
/* total_len is the current offset into the value[i] string as a
* whole; len is the length of the current element */
size_t total_len = sizeof("memcached:") - 1;
len = 0;

for (j = total_len; j < value[i].len; j++) {
total_len++;
if (value[i].data[j] == ':') {
value[i].data[j] = '\0';
break;
}

len++;
}

if (len == 0) {
goto invalid;
}

sscf->ext_session_cache.memcache_name.len = len;
sscf->ext_session_cache.memcache_name.data = value[i].data + sizeof("memcached:") - 1;

ngx_log_error_core(NGX_LOG_DEBUG, cf->log, 0,
"memcache_name parsed as %V",
&sscf->ext_session_cache.memcache_name);

if (value[i].len > total_len) {
/* We have a host */
len = 0;
for (j = total_len; j < value[i].len; j++) {
if (value[i].data[j] == ':') {
value[i].data[j] = '\0';
break;
}
total_len++;
len++;
}

sscf->ext_session_cache.memcache_host.len = len;
sscf->ext_session_cache.memcache_host.data = value[i].data + total_len - len;

ngx_log_error_core(NGX_LOG_DEBUG, cf->log, 0,
"memcache_host parsed as %V (%d)",
&sscf->ext_session_cache.memcache_host, len);

/* Skip over ':' */
total_len++;
}

if (value[i].len > total_len) {
/* Wow, we even have a port */
sscf->ext_session_cache.memcache_port = ngx_atoi(value[i].data + total_len, value[i].len - total_len);

ngx_log_error_core(NGX_LOG_DEBUG, cf->log, 0,
"memcache_port parsed as %i",
sscf->ext_session_cache.memcache_port);
}

continue;
}
#endif

goto invalid;
}

if (sscf->shm_zone && sscf->builtin_session_cache == NGX_CONF_UNSET) {
if ((sscf->ext_session_cache.shm_zone
|| sscf->ext_session_cache.memcache_name.len > 0)
&& sscf->builtin_session_cache == NGX_CONF_UNSET) {
sscf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
}

Expand Down
2 changes: 1 addition & 1 deletion src/http/modules/ngx_http_ssl_module.h
Expand Up @@ -37,7 +37,7 @@ typedef struct {

ngx_str_t ciphers;

ngx_shm_zone_t *shm_zone;
ngx_ssl_session_cache_cfg_t ext_session_cache;

u_char *file;
ngx_uint_t line;
Expand Down