Index: sys/netinet/cc/cc.h =================================================================== --- sys/netinet/cc/cc.h +++ sys/netinet/cc/cc.h @@ -81,6 +81,7 @@ int bytes_this_ack; /* # bytes acked by the current ACK. */ tcp_seq curack; /* Most recent ACK. */ uint32_t flags; /* Flags for cc_var (see below) */ + int32_t sample_rtt_us; /* RTT as measured by this ack in us */ int type; /* Indicates which ptr is valid in ccvc. */ union ccv_container { struct tcpcb *tcp; Index: sys/netinet/tcp_input.c =================================================================== --- sys/netinet/tcp_input.c +++ sys/netinet/tcp_input.c @@ -304,9 +304,10 @@ * CC wrapper hook functions */ void -cc_ack_received(struct tcpcb *tp, struct tcphdr *th, uint16_t nsegs, - uint16_t type) +cc_ack_received(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to, + uint16_t nsegs, uint16_t type) { + int ts; INP_WLOCK_ASSERT(tp->t_inpcb); tp->ccv->nsegs = nsegs; @@ -333,6 +334,12 @@ if (CC_ALGO(tp)->ack_received != NULL) { /* XXXLAS: Find a way to live without this */ tp->ccv->curack = th->th_ack; + ts = tcp_ts_getticks(); + if (to->to_tsecr && TSTMP_LT(to->to_tsecr, ts)) + tp->ccv->sample_rtt_us = + (ts - to->to_tsecr)*(1000000/*USEC_PER_SEC*//hz); + else + tp->ccv->sample_rtt_us = -1; CC_ALGO(tp)->ack_received(tp->ccv, type); } } @@ -642,6 +649,7 @@ m = *mp; *mp = NULL; to.to_flags = 0; + to.to_tsecr = 0; TCPSTAT_INC(tcps_rcvtotal); #ifdef INET6 @@ -1781,7 +1789,7 @@ * typically means increasing the congestion * window. */ - cc_ack_received(tp, th, nsegs, CC_ACK); + cc_ack_received(tp, th, &to, nsegs, CC_ACK); tp->snd_una = th->th_ack; /* @@ -2581,7 +2589,7 @@ tp->t_dupacks = 0; else if (++tp->t_dupacks > tcprexmtthresh || IN_FASTRECOVERY(tp->t_flags)) { - cc_ack_received(tp, th, nsegs, + cc_ack_received(tp, th, &to, nsegs, CC_DUPACK); if ((tp->t_flags & TF_SACK_PERMIT) && IN_FASTRECOVERY(tp->t_flags)) { @@ -2641,7 +2649,7 @@ } /* Congestion signal before ack. */ cc_cong_signal(tp, th, CC_NDUPACK); - cc_ack_received(tp, th, nsegs, + cc_ack_received(tp, th, &to, nsegs, CC_DUPACK); tcp_timer_activate(tp, TT_REXMT, 0); tp->t_rtttime = 0; @@ -2679,7 +2687,7 @@ * segment. Restore the original * snd_cwnd after packet transmission. */ - cc_ack_received(tp, th, nsegs, + cc_ack_received(tp, th, &to, nsegs, CC_DUPACK); uint32_t oldcwnd = tp->snd_cwnd; tcp_seq oldsndmax = tp->snd_max; @@ -2847,7 +2855,7 @@ * control related information. This typically means increasing * the congestion window. */ - cc_ack_received(tp, th, nsegs, CC_ACK); + cc_ack_received(tp, th, &to, nsegs, CC_ACK); SOCKBUF_LOCK(&so->so_snd); if (acked > sbavail(&so->so_snd)) { Index: sys/netinet/tcp_stacks/fastpath.c =================================================================== --- sys/netinet/tcp_stacks/fastpath.c +++ sys/netinet/tcp_stacks/fastpath.c @@ -285,7 +285,7 @@ * typically means increasing the congestion * window. */ - cc_ack_received(tp, th, nsegs, CC_ACK); + cc_ack_received(tp, th, &to, nsegs, CC_ACK); tp->snd_una = th->th_ack; /* @@ -1097,7 +1097,7 @@ tp->t_dupacks = 0; else if (++tp->t_dupacks > tcprexmtthresh || IN_FASTRECOVERY(tp->t_flags)) { - cc_ack_received(tp, th, nsegs, + cc_ack_received(tp, th, &to, nsegs, CC_DUPACK); if ((tp->t_flags & TF_SACK_PERMIT) && IN_FASTRECOVERY(tp->t_flags)) { @@ -1148,7 +1148,7 @@ } /* Congestion signal before ack. */ cc_cong_signal(tp, th, CC_NDUPACK); - cc_ack_received(tp, th, nsegs, + cc_ack_received(tp, th, &to, nsegs, CC_DUPACK); tcp_timer_activate(tp, TT_REXMT, 0); tp->t_rtttime = 0; @@ -1183,7 +1183,7 @@ * segment. Restore the original * snd_cwnd after packet transmission. */ - cc_ack_received(tp, th, nsegs, + cc_ack_received(tp, th, &to, nsegs, CC_DUPACK); uint32_t oldcwnd = tp->snd_cwnd; tcp_seq oldsndmax = tp->snd_max; @@ -1338,7 +1338,7 @@ * control related information. This typically means increasing * the congestion window. */ - cc_ack_received(tp, th, nsegs, CC_ACK); + cc_ack_received(tp, th, &to, nsegs, CC_ACK); SOCKBUF_LOCK(&so->so_snd); if (acked > sbavail(&so->so_snd)) { @@ -2150,7 +2150,7 @@ * typically means increasing the congestion * window. */ - cc_ack_received(tp, th, nsegs, CC_ACK); + cc_ack_received(tp, th, &to, nsegs, CC_ACK); tp->snd_una = th->th_ack; tp->t_dupacks = 0; Index: sys/netinet/tcp_var.h =================================================================== --- sys/netinet/tcp_var.h +++ sys/netinet/tcp_var.h @@ -785,7 +785,7 @@ struct tcphdr *, struct mbuf *, int); void tcp_xmit_timer(struct tcpcb *, int); void tcp_newreno_partial_ack(struct tcpcb *, struct tcphdr *); -void cc_ack_received(struct tcpcb *tp, struct tcphdr *th, +void cc_ack_received(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to, uint16_t nsegs, uint16_t type); void cc_conn_init(struct tcpcb *tp); void cc_post_recovery(struct tcpcb *tp, struct tcphdr *th);