]> git.saurik.com Git - apple/network_cmds.git/blobdiff - alias/alias.c
network_cmds-245.1.3.tar.gz
[apple/network_cmds.git] / alias / alias.c
index fffcae238162f6d7fa9d05d3812a36f8fa0bc74c..f5180d2022fe2186345d1e558251f34afbe7e58c 100644 (file)
@@ -3,19 +3,20 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * 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. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
  * 
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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,
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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_HEADER_END@
  */
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
     TcpMonitorIn()  -- These routines monitor TCP connections, and
     TcpMonitorOut()    delete a link when a connection is closed.
 
     TcpMonitorIn()  -- These routines monitor TCP connections, and
     TcpMonitorOut()    delete a link when a connection is closed.
 
+       DoMSSClamp()    -- Clamps the MSS of the given TCP header to the
+                       value in packetAliasMSS.
+
 These routines look for SYN, FIN and RST flags to determine when TCP
 connections open and close.  When a TCP connection closes, the data
 structure containing packet aliasing information is deleted after
 These routines look for SYN, FIN and RST flags to determine when TCP
 connections open and close.  When a TCP connection closes, the data
 structure containing packet aliasing information is deleted after
@@ -176,6 +180,55 @@ static void TcpMonitorIn(struct ip *, struct alias_link *);
 static void TcpMonitorOut(struct ip *, struct alias_link *);
 
 
 static void TcpMonitorOut(struct ip *, struct alias_link *);
 
 
+static u_short packetAliasMSS;
+
+void PacketAliasClampMSS(u_short mss)
+{
+    packetAliasMSS = mss;
+}
+
+static void DoMSSClamp(struct tcphdr *tc)
+{
+    u_char *option    = (u_char *) tc + sizeof(*tc);
+    u_char *optionEnd = option + ((tc->th_off << 2) - sizeof(*tc));
+
+    while (optionEnd > option)
+    {
+        switch (option[0])
+        {
+            case TCPOPT_EOL:
+                option = optionEnd;
+                break;
+
+            case TCPOPT_NOP:
+                ++option;
+                break;
+
+            case TCPOPT_MAXSEG:
+                if (option[1] == 4)
+                {
+                    u_short *mssPtr = (u_short *) option + 1;
+                    u_short mssVal  = ntohs(*mssPtr);
+
+                    if (packetAliasMSS < mssVal)
+                    {
+                        int accumulate = mssVal;
+                        accumulate -= packetAliasMSS;
+                        *mssPtr = htons(packetAliasMSS);
+                        ADJUST_CHECKSUM(accumulate, tc->th_sum);
+                    }
+
+                    option = optionEnd;
+                }
+                break;
+
+            default:
+                option += option[1];
+                break;
+        }
+    }
+}
+
 static void
 TcpMonitorIn(struct ip *pip, struct alias_link *link)
 {
 static void
 TcpMonitorIn(struct ip *pip, struct alias_link *link)
 {
@@ -189,7 +242,12 @@ TcpMonitorIn(struct ip *pip, struct alias_link *link)
             if (tc->th_flags & TH_RST)
                 SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED);
             else if (tc->th_flags & TH_SYN)
             if (tc->th_flags & TH_RST)
                 SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED);
             else if (tc->th_flags & TH_SYN)
+            {
                 SetStateIn(link, ALIAS_TCP_STATE_CONNECTED);
                 SetStateIn(link, ALIAS_TCP_STATE_CONNECTED);
+
+                if (packetAliasMSS)
+                    DoMSSClamp(tc);
+            }
             break;
         case ALIAS_TCP_STATE_CONNECTED:
             if (tc->th_flags & (TH_FIN | TH_RST))
             break;
         case ALIAS_TCP_STATE_CONNECTED:
             if (tc->th_flags & (TH_FIN | TH_RST))
@@ -211,7 +269,12 @@ TcpMonitorOut(struct ip *pip, struct alias_link *link)
             if (tc->th_flags & TH_RST)
                 SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED);
             else if (tc->th_flags & TH_SYN)
             if (tc->th_flags & TH_RST)
                 SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED);
             else if (tc->th_flags & TH_SYN)
+            {
                 SetStateOut(link, ALIAS_TCP_STATE_CONNECTED);
                 SetStateOut(link, ALIAS_TCP_STATE_CONNECTED);
+
+                if (packetAliasMSS)
+                    DoMSSClamp(tc);
+            }
             break;
         case ALIAS_TCP_STATE_CONNECTED:
             if (tc->th_flags & (TH_FIN | TH_RST))
             break;
         case ALIAS_TCP_STATE_CONNECTED:
             if (tc->th_flags & (TH_FIN | TH_RST))