Index: sys/netinet/tcp_input.c =================================================================== --- sys/netinet/tcp_input.c +++ sys/netinet/tcp_input.c @@ -2563,7 +2563,8 @@ */ if (th->th_ack != tp->snd_una || ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK) && + ((to.to_flags & TOF_SACK) || + (!TAILQ_EMPTY(&tp->snd_holes))) && !sack_changed)) break; else if (!tcp_timer_active(tp, TT_REXMT)) @@ -2576,7 +2577,8 @@ IN_FASTRECOVERY(tp->t_flags)) { tcp_do_prr_ack(tp, th, &to); } else if ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK) && + ((to.to_flags & TOF_SACK) || + (!TAILQ_EMPTY(&tp->snd_holes))) && IN_FASTRECOVERY(tp->t_flags)) { int awnd; @@ -2650,7 +2652,8 @@ * cc_cong_signal. */ if ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK)) { + ((to.to_flags & TOF_SACK) || + (!TAILQ_EMPTY(&tp->snd_holes)))) { tp->sackhint.prr_delivered = tp->sackhint.sacked_bytes; } else { @@ -2663,7 +2666,8 @@ tp->snd_nxt - tp->snd_una); } if ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK)) { + ((to.to_flags & TOF_SACK) || + (!TAILQ_EMPTY(&tp->snd_holes)))) { TCPSTAT_INC( tcps_sack_recovery_episode); tp->snd_recover = tp->snd_nxt;