/** @file
  Misc support routines for TCP driver.

  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "TcpMain.h"

LIST_ENTRY  mTcpRunQue = {
  &mTcpRunQue,
  &mTcpRunQue
};

LIST_ENTRY  mTcpListenQue = {
  &mTcpListenQue,
  &mTcpListenQue
};

TCP_SEQNO  mTcpGlobalIss = TCP_BASE_ISS;

CHAR16  *mTcpStateName[] = {
  L"TCP_CLOSED",
  L"TCP_LISTEN",
  L"TCP_SYN_SENT",
  L"TCP_SYN_RCVD",
  L"TCP_ESTABLISHED",
  L"TCP_FIN_WAIT_1",
  L"TCP_FIN_WAIT_2",
  L"TCP_CLOSING",
  L"TCP_TIME_WAIT",
  L"TCP_CLOSE_WAIT",
  L"TCP_LAST_ACK"
};

/**
  Initialize the Tcb local related members.

  @param[in, out]  Tcb               Pointer to the TCP_CB of this TCP instance.

**/
VOID
TcpInitTcbLocal (
  IN OUT TCP_CB  *Tcb
  )
{
  //
  // Compute the checksum of the fixed parts of pseudo header
  //
  if (Tcb->Sk->IpVersion == IP_VERSION_4) {
    Tcb->HeadSum = NetPseudoHeadChecksum (
                     Tcb->LocalEnd.Ip.Addr[0],
                     Tcb->RemoteEnd.Ip.Addr[0],
                     0x06,
                     0
                     );
  } else {
    Tcb->HeadSum = NetIp6PseudoHeadChecksum (
                     &Tcb->LocalEnd.Ip.v6,
                     &Tcb->RemoteEnd.Ip.v6,
                     0x06,
                     0
                     );
  }

  Tcb->Iss    = TcpGetIss ();
  Tcb->SndUna = Tcb->Iss;
  Tcb->SndNxt = Tcb->Iss;

  Tcb->SndWl2 = Tcb->Iss;
  Tcb->SndWnd = 536;

  Tcb->RcvWnd = GET_RCV_BUFFSIZE (Tcb->Sk);

  //
  // First window size is never scaled
  //
  Tcb->RcvWndScale   = 0;
  Tcb->RetxmitSeqMax = 0;

  Tcb->ProbeTimerOn = FALSE;
}

/**
  Initialize the peer related members.

  @param[in, out]  Tcb    Pointer to the TCP_CB of this TCP instance.
  @param[in]       Seg    Pointer to the segment that contains the peer's initial info.
  @param[in]       Opt    Pointer to the options announced by the peer.

**/
VOID
TcpInitTcbPeer (
  IN OUT TCP_CB      *Tcb,
  IN     TCP_SEG     *Seg,
  IN     TCP_OPTION  *Opt
  )
{
  UINT16  RcvMss;

  ASSERT ((Tcb != NULL) && (Seg != NULL) && (Opt != NULL));
  ASSERT (TCP_FLG_ON (Seg->Flag, TCP_FLG_SYN));

  Tcb->SndWnd    = Seg->Wnd;
  Tcb->SndWndMax = Tcb->SndWnd;
  Tcb->SndWl1    = Seg->Seq;

  if (TCP_FLG_ON (Seg->Flag, TCP_FLG_ACK)) {
    Tcb->SndWl2 = Seg->Ack;
  } else {
    Tcb->SndWl2 = Tcb->Iss + 1;
  }

  if (TCP_FLG_ON (Opt->Flag, TCP_OPTION_RCVD_MSS)) {
    Tcb->SndMss = (UINT16)MAX (64, Opt->Mss);

    RcvMss = TcpGetRcvMss (Tcb->Sk);
    if (Tcb->SndMss > RcvMss) {
      Tcb->SndMss = RcvMss;
    }
  } else {
    //
    // One end doesn't support MSS option, use default.
    //
    Tcb->RcvMss = 536;
  }

  Tcb->CWnd = Tcb->SndMss;

  Tcb->Irs    = Seg->Seq;
  Tcb->RcvNxt = Tcb->Irs + 1;

  Tcb->RcvWl2 = Tcb->RcvNxt;

  if (TCP_FLG_ON (Opt->Flag, TCP_OPTION_RCVD_WS) && !TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS)) {
    Tcb->SndWndScale = Opt->WndScale;

    Tcb->RcvWndScale = TcpComputeScale (Tcb);
    TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_RCVD_WS);
  } else {
    //
    // One end doesn't support window scale option. use zero.
    //
    Tcb->RcvWndScale = 0;
  }

  if (TCP_FLG_ON (Opt->Flag, TCP_OPTION_RCVD_TS) && !TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS)) {
    TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_TS);
    TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_RCVD_TS);

    Tcb->TsRecent = Opt->TSVal;

    //
    // Compute the effective SndMss per RFC1122
    // section 4.2.2.6. If timestamp option is
    // enabled, it will always occupy 12 bytes.
    //
    Tcb->SndMss -= TCP_OPTION_TS_ALIGNED_LEN;
  }
}

/**
  Check whether one IP address equals the other.

  @param[in]   Ip1     Pointer to IP address to be checked.
  @param[in]   Ip2     Pointer to IP address to be checked.
  @param[in]   Version IP_VERSION_4 indicates the IP address is an IPv4 address,
                       IP_VERSION_6 indicates the IP address is an IPv6 address.

  @retval      TRUE    Ip1 equals Ip2.
  @retval      FALSE   Ip1 does not equal Ip2.

**/
BOOLEAN
TcpIsIpEqual (
  IN EFI_IP_ADDRESS  *Ip1,
  IN EFI_IP_ADDRESS  *Ip2,
  IN UINT8           Version
  )
{
  ASSERT ((Version == IP_VERSION_4) || (Version == IP_VERSION_6));

  if (Version == IP_VERSION_4) {
    return (BOOLEAN)(Ip1->Addr[0] == Ip2->Addr[0]);
  } else {
    return (BOOLEAN)EFI_IP6_EQUAL (&Ip1->v6, &Ip2->v6);
  }
}

/**
  Check whether one IP address is filled with ZERO.

  @param[in]   Ip      Pointer to the IP address to be checked.
  @param[in]   Version IP_VERSION_4 indicates the IP address is an IPv4 address,
                       IP_VERSION_6 indicates the IP address is an IPv6 address.

  @retval      TRUE    Ip is all zero address.
  @retval      FALSE   Ip is not all zero address.

**/
BOOLEAN
TcpIsIpZero (
  IN EFI_IP_ADDRESS  *Ip,
  IN UINT8           Version
  )
{
  ASSERT ((Version == IP_VERSION_4) || (Version == IP_VERSION_6));

  if (Version == IP_VERSION_4) {
    return (BOOLEAN)(Ip->Addr[0] == 0);
  } else {
    return (BOOLEAN)((Ip->Addr[0] == 0) && (Ip->Addr[1] == 0) &&
                     (Ip->Addr[2] == 0) && (Ip->Addr[3] == 0));
  }
}

/**
  Locate a listen TCB that matchs the Local and Remote.

  @param[in]  Local    Pointer to the local (IP, Port).
  @param[in]  Remote   Pointer to the remote (IP, Port).
  @param[in]  Version  IP_VERSION_4 indicates TCP is running on IP4 stack,
                       IP_VERSION_6 indicates TCP is running on IP6 stack.

  @return  Pointer to the TCP_CB with the least number of wildcards,
           if NULL no match is found.

**/
TCP_CB *
TcpLocateListenTcb (
  IN TCP_PEER  *Local,
  IN TCP_PEER  *Remote,
  IN UINT8     Version
  )
{
  LIST_ENTRY  *Entry;
  TCP_CB      *Node;
  TCP_CB      *Match;
  INTN        Last;
  INTN        Cur;

  Last  = 4;
  Match = NULL;

  NET_LIST_FOR_EACH (Entry, &mTcpListenQue) {
    Node = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);

    if ((Version != Node->Sk->IpVersion) ||
        (Local->Port != Node->LocalEnd.Port) ||
        !TCP_PEER_MATCH (Remote, &Node->RemoteEnd, Version) ||
        !TCP_PEER_MATCH (Local, &Node->LocalEnd, Version)
        )
    {
      continue;
    }

    //
    // Compute the number of wildcard
    //
    Cur = 0;
    if (TcpIsIpZero (&Node->RemoteEnd.Ip, Version)) {
      Cur++;
    }

    if (Node->RemoteEnd.Port == 0) {
      Cur++;
    }

    if (TcpIsIpZero (&Node->LocalEnd.Ip, Version)) {
      Cur++;
    }

    if (Cur < Last) {
      if (Cur == 0) {
        return Node;
      }

      Last  = Cur;
      Match = Node;
    }
  }

  return Match;
}

/**
  Try to find one Tcb whose <Ip, Port> equals to <IN Addr, IN Port>.

  @param[in]  Addr     Pointer to the IP address needs to match.
  @param[in]  Port     The port number needs to match.
  @param[in]  Version  IP_VERSION_4 indicates TCP is running on IP4 stack,
                       IP_VERSION_6 indicates TCP is running on IP6 stack.


  @retval     TRUE     The Tcb which matches the <Addr Port> pair exists.
  @retval     FALSE    Otherwise

**/
BOOLEAN
TcpFindTcbByPeer (
  IN EFI_IP_ADDRESS  *Addr,
  IN TCP_PORTNO      Port,
  IN UINT8           Version
  )
{
  TCP_PORTNO  LocalPort;
  LIST_ENTRY  *Entry;
  TCP_CB      *Tcb;

  ASSERT ((Addr != NULL) && (Port != 0));

  LocalPort = HTONS (Port);

  NET_LIST_FOR_EACH (Entry, &mTcpListenQue) {
    Tcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);

    if ((Version == Tcb->Sk->IpVersion) &&
        TcpIsIpEqual (Addr, &Tcb->LocalEnd.Ip, Version) &&
        (LocalPort == Tcb->LocalEnd.Port)
        )
    {
      return TRUE;
    }
  }

  NET_LIST_FOR_EACH (Entry, &mTcpRunQue) {
    Tcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);

    if ((Version == Tcb->Sk->IpVersion) &&
        TcpIsIpEqual (Addr, &Tcb->LocalEnd.Ip, Version) &&
        (LocalPort == Tcb->LocalEnd.Port)
        )
    {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Locate the TCP_CB related to the socket pair.

  @param[in]  LocalPort      The local port number.
  @param[in]  LocalIp        The local IP address.
  @param[in]  RemotePort     The remote port number.
  @param[in]  RemoteIp       The remote IP address.
  @param[in]  Version        IP_VERSION_4 indicates TCP is running on IP4 stack,
                             IP_VERSION_6 indicates TCP is running on IP6 stack.
  @param[in]  Syn            If TRUE, the listen sockets are searched.

  @return Pointer to the related TCP_CB. If NULL, no match is found.

**/
TCP_CB *
TcpLocateTcb (
  IN TCP_PORTNO      LocalPort,
  IN EFI_IP_ADDRESS  *LocalIp,
  IN TCP_PORTNO      RemotePort,
  IN EFI_IP_ADDRESS  *RemoteIp,
  IN UINT8           Version,
  IN BOOLEAN         Syn
  )
{
  TCP_PEER    Local;
  TCP_PEER    Remote;
  LIST_ENTRY  *Entry;
  TCP_CB      *Tcb;

  Local.Port  = LocalPort;
  Remote.Port = RemotePort;

  CopyMem (&Local.Ip, LocalIp, sizeof (EFI_IP_ADDRESS));
  CopyMem (&Remote.Ip, RemoteIp, sizeof (EFI_IP_ADDRESS));

  //
  // First check for exact match.
  //
  NET_LIST_FOR_EACH (Entry, &mTcpRunQue) {
    Tcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);

    if ((Version == Tcb->Sk->IpVersion) &&
        TCP_PEER_EQUAL (&Remote, &Tcb->RemoteEnd, Version) &&
        TCP_PEER_EQUAL (&Local, &Tcb->LocalEnd, Version)
        )
    {
      RemoveEntryList (&Tcb->List);
      InsertHeadList (&mTcpRunQue, &Tcb->List);

      return Tcb;
    }
  }

  //
  // Only check the listen queue when the SYN flag is on.
  //
  if (Syn) {
    return TcpLocateListenTcb (&Local, &Remote, Version);
  }

  return NULL;
}

/**
  Insert a Tcb into the proper queue.

  @param[in]  Tcb               Pointer to the TCP_CB to be inserted.

  @retval 0                     The Tcb was inserted successfully.
  @retval -1                    Error condition occurred.

**/
INTN
TcpInsertTcb (
  IN TCP_CB  *Tcb
  )
{
  LIST_ENTRY  *Entry;
  LIST_ENTRY  *Head;
  TCP_CB      *Node;

  ASSERT (
    (Tcb != NULL) &&
    (
     (Tcb->State == TCP_LISTEN) ||
     (Tcb->State == TCP_SYN_SENT) ||
     (Tcb->State == TCP_SYN_RCVD) ||
     (Tcb->State == TCP_CLOSED)
    )
    );

  if (Tcb->LocalEnd.Port == 0) {
    return -1;
  }

  Head = &mTcpRunQue;

  if (Tcb->State == TCP_LISTEN) {
    Head = &mTcpListenQue;
  }

  //
  // Check that the Tcb isn't already on the list.
  //
  NET_LIST_FOR_EACH (Entry, Head) {
    Node = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);

    if (TCP_PEER_EQUAL (&Tcb->LocalEnd, &Node->LocalEnd, Tcb->Sk->IpVersion) &&
        TCP_PEER_EQUAL (&Tcb->RemoteEnd, &Node->RemoteEnd, Tcb->Sk->IpVersion)
        )
    {
      return -1;
    }
  }

  InsertHeadList (Head, &Tcb->List);

  return 0;
}

/**
  Clone a TCP_CB from Tcb.

  @param[in]  Tcb                   Pointer to the TCP_CB to be cloned.

  @return Pointer to the new cloned TCP_CB; if NULL, error condition occurred.

**/
TCP_CB *
TcpCloneTcb (
  IN TCP_CB  *Tcb
  )
{
  TCP_CB  *Clone;

  Clone = AllocateZeroPool (sizeof (TCP_CB));

  if (Clone == NULL) {
    return NULL;
  }

  CopyMem (Clone, Tcb, sizeof (TCP_CB));

  //
  // Increase the reference count of the shared IpInfo.
  //
  NET_GET_REF (Tcb->IpInfo);

  InitializeListHead (&Clone->List);
  InitializeListHead (&Clone->SndQue);
  InitializeListHead (&Clone->RcvQue);

  Clone->Sk = SockClone (Tcb->Sk);
  if (Clone->Sk == NULL) {
    DEBUG ((DEBUG_ERROR, "TcpCloneTcb: failed to clone a sock\n"));
    FreePool (Clone);
    return NULL;
  }

  ((TCP_PROTO_DATA *)(Clone->Sk->ProtoReserved))->TcpPcb = Clone;

  return Clone;
}

/**
  Compute an ISS to be used by a new connection.

  @return The resulting ISS.

**/
TCP_SEQNO
TcpGetIss (
  VOID
  )
{
  mTcpGlobalIss += TCP_ISS_INCREMENT_1;
  return mTcpGlobalIss;
}

/**
  Get the local mss.

  @param[in]  Sock        Pointer to the socket to get mss.

  @return The mss size.

**/
UINT16
TcpGetRcvMss (
  IN SOCKET  *Sock
  )
{
  EFI_IP4_MODE_DATA  Ip4Mode;
  EFI_IP6_MODE_DATA  Ip6Mode;
  EFI_IP4_PROTOCOL   *Ip4;
  EFI_IP6_PROTOCOL   *Ip6;
  TCP_PROTO_DATA     *TcpProto;

  ASSERT (Sock != NULL);

  ZeroMem (&Ip4Mode, sizeof (EFI_IP4_MODE_DATA));
  ZeroMem (&Ip6Mode, sizeof (EFI_IP6_MODE_DATA));

  TcpProto = (TCP_PROTO_DATA *)Sock->ProtoReserved;

  if (Sock->IpVersion == IP_VERSION_4) {
    Ip4 = TcpProto->TcpService->IpIo->Ip.Ip4;
    ASSERT (Ip4 != NULL);
    Ip4->GetModeData (Ip4, &Ip4Mode, NULL, NULL);

    return (UINT16)(Ip4Mode.MaxPacketSize - sizeof (TCP_HEAD));
  } else {
    Ip6 = TcpProto->TcpService->IpIo->Ip.Ip6;
    ASSERT (Ip6 != NULL);
    if (!EFI_ERROR (Ip6->GetModeData (Ip6, &Ip6Mode, NULL, NULL))) {
      if (Ip6Mode.AddressList != NULL) {
        FreePool (Ip6Mode.AddressList);
      }

      if (Ip6Mode.GroupTable != NULL) {
        FreePool (Ip6Mode.GroupTable);
      }

      if (Ip6Mode.RouteTable != NULL) {
        FreePool (Ip6Mode.RouteTable);
      }

      if (Ip6Mode.NeighborCache != NULL) {
        FreePool (Ip6Mode.NeighborCache);
      }

      if (Ip6Mode.PrefixTable != NULL) {
        FreePool (Ip6Mode.PrefixTable);
      }

      if (Ip6Mode.IcmpTypeList != NULL) {
        FreePool (Ip6Mode.IcmpTypeList);
      }
    }

    return (UINT16)(Ip6Mode.MaxPacketSize - sizeof (TCP_HEAD));
  }
}

/**
  Set the Tcb's state.

  @param[in]  Tcb                   Pointer to the TCP_CB of this TCP instance.
  @param[in]  State                 The state to be set.

**/
VOID
TcpSetState (
  IN TCP_CB  *Tcb,
  IN UINT8   State
  )
{
  ASSERT (Tcb->State < (sizeof (mTcpStateName) / sizeof (CHAR16 *)));
  ASSERT (State < (sizeof (mTcpStateName) / sizeof (CHAR16 *)));

  DEBUG (
    (DEBUG_NET,
     "Tcb (%p) state %s --> %s\n",
     Tcb,
     mTcpStateName[Tcb->State],
     mTcpStateName[State])
    );

  Tcb->State = State;

  switch (State) {
    case TCP_ESTABLISHED:

      SockConnEstablished (Tcb->Sk);

      if (Tcb->Parent != NULL) {
        //
        // A new connection is accepted by a listening socket. Install
        // the device path.
        //
        TcpInstallDevicePath (Tcb->Sk);
      }

      break;

    case TCP_CLOSED:

      SockConnClosed (Tcb->Sk);

      break;
    default:
      break;
  }
}

/**
  Compute the TCP segment's checksum.

  @param[in]  Nbuf       Pointer to the buffer that contains the TCP segment.
  @param[in]  HeadSum    The checksum value of the fixed part of pseudo header.

  @return The checksum value.

**/
UINT16
TcpChecksum (
  IN NET_BUF  *Nbuf,
  IN UINT16   HeadSum
  )
{
  UINT16  Checksum;

  Checksum = NetbufChecksum (Nbuf);
  Checksum = NetAddChecksum (Checksum, HeadSum);

  Checksum = NetAddChecksum (
               Checksum,
               HTONS ((UINT16)Nbuf->TotalSize)
               );

  return (UINT16)(~Checksum);
}

/**
  Translate the information from the head of the received TCP
  segment Nbuf contents and fill it into a TCP_SEG structure.

  @param[in]       Tcb           Pointer to the TCP_CB of this TCP instance.
  @param[in, out]  Nbuf          Pointer to the buffer contains the TCP segment.

  @return Pointer to the TCP_SEG that contains the translated TCP head information.

**/
TCP_SEG *
TcpFormatNetbuf (
  IN     TCP_CB   *Tcb,
  IN OUT NET_BUF  *Nbuf
  )
{
  TCP_SEG   *Seg;
  TCP_HEAD  *Head;

  Seg  = TCPSEG_NETBUF (Nbuf);
  Head = (TCP_HEAD *)NetbufGetByte (Nbuf, 0, NULL);
  ASSERT (Head != NULL);

  Nbuf->Tcp = Head;

  Seg->Seq = NTOHL (Head->Seq);
  Seg->Ack = NTOHL (Head->Ack);
  Seg->End = Seg->Seq + (Nbuf->TotalSize - (Head->HeadLen << 2));

  Seg->Urg  = NTOHS (Head->Urg);
  Seg->Wnd  = (NTOHS (Head->Wnd) << Tcb->SndWndScale);
  Seg->Flag = Head->Flag;

  //
  // SYN and FIN flag occupy one sequence space each.
  //
  if (TCP_FLG_ON (Seg->Flag, TCP_FLG_SYN)) {
    //
    // RFC requires that the initial window not be scaled.
    //
    Seg->Wnd = NTOHS (Head->Wnd);
    Seg->End++;
  }

  if (TCP_FLG_ON (Seg->Flag, TCP_FLG_FIN)) {
    Seg->End++;
  }

  return Seg;
}

/**
  Initialize an active connection.

  @param[in, out]  Tcb          Pointer to the TCP_CB that wants to initiate a
                                connection.

**/
VOID
TcpOnAppConnect (
  IN OUT TCP_CB  *Tcb
  )
{
  TcpInitTcbLocal (Tcb);
  TcpSetState (Tcb, TCP_SYN_SENT);

  TcpSetTimer (Tcb, TCP_TIMER_CONNECT, Tcb->ConnectTimeout);
  TcpToSendData (Tcb, 1);
}

/**
  Initiate the connection close procedure, called when
  applications want to close the connection.

  @param[in, out]  Tcb          Pointer to the TCP_CB of this TCP instance.

**/
VOID
TcpOnAppClose (
  IN OUT TCP_CB  *Tcb
  )
{
  ASSERT (Tcb != NULL);

  if (!IsListEmpty (&Tcb->RcvQue) || (GET_RCV_DATASIZE (Tcb->Sk) != 0)) {
    DEBUG (
      (DEBUG_WARN,
       "TcpOnAppClose: connection reset because data is lost for TCB %p\n",
       Tcb)
      );

    TcpResetConnection (Tcb);
    TcpClose (Tcb);
    return;
  }

  switch (Tcb->State) {
    case TCP_CLOSED:
    case TCP_LISTEN:
    case TCP_SYN_SENT:
      TcpSetState (Tcb, TCP_CLOSED);
      break;

    case TCP_SYN_RCVD:
    case TCP_ESTABLISHED:
      TcpSetState (Tcb, TCP_FIN_WAIT_1);
      break;

    case TCP_CLOSE_WAIT:
      TcpSetState (Tcb, TCP_LAST_ACK);
      break;
    default:
      break;
  }

  TcpToSendData (Tcb, 1);
}

/**
  Check whether the application's newly delivered data can be sent out.

  @param[in, out]  Tcb          Pointer to the TCP_CB of this TCP instance.

  @retval 0                     The data has been sent out successfully.
  @retval -1                    The Tcb is not in a state that data is permitted to
                                be sent out.

**/
INTN
TcpOnAppSend (
  IN OUT TCP_CB  *Tcb
  )
{
  switch (Tcb->State) {
    case TCP_CLOSED:
      return -1;

    case TCP_LISTEN:
      return -1;

    case TCP_SYN_SENT:
    case TCP_SYN_RCVD:
      return 0;

    case TCP_ESTABLISHED:
    case TCP_CLOSE_WAIT:
      TcpToSendData (Tcb, 0);
      return 0;

    case TCP_FIN_WAIT_1:
    case TCP_FIN_WAIT_2:
    case TCP_CLOSING:
    case TCP_LAST_ACK:
    case TCP_TIME_WAIT:
      return -1;

    default:
      break;
  }

  return 0;
}

/**
  Application has consumed some data. Check whether
  to send a window update ack or a delayed ack.

  @param[in]  Tcb        Pointer to the TCP_CB of this TCP instance.

**/
VOID
TcpOnAppConsume (
  IN TCP_CB  *Tcb
  )
{
  UINT32  TcpOld;

  switch (Tcb->State) {
    case TCP_ESTABLISHED:
      TcpOld = TcpRcvWinOld (Tcb);
      if (TcpRcvWinNow (Tcb) > TcpOld) {
        if (TcpOld < Tcb->RcvMss) {
          DEBUG (
            (DEBUG_NET,
             "TcpOnAppConsume: send a window update for a window closed Tcb %p\n",
             Tcb)
            );

          TcpSendAck (Tcb);
        } else if (Tcb->DelayedAck == 0) {
          DEBUG (
            (DEBUG_NET,
             "TcpOnAppConsume: scheduled a delayed ACK to update window for Tcb %p\n",
             Tcb)
            );

          Tcb->DelayedAck = 1;
        }
      }

      break;

    default:
      break;
  }
}

/**
  Abort the connection by sending a reset segment. Called
  when the application wants to abort the connection.

  @param[in]  Tcb                   Pointer to the TCP_CB of the TCP instance.

**/
VOID
TcpOnAppAbort (
  IN TCP_CB  *Tcb
  )
{
  DEBUG (
    (DEBUG_WARN,
     "TcpOnAppAbort: connection reset issued by application for TCB %p\n",
     Tcb)
    );

  switch (Tcb->State) {
    case TCP_SYN_RCVD:
    case TCP_ESTABLISHED:
    case TCP_FIN_WAIT_1:
    case TCP_FIN_WAIT_2:
    case TCP_CLOSE_WAIT:
      TcpResetConnection (Tcb);
      break;
    default:
      break;
  }

  TcpSetState (Tcb, TCP_CLOSED);
}

/**
  Reset the connection related with Tcb.

  @param[in]  Tcb         Pointer to the TCP_CB of the connection to be reset.

**/
VOID
TcpResetConnection (
  IN TCP_CB  *Tcb
  )
{
  NET_BUF   *Nbuf;
  TCP_HEAD  *Nhead;

  Nbuf = NetbufAlloc (TCP_MAX_HEAD);

  if (Nbuf == NULL) {
    return;
  }

  Nhead = (TCP_HEAD *)NetbufAllocSpace (
                        Nbuf,
                        sizeof (TCP_HEAD),
                        NET_BUF_TAIL
                        );

  ASSERT (Nhead != NULL);

  Nbuf->Tcp = Nhead;

  Nhead->Flag     = TCP_FLG_RST;
  Nhead->Seq      = HTONL (Tcb->SndNxt);
  Nhead->Ack      = HTONL (Tcb->RcvNxt);
  Nhead->SrcPort  = Tcb->LocalEnd.Port;
  Nhead->DstPort  = Tcb->RemoteEnd.Port;
  Nhead->HeadLen  = (UINT8)(sizeof (TCP_HEAD) >> 2);
  Nhead->Res      = 0;
  Nhead->Wnd      = HTONS (0xFFFF);
  Nhead->Checksum = 0;
  Nhead->Urg      = 0;
  Nhead->Checksum = TcpChecksum (Nbuf, Tcb->HeadSum);

  TcpSendIpPacket (Tcb, Nbuf, &Tcb->LocalEnd.Ip, &Tcb->RemoteEnd.Ip, Tcb->Sk->IpVersion);

  NetbufFree (Nbuf);
}

/**
  Install the device path protocol on the TCP instance.

  @param[in]  Sock          Pointer to the socket representing the TCP instance.

  @retval EFI_SUCCESS           The device path protocol was installed.
  @retval other                 Failed to install the device path protocol.

**/
EFI_STATUS
TcpInstallDevicePath (
  IN SOCKET  *Sock
  )
{
  TCP_PROTO_DATA            *TcpProto;
  TCP_SERVICE_DATA          *TcpService;
  TCP_CB                    *Tcb;
  IPv4_DEVICE_PATH          Ip4DPathNode;
  IPv6_DEVICE_PATH          Ip6DPathNode;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_STATUS                Status;
  TCP_PORTNO                LocalPort;
  TCP_PORTNO                RemotePort;

  TcpProto   = (TCP_PROTO_DATA *)Sock->ProtoReserved;
  TcpService = TcpProto->TcpService;
  Tcb        = TcpProto->TcpPcb;

  LocalPort  = NTOHS (Tcb->LocalEnd.Port);
  RemotePort = NTOHS (Tcb->RemoteEnd.Port);
  if (Sock->IpVersion == IP_VERSION_4) {
    NetLibCreateIPv4DPathNode (
      &Ip4DPathNode,
      TcpService->ControllerHandle,
      Tcb->LocalEnd.Ip.Addr[0],
      LocalPort,
      Tcb->RemoteEnd.Ip.Addr[0],
      RemotePort,
      EFI_IP_PROTO_TCP,
      Tcb->UseDefaultAddr
      );

    IP4_COPY_ADDRESS (&Ip4DPathNode.SubnetMask, &Tcb->SubnetMask);

    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&Ip4DPathNode;
  } else {
    NetLibCreateIPv6DPathNode (
      &Ip6DPathNode,
      TcpService->ControllerHandle,
      &Tcb->LocalEnd.Ip.v6,
      LocalPort,
      &Tcb->RemoteEnd.Ip.v6,
      RemotePort,
      EFI_IP_PROTO_TCP
      );

    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&Ip6DPathNode;
  }

  Sock->DevicePath = AppendDevicePathNode (Sock->ParentDevicePath, DevicePath);
  if (Sock->DevicePath == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gBS->InstallProtocolInterface (
                  &Sock->SockHandle,
                  &gEfiDevicePathProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  Sock->DevicePath
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Sock->DevicePath);
    Sock->DevicePath = NULL;
  }

  return Status;
}
