/* * If the ack type is CC_ACK, and the inferred queueing delay is greater than * the Qmin threshold, cwnd is reduced probabilistically. When backing off due * to delay, HD behaves like NewReno when an ECN signal is received. HD behaves * as NewReno in all other circumstances. */ static void hd_ack_received(struct cc_var *ccv, uint16_t ack_type) { struct ertt *e_t; int qdly; if (ack_type == CC_ACK) { //ScenSim-Port// e_t = khelp_get_osd(CCV(ccv, osd), ertt_id); e_t = &ccv->ertt_porting; //ScenSim-Port// if (e_t->rtt && e_t->minrtt && V_hd_qthresh > 0) { qdly = e_t->rtt - e_t->minrtt; if (qdly > V_hd_qmin && !IN_RECOVERY(CCV(ccv, t_flags))) { /* Probabilistic backoff of cwnd. */ if (should_backoff(qdly, e_t->maxrtt - e_t->minrtt)) { /* * Update cwnd and ssthresh update to * half cwnd and behave like an ECN (ie * not a packet loss). */ newreno_cc_algo.cong_signal(ccv, CC_ECN); return; } } } } newreno_cc_algo.ack_received(ccv, ack_type); /* As for NewReno. */ }
static void newreno_ack_received(struct cc_var *ccv, uint16_t type) { if (type == CC_ACK && !IN_RECOVERY(CCV(ccv, t_flags)) && (ccv->flags & CCF_CWND_LIMITED)) { u_int cw = CCV(ccv, snd_cwnd); u_int incr = CCV(ccv, t_maxseg); /* * Regular in-order ACK, open the congestion window. * Method depends on which congestion control state we're * in (slow start or cong avoid) and if ABC (RFC 3465) is * enabled. * * slow start: cwnd <= ssthresh * cong avoid: cwnd > ssthresh * * slow start and ABC (RFC 3465): * Grow cwnd exponentially by the amount of data * ACKed capping the max increment per ACK to * (abc_l_var * maxseg) bytes. * * slow start without ABC (RFC 5681): * Grow cwnd exponentially by maxseg per ACK. * * cong avoid and ABC (RFC 3465): * Grow cwnd linearly by maxseg per RTT for each * cwnd worth of ACKed data. * * cong avoid without ABC (RFC 5681): * Grow cwnd linearly by approximately maxseg per RTT using * maxseg^2 / cwnd per ACK as the increment. * If cwnd > maxseg^2, fix the cwnd increment at 1 byte to * avoid capping cwnd. */ if (cw > CCV(ccv, snd_ssthresh)) { if (V_tcp_do_rfc3465) { if (ccv->flags & CCF_ABC_SENTAWND) ccv->flags &= ~CCF_ABC_SENTAWND; else incr = 0; } else incr = max((incr * incr / cw), 1); } else if (V_tcp_do_rfc3465) { /* * In slow-start with ABC enabled and no RTO in sight? * (Must not use abc_l_var > 1 if slow starting after * an RTO. On RTO, snd_nxt = snd_una, so the * snd_nxt == snd_max check is sufficient to * handle this). * * XXXLAS: Find a way to signal SS after RTO that * doesn't rely on tcpcb vars. */ if (CCV(ccv, snd_nxt) == CCV(ccv, snd_max)) incr = min(ccv->bytes_this_ack, V_tcp_abc_l_var * CCV(ccv, t_maxseg)); else incr = min(ccv->bytes_this_ack, CCV(ccv, t_maxseg)); } /* ABC is on by default, so incr equals 0 frequently. */ if (incr > 0) CCV(ccv, snd_cwnd) = min(cw + incr, TCP_MAXWIN << CCV(ccv, snd_scale)); } }