]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c
MdeModulePkg: Addressing TCP Window Retraction when window scale factor is used.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Misc.c
index 1cc84881118e2c043de0595deb52d80bafb7931d..892d19b0721437c4ee7ce477227fe727480c3114 100644 (file)
@@ -1,41 +1,35 @@
 /** @file\r
+  Misc support routines for tcp.\r
 \r
-Copyright (c) 2005 - 2006, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2005 - 2017, 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\r
+http://opensource.org/licenses/bsd-license.php<BR>\r
 \r
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
-Module Name:\r
-\r
-  Tcp4Misc.c\r
-\r
-Abstract:\r
-\r
-  Misc support routines for tcp.\r
-\r
-\r
 **/\r
 \r
 \r
 #include "Tcp4Main.h"\r
 \r
-NET_LIST_ENTRY  mTcpRunQue = {\r
+#include <Library/DevicePathLib.h>\r
+\r
+LIST_ENTRY      mTcpRunQue = {\r
   &mTcpRunQue,\r
   &mTcpRunQue\r
 };\r
 \r
-NET_LIST_ENTRY  mTcpListenQue = {\r
+LIST_ENTRY      mTcpListenQue = {\r
   &mTcpListenQue,\r
   &mTcpListenQue\r
 };\r
 \r
 TCP_SEQNO       mTcpGlobalIss = 0x4d7e980b;\r
 \r
-STATIC CHAR16   *mTcpStateName[] = {\r
+CHAR16   *mTcpStateName[] = {\r
   L"TCP_CLOSED",\r
   L"TCP_LISTEN",\r
   L"TCP_SYN_SENT",\r
@@ -55,12 +49,10 @@ STATIC CHAR16   *mTcpStateName[] = {
 \r
   @param  Tcb                   Pointer to the TCP_CB of this TCP instance.\r
 \r
-  @return None\r
-\r
 **/\r
 VOID\r
 TcpInitTcbLocal (\r
-  IN TCP_CB *Tcb\r
+  IN OUT TCP_CB *Tcb\r
   )\r
 {\r
   //\r
@@ -83,9 +75,12 @@ TcpInitTcbLocal (
   Tcb->RcvWnd = GET_RCV_BUFFSIZE (Tcb->Sk);\r
 \r
   //\r
-  // Fisrt window size is never scaled\r
+  // First window size is never scaled\r
   //\r
-  Tcb->RcvWndScale = 0;\r
+  Tcb->RcvWndScale  = 0;\r
+  Tcb->RetxmitSeqMax = 0;\r
+  \r
+  Tcb->ProbeTimerOn = FALSE;\r
 }\r
 \r
 \r
@@ -97,19 +92,17 @@ TcpInitTcbLocal (
                                 intial info.\r
   @param  Opt                   Pointer to the options announced by the peer.\r
 \r
-  @return None\r
-\r
 **/\r
 VOID\r
 TcpInitTcbPeer (\r
-  IN TCP_CB     *Tcb,\r
-  IN TCP_SEG    *Seg,\r
-  IN TCP_OPTION *Opt\r
+  IN OUT TCP_CB     *Tcb,\r
+  IN     TCP_SEG    *Seg,\r
+  IN     TCP_OPTION *Opt\r
   )\r
 {\r
   UINT16  RcvMss;\r
 \r
-  ASSERT (Tcb && Seg && Opt);\r
+  ASSERT ((Tcb != NULL) && (Seg != NULL) && (Opt != NULL));\r
   ASSERT (TCP_FLG_ON (Seg->Flag, TCP_FLG_SYN));\r
 \r
   Tcb->SndWnd     = Seg->Wnd;\r
@@ -123,7 +116,7 @@ TcpInitTcbPeer (
   }\r
 \r
   if (TCP_FLG_ON (Opt->Flag, TCP_OPTION_RCVD_MSS)) {\r
-    Tcb->SndMss = (UINT16) NET_MAX (64, Opt->Mss);\r
+    Tcb->SndMss = (UINT16) MAX (64, Opt->Mss);\r
 \r
     RcvMss = TcpGetRcvMss (Tcb->Sk);\r
     if (Tcb->SndMss > RcvMss) {\r
@@ -165,6 +158,8 @@ TcpInitTcbPeer (
     TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_TS);\r
     TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_RCVD_TS);\r
 \r
+    Tcb->TsRecent = Opt->TSVal;\r
+\r
     //\r
     // Compute the effective SndMss per RFC1122\r
     // section 4.2.2.6. If timestamp option is\r
@@ -181,17 +176,17 @@ TcpInitTcbPeer (
   @param  Local                 Pointer to the local (IP, Port).\r
   @param  Remote                Pointer to the remote (IP, Port).\r
 \r
-  @return Pointer to the TCP_CB with the least number of wildcard, if NULL no match is found.\r
+  @return  Pointer to the TCP_CB with the least number of wildcard,\r
+           if NULL no match is found.\r
 \r
 **/\r
-STATIC\r
 TCP_CB *\r
 TcpLocateListenTcb (\r
   IN TCP_PEER *Local,\r
   IN TCP_PEER *Remote\r
   )\r
 {\r
-  NET_LIST_ENTRY  *Entry;\r
+  LIST_ENTRY      *Entry;\r
   TCP_CB          *Node;\r
   TCP_CB          *Match;\r
   INTN            Last;\r
@@ -205,8 +200,7 @@ TcpLocateListenTcb (
 \r
     if ((Local->Port != Node->LocalEnd.Port) ||\r
         !TCP_PEER_MATCH (Remote, &Node->RemoteEnd) ||\r
-        !TCP_PEER_MATCH (Local, &Node->LocalEnd)\r
-          ) {\r
+        !TCP_PEER_MATCH (Local, &Node->LocalEnd)) {\r
 \r
       continue;\r
     }\r
@@ -247,7 +241,7 @@ TcpLocateListenTcb (
   @param  Addr                  Pointer to the IP address needs to match.\r
   @param  Port                  The port number needs to match.\r
 \r
-  @return The Tcb which matches the <Addr Port> paire exists or not.\r
+  @return  The Tcb which matches the <Addr Port> paire exists or not.\r
 \r
 **/\r
 BOOLEAN\r
@@ -257,7 +251,7 @@ TcpFindTcbByPeer (
   )\r
 {\r
   TCP_PORTNO      LocalPort;\r
-  NET_LIST_ENTRY  *Entry;\r
+  LIST_ENTRY      *Entry;\r
   TCP_CB          *Tcb;\r
 \r
   ASSERT ((Addr != NULL) && (Port != 0));\r
@@ -267,7 +261,7 @@ TcpFindTcbByPeer (
   NET_LIST_FOR_EACH (Entry, &mTcpListenQue) {\r
     Tcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);\r
 \r
-    if (EFI_IP4_EQUAL (*Addr, Tcb->LocalEnd.Ip) &&\r
+    if (EFI_IP4_EQUAL (Addr, &Tcb->LocalEnd.Ip) &&\r
       (LocalPort == Tcb->LocalEnd.Port)) {\r
 \r
       return TRUE;\r
@@ -277,7 +271,7 @@ TcpFindTcbByPeer (
   NET_LIST_FOR_EACH (Entry, &mTcpRunQue) {\r
     Tcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);\r
 \r
-    if (EFI_IP4_EQUAL (*Addr, Tcb->LocalEnd.Ip) &&\r
+    if (EFI_IP4_EQUAL (Addr, &Tcb->LocalEnd.Ip) &&\r
       (LocalPort == Tcb->LocalEnd.Port)) {\r
 \r
       return TRUE;\r
@@ -298,7 +292,7 @@ TcpFindTcbByPeer (
   @param  Syn                   Whether to search the listen sockets, if TRUE, the\r
                                 listen sockets are searched.\r
 \r
-  @return Pointer to the related TCP_CB, if NULL no match is found.\r
+  @return  Pointer to the related TCP_CB, if NULL no match is found.\r
 \r
 **/\r
 TCP_CB *\r
@@ -312,7 +306,7 @@ TcpLocateTcb (
 {\r
   TCP_PEER        Local;\r
   TCP_PEER        Remote;\r
-  NET_LIST_ENTRY  *Entry;\r
+  LIST_ENTRY      *Entry;\r
   TCP_CB          *Tcb;\r
 \r
   Local.Port  = LocalPort;\r
@@ -330,8 +324,8 @@ TcpLocateTcb (
     if (TCP_PEER_EQUAL (&Remote, &Tcb->RemoteEnd) &&\r
         TCP_PEER_EQUAL (&Local, &Tcb->LocalEnd)) {\r
 \r
-      NetListRemoveEntry (&Tcb->List);\r
-      NetListInsertHead (&mTcpRunQue, &Tcb->List);\r
+      RemoveEntryList (&Tcb->List);\r
+      InsertHeadList (&mTcpRunQue, &Tcb->List);\r
 \r
       return Tcb;\r
     }\r
@@ -362,19 +356,16 @@ TcpInsertTcb (
   IN TCP_CB *Tcb\r
   )\r
 {\r
-  NET_LIST_ENTRY   *Entry;\r
-  NET_LIST_ENTRY   *Head;\r
+  LIST_ENTRY       *Entry;\r
+  LIST_ENTRY       *Head;\r
   TCP_CB           *Node;\r
-  TCP4_PROTO_DATA  *TcpProto;\r
 \r
   ASSERT (\r
-    Tcb &&\r
-    (\r
-    (Tcb->State == TCP_LISTEN) ||\r
-    (Tcb->State == TCP_SYN_SENT) ||\r
-    (Tcb->State == TCP_SYN_RCVD) ||\r
-    (Tcb->State == TCP_CLOSED)\r
-    )\r
+    (Tcb != NULL) &&\r
+    ((Tcb->State == TCP_LISTEN) ||\r
+     (Tcb->State == TCP_SYN_SENT) ||\r
+     (Tcb->State == TCP_SYN_RCVD) ||\r
+     (Tcb->State == TCP_CLOSED))\r
     );\r
 \r
   if (Tcb->LocalEnd.Port == 0) {\r
@@ -400,21 +391,18 @@ TcpInsertTcb (
     }\r
   }\r
 \r
-  NetListInsertHead (Head, &Tcb->List);\r
-\r
-  TcpProto = (TCP4_PROTO_DATA *) Tcb->Sk->ProtoReserved;\r
-  TcpSetVariableData (TcpProto->TcpService);\r
+  InsertHeadList (Head, &Tcb->List);\r
 \r
   return 0;\r
 }\r
 \r
 \r
 /**\r
-  Clone a TCP_CB from Tcb.\r
+  Clone a TCB_CB from Tcb.\r
 \r
   @param  Tcb                   Pointer to the TCP_CB to be cloned.\r
 \r
-  @return Pointer to the new cloned TCP_CB, if NULL error condition occurred.\r
+  @return  Pointer to the new cloned TCP_CB, if NULL error condition occurred.\r
 \r
 **/\r
 TCP_CB *\r
@@ -424,28 +412,28 @@ TcpCloneTcb (
 {\r
   TCP_CB               *Clone;\r
 \r
-  Clone = NetAllocatePool (sizeof (TCP_CB));\r
+  Clone = AllocatePool (sizeof (TCP_CB));\r
 \r
   if (Clone == NULL) {\r
     return NULL;\r
 \r
   }\r
 \r
-  NetCopyMem (Clone, Tcb, sizeof (TCP_CB));\r
+  CopyMem (Clone, Tcb, sizeof (TCP_CB));\r
 \r
   //\r
   // Increate the reference count of the shared IpInfo.\r
   //\r
   NET_GET_REF (Tcb->IpInfo);\r
 \r
-  NetListInit (&Clone->List);\r
-  NetListInit (&Clone->SndQue);\r
-  NetListInit (&Clone->RcvQue);\r
+  InitializeListHead (&Clone->List);\r
+  InitializeListHead (&Clone->SndQue);\r
+  InitializeListHead (&Clone->RcvQue);\r
 \r
   Clone->Sk = SockClone (Tcb->Sk);\r
   if (Clone->Sk == NULL) {\r
-    TCP4_DEBUG_ERROR (("TcpCloneTcb: failed to clone a sock\n"));\r
-    NetFreePool (Clone);\r
+    DEBUG ((EFI_D_ERROR, "TcpCloneTcb: failed to clone a sock\n"));\r
+    FreePool (Clone);\r
     return NULL;\r
   }\r
 \r
@@ -458,9 +446,7 @@ TcpCloneTcb (
 /**\r
   Compute an ISS to be used by a new connection.\r
 \r
-  None\r
-\r
-  @return The result ISS.\r
+  @return  The result ISS.\r
 \r
 **/\r
 TCP_SEQNO\r
@@ -476,9 +462,9 @@ TcpGetIss (
 /**\r
   Get the local mss.\r
 \r
-  None\r
+  @param  Sock        Pointer to the socket to get mss\r
 \r
-  @return The mss size.\r
+  @return  The mss size.\r
 \r
 **/\r
 UINT16\r
@@ -486,19 +472,19 @@ TcpGetRcvMss (
   IN SOCKET  *Sock\r
   )\r
 {\r
-  EFI_SIMPLE_NETWORK_MODE SnpMode;\r
+  EFI_IP4_MODE_DATA       Ip4Mode;\r
   TCP4_PROTO_DATA         *TcpProto;\r
   EFI_IP4_PROTOCOL        *Ip;\r
 \r
-  ASSERT (Sock);\r
+  ASSERT (Sock != NULL);\r
 \r
   TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;\r
-  Ip       = TcpProto->TcpService->IpIo->Ip;\r
-  ASSERT (Ip);\r
+  Ip       = TcpProto->TcpService->IpIo->Ip.Ip4;\r
+  ASSERT (Ip != NULL);\r
 \r
-  Ip->GetModeData (Ip, NULL, NULL, &SnpMode);\r
+  Ip->GetModeData (Ip, &Ip4Mode, NULL, NULL);\r
 \r
-  return (UINT16) (SnpMode.MaxPacketSize - 40);\r
+  return (UINT16) (Ip4Mode.MaxPacketSize - sizeof (TCP_HEAD));\r
 }\r
 \r
 \r
@@ -508,17 +494,19 @@ TcpGetRcvMss (
   @param  Tcb                   Pointer to the TCP_CB of this TCP instance.\r
   @param  State                 The state to be set.\r
 \r
-  @return None\r
-\r
 **/\r
 VOID\r
 TcpSetState (\r
-  IN TCP_CB *Tcb,\r
-  IN UINT8  State\r
+  IN OUT TCP_CB  *Tcb,\r
+  IN     UINT8   State\r
   )\r
 {\r
-  TCP4_DEBUG_TRACE (\r
-    ("Tcb (%x) state %s --> %s\n",\r
+  ASSERT (Tcb->State < (sizeof (mTcpStateName) / sizeof (CHAR16 *)));\r
+  ASSERT (State < (sizeof (mTcpStateName) / sizeof (CHAR16 *)));\r
+\r
+  DEBUG (\r
+    (EFI_D_NET,\r
+    "Tcb (%p) state %s --> %s\n",\r
     Tcb,\r
     mTcpStateName[Tcb->State],\r
     mTcpStateName[State])\r
@@ -530,12 +518,23 @@ TcpSetState (
   case TCP_ESTABLISHED:\r
 \r
     SockConnEstablished (Tcb->Sk);\r
+\r
+    if (Tcb->Parent != NULL) {\r
+      //\r
+      // A new connection is accepted by a listening socket, install\r
+      // the device path.\r
+      //\r
+      TcpInstallDevicePath (Tcb->Sk);\r
+    }\r
+\r
     break;\r
 \r
   case TCP_CLOSED:\r
 \r
     SockConnClosed (Tcb->Sk);\r
 \r
+    break;\r
+  default:\r
     break;\r
   }\r
 }\r
@@ -549,7 +548,7 @@ TcpSetState (
   @param  HeadSum               The checksum value of the fixed part of pseudo\r
                                 header.\r
 \r
-  @return The checksum value.\r
+  @return  The checksum value.\r
 \r
 **/\r
 UINT16\r
@@ -563,15 +562,14 @@ TcpChecksum (
   Checksum  = NetbufChecksum (Nbuf);\r
   Checksum  = NetAddChecksum (Checksum, HeadSum);\r
 \r
-  Checksum = NetAddChecksum (\r
-              Checksum,\r
-              HTONS ((UINT16) Nbuf->TotalSize)\r
-              );\r
+  Checksum  = NetAddChecksum (\r
+                Checksum,\r
+                HTONS ((UINT16) Nbuf->TotalSize)\r
+                );\r
 \r
   return (UINT16) ~Checksum;\r
 }\r
 \r
-\r
 /**\r
   Translate the information from the head of the received TCP\r
   segment Nbuf contains and fill it into a TCP_SEG structure.\r
@@ -579,13 +577,13 @@ TcpChecksum (
   @param  Tcb                   Pointer to the TCP_CB of this TCP instance.\r
   @param  Nbuf                  Pointer to the buffer contains the TCP segment.\r
 \r
-  @return Pointer to the TCP_SEG that contains the translated TCP head information.\r
+  @return  Pointer to the TCP_SEG that contains the translated TCP head information.\r
 \r
 **/\r
 TCP_SEG *\r
 TcpFormatNetbuf (\r
-  IN TCP_CB  *Tcb,\r
-  IN NET_BUF *Nbuf\r
+  IN     TCP_CB  *Tcb,\r
+  IN OUT NET_BUF *Nbuf\r
   )\r
 {\r
   TCP_SEG   *Seg;\r
@@ -593,6 +591,7 @@ TcpFormatNetbuf (
 \r
   Seg       = TCPSEG_NETBUF (Nbuf);\r
   Head      = (TCP_HEAD *) NetbufGetByte (Nbuf, 0, NULL);\r
+  ASSERT (Head != NULL);\r
   Nbuf->Tcp = Head;\r
 \r
   Seg->Seq  = NTOHL (Head->Seq);\r
@@ -628,8 +627,6 @@ TcpFormatNetbuf (
   @param  Tcb                   Pointer to the TCP_CB of the connection to be\r
                                 reset.\r
 \r
-  @return None\r
-\r
 **/\r
 VOID\r
 TcpResetConnection (\r
@@ -660,7 +657,7 @@ TcpResetConnection (
   Nhead->Ack      = HTONL (Tcb->RcvNxt);\r
   Nhead->SrcPort  = Tcb->LocalEnd.Port;\r
   Nhead->DstPort  = Tcb->RemoteEnd.Port;\r
-  Nhead->HeadLen  = (sizeof (TCP_HEAD) >> 2);\r
+  Nhead->HeadLen  = (UINT8) (sizeof (TCP_HEAD) >> 2);\r
   Nhead->Res      = 0;\r
   Nhead->Wnd      = HTONS (0xFFFF);\r
   Nhead->Checksum = 0;\r
@@ -674,17 +671,15 @@ TcpResetConnection (
 \r
 \r
 /**\r
-  Initialize an active connection,\r
+  Initialize an active connection.\r
 \r
   @param  Tcb                   Pointer to the TCP_CB that wants to initiate a\r
                                 connection.\r
 \r
-  @return None\r
-\r
 **/\r
 VOID\r
 TcpOnAppConnect (\r
-  IN TCP_CB  *Tcb\r
+  IN OUT TCP_CB  *Tcb\r
   )\r
 {\r
   TcpInitTcbLocal (Tcb);\r
@@ -701,20 +696,18 @@ TcpOnAppConnect (
 \r
   @param  Tcb                   Pointer to the TCP_CB of this TCP instance.\r
 \r
-  @return None.\r
-\r
 **/\r
 VOID\r
 TcpOnAppClose (\r
-  IN TCP_CB *Tcb\r
+  IN OUT TCP_CB *Tcb\r
   )\r
 {\r
-  ASSERT (Tcb);\r
+  ASSERT (Tcb != NULL);\r
 \r
-  if (!NetListIsEmpty (&Tcb->RcvQue) || GET_RCV_DATASIZE (Tcb->Sk)) {\r
+  if (!IsListEmpty (&Tcb->RcvQue) || GET_RCV_DATASIZE (Tcb->Sk) != 0) {\r
 \r
-    TCP4_DEBUG_WARN (("TcpOnAppClose: connection reset "\r
-      "because data is lost for TCB %x\n", Tcb));\r
+    DEBUG ((EFI_D_WARN, "TcpOnAppClose: connection reset "\r
+      "because data is lost for TCB %p\n", Tcb));\r
 \r
     TcpResetConnection (Tcb);\r
     TcpClose (Tcb);\r
@@ -736,6 +729,8 @@ TcpOnAppClose (
   case TCP_CLOSE_WAIT:\r
     TcpSetState (Tcb, TCP_LAST_ACK);\r
     break;\r
+  default:\r
+    break;\r
   }\r
 \r
   TcpToSendData (Tcb, 1);\r
@@ -743,8 +738,7 @@ TcpOnAppClose (
 \r
 \r
 /**\r
-  Check whether the application's newly delivered data\r
-  can be sent out.\r
+  Check whether the application's newly delivered data can be sent out.\r
 \r
   @param  Tcb                   Pointer to the TCP_CB of this TCP instance.\r
 \r
@@ -756,29 +750,25 @@ TcpOnAppClose (
 **/\r
 INTN\r
 TcpOnAppSend (\r
-  IN TCP_CB *Tcb\r
+  IN OUT TCP_CB *Tcb\r
   )\r
 {\r
 \r
   switch (Tcb->State) {\r
   case TCP_CLOSED:\r
     return -1;\r
-    break;\r
 \r
   case TCP_LISTEN:\r
     return -1;\r
-    break;\r
 \r
   case TCP_SYN_SENT:\r
   case TCP_SYN_RCVD:\r
     return 0;\r
-    break;\r
 \r
   case TCP_ESTABLISHED:\r
   case TCP_CLOSE_WAIT:\r
     TcpToSendData (Tcb, 0);\r
     return 0;\r
-    break;\r
 \r
   case TCP_FIN_WAIT_1:\r
   case TCP_FIN_WAIT_2:\r
@@ -786,6 +776,8 @@ TcpOnAppSend (
   case TCP_LAST_ACK:\r
   case TCP_TIME_WAIT:\r
     return -1;\r
+\r
+  default:\r
     break;\r
   }\r
 \r
@@ -799,9 +791,8 @@ TcpOnAppSend (
 \r
   @param  Tcb                   Pointer to the TCP_CB of this TCP instance.\r
 \r
-\r
 **/\r
-INTN\r
+VOID\r
 TcpOnAppConsume (\r
   IN TCP_CB *Tcb\r
   )\r
@@ -810,17 +801,14 @@ TcpOnAppConsume (
 \r
   switch (Tcb->State) {\r
   case TCP_CLOSED:\r
-    return -1;\r
-    break;\r
+    return;\r
 \r
   case TCP_LISTEN:\r
-    return -1;\r
-    break;\r
+    return;\r
 \r
   case TCP_SYN_SENT:\r
   case TCP_SYN_RCVD:\r
-    return 0;\r
-    break;\r
+    return;\r
 \r
   case TCP_ESTABLISHED:\r
     TcpOld = TcpRcvWinOld (Tcb);\r
@@ -828,14 +816,14 @@ TcpOnAppConsume (
 \r
       if (TcpOld < Tcb->RcvMss) {\r
 \r
-        TCP4_DEBUG_TRACE (("TcpOnAppConsume: send a window"\r
-          " update for a window closed Tcb(%x)\n", Tcb));\r
+        DEBUG ((EFI_D_NET, "TcpOnAppConsume: send a window"\r
+          " update for a window closed Tcb %p\n", Tcb));\r
 \r
         TcpSendAck (Tcb);\r
       } else if (Tcb->DelayedAck == 0) {\r
 \r
-        TCP4_DEBUG_TRACE (("TcpOnAppConsume: scheduled a delayed"\r
-          " ACK to update window for Tcb(%x)\n", Tcb));\r
+        DEBUG ((EFI_D_NET, "TcpOnAppConsume: scheduled a delayed"\r
+          " ACK to update window for Tcb %p\n", Tcb));\r
 \r
         Tcb->DelayedAck = 1;\r
       }\r
@@ -844,19 +832,18 @@ TcpOnAppConsume (
     break;\r
 \r
   case TCP_CLOSE_WAIT:\r
-    return 0;\r
-    break;\r
+    return;\r
 \r
   case TCP_FIN_WAIT_1:\r
   case TCP_FIN_WAIT_2:\r
   case TCP_CLOSING:\r
   case TCP_LAST_ACK:\r
   case TCP_TIME_WAIT:\r
-    return -1;\r
+    return;\r
+\r
+  default:\r
     break;\r
   }\r
-\r
-  return -1;\r
 }\r
 \r
 \r
@@ -866,16 +853,14 @@ TcpOnAppConsume (
 \r
   @param  Tcb                   Pointer to the TCP_CB of the TCP instance.\r
 \r
-  @return None.\r
-\r
 **/\r
 VOID\r
 TcpOnAppAbort (\r
   IN TCP_CB *Tcb\r
   )\r
 {\r
-  TCP4_DEBUG_WARN (("TcpOnAppAbort: connection reset "\r
-    "issued by application for TCB %x\n", Tcb));\r
+  DEBUG ((EFI_D_WARN, "TcpOnAppAbort: connection reset "\r
+    "issued by application for TCB %p\n", Tcb));\r
 \r
   switch (Tcb->State) {\r
   case TCP_SYN_RCVD:\r
@@ -885,209 +870,71 @@ TcpOnAppAbort (
   case TCP_CLOSE_WAIT:\r
     TcpResetConnection (Tcb);\r
     break;\r
+  default:\r
+    break;\r
   }\r
 \r
   TcpSetState (Tcb, TCP_CLOSED);\r
 }\r
 \r
-\r
 /**\r
-  Set the Tdp4 variable data.\r
+  Install the device path protocol on the TCP instance.\r
 \r
-  @param  Tcp4Service           Tcp4 service data.\r
+  @param  Sock             Pointer to the socket representing the TCP instance.\r
 \r
-  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to set the variable.\r
-  @retval other                 Set variable failed.\r
+  @retval  EFI_SUCCESS     The device path protocol is installed.\r
+  @retval  other           Failed to install the device path protocol.\r
 \r
 **/\r
 EFI_STATUS\r
-TcpSetVariableData (\r
-  IN TCP4_SERVICE_DATA  *Tcp4Service\r
+TcpInstallDevicePath (\r
+  IN SOCKET *Sock\r
   )\r
 {\r
-  UINT32                  NumConfiguredInstance;\r
-  NET_LIST_ENTRY          *Entry;\r
-  TCP_CB                  *TcpPcb;\r
-  TCP4_PROTO_DATA         *TcpProto;\r
-  UINTN                   VariableDataSize;\r
-  EFI_TCP4_VARIABLE_DATA  *Tcp4VariableData;\r
-  EFI_TCP4_SERVICE_POINT  *Tcp4ServicePoint;\r
-  CHAR16                  *NewMacString;\r
-  EFI_STATUS              Status;\r
-\r
-  NumConfiguredInstance = 0;\r
-\r
-  //\r
-  // Go through the running queue to count the instances.\r
-  //\r
-  NET_LIST_FOR_EACH (Entry, &mTcpRunQue) {\r
-    TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);\r
-\r
-    TcpProto = (TCP4_PROTO_DATA *) TcpPcb->Sk->ProtoReserved;\r
-\r
-    if (TcpProto->TcpService == Tcp4Service) {\r
-      //\r
-      // This tcp instance belongs to the Tcp4Service.\r
-      //\r
-      NumConfiguredInstance++;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Go through the listening queue to count the instances.\r
-  //\r
-  NET_LIST_FOR_EACH (Entry, &mTcpListenQue) {\r
-    TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);\r
-\r
-    TcpProto = (TCP4_PROTO_DATA *) TcpPcb->Sk->ProtoReserved;\r
-\r
-    if (TcpProto->TcpService == Tcp4Service) {\r
-      //\r
-      // This tcp instance belongs to the Tcp4Service.\r
-      //\r
-      NumConfiguredInstance++;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Calculate the size of the Tcp4VariableData. As there may be no Tcp4 child,\r
-  // we should add extra buffer for the service points only if the number of configured\r
-  // children is more than 1.\r
-  //\r
-  VariableDataSize = sizeof (EFI_TCP4_VARIABLE_DATA);\r
+  TCP4_PROTO_DATA    *TcpProto;\r
+  TCP4_SERVICE_DATA  *TcpService;\r
+  TCP_CB             *Tcb;\r
+  IPv4_DEVICE_PATH   Ip4DPathNode;\r
+  EFI_STATUS         Status;\r
+  TCP_PORTNO         LocalPort;\r
+  TCP_PORTNO         RemotePort;\r
+\r
+  TcpProto   = (TCP4_PROTO_DATA *) Sock->ProtoReserved;\r
+  TcpService = TcpProto->TcpService;\r
+  Tcb        = TcpProto->TcpPcb;\r
+\r
+  LocalPort = NTOHS (Tcb->LocalEnd.Port);\r
+  RemotePort = NTOHS (Tcb->RemoteEnd.Port);\r
+  NetLibCreateIPv4DPathNode (\r
+    &Ip4DPathNode,\r
+    TcpService->ControllerHandle,\r
+    Tcb->LocalEnd.Ip,\r
+    LocalPort,\r
+    Tcb->RemoteEnd.Ip,\r
+    RemotePort,\r
+    EFI_IP_PROTO_TCP,\r
+    Tcb->UseDefaultAddr\r
+    );\r
 \r
-  if (NumConfiguredInstance > 1) {\r
-    VariableDataSize += sizeof (EFI_TCP4_SERVICE_POINT) * (NumConfiguredInstance - 1);\r
-  }\r
+  IP4_COPY_ADDRESS (&Ip4DPathNode.SubnetMask, &Tcb->SubnetMask);\r
 \r
-  Tcp4VariableData = NetAllocatePool (VariableDataSize);\r
-  if (Tcp4VariableData == NULL) {\r
+  Sock->DevicePath = AppendDevicePathNode (\r
+                       Sock->ParentDevicePath,\r
+                       (EFI_DEVICE_PATH_PROTOCOL *) &Ip4DPathNode\r
+                       );\r
+  if (Sock->DevicePath == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  Tcp4VariableData->DriverHandle = Tcp4Service->DriverBindingHandle;\r
-  Tcp4VariableData->ServiceCount = NumConfiguredInstance;\r
-\r
-  Tcp4ServicePoint = &Tcp4VariableData->Services[0];\r
-\r
-  //\r
-  // Go through the running queue to fill the service points.\r
-  //\r
-  NET_LIST_FOR_EACH (Entry, &mTcpRunQue) {\r
-    TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);\r
-\r
-    TcpProto = (TCP4_PROTO_DATA *) TcpPcb->Sk->ProtoReserved;\r
-\r
-    if (TcpProto->TcpService == Tcp4Service) {\r
-      //\r
-      // This tcp instance belongs to the Tcp4Service.\r
-      //\r
-      Tcp4ServicePoint->InstanceHandle          = TcpPcb->Sk->SockHandle;\r
-      NetCopyMem (&Tcp4ServicePoint->LocalAddress, &TcpPcb->LocalEnd.Ip, sizeof (EFI_IPv4_ADDRESS));\r
-      Tcp4ServicePoint->LocalPort               = NTOHS (TcpPcb->LocalEnd.Port);\r
-      NetCopyMem (&Tcp4ServicePoint->RemoteAddress, &TcpPcb->RemoteEnd.Ip, sizeof (EFI_IPv4_ADDRESS));\r
-      Tcp4ServicePoint->RemotePort              = NTOHS (TcpPcb->RemoteEnd.Port);\r
-\r
-      Tcp4ServicePoint++;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Go through the listening queue to fill the service points.\r
-  //\r
-  NET_LIST_FOR_EACH (Entry, &mTcpListenQue) {\r
-    TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);\r
-\r
-    TcpProto = (TCP4_PROTO_DATA *) TcpPcb->Sk->ProtoReserved;\r
-\r
-    if (TcpProto->TcpService == Tcp4Service) {\r
-      //\r
-      // This tcp instance belongs to the Tcp4Service.\r
-      //\r
-      Tcp4ServicePoint->InstanceHandle          = TcpPcb->Sk->SockHandle;\r
-      NetCopyMem (&Tcp4ServicePoint->LocalAddress, &TcpPcb->LocalEnd.Ip, sizeof (EFI_IPv4_ADDRESS));\r
-      Tcp4ServicePoint->LocalPort               = NTOHS (TcpPcb->LocalEnd.Port);\r
-      NetCopyMem (&Tcp4ServicePoint->RemoteAddress, &TcpPcb->RemoteEnd.Ip, sizeof (EFI_IPv4_ADDRESS));\r
-      Tcp4ServicePoint->RemotePort              = NTOHS (TcpPcb->RemoteEnd.Port);\r
-\r
-      Tcp4ServicePoint++;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Get the mac string.\r
-  //\r
-  Status = NetLibGetMacString (\r
-             Tcp4Service->ControllerHandle,\r
-             Tcp4Service->DriverBindingHandle,\r
-             &NewMacString\r
-             );\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &Sock->SockHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  Sock->DevicePath\r
+                  );\r
   if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
+    FreePool (Sock->DevicePath);\r
   }\r
 \r
-  if (Tcp4Service->MacString != NULL) {\r
-    //\r
-    // The variable is set already, we're going to update it.\r
-    //\r
-    if (StrCmp (Tcp4Service->MacString, NewMacString) != 0) {\r
-      //\r
-      // The mac address is changed, delete the previous variable first.\r
-      //\r
-      gRT->SetVariable (\r
-             Tcp4Service->MacString,\r
-             &gEfiTcp4ServiceBindingProtocolGuid,\r
-             EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
-             0,\r
-             NULL\r
-             );\r
-    }\r
-\r
-    NetFreePool (Tcp4Service->MacString);\r
-  }\r
-\r
-  Tcp4Service->MacString = NewMacString;\r
-\r
-  Status = gRT->SetVariable (\r
-                  Tcp4Service->MacString,\r
-                  &gEfiTcp4ServiceBindingProtocolGuid,\r
-                  EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
-                  VariableDataSize,\r
-                  (VOID *) Tcp4VariableData\r
-                  );\r
-\r
-ON_ERROR:\r
-\r
-  NetFreePool (Tcp4VariableData);\r
-\r
   return Status;\r
 }\r
-\r
-\r
-/**\r
-  Clear the variable and free the resource.\r
-\r
-  @param  Tcp4Service           Tcp4 service data.\r
-\r
-  @return None.\r
-\r
-**/\r
-VOID\r
-TcpClearVariableData (\r
-  IN TCP4_SERVICE_DATA  *Tcp4Service\r
-  )\r
-{\r
-  ASSERT (Tcp4Service->MacString != NULL);\r
-\r
-  gRT->SetVariable (\r
-         Tcp4Service->MacString,\r
-         &gEfiTcp4ServiceBindingProtocolGuid,\r
-         EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
-         0,\r
-         NULL\r
-         );\r
-\r
-  NetFreePool (Tcp4Service->MacString);\r
-  Tcp4Service->MacString = NULL;\r
-}\r
-\r