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

📄 ccid2.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);	/* slow start */	if (hctx->ccid2hctx_cwnd < hctx->ccid2hctx_ssthresh) {		hctx->ccid2hctx_acks = 0;		/* We can increase cwnd at most maxincr [ack_ratio/2] */		if (*maxincr) {			/* increase every 2 acks */			hctx->ccid2hctx_ssacks++;			if (hctx->ccid2hctx_ssacks == 2) {				ccid2_change_cwnd(sk, hctx->ccid2hctx_cwnd + 1);				hctx->ccid2hctx_ssacks = 0;				*maxincr = *maxincr - 1;			}		} else {			/* increased cwnd enough for this single ack */			hctx->ccid2hctx_ssacks = 0;		}	} else {		hctx->ccid2hctx_ssacks = 0;		hctx->ccid2hctx_acks++;		if (hctx->ccid2hctx_acks >= hctx->ccid2hctx_cwnd) {			ccid2_change_cwnd(sk, hctx->ccid2hctx_cwnd + 1);			hctx->ccid2hctx_acks = 0;		}	}	/* update RTO */	if (hctx->ccid2hctx_srtt == -1 ||	    (jiffies - hctx->ccid2hctx_lastrtt) >= hctx->ccid2hctx_srtt) {		unsigned long r = jiffies - seqp->ccid2s_sent;		int s;		/* first measurement */		if (hctx->ccid2hctx_srtt == -1) {			ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n",			       	       r, jiffies, seqp->ccid2s_seq);			hctx->ccid2hctx_srtt = r;			hctx->ccid2hctx_rttvar = r >> 1;		} else {			/* RTTVAR */			long tmp = hctx->ccid2hctx_srtt - r;			if (tmp < 0)				tmp *= -1;			tmp >>= 2;			hctx->ccid2hctx_rttvar *= 3;			hctx->ccid2hctx_rttvar >>= 2;			hctx->ccid2hctx_rttvar += tmp;			/* SRTT */			hctx->ccid2hctx_srtt *= 7;			hctx->ccid2hctx_srtt >>= 3;			tmp = r >> 3;			hctx->ccid2hctx_srtt += tmp;		}		s = hctx->ccid2hctx_rttvar << 2;		/* clock granularity is 1 when based on jiffies */		if (!s)			s = 1;		hctx->ccid2hctx_rto = hctx->ccid2hctx_srtt + s;		/* must be at least a second */		s = hctx->ccid2hctx_rto / HZ;		/* DCCP doesn't require this [but I like it cuz my code sux] */#if 1		if (s < 1)			hctx->ccid2hctx_rto = HZ;#endif		/* max 60 seconds */		if (s > 60)			hctx->ccid2hctx_rto = HZ * 60;		hctx->ccid2hctx_lastrtt = jiffies;		ccid2_pr_debug("srtt: %ld rttvar: %ld rto: %ld (HZ=%d) R=%lu\n",		       	       hctx->ccid2hctx_srtt, hctx->ccid2hctx_rttvar,		       	       hctx->ccid2hctx_rto, HZ, r);		hctx->ccid2hctx_sent = 0;	}	/* we got a new ack, so re-start RTO timer */	ccid2_hc_tx_kill_rto_timer(sk);	ccid2_start_rto_timer(sk);}static void ccid2_hc_tx_dec_pipe(struct sock *sk){	struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);	hctx->ccid2hctx_pipe--;	BUG_ON(hctx->ccid2hctx_pipe < 0);	if (hctx->ccid2hctx_pipe == 0)		ccid2_hc_tx_kill_rto_timer(sk);}static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb){	struct dccp_sock *dp = dccp_sk(sk);	struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);	u64 ackno, seqno;	struct ccid2_seq *seqp;	unsigned char *vector;	unsigned char veclen;	int offset = 0;	int done = 0;	int loss = 0;	unsigned int maxincr = 0;	ccid2_hc_tx_check_sanity(hctx);	/* check reverse path congestion */	seqno = DCCP_SKB_CB(skb)->dccpd_seq;	/* XXX this whole "algorithm" is broken.  Need to fix it to keep track	 * of the seqnos of the dupacks so that rpseq and rpdupack are correct	 * -sorbo.	 */	/* need to bootstrap */	if (hctx->ccid2hctx_rpdupack == -1) {		hctx->ccid2hctx_rpdupack = 0;		hctx->ccid2hctx_rpseq = seqno;	} else {		/* check if packet is consecutive */		if ((hctx->ccid2hctx_rpseq + 1) == seqno)			hctx->ccid2hctx_rpseq++;		/* it's a later packet */		else if (after48(seqno, hctx->ccid2hctx_rpseq)) {			hctx->ccid2hctx_rpdupack++;			/* check if we got enough dupacks */			if (hctx->ccid2hctx_rpdupack >=			    hctx->ccid2hctx_numdupack) {				hctx->ccid2hctx_rpdupack = -1; /* XXX lame */				hctx->ccid2hctx_rpseq = 0;				ccid2_change_l_ack_ratio(sk, dp->dccps_l_ack_ratio << 1);			}		}	}	/* check forward path congestion */	/* still didn't send out new data packets */	if (hctx->ccid2hctx_seqh == hctx->ccid2hctx_seqt)		return;	switch (DCCP_SKB_CB(skb)->dccpd_type) {	case DCCP_PKT_ACK:	case DCCP_PKT_DATAACK:		break;	default:		return;	}	ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;	seqp = hctx->ccid2hctx_seqh->ccid2s_prev;	/* If in slow-start, cwnd can increase at most Ack Ratio / 2 packets for	 * this single ack.  I round up.	 * -sorbo.	 */	maxincr = dp->dccps_l_ack_ratio >> 1;	maxincr++;	/* go through all ack vectors */	while ((offset = ccid2_ackvector(sk, skb, offset,					 &vector, &veclen)) != -1) {		/* go through this ack vector */		while (veclen--) {			const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;			u64 ackno_end_rl;			dccp_set_seqno(&ackno_end_rl, ackno - rl);			ccid2_pr_debug("ackvec start:%llu end:%llu\n", ackno,				       ackno_end_rl);			/* if the seqno we are analyzing is larger than the			 * current ackno, then move towards the tail of our			 * seqnos.			 */			while (after48(seqp->ccid2s_seq, ackno)) {				if (seqp == hctx->ccid2hctx_seqt) {					done = 1;					break;				}				seqp = seqp->ccid2s_prev;			}			if (done)				break;			/* check all seqnos in the range of the vector			 * run length			 */			while (between48(seqp->ccid2s_seq,ackno_end_rl,ackno)) {				const u8 state = (*vector &						  DCCP_ACKVEC_STATE_MASK) >> 6;				/* new packet received or marked */				if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED &&				    !seqp->ccid2s_acked) {				    	if (state ==					    DCCP_ACKVEC_STATE_ECN_MARKED) {						loss = 1;					} else						ccid2_new_ack(sk, seqp,							      &maxincr);					seqp->ccid2s_acked = 1;					ccid2_pr_debug("Got ack for %llu\n",					       	       seqp->ccid2s_seq);					ccid2_hc_tx_dec_pipe(sk);				}				if (seqp == hctx->ccid2hctx_seqt) {					done = 1;					break;				}				seqp = seqp->ccid2s_next;			}			if (done)				break;			dccp_set_seqno(&ackno, ackno_end_rl - 1);			vector++;		}		if (done)			break;	}	/* The state about what is acked should be correct now	 * Check for NUMDUPACK	 */	seqp = hctx->ccid2hctx_seqh->ccid2s_prev;	done = 0;	while (1) {		if (seqp->ccid2s_acked) {			done++;			if (done == hctx->ccid2hctx_numdupack)				break;		}		if (seqp == hctx->ccid2hctx_seqt)			break;		seqp = seqp->ccid2s_prev;	}	/* If there are at least 3 acknowledgements, anything unacknowledged	 * below the last sequence number is considered lost	 */	if (done == hctx->ccid2hctx_numdupack) {		struct ccid2_seq *last_acked = seqp;		/* check for lost packets */		while (1) {			if (!seqp->ccid2s_acked) {				loss = 1;				ccid2_hc_tx_dec_pipe(sk);			}			if (seqp == hctx->ccid2hctx_seqt)				break;			seqp = seqp->ccid2s_prev;		}		hctx->ccid2hctx_seqt = last_acked;	}	/* trim acked packets in tail */	while (hctx->ccid2hctx_seqt != hctx->ccid2hctx_seqh) {		if (!hctx->ccid2hctx_seqt->ccid2s_acked)			break;		hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqt->ccid2s_next;	}	if (loss) {		/* XXX do bit shifts guarantee a 0 as the new bit? */		ccid2_change_cwnd(sk, hctx->ccid2hctx_cwnd >> 1);		hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd;		if (hctx->ccid2hctx_ssthresh < 2)			hctx->ccid2hctx_ssthresh = 2;	}	ccid2_hc_tx_check_sanity(hctx);}static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk){        struct ccid2_hc_tx_sock *hctx = ccid_priv(ccid);	int seqcount = ccid2_seq_len;	int i;	/* XXX init variables with proper values */	hctx->ccid2hctx_cwnd	  = 1;	hctx->ccid2hctx_ssthresh  = 10;	hctx->ccid2hctx_numdupack = 3;	/* XXX init ~ to window size... */	hctx->ccid2hctx_seqbuf = kmalloc(sizeof(*hctx->ccid2hctx_seqbuf) *					 seqcount, gfp_any());	if (hctx->ccid2hctx_seqbuf == NULL)		return -ENOMEM;	for (i = 0; i < (seqcount - 1); i++) {		hctx->ccid2hctx_seqbuf[i].ccid2s_next =					&hctx->ccid2hctx_seqbuf[i + 1];		hctx->ccid2hctx_seqbuf[i + 1].ccid2s_prev =					&hctx->ccid2hctx_seqbuf[i];	}	hctx->ccid2hctx_seqbuf[seqcount - 1].ccid2s_next =					hctx->ccid2hctx_seqbuf;	hctx->ccid2hctx_seqbuf->ccid2s_prev =					&hctx->ccid2hctx_seqbuf[seqcount - 1];	hctx->ccid2hctx_seqh	 = hctx->ccid2hctx_seqbuf;	hctx->ccid2hctx_seqt	 = hctx->ccid2hctx_seqh;	hctx->ccid2hctx_sent	 = 0;	hctx->ccid2hctx_rto	 = 3 * HZ;	hctx->ccid2hctx_srtt	 = -1;	hctx->ccid2hctx_rttvar	 = -1;	hctx->ccid2hctx_lastrtt  = 0;	hctx->ccid2hctx_rpdupack = -1;	hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire;	hctx->ccid2hctx_rtotimer.data	  = (unsigned long)sk;	init_timer(&hctx->ccid2hctx_rtotimer);	ccid2_hc_tx_check_sanity(hctx);	return 0;}static void ccid2_hc_tx_exit(struct sock *sk){        struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);	ccid2_hc_tx_kill_rto_timer(sk);	kfree(hctx->ccid2hctx_seqbuf);	hctx->ccid2hctx_seqbuf = NULL;}static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb){	const struct dccp_sock *dp = dccp_sk(sk);	struct ccid2_hc_rx_sock *hcrx = ccid2_hc_rx_sk(sk);	switch (DCCP_SKB_CB(skb)->dccpd_type) {	case DCCP_PKT_DATA:	case DCCP_PKT_DATAACK:		hcrx->ccid2hcrx_data++;		if (hcrx->ccid2hcrx_data >= dp->dccps_r_ack_ratio) {			dccp_send_ack(sk);			hcrx->ccid2hcrx_data = 0;		}		break;	}}static struct ccid_operations ccid2 = {	.ccid_id		= 2,	.ccid_name		= "ccid2",	.ccid_owner		= THIS_MODULE,	.ccid_hc_tx_obj_size	= sizeof(struct ccid2_hc_tx_sock),	.ccid_hc_tx_init	= ccid2_hc_tx_init,	.ccid_hc_tx_exit	= ccid2_hc_tx_exit,	.ccid_hc_tx_send_packet	= ccid2_hc_tx_send_packet,	.ccid_hc_tx_packet_sent	= ccid2_hc_tx_packet_sent,	.ccid_hc_tx_packet_recv	= ccid2_hc_tx_packet_recv,	.ccid_hc_rx_obj_size	= sizeof(struct ccid2_hc_rx_sock),	.ccid_hc_rx_packet_recv	= ccid2_hc_rx_packet_recv,};module_param(ccid2_debug, int, 0444);MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");static __init int ccid2_module_init(void){	return ccid_register(&ccid2);}module_init(ccid2_module_init);static __exit void ccid2_module_exit(void){	ccid_unregister(&ccid2);}module_exit(ccid2_module_exit);MODULE_AUTHOR("Andrea Bittau <a.bittau@cs.ucl.ac.uk>");MODULE_DESCRIPTION("DCCP TCP-Like (CCID2) CCID");MODULE_LICENSE("GPL");MODULE_ALIAS("net-dccp-ccid-2");

⌨️ 快捷键说明

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