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.
*/