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

📄 sctp_msg.c

📁 No7信令,我需要交换类似的代码, 请店长审核,谢谢了,急着交换,谢谢
💻 C
📖 第 1 页 / 共 5 页
字号:
			m->ch.flags = 0;			m->ch.len   = htons(clen);			m->i_tag    = sp->v_tag;			m->a_rwnd   = htonl( sp->a_rwnd );			m->n_istr   = htons( sp->max_istr );			m->n_ostr   = htons( sp->req_ostr );			m->i_tsn    = htonl( sp->v_tag );			mp->b_wptr += sizeof(*m);			for ( ss = sp->saddr; ss && sanum; ss = ss->next, sanum-- )			{				ap = (struct sctp_ipv4_addr *)mp->b_wptr;				ap->ph.type = SCTP_PTYPE_IPV4_ADDR;				ap->ph.len  = htons( sizeof(*ap) );				ap->addr    = ss->saddr;				mp->b_wptr += PADC( sizeof(*ap) );			}			unusual( ss    );			unusual( sanum );			if ( sp->ck_inc )			{				cp = (struct sctp_cookie_psrv *)mp->b_wptr;				cp->ph.type = SCTP_PTYPE_COOKIE_PSRV;				cp->ph.len  = htons( sizeof(*cp) );;				cp->ck_inc  = htonl( sp->ck_inc );				mp->b_wptr += PADC( sizeof(*cp) );			}						at = (struct sctp_addr_type *)mp->b_wptr;			at->ph.type = SCTP_PTYPE_ADDR_TYPE;			at->ph.len  = htons( sizeof(*at)+sizeof(at->type[0]) );			at->type[0] = SCTP_PTYPE_IPV4_ADDR;			mp->b_wptr += PADC( sizeof(*at)+sizeof(at->type[0]) );			sctp_send_msg(sp, sd, mp);			mod_timeout(&sp->timer_init, &sctp_init_timeout, sd, sd->rto);			unusual( sp->retry );			freechunks(xchg(&sp->retry, mp));			sp->s_state = SCTP_COOKIE_WAIT;			return(0);		}		rare(); return(-ENOBUFS);	}	rare(); return(-EFAULT);}/* *  SEND INIT ACK *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *  No s_state change results from replying to an INIT.  INIT ACKs are sent *  without a TCB but a STREAM is referenced.  INIT ACK chunks cannot have any *  other chunks bundled with them. (RFC 2960 6.10). */static void sctp_send_init_ack(sp, daddr, sh, ck)	sctp_t *sp;	uint32_t daddr;	struct sctphdr *sh;	struct sctp_cookie *ck;{	mblk_t *mp;	struct sctp_init_ack *m;	struct sctpphdr *ph;	struct sctp_cookie *cp;	struct sctp_ipv4_addr *ap;	struct sctp_init *im = (struct sctp_init *)(sh+1);	unsigned char *init = (unsigned char *)im;		int anum = ck->danum;	int snum = ck->sanum;		size_t klen = sizeof(*ph)+raw_cookie_size(ck)+HMAC_SIZE;	size_t dlen = sp->sanum * PADC(sizeof(*ap));	size_t clen = sizeof(*m)+dlen+klen;		int arem, alen;		assert(sp);	if ( (mp = sctp_alloc_reply(sh, clen)) )	{		sctp_saddr_t *ss;		struct sctphdr *rh;		rh = ((struct sctphdr *)mp->b_wptr)-1;		rh->v_tag   = im->i_tag;				m = (struct sctp_init_ack *)mp->b_wptr;		m->ch.type  = SCTP_CTYPE_INIT_ACK;		m->ch.flags = 0;		m->ch.len   = htons(clen);		m->i_tag    = ck->v_tag;		m->a_rwnd   = htonl( sp->a_rwnd );		m->n_istr   = htons( ck->n_istr );		m->n_ostr   = htons( ck->n_ostr );		m->i_tsn    = htonl( ck->v_tag );		mp->b_wptr += sizeof(*m);				for ( ss = sp->saddr; ss; ss = ss->next )		{			ap = (struct sctp_ipv4_addr *)mp->b_wptr;			ap->ph.type = SCTP_PTYPE_IPV4_ADDR;			ap->ph.len  = __constant_htons( sizeof(*ap) );			ap->addr    = ss->saddr;			mp->b_wptr += PADC(sizeof(*ap));		}				ph = (struct sctpphdr *)mp->b_wptr;		ph->type    = SCTP_PTYPE_STATE_COOKIE;		ph->len	    = htons( klen );		mp->b_wptr += sizeof(*ph);				cp = (struct sctp_cookie *)mp->b_wptr;		bcopy(ck, cp, sizeof(*cp));		mp->b_wptr += sizeof(*cp);		#if 0		/* copy in IP reply options */		if ( ck->opt_len )		{			assure(opt);			bcopy(opt, mp->b_wptr, optlength(opt));			kfree_s(opt, optlength(opt));			sp->opt = (struct ip_options *)mp->b_wptr;			mp->b_wptr += ck->opt_len;		}#endif		for ( ap = (struct sctp_ipv4_addr *)(init + sizeof(struct sctp_init)),				arem = PADC(htons(((struct sctpchdr *)init)->len)) - sizeof(struct sctp_init);				anum && arem >= sizeof(struct sctpphdr);				arem -= PADC(alen),				ap = (struct sctp_ipv4_addr *)(((uint8_t *)ap)+PADC(alen)) )		{			if ( (alen = ntohs(ap->ph.len)) > arem )			{				assure( alen <= arem );				freemsg(mp);				rare(); return;			}			if ( ap->ph.type == SCTP_PTYPE_IPV4_ADDR )			{				/* skip primary */				if ( ap->addr != ck->daddr )				{					*((uint32_t *)mp->b_wptr)++ = ap->addr;					anum--;				}			}		}				for ( ss = sp->saddr; ss; ss = ss->next )		{			if ( ss->saddr != ck->saddr )			{				*((uint32_t *)mp->b_wptr)++ = ss->saddr;				snum--;			}		}				assure( !anum );		assure( !snum );		sctp_sign_cookie(sp, cp);		mp->b_wptr += HMAC_SIZE;				sctp_xmit_msg(daddr, mp, sp);	}}/* *  SEND COOKIE ECHO *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *  If we fail to launch the COOKIE ECHO and get timers started, we must *  return an error to the user interface calling this function. */static int sctp_send_cookie_echo(sp, kptr, klen)	sctp_t *sp;	caddr_t kptr;	size_t klen;{	sctp_daddr_t *sd;		assert(sp);	if ( (sd = sp->daddr) )	{		mblk_t *mp;		struct sctp_cookie_echo *m;		size_t clen = sizeof(*m)+klen;		size_t plen = PADC(clen);				if ( (mp = sctp_alloc_msg(sp, clen)) )		{			m = (struct sctp_cookie_echo *)mp->b_wptr;			m->ch.type  = SCTP_CTYPE_COOKIE_ECHO;			m->ch.flags = 0;			m->ch.len   = htons(clen);			bcopy(kptr, (m+1), klen);			mp->b_wptr += plen;						sctp_bundle_more(sp, sd, mp);			sctp_send_msg(sp, sd, mp);			mod_timeout(&sp->timer_cookie, &sctp_cookie_timeout, sd, sd->rto);			unusual( sp->retry );			freechunks(xchg(&sp->retry, mp));			sp->s_state = SCTP_COOKIE_ECHOED;			return(0);		}		rare(); return(-ENOBUFS);	}	rare(); return(-EFAULT);}/* *  SEND COOKIE ACK *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *  SACK and DATA can be bundled with the COOKIE ACK. */static void sctp_send_cookie_ack(sp)	sctp_t *sp;{	sctp_daddr_t *sd;		assert(sp);	if ( (sd = sctp_route_response(sp)) )	{		mblk_t *mp;		struct sctp_cookie_ack *m;		size_t clen = sizeof(*m);		size_t plen = PADC(clen);				if ( (mp = sctp_alloc_msg(sp, clen)) )		{			m = (struct sctp_cookie_ack *)mp->b_wptr;			m->ch.type  = SCTP_CTYPE_COOKIE_ACK;			m->ch.flags = 0;			m->ch.len   = __constant_htons(clen);			mp->b_wptr += plen;						sctp_bundle_more(sp, sd, mp);			sctp_send_msg(sp, sd, mp);			freechunks(mp);		}		sp->s_state = SCTP_ESTABLISHED;		/* start idle timers */		for ( sd = sp->daddr; sd; sd = sd->next )			sctp_reset_idle(sd);	}}/* *  SEND HEARTBEAT *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *  We don't send heartbeats when idle timers expire if we are in the wrong *  state, we just reset the idle timer. */static void sctp_send_heartbeat(sp, sd)	sctp_t *sp;	sctp_daddr_t *sd;{	mblk_t *mp;	struct sctp_heartbeat *m;	struct sctp_heartbeat_info *h;	size_t fill, clen, hlen, plen;		assert(sp);	assert(sd);	fill = sd->hb_fill;	clen = sizeof(*m)+sizeof(*h)+fill;	hlen = clen - sizeof(struct sctpchdr);	plen = PADC(clen);	sd->hb_time = jiffies;	if ( (mp = sctp_alloc_msg(sp, clen)) )	{		m = (struct sctp_heartbeat *)mp->b_wptr;		m->ch.type  = SCTP_CTYPE_HEARTBEAT;		m->ch.flags = 0;		m->ch.len   = htons(clen);				h = (struct sctp_heartbeat_info *)(m+1);		h->ph.type  = SCTP_PTYPE_HEARTBEAT_INFO;		h->ph.len   = htons(hlen);		h->hb_info.timestamp = sd->hb_time;		h->hb_info.daddr     = sd->daddr;		h->hb_info.mtu       = sd->mtu;				bzero(h->hb_info.fill, fill);		mp->b_wptr += plen;				sctp_send_msg(sp, sd, mp);		freechunks(mp);	}	mod_timeout(&sd->timer_heartbeat, &sctp_heartbeat_timeout, sd, sd->rto);}/* *  SEND HEARTBEAT ACK *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *  Take the incoming HEARTBEAT message and turn it back around as a HEARTBEAT *  ACK message.  Note that if the incoming chunk parameters are invalid, so *  are the outgoing parameters, this is because the hb_info parameter is *  opaque to us.  This is consistent with draft-stewart-ong-sctpbakeoff- *  sigtran-01. */static void sctp_send_heartbeat_ack(sp, hptr, hlen)	sctp_t *sp;	caddr_t hptr;	size_t hlen;{	sctp_daddr_t *sd;		assert(sp);	if ( (sd = sctp_route_response(sp)) )	{		mblk_t *mp;		struct sctp_heartbeat_ack *m;		size_t clen = sizeof(*m)+hlen;		size_t plen = PADC(clen);				if ( (mp = sctp_alloc_msg(sp, clen)) )		{			m = (struct sctp_heartbeat_ack *)mp->b_wptr;			m->ch.type  = SCTP_CTYPE_HEARTBEAT_ACK;			m->ch.flags = 0;			m->ch.len   = htons(clen);			bcopy(hptr, (m+1), hlen);			mp->b_wptr += plen;			sctp_send_msg(sp, sd, mp);			freechunks(mp);		}	}}/* *  SEND ABORT *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *  There is no point in bundling control chunks after an ABORT chunk.  Also, *  DATA chunks are not to be bundled with ABORT chunks. */static void sctp_send_abort(sp)	sctp_t *sp;{	sctp_daddr_t *sd;		assert(sp);	if ( (1<<sp->s_state) & SCTPF_CONNECTED )		sd = sctp_route_normal(sp);	else	sd = sp->daddr;	if ( sd )	{		mblk_t *mp;		struct sctp_abort *m;		size_t clen = sizeof(*m);		size_t plen = PADC(clen);				if ( (mp = sctp_alloc_msg(sp, clen)) )		{			m = (struct sctp_abort *)mp->b_wptr;			m->ch.type  = SCTP_CTYPE_ABORT;			m->ch.flags = 0;			m->ch.len   = __constant_htons(clen);			mp->b_wptr += plen;			sctp_send_msg(sp, sd, mp);			freechunks(mp);		}		sp->s_state = sp->conind?SCTP_LISTEN:SCTP_CLOSED;	}}/* *  SEND ABORT (w/ERROR CAUSE) *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *  Errors (beyond the error header) must be formatted by the called and *  indicated by are and len.  There is no point in bundling data or control *  chunks after and abort chunk. */static void sctp_send_abort_error(sp, errn, aptr, alen)	sctp_t *sp;	int errn;	void *aptr; /* argument ptr */	size_t alen; /* argument len */{	sctp_daddr_t *sd;		assert(sp);	if ( (sd = sctp_route_normal(sp)) )	{		if ( errn )		{			mblk_t *mp;			struct sctp_abort *m;			struct sctpehdr *eh;			size_t elen = sizeof(*eh)+alen;			size_t clen = sizeof(*m)+elen;			size_t plen = PADC(clen);						if ( (mp = sctp_alloc_msg(sp, clen)) )			{				m = (struct sctp_abort *)mp->b_wptr;				m->ch.type  = SCTP_CTYPE_ABORT;				m->ch.flags = 0;				m->ch.len   = htons(clen);				eh = (struct sctpehdr *)(m+1);				eh->code    = htons(errn);				eh->len	    = htons(elen);				bcopy(aptr, (eh+1), alen);				mp->b_wptr += plen;				sctp_send_msg(sp, sd, mp);				freechunks(mp);			}			sp->s_state = sp->conind?SCTP_LISTEN:SCTP_CLOSED;			return;		}		sctp_send_abort(sp);	}}/* *  SEND SHUTDOWN *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *  RFC 2960 6.2 "... DATA chunks cannot be bundled with SHUTDOWN or SHUTDOWN *  ACK chunks ..." * *  If we fail to launch the SHUTDOWN and get timers started, we must inform *  the user interface calling this function. */static int sctp_send_shutdown(sp)	sctp_t *sp;{	mblk_t *mp;	sctp_daddr_t *sd;		assert(sp);	if ( (sd = sctp_route_normal(sp)) )	{		struct sctp_shutdown *m;		size_t clen = sizeof(*m);		size_t plen = PADC(clen);				if ( (mp = sctp_alloc_msg(sp, clen)) )		{			m = (struct sctp_shutdown *)mp->b_wptr;			m->ch.type  = SCTP_CTYPE_SHUTDOWN;			m->ch.flags = 0;			m->ch.len   = __constant_htons(clen);			m->c_tsn    = htonl(sp->r_ack);			mp->b_wptr += plen;						/* shutdown acks everything but dups and gaps */			sp->sackf &= (SCTP_SACKF_DUP|SCTP_SACKF_GAP);						sctp_bundle_more(sp, sd, mp);	/* not DATA */			sctp_send_msg(sp, sd, mp);			mod_timeout(&sp->timer_shutdown, &sctp_shutdown_timeout, sd, sd->rto);//			unusual( sp->retry );	/* not that unusual */			freechunks(xchg(&sp->retry, mp));			sp->s_state = SCTP_SHUTDOWN_SENT;			return(0);		}		rare(); return(-ENOBUFS);	}	rare(); return(-EFAULT);}/* *  SEND SHUTDOWN ACK *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *  SHUTDOWN ACK is sent in response to a SHUTDOWN message after all data has *  cleared or in reponse to a COOKIE ECHO during the SHUTDOWN_ACK_SENT s_state. *  If the error flag is set, we want to bundle and ERROR chunk with the *  SHUTDOWN ACK indicating "cookie received while shutting down." * *  RFC 2960 6.2. "...  DATA chunks cannot be bundled with SHUTDOWN or *  SHUTDOWN ACK chunks ..." * *  If we fail to launch the SHUTDOWN ACK and get timers started, we must *  return an error to the user interface calling this function. */static int sctp_send_shutdown_ack(sp)	sctp_t *sp;{	mblk_t *mp;	sctp_daddr_t *sd;		assert(sp);	if ( (sd = sctp_route_response(sp)) )	{		struct sctp_shutdown_ack *m;		size_t clen = sizeof(*m);		size_t plen = PADC(clen);				if ( (mp = sctp_alloc_msg(sp, clen)) )		{			m = (struct sctp_shutdown_ack *)mp->b_wptr;			m->ch.type  = SCTP_CTYPE_SHUTDOWN_ACK;			m->ch.flags = 0;			m->ch.len   = __constant_htons(clen);			mp->b_wptr  += plen;			sctp_bundle_more(sp, sd, mp);	/* not DATA */			sctp_send_msg(sp, sd, mp);			mod_timeout(&sp->timer_shutdown, &sctp_shutdown_timeout, sd, sd->rto);			unusual( sp->retry );			freechunks(xchg(&sp->retry, mp));			sp->s_state = SCTP_SHUTDOWN_ACK_SENT;			return(0);

⌨️ 快捷键说明

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