Apply by doing:
        cd /usr/src
        patch -p0 < 030_sack.patch

And then rebuild your kernel.

--- sys/netinet/tcp_input.c.orig	Mon Mar 28 21:48:25 2005
+++ sys/netinet/tcp_input.c	Mon Mar 28 21:49:41 2005
@@ -133,6 +133,10 @@ struct timeval tcp_synack_ppslim_last;
 #define TSTMP_LT(a,b)	((int)((a)-(b)) < 0)
 #define TSTMP_GEQ(a,b)	((int)((a)-(b)) >= 0)
 
+/* for TCP SACK comparisons */
+#define	SEQ_MIN(a,b)	(SEQ_LT(a,b) ? (a) : (b))
+#define	SEQ_MAX(a,b)	(SEQ_GT(a,b) ? (a) : (b))
+
 /*
  * Neighbor Discovery, Neighbor Unreachability Detection Upper layer hint.
  */
@@ -2282,8 +2286,7 @@ tcp_dooptions(tp, cp, cnt, th, m, iphlen
 				tp->t_flags |= TF_SACK_PERMIT;
 			break;
 		case TCPOPT_SACK:
-			if (tcp_sack_option(tp, th, cp, optlen))
-				continue;
+			tcp_sack_option(tp, th, cp, optlen);
 			break;
 #endif
 #ifdef TCP_SIGNATURE
@@ -2547,11 +2550,10 @@ tcp_update_sack_list(tp)
 }
 
 /*
- * Process the TCP SACK option.  Returns 1 if tcp_dooptions() should continue,
- * and 0 otherwise, if the option was fine.  tp->snd_holes is an ordered list
+ * Process the TCP SACK option.  tp->snd_holes is an ordered list
  * of holes (oldest to newest, in terms of the sequence space).
  */
-int
+void
 tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
 {
 	int tmp_olen;
@@ -2559,11 +2561,18 @@ tcp_sack_option(struct tcpcb *tp, struct
 	struct sackhole *cur, *p, *temp;
 
 	if (!tp->sack_enable)
-		return (1);
-
+		return;
+	/* SACK without ACK doesn't make sense. */
+	if ((th->th_flags & TH_ACK) == 0)
+	       return;
+	/* Make sure the ACK on this segment is in [snd_una, snd_max]. */
+	if (SEQ_LT(th->th_ack, tp->snd_una) ||
+	    SEQ_GT(th->th_ack, tp->snd_max))
+		return;
 	/* Note: TCPOLEN_SACK must be 2*sizeof(tcp_seq) */
 	if (optlen <= 2 || (optlen - 2) % TCPOLEN_SACK != 0)
-		return (1);
+		return;
+	/* Note: TCPOLEN_SACK must be 2*sizeof(tcp_seq) */
 	tmp_cp = cp + 2;
 	tmp_olen = optlen - 2;
 	if (tp->snd_numholes < 0)
@@ -2600,7 +2609,7 @@ tcp_sack_option(struct tcpcb *tp, struct
 			    pool_get(&sackhl_pool, PR_NOWAIT);
 			if (tp->snd_holes == NULL) {
 				/* ENOBUFS, so ignore SACKed block for now*/
-				continue;
+				goto done;
 			}
 			cur = tp->snd_holes;
 			cur->start = th->th_ack;
@@ -2664,7 +2673,7 @@ tcp_sack_option(struct tcpcb *tp, struct
 				}
 				/* otherwise, move start of hole forward */
 				cur->start = sack.end;
-				cur->rxmit = max (cur->rxmit, cur->start);
+				cur->rxmit = SEQ_MAX(cur->rxmit, cur->start);
 				p = cur;
 				cur = cur->next;
 				continue;
@@ -2678,7 +2687,7 @@ tcp_sack_option(struct tcpcb *tp, struct
 					    sack.start);
 #endif /* TCP_FACK */
 				cur->end = sack.start;
-				cur->rxmit = min(cur->rxmit, cur->end);
+				cur->rxmit = SEQ_MIN(cur->rxmit, cur->end);
 				cur->dups++;
 				if (((sack.end - cur->end)/tp->t_maxseg) >=
 				    tcprexmtthresh)
@@ -2696,7 +2705,7 @@ tcp_sack_option(struct tcpcb *tp, struct
 				temp = (struct sackhole *)
 				    pool_get(&sackhl_pool, PR_NOWAIT);
 				if (temp == NULL)
-					continue; /* ENOBUFS */
+					goto done; /* ENOBUFS */
 #if defined(TCP_SACK) && defined(TCP_FACK)
 				if (SEQ_GT(cur->rxmit, sack.end))
 					tp->retran_data -=
@@ -2711,9 +2720,9 @@ tcp_sack_option(struct tcpcb *tp, struct
 				temp->start = sack.end;
 				temp->end = cur->end;
 				temp->dups = cur->dups;
-				temp->rxmit = max(cur->rxmit, temp->start);
+				temp->rxmit = SEQ_MAX(cur->rxmit, temp->start);
 				cur->end = sack.start;
-				cur->rxmit = min(cur->rxmit, cur->end);
+				cur->rxmit = SEQ_MIN(cur->rxmit, cur->end);
 				cur->dups++;
 				if (((sack.end - cur->end)/tp->t_maxseg) >=
 					tcprexmtthresh)
@@ -2733,7 +2742,7 @@ tcp_sack_option(struct tcpcb *tp, struct
 			temp = (struct sackhole *)
 			    pool_get(&sackhl_pool, PR_NOWAIT);
 			if (temp == NULL)
-				continue; /* ENOBUFS */
+				goto done; /* ENOBUFS */
 			temp->start = tp->rcv_lastsack;
 			temp->end = sack.start;
 			temp->dups = min(tcprexmtthresh,
@@ -2747,6 +2756,7 @@ tcp_sack_option(struct tcpcb *tp, struct
 			tp->snd_numholes++;
 		}
 	}
+done:
 #if defined(TCP_SACK) && defined(TCP_FACK)
 	/*
 	 * Update retran_data and snd_awnd.  Go through the list of
@@ -2762,7 +2772,7 @@ tcp_sack_option(struct tcpcb *tp, struct
 	    tp->retran_data;
 #endif /* TCP_FACK */
 
-	return (0);
+	return;
 }
 
 /*
--- sys/netinet/tcp_subr.c.orig	Mon Mar 28 21:48:44 2005
+++ sys/netinet/tcp_subr.c	Mon Mar 28 21:49:42 2005
@@ -149,6 +149,9 @@ int	tcp_syn_bucket_limit = 3*TCP_SYN_BUC
 struct	syn_cache_head tcp_syn_cache[TCP_SYN_HASH_SIZE];
 
 int tcp_reass_limit = NMBCLUSTERS / 2; /* hardlimit for tcpqe_pool */
+#ifdef TCP_SACK
+int tcp_sackhole_limit = 32*1024; /* hardlimit for sackhl_pool */
+#endif
 
 #ifdef INET6
 extern int ip6_defhlim;
@@ -180,6 +183,7 @@ tcp_init()
 #ifdef TCP_SACK
 	pool_init(&sackhl_pool, sizeof(struct sackhole), 0, 0, 0, "sackhlpl",
 	    NULL);
+	pool_sethardlimit(&sackhl_pool, tcp_sackhole_limit, NULL, 0);
 #endif /* TCP_SACK */
 	in_pcbinit(&tcbtable, tcbhashsize);
 	tcp_now = arc4random() / 2;
--- sys/netinet/tcp_usrreq.c.orig	Mon Mar 28 21:49:00 2005
+++ sys/netinet/tcp_usrreq.c	Mon Mar 28 21:49:42 2005
@@ -916,6 +916,20 @@ tcp_sysctl(name, namelen, oldp, oldlenp,
 			tcp_reass_limit = nval;
 		}
 		return (0);
+#ifdef TCP_SACK
+	case TCPCTL_SACKHOLE_LIMIT:
+		nval = tcp_sackhole_limit;
+		error = sysctl_int(oldp, oldlenp, newp, newlen, &nval);
+		if (error)
+			return (error);
+		if (nval != tcp_sackhole_limit) {
+			error = pool_sethardlimit(&sackhl_pool, nval, NULL, 0);
+			if (error)
+				return (error);
+			tcp_sackhole_limit = nval;
+		}
+		return (0);
+#endif
 	default:
 		if (name[0] < TCPCTL_MAXID)
 			return (sysctl_int_arr(tcpctl_vars, name, namelen,
--- sys/netinet/tcp_var.h.orig	Mon Mar 28 21:49:15 2005
+++ sys/netinet/tcp_var.h	Mon Mar 28 21:59:15 2005
@@ -465,7 +465,8 @@ struct	tcpstat {
 #define	TCPCTL_SYN_BUCKET_LIMIT	16 /* max size of hash bucket */
 #define	TCPCTL_RFC3390	       17 /* enable/disable RFC3390 increased cwnd */
 #define	TCPCTL_REASS_LIMIT     18 /* max entries for tcp reass queues */
-#define	TCPCTL_MAXID	       19
+#define	TCPCTL_SACKHOLE_LIMIT  19 /* max entries for tcp sack queues */
+#define	TCPCTL_MAXID	       20
 
 #define	TCPCTL_NAMES { \
 	{ 0, 0 }, \
@@ -487,6 +488,7 @@ struct	tcpstat {
 	{ "synbucketlimit", 	CTLTYPE_INT }, \
 	{ "rfc3390", 	CTLTYPE_INT }, \
 	{ "reasslimit", 	CTLTYPE_INT }, \
+	{ "sackholelimit",	CTLTYPE_INT }, \
 }
 
 #define	TCPCTL_VARS { \
@@ -508,6 +510,7 @@ struct	tcpstat {
 	&tcp_syn_cache_limit, \
 	&tcp_syn_bucket_limit, \
 	&tcp_do_rfc3390, \
+	NULL, \
 	NULL \
 }
 
@@ -526,6 +529,7 @@ extern	int tcp_ack_on_push;	/* ACK immed
 #ifdef TCP_SACK
 extern	int tcp_do_sack;	/* SACK enabled/disabled */
 extern	struct pool sackhl_pool;
+extern	int tcp_sackhole_limit;	/* max entries for tcp sack queues */
 #endif
 extern	int tcp_do_ecn;		/* RFC3168 ECN enabled/disabled? */
 extern	int tcp_do_rfc3390;	/* RFC3390 Increasing TCP's Initial Window */
@@ -597,7 +601,7 @@ int	 tcp_usrreq(struct socket *,
 void	 tcp_xmit_timer(struct tcpcb *, int);
 void	 tcpdropoldhalfopen(struct tcpcb *, u_int16_t);
 #ifdef TCP_SACK
-int	 tcp_sack_option(struct tcpcb *,struct tcphdr *,u_char *,int);
+void	 tcp_sack_option(struct tcpcb *,struct tcphdr *,u_char *,int);
 void	 tcp_update_sack_list(struct tcpcb *tp);
 void	 tcp_del_sackholes(struct tcpcb *, struct tcphdr *);
 void	 tcp_clean_sackreport(struct tcpcb *tp);