ngx_http_session_ctx_t * ngx_http_session_create_ctx(ngx_http_session_t *session, u_char *name, ngx_int_t (*init)(void *ctx), void (*destroy)(void *ctx)) { ngx_int_t i; ngx_http_session_list_t *session_list; ngx_http_session_ctx_t *ctx; ctx = ngx_http_session_find_ctx(session, name); if (ctx) { return NULL; } session_list = ngx_http_session_shm_zone->data; /* create a new ctx */ if (name == NULL || init == NULL || destroy == NULL) { return NULL; } ctx = session->ctx; for (i = 0; i < NGX_HTTP_SESSION_MAX_CTX; i++) { if (ctx[i].in_use == 0) { /* find a empty slot */ ngx_shmtx_lock(&session_list->shpool->mutex); if (init(&ctx[i]) != NGX_OK) { ngx_shmtx_unlock(&session_list->shpool->mutex); return NULL; } ngx_shmtx_unlock(&session_list->shpool->mutex); ctx[i].destroy = destroy; ctx[i].in_use = 1; strncpy((char *)(ctx[i].name), (char *)name, NGX_HTTP_SESSION_CTX_NAME_LEN); return &ctx[i]; } } /* slots full */ return NULL; }
void ngx_http_session_destroy_ctx(ngx_http_session_t *session, u_char *name) { ngx_http_session_ctx_t *ctx; ctx = ngx_http_session_find_ctx(session, name); if (ctx == NULL) return; if (ctx->data) { if (ctx->destroy) { ctx->destroy(ctx); memset(ctx, 0, sizeof(ngx_http_session_ctx_t)); } else { /* have data but no destroy function */ fprintf(stderr, "ERROR: no destroyer in session ctx(%s), memory leaks...\n", ctx->name); } } return; }
static ngx_http_cp_monitored_cookie_t * ngx_http_cp_check_cookie(ngx_http_request_t *r, ngx_str_t *cookie_name) { ngx_http_session_t *session; ngx_http_session_ctx_t *session_ctx; ngx_http_cp_session_ctx_t *cp_ctx; ngx_http_cp_monitored_cookie_t *m_cookie; session = ngx_http_session_get(r); if (!session) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "cp get session failed when update monitored cookies"); return NULL; } ngx_shmtx_lock(&session->mutex); session_ctx = ngx_http_session_find_ctx(session, (u_char *)"cookie_poisoning"); if (!session_ctx) { ngx_shmtx_unlock(&session->mutex); ngx_http_session_put(r); return NULL; } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "found session ctx\n"); cp_ctx = session_ctx->data; m_cookie = ngx_http_cp_hash_find(&cp_ctx->monitored_cookies, cookie_name); ngx_shmtx_unlock(&session->mutex); ngx_http_session_put(r); return m_cookie; }
static ngx_int_t ngx_http_cp_update_monitored_cookies(ngx_http_request_t *r, ngx_str_t *cookie_name, ngx_str_t *neteye_cookie, ngx_uint_t magic) { ngx_http_session_t *session; ngx_http_session_ctx_t *session_ctx; ngx_http_cp_session_ctx_t *cp_ctx; ngx_http_cp_monitored_cookie_t *m_cookie; ngx_uint_t key; session = ngx_http_session_get(r); if (!session) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "cp get session failed when update monitored cookies"); return NGX_ERROR; } ngx_shmtx_lock(&session->mutex); session_ctx = ngx_http_session_find_ctx(session, (u_char *)"cookie_poisoning"); if (!session_ctx) { ngx_shmtx_unlock(&session->mutex); ngx_http_session_put(r); return NGX_ERROR; } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "found session ctx\n"); cp_ctx = session_ctx->data; key = ngx_http_cp_hash_key(&cp_ctx->monitored_cookies, cookie_name); m_cookie = __ngx_http_cp_hash_find(&cp_ctx->monitored_cookies, cookie_name, key); if (m_cookie != NULL) { /* update, 32 is the length of md5 value */ memcpy(m_cookie->cookie_magic, neteye_cookie->data, NGX_HTTP_CP_MD5_LEN); m_cookie->magic = magic; } else { /* insert */ m_cookie = ngx_http_session_shm_alloc_nolock( sizeof(ngx_http_cp_monitored_cookie_t)); if (!m_cookie) { ngx_shmtx_unlock(&session->mutex); ngx_http_session_put(r); return NGX_ERROR; } m_cookie->cookie_name.data = ngx_http_session_shm_alloc_nolock( cookie_name->len); if (!m_cookie->cookie_name.data) { ngx_shmtx_unlock(&session->mutex); ngx_http_session_put(r); return NGX_ERROR; } memcpy(m_cookie->cookie_name.data, cookie_name->data, cookie_name->len); m_cookie->cookie_name.len = cookie_name->len; memcpy(m_cookie->cookie_magic, neteye_cookie->data, NGX_HTTP_CP_MD5_LEN); m_cookie->magic = magic; m_cookie->next = NULL; __ngx_http_cp_hash_insert(&cp_ctx->monitored_cookies, m_cookie, key); } ngx_shmtx_unlock(&session->mutex); ngx_http_session_put(r); return NGX_OK; }