⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sctp_cache.c

📁 No7信令,我需要交换类似的代码, 请店长审核,谢谢了,急着交换,谢谢
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  ------------------------------------------------------------------------- * *  SCTP Stream handling * *  ------------------------------------------------------------------------- * *  Allocate an Inbound or Outbound Stream *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */sctp_strm_t *sctp_strm_alloc(stp, sid, errp)	sctp_strm_t **stp;	uint16_t sid;	int *errp;{	sctp_strm_t *st;	if ( (st = kmem_cache_alloc(sctp_strm_cachep, SLAB_ATOMIC)) )	{		bzero(st, sizeof(*st));		if ( (st->next = (*stp)) )			st->next->prev = &st->next;		st->prev = stp;		(*stp)	 = st;		st->sid	 = sid;		return(st);	}	*errp = -ENOMEM;	rare(); return(NULL);}/* *  Free a Stream *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static void sctp_strm_free(st)	sctp_strm_t *st;{	assert(st);	if ( (*st->prev = st->next) )		st->next->prev = st->prev;	kmem_cache_free(sctp_strm_cachep, st);}/* *  Free all Streams *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static void sctp_free_strms(sp)	sctp_t *sp;{	sctp_strm_t *st, *st_next;	assert(sp);	st_next = sp->ostrm;	usual( st_next );	while ( (st = st_next) )	{		st_next = st->next;		sctp_strm_free(st);	}	sp->ostr  = NULL;	st_next = sp->istrm;	usual( st_next );	while ( (st = st_next) )	{		st_next = st->next;		sctp_strm_free(st);	}	sp->istr  = NULL;}/* *  ========================================================================= * *  SCTP Private Data Structure Functions * *  ========================================================================= * *  We use Linux hardware aligned cache here for speedy access to information *  contained in the private data structure. */sctp_t *sctp_alloc_priv(q, spp, cmajor, cminor, ops)	queue_t *q;	sctp_t **spp;	int cmajor;	int cminor;	struct sctp_ifops *ops;{	sctp_t *sp;	assert(q);	assert(spp);	/* must have these 4 */	ensure( ops->sctp_conn_ind,   return(NULL) );	ensure( ops->sctp_conn_con,   return(NULL) );	ensure( ops->sctp_data_ind,   return(NULL) );	ensure( ops->sctp_discon_ind, return(NULL) );	assure( cmajor );	assure( cminor );	if ( (sp = kmem_cache_alloc(sctp_sctp_cachep, SLAB_ATOMIC)) )	{		MOD_INC_USE_COUNT;		bzero(sp, sizeof(*sp));		/* link into master list */		if ( (sp->next = *spp) )			sp->next->prev = &sp->next;		sp->prev = spp;		*spp = sp;		RD(q)->q_ptr	= WR(q)->q_ptr = sp;		sp->rq		= RD(q);		sp->wq		= WR(q);		sp->cmajor	= cmajor;		sp->cminor	= cminor;		sp->ops		= ops;		sp->i_state	= 0;		sp->s_state	= SCTP_CLOSED;		/* ip defaults */		sp->ip_tos	= sctp_default_ip_tos;		sp->ip_ttl	= sctp_default_ip_ttl;		sp->ip_proto	= sctp_default_ip_proto;		sp->ip_dontroute= sctp_default_ip_dontroute;		sp->ip_broadcast= sctp_default_ip_broadcast;		sp->ip_priority	= sctp_default_ip_priority;		/* per association defaults */		sp->max_istr	= sctp_default_max_istreams;		sp->req_ostr	= sctp_default_req_ostreams;		sp->max_inits	= sctp_default_max_init_retries;		sp->max_retrans	= sctp_default_assoc_max_retrans;		sp->a_rwnd	= q->q_hiwat; /* sctp_default_rmem not used */		sp->ck_life	= sctp_default_valid_cookie_life;		sp->ck_inc	= sctp_default_cookie_inc;		sp->hmac	= sctp_default_mac_type;		sp->throttle	= sctp_default_throttle_itvl;		sp->sid		= sctp_default_sid;		sp->ppi		= sctp_default_ppi;		sp->max_sack	= sctp_default_max_sack_delay;		/* per destination association defaults */		sp->rto_ini	= sctp_default_rto_initial;		sp->rto_min	= sctp_default_rto_min;		sp->rto_max	= sctp_default_rto_max;		sp->rtx_path	= sctp_default_path_max_retrans;		sp->hb_itvl	= sctp_default_heartbeat_itvl;		bufq_init(&sp->rcvq);		bufq_init(&sp->sndq);		bufq_init(&sp->urgq);		bufq_init(&sp->errq);		bufq_init(&sp->oooq);		bufq_init(&sp->dupq);		bufq_init(&sp->rtxq);		bufq_init(&sp->ackq);		bufq_init(&sp->conq);		sctp_init_lock(sp);		sp->pmtu = 576;		sp->s_state = SCTP_CLOSED;	}	usual(sp); return(sp);}void sctp_free_priv(q)	queue_t *q;{	sctp_t *sp;	ensure( q, return );	sp = SCTP_PRIV(q);	ensure( sp, return );	SCTPHASH_LOCK();	{		sp->s_state = SCTP_CLOSED;		__sctp_unhash(sp);		if ( sp->timer_init	) { rare(); untimeout(xchg(&sp->timer_init,    0)); }		if ( sp->timer_cookie	) { rare(); untimeout(xchg(&sp->timer_cookie,  0)); }		if ( sp->timer_shutdown ) { rare(); untimeout(xchg(&sp->timer_shutdown,0)); }		if ( sp->timer_sack	) { rare(); untimeout(xchg(&sp->timer_sack,    0)); }		if ( sp->saddr ) { __sctp_free_saddrs(sp); }		if ( sp->daddr ) { __sctp_free_daddrs(sp); }	}	SCTPHASH_UNLOCK();	unusual(sp->retry); freechunks(xchg(&sp->retry, NULL));	sp->sackf	= 0;	sp->in_flight   = 0;	sp->retransmits = 0;	sp->n_istr	= 0;	sp->n_ostr	= 0;	sp->v_tag	= 0;	sp->p_tag	= 0;	sp->p_rwnd	= 0;	unusual( sp->conq.q_msgs ); bufq_purge(&sp->conq);	unusual( sp->rq->q_count ); flushq(sp->rq, FLUSHALL);	unusual( sp->wq->q_count ); flushq(sp->wq, FLUSHALL);	unusual( sp->rcvq.q_msgs ); bufq_purge(&sp->rcvq);	unusual( sp->sndq.q_msgs ); bufq_purge(&sp->sndq);	unusual( sp->urgq.q_msgs ); bufq_purge(&sp->urgq);	unusual( sp->errq.q_msgs ); bufq_purge(&sp->errq);	unusual( sp->dupq.q_msgs ); bufq_purge(&sp->dupq);	unusual( sp->dups  ); sp->dups = NULL;	unusual( sp->ndups ); sp->ndups = 0;#ifdef _DEBUG	if ( sp->oooq.q_msgs && sp->oooq.q_head ) {		mblk_t *mp;		for ( mp = sp->oooq.q_head; mp; mp = mp->b_next )		{			sctp_tcb_t *cb = SCTP_TCB(mp);			printk("oooq tsn = %u\n", cb->tsn);		}	}#endif	unusual( sp->oooq.q_msgs ); bufq_purge(&sp->oooq);	unusual( sp->gaps  ); sp->gaps = NULL;	unusual( sp->ngaps ); sp->ngaps = 0;	unusual( sp->nunds ); sp->nunds = 0;#ifdef _DEBUG	if ( sp->rtxq.q_msgs && sp->rtxq.q_head ) {		mblk_t *mp;		for ( mp = sp->rtxq.q_head; mp; mp = mp->b_next )		{			sctp_tcb_t *cb = SCTP_TCB(mp);			printk("rtxq tsn = %u\n", cb->tsn);		}	}#endif	unusual( sp->rtxq.q_msgs ); bufq_purge(&sp->rtxq);	unusual( sp->nrtxs ); sp->nrtxs = 0;	unusual( sp->ackq.q_msgs ); bufq_purge(&sp->ackq);	/* do we really need to keep this stuff hanging around for retrieval? */	if ( sp->ostrm || sp->istrm ) { sctp_free_strms(sp); }	RD(q)->q_ptr = WR(q)->q_ptr = NULL;	if ( (*sp->prev = sp->next) )		sp->next->prev = sp->prev;	sp->next = NULL;	sp->prev = NULL;	kmem_cache_free(sctp_sctp_cachep, sp);	MOD_DEC_USE_COUNT;}/* *  DISCONNECT *  ------------------------------------------------------------------------- *  Disconnect the STREAM.  The caller must send a disconnect indication to *  the user interface if necessary and send an abort if necessary.  This just *  pulls the stream out of the hashes, stops timers, frees simple *  retransmission, and zeros connection info.  The stream is left bound and *  destination addressses are left allocated.  Any connection indications are *  left queued against the stream. */void sctp_disconnect(sp)	sctp_t *sp;{	assert(sp);	SCTPHASH_LOCK();	{		sctp_daddr_t *sd;		sp->s_state = sp->conind?SCTP_LISTEN:SCTP_CLOSED;		/* remove from connected hashes */		__sctp_conn_unhash(sp);		/* stop timers */		if ( sp->timer_init	) { untimeout(xchg(&sp->timer_init,     0)); }		if ( sp->timer_cookie	) { untimeout(xchg(&sp->timer_cookie,   0)); }		if ( sp->timer_shutdown ) { untimeout(xchg(&sp->timer_shutdown, 0)); }		if ( sp->timer_sack	) { untimeout(xchg(&sp->timer_sack,     0)); }		for ( sd = sp->daddr; sd; sd = sd->next )		{			if ( sd->dst_cache       ) {           dst_release(xchg(&sd->dst_cache,0)); }			if ( sd->timer_idle      ) {           untimeout(xchg(&sd->timer_idle,      0)); }			if ( sd->timer_retrans   ) { seldom(); untimeout(xchg(&sd->timer_retrans,   0)); }			if ( sd->timer_heartbeat ) { seldom(); untimeout(xchg(&sd->timer_heartbeat, 0)); }		}	}	SCTPHASH_UNLOCK();	unusual(sp->retry); freechunks(xchg(&sp->retry, NULL));	sp->sackf	= 0;	sp->in_flight   = 0;	sp->retransmits = 0;	sp->n_istr	= 0;	sp->n_ostr	= 0;	sp->v_tag	= 0;	sp->p_tag	= 0;	sp->p_rwnd	= 0;}/* *  Non-locking version for use from within timeouts (runninga at *  bottom-half so don't do bottom-half locks). */void __sctp_disconnect(sp)	sctp_t *sp;{	sctp_daddr_t *sd;	assert(sp);	sp->s_state = sp->conind?SCTP_LISTEN:SCTP_CLOSED;	/* remove from connected hashes */	__sctp_conn_unhash(sp);	/* stop timers */	if ( sp->timer_init	) { seldom(); untimeout(xchg(&sp->timer_init,     0)); }	if ( sp->timer_cookie	) { seldom(); untimeout(xchg(&sp->timer_cookie,   0)); }	if ( sp->timer_shutdown ) { seldom(); untimeout(xchg(&sp->timer_shutdown, 0)); }	if ( sp->timer_sack	) { seldom(); untimeout(xchg(&sp->timer_sack,     0)); }	for ( sd = sp->daddr; sd; sd = sd->next )	{		if ( sd->dst_cache       ) { seldom(); dst_release(xchg(&sd->dst_cache,0)); }		if ( sd->timer_idle      ) { seldom(); untimeout(xchg(&sd->timer_idle,      0)); }		if ( sd->timer_retrans   ) { rare();   untimeout(xchg(&sd->timer_retrans,   0)); }		if ( sd->timer_heartbeat ) { rare();   untimeout(xchg(&sd->timer_heartbeat, 0)); }	}	unusual(sp->retry); freechunks(xchg(&sp->retry, NULL));	sp->sackf	= 0;	sp->in_flight   = 0;	sp->retransmits = 0;	sp->n_istr	= 0;	sp->n_ostr	= 0;	sp->v_tag	= 0;	sp->p_tag	= 0;	sp->p_rwnd	= 0;}/* *  UNBIND *  ------------------------------------------------------------------------- *  We should already be in a disconnected state.  This pulls us from the bind *  hashes and deallocates source addresses, any connection indications that *  are queued against the stream are purged (these might occur if a *  connection indication comes in just before we unbind and we have made an *  error somewhere else: normally the response to an X_UNBIND_REQ in a *  connection indication state will be a X_ERROR_ACK). */void sctp_unbind(sp)	sctp_t *sp;{	assert(sp);	SCTPHASH_LOCK();	{		sp->s_state = SCTP_CLOSED;		__sctp_bind_unhash(sp);		__sctp_free_saddrs(sp);	}	SCTPHASH_UNLOCK();	unusual( sp->conq.q_msgs ); bufq_purge(&sp->conq);}/* *  RESET *  ------------------------------------------------------------------------- *  Clear the connection information hanging around on a stream.  This include *  any queued data blocks that are waitinga around for retrieval.  It is OK *  to call this function twice in a row on the same streeam. */void sctp_reset(sp)	sctp_t *sp;{	unusual( sp->rq->q_count ); flushq(sp->rq, FLUSHALL);	unusual( sp->wq->q_count ); flushq(sp->wq, FLUSHALL);	sp->pmtu = 576;	/* purge queues */	unusual( sp->rcvq.q_msgs ); bufq_purge(&sp->rcvq);	unusual( sp->sndq.q_msgs ); bufq_purge(&sp->sndq);	unusual( sp->urgq.q_msgs ); bufq_purge(&sp->urgq);	unusual( sp->errq.q_msgs ); bufq_purge(&sp->errq);	unusual( sp->dupq.q_msgs ); bufq_purge(&sp->dupq);	unusual( sp->dups  ); sp->dups = NULL;	unusual( sp->ndups ); sp->ndups = 0;	unusual( sp->oooq.q_msgs ); bufq_purge(&sp->oooq);	unusual( sp->gaps  ); sp->gaps = NULL;	unusual( sp->ngaps ); sp->ngaps = 0;	unusual( sp->nunds ); sp->nunds = 0;	unusual( sp->rtxq.q_msgs ); bufq_purge(&sp->rtxq);	unusual( sp->nrtxs ); sp->nrtxs = 0;	unusual( sp->ackq.q_msgs ); bufq_purge(&sp->ackq);	if ( sp->ostrm || sp->istrm ) { sctp_free_strms(sp); }}

⌨️ 快捷键说明

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