ssl_sess.c

来自「一个用于点对点传输加密的工具包源码」· C语言 代码 · 共 681 行 · 第 1/2 页

C
681
字号
	if (fatal)		return -1;	else		return 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=(SSL_SESSION *)lh_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;		} 	/* 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_w_unlock(CRYPTO_LOCK_SSL_CTX);	return(ret);	}int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c){	return remove_session_lock(ctx, c, 1);}static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)	{	SSL_SESSION *r;	int ret=0;	if ((c != NULL) && (c->session_id_length != 0))		{		if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);		r=(SSL_SESSION *)lh_delete(ctx->sessions,c);		if (r != NULL)			{			ret=1;			SSL_SESSION_list_remove(ctx,c);			}		if(lck) CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);		if (ret)			{			r->not_resumable=1;			if (ctx->remove_session_cb != NULL)				ctx->remove_session_cb(ctx,r);			SSL_SESSION_free(r);			}		}	else		ret=0;	return(ret);	}void SSL_SESSION_free(SSL_SESSION *ss)	{	int i;	if(ss == NULL)	    return;	i=CRYPTO_add(&ss->references,-1,CRYPTO_LOCK_SSL_SESSION);#ifdef REF_PRINT	REF_PRINT("SSL_SESSION",ss);#endif	if (i > 0) return;#ifdef REF_CHECK	if (i < 0)		{		fprintf(stderr,"SSL_SESSION_free, bad reference count\n");		abort(); /* ok */		}#endif	CRYPTO_free_ex_data(ssl_session_meth,ss,&ss->ex_data);	memset(ss->key_arg,0,SSL_MAX_KEY_ARG_LENGTH);	memset(ss->master_key,0,SSL_MAX_MASTER_KEY_LENGTH);	memset(ss->session_id,0,SSL_MAX_SSL_SESSION_ID_LENGTH);	if (ss->sess_cert != NULL) ssl_sess_cert_free(ss->sess_cert);	if (ss->peer != NULL) X509_free(ss->peer);	if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers);	memset(ss,0,sizeof(*ss));	OPENSSL_free(ss);	}int SSL_set_session(SSL *s, SSL_SESSION *session)	{	int ret=0;	SSL_METHOD *meth;	if (session != NULL)		{		meth=s->ctx->method->get_ssl_method(session->ssl_version);		if (meth == NULL)			meth=s->method->get_ssl_method(session->ssl_version);		if (meth == NULL)			{			SSLerr(SSL_F_SSL_SET_SESSION,SSL_R_UNABLE_TO_FIND_SSL_METHOD);			return(0);			}		if (meth != s->method)			{			if (!SSL_set_ssl_method(s,meth))				return(0);			if (s->ctx->session_timeout == 0)				session->timeout=SSL_get_default_timeout(s);			else				session->timeout=s->ctx->session_timeout;			}		/* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/		CRYPTO_add(&session->references,1,CRYPTO_LOCK_SSL_SESSION);		if (s->session != NULL)			SSL_SESSION_free(s->session);		s->session=session;		/* CRYPTO_w_unlock(CRYPTO_LOCK_SSL);*/		ret=1;		}	else		{		if (s->session != NULL)			{			SSL_SESSION_free(s->session);			s->session=NULL;			}		meth=s->ctx->method;		if (meth != s->method)			{			if (!SSL_set_ssl_method(s,meth))				return(0);			}		ret=1;		}	return(ret);	}long SSL_SESSION_set_timeout(SSL_SESSION *s, long t)	{	if (s == NULL) return(0);	s->timeout=t;	return(1);	}long SSL_SESSION_get_timeout(SSL_SESSION *s)	{	if (s == NULL) return(0);	return(s->timeout);	}long SSL_SESSION_get_time(SSL_SESSION *s)	{	if (s == NULL) return(0);	return(s->time);	}long SSL_SESSION_set_time(SSL_SESSION *s, long t)	{	if (s == NULL) return(0);	s->time=t;	return(t);	}long SSL_CTX_set_timeout(SSL_CTX *s, long t)	{	long l;	if (s == NULL) return(0);	l=s->session_timeout;	s->session_timeout=t;	return(l);	}long SSL_CTX_get_timeout(SSL_CTX *s)	{	if (s == NULL) return(0);	return(s->session_timeout);	}typedef struct timeout_param_st	{	SSL_CTX *ctx;	long time;	LHASH *cache;	} TIMEOUT_PARAM;static void timeout(SSL_SESSION *s, TIMEOUT_PARAM *p)	{	if ((p->time == 0) || (p->time > (s->time+s->timeout))) /* timeout */		{		/* The reason we don't call SSL_CTX_remove_session() is to		 * save on locking overhead */		lh_delete(p->cache,s);		SSL_SESSION_list_remove(p->ctx,s);		s->not_resumable=1;		if (p->ctx->remove_session_cb != NULL)			p->ctx->remove_session_cb(p->ctx,s);		SSL_SESSION_free(s);		}	}void SSL_CTX_flush_sessions(SSL_CTX *s, long t)	{	unsigned long i;	TIMEOUT_PARAM tp;	tp.ctx=s;	tp.cache=s->sessions;	if (tp.cache == NULL) return;	tp.time=t;	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);	i=tp.cache->down_load;	tp.cache->down_load=0;	lh_doall_arg(tp.cache,(void (*)())timeout,&tp);	tp.cache->down_load=i;	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);	}int ssl_clear_bad_session(SSL *s)	{	if (	(s->session != NULL) &&		!(s->shutdown & SSL_SENT_SHUTDOWN) &&		!(SSL_in_init(s) || SSL_in_before(s)))		{		SSL_CTX_remove_session(s->ctx,s->session);		return(1);		}	else		return(0);	}/* locked by SSL_CTX in the calling function */static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s)	{	if ((s->next == NULL) || (s->prev == NULL)) return;	if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail))		{ /* last element in list */		if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))			{ /* only one element in list */			ctx->session_cache_head=NULL;			ctx->session_cache_tail=NULL;			}		else			{			ctx->session_cache_tail=s->prev;			s->prev->next=(SSL_SESSION *)&(ctx->session_cache_tail);			}		}	else		{		if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))			{ /* first element in list */			ctx->session_cache_head=s->next;			s->next->prev=(SSL_SESSION *)&(ctx->session_cache_head);			}		else			{ /* middle of list */			s->next->prev=s->prev;			s->prev->next=s->next;			}		}	s->prev=s->next=NULL;	}static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s)	{	if ((s->next != NULL) && (s->prev != NULL))		SSL_SESSION_list_remove(ctx,s);	if (ctx->session_cache_head == NULL)		{		ctx->session_cache_head=s;		ctx->session_cache_tail=s;		s->prev=(SSL_SESSION *)&(ctx->session_cache_head);		s->next=(SSL_SESSION *)&(ctx->session_cache_tail);		}	else		{		s->next=ctx->session_cache_head;		s->next->prev=s;		s->prev=(SSL_SESSION *)&(ctx->session_cache_head);		ctx->session_cache_head=s;		}	}

⌨️ 快捷键说明

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