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

📄 sctp_t.c

📁 No7信令,我需要交换类似的代码, 请店长审核,谢谢了,急着交换,谢谢
💻 C
📖 第 1 页 / 共 5 页
字号:
		/* not supported yet */	}	if ( ops->reuse ) {		/* not supported yet */	}	if ( ops->tos ) {		if ( ops->tos->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->tos+1);			sp->ip_tos = *val & 0xff;			*val = sp->ip_tos;			ops->flags |= TF_IP_TOS;		}	}	if ( ops->ttl ) {		if ( ops->ttl->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->ttl+1);			sp->ip_ttl = *val & 0xff;			*val = sp->ip_ttl;			ops->flags |= TF_IP_TTL;		}	}	if ( ops->nd ) {		if ( ops->nd->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->nd+1);			switch ( *val )			{				case T_YES: sp->options  &=~SCTP_OPTION_NAGLE; break;				case T_NO:  sp->options  |= SCTP_OPTION_NAGLE; break;					    break;			}			*val = (sp->options & SCTP_OPTION_NAGLE)?T_NO:T_YES;			ops->flags |= TF_SCTP_NODELAY;		}	}	if ( ops->cork ) {		if ( ops->cork->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->cork+1);			switch ( *val )			{				case T_YES: sp->options  |= SCTP_OPTION_CORK; break;				case T_NO:  sp->options  &=~SCTP_OPTION_CORK; break;			}			*val = (sp->options & SCTP_OPTION_CORK)?T_YES:T_NO;			ops->flags |= TF_SCTP_CORK;		}	}	if ( ops->ppi ) {		if ( ops->ppi->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->ppi+1);			sp->ppi = *val;			*val = sp->ppi;			ops->flags |= TF_SCTP_PPI;		}	}	if ( ops->sid ) {		if ( ops->sid->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->sid+1);			sp->sid = *val;			*val = sp->sid;			ops->flags |= TF_SCTP_SID;		}	}	if ( ops->ssn ) {		/* not writeable */	}	if ( ops->tsn ) {		/* not writeable */	}	if ( ops->ropt ) {		if ( ops->ropt->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->ropt+1);			switch ( *val )			{				case T_YES: sp->i_flags  |= TF_SCTP_RECVOPT; break;				case T_NO:  sp->i_flags  &=~TF_SCTP_RECVOPT; break;			}			*val = (sp->i_flags & TF_SCTP_RECVOPT)?T_YES:T_NO;			ops->flags |= TF_SCTP_RECVOPT;		}	}	if ( ops->cklife ) {		if ( ops->cklife->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->cklife+1);			if ( *val < 10 ) *val = 10;			sp->ck_life = (*val*HZ+999)/1000;			*val = (sp->ck_life*1000+HZ-1)/HZ;			ops->flags |= TF_SCTP_COOKIE_LIFE;		}	}	if ( ops->sack ) {		if ( ops->sack->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->sack+1);			sp->max_sack = (*val*HZ+999)/1000;			*val = (sp->max_sack*1000+HZ-1)/HZ;			ops->flags |= TF_SCTP_SACK_DELAY;		}	}	if ( ops->path ) {		if ( ops->path->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->path+1);			sp->rtx_path = *val;			*val = sp->rtx_path;			ops->flags |= TF_SCTP_PATH_MAX_RETRANS;		}	}	if ( ops->assoc ) {		if ( ops->assoc->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->assoc+1);			sp->max_retrans = *val;			*val = sp->max_retrans;			ops->flags |= TF_SCTP_ASSOC_MAX_RETRANS;		}	}	if ( ops->init ) {		if ( ops->init->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->init+1);			sp->max_inits = *val;			*val = sp->max_inits;			ops->flags |= TF_SCTP_MAX_INIT_RETRIES;		}	}	if ( ops->hbitvl ) {		if ( ops->hbitvl->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->hbitvl+1);			sp->hb_itvl = (*val*HZ+999)/1000;			*val = (sp->hb_itvl*1000+HZ-1)/HZ;			ops->flags |= TF_SCTP_HEARTBEAT_ITVL;		}	}	if ( ops->rtoinit ) {		if ( ops->rtoinit->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->rtoinit+1);			sp->rto_ini = (*val*HZ+999)/1000;			*val = (sp->rto_ini*1000+HZ-1)/HZ;			ops->flags |= TF_SCTP_RTO_INITIAL;		}	}	if ( ops->rtomin ) {		if ( ops->rtomin->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->rtomin+1);			sp->rto_min = (*val*HZ+999)/1000;			*val = (sp->rto_min*1000+HZ-1)/HZ;			ops->flags |= TF_SCTP_RTO_MIN;		}	}	if ( ops->rtomax ) {		if ( ops->rtomax->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->rtomax+1);			sp->rto_max = (*val*HZ+999)/1000;			*val = (sp->rto_max*1000+HZ-1)/HZ;			ops->flags |= TF_SCTP_RTO_MAX;		}	}	if ( ops->ostr ) {		if ( ops->ostr->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->ostr+1);			sp->req_ostr = *val;			*val = sp->req_ostr;			ops->flags |= TF_SCTP_OSTREAMS;		}	}	if ( ops->istr ) {		if ( ops->istr->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->istr+1);			sp->max_istr = *val;			*val = sp->max_istr;			ops->flags |= TF_SCTP_ISTREAMS;		}	}	if ( ops->ckinc ) {		if ( ops->ckinc->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->ckinc+1);			sp->ck_inc = (*val*HZ+999)/1000;			*val = (sp->ck_inc*1000+HZ-1)/HZ;			ops->flags |= TF_SCTP_COOKIE_INC;		}	}	if ( ops->titvl ) {		if ( ops->titvl->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->titvl+1);			sp->throttle = (*val*HZ+999)/1000;			*val = (sp->throttle*1000+HZ-1)/HZ;			ops->flags |= TF_SCTP_THROTTLE_ITVL;		}	}	if ( ops->hmac ) {		if ( ops->hmac->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->hmac+1);			sp->hmac = *val;			*val = sp->hmac;			ops->flags |= TF_SCTP_MAC_TYPE;		}	}	if ( ops->mseg ) {		/* not writeable */	}	if ( ops->debug ) {		if ( ops->debug->len >= olen ) {			t_scalar_t *val = (t_scalar_t *)(ops->debug+1);			sp->options = *val;			*val = sp->options;			ops->flags |= TF_SCTP_DEBUG;		}	}	if ( ops->hb ) {		/* not support yet */	}	if ( ops->rto ) {		/* not support yet */	}	if ( ops->status ) {		/* not writeable */	}	return;}/* *  Check options *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static void sctp_check_opts(sctp_t *sp, sctp_opts_t *ops){	if ( !ops ) return;	ops->flags = TF_SCTP_ALLOPS;	/*	 *  FIXME: actually check some options.	 */	fixme(("Actually check some options.\n"));	return;}/* *  ========================================================================= * *  SCTP T-Provider --> T-User Primitives (Indication, Confirmation and Ack) * *  ========================================================================= * *  T_CONN_IND	    11 - connection indication *  ----------------------------------------------------------------- *  We get the connection indication information from the cookie received in the COOKIE ECHO *  which invokes the indication.  (We queue the COOKIE ECHO chunks themselves as *  indications.) */static int t_conn_ind(sctp_t *sp, mblk_t *cp){	mblk_t *mp;	struct T_conn_ind *p;	struct t_opthdr *oh;	struct sctp_cookie_echo *m = (struct sctp_cookie_echo *)cp->b_rptr;	struct sctp_cookie *ck = (struct sctp_cookie *)m->cookie;	size_t danum = ck->danum + 1;	uint32_t *daptr = (uint32_t *)(((caddr_t)(ck+1)+ck->opt_len));	size_t src_len = danum?sizeof(uint16_t)+danum*sizeof(uint32_t):0;	size_t str_len = sizeof(struct t_opthdr)+sizeof(t_scalar_t);	size_t opt_len = 2*str_len;	ensure( ((1<<sp->i_state) & (TSF_IDLE|TSF_WRES_CIND)), return(-EFAULT) );	if ( bufq_length(&sp->conq) < sp->conind ) {	if ( canputnext(sp->rq) ) {	if ( (mp = allocb(sizeof(*p)+src_len+opt_len, BPRI_MED)) ) {		mp->b_datap->db_type = M_PROTO;		p = ((struct T_conn_ind *)mp->b_wptr)++;		p->PRIM_type		= T_CONN_IND;		p->SRC_length		= src_len;		p->SRC_offset		= src_len?sizeof(*p):0;		p->OPT_length		= opt_len;		p->OPT_offset		= opt_len?sizeof(*p)+src_len:0;		p->SEQ_number		= (ulong)cp;		/* place address information from cookie */		if    ( danum   ) *((uint16_t *)mp->b_wptr)++ = ck->dport;		if    ( danum-- ) *((uint32_t *)mp->b_wptr)++ = ck->daddr;		while ( danum-- ) *((uint32_t *)mp->b_wptr)++ = *daptr++;		/* indicate options */		oh = ((struct t_opthdr *)mp->b_wptr)++;		oh->len	    = str_len;		oh->level   = T_INET_SCTP;		oh->name    = T_SCTP_ISTREAMS;		oh->status  = T_SUCCESS;		*((t_scalar_t *)mp->b_wptr)++ = ck->n_istr;		/* indicate options */		oh = ((struct t_opthdr *)mp->b_wptr)++;		oh->len	    = str_len;		oh->level   = T_INET_SCTP;		oh->name    = T_SCTP_OSTREAMS;		oh->status  = T_SUCCESS;		*((t_scalar_t *)mp->b_wptr)++ = ck->n_ostr;		bufq_queue(&sp->conq, cp);		sp->i_state = TS_WRES_CIND;		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);	} seldom(); return(-EBUSY);	} seldom(); return(-ERESTART);}/* *  T_CONN_CON	    12 - connection confirmation *  ----------------------------------------------------------------- *  The only options with end-to-end significance that are negotiated are the number of *  inbound and outbound streams. */static int t_conn_con(sctp_t *sp){	mblk_t *mp;	struct T_conn_con *p;	struct t_opthdr *oh;	struct sctp_daddr *sd = sp->daddr;	size_t res_len = sp->danum?sizeof(uint16_t)+sp->danum*sizeof(sd->daddr):0;	size_t str_len = sizeof(*oh)+sizeof(t_scalar_t);	size_t opt_len = 2*str_len;	ensure( (sp->i_state == TS_WCON_CREQ), return(-EFAULT) );	if ( canputnext(sp->rq) ) {	if ( (mp = allocb(sizeof(*p)+res_len+opt_len, BPRI_MED)) ) {		mp->b_datap->db_type = M_PROTO;		mp->b_band = 1;	/* expedite */		p = ((struct T_conn_con *)mp->b_wptr)++;		p->PRIM_type		= T_CONN_CON;		p->RES_length		= res_len;		p->RES_offset		= res_len?sizeof(*p):0;		p->OPT_length		= opt_len;		p->OPT_offset		= opt_len?sizeof(*p)+res_len:0;		/* place destination (responding) address */		if ( sd )			*((uint16_t *)mp->b_wptr)++ = sp->dport;		for ( ; sd; sd = sd->next )			*((uint32_t *)mp->b_wptr)++ = sd->daddr;		/* indicate options */		oh = ((struct t_opthdr *)mp->b_wptr)++;		oh->len	    = str_len;		oh->level   = T_INET_SCTP;		oh->name    = T_SCTP_ISTREAMS;		oh->status  = T_SUCCESS;		*((t_scalar_t *)mp->b_wptr)++ = sp->n_istr;		/* indicate options */		oh = ((struct t_opthdr *)mp->b_wptr)++;		oh->len	    = str_len;		oh->level   = T_INET_SCTP;		oh->name    = T_SCTP_OSTREAMS;		oh->status  = T_SUCCESS;		*((t_scalar_t *)mp->b_wptr)++ = sp->n_ostr;		sp->i_state = TS_DATA_XFER;		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);	} seldom(); return(-EBUSY);}/* *  T_DISCON_IND    13 - disconnect indication *  ----------------------------------------------------------------- *  We use the address of the mblk that contains the COOKIE-ECHO chunk as a SEQ_number for *  connect indications that are rejected with a disconnect indication as well.  We can use *  this to directly address the mblk in the connection indication bufq. * *  If the caller provides disconnect data, the caller needs to set the current ord, ppi, *  sid, and ssn fields so that the user can examine them with T_OPTMGMT_REQ T_CURRENT if it *  has need to know them. */static int t_discon_ind(sctp_t *sp, long reason, mblk_t *seq){	mblk_t *mp;	struct T_discon_ind *p;	ensure( ((1<<sp->i_state) & (TSF_WCON_CREQ|TSF_WRES_CIND|TSF_DATA_XFER|TSF_WIND_ORDREL|TSF_WREQ_ORDREL)), return(-EFAULT) );	if ( canputnext(sp->rq) ) {	if ( (mp = allocb(sizeof(*p), BPRI_MED)) ) {		mp->b_datap->db_type = M_PROTO;		p = ((struct T_discon_ind *)mp->b_wptr)++;		p->PRIM_type		= T_DISCON_IND;		p->DISCON_reason	= reason;		p->SEQ_number		= (ulong)seq;		if ( seq ) {			bufq_unlink(&sp->conq, seq);			freemsg(seq);		}		if ( !bufq_length(&sp->conq) )			sp->i_state = TS_IDLE;		else	sp->i_state = TS_WRES_CIND;		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);	} seldom(); return(-EBUSY);}/* *  T_DATA_IND	    14 - data indication *  ----------------------------------------------------------------- *  This indication is only useful for delivering data indications for the default stream. *  The caller should check that ppi and sid match the default before using this indication. *  Otherwise the caller should use the T_OPTDATA_IND. */static int t_data_ind(sctp_t *sp, ulong more, mblk_t *dp){	mblk_t *mp;	struct T_data_ind *p;	ensure( ((1<<sp->i_state) & (TSF_DATA_XFER|TSF_WIND_ORDREL)), return(-EFAULT) );	if ( canputnext(sp->rq) ) {	if ( (mp = allocb(sizeof(*p), BPRI_MED)) ) {		mp->b_datap->db_type = M_PROTO;		p = ((struct T_data_ind *)mp->b_wptr)++;		p->PRIM_type		= T_DATA_IND;		p->MORE_flag		= more;		mp->b_cont = dp;		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);	} seldom(); return(-EBUSY);}/* *  T_EXDATA_IND    15 - expedited data indication *  ----------------------------------------------------------------- *  This indication is only useful for delivering data indications for the default stream. *  The caller should check that ppi and ssn match the default before using this indication. *  Otherwise the caller should use the T_OPTDATA_IND. */static int t_exdata_ind(sctp_t *sp, ulong more, mblk_t *dp){

⌨️ 快捷键说明

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