Example #1
0
int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) {
  int ret = 0;
  SSL_SESSION *s;

  /* add just 1 reference count for the SSL_CTX's session cache even though it
   * has two ways of access: each session is in a doubly linked list and an
   * lhash */
  SSL_SESSION_up_ref(c);
  /* if session c is in already in cache, we take back the increment later */

  CRYPTO_MUTEX_lock_write(&ctx->lock);
  if (!lh_SSL_SESSION_insert(ctx->sessions, &s, c)) {
    CRYPTO_MUTEX_unlock(&ctx->lock);
    return 0;
  }

  /* s != NULL iff we already had a session with the given PID. In this case, s
   * == c should hold (then we did not really modify ctx->sessions), or we're
   * in trouble. */
  if (s != NULL && s != c) {
    /* We *are* in trouble ... */
    SSL_SESSION_list_remove(ctx, s);
    SSL_SESSION_free(s);
    /* ... so pretend the other session did not exist in cache (we cannot
     * handle two SSL_SESSION structures with identical session ID in the same
     * cache, which could happen e.g. when two threads concurrently obtain the
     * same session from an external cache) */
    s = NULL;
  }

  /* Put at the head of the queue unless it is already in the cache */
  if (s == NULL) {
    SSL_SESSION_list_add(ctx, c);
  }

  if (s != NULL) {
    /* existing cache entry -- decrement previously incremented reference count
     * because it already takes into account the cache */
    SSL_SESSION_free(s); /* s == c */
    ret = 0;
  } else {
    /* new cache entry -- remove old ones if cache has become too large */
    ret = 1;

    if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
      while (SSL_CTX_sess_number(ctx) > SSL_CTX_sess_get_cache_size(ctx)) {
        if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) {
          break;
        }
      }
    }
  }

  CRYPTO_MUTEX_unlock(&ctx->lock);
  return ret;
}
int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session) {
  /* Although |session| is inserted into two structures (a doubly-linked list
   * and the hash table), |ctx| only takes one reference. */
  SSL_SESSION_up_ref(session);

  SSL_SESSION *old_session;
  CRYPTO_MUTEX_lock_write(&ctx->lock);
  if (!lh_SSL_SESSION_insert(ctx->sessions, &old_session, session)) {
    CRYPTO_MUTEX_unlock(&ctx->lock);
    SSL_SESSION_free(session);
    return 0;
  }

  if (old_session != NULL) {
    if (old_session == session) {
      /* |session| was already in the cache. */
      CRYPTO_MUTEX_unlock(&ctx->lock);
      SSL_SESSION_free(old_session);
      return 0;
    }

    /* There was a session ID collision. |old_session| must be removed from
     * the linked list and released. */
    SSL_SESSION_list_remove(ctx, old_session);
    SSL_SESSION_free(old_session);
  }

  SSL_SESSION_list_add(ctx, session);

  /* Enforce any cache size limits. */
  if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
    while (SSL_CTX_sess_number(ctx) > SSL_CTX_sess_get_cache_size(ctx)) {
      if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) {
        break;
      }
    }
  }

  CRYPTO_MUTEX_unlock(&ctx->lock);
  return 1;
}
Example #3
0
int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
{
    int ret = 0;
    SSL_SESSION *s;

    /*
     * add just 1 reference count for the SSL_CTX's session cache even though
     * it has two ways of access: each session is in a doubly linked list and
     * an lhash
     */
    SSL_SESSION_up_ref(c);
    /*
     * if session c is in already in cache, we take back the increment later
     */

    CRYPTO_THREAD_write_lock(ctx->lock);
    s = lh_SSL_SESSION_insert(ctx->sessions, c);

    /*
     * s != NULL iff we already had a session with the given PID. In this
     * case, s == c should hold (then we did not really modify
     * ctx->sessions), or we're in trouble.
     */
    if (s != NULL && s != c) {
        /* We *are* in trouble ... */
        SSL_SESSION_list_remove(ctx, s);
        SSL_SESSION_free(s);
        /*
         * ... so pretend the other session did not exist in cache (we cannot
         * handle two SSL_SESSION structures with identical session ID in the
         * same cache, which could happen e.g. when two threads concurrently
         * obtain the same session from an external cache)
         */
        s = NULL;
    } else if (s == NULL &&
               lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) {
        /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */

        /*
         * ... so take back the extra reference and also don't add
         * the session to the SSL_SESSION_list at this time
         */
        s = c;
    }

    /* Put at the head of the queue unless it is already in the cache */
    if (s == NULL)
        SSL_SESSION_list_add(ctx, c);

    if (s != NULL) {
        /*
         * existing cache entry -- decrement previously incremented reference
         * count because it already takes into account the cache
         */

        SSL_SESSION_free(s);    /* s == c */
        ret = 0;
    } else {
        /*
         * new cache entry -- remove old ones if cache has become too large
         */

        ret = 1;

        if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
            while (SSL_CTX_sess_number(ctx) > SSL_CTX_sess_get_cache_size(ctx)) {
                if (!remove_session_lock(ctx, ctx->session_cache_tail, 0))
                    break;
                else
                    ctx->stats.sess_cache_full++;
            }
        }
    }
    CRYPTO_THREAD_unlock(ctx->lock);
    return ret;
}
Example #4
0
int
SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
{
	int ret = 0;
	SSL_SESSION *s;

	/*
	 * Add just 1 reference count for the SSL_CTX's session cache
	 * even though it has two ways of access: each session is in a
	 * doubly linked list and an lhash.
	 */
	CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION);

	/*
	 * If session c is in already in cache, we take back the increment
	 * later.
	 */
	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
	s = lh_SSL_SESSION_insert(ctx->internal->sessions, c);

	/*
	 * s != NULL iff we already had a session with the given PID.
	 * In this case, s == c should hold (then we did not really modify
	 * ctx->internal->sessions), or we're in trouble.
	 */
	if (s != NULL && s != c) {
		/* We *are* in trouble ... */
		SSL_SESSION_list_remove(ctx, s);
		SSL_SESSION_free(s);
		/*
		 * ... so pretend the other session did not exist in cache
		 * (we cannot handle two SSL_SESSION structures with identical
		 * session ID in the same cache, which could happen e.g. when
		 * two threads concurrently obtain the same session from an
		 * external cache).
		 */
		s = NULL;
	}

	/* Put at the head of the queue unless it is already in the cache */
	if (s == NULL)
		SSL_SESSION_list_add(ctx, c);

	if (s != NULL) {
		/*
		 * existing cache entry -- decrement previously incremented
		 * reference count because it already takes into account the
		 * cache.
		 */
		SSL_SESSION_free(s); /* s == c */
		ret = 0;
	} else {
		/*
		 * New cache entry -- remove old ones if cache has become
		 * too large.
		 */

		ret = 1;

		if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
			while (SSL_CTX_sess_number(ctx) >
			    SSL_CTX_sess_get_cache_size(ctx)) {
				if (!remove_session_lock(ctx,
				    ctx->internal->session_cache_tail, 0))
					break;
				else
					ctx->internal->stats.sess_cache_full++;
			}
		}
	}
	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
	return (ret);
}