ngx_event_openssl.c

来自「Nginx是一个高性能的HTTP和反向代理服务器」· C语言 代码 · 共 1,975 行 · 第 1/4 页

C
1,975
字号
    ngx_slab_pool_t          *shpool;    ngx_connection_t         *c;    ngx_rbtree_node_t        *node, *sentinel;    ngx_ssl_session_t        *sess;    ngx_ssl_sess_id_t        *sess_id;    ngx_ssl_session_cache_t  *cache;    u_char                    buf[NGX_SSL_MAX_SESSION_SIZE];    c = ngx_ssl_get_connection(ssl_conn);    hash = ngx_crc32_short(id, (size_t) len);    *copy = 0;    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,                   "http ssl get session: %08XD:%d", hash, len);    shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn),                                   ngx_ssl_session_cache_index);    cache = shm_zone->data;    sess = NULL;    shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;    ngx_shmtx_lock(&shpool->mutex);    node = cache->session_rbtree.root;    sentinel = cache->session_rbtree.sentinel;    while (node != sentinel) {        if (hash < node->key) {            node = node->left;            continue;        }        if (hash > node->key) {            node = node->right;            continue;        }        /* hash == node->key */        do {            sess_id = (ngx_ssl_sess_id_t *) node;            rc = ngx_memn2cmp(id, sess_id->id,                              (size_t) len, (size_t) node->data);            if (rc == 0) {                if (sess_id->expire > ngx_time()) {                    ngx_memcpy(buf, sess_id->session, sess_id->len);                    ngx_shmtx_unlock(&shpool->mutex);                    p = buf;                    sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);                    return sess;                }                ngx_queue_remove(&sess_id->queue);                ngx_rbtree_delete(&cache->session_rbtree, node);                ngx_slab_free_locked(shpool, sess_id->session);#if (NGX_PTR_SIZE == 4)                ngx_slab_free_locked(shpool, sess_id->id);#endif                ngx_slab_free_locked(shpool, sess_id);                sess = NULL;                goto done;            }            node = (rc < 0) ? node->left : node->right;        } while (node != sentinel && hash == node->key);        break;    }done:    ngx_shmtx_unlock(&shpool->mutex);    return sess;}voidngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess){     SSL_CTX_remove_session(ssl, sess);     ngx_ssl_remove_session(ssl, sess);}static voidngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess){    size_t                    len;    u_char                   *id;    uint32_t                  hash;    ngx_int_t                 rc;    ngx_shm_zone_t           *shm_zone;    ngx_slab_pool_t          *shpool;    ngx_rbtree_node_t        *node, *sentinel;    ngx_ssl_sess_id_t        *sess_id;    ngx_ssl_session_cache_t  *cache;    shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index);    if (shm_zone == NULL) {        return;    }    cache = shm_zone->data;    id = sess->session_id;    len = (size_t) sess->session_id_length;    hash = ngx_crc32_short(id, len);    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,                   "http ssl remove session: %08XD:%uz", hash, len);    shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;    ngx_shmtx_lock(&shpool->mutex);    node = cache->session_rbtree.root;    sentinel = cache->session_rbtree.sentinel;    while (node != sentinel) {        if (hash < node->key) {            node = node->left;            continue;        }        if (hash > node->key) {            node = node->right;            continue;        }        /* hash == node->key */        do {            sess_id = (ngx_ssl_sess_id_t *) node;            rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);            if (rc == 0) {                ngx_queue_remove(&sess_id->queue);                ngx_rbtree_delete(&cache->session_rbtree, node);                ngx_slab_free_locked(shpool, sess_id->session);#if (NGX_PTR_SIZE == 4)                ngx_slab_free_locked(shpool, sess_id->id);#endif                ngx_slab_free_locked(shpool, sess_id);                goto done;            }            node = (rc < 0) ? node->left : node->right;        } while (node != sentinel && hash == node->key);        break;    }done:    ngx_shmtx_unlock(&shpool->mutex);}static voidngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,    ngx_slab_pool_t *shpool, ngx_uint_t n){    time_t              now;    ngx_queue_t        *q;    ngx_ssl_sess_id_t  *sess_id;    now = ngx_time();    while (n < 3) {        if (ngx_queue_empty(&cache->expire_queue)) {            return;        }        q = ngx_queue_last(&cache->expire_queue);        sess_id = ngx_queue_data(q, ngx_ssl_sess_id_t, queue);        if (n++ != 0 && sess_id->expire > now) {            return;        }        ngx_queue_remove(q);        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,                       "expire session: %08Xi", sess_id->node.key);        ngx_rbtree_delete(&cache->session_rbtree, &sess_id->node);        ngx_slab_free_locked(shpool, sess_id->session);#if (NGX_PTR_SIZE == 4)        ngx_slab_free_locked(shpool, sess_id->id);#endif        ngx_slab_free_locked(shpool, sess_id);    }}static voidngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,    ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel){    ngx_rbtree_node_t  **p;    ngx_ssl_sess_id_t   *sess_id, *sess_id_temp;    for ( ;; ) {        if (node->key < temp->key) {            p = &temp->left;        } else if (node->key > temp->key) {            p = &temp->right;        } else { /* node->key == temp->key */            sess_id = (ngx_ssl_sess_id_t *) node;            sess_id_temp = (ngx_ssl_sess_id_t *) temp;            p = (ngx_memn2cmp(sess_id->id, sess_id_temp->id,                              (size_t) node->data, (size_t) temp->data)                 < 0) ? &temp->left : &temp->right;        }        if (*p == sentinel) {            break;        }        temp = *p;    }    *p = node;    node->parent = temp;    node->left = sentinel;    node->right = sentinel;    ngx_rbt_red(node);}voidngx_ssl_cleanup_ctx(void *data){    ngx_ssl_t  *ssl = data;    SSL_CTX_free(ssl->ctx);}ngx_int_tngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s){    s->data = (u_char *) SSL_get_version(c->ssl->connection);    return NGX_OK;}ngx_int_tngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s){    s->data = (u_char *) SSL_get_cipher_name(c->ssl->connection);    return NGX_OK;}ngx_int_tngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s){    char       *p;    size_t      len;    X509       *cert;    X509_NAME  *name;    s->len = 0;    cert = SSL_get_peer_certificate(c->ssl->connection);    if (cert == NULL) {        return NGX_OK;    }    name = X509_get_subject_name(cert);    if (name == NULL) {        X509_free(cert);        return NGX_ERROR;    }    p = X509_NAME_oneline(name, NULL, 0);    for (len = 0; p[len]; len++) { /* void */ }    s->len = len;    s->data = ngx_palloc(pool, len);    if (s->data == NULL) {        OPENSSL_free(p);        X509_free(cert);        return NGX_ERROR;    }    ngx_memcpy(s->data, p, len);    OPENSSL_free(p);    X509_free(cert);    return NGX_OK;}ngx_int_tngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s){    char       *p;    size_t      len;    X509       *cert;    X509_NAME  *name;    s->len = 0;    cert = SSL_get_peer_certificate(c->ssl->connection);    if (cert == NULL) {        return NGX_OK;    }    name = X509_get_issuer_name(cert);    if (name == NULL) {        X509_free(cert);        return NGX_ERROR;    }    p = X509_NAME_oneline(name, NULL, 0);    for (len = 0; p[len]; len++) { /* void */ }    s->len = len;    s->data = ngx_palloc(pool, len);    if (s->data == NULL) {        OPENSSL_free(p);        X509_free(cert);        return NGX_ERROR;    }    ngx_memcpy(s->data, p, len);    OPENSSL_free(p);    X509_free(cert);    return NGX_OK;}ngx_int_tngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s){    size_t   len;    X509    *cert;    BIO     *bio;    s->len = 0;    cert = SSL_get_peer_certificate(c->ssl->connection);    if (cert == NULL) {        return NGX_OK;    }    bio = BIO_new(BIO_s_mem());    if (bio == NULL) {        X509_free(cert);        return NGX_ERROR;    }    i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert));    len = BIO_pending(bio);    s->len = len;    s->data = ngx_palloc(pool, len);    if (s->data == NULL) {        BIO_free(bio);        X509_free(cert);        return NGX_ERROR;    }    BIO_read(bio, s->data, len);    BIO_free(bio);    X509_free(cert);    return NGX_OK;}static void *ngx_openssl_create_conf(ngx_cycle_t *cycle){    ngx_openssl_conf_t  *oscf;    oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t));    if (oscf == NULL) {        return NGX_CONF_ERROR;    }    /*     * set by ngx_pcalloc():     *     *     oscf->engine.len = 0;     *     oscf->engine.data = NULL;     */    return oscf;}static char *ngx_openssl_init_conf(ngx_cycle_t *cycle, void *conf){#if (NGX_SSL_ENGINE)    ngx_openssl_conf_t *oscf = conf;    ENGINE  *engine;    if (oscf->engine.len == 0) {        return NGX_CONF_OK;    }    engine = ENGINE_by_id((const char *) oscf->engine.data);    if (engine == NULL) {        ngx_ssl_error(NGX_LOG_WARN, cycle->log, 0,                      "ENGINE_by_id(\"%V\") failed", &oscf->engine);        return NGX_CONF_ERROR;    }    if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) {        ngx_ssl_error(NGX_LOG_WARN, cycle->log, 0,                      "ENGINE_set_default(\"%V\", ENGINE_METHOD_ALL) failed",                      &oscf->engine);        return NGX_CONF_ERROR;    }    ENGINE_free(engine);#endif    return NGX_CONF_OK;}#if !(NGX_SSL_ENGINE)static char *ngx_openssl_noengine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,                       "\"ssl_engine\" directive is available only in "                       "OpenSSL 0.9.7 and higher,");    return NGX_CONF_ERROR;}#endifstatic voidngx_openssl_exit(ngx_cycle_t *cycle){#if (NGX_SSL_ENGINE)    ENGINE_cleanup();#endif}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?