亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? nr4.c

?? TCPIP協議包
?? C
?? 第 1 頁 / 共 2 頁
字號:
	}
			
	/* If this is a new frame, within the window, buffer it,
	 * then see what we can deliver
	 */
	if(nr4between(cb->rxpected,rxseq,cb->rxpastwin)
		&& !cb->rxbufs[rxbuf].occupied){
#ifdef NR4DEBUG
		printf("Frame within window\n");
#endif
		cb->rxbufs[rxbuf].occupied = 1;
		cb->rxbufs[rxbuf].data = *bpp;
		*bpp = NULL;
				
		for(rxbuf = cb->rxpected % window; cb->rxbufs[rxbuf].occupied;
			 rxbuf = cb->rxpected % window){
#ifdef NR4DEBUG
			printf("Removing frame from buffer %d\n", rxbuf);
#endif
			newdata = 1;
			cb->rxbufs[rxbuf].occupied = 0;
			append(&cb->rxq,&cb->rxbufs[rxbuf].data);
			cb->rxbufs[rxbuf].data = NULL;
			cb->rxpected = (cb->rxpected + 1) & NR4SEQMASK;
			cb->rxpastwin = (cb->rxpastwin + 1) & NR4SEQMASK;
		}
		if(newdata){
			cb->naksent = 0;	/* OK to send NAKs again */
			if(cb->r_upcall != NULL)
				(*cb->r_upcall)(cb,len_p(cb->rxq));

			/* Now that our upcall has had a shot at the queue, */
			/* see if it's past the queue length limit.  If so, */
			/* go into choked mode (i.e. flow controlled). */

			if(len_p(cb->rxq) > Nr4qlimit){
				cb->qfull = 1;
				nr4ackit((void *)cb);	/* Tell `em right away */
			} else
				start_timer(&cb->tack);
		}
	} else 	/* It's out of the window or we've seen it already */
		free_p(bpp);
}


/* Send the transmit buffer whose sequence number is seq */
void
nr4sbuf(cb, seq)
struct nr4cb *cb;
unsigned seq;
{
	struct nr4hdr hdr;
	struct mbuf *bufbp, *bp;
	unsigned bufnum = seq % cb->window;
	struct timer *t;
	
	/* sanity check */
	if(bufnum >= cb->window){
#ifdef NRDEBUG
		printf("sbuf: buffer number %u beyond window\n",bufnum);
#endif
		return;
	}

	/* Stop the ACK timer, since our sending of the frame is
	 * an implied ACK.
	 */
	stop_timer(&cb->tack);
	
	/* Duplicate the mbuf, since we have to keep it around
	 * until it is acknowledged
	 */
	bufbp = cb->txbufs[bufnum].data;

	/* Notice that we use copy_p instead of dup_p.  This is because
	 * a frame can still be sitting on the AX.25 send queue when it
	 * get acknowledged, and we don't want to deallocate its data
	 * before it gets sent!
	 */
	if((bp = copy_p(bufbp, len_p(bufbp))) == NULL){
		free_mbuf(&bp);
		return;
	}

	/* Prepare the header */
	if(cb->qfull)				/* are we choked? */
		hdr.opcode = NR4OPINFO | NR4CHOKE;
	else
		hdr.opcode = NR4OPINFO;
	hdr.yourindex = cb->yournum;
	hdr.yourid = cb->yourid;
	hdr.u.info.txseq = (unsigned char)(seq & NR4SEQMASK);
	hdr.u.info.rxseq = cb->rxpected;
	
	/* Send the frame, then set and start the timer */
	nr4sframe(cb->remote.node, &hdr, &bp);

	t = &cb->txbufs[bufnum].tretry;
	set_timer(t, (1 << cb->blevel) * (4 * cb->mdev + cb->srtt));
	start_timer(t);
}

/* Check to see if any of our frames have been ACKed */

static void
nr4ackours(cb, seq, gotchoke)
struct nr4cb *cb;
unsigned seq;
int gotchoke;	/* The choke flag is set in the received frame */
{
	unsigned txbuf;
	struct timer *t;
	
	/* If we are choked, there is nothing in the send window
	 * by definition, so we can just return.
	 */
	if(cb->choked)
		return;
		
	/* Adjust seq to point to the frame being ACK'd, not the one
	 * beyond it, which is how it arrives.
	 */
	seq = (seq - 1) & NR4SEQMASK;

	/* Free up all the ack'd frames, and adjust the round trip
	 * timing stuff
	 */
	while (nr4between(cb->ackxpected, seq, cb->nextosend)){
#ifdef NR4DEBUG
		printf("Sequence # %u acknowledged\n", seq);
#endif
		cb->nbuffered--;
		txbuf = cb->ackxpected % cb->window;
		free_mbuf(&cb->txbufs[txbuf].data);
		cb->txbufs[txbuf].data = NULL;
		cb->ackxpected = (cb->ackxpected + 1) & NR4SEQMASK;

		/* Round trip time estimation, cribbed from TCP */
		if(cb->txbufs[txbuf].retries == 0){
			/* We only sent this one once */
			int32 rtt;
			int32 abserr;

			t = &cb->txbufs[txbuf].tretry;
			/* get our rtt in msec */
			rtt = dur_timer(t) - read_timer(t);
			abserr = (rtt > cb->srtt) ? rtt - cb->srtt : cb->srtt - rtt;
			cb->srtt = (cb->srtt * 7 + rtt) >> 3;
			cb->mdev = (cb->mdev * 3 + abserr) >> 2;

			/* Reset the backoff level */
			cb->blevel = 0;
		}
		stop_timer(&cb->txbufs[txbuf].tretry);
	}	
	/* Now we recalculate tmax, the maximum number of retries for
	 * any frame in the window.  tmax is used as a baseline to
	 * determine when the window has reached a new high in retries.
	 * We don't want to increment blevel for every frame that times
	 * out, since that would lead to us backing off too fast when
	 * all the frame timers expired at around the same time.
	 */
	cb->txmax = 0;
	
	for(seq = cb->ackxpected;
		 nr4between(cb->ackxpected, seq, cb->nextosend);
		 seq = (seq + 1) & NR4SEQMASK)
		if(cb->txbufs[seq % cb->window].retries > cb->txmax)
			cb->txmax = cb->txbufs[seq % cb->window].retries;

	/* This is kind of a hack.  This function is called under
	 * three different conditions:  either we are choked, in
	 * which case we return immediately, or we are not choked,
	 * in which case we proceed normally to keep the send
	 * window full, or we have seen the choke flag for the first
	 * time.  In the last case, gotchoke is true while cb->choked
	 * is false.  We want to process any acknowledgments of existing
	 * frames in the send window before we purge it, while at the
	 * same time we don't want to take anything else off the txq
	 * or send it out.  So, in the third case we listed, we return
	 * now since we've processed the ACK.
	 */
	
	if(gotchoke)
		return;
		
	nr4output(cb);			/* yank stuff off txq and send it */

	/* At this point, either the send window is full, or
	 * nr4output() didn't find enough on the txq to fill it.
	 * If the window is not full, then the txq must be empty,
	 * and we'll make a tx upcall
	 */
	if(cb->nbuffered < cb->window && cb->t_upcall != NULL)
		(*cb->t_upcall)(cb, (uint16)((cb->window - cb->nbuffered) * NR4MAXINFO));

}


/* If the send window is open and there are frames on the txq,
 * move as many as possible to the transmit buffers and send them.
 * Return the number of frames sent.
 */
int
nr4output(cb)
struct nr4cb *cb;
{
	int numq, i;
	struct mbuf *bp;
	struct nr4txbuf *tp;

	/* Are we in the proper state? */
	if(cb->state != NR4STCON || cb->choked)
		return 0;		/* No sending if not connected */
					/* or if choked */
		
	/* See if the window is open */
	if(cb->nbuffered >= cb->window)
		return 0;

	numq = len_q(cb->txq);
	
#ifdef NR4DEBUG
	printf("nr4output: %d packets on txq\n", numq);
#endif
	
	for(i = 0; i < numq; i++){
		bp = dequeue(&cb->txq);
#ifdef NR4DEBUG
		if(len_p(bp) > NR4MAXINFO){	/* should be checked higher up */
			printf("Upper layers queued too big a buffer\n");
			continue;
		}
#endif
		/* Set up and send buffer */
		tp = &cb->txbufs[cb->nextosend % cb->window];
		tp->retries = 0;
		tp->data = bp;
		nr4sbuf(cb, cb->nextosend);

		/* Update window and buffered count */
		cb->nextosend = (cb->nextosend + 1) & NR4SEQMASK;
		if(++cb->nbuffered >= cb->window)
			break;
	}
	return i;		
}

void
nr4state(cb, newstate)
struct nr4cb *cb;
int newstate;
{
	int i;
	int oldstate = cb->state;
	
	cb->state = newstate;

	switch(cb->state){
	case NR4STDPEND:
		stop_timer(&cb->tchoke);

		/* When we request a disconnect, we lose the contents of
		 * our transmit queue and buffers, but we retain our ability
		 * to receive any packets in transit until a disconnect
		 * acknowledge arrives
		 */
		free_q(&cb->txq);
		
		for(i = 0; i < cb->window; i++){
			free_mbuf(&cb->txbufs[i].data);
			cb->txbufs[i].data = NULL;
			stop_timer(&cb->txbufs[i].tretry);
		}
		
		/* Tidy up stats: roll the top window pointer back
		 * and reset nbuffered to reflect this.  Not really
		 * necessary, but leads to a bit more truth telling
		 * in the status displays.
		 */
		cb->nextosend = cb->ackxpected;
		cb->nbuffered = 0;
		break;
	  case NR4STDISC:
		stop_timer(&cb->tchoke);
		stop_timer(&cb->tack);
		stop_timer(&cb->tcd);

		/* We don't clear the rxq, since the state change upcall
		 * may pull something off of it at the last minute.
		 */
		free_q(&cb->txq);

		/* The following loop will only be executed if the
		 * window was set, since when the control block is
		 * calloc'd the window field gets a 0 in it.  This
		 * protects us from dereferencing an unallocated
		 * window buffer pointer
		 */
		for(i = 0; i < cb->window; i++){
			free_mbuf(&cb->rxbufs[i].data);
			cb->rxbufs[i].data = NULL;
			free_mbuf(&cb->txbufs[i].data);
			cb->txbufs[i].data = NULL;
			stop_timer(&cb->txbufs[i].tretry);
		}
		break;
	}

	if(oldstate != newstate && cb->s_upcall != NULL)
		(*cb->s_upcall)(cb, oldstate, newstate);

	/* We take responsibility for deleting the circuit
	 * descriptor.  Don't do this anywhere else!
	 */
	if(newstate == NR4STDISC)
		free_n4circ(cb);
}

/* Process NAKs.  seq indicates the next frame expected by the
 * NAK'ing station.
 */

static void
nr4gotnak(cb, seq)
struct nr4cb *cb;
unsigned seq;
{
	if(nr4between(cb->ackxpected, seq, cb->nextosend))
		nr4sbuf(cb, seq);
}


/* This is called when we first get a CHOKE indication from the
 * remote.  It purges the send window and sets the choke timer.
 */

static void
nr4choke(cb)
struct nr4cb *cb;
{
	unsigned seq;
	struct mbuf *q, *bp;
	struct nr4txbuf *t;

	q = cb->txq;

	/* We purge the send window, returning the buffers to the
	 * txq in the proper order.
	 */
	for(seq = (cb->nextosend - 1) & NR4SEQMASK;
		 nr4between(cb->ackxpected, seq, cb->nextosend);
		 seq = (seq - 1) & NR4SEQMASK){

		t = &cb->txbufs[seq % cb->window];
		stop_timer(&t->tretry);
		bp = t->data;
		t->data = NULL;
		enqueue(&bp, &q);	/* prepend this packet to the queue */
		q = bp;
	 }

	cb->nextosend = cb->ackxpected;	/* close the window */
	cb->nbuffered = 0;		/* nothing in the window */
	cb->txq = q;			/* Replace the txq with the one that has */
					/* the purged packets prepended */
	cb->choked = 1;		/* Set the choked flag */

	start_timer(&cb->tchoke);
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
av在线播放成人| 久久九九久久九九| 久久精品综合网| 亚洲欧美色图小说| 国产美女精品在线| 欧美精品在线视频| 欧美国产丝袜视频| 国产一区二区导航在线播放| 欧美日韩不卡一区| 亚洲美女免费在线| 国产成人综合自拍| 日韩欧美在线1卡| 亚洲综合丝袜美腿| 色综合天天在线| 日本一区二区高清| 国产毛片精品视频| 欧美本精品男人aⅴ天堂| 亚洲线精品一区二区三区八戒| 成人黄色软件下载| 国产日产精品1区| 久久99国产精品尤物| 91精品免费观看| 日韩精品电影一区亚洲| 欧美日韩在线免费视频| 亚洲另类春色校园小说| 99久久99久久综合| 国产精品卡一卡二卡三| 岛国一区二区在线观看| 国产欧美一区二区精品忘忧草 | 欧美大片在线观看| 首页国产丝袜综合| 欧美欧美欧美欧美| 青娱乐精品视频在线| 日韩一区二区在线观看视频| 青青草成人在线观看| 日韩一区二区三区视频| 免费成人在线观看| 久久综合丝袜日本网| 国产ts人妖一区二区| 亚洲国产成人午夜在线一区| 成人av免费在线| 亚洲老妇xxxxxx| 欧美日韩一区中文字幕| 香蕉加勒比综合久久| 日韩视频一区二区在线观看| 日本欧美在线看| 亚洲精品一区二区三区香蕉| 国产精品一区专区| ...av二区三区久久精品| 91小视频免费观看| 日韩国产一区二| 精品捆绑美女sm三区| 成人永久aaa| 一区二区理论电影在线观看| 欧美精品久久一区| 国产一区二区三区在线观看精品| 国产日韩一级二级三级| 色女孩综合影院| 日韩va亚洲va欧美va久久| 亚洲精品一线二线三线| 91麻豆国产福利在线观看| 亚洲成av人综合在线观看| 精品免费一区二区三区| www.99精品| 久久精品国产99国产| 国产日韩成人精品| 欧美日韩1区2区| 国产成人精品影视| 亚洲国产成人精品视频| 久久综合色播五月| 一本色道综合亚洲| 精品一区二区三区久久久| 18成人在线视频| 日韩美女在线视频| 色婷婷狠狠综合| 精品一区二区影视| 亚洲国产精品欧美一二99| 欧美精品一区二区三区四区| 91麻豆免费视频| 国产激情视频一区二区在线观看 | 久久久精品欧美丰满| 色欧美日韩亚洲| 国产成人精品一区二| 亚洲va欧美va国产va天堂影院| 久久久www免费人成精品| 欧美日韩国产高清一区二区三区| 国产成人自拍高清视频在线免费播放| 一级做a爱片久久| 国产精品私人自拍| 欧美tickling网站挠脚心| 欧美最猛性xxxxx直播| 国产精品乡下勾搭老头1| 视频一区视频二区在线观看| 成人免费在线视频观看| 久久久久久亚洲综合| 欧美精品免费视频| 欧美色综合久久| 色天天综合色天天久久| 99久久精品久久久久久清纯| 国产v综合v亚洲欧| 国产一区二区福利视频| 经典三级视频一区| 免费不卡在线观看| 日一区二区三区| 午夜欧美视频在线观看| 亚洲一区视频在线| 亚洲精品成人少妇| 一区二区三区日韩精品视频| 国产精品私人影院| 国产亚洲精品精华液| 久久久久久久久伊人| 26uuu另类欧美| 精品国产乱码久久久久久闺蜜| 91精品国产综合久久小美女| 欧美日韩一区中文字幕| 欧美少妇一区二区| 在线观看91精品国产麻豆| 欧美日韩成人一区| 日韩网站在线看片你懂的| 精品久久一区二区| 精品国产乱码久久久久久闺蜜| www激情久久| 亚洲国产精品精华液ab| 国产精品久久久久一区| 亚洲乱码日产精品bd| 一级日本不卡的影视| 日韩精品每日更新| 国产伦精一区二区三区| 成人视屏免费看| 在线免费av一区| 日韩一区二区三区四区| 国产亚洲精品aa午夜观看| 中文字幕一区二区三区色视频 | 蜜桃av一区二区三区电影| 裸体歌舞表演一区二区| 国产精品一区二区在线观看不卡 | 日韩亚洲欧美一区二区三区| 精品欧美一区二区久久| 国产精品国产三级国产aⅴ中文| 亚洲麻豆国产自偷在线| 视频一区二区国产| 高清不卡一区二区| 色偷偷成人一区二区三区91 | 色综合一个色综合亚洲| 欧美撒尿777hd撒尿| 日韩精品一区二区三区在线观看| 国产夜色精品一区二区av| 一区二区三区资源| 精品一区二区三区欧美| 99re成人精品视频| 91精品国产麻豆国产自产在线 | 欧美激情一区二区三区四区| 一区二区久久久久| 精品无人码麻豆乱码1区2区 | 色哟哟一区二区三区| 欧美一激情一区二区三区| 国产欧美日韩精品在线| 亚洲综合精品久久| 国产真实乱偷精品视频免| 色天天综合色天天久久| 久久午夜国产精品| 亚洲图片有声小说| 不卡av免费在线观看| 日韩欧美色综合网站| 依依成人精品视频| 国产91色综合久久免费分享| 欧美日韩一区二区三区高清 | 精品国产一区久久| 亚洲综合色噜噜狠狠| 国产精品一区二区黑丝| 91精品黄色片免费大全| 亚洲精品高清在线| 99视频有精品| 久久久久99精品国产片| 麻豆精品视频在线观看免费| 日本高清不卡视频| 日韩理论电影院| 成人精品一区二区三区四区 | 国产风韵犹存在线视精品| 在线电影院国产精品| 亚洲一区影音先锋| 91蜜桃在线免费视频| 国产欧美日韩视频一区二区| 久久99九九99精品| 日韩一级免费观看| 同产精品九九九| 91老司机福利 在线| 中日韩免费视频中文字幕| 国产综合久久久久久鬼色| 日韩精品一区二区三区三区免费| 日本午夜一区二区| 欧美精品高清视频| 天天免费综合色| 91.麻豆视频| 午夜精品福利久久久| 欧美亚洲综合网| 亚洲成人福利片| 91精品国产欧美一区二区18| 天堂成人国产精品一区| 7777精品久久久大香线蕉|