]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netinet/tcp_sack.c
xnu-1699.22.73.tar.gz
[apple/xnu.git] / bsd / netinet / tcp_sack.c
index 897f149ee69455ea4dce8653936cd85cf9c589aa..69fb8a7d08f36d2fa2aa7dbba5095765afe467c3 100644 (file)
@@ -1,31 +1,29 @@
 /*
- * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2004,2007 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
- * This file contains Original Code and/or Modifications of Original Code 
- * as defined in and that are subject to the Apple Public Source License 
- * Version 2.0 (the 'License'). You may not use this file except in 
- * compliance with the License.  The rights granted to you under the 
- * License may not be used to create, or enable the creation or 
- * redistribution of, unlawful or unlicensed copies of an Apple operating 
- * system, or to circumvent, violate, or enable the circumvention or 
- * violation of, any terms of an Apple operating system software license 
- * agreement.
- *
- * Please obtain a copy of the License at 
- * http://www.opensource.apple.com/apsl/ and read it before using this 
- * file.
- *
- * The Original Code and all software distributed under the License are 
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
- * Please see the License for the specific language governing rights and 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
  * limitations under the License.
- *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
@@ -74,6 +72,8 @@
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 
+#include <kern/zalloc.h>
+
 #include <net/route.h>
 
 #include <netinet/in.h>
 #endif /*IPSEC*/
 
 int    tcp_do_sack = 1;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, sack, CTLFLAG_RW, &tcp_do_sack, 0,
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, sack, CTLFLAG_RW | CTLFLAG_LOCKED, &tcp_do_sack, 0,
        "Enable/Disable TCP SACK support");
 static int tcp_sack_maxholes = 128;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, sack_maxholes, CTLFLAG_RW,
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, sack_maxholes, CTLFLAG_RW | CTLFLAG_LOCKED,
        &tcp_sack_maxholes, 0, 
     "Maximum number of TCP SACK holes allowed per connection");
 
 static int tcp_sack_globalmaxholes = 65536;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, sack_globalmaxholes, CTLFLAG_RW,
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, sack_globalmaxholes, CTLFLAG_RW | CTLFLAG_LOCKED,
        &tcp_sack_globalmaxholes, 0, 
     "Global maximum number of TCP SACK holes");
 
 static int tcp_sack_globalholes = 0;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, sack_globalholes, CTLFLAG_RD,
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, sack_globalholes, CTLFLAG_RD | CTLFLAG_LOCKED,
     &tcp_sack_globalholes, 0,
     "Global number of TCP SACK holes currently allocated");
 
@@ -203,6 +203,18 @@ tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_start, tcp_seq rcv_end)
 
        /* Save the number of SACK blocks. */
        tp->rcv_numsacks = num_head + num_saved;
+
+       /* If we are requesting SACK recovery, reset the stretch-ack state
+        * so that connection will generate more acks after recovery and
+        * sender's cwnd will open.
+        */
+       if ((tp->t_flags & TF_STRETCHACK) != 0 && tp->rcv_numsacks > 0)
+               tcp_reset_stretch_ack(tp);
+
+#if TRAFFIC_MGT
+       if (tp->acc_iaj > 0 && tp->rcv_numsacks > 0) 
+               reset_acc_iaj(tp);
+#endif /* TRAFFIC_MGT */
 }
 
 /*
@@ -211,13 +223,8 @@ tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_start, tcp_seq rcv_end)
 void
 tcp_clean_sackreport( struct tcpcb *tp)
 {
-/*
-       int i;
 
        tp->rcv_numsacks = 0;
-       for (i = 0; i < MAX_SACK_BLKS; i++)
-               tp->sackblks[i].start = tp->sackblks[i].end=0;
-*/
        bzero(&tp->sackblks[0], sizeof (struct sackblk) * MAX_SACK_BLKS);
 }
 
@@ -328,16 +335,20 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
        }
        /*
         * Append received valid SACK blocks to sack_blocks[].
+        * Check that the SACK block range is valid.
         */
-       for (i = 0; i < to->to_nsacks; i++) {
-               bcopy((to->to_sacks + i * TCPOLEN_SACK), &sack, sizeof(sack));
-               sack.start = ntohl(sack.start);
-               sack.end = ntohl(sack.end);
-               if (SEQ_GT(sack.end, sack.start) &&
-                   SEQ_GT(sack.start, tp->snd_una) &&
-                   SEQ_GT(sack.start, th_ack) &&
-                   SEQ_LEQ(sack.end, tp->snd_max))
-                       sack_blocks[num_sack_blks++] = sack;
+               for (i = 0; i < to->to_nsacks; i++) {
+                       bcopy((to->to_sacks + i * TCPOLEN_SACK),
+                           &sack, sizeof(sack));
+                       sack.start = ntohl(sack.start);
+                       sack.end = ntohl(sack.end);
+                       if (SEQ_GT(sack.end, sack.start) &&
+                           SEQ_GT(sack.start, tp->snd_una) &&
+                           SEQ_GT(sack.start, th_ack) &&
+                           SEQ_LT(sack.start, tp->snd_max) &&
+                           SEQ_GT(sack.end, tp->snd_una) &&
+                           SEQ_LEQ(sack.end, tp->snd_max))
+                               sack_blocks[num_sack_blks++] = sack;
        }
 
        /*
@@ -504,6 +515,8 @@ tcp_free_sackholes(struct tcpcb *tp)
        while ((q = TAILQ_FIRST(&tp->snd_holes)) != NULL)
                tcp_sackhole_remove(tp, q);
        tp->sackhint.sack_bytes_rexmit = 0;
+       tp->sackhint.nexthole = NULL;
+       tp->sack_newdata = 0;
 
 }