コード例 #1
0
ファイル: tcp_cubic.c プロジェクト: Andromeda-OS/Kernel
static void
tcp_cubic_ack_rcvd(struct tcpcb *tp, struct tcphdr *th)
{
	/* Do not increase the congestion window in non-validated phase */
	if (tcp_cc_is_cwnd_nonvalidated(tp) != 0)
		return;

	if (tp->snd_cwnd >= tp->snd_ssthresh) {
		/* Congestion avoidance phase */
		tcp_cubic_congestion_avd(tp, th);
	} else {
		/*
		 * Use 2*SMSS as limit on increment as suggested
		 * by RFC 3465 section 2.3
		 */
		uint32_t acked, abc_lim, incr;

		acked = BYTES_ACKED(th, tp);
		abc_lim = (tcp_do_rfc3465_lim2 && 
			tp->snd_nxt == tp->snd_max) ?
			2 * tp->t_maxseg : tp->t_maxseg;
		incr = min(acked, abc_lim);

		tp->snd_cwnd += incr;
		tp->snd_cwnd = min(tp->snd_cwnd, 
			TCP_MAXWIN << tp->snd_scale);
	}
}
コード例 #2
0
ファイル: tcp_newreno.c プロジェクト: aglab2/darwin-xnu
/* Function to process an ack.
 */
void
tcp_newreno_ack_rcvd(struct tcpcb *tp, struct tcphdr *th) {
	/*
	 * RFC 3465 - Appropriate Byte Counting.
	 *
	 * If the window is currently less than ssthresh,
	 * open the window by the number of bytes ACKed by
	 * the last ACK, however clamp the window increase
	 * to an upper limit "L".
	 *
	 * In congestion avoidance phase, open the window by
	 * one segment each time "bytes_acked" grows to be
	 * greater than or equal to the congestion window.
	 */

	u_int cw = tp->snd_cwnd;
	u_int incr = tp->t_maxseg;
	int acked = 0;

	acked = BYTES_ACKED(th, tp);
	if (tcp_do_rfc3465) {

		if (cw >= tp->snd_ssthresh) {
			tp->t_bytes_acked += acked;
			if (tp->t_bytes_acked >= cw) {
				/* Time to increase the window. */
				tp->t_bytes_acked -= cw;
			} else {
				/* No need to increase yet. */
				incr = 0;
			}
		} else {
			/*
			 * If the user explicitly enables RFC3465
			 * use 2*SMSS for the "L" param.  Otherwise
			 * use the more conservative 1*SMSS.
			 *
			 * (See RFC 3465 2.3 Choosing the Limit)
			 */
			uint32_t abc_lim;
			abc_lim = (tcp_do_rfc3465_lim2 &&
				tp->snd_nxt == tp->snd_max) ? incr * 2 
				: incr;

			incr = lmin(acked, abc_lim);
		}
	} else {
		/*
		 * If the window gives us less than ssthresh packets
		 * in flight, open exponentially (segsz per packet).
		 * Otherwise open linearly: segsz per window
		 * (segsz^2 / cwnd per packet).
		 */

		if (cw >= tp->snd_ssthresh)
			incr = max((incr * incr / cw), 1);
	}
	tp->snd_cwnd = min(cw+incr, TCP_MAXWIN<<tp->snd_scale);
}
コード例 #3
0
ファイル: tcp_cubic.c プロジェクト: Andromeda-OS/Kernel
/*
 * Handle an in-sequence ack during congestion avoidance phase.
 */
static void
tcp_cubic_congestion_avd(struct tcpcb *tp, struct tcphdr *th)
{
	u_int32_t cubic_target_win, tcp_win, rtt;

	/* Do not increase congestion window in non-validated phase */
	if (tcp_cc_is_cwnd_nonvalidated(tp) != 0)
		return;

	tp->t_bytes_acked += BYTES_ACKED(th, tp);

	rtt = get_base_rtt(tp);
	/*
	 * First compute cubic window. If cubic variables are not
	 * initialized (after coming out of recovery), this call will
	 * initialize them.
	 */
	cubic_target_win = tcp_cubic_update(tp, rtt);

	/* Compute TCP window if a multiplicative decrease of 0.2 is used */
	tcp_win = tcp_cubic_tcpwin(tp, th);

	if (tp->snd_cwnd < tcp_win &&
	    (tcp_cubic_tcp_friendliness == 1 ||
	    TCP_CUBIC_ENABLE_TCPMODE(tp))) {
		/* this connection is in TCP-friendly region */
		if (tp->t_bytes_acked >= tp->snd_cwnd) {
			tp->t_bytes_acked -= tp->snd_cwnd;
			tp->snd_cwnd = min(tcp_win, TCP_MAXWIN << tp->snd_scale);
		}
	} else {
		if (cubic_target_win > tp->snd_cwnd) {
			/*
			 * The target win is computed for the next RTT.
			 * To reach this value, cwnd will have to be updated
			 * one segment at a time. Compute how many bytes 
			 * need to be acknowledged before we can increase 
			 * the cwnd by one segment.
			 */
			u_int64_t incr_win;
			incr_win = tp->snd_cwnd * tp->t_maxseg;
			incr_win /= (cubic_target_win - tp->snd_cwnd);
			if (incr_win > 0 &&
			    tp->t_bytes_acked >= incr_win) {
				tp->t_bytes_acked -= incr_win;
				tp->snd_cwnd = 
				    min((tp->snd_cwnd + tp->t_maxseg),
				    TCP_MAXWIN << tp->snd_scale);
			}
		}
	}
}
コード例 #4
0
ファイル: tcp_newreno.c プロジェクト: aglab2/darwin-xnu
/* Function to handle an in-sequence ack during congestion avoidance phase.
 * This will get called from header prediction code.
 */
void
tcp_newreno_congestion_avd(struct tcpcb *tp, struct tcphdr *th) {
	uint32_t acked = 0;
	acked = BYTES_ACKED(th, tp);
	/*
	 * Grow the congestion window, if the
	 * connection is cwnd bound.
	 */
	if (tp->snd_cwnd < tp->snd_wnd) {
		tp->t_bytes_acked += acked;
		if (tp->t_bytes_acked > tp->snd_cwnd) {
			tp->t_bytes_acked -= tp->snd_cwnd;
			tp->snd_cwnd += tp->t_maxseg;
		}
	}
}
コード例 #5
0
ファイル: tcp_ledbat.c プロジェクト: Andromeda-OS/Kernel
/* Function to handle an in-sequence ack which is fast-path processing 
 * of an in sequence ack in tcp_input function (called as header prediction). 
 * This gets called only during congestion avoidance phase.
 */
void
tcp_ledbat_congestion_avd(struct tcpcb *tp, struct tcphdr *th) {
	int acked = 0;
	u_int32_t incr = 0;

	acked = BYTES_ACKED(th, tp);
	tp->t_bytes_acked += acked;
	if (tp->t_bytes_acked > tp->snd_cwnd) {
		tp->t_bytes_acked -= tp->snd_cwnd;
		incr = tp->t_maxseg;
	}

	if (tp->snd_cwnd < tp->snd_wnd && incr > 0) {
		update_cwnd(tp, incr);
	}
}
コード例 #6
0
ファイル: tcp_ledbat.c プロジェクト: Andromeda-OS/Kernel
/* Function to process an ack.
 */
void
tcp_ledbat_ack_rcvd(struct tcpcb *tp, struct tcphdr *th) {
	/*
	 * RFC 3465 - Appropriate Byte Counting.
	 *
	 * If the window is currently less than ssthresh,
	 * open the window by the number of bytes ACKed by
	 * the last ACK, however clamp the window increase
	 * to an upper limit "L".
	 *
	 * In congestion avoidance phase, open the window by
	 * one segment each time "bytes_acked" grows to be
	 * greater than or equal to the congestion window.
	 */

	register u_int cw = tp->snd_cwnd;
	register u_int incr = tp->t_maxseg;
	int acked = 0;

	acked = BYTES_ACKED(th, tp);
	tp->t_bytes_acked += acked;
	if (cw >= tp->bg_ssthresh) {
		/* congestion-avoidance */
		if (tp->t_bytes_acked < cw) {
			/* No need to increase yet. */
			incr = 0;
		}
	} else {
		/*
		 * If the user explicitly enables RFC3465
		 * use 2*SMSS for the "L" param.  Otherwise
		 * use the more conservative 1*SMSS.
		 *
		 * (See RFC 3465 2.3 Choosing the Limit)
		 */
		u_int abc_lim;

		abc_lim = (tcp_do_rfc3465_lim2 &&
			tp->snd_nxt == tp->snd_max) ? incr * 2 : incr;

		incr = lmin(acked, abc_lim);
	}
	if (tp->t_bytes_acked >= cw)
		tp->t_bytes_acked -= cw;
	if (incr > 0) 
		update_cwnd(tp, incr);
}
コード例 #7
0
ファイル: tcp_cubic.c プロジェクト: suxinde2009/Kernel
/*
 * Compute the window growth if standard TCP (AIMD) was used with 
 * a backoff of 0.5 and additive increase of 1 packet per RTT.
 * 
 * TCP window at time t can be calculated using the following equation
 * with beta as 0.8 
 *
 * W(t) <- Wmax * beta + 3 * ((1 - beta)/(1 + beta)) * t/RTT
 *
 */
static uint32_t
tcp_cubic_tcpwin(struct tcpcb *tp, struct tcphdr *th)
{
	if (tp->t_ccstate->cub_tcp_win == 0) {
		tp->t_ccstate->cub_tcp_win = min(tp->snd_cwnd, tp->snd_wnd);
		tp->t_ccstate->cub_tcp_bytes_acked = 0;
	} else {
		tp->t_ccstate->cub_tcp_bytes_acked +=
		    BYTES_ACKED(th, tp);
		if (tp->t_ccstate->cub_tcp_bytes_acked >=
		    tp->t_ccstate->cub_tcp_win) {
			tp->t_ccstate->cub_tcp_bytes_acked -=
			    tp->t_ccstate->cub_tcp_win;
			tp->t_ccstate->cub_tcp_win += tp->t_maxseg;
		}
	}	
	return (tp->t_ccstate->cub_tcp_win);
}