Apply by doing: cd /usr/src/sys patch -p0 < 004_tcpsack.patch And then rebuild your kernel. Index: netinet/tcp_input.c =================================================================== RCS file: /cvs/src/sys/netinet/tcp_input.c,v retrieving revision 1.33 retrieving revision 1.34 diff -u -r1.33 -r1.34 --- src/sys/netinet/tcp_input.c 1999/03/27 21:04:20 1.33 +++ src/sys/netinet/tcp_input.c 1999/04/21 21:38:58 1.34 @@ -875,6 +875,14 @@ tcpstat.tcps_rcvackbyte += acked; sbdrop(&so->so_snd, acked); tp->snd_una = th->th_ack; +#if defined(TCP_SACK) || defined(TCP_NEWRENO) + /* + * We want snd_last to track snd_una so + * as to avoid sequence wraparound problems + * for very large transfers. + */ + tp->snd_last = tp->snd_una; +#endif /* TCP_SACK or TCP_NEWRENO */ #if defined(TCP_SACK) && defined(TCP_FACK) tp->snd_fack = tp->snd_una; tp->retran_data = 0; @@ -2978,7 +2986,11 @@ tp->t_timer[TCPT_REXMT] = 0; tp->t_rtt = 0; tp->snd_nxt = th->th_ack; - tp->snd_cwnd = tp->t_maxseg; + /* + * Set snd_cwnd to one segment beyond acknowledged offset + * (tp->snd_una not yet updated when this function is called) + */ + tp->snd_cwnd = tp->t_maxseg + (th->th_ack - tp->snd_una); (void) tcp_output(tp); tp->snd_cwnd = ocwnd; if (SEQ_GT(onxt, tp->snd_nxt)) Index: netinet/tcp_timer.c =================================================================== RCS file: /cvs/src/sys/netinet/tcp_timer.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- src/sys/netinet/tcp_timer.c 1999/01/27 16:47:29 1.11 +++ src/sys/netinet/tcp_timer.c 1999/04/21 21:38:58 1.12 @@ -247,6 +247,13 @@ tp->t_srtt = 0; } tp->snd_nxt = tp->snd_una; +#if defined(TCP_SACK) || defined(TCP_NEWRENO) + /* + * Note: We overload snd_last to function also as the + * snd_last variable described in RFC 2582 + */ + tp->snd_last = tp->snd_max; +#endif /* TCP_SACK or TCP_NEWRENO */ /* * If timing a segment in this window, stop the timer. */