/** @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>
  Copyright (c) Microsoft Corporation
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "TcpMain.h"

LIST_ENTRY  mTcpRunQue = {
  &mTcpRunQue,
  &mTcpRunQue
};

LIST_ENTRY  mTcpListenQue = {
  &mTcpListenQue,
  &mTcpListenQue
};

//
// The Session secret
// This must be initialized to a random value at boot time
//
TCP_SEQNO  mTcpGlobalSecret;

//
// Union to hold either an IPv4 or IPv6 address
// This is used to simplify the ISN hash computation
//
typedef union {
  UINT8    IPv4[4];
  UINT8    IPv6[16];
} NETWORK_ADDRESS;

//
// The ISN is computed by hashing this structure
// It is initialized with the local and remote IP addresses and ports
// and the secret
//
//
typedef struct {
  UINT16             LocalPort;
  UINT16             RemotePort;
  NETWORK_ADDRESS    LocalAddress;
  NETWORK_ADDRESS    RemoteAddress;
  TCP_SEQNO          Secret;
} ISN_HASH_CTX;

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.

  @retval EFI_SUCCESS             The operation completed successfully
  @retval others                  The underlying functions failed and could not complete the operation

**/
EFI_STATUS
TcpInitTcbLocal (
  IN OUT TCP_CB  *Tcb
  )
{
  TCP_SEQNO   Isn;
  EFI_STATUS  Status;

  //
  // 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
                     );

    Status = TcpGetIsn (
               Tcb->LocalEnd.Ip.v4.Addr,
               sizeof (IPv4_ADDRESS),
               Tcb->LocalEnd.Port,
               Tcb->RemoteEnd.Ip.v4.Addr,
               sizeof (IPv4_ADDRESS),
               Tcb->RemoteEnd.Port,
               &Isn
               );
  } else {
    Tcb->HeadSum = NetIp6PseudoHeadChecksum (
                     &Tcb->LocalEnd.Ip.v6,
                     &Tcb->RemoteEnd.Ip.v6,
                     0x06,
                     0
                     );

    Status = TcpGetIsn (
               Tcb->LocalEnd.Ip.v6.Addr,
               sizeof (IPv6_ADDRESS),
               Tcb->LocalEnd.Port,
               Tcb->RemoteEnd.Ip.v6.Addr,
               sizeof (IPv6_ADDRESS),
               Tcb->RemoteEnd.Port,
               &Isn
               );
  }

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TcpInitTcbLocal: failed to get isn\n"));
    ASSERT (FALSE);
    return Status;
  }

  Tcb->Iss    = Isn;
  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;

  return EFI_SUCCESS;
}

/**
  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;
}

/**
  Retrieves the Initial Sequence Number (ISN) for a TCP connection identified by local
  and remote IP addresses and ports.

  This method is based on https://datatracker.ietf.org/doc/html/rfc9293#section-3.4.1
  Where the ISN is computed as follows:
    ISN = TimeStamp + MD5(LocalIP, LocalPort, RemoteIP, RemotePort, Secret)

  Otherwise:
    ISN = M + F(localip, localport, remoteip, remoteport, secretkey)

    "Here M is the 4 microsecond timer, and F() is a pseudorandom function (PRF) of the
    connection's identifying parameters ("localip, localport, remoteip, remoteport")
    and a secret key ("secretkey") (SHLD-1). F() MUST NOT be computable from the
    outside (MUST-9), or an attacker could still guess at sequence numbers from the
    ISN used for some other connection. The PRF could be implemented as a
    cryptographic hash of the concatenation of the TCP connection parameters and some
    secret data. For discussion of the selection of a specific hash algorithm and
    management of the secret key data."

  @param[in]       LocalIp        A pointer to the local IP address of the TCP connection.
  @param[in]       LocalIpSize    The size, in bytes, of the LocalIp buffer.
  @param[in]       LocalPort      The local port number of the TCP connection.
  @param[in]       RemoteIp       A pointer to the remote IP address of the TCP connection.
  @param[in]       RemoteIpSize   The size, in bytes, of the RemoteIp buffer.
  @param[in]       RemotePort     The remote port number of the TCP connection.
  @param[out]      Isn            A pointer to the variable that will receive the Initial
                                  Sequence Number (ISN).

  @retval EFI_SUCCESS             The operation completed successfully, and the ISN was
                                  retrieved.
  @retval EFI_INVALID_PARAMETER   One or more of the input parameters are invalid.
  @retval EFI_UNSUPPORTED         The operation is not supported.

**/
EFI_STATUS
TcpGetIsn (
  IN UINT8       *LocalIp,
  IN UINTN       LocalIpSize,
  IN UINT16      LocalPort,
  IN UINT8       *RemoteIp,
  IN UINTN       RemoteIpSize,
  IN UINT16      RemotePort,
  OUT TCP_SEQNO  *Isn
  )
{
  EFI_STATUS          Status;
  EFI_HASH2_PROTOCOL  *Hash2Protocol;
  EFI_HASH2_OUTPUT    HashResult;
  ISN_HASH_CTX        IsnHashCtx;
  EFI_TIME            TimeStamp;

  //
  // Check that the ISN pointer is valid
  //
  if (Isn == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The local ip may be a v4 or v6 address and may not be NULL
  //
  if ((LocalIp == NULL) || (LocalIpSize == 0) || (RemoteIp == NULL) || (RemoteIpSize == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // the local ip may be a v4 or v6 address
  //
  if ((LocalIpSize != sizeof (EFI_IPv4_ADDRESS)) && (LocalIpSize != sizeof (EFI_IPv6_ADDRESS))) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Locate the Hash Protocol
  //
  Status = gBS->LocateProtocol (&gEfiHash2ProtocolGuid, NULL, (VOID **)&Hash2Protocol);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_NET, "Failed to locate Hash Protocol: %r\n", Status));

    //
    // TcpCreateService(..) is expected to be called prior to this function
    //
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  //
  // Initialize the hash algorithm
  //
  Status = Hash2Protocol->HashInit (Hash2Protocol, &gEfiHashAlgorithmSha256Guid);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_NET, "Failed to initialize sha256 hash algorithm: %r\n", Status));
    return Status;
  }

  IsnHashCtx.LocalPort  = LocalPort;
  IsnHashCtx.RemotePort = RemotePort;
  IsnHashCtx.Secret     = mTcpGlobalSecret;

  //
  // Check the IP address family and copy accordingly
  //
  if (LocalIpSize == sizeof (EFI_IPv4_ADDRESS)) {
    CopyMem (&IsnHashCtx.LocalAddress.IPv4, LocalIp, LocalIpSize);
  } else if (LocalIpSize == sizeof (EFI_IPv6_ADDRESS)) {
    CopyMem (&IsnHashCtx.LocalAddress.IPv6, LocalIp, LocalIpSize);
  } else {
    return EFI_INVALID_PARAMETER; // Unsupported address size
  }

  //
  // Repeat the process for the remote IP address
  //
  if (RemoteIpSize == sizeof (EFI_IPv4_ADDRESS)) {
    CopyMem (&IsnHashCtx.RemoteAddress.IPv4, RemoteIp, RemoteIpSize);
  } else if (RemoteIpSize == sizeof (EFI_IPv6_ADDRESS)) {
    CopyMem (&IsnHashCtx.RemoteAddress.IPv6, RemoteIp, RemoteIpSize);
  } else {
    return EFI_INVALID_PARAMETER; // Unsupported address size
  }

  //
  // Compute the hash
  // Update the hash with the data
  //
  Status = Hash2Protocol->HashUpdate (Hash2Protocol, (UINT8 *)&IsnHashCtx, sizeof (IsnHashCtx));
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_NET, "Failed to update hash: %r\n", Status));
    return Status;
  }

  //
  // Finalize the hash and retrieve the result
  //
  Status = Hash2Protocol->HashFinal (Hash2Protocol, &HashResult);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_NET, "Failed to finalize hash: %r\n", Status));
    return Status;
  }

  Status = gRT->GetTime (&TimeStamp, NULL);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // copy the first 4 bytes of the hash result into the ISN
  //
  CopyMem (Isn, HashResult.Md5Hash, sizeof (*Isn));

  //
  // now add the timestamp to the ISN as 4 microseconds units (1000 / 4 = 250)
  //
  *Isn += (TCP_SEQNO)TimeStamp.Nanosecond * 250;

  return Status;
}

/**
  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.

  @retval EFI_SUCCESS             The operation completed successfully
  @retval others                  The underlying functions failed and could not complete the operation

**/
EFI_STATUS
TcpOnAppConnect (
  IN OUT TCP_CB  *Tcb
  )
{
  EFI_STATUS  Status;

  Status = TcpInitTcbLocal (Tcb);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  TcpSetState (Tcb, TCP_SYN_SENT);

  TcpSetTimer (Tcb, TCP_TIMER_CONNECT, Tcb->ConnectTimeout);
  TcpToSendData (Tcb, 1);

  return EFI_SUCCESS;
}

/**
  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;
}
