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

📄 sctp_msg.c

📁 No7信令,我需要交换类似的代码, 请店长审核,谢谢了,急着交换,谢谢
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** @(#) sctp_msg.c,v 0.7.8.1 2001/12/11 13:26:33 brian Exp ----------------------------------------------------------------------------- Copyright (C) 2001  OpenSS7 Corporation <http://www.openss7.com> All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ----------------------------------------------------------------------------- U.S. GOVERNMENT RESTRICTED RIGHTS.  If you are licensing this Software on behalf of the U.S. Government ("Government"), the following provisions apply to you.  If the Software is supplied by the Department of Defense ("DoD"), it is classified as "Commercial Computer Software" under paragraph 252.227-7014 of the DoD Supplement to the Federal Acquisition Regulations ("DFARS") (or any successor regulations) and the Government is acquiring only the license rights granted herein (the license rights customarily provided to non-Government users).  If the Software is supplied to any unit or agency of the Government other than DoD, it is classified as "Restricted Computer Software" and the Government's rights in the Software are defined in paragraph 52.227-19 of the Federal Acquisition Regulations ("FAR") (or any success regulations) or, in the cases of NASA, in paragraph 18.52.227-86 of the NASA Supplement to the FAR (or any successor regulations). ----------------------------------------------------------------------------- Last Modified 2001/12/11 13:26:33 by brian *****************************************************************************/#ident "@(#) sctp_msg.c,v 0.7.8.1 2001/12/11 13:26:33 brian Exp"static char const ident[] = "SS7AlphaRelease(0.7.8.1) 2001/12/11 13:26:33";#define __NO_VERSION__#include <linux/config.h>#include <linux/version.h>#include <linux/modversions.h>#include <linux/module.h>#include <sys/stream.h>#include <sys/stropts.h>#include <sys/cmn_err.h>#include <sys/dki.h>#include "sctp_debug.h"#include "sctp_bufq.h"#include "sctp.h"#include "sctp_defs.h"#include "sctp_hash.h"#include "sctp_cache.h"#include "sctp_route.h"#include "sctp_cookie.h"#include "sctp_output.h"#undef min  /* LiS should not have defined these */#undef max  /* LiS should not have defined these */#define sctp_daddr sctp_daddr__#define sctp_saddr sctp_saddr__#define sctp_strm  sctp_strm__#ifdef ASSERT#undef ASSERT#endif#include <net/ip.h>#include <net/icmp.h>#include <net/route.h>#undef sctp_daddr#undef sctp_saddr#undef sctp_strm#ifdef ASSERT#undef ASSERT#endif#include "sctp_msg.h"#include <linux/random.h>static uint32_t sctp_get_vtag(uint32_t daddr, uint32_t saddr, uint16_t dport, uint16_t sport){	uint32_t ret;	ret = secure_tcp_sequence_number(daddr, saddr, dport, sport);	usual( ret ); return(ret);}static void set_timeout(int *tidp, timo_fcn_t *fnc, void *data, long ticks){	assert( tidp );	assert( data );	if ( *tidp ) { abnormal(*tidp); untimeout(*tidp); }	*tidp = timeout(fnc, data, ticks?ticks:1);}static void mod_timeout(int *tidp, timo_fcn_t *fnc, void *data, long ticks){	assert( tidp );	assert( data );	if ( *tidp ) { untimeout(*tidp); }	*tidp = timeout(fnc, data, ticks?ticks:1);}/* *  ========================================================================== * *  SCTP --> SCTP Peer Messages (Send Messages) * *  ========================================================================== *//* *  BUNDLING FUNCTIONS *  ------------------------------------------------------------------------- * *  BUNDLE SACK *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static void sctp_bundle_sack(sp, sd, dmps, amps, dpp, mrem, mlen)	sctp_t *sp;	    /* association */	sctp_daddr_t *sd;   /* destination */	size_t dmps;	    /* destination maximum payload size */	size_t amps;	    /* association maximum payload size */	mblk_t ***dpp;	    /* place to link buffer */	size_t *mrem;	    /* remaining payload */	size_t *mlen;	    /* current message length */{	mblk_t *mp;	sctp_tcb_t *cb;	struct sctp_sack *m;	size_t ngaps, ndups, glen, dlen, clen, plen;	ngaps = sp->ngaps;	ndups = sp->ndups;	glen = ngaps * sizeof(uint32_t);	dlen = ndups * sizeof(uint32_t);	clen = sizeof(*m) + glen + dlen;	plen = PADC(clen);	if ( clen > dmps )	{		size_t too_many_dups;		rare(); /* trim down sack */		too_many_dups = (clen-*mrem+3)/sizeof(uint32_t);		ndups = ndups > too_many_dups ? ndups - too_many_dups : 0;		clen = sizeof(*m) + glen + ndups * sizeof(uint32_t);		if ( *mrem < clen )		{			size_t too_many_gaps;			rare(); /* trim some more */			too_many_gaps = (clen-*mrem+3)/sizeof(uint32_t);			ngaps = ngaps > too_many_gaps ? ngaps - too_many_gaps : 0;			clen = sizeof(*m) + ngaps * sizeof(uint32_t);		}	}	if ( plen > *mrem && plen <= dmps ) {		rare(); return;	/* wait for next packet */	}	if ( (mp = allocb(sizeof(*cb)+plen, BPRI_HI)) )	{		sctp_tcb_t *gap = sp->gaps;		sctp_tcb_t *dup = sp->dups;		size_t arwnd =	sp->a_rwnd;		size_t count =	bufq_size(&sp->oooq) +				bufq_size(&sp->dupq) +				bufq_size(&sp->rcvq);		arwnd = count < arwnd ? arwnd - count : 0;//		if ( !canputnext(sp->rq) ) arwnd = 0;		mp->b_datap->db_type = M_DATA;		cb = (sctp_tcb_t *)mp->b_wptr;		bzero(cb, sizeof(*cb));		cb->mp	    = mp;		cb->dlen    = clen; /* XXX */		mp->b_rptr += sizeof(*cb);  /* hide control block */		mp->b_wptr  = mp->b_rptr;		bzero(mp->b_wptr+clen,plen-clen);		m = (struct sctp_sack *)mp->b_wptr;		m->ch.type  = SCTP_CTYPE_SACK;		m->ch.flags = 0;		m->ch.len   = htons( clen );		m->c_tsn    = htonl( sp->r_ack );		m->a_rwnd   = htonl( arwnd );		m->ngaps    = htons( ngaps );		m->ndups    = htons( ndups );		mp->b_wptr += sizeof(*m);		for ( ; gap && ngaps; gap = gap->next, ngaps-- )		{			*((uint16_t *)mp->b_wptr)++ = htons(gap->tsn - sp->r_ack);			gap = gap->tail;			*((uint16_t *)mp->b_wptr)++ = htons(gap->tsn - sp->r_ack);		}		for ( ; dup && ndups; dup = dup->next, ndups-- )			*((uint32_t *)mp->b_wptr)++ = htonl(dup->tsn);		bufq_purge(&sp->dupq);		sp->ndups = 0;		sp->dups  = NULL;		sp->sackf = 0;		if ( sp->timer_sack )			untimeout(xchg(&sp->timer_sack,0));		*mrem = *mrem > plen ? *mrem - plen : 0;		*mlen += plen;		**dpp = mp;		*dpp = &(mp->b_next);		mp->b_next = NULL;		return;	}	rare();}/* *  BUNDLE ERROR *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static void sctp_bundle_error(sp, sd, dmps, amps, dpp, mrem, mlen)	sctp_t *sp;	    /* association */	sctp_daddr_t *sd;   /* destination */	size_t dmps;	    /* destination maximum payload size */	size_t amps;	    /* association maximum payload size */	mblk_t ***dpp;	    /* place to link buffer */	size_t *mrem;	    /* remaining payload */	size_t *mlen;	    /* current message length */{	mblk_t *mp;	while ( *mrem && (mp = bufq_head(&sp->errq)) )	{		size_t clen = mp->b_wptr - mp->b_rptr;		size_t plen = PADC(clen);		if ( plen > *mrem && plen <= dmps ) {			rare(); return; /* wait for next packet */		}		*mrem = *mrem > plen ? *mrem - plen : 0;		*mlen += plen;		mp = bufq_dequeue(&sp->errq);		**dpp = mp;		*dpp = &(mp->b_next);		mp->b_next = NULL;		continue;	}}/* *  BUNDLE DATA *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static inline int trimhead(mblk_t *mp, int len){	for ( ; len && mp; mp = mp->b_cont )	{		if ( mp->b_datap->db_type == M_DATA )		{			int size = mp->b_wptr - mp->b_rptr;			if ( size > len ) {				mp->b_rptr += len;				len = 0;			} else if ( size >= 0 ) {				mp->b_rptr = mp->b_wptr;				len -= size;			}		}	}	assure(!len);	return(len);}static inline int trimtail(mblk_t *mp, int len){	for ( ; len && mp; mp = mp->b_cont ) {		if ( mp->b_datap->db_type == M_DATA )		{			int size = mp->b_wptr - mp->b_rptr;			if ( size  > len ) {				mp->b_wptr = mp->b_rptr + len;				len = 0;			} else if ( size >= 0 ) {				mp->b_wptr = mp->b_rptr;				len -=  size;			}		}	}	for ( ; mp; mp = mp->b_cont )		if ( mp->b_datap->db_type == M_DATA )			if ( mp->b_wptr > mp->b_rptr )				mp->b_wptr = mp->b_rptr;	assure(!len);	return(len);}/* *  FRAGMENT DATA CHUNKS * *  Try to fragment a DATA chunk which has not been transmitted yet into *  two chunks, the first small enough to fit into the pmtu and the second one *  containing the remainder of the data in a chunk.  This is called *  iteratively, so the reminaing data may also be further fragmented *  according to the pmtu experienced at the time that it is further *  fragmented. */#if defined(_DEBUG)||defined(_SAFE)static void sctp_frag_chunk(bq, mp, mps)	bufq_t *bq;	mblk_t *mp;	size_t mps;{	mblk_t *dp;	assert(bq);	assert(mp);	rare();	/*	 *  This should be extremely rare, now that we are fragmenting in	 *  sctp_send_data.  This fragmentation only occurs if the path MTU	 *  has dropped since we buffered data for transmission.  It is	 *  probably not necessary any more.	 */	{		mblk_t *bp;		/* copy the transmission control block and data header */		if ( !(dp = copyb(mp)) ) {			rare(); return;		}		/* copyb does not copy the hiddle control block */		bcopy(mp->b_datap->db_base, dp->b_datap->db_base,				mp->b_datap->db_lim - mp->b_datap->db_base);		/* duplicate the message blocks which form the data */		if ( !(bp = dupmsg(mp->b_cont)) ) {			rare(); freeb(dp); return;		}		dp->b_cont = bp;	}	{		sctp_tcb_t *cb1 = SCTP_TCB(mp);		sctp_tcb_t *cb2 = SCTP_TCB(dp);		struct sctp_data *m1 = (struct sctp_data *)mp->b_rptr;		struct sctp_data *m2 = (struct sctp_data *)dp->b_rptr;		size_t dlen = (mps - sizeof(struct sctp_data));		cb1->dlen   = dlen;		cb1->flags &= ~SCTPCB_FLAG_LAST_FRAG;		m1->ch.len = htons( cb1->dlen + sizeof(*m1));		m1->ch.flags = cb1->flags & 0x7;		cb2->dlen  -= dlen;		cb2->flags &= ~SCTPCB_FLAG_FIRST_FRAG;		m2->ch.len = htons( cb2->dlen + sizeof(*m2));		m2->ch.flags = cb2->flags & 0x7;#if 1		{			int ret;			ret = trimhead(mp, dlen);   /* trim originai */			ensure( ret, freemsg(dp); return; );			ret = trimtail(dp, dlen);   /* trim fragment */			ensure( ret, freemsg(dp); return; );		}#else		fixme(("Should consider multiple mblks\n"));		mp->b_cont->b_wptr = mp->b_cont->b_rptr + dlen;	/* trim original */		dp->b_cont->b_rptr = dp->b_cont->b_rptr + dlen;	/* trim fragment */#endif	}	/* insert the fresh copy after the existing copy in the bufq */	__ctrace(bufq_append(bq, mp, dp));}#endif/* *  CONGESTION/RECEIVE WINDOW AVAILABILITY *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  Calculate of the remaining space in the current packet, how much is *  available for use by data according to the current peer receive window, *  the current destination congestion window, and the current outstanding *  data bytes in flight. * *  This is called iteratively as each data chunk is tested for bundling into *  the current message.  The usable length returned does not include the data *  chunk header. */static size_t sctp_avail(sp, sd, dmps, mrem)	sctp_t *sp;	sctp_daddr_t *sd;	size_t dmps;	size_t mrem;{	size_t ulen;	ulen = mrem > sizeof(struct sctp_data) ? mrem - sizeof(struct sctp_data) : 0;	if ( ulen )	{		size_t cwnd, rwnd, swnd, awnd;		cwnd = sd->cwnd + dmps;		cwnd = cwnd > sd->in_flight ? cwnd - sd->in_flight : 0;		rwnd = sp->p_rwnd;		rwnd = rwnd > sp->in_flight ? rwnd - sp->in_flight : 0;		swnd = cwnd < rwnd ? cwnd : rwnd;		awnd = sp->in_flight ? swnd : cwnd;		ulen = awnd < ulen ? awnd : ulen;	}	return(ulen);}/* *  BUNDLE DATA for RETRANSMISSION */static void sctp_bundle_data_retrans(sp, sd, dmps, amps, dpp, mrem, mlen)	sctp_t *sp;	    /* association */	sctp_daddr_t *sd;   /* destination */	size_t dmps;	    /* destination maximum payload size */	size_t amps;	    /* association maximum payload size */	mblk_t ***dpp;	    /* place to link buffer */	size_t *mrem;	    /* remaining payload */	size_t *mlen;	    /* current message length */{	mblk_t *mp = bufq_head(&sp->rtxq);	size_t swnd = sctp_avail(sp, sd, dmps, *mrem);	for ( ; mp && *mrem && swnd; mp = mp->b_next )	{		if ( (SCTP_TCB(mp)->flags & SCTPCB_FLAG_RETRANS) )		{			mblk_t *db;			sctp_tcb_t *cb = SCTP_TCB(mp);			size_t dlen = cb->dlen;			size_t plen = PADC(sizeof(struct sctp_data) + dlen);			if ( dlen > swnd ) {				rare(); return;	/* congested */			}			if ( plen > *mrem && plen <= dmps ) {				rare(); return;	/* wait for next packet */			}			if ( (db = dupmsg(mp)) )			{				cb->flags  &= ~SCTPCB_FLAG_RETRANS;				sp->nrtxs--;//				cb->trans  += 1;    done by sctp_send_msg */				cb->sacks   = 0;				cb->when    = jiffies;				cb->daddr   = sd;				sd->in_flight += dlen;				sp->in_flight += dlen;				*mrem = *mrem > plen ? *mrem - plen : 0;				*mlen += plen;				**dpp = db;				*dpp = &(db->b_next);				db->b_next = NULL;				swnd = sctp_avail(sp, sd, dmps, *mrem);				continue;			}			rare(); return;		}	}	return;}/* *  BUNDLE NEW EXPEDITED (OUT OF ORDER) DATA */static void sctp_bundle_data_urgent(sp, sd, dmps, amps, dpp, mrem, mlen)	sctp_t *sp;	    /* association */	sctp_daddr_t *sd;   /* destination */	size_t dmps;	    /* destination maximum payload size */	size_t amps;	    /* association maximum payload size */	mblk_t ***dpp;	    /* place to link buffer */	size_t *mrem;	    /* remaining payload */	size_t *mlen;	    /* current message length */{

⌨️ 快捷键说明

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