]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Input.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Input.c
index b29e6cb67202abfc70955bdcb93fbdd89f4c82c1..f48efdac7cd8423ccc6e9db6b1f03e8dda33fc3a 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   TCP input process routines.\r
 \r
-Copyright (c) 2005 - 2009, Intel Corporation<BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php<BR>\r
@@ -32,8 +32,8 @@ TcpSeqAcceptable (
   IN TCP_SEG *Seg\r
   )\r
 {\r
-  return (TCP_SEQ_LEQ (Tcb->RcvWl2, Seg->End) &&\r
-          TCP_SEQ_LEQ (Seg->Seq, Tcb->RcvWl2 + Tcb->RcvWnd));\r
+  return (TCP_SEQ_LEQ (Tcb->RcvNxt, Seg->End) &&\r
+          TCP_SEQ_LT (Seg->Seq, Tcb->RcvWl2 + Tcb->RcvWnd));\r
 }\r
 \r
 \r
@@ -61,7 +61,7 @@ TcpFastRecover (
     //\r
     // Step 1A: Invoking fast retransmission.\r
     //\r
-    FlightSize = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna);\r
+    FlightSize        = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna);\r
 \r
     Tcb->Ssthresh     = MAX (FlightSize >> 1, (UINT32) (2 * Tcb->SndMss));\r
     Tcb->Recover      = Tcb->SndNxt;\r
@@ -75,7 +75,7 @@ TcpFastRecover (
     TcpRetransmit (Tcb, Tcb->SndUna);\r
     Tcb->CWnd = Tcb->Ssthresh + 3 * Tcb->SndMss;\r
 \r
-    DEBUG ((EFI_D_INFO, "TcpFastRecover: enter fast retransmission"\r
+    DEBUG ((EFI_D_NET, "TcpFastRecover: enter fast retransmission"\r
       " for TCB %p, recover point is %d\n", Tcb, Tcb->Recover));\r
     return;\r
   }\r
@@ -94,7 +94,7 @@ TcpFastRecover (
     // by TcpToSendData\r
     //\r
     Tcb->CWnd += Tcb->SndMss;\r
-    DEBUG ((EFI_D_INFO, "TcpFastRecover: received another"\r
+    DEBUG ((EFI_D_NET, "TcpFastRecover: received another"\r
       " duplicated ACK (%d) for TCB %p\n", Seg->Ack, Tcb));\r
 \r
   } else {\r
@@ -109,12 +109,12 @@ TcpFastRecover (
       // Step 5 - Full ACK:\r
       // deflate the congestion window, and exit fast recovery\r
       //\r
-      FlightSize = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna);\r
+      FlightSize        = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna);\r
 \r
       Tcb->CWnd         = MIN (Tcb->Ssthresh, FlightSize + Tcb->SndMss);\r
 \r
       Tcb->CongestState = TCP_CONGEST_OPEN;\r
-      DEBUG ((EFI_D_INFO, "TcpFastRecover: received a full ACK(%d)"\r
+      DEBUG ((EFI_D_NET, "TcpFastRecover: received a full ACK(%d)"\r
         " for TCB %p, exit fast recovery\n", Seg->Ack, Tcb));\r
 \r
     } else {\r
@@ -139,7 +139,7 @@ TcpFastRecover (
 \r
       Tcb->CWnd -= Acked;\r
 \r
-      DEBUG ((EFI_D_INFO, "TcpFastRecover: received a partial"\r
+      DEBUG ((EFI_D_NET, "TcpFastRecover: received a partial"\r
         " ACK(%d) for TCB %p\n", Seg->Ack, Tcb));\r
 \r
     }\r
@@ -174,7 +174,7 @@ TcpFastLossRecover (
       Tcb->LossTimes    = 0;\r
       Tcb->CongestState = TCP_CONGEST_OPEN;\r
 \r
-      DEBUG ((EFI_D_INFO, "TcpFastLossRecover: received a "\r
+      DEBUG ((EFI_D_NET, "TcpFastLossRecover: received a "\r
         "full ACK(%d) for TCB %p\n", Seg->Ack, Tcb));\r
 \r
     } else {\r
@@ -184,7 +184,7 @@ TcpFastLossRecover (
       // fast retransmit the first unacknowledge field.\r
       //\r
       TcpRetransmit (Tcb, Seg->Ack);\r
-      DEBUG ((EFI_D_INFO, "TcpFastLossRecover: received a "\r
+      DEBUG ((EFI_D_NET, "TcpFastLossRecover: received a "\r
         "partial ACK(%d) for TCB %p\n", Seg->Ack, Tcb));\r
     }\r
   }\r
@@ -243,7 +243,7 @@ TcpComputeRtt (
 \r
   }\r
 \r
-  DEBUG ((EFI_D_INFO, "TcpComputeRtt: new RTT for TCB %p"\r
+  DEBUG ((EFI_D_NET, "TcpComputeRtt: new RTT for TCB %p"\r
     " computed SRTT: %d RTTVAR: %d RTO: %d\n",\r
     Tcb, Tcb->SRtt, Tcb->RttVar, Tcb->Rto));\r
 \r
@@ -429,7 +429,7 @@ TcpDeliverData (
         return -1;\r
       }\r
 \r
-      DEBUG ((EFI_D_INFO, "TcpDeliverData: processing FIN "\r
+      DEBUG ((EFI_D_NET, "TcpDeliverData: processing FIN "\r
         "from peer of TCB %p\n", Tcb));\r
 \r
       switch (Tcb->State) {\r
@@ -478,7 +478,6 @@ TcpDeliverData (
         //\r
         NetbufFree (Nbuf);\r
         return -1;\r
-        break;\r
       default:\r
         break;\r
       }\r
@@ -557,15 +556,15 @@ TcpQueueData (
   if (IsListEmpty (Head)) {\r
 \r
     InsertTailList (Head, &Nbuf->List);\r
-    return ;\r
+    return;\r
   }\r
 \r
   //\r
   // Find the point to insert the buffer\r
   //\r
   for (Prev = Head, Cur = Head->ForwardLink;\r
-      Cur != Head;\r
-      Prev = Cur, Cur = Cur->ForwardLink) {\r
+       Cur != Head;\r
+       Prev = Cur, Cur = Cur->ForwardLink) {\r
 \r
     Node = NET_LIST_USER_STRUCT (Cur, NET_BUF, List);\r
 \r
@@ -586,7 +585,7 @@ TcpQueueData (
       if (TCP_SEQ_LEQ (Seg->End, TCPSEG_NETBUF (Node)->End)) {\r
 \r
         NetbufFree (Nbuf);\r
-        return ;\r
+        return;\r
       }\r
 \r
       TcpTrimSegment (Nbuf, TCPSEG_NETBUF (Node)->End, Seg->End);\r
@@ -704,6 +703,7 @@ TcpInput (
   TCP_SEG     *Seg;\r
   TCP_SEQNO   Right;\r
   TCP_SEQNO   Urg;\r
+  INT32       Usable;\r
 \r
   NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);\r
 \r
@@ -711,12 +711,19 @@ TcpInput (
   Tcb     = NULL;\r
 \r
   Head    = (TCP_HEAD *) NetbufGetByte (Nbuf, 0, NULL);\r
+  ASSERT (Head != NULL);\r
+\r
+  if (Nbuf->TotalSize < sizeof (TCP_HEAD)) {\r
+    DEBUG ((EFI_D_NET, "TcpInput: received a malformed packet\n"));\r
+    goto DISCARD;\r
+  }\r
+\r
   Len     = Nbuf->TotalSize - (Head->HeadLen << 2);\r
 \r
   if ((Head->HeadLen < 5) || (Len < 0) ||\r
       (TcpChecksum (Nbuf, NetPseudoHeadChecksum (Src, Dst, 6, 0)) != 0)) {\r
 \r
-    DEBUG ((EFI_D_INFO, "TcpInput: received an mal-formated packet\n"));\r
+    DEBUG ((EFI_D_NET, "TcpInput: received a malformed packet\n"));\r
     goto DISCARD;\r
   }\r
 \r
@@ -737,7 +744,7 @@ TcpInput (
           );\r
 \r
   if ((Tcb == NULL) || (Tcb->State == TCP_CLOSED)) {\r
-    DEBUG ((EFI_D_INFO, "TcpInput: send reset because no TCB find\n"));\r
+    DEBUG ((EFI_D_NET, "TcpInput: send reset because no TCB found\n"));\r
 \r
     Tcb = NULL;\r
     goto SEND_RESET;\r
@@ -751,7 +758,7 @@ TcpInput (
   //\r
   if (TcpParseOption (Nbuf->Tcp, &Option) == -1) {\r
     DEBUG ((EFI_D_ERROR, "TcpInput: reset the peer because"\r
-      " of mal-format option for Tcb %p\n", Tcb));\r
+      " of malformed option for TCB %p\n", Tcb));\r
 \r
     goto SEND_RESET;\r
   }\r
@@ -799,12 +806,12 @@ TcpInput (
       Tcb     = TcpCloneTcb (Parent);\r
       if (Tcb == NULL) {\r
         DEBUG ((EFI_D_ERROR, "TcpInput: discard a segment because"\r
-          "failed to clone a child for TCB%x\n", Tcb));\r
+          " failed to clone a child for TCB %p\n", Tcb));\r
 \r
         goto DISCARD;\r
       }\r
 \r
-      DEBUG ((EFI_D_INFO, "TcpInput: create a child for TCB %p"\r
+      DEBUG ((EFI_D_NET, "TcpInput: create a child for TCB %p"\r
         " in listening\n", Tcb));\r
 \r
       //\r
@@ -865,7 +872,7 @@ TcpInput (
     //\r
 \r
     //\r
-    // Fourth step: Check SYN. Pay attention to sitimulatous open\r
+    // Fourth step: Check SYN. Pay attention to simultaneous open\r
     //\r
     if (TCP_FLG_ON (Seg->Flag, TCP_FLG_SYN)) {\r
 \r
@@ -896,13 +903,13 @@ TcpInput (
 \r
         TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_ACK_NOW);\r
 \r
-        DEBUG ((EFI_D_INFO, "TcpInput: connection established"\r
+        DEBUG ((EFI_D_NET, "TcpInput: connection established"\r
           " for TCB %p in SYN_SENT\n", Tcb));\r
 \r
         goto StepSix;\r
       } else {\r
         //\r
-        // Received a SYN segment without ACK, simultanous open.\r
+        // Received a SYN segment without ACK, simultaneous open.\r
         //\r
         TcpSetState (Tcb, TCP_SYN_RCVD);\r
 \r
@@ -911,7 +918,7 @@ TcpInput (
 \r
         TcpTrimInWnd (Tcb, Nbuf);\r
 \r
-        DEBUG ((EFI_D_WARN, "TcpInput: simultanous open "\r
+        DEBUG ((EFI_D_WARN, "TcpInput: simultaneous open "\r
           "for TCB %p in SYN_SENT\n", Tcb));\r
 \r
         goto StepSix;\r
@@ -925,6 +932,14 @@ TcpInput (
   // Process segment in SYN_RCVD or TCP_CONNECTED states\r
   //\r
 \r
+  //\r
+  // Clear probe timer since the RecvWindow is opened.\r
+  //\r
+  if (Tcb->ProbeTimerOn && (Seg->Wnd != 0)) {\r
+    TcpClearTimer (Tcb, TCP_TIMER_PROBE);\r
+    Tcb->ProbeTimerOn = FALSE;\r
+  }\r
+\r
   //\r
   // First step: Check whether SEG.SEQ is acceptable\r
   //\r
@@ -1023,7 +1038,7 @@ TcpInput (
       TcpClearTimer (Tcb, TCP_TIMER_CONNECT);\r
       TcpDeliverData (Tcb);\r
 \r
-      DEBUG ((EFI_D_INFO, "TcpInput: connection established "\r
+      DEBUG ((EFI_D_NET, "TcpInput: connection established "\r
         " for TCB %p in SYN_RCVD\n", Tcb));\r
 \r
       //\r
@@ -1173,9 +1188,27 @@ TcpInput (
       }\r
 \r
       if (TCP_SEQ_LT (Right, Tcb->SndNxt)) {\r
-\r
-        Tcb->SndNxt = Right;\r
-\r
+        //\r
+        // Check for Window Retraction in RFC7923 section 2.4.\r
+        // The lower n bits of the peer's actual receive window is wiped out if TCP\r
+        // window scale is enabled, it will look like the peer is shrinking the window.\r
+        // Check whether the SndNxt is out of the advertised receive window by more than\r
+        // 2^Rcv.Wind.Shift before moving the SndNxt to the left.\r
+        //\r
+        DEBUG (\r
+          (EFI_D_WARN,\r
+          "TcpInput: peer advise negative useable window for connected TCB %p\n",\r
+          Tcb)\r
+          );\r
+        Usable = TCP_SUB_SEQ (Tcb->SndNxt, Right);\r
+        if ((Usable >> Tcb->SndWndScale) > 0) {\r
+          DEBUG (\r
+            (EFI_D_WARN,\r
+            "TcpInput: SndNxt is out of window by more than window scale for TCB %p\n",\r
+            Tcb)\r
+            );\r
+          Tcb->SndNxt = Right;\r
+        }\r
         if (Right == Tcb->SndUna) {\r
 \r
           TcpClearTimer (Tcb, TCP_TIMER_REXMIT);\r
@@ -1195,7 +1228,7 @@ NO_UPDATE:
   if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_FIN_SENT) &&\r
       (Tcb->SndUna == Tcb->SndNxt)) {\r
 \r
-    DEBUG ((EFI_D_INFO, "TcpInput: local FIN is ACKed by"\r
+    DEBUG ((EFI_D_NET, "TcpInput: local FIN is ACKed by"\r
       " peer for connected TCB %p\n", Tcb));\r
 \r
     TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_FIN_ACKED);\r
@@ -1281,15 +1314,11 @@ StepSix:
   Tcb->Idle = 0;\r
   TcpSetKeepaliveTimer (Tcb);\r
 \r
-  if (TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_PROBE)) {\r
-\r
-    TcpClearTimer (Tcb, TCP_TIMER_PROBE);\r
-  }\r
-\r
   if (TCP_FLG_ON (Seg->Flag, TCP_FLG_URG) &&\r
-      !TCP_FIN_RCVD (Tcb->State)) {\r
+      !TCP_FIN_RCVD (Tcb->State))\r
+  {\r
 \r
-    DEBUG ((EFI_D_INFO, "TcpInput: received urgent data "\r
+    DEBUG ((EFI_D_NET, "TcpInput: received urgent data "\r
       "from peer for connected TCB %p\n", Tcb));\r
 \r
     Urg = Seg->Seq + Seg->Urg;\r
@@ -1419,7 +1448,12 @@ TcpIcmpInput (
   BOOLEAN          IcmpErrIsHard;\r
   BOOLEAN          IcmpErrNotify;\r
 \r
+  if (Nbuf->TotalSize < sizeof (TCP_HEAD)) {\r
+    goto CLEAN_EXIT;\r
+  }\r
+\r
   Head = (TCP_HEAD *) NetbufGetByte (Nbuf, 0, NULL);\r
+  ASSERT (Head != NULL);\r
   Tcb = TcpLocateTcb (\r
           Head->DstPort,\r
           Dst,\r