/** @file
DnsDxe support functions implementation.

Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DnsImpl.h"

/**
  Remove TokenEntry from TokenMap.

  @param[in] TokenMap          All DNSv4 Token entrys.
  @param[in] TokenEntry        TokenEntry need to be removed.

  @retval EFI_SUCCESS          Remove TokenEntry from TokenMap successfully.
  @retval EFI_NOT_FOUND        TokenEntry is not found in TokenMap.

**/
EFI_STATUS
Dns4RemoveTokenEntry (
  IN NET_MAP                    *TokenMap,
  IN DNS4_TOKEN_ENTRY           *TokenEntry
  )
{
  NET_MAP_ITEM  *Item;

  //
  // Find the TokenEntry first.
  //
  Item = NetMapFindKey (TokenMap, (VOID *) TokenEntry);

  if (Item != NULL) {
    //
    // Remove the TokenEntry if it's found in the map.
    //
    NetMapRemoveItem (TokenMap, Item, NULL);

    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  Remove TokenEntry from TokenMap.

  @param[in] TokenMap           All DNSv6 Token entrys.
  @param[in] TokenEntry         TokenEntry need to be removed.

  @retval EFI_SUCCESS           Remove TokenEntry from TokenMap successfully.
  @retval EFI_NOT_FOUND         TokenEntry is not found in TokenMap.

**/
EFI_STATUS
Dns6RemoveTokenEntry (
  IN NET_MAP                    *TokenMap,
  IN DNS6_TOKEN_ENTRY           *TokenEntry
  )
{
  NET_MAP_ITEM  *Item;

  //
  // Find the TokenEntry first.
  //
  Item = NetMapFindKey (TokenMap, (VOID *) TokenEntry);

  if (Item != NULL) {
    //
    // Remove the TokenEntry if it's found in the map.
    //
    NetMapRemoveItem (TokenMap, Item, NULL);

    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  This function cancel the token specified by Arg in the Map.

  @param[in]  Map             Pointer to the NET_MAP.
  @param[in]  Item            Pointer to the NET_MAP_ITEM.
  @param[in]  Arg             Pointer to the token to be cancelled. If NULL, all
                              the tokens in this Map will be cancelled.
                              This parameter is optional and may be NULL.

  @retval EFI_SUCCESS         The token is cancelled if Arg is NULL, or the token
                              is not the same as that in the Item, if Arg is not
                              NULL.
  @retval EFI_ABORTED         Arg is not NULL, and the token specified by Arg is
                              cancelled.

**/
EFI_STATUS
EFIAPI
Dns4CancelTokens (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Arg OPTIONAL
  )
{
  DNS4_TOKEN_ENTRY           *TokenEntry;
  NET_BUF                    *Packet;
  UDP_IO                     *UdpIo;

  if ((Arg != NULL) && (Item->Key != Arg)) {
    return EFI_SUCCESS;
  }

  if (Item->Value != NULL) {
    //
    // If the TokenEntry is a transmit TokenEntry, the corresponding Packet is recorded in
    // Item->Value.
    //
    Packet  = (NET_BUF *) (Item->Value);
    UdpIo = (UDP_IO *) (*((UINTN *) &Packet->ProtoData[0]));

    UdpIoCancelSentDatagram (UdpIo, Packet);
  }

  //
  // Remove TokenEntry from Dns4TxTokens.
  //
  TokenEntry = (DNS4_TOKEN_ENTRY *) Item->Key;
  if (Dns4RemoveTokenEntry (Map, TokenEntry) == EFI_SUCCESS) {
    TokenEntry->Token->Status = EFI_ABORTED;
    gBS->SignalEvent (TokenEntry->Token->Event);
    DispatchDpc ();
  }

  if (Arg != NULL) {
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  This function cancel the token specified by Arg in the Map.

  @param[in]  Map             Pointer to the NET_MAP.
  @param[in]  Item            Pointer to the NET_MAP_ITEM.
  @param[in]  Arg             Pointer to the token to be cancelled. If NULL, all
                              the tokens in this Map will be cancelled.
                              This parameter is optional and may be NULL.

  @retval EFI_SUCCESS         The token is cancelled if Arg is NULL, or the token
                              is not the same as that in the Item, if Arg is not
                              NULL.
  @retval EFI_ABORTED         Arg is not NULL, and the token specified by Arg is
                              cancelled.

**/
EFI_STATUS
EFIAPI
Dns6CancelTokens (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Arg OPTIONAL
  )
{
  DNS6_TOKEN_ENTRY           *TokenEntry;
  NET_BUF                    *Packet;
  UDP_IO                     *UdpIo;

  if ((Arg != NULL) && (Item->Key != Arg)) {
    return EFI_SUCCESS;
  }

  if (Item->Value != NULL) {
    //
    // If the TokenEntry is a transmit TokenEntry, the corresponding Packet is recorded in
    // Item->Value.
    //
    Packet  = (NET_BUF *) (Item->Value);
    UdpIo = (UDP_IO *) (*((UINTN *) &Packet->ProtoData[0]));

    UdpIoCancelSentDatagram (UdpIo, Packet);
  }

  //
  // Remove TokenEntry from Dns6TxTokens.
  //
  TokenEntry = (DNS6_TOKEN_ENTRY *) Item->Key;
  if (Dns6RemoveTokenEntry (Map, TokenEntry) == EFI_SUCCESS) {
    TokenEntry->Token->Status = EFI_ABORTED;
    gBS->SignalEvent (TokenEntry->Token->Event);
    DispatchDpc ();
  }

  if (Arg != NULL) {
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  Get the TokenEntry from the TokensMap.

  @param[in]  TokensMap           All DNSv4 Token entrys
  @param[in]  Token               Pointer to the token to be get.
  @param[out] TokenEntry          Pointer to TokenEntry corresponding Token.

  @retval EFI_SUCCESS             Get the TokenEntry from the TokensMap successfully.
  @retval EFI_NOT_FOUND           TokenEntry is not found in TokenMap.

**/
EFI_STATUS
EFIAPI
GetDns4TokenEntry (
  IN     NET_MAP                   *TokensMap,
  IN     EFI_DNS4_COMPLETION_TOKEN *Token,
     OUT DNS4_TOKEN_ENTRY          **TokenEntry
  )
{
  LIST_ENTRY              *Entry;

  NET_MAP_ITEM            *Item;

  NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {
    Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
    *TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);
    if ((*TokenEntry)->Token == Token) {
      return EFI_SUCCESS;
    }
  }

  *TokenEntry = NULL;

  return EFI_NOT_FOUND;
}

/**
  Get the TokenEntry from the TokensMap.

  @param[in]  TokensMap           All DNSv6 Token entrys
  @param[in]  Token               Pointer to the token to be get.
  @param[out] TokenEntry          Pointer to TokenEntry corresponding Token.

  @retval EFI_SUCCESS             Get the TokenEntry from the TokensMap successfully.
  @retval EFI_NOT_FOUND           TokenEntry is not found in TokenMap.

**/
EFI_STATUS
EFIAPI
GetDns6TokenEntry (
  IN     NET_MAP                   *TokensMap,
  IN     EFI_DNS6_COMPLETION_TOKEN *Token,
     OUT DNS6_TOKEN_ENTRY          **TokenEntry
  )
{
  LIST_ENTRY              *Entry;

  NET_MAP_ITEM            *Item;

  NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {
    Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
    *TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);
    if ((*TokenEntry)->Token == Token) {
      return EFI_SUCCESS;
    }
  }

  *TokenEntry =NULL;

  return EFI_NOT_FOUND;
}

/**
  Cancel DNS4 tokens from the DNS4 instance.

  @param[in]  Instance           Pointer to the DNS instance context data.
  @param[in]  Token              Pointer to the token to be canceled. If NULL, all
                                 tokens in this instance will be cancelled.
                                 This parameter is optional and may be NULL.

  @retval EFI_SUCCESS            The Token is cancelled.
  @retval EFI_NOT_FOUND          The Token is not found.

**/
EFI_STATUS
Dns4InstanceCancelToken (
  IN DNS_INSTANCE               *Instance,
  IN EFI_DNS4_COMPLETION_TOKEN  *Token
  )
{
  EFI_STATUS        Status;
  DNS4_TOKEN_ENTRY  *TokenEntry;

  TokenEntry = NULL;

  if(Token != NULL  ) {
    Status = GetDns4TokenEntry (&Instance->Dns4TxTokens, Token, &TokenEntry);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  } else {
    TokenEntry = NULL;
  }

  //
  // Cancel this TokenEntry from the Dns4TxTokens map.
  //
  Status = NetMapIterate (&Instance->Dns4TxTokens, Dns4CancelTokens, TokenEntry);

  if ((TokenEntry != NULL) && (Status == EFI_ABORTED)) {
    //
    // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from
    // the Dns4TxTokens and returns success.
    //
    if (NetMapIsEmpty (&Instance->Dns4TxTokens)) {
       Instance->UdpIo->Protocol.Udp4->Cancel (Instance->UdpIo->Protocol.Udp4, &Instance->UdpIo->RecvRequest->Token.Udp4);
    }
    return EFI_SUCCESS;
  }

  ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns4TxTokens)));

  if (NetMapIsEmpty (&Instance->Dns4TxTokens)) {
    Instance->UdpIo->Protocol.Udp4->Cancel (Instance->UdpIo->Protocol.Udp4, &Instance->UdpIo->RecvRequest->Token.Udp4);
  }

  return EFI_SUCCESS;
}

/**
  Cancel DNS6 tokens from the DNS6 instance.

  @param[in]  Instance           Pointer to the DNS instance context data.
  @param[in]  Token              Pointer to the token to be canceled. If NULL, all
                                 tokens in this instance will be cancelled.
                                 This parameter is optional and may be NULL.

  @retval EFI_SUCCESS            The Token is cancelled.
  @retval EFI_NOT_FOUND          The Token is not found.

**/
EFI_STATUS
Dns6InstanceCancelToken (
  IN DNS_INSTANCE               *Instance,
  IN EFI_DNS6_COMPLETION_TOKEN  *Token
  )
{
  EFI_STATUS        Status;
  DNS6_TOKEN_ENTRY  *TokenEntry;

  TokenEntry = NULL;

  if(Token != NULL  ) {
    Status = GetDns6TokenEntry (&Instance->Dns6TxTokens, Token, &TokenEntry);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  } else {
    TokenEntry = NULL;
  }

  //
  // Cancel this TokenEntry from the Dns6TxTokens map.
  //
  Status = NetMapIterate (&Instance->Dns6TxTokens, Dns6CancelTokens, TokenEntry);

  if ((TokenEntry != NULL) && (Status == EFI_ABORTED)) {
    //
    // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from
    // the Dns6TxTokens and returns success.
    //
    if (NetMapIsEmpty (&Instance->Dns6TxTokens)) {
       Instance->UdpIo->Protocol.Udp6->Cancel (Instance->UdpIo->Protocol.Udp6, &Instance->UdpIo->RecvRequest->Token.Udp6);
    }
    return EFI_SUCCESS;
  }

  ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns6TxTokens)));

  if (NetMapIsEmpty (&Instance->Dns6TxTokens)) {
    Instance->UdpIo->Protocol.Udp6->Cancel (Instance->UdpIo->Protocol.Udp6, &Instance->UdpIo->RecvRequest->Token.Udp6);
  }

  return EFI_SUCCESS;
}

/**
  Free the resource related to the configure parameters.

  @param  Config                 The DNS configure data

**/
VOID
Dns4CleanConfigure (
  IN OUT EFI_DNS4_CONFIG_DATA  *Config
  )
{
  if (Config->DnsServerList != NULL) {
    FreePool (Config->DnsServerList);
  }

  ZeroMem (Config, sizeof (EFI_DNS4_CONFIG_DATA));
}

/**
  Free the resource related to the configure parameters.

  @param  Config                 The DNS configure data

**/
VOID
Dns6CleanConfigure (
  IN OUT EFI_DNS6_CONFIG_DATA  *Config
  )
{
  if (Config->DnsServerList != NULL) {
    FreePool (Config->DnsServerList);
  }

  ZeroMem (Config, sizeof (EFI_DNS6_CONFIG_DATA));
}

/**
  Allocate memory for configure parameter such as timeout value for Dst,
  then copy the configure parameter from Src to Dst.

  @param[out]  Dst               The destination DHCP configure data.
  @param[in]   Src               The source DHCP configure data.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
  @retval EFI_SUCCESS            The configure is copied.

**/
EFI_STATUS
Dns4CopyConfigure (
  OUT EFI_DNS4_CONFIG_DATA  *Dst,
  IN  EFI_DNS4_CONFIG_DATA  *Src
  )
{
  UINTN                     Len;
  UINT32                    Index;

  CopyMem (Dst, Src, sizeof (*Dst));
  Dst->DnsServerList = NULL;

  //
  // Allocate a memory then copy DnsServerList to it
  //
  if (Src->DnsServerList != NULL) {
    Len                = Src->DnsServerListCount * sizeof (EFI_IPv4_ADDRESS);
    Dst->DnsServerList = AllocatePool (Len);
    if (Dst->DnsServerList == NULL) {
      Dns4CleanConfigure (Dst);
      return EFI_OUT_OF_RESOURCES;
    }

    for (Index = 0; Index < Src->DnsServerListCount; Index++) {
      CopyMem (&Dst->DnsServerList[Index], &Src->DnsServerList[Index], sizeof (EFI_IPv4_ADDRESS));
    }
  }

  return EFI_SUCCESS;
}

/**
  Allocate memory for configure parameter such as timeout value for Dst,
  then copy the configure parameter from Src to Dst.

  @param[out]  Dst               The destination DHCP configure data.
  @param[in]   Src               The source DHCP configure data.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
  @retval EFI_SUCCESS            The configure is copied.

**/
EFI_STATUS
Dns6CopyConfigure (
  OUT EFI_DNS6_CONFIG_DATA  *Dst,
  IN  EFI_DNS6_CONFIG_DATA  *Src
  )
{
  UINTN                     Len;
  UINT32                    Index;

  CopyMem (Dst, Src, sizeof (*Dst));
  Dst->DnsServerList = NULL;

  //
  // Allocate a memory then copy DnsServerList to it
  //
  if (Src->DnsServerList != NULL) {
    Len                = Src->DnsServerCount * sizeof (EFI_IPv6_ADDRESS);
    Dst->DnsServerList = AllocatePool (Len);
    if (Dst->DnsServerList == NULL) {
      Dns6CleanConfigure (Dst);
      return EFI_OUT_OF_RESOURCES;
    }

    for (Index = 0; Index < Src->DnsServerCount; Index++) {
      CopyMem (&Dst->DnsServerList[Index], &Src->DnsServerList[Index], sizeof (EFI_IPv6_ADDRESS));
    }
  }

  return EFI_SUCCESS;
}

/**
  Callback of Dns packet. Does nothing.

  @param Arg           The context.

**/
VOID
EFIAPI
DnsDummyExtFree (
  IN VOID                   *Arg
  )
{
}

/**
  Poll the UDP to get the IP4 default address, which may be retrieved
  by DHCP.

  The default time out value is 5 seconds. If IP has retrieved the default address,
  the UDP is reconfigured.

  @param  Instance               The DNS instance
  @param  UdpIo                  The UDP_IO to poll
  @param  UdpCfgData             The UDP configure data to reconfigure the UDP_IO

  @retval TRUE                   The default address is retrieved and UDP is reconfigured.
  @retval FALSE                  Some error occurred.

**/
BOOLEAN
Dns4GetMapping (
  IN DNS_INSTANCE           *Instance,
  IN UDP_IO                 *UdpIo,
  IN EFI_UDP4_CONFIG_DATA   *UdpCfgData
  )
{
  DNS_SERVICE               *Service;
  EFI_IP4_MODE_DATA         Ip4Mode;
  EFI_UDP4_PROTOCOL         *Udp;
  EFI_STATUS                Status;

  ASSERT (Instance->Dns4CfgData.UseDefaultSetting);

  Service = Instance->Service;
  Udp     = UdpIo->Protocol.Udp4;

  Status = gBS->SetTimer (
                  Service->TimerToGetMap,
                  TimerRelative,
                  DNS_TIME_TO_GETMAP * TICKS_PER_SECOND
                  );
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {
    Udp->Poll (Udp);

    if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip4Mode, NULL, NULL)) &&
        Ip4Mode.IsConfigured) {

      Udp->Configure (Udp, NULL);
      return (BOOLEAN) (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);
    }
  }

  return FALSE;
}

/**
  Configure the opened Udp6 instance until the corresponding Ip6 instance
  has been configured.

  @param  Instance               The DNS instance
  @param  UdpIo                  The UDP_IO to poll
  @param  UdpCfgData             The UDP configure data to reconfigure the UDP_IO

  @retval TRUE                   Configure the Udp6 instance successfully.
  @retval FALSE                  Some error occurred.

**/
BOOLEAN
Dns6GetMapping (
  IN DNS_INSTANCE           *Instance,
  IN UDP_IO                 *UdpIo,
  IN EFI_UDP6_CONFIG_DATA   *UdpCfgData
  )
{
  DNS_SERVICE               *Service;
  EFI_IP6_MODE_DATA         Ip6Mode;
  EFI_UDP6_PROTOCOL         *Udp;
  EFI_STATUS                Status;

  Service = Instance->Service;
  Udp     = UdpIo->Protocol.Udp6;

  Status = gBS->SetTimer (
                  Service->TimerToGetMap,
                  TimerRelative,
                  DNS_TIME_TO_GETMAP * TICKS_PER_SECOND
                  );
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {
    Udp->Poll (Udp);

    if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &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);
      }

      if (!Ip6Mode.IsStarted || Ip6Mode.IsConfigured) {
        Udp->Configure (Udp, NULL);
        if (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS) {
          return TRUE;
        }
      }
    }
  }

  return FALSE;
}

/**
  Configure the UDP.

  @param  Instance               The DNS session
  @param  UdpIo                  The UDP_IO instance

  @retval EFI_SUCCESS            The UDP is successfully configured for the
                                 session.

**/
EFI_STATUS
Dns4ConfigUdp (
  IN DNS_INSTANCE           *Instance,
  IN UDP_IO                 *UdpIo
  )
{
  EFI_DNS4_CONFIG_DATA      *Config;
  EFI_UDP4_CONFIG_DATA      UdpConfig;
  EFI_STATUS                Status;

  Config = &Instance->Dns4CfgData;

  UdpConfig.AcceptBroadcast    = FALSE;
  UdpConfig.AcceptPromiscuous  = FALSE;
  UdpConfig.AcceptAnyPort      = FALSE;
  UdpConfig.AllowDuplicatePort = FALSE;
  UdpConfig.TypeOfService      = 0;
  UdpConfig.TimeToLive         = 128;
  UdpConfig.DoNotFragment      = FALSE;
  UdpConfig.ReceiveTimeout     = 0;
  UdpConfig.TransmitTimeout    = 0;
  UdpConfig.UseDefaultAddress  = Config->UseDefaultSetting;
  UdpConfig.SubnetMask         = Config->SubnetMask;
  UdpConfig.StationPort        = Config->LocalPort;
  UdpConfig.RemotePort         = DNS_SERVER_PORT;

  CopyMem (&UdpConfig.StationAddress, &Config->StationIp, sizeof (EFI_IPv4_ADDRESS));
  CopyMem (&UdpConfig.RemoteAddress, &Instance->SessionDnsServer.v4, sizeof (EFI_IPv4_ADDRESS));

  Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfig);

  if ((Status == EFI_NO_MAPPING) && Dns4GetMapping (Instance, UdpIo, &UdpConfig)) {
    return EFI_SUCCESS;
  }

  return Status;
}

/**
  Configure the UDP.

  @param  Instance               The DNS session
  @param  UdpIo                  The UDP_IO instance

  @retval EFI_SUCCESS            The UDP is successfully configured for the
                                 session.

**/
EFI_STATUS
Dns6ConfigUdp (
  IN DNS_INSTANCE           *Instance,
  IN UDP_IO                 *UdpIo
  )
{
  EFI_DNS6_CONFIG_DATA      *Config;
  EFI_UDP6_CONFIG_DATA      UdpConfig;
  EFI_STATUS                Status;

  Config = &Instance->Dns6CfgData;

  UdpConfig.AcceptPromiscuous  = FALSE;
  UdpConfig.AcceptAnyPort      = FALSE;
  UdpConfig.AllowDuplicatePort = FALSE;
  UdpConfig.TrafficClass       = 0;
  UdpConfig.HopLimit           = 128;
  UdpConfig.ReceiveTimeout     = 0;
  UdpConfig.TransmitTimeout    = 0;
  UdpConfig.StationPort        = Config->LocalPort;
  UdpConfig.RemotePort         = DNS_SERVER_PORT;
  CopyMem (&UdpConfig.StationAddress, &Config->StationIp, sizeof (EFI_IPv6_ADDRESS));
  CopyMem (&UdpConfig.RemoteAddress, &Instance->SessionDnsServer.v6, sizeof (EFI_IPv6_ADDRESS));

  Status = UdpIo->Protocol.Udp6->Configure (UdpIo->Protocol.Udp6, &UdpConfig);

  if ((Status == EFI_NO_MAPPING) && Dns6GetMapping (Instance, UdpIo, &UdpConfig)) {
    return EFI_SUCCESS;
  }

  return Status;
}

/**
  Update Dns4 cache to shared list of caches of all DNSv4 instances.

  @param  Dns4CacheList      All Dns4 cache list.
  @param  DeleteFlag         If FALSE, this function is to add one entry to the DNS Cache.
                             If TRUE, this function will delete matching DNS Cache entry.
  @param  Override           If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
                             If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
  @param  DnsCacheEntry      Entry Pointer to DNS Cache entry.

  @retval EFI_SUCCESS        Update Dns4 cache successfully.
  @retval Others             Failed to update Dns4 cache.

**/
EFI_STATUS
EFIAPI
UpdateDns4Cache (
  IN LIST_ENTRY             *Dns4CacheList,
  IN BOOLEAN                DeleteFlag,
  IN BOOLEAN                Override,
  IN EFI_DNS4_CACHE_ENTRY   DnsCacheEntry
  )
{
  DNS4_CACHE    *NewDnsCache;
  DNS4_CACHE    *Item;
  LIST_ENTRY    *Entry;
  LIST_ENTRY    *Next;

  NewDnsCache = NULL;
  Item        = NULL;

  //
  // Search the database for the matching EFI_DNS_CACHE_ENTRY
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns4CacheList) {
    Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
    if (StrCmp (DnsCacheEntry.HostName, Item->DnsCache.HostName) == 0 && \
        CompareMem (DnsCacheEntry.IpAddress, Item->DnsCache.IpAddress, sizeof (EFI_IPv4_ADDRESS)) == 0) {
      //
      // This is the Dns cache entry
      //
      if (DeleteFlag) {
        //
        // Delete matching DNS Cache entry
        //
        RemoveEntryList (&Item->AllCacheLink);

        FreePool (Item->DnsCache.HostName);
        FreePool (Item->DnsCache.IpAddress);
        FreePool (Item);

        return EFI_SUCCESS;
      } else if (Override) {
        //
        // Update this one
        //
        Item->DnsCache.Timeout = DnsCacheEntry.Timeout;

        return EFI_SUCCESS;
      } else {
        return EFI_ACCESS_DENIED;
      }
    }
  }

  //
  // Add new one
  //
  NewDnsCache = AllocatePool (sizeof (DNS4_CACHE));
  if (NewDnsCache == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (&NewDnsCache->AllCacheLink);

  NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));
  if (NewDnsCache->DnsCache.HostName == NULL) {
    FreePool (NewDnsCache);
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));

  NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv4_ADDRESS));
  if (NewDnsCache->DnsCache.IpAddress == NULL) {
    FreePool (NewDnsCache->DnsCache.HostName);
    FreePool (NewDnsCache);
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv4_ADDRESS));

  NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;

  InsertTailList (Dns4CacheList, &NewDnsCache->AllCacheLink);

  return EFI_SUCCESS;
}

/**
  Update Dns6 cache to shared list of caches of all DNSv6 instances.

  @param  Dns6CacheList      All Dns6 cache list.
  @param  DeleteFlag         If FALSE, this function is to add one entry to the DNS Cache.
                             If TRUE, this function will delete matching DNS Cache entry.
  @param  Override           If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
                             If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
  @param  DnsCacheEntry      Entry Pointer to DNS Cache entry.

  @retval EFI_SUCCESS        Update Dns6 cache successfully.
  @retval Others             Failed to update Dns6 cache.
**/
EFI_STATUS
EFIAPI
UpdateDns6Cache (
  IN LIST_ENTRY             *Dns6CacheList,
  IN BOOLEAN                DeleteFlag,
  IN BOOLEAN                Override,
  IN EFI_DNS6_CACHE_ENTRY   DnsCacheEntry
  )
{
  DNS6_CACHE    *NewDnsCache;
  DNS6_CACHE    *Item;
  LIST_ENTRY    *Entry;
  LIST_ENTRY    *Next;

  NewDnsCache = NULL;
  Item        = NULL;

  //
  // Search the database for the matching EFI_DNS_CACHE_ENTRY
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns6CacheList) {
    Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
    if (StrCmp (DnsCacheEntry.HostName, Item->DnsCache.HostName) == 0 && \
        CompareMem (DnsCacheEntry.IpAddress, Item->DnsCache.IpAddress, sizeof (EFI_IPv6_ADDRESS)) == 0) {
      //
      // This is the Dns cache entry
      //
      if (DeleteFlag) {
        //
        // Delete matching DNS Cache entry
        //
        RemoveEntryList (&Item->AllCacheLink);

        FreePool (Item->DnsCache.HostName);
        FreePool (Item->DnsCache.IpAddress);
        FreePool (Item);

        return EFI_SUCCESS;
      } else if (Override) {
        //
        // Update this one
        //
        Item->DnsCache.Timeout = DnsCacheEntry.Timeout;

        return EFI_SUCCESS;
      } else {
        return EFI_ACCESS_DENIED;
      }
    }
  }

  //
  // Add new one
  //
  NewDnsCache = AllocatePool (sizeof (DNS6_CACHE));
  if (NewDnsCache == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (&NewDnsCache->AllCacheLink);

  NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));
  if (NewDnsCache->DnsCache.HostName == NULL) {
    FreePool (NewDnsCache);
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));

  NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv6_ADDRESS));
  if (NewDnsCache->DnsCache.IpAddress == NULL) {
    FreePool (NewDnsCache->DnsCache.HostName);
    FreePool (NewDnsCache);
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv6_ADDRESS));

  NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;

  InsertTailList (Dns6CacheList, &NewDnsCache->AllCacheLink);

  return EFI_SUCCESS;
}

/**
  Add Dns4 ServerIp to common list of addresses of all configured DNSv4 server.

  @param  Dns4ServerList    Common list of addresses of all configured DNSv4 server.
  @param  ServerIp          DNS server Ip.

  @retval EFI_SUCCESS       Add Dns4 ServerIp to common list successfully.
  @retval Others            Failed to add Dns4 ServerIp to common list.

**/
EFI_STATUS
EFIAPI
AddDns4ServerIp (
  IN LIST_ENTRY                *Dns4ServerList,
  IN EFI_IPv4_ADDRESS           ServerIp
  )
{
  DNS4_SERVER_IP    *NewServerIp;
  DNS4_SERVER_IP    *Item;
  LIST_ENTRY        *Entry;
  LIST_ENTRY        *Next;

  NewServerIp = NULL;
  Item        = NULL;

  //
  // Search the database for the matching ServerIp
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns4ServerList) {
    Item = NET_LIST_USER_STRUCT (Entry, DNS4_SERVER_IP, AllServerLink);
    if (CompareMem (&Item->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS)) == 0) {
      //
      // Already done.
      //
      return EFI_SUCCESS;
    }
  }

  //
  // Add new one
  //
  NewServerIp = AllocatePool (sizeof (DNS4_SERVER_IP));
  if (NewServerIp == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (&NewServerIp->AllServerLink);

  CopyMem (&NewServerIp->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS));

  InsertTailList (Dns4ServerList, &NewServerIp->AllServerLink);

  return EFI_SUCCESS;
}

/**
  Add Dns6 ServerIp to common list of addresses of all configured DNSv6 server.

  @param  Dns6ServerList    Common list of addresses of all configured DNSv6 server.
  @param  ServerIp          DNS server Ip.

  @retval EFI_SUCCESS       Add Dns6 ServerIp to common list successfully.
  @retval Others            Failed to add Dns6 ServerIp to common list.

**/
EFI_STATUS
EFIAPI
AddDns6ServerIp (
  IN LIST_ENTRY                *Dns6ServerList,
  IN EFI_IPv6_ADDRESS           ServerIp
  )
{
  DNS6_SERVER_IP    *NewServerIp;
  DNS6_SERVER_IP    *Item;
  LIST_ENTRY        *Entry;
  LIST_ENTRY        *Next;

  NewServerIp = NULL;
  Item        = NULL;

  //
  // Search the database for the matching ServerIp
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns6ServerList) {
    Item = NET_LIST_USER_STRUCT (Entry, DNS6_SERVER_IP, AllServerLink);
    if (CompareMem (&Item->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS)) == 0) {
      //
      // Already done.
      //
      return EFI_SUCCESS;
    }
  }

  //
  // Add new one
  //
  NewServerIp = AllocatePool (sizeof (DNS6_SERVER_IP));
  if (NewServerIp == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (&NewServerIp->AllServerLink);

  CopyMem (&NewServerIp->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS));

  InsertTailList (Dns6ServerList, &NewServerIp->AllServerLink);

  return EFI_SUCCESS;
}

/**
  Find out whether the response is valid or invalid.

  @param  TokensMap       All DNS transmittal Tokens entry.
  @param  Identification  Identification for queried packet.
  @param  Type            Type for queried packet.
  @param  Class           Class for queried packet.
  @param  Item            Return corresponding Token entry.

  @retval TRUE            The response is valid.
  @retval FALSE           The response is invalid.

**/
BOOLEAN
IsValidDnsResponse (
  IN     NET_MAP      *TokensMap,
  IN     UINT16       Identification,
  IN     UINT16       Type,
  IN     UINT16       Class,
     OUT NET_MAP_ITEM **Item
  )
{
  LIST_ENTRY              *Entry;

  NET_BUF                 *Packet;
  UINT8                   *TxString;
  DNS_HEADER              *DnsHeader;
  CHAR8                   *QueryName;
  DNS_QUERY_SECTION       *QuerySection;

  NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {
    *Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
    Packet = (NET_BUF *) ((*Item)->Value);
    if (Packet == NULL) {

      continue;
    } else {
      TxString = NetbufGetByte (Packet, 0, NULL);
      ASSERT (TxString != NULL);
      DnsHeader = (DNS_HEADER *) TxString;
      QueryName = (CHAR8 *) (TxString + sizeof (*DnsHeader));
      QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);

      if (NTOHS (DnsHeader->Identification) == Identification &&
          NTOHS (QuerySection->Type) == Type &&
          NTOHS (QuerySection->Class) == Class) {
        return TRUE;
      }
    }
  }

  *Item = NULL;

  return FALSE;
}

/**
  Parse Dns Response.

  @param  Instance              The DNS instance
  @param  RxString              Received buffer.
  @param  Length                Received buffer length.
  @param  Completed             Flag to indicate that Dns response is valid.

  @retval EFI_SUCCESS           Parse Dns Response successfully.
  @retval Others                Failed to parse Dns Response.

**/
EFI_STATUS
ParseDnsResponse (
  IN OUT DNS_INSTANCE              *Instance,
  IN     UINT8                     *RxString,
  IN     UINT32                    Length,
     OUT BOOLEAN                   *Completed
  )
{
  DNS_HEADER            *DnsHeader;

  CHAR8                 *QueryName;
  UINT32                QueryNameLen;
  DNS_QUERY_SECTION     *QuerySection;

  CHAR8                 *AnswerName;
  DNS_ANSWER_SECTION    *AnswerSection;
  UINT8                 *AnswerData;

  NET_MAP_ITEM          *Item;
  DNS4_TOKEN_ENTRY      *Dns4TokenEntry;
  DNS6_TOKEN_ENTRY      *Dns6TokenEntry;

  UINT32                IpCount;
  UINT32                RRCount;
  UINT32                AnswerSectionNum;
  UINT32                CNameTtl;

  EFI_IPv4_ADDRESS      *HostAddr4;
  EFI_IPv6_ADDRESS      *HostAddr6;

  EFI_DNS4_CACHE_ENTRY  *Dns4CacheEntry;
  EFI_DNS6_CACHE_ENTRY  *Dns6CacheEntry;

  DNS_RESOURCE_RECORD   *Dns4RR;
  DNS6_RESOURCE_RECORD  *Dns6RR;

  EFI_STATUS            Status;
  UINT32                RemainingLength;

  EFI_TPL               OldTpl;

  Item             = NULL;
  Dns4TokenEntry   = NULL;
  Dns6TokenEntry   = NULL;

  IpCount          = 0;
  RRCount          = 0;
  AnswerSectionNum = 0;
  CNameTtl         = 0;

  HostAddr4        = NULL;
  HostAddr6        = NULL;

  Dns4CacheEntry   = NULL;
  Dns6CacheEntry   = NULL;

  Dns4RR           = NULL;
  Dns6RR           = NULL;

  *Completed       = TRUE;
  Status           = EFI_SUCCESS;
  RemainingLength  = Length;

  //
  // Check whether the remaining packet length is available or not.
  //
  if (RemainingLength <= sizeof (DNS_HEADER)) {
    *Completed = FALSE;
    return EFI_ABORTED;
  } else {
    RemainingLength -= sizeof (DNS_HEADER);
  }

  //
  // Get header
  //
  DnsHeader = (DNS_HEADER *) RxString;

  DnsHeader->Identification = NTOHS (DnsHeader->Identification);
  DnsHeader->Flags.Uint16 = NTOHS (DnsHeader->Flags.Uint16);
  DnsHeader->QuestionsNum = NTOHS (DnsHeader->QuestionsNum);
  DnsHeader->AnswersNum = NTOHS (DnsHeader->AnswersNum);
  DnsHeader->AuthorityNum = NTOHS (DnsHeader->AuthorityNum);
  DnsHeader->AditionalNum = NTOHS (DnsHeader->AditionalNum);

  //
  // There is always one QuestionsNum in DNS message. The capability to handle more
  // than one requires to redesign the message format. Currently, it's not supported.
  //
  if (DnsHeader->QuestionsNum > 1) {
    *Completed = FALSE;
    return EFI_UNSUPPORTED;
  }

  //
  // Get Query name
  //
  QueryName = (CHAR8 *) (RxString + sizeof (*DnsHeader));

  QueryNameLen = (UINT32) AsciiStrLen (QueryName) + 1;

  //
  // Check whether the remaining packet length is available or not.
  //
  if (RemainingLength <= QueryNameLen + sizeof (DNS_QUERY_SECTION)) {
    *Completed = FALSE;
    return EFI_ABORTED;
  } else {
    RemainingLength -= (QueryNameLen + sizeof (DNS_QUERY_SECTION));
  }

  //
  // Get query section
  //
  QuerySection = (DNS_QUERY_SECTION *) (QueryName + QueryNameLen);
  QuerySection->Type = NTOHS (QuerySection->Type);
  QuerySection->Class = NTOHS (QuerySection->Class);

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Check DnsResponse Validity, if so, also get a valid NET_MAP_ITEM.
  //
  if (Instance->Service->IpVersion == IP_VERSION_4) {
    if (!IsValidDnsResponse (
           &Instance->Dns4TxTokens,
           DnsHeader->Identification,
           QuerySection->Type,
           QuerySection->Class,
           &Item
           )) {
      *Completed = FALSE;
      Status = EFI_ABORTED;
      goto ON_EXIT;
    }
    ASSERT (Item != NULL);
    Dns4TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);
  } else {
    if (!IsValidDnsResponse (
           &Instance->Dns6TxTokens,
           DnsHeader->Identification,
           QuerySection->Type,
           QuerySection->Class,
           &Item
           )) {
      *Completed = FALSE;
      Status = EFI_ABORTED;
      goto ON_EXIT;
    }
    ASSERT (Item != NULL);
    Dns6TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);
  }

  //
  // Continue Check Some Errors.
  //
  if (DnsHeader->Flags.Bits.RCode != DNS_FLAGS_RCODE_NO_ERROR || DnsHeader->AnswersNum < 1 || \
      DnsHeader->Flags.Bits.QR != DNS_FLAGS_QR_RESPONSE) {
    //
    // The domain name referenced in the query does not exist.
    //
    if (DnsHeader->Flags.Bits.RCode == DNS_FLAGS_RCODE_NAME_ERROR) {
      Status = EFI_NOT_FOUND;
    } else {
      Status = EFI_DEVICE_ERROR;
    }

    goto ON_COMPLETE;
  }

  //
  // Do some buffer allocations.
  //
  if (Instance->Service->IpVersion == IP_VERSION_4) {
    ASSERT (Dns4TokenEntry != NULL);

    if (Dns4TokenEntry->GeneralLookUp) {
      //
      // It's the GeneralLookUp querying.
      //
      Dns4TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));
      if (Dns4TokenEntry->Token->RspData.GLookupData == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }
      Dns4TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));
      if (Dns4TokenEntry->Token->RspData.GLookupData->RRList == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }
    } else {
      //
      // It's not the GeneralLookUp querying. Check the Query type.
      //
      if (QuerySection->Type == DNS_TYPE_A) {
        Dns4TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS_HOST_TO_ADDR_DATA));
        if (Dns4TokenEntry->Token->RspData.H2AData == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto ON_EXIT;
        }
        Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));
        if (Dns4TokenEntry->Token->RspData.H2AData->IpList == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto ON_EXIT;
        }
      } else {
        Status = EFI_UNSUPPORTED;
        goto ON_EXIT;
      }
    }
  } else {
    ASSERT (Dns6TokenEntry != NULL);

    if (Dns6TokenEntry->GeneralLookUp) {
      //
      // It's the GeneralLookUp querying.
      //
      Dns6TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));
      if (Dns6TokenEntry->Token->RspData.GLookupData == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }
      Dns6TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));
      if (Dns6TokenEntry->Token->RspData.GLookupData->RRList == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }
    } else {
      //
      // It's not the GeneralLookUp querying. Check the Query type.
      //
      if (QuerySection->Type == DNS_TYPE_AAAA) {
        Dns6TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS6_HOST_TO_ADDR_DATA));
        if (Dns6TokenEntry->Token->RspData.H2AData == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto ON_EXIT;
        }
        Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));
        if (Dns6TokenEntry->Token->RspData.H2AData->IpList == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto ON_EXIT;
        }
      } else {
        Status = EFI_UNSUPPORTED;
        goto ON_EXIT;
      }
    }
  }

  Status = EFI_NOT_FOUND;

  //
  // Get Answer name
  //
  AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection);

  //
  // Processing AnswerSection.
  //
  while (AnswerSectionNum < DnsHeader->AnswersNum) {
    //
    // Check whether the remaining packet length is available or not.
    //
    if (RemainingLength <= sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION)) {
      *Completed = FALSE;
      Status = EFI_ABORTED;
      goto ON_EXIT;
    } else {
      RemainingLength -= (sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION));
    }

    //
    // Answer name should be PTR, else EFI_UNSUPPORTED returned.
    //
    if ((*(UINT8 *) AnswerName & 0xC0) != 0xC0) {
      Status = EFI_UNSUPPORTED;
      goto ON_EXIT;
    }

    //
    // Get Answer section.
    //
    AnswerSection = (DNS_ANSWER_SECTION *) (AnswerName + sizeof (UINT16));
    AnswerSection->Type = NTOHS (AnswerSection->Type);
    AnswerSection->Class = NTOHS (AnswerSection->Class);
    AnswerSection->Ttl = NTOHL (AnswerSection->Ttl);
    AnswerSection->DataLength = NTOHS (AnswerSection->DataLength);

    //
    // Check whether the remaining packet length is available or not.
    //
    if (RemainingLength < AnswerSection->DataLength) {
      *Completed = FALSE;
      Status = EFI_ABORTED;
      goto ON_EXIT;
    } else {
      RemainingLength -= AnswerSection->DataLength;
    }

    //
    // Check whether it's the GeneralLookUp querying.
    //
    if (Instance->Service->IpVersion == IP_VERSION_4 && Dns4TokenEntry->GeneralLookUp) {
      Dns4RR = Dns4TokenEntry->Token->RspData.GLookupData->RRList;
      AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);

      //
      // Fill the ResourceRecord.
      //
      Dns4RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);
      if (Dns4RR[RRCount].QName == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }
      CopyMem (Dns4RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));
      Dns4RR[RRCount].QType = AnswerSection->Type;
      Dns4RR[RRCount].QClass = AnswerSection->Class;
      Dns4RR[RRCount].TTL = AnswerSection->Ttl;
      Dns4RR[RRCount].DataLength = AnswerSection->DataLength;
      Dns4RR[RRCount].RData = AllocateZeroPool (Dns4RR[RRCount].DataLength);
      if (Dns4RR[RRCount].RData == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }
      CopyMem (Dns4RR[RRCount].RData, AnswerData, Dns4RR[RRCount].DataLength);

      RRCount ++;
      Status = EFI_SUCCESS;
    } else if (Instance->Service->IpVersion == IP_VERSION_6 && Dns6TokenEntry->GeneralLookUp) {
      Dns6RR = Dns6TokenEntry->Token->RspData.GLookupData->RRList;
      AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);

      //
      // Fill the ResourceRecord.
      //
      Dns6RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);
      if (Dns6RR[RRCount].QName == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }
      CopyMem (Dns6RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));
      Dns6RR[RRCount].QType = AnswerSection->Type;
      Dns6RR[RRCount].QClass = AnswerSection->Class;
      Dns6RR[RRCount].TTL = AnswerSection->Ttl;
      Dns6RR[RRCount].DataLength = AnswerSection->DataLength;
      Dns6RR[RRCount].RData = AllocateZeroPool (Dns6RR[RRCount].DataLength);
      if (Dns6RR[RRCount].RData == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }
      CopyMem (Dns6RR[RRCount].RData, AnswerData, Dns6RR[RRCount].DataLength);

      RRCount ++;
      Status = EFI_SUCCESS;
    } else {
      //
      // It's not the GeneralLookUp querying.
      // Check the Query type, parse the response packet.
      //
      switch (AnswerSection->Type) {
      case DNS_TYPE_A:
        //
        // This is address entry, get Data.
        //
        ASSERT (Dns4TokenEntry != NULL);

        if (AnswerSection->DataLength != 4) {
          Status = EFI_ABORTED;
          goto ON_EXIT;
        }

        HostAddr4 = Dns4TokenEntry->Token->RspData.H2AData->IpList;
        AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
        CopyMem (&HostAddr4[IpCount], AnswerData, sizeof (EFI_IPv4_ADDRESS));

        //
        // Allocate new CacheEntry pool to update DNS cache dynamically.
        //
        Dns4CacheEntry = AllocateZeroPool (sizeof (EFI_DNS4_CACHE_ENTRY));
        if (Dns4CacheEntry == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto ON_EXIT;
        }
        Dns4CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));
        if (Dns4CacheEntry->HostName == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto ON_EXIT;
        }
        CopyMem (Dns4CacheEntry->HostName, Dns4TokenEntry->QueryHostName, 2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));
        Dns4CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS));
        if (Dns4CacheEntry->IpAddress == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto ON_EXIT;
        }
        CopyMem (Dns4CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv4_ADDRESS));

        if (CNameTtl != 0 && AnswerSection->Ttl != 0) {
          Dns4CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);
        } else {
          Dns4CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);
        }

        UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);

        //
        // Free allocated CacheEntry pool.
        //
        FreePool (Dns4CacheEntry->HostName);
        Dns4CacheEntry->HostName = NULL;

        FreePool (Dns4CacheEntry->IpAddress);
        Dns4CacheEntry->IpAddress = NULL;

        FreePool (Dns4CacheEntry);
        Dns4CacheEntry = NULL;

        IpCount ++;
        Status = EFI_SUCCESS;
        break;
      case DNS_TYPE_AAAA:
        //
        // This is address entry, get Data.
        //
        ASSERT (Dns6TokenEntry != NULL);

        if (AnswerSection->DataLength != 16) {
          Status = EFI_ABORTED;
          goto ON_EXIT;
        }

        HostAddr6 = Dns6TokenEntry->Token->RspData.H2AData->IpList;
        AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
        CopyMem (&HostAddr6[IpCount], AnswerData, sizeof (EFI_IPv6_ADDRESS));

        //
        // Allocate new CacheEntry pool to update DNS cache dynamically.
        //
        Dns6CacheEntry = AllocateZeroPool (sizeof (EFI_DNS6_CACHE_ENTRY));
        if (Dns6CacheEntry == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto ON_EXIT;
        }
        Dns6CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));
        if (Dns6CacheEntry->HostName == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto ON_EXIT;
        }
        CopyMem (Dns6CacheEntry->HostName, Dns6TokenEntry->QueryHostName, 2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));
        Dns6CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));
        if (Dns6CacheEntry->IpAddress == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto ON_EXIT;
        }
        CopyMem (Dns6CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv6_ADDRESS));

        if (CNameTtl != 0 && AnswerSection->Ttl != 0) {
          Dns6CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);
        } else {
          Dns6CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);
        }

        UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);

        //
        // Free allocated CacheEntry pool.
        //
        FreePool (Dns6CacheEntry->HostName);
        Dns6CacheEntry->HostName = NULL;

        FreePool (Dns6CacheEntry->IpAddress);
        Dns6CacheEntry->IpAddress = NULL;

        FreePool (Dns6CacheEntry);
        Dns6CacheEntry = NULL;

        IpCount ++;
        Status = EFI_SUCCESS;
        break;
      case DNS_TYPE_CNAME:
        //
        // According RFC 1034 - 3.6.2, if the query name is an alias, the name server will include the CNAME
        // record in the response and restart the query at the domain name specified in the data field of the
        // CNAME record. So, just record the TTL value of the CNAME, then skip to parse the next record.
        //
        CNameTtl = AnswerSection->Ttl;
        break;
      default:
        Status = EFI_UNSUPPORTED;
        goto ON_EXIT;
      }
    }

    //
    // Find next one
    //
    AnswerName = (CHAR8 *) AnswerSection + sizeof (*AnswerSection) + AnswerSection->DataLength;
    AnswerSectionNum ++;
  }

  if (Instance->Service->IpVersion == IP_VERSION_4) {
    ASSERT (Dns4TokenEntry != NULL);

    if (Dns4TokenEntry->GeneralLookUp) {
      Dns4TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;
    } else {
      if (QuerySection->Type == DNS_TYPE_A) {
        Dns4TokenEntry->Token->RspData.H2AData->IpCount = IpCount;
      } else {
        Status = EFI_UNSUPPORTED;
        goto ON_EXIT;
      }
    }
  } else {
    ASSERT (Dns6TokenEntry != NULL);

    if (Dns6TokenEntry->GeneralLookUp) {
      Dns6TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;
    } else {
      if (QuerySection->Type == DNS_TYPE_AAAA) {
        Dns6TokenEntry->Token->RspData.H2AData->IpCount = IpCount;
      } else {
        Status = EFI_UNSUPPORTED;
        goto ON_EXIT;
      }
    }
  }

ON_COMPLETE:
  //
  // Parsing is complete, free the sending packet and signal Event here.
  //
  if (Item != NULL && Item->Value != NULL) {
    NetbufFree ((NET_BUF *) (Item->Value));
  }

  if (Instance->Service->IpVersion == IP_VERSION_4) {
    ASSERT (Dns4TokenEntry != NULL);
    Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);
    Dns4TokenEntry->Token->Status = Status;
    if (Dns4TokenEntry->Token->Event != NULL) {
      gBS->SignalEvent (Dns4TokenEntry->Token->Event);
      DispatchDpc ();
    }
  } else {
    ASSERT (Dns6TokenEntry != NULL);
    Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);
    Dns6TokenEntry->Token->Status = Status;
    if (Dns6TokenEntry->Token->Event != NULL) {
      gBS->SignalEvent (Dns6TokenEntry->Token->Event);
      DispatchDpc ();
    }
  }

ON_EXIT:
  //
  // Free the allocated buffer if error happen.
  //
  if (EFI_ERROR (Status)) {
    if (Dns4TokenEntry != NULL) {
      if (Dns4TokenEntry->GeneralLookUp) {
        if (Dns4TokenEntry->Token->RspData.GLookupData != NULL) {
          if (Dns4TokenEntry->Token->RspData.GLookupData->RRList != NULL) {
            while (RRCount != 0) {
              RRCount --;
              if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {
                FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);
              }

              if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {
                FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);
              }
            }

            FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList);
          }

          FreePool (Dns4TokenEntry->Token->RspData.GLookupData);
        }
      } else {
        if (QuerySection->Type == DNS_TYPE_A && Dns4TokenEntry->Token->RspData.H2AData != NULL) {
          if (Dns4TokenEntry->Token->RspData.H2AData->IpList != NULL) {
            FreePool (Dns4TokenEntry->Token->RspData.H2AData->IpList);
          }

          FreePool (Dns4TokenEntry->Token->RspData.H2AData);
          Dns4TokenEntry->Token->RspData.H2AData = NULL;
        }
      }
    }

    if (Dns6TokenEntry != NULL) {
      if (Dns6TokenEntry->GeneralLookUp) {
        if (Dns6TokenEntry->Token->RspData.GLookupData != NULL) {
          if (Dns6TokenEntry->Token->RspData.GLookupData->RRList != NULL) {
            while (RRCount != 0) {
              RRCount --;
              if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {
                FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);
              }

              if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {
                FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);
              }
            }

            FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList);
          }

          FreePool (Dns6TokenEntry->Token->RspData.GLookupData);
        }
      } else {
        if (QuerySection->Type == DNS_TYPE_AAAA && Dns6TokenEntry->Token->RspData.H2AData != NULL) {
          if (Dns6TokenEntry->Token->RspData.H2AData->IpList != NULL) {
            FreePool (Dns6TokenEntry->Token->RspData.H2AData->IpList);
          }

          FreePool (Dns6TokenEntry->Token->RspData.H2AData);
          Dns6TokenEntry->Token->RspData.H2AData = NULL;
        }
      }
    }

    if (Dns4CacheEntry != NULL) {
      if (Dns4CacheEntry->HostName != NULL) {
        FreePool (Dns4CacheEntry->HostName);
      }

      if (Dns4CacheEntry->IpAddress != NULL) {
        FreePool (Dns4CacheEntry->IpAddress);
      }

      FreePool (Dns4CacheEntry);
    }

    if (Dns6CacheEntry != NULL) {
      if (Dns6CacheEntry->HostName != NULL) {
        FreePool (Dns6CacheEntry->HostName);
      }

      if (Dns6CacheEntry->IpAddress != NULL) {
        FreePool (Dns6CacheEntry->IpAddress);
      }

      FreePool (Dns6CacheEntry);
    }
  }

  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Parse response packet.

  @param  Packet                The packets received.
  @param  EndPoint              The local/remote UDP access point
  @param  IoStatus              The status of the UDP receive
  @param  Context               The opaque parameter to the function.

**/
VOID
EFIAPI
DnsOnPacketReceived (
  NET_BUF                   *Packet,
  UDP_END_POINT             *EndPoint,
  EFI_STATUS                IoStatus,
  VOID                      *Context
  )
{
  DNS_INSTANCE              *Instance;

  UINT8                     *RcvString;
  UINT32                    Len;

  BOOLEAN                   Completed;

  Instance  = (DNS_INSTANCE *) Context;
  NET_CHECK_SIGNATURE (Instance, DNS_INSTANCE_SIGNATURE);

  RcvString = NULL;
  Completed = FALSE;

  if (EFI_ERROR (IoStatus)) {
    goto ON_EXIT;
  }

  ASSERT (Packet != NULL);

  Len = Packet->TotalSize;

  RcvString = NetbufGetByte (Packet, 0, NULL);
  ASSERT (RcvString != NULL);

  //
  // Parse Dns Response
  //
  ParseDnsResponse (Instance, RcvString, Len, &Completed);

ON_EXIT:

  if (Packet != NULL) {
    NetbufFree (Packet);
  }

  if (!Completed) {
    UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);
  }
}

/**
  Release the net buffer when packet is sent.

  @param  Packet                The packets received.
  @param  EndPoint              The local/remote UDP access point
  @param  IoStatus              The status of the UDP receive
  @param  Context               The opaque parameter to the function.

**/
VOID
EFIAPI
DnsOnPacketSent (
  NET_BUF                   *Packet,
  UDP_END_POINT             *EndPoint,
  EFI_STATUS                IoStatus,
  VOID                      *Context
  )
{
  DNS_INSTANCE              *Instance;
  LIST_ENTRY                *Entry;
  NET_MAP_ITEM              *Item;
  DNS4_TOKEN_ENTRY          *Dns4TokenEntry;
  DNS6_TOKEN_ENTRY          *Dns6TokenEntry;

  Dns4TokenEntry = NULL;
  Dns6TokenEntry = NULL;

  Instance  = (DNS_INSTANCE *) Context;
  NET_CHECK_SIGNATURE (Instance, DNS_INSTANCE_SIGNATURE);

  if (Instance->Service->IpVersion == IP_VERSION_4) {
    NET_LIST_FOR_EACH (Entry, &Instance->Dns4TxTokens.Used) {
      Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
      if (Packet == (NET_BUF *)(Item->Value)) {
        Dns4TokenEntry = ((DNS4_TOKEN_ENTRY *)Item->Key);
        Dns4TokenEntry->PacketToLive = Dns4TokenEntry->Token->RetryInterval;
        break;
      }
    }
  } else {
    NET_LIST_FOR_EACH (Entry, &Instance->Dns6TxTokens.Used) {
      Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
      if (Packet == (NET_BUF *)(Item->Value)) {
        Dns6TokenEntry = ((DNS6_TOKEN_ENTRY *)Item->Key);
        Dns6TokenEntry->PacketToLive = Dns6TokenEntry->Token->RetryInterval;
        break;
      }
    }
  }

  NetbufFree (Packet);
}

/**
  Query request information.

  @param  Instance              The DNS instance
  @param  Packet                The packet for querying request information.

  @retval EFI_SUCCESS           Query request information successfully.
  @retval Others                Failed to query request information.

**/
EFI_STATUS
DoDnsQuery (
  IN  DNS_INSTANCE              *Instance,
  IN  NET_BUF                   *Packet
  )
{
  EFI_STATUS      Status;

  //
  // Ready to receive the DNS response.
  //
  if (Instance->UdpIo->RecvRequest == NULL) {
    Status = UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Transmit the DNS packet.
  //
  NET_GET_REF (Packet);

  Status = UdpIoSendDatagram (Instance->UdpIo, Packet, NULL, NULL, DnsOnPacketSent, Instance);

  return Status;
}

/**
  Construct the Packet according query section.

  @param  Instance              The DNS instance
  @param  QueryName             Queried Name
  @param  Type                  Queried Type
  @param  Class                 Queried Class
  @param  Packet                The packet for query

  @retval EFI_SUCCESS           The packet is constructed.
  @retval Others                Failed to construct the Packet.

**/
EFI_STATUS
ConstructDNSQuery (
  IN  DNS_INSTANCE              *Instance,
  IN  CHAR8                     *QueryName,
  IN  UINT16                    Type,
  IN  UINT16                    Class,
  OUT NET_BUF                   **Packet
  )
{
  NET_FRAGMENT        Frag;
  DNS_HEADER          *DnsHeader;
  DNS_QUERY_SECTION   *DnsQuery;

  //
  // Messages carried by UDP are restricted to 512 bytes (not counting the IP
  // or UDP headers).
  //
  Frag.Bulk = AllocatePool (DNS_MAX_MESSAGE_SIZE * sizeof (UINT8));
  if (Frag.Bulk == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Fill header
  //
  DnsHeader = (DNS_HEADER *) Frag.Bulk;
  DnsHeader->Identification = (UINT16)NET_RANDOM (NetRandomInitSeed());
  DnsHeader->Flags.Uint16 = 0x0000;
  DnsHeader->Flags.Bits.RD = 1;
  DnsHeader->Flags.Bits.OpCode = DNS_FLAGS_OPCODE_STANDARD;
  DnsHeader->Flags.Bits.QR = DNS_FLAGS_QR_QUERY;
  DnsHeader->QuestionsNum = 1;
  DnsHeader->AnswersNum = 0;
  DnsHeader->AuthorityNum = 0;
  DnsHeader->AditionalNum = 0;

  DnsHeader->Identification = HTONS (DnsHeader->Identification);
  DnsHeader->Flags.Uint16 = HTONS (DnsHeader->Flags.Uint16);
  DnsHeader->QuestionsNum = HTONS (DnsHeader->QuestionsNum);
  DnsHeader->AnswersNum = HTONS (DnsHeader->AnswersNum);
  DnsHeader->AuthorityNum = HTONS (DnsHeader->AuthorityNum);
  DnsHeader->AditionalNum = HTONS (DnsHeader->AditionalNum);

  Frag.Len = sizeof (*DnsHeader);

  //
  // Fill Query name
  //
  CopyMem (Frag.Bulk + Frag.Len, QueryName, AsciiStrLen (QueryName));
  Frag.Len = (UINT32) (Frag.Len + AsciiStrLen (QueryName));
  *(Frag.Bulk + Frag.Len) = 0;
  Frag.Len ++;

  //
  // Rest query section
  //
  DnsQuery = (DNS_QUERY_SECTION *) (Frag.Bulk + Frag.Len);

  DnsQuery->Type = HTONS (Type);
  DnsQuery->Class = HTONS (Class);

  Frag.Len += sizeof (*DnsQuery);

  //
  // Wrap the Frag in a net buffer.
  //
  *Packet = NetbufFromExt (&Frag, 1, 0, 0, DnsDummyExtFree, NULL);
  if (*Packet == NULL) {
    FreePool (Frag.Bulk);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Store the UdpIo in ProtoData.
  //
  *((UINTN *) &((*Packet)->ProtoData[0])) = (UINTN) (Instance->UdpIo);

  return EFI_SUCCESS;
}

/**
  Retransmit the packet.

  @param  Instance              The DNS instance
  @param  Packet                Retransmit the packet

  @retval EFI_SUCCESS           The packet is retransmitted.
  @retval Others                Failed to retransmit.

**/
EFI_STATUS
DnsRetransmit (
  IN DNS_INSTANCE        *Instance,
  IN NET_BUF             *Packet
  )
{
  EFI_STATUS      Status;

  UINT8           *Buffer;

  ASSERT (Packet != NULL);

  //
  // Set the requests to the listening port, other packets to the connected port
  //
  Buffer = NetbufGetByte (Packet, 0, NULL);
  ASSERT (Buffer != NULL);

  NET_GET_REF (Packet);

  Status = UdpIoSendDatagram (
             Instance->UdpIo,
             Packet,
             NULL,
             NULL,
             DnsOnPacketSent,
             Instance
             );

  if (EFI_ERROR (Status)) {
    NET_PUT_REF (Packet);
  }

  return Status;
}

/**
  The timer ticking function for the DNS services.

  @param  Event                 The ticking event
  @param  Context               The DNS service instance

**/
VOID
EFIAPI
DnsOnTimerRetransmit (
  IN EFI_EVENT              Event,
  IN VOID                   *Context
  )
{
  DNS_SERVICE                *Service;

  LIST_ENTRY                 *Entry;
  LIST_ENTRY                 *Next;

  DNS_INSTANCE               *Instance;
  LIST_ENTRY                 *EntryNetMap;
  NET_MAP_ITEM               *ItemNetMap;
  DNS4_TOKEN_ENTRY           *Dns4TokenEntry;
  DNS6_TOKEN_ENTRY           *Dns6TokenEntry;

  Dns4TokenEntry = NULL;
  Dns6TokenEntry = NULL;

  Service = (DNS_SERVICE *) Context;


  if (Service->IpVersion == IP_VERSION_4) {
    //
    // Iterate through all the children of the DNS service instance. Time
    // out the packet. If maximum retries reached, clean the Token up.
    //
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Dns4ChildrenList) {
      Instance = NET_LIST_USER_STRUCT (Entry, DNS_INSTANCE, Link);

      EntryNetMap = Instance->Dns4TxTokens.Used.ForwardLink;
      while (EntryNetMap != &Instance->Dns4TxTokens.Used) {
        ItemNetMap = NET_LIST_USER_STRUCT (EntryNetMap, NET_MAP_ITEM, Link);
        Dns4TokenEntry = (DNS4_TOKEN_ENTRY *)(ItemNetMap->Key);
        if (Dns4TokenEntry->PacketToLive == 0 || (--Dns4TokenEntry->PacketToLive > 0)) {
          EntryNetMap = EntryNetMap->ForwardLink;
          continue;
        }

        //
        // Retransmit the packet if haven't reach the maximum retry count,
        // otherwise exit the transfer.
        //
        if (++Dns4TokenEntry->RetryCounting <= Dns4TokenEntry->Token->RetryCount) {
          DnsRetransmit (Instance, (NET_BUF *)ItemNetMap->Value);
          EntryNetMap = EntryNetMap->ForwardLink;
        } else {
          //
          // Maximum retries reached, clean the Token up.
          //
          Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);
          Dns4TokenEntry->Token->Status = EFI_TIMEOUT;
          gBS->SignalEvent (Dns4TokenEntry->Token->Event);
          DispatchDpc ();

          //
          // Free the sending packet.
          //
          if (ItemNetMap->Value != NULL) {
            NetbufFree ((NET_BUF *)(ItemNetMap->Value));
          }

          EntryNetMap = Instance->Dns4TxTokens.Used.ForwardLink;
        }
      }
    }
  } else {
    //
    // Iterate through all the children of the DNS service instance. Time
    // out the packet. If maximum retries reached, clean the Token up.
    //
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Dns6ChildrenList) {
      Instance = NET_LIST_USER_STRUCT (Entry, DNS_INSTANCE, Link);

      EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;
      while (EntryNetMap != &Instance->Dns6TxTokens.Used) {
        ItemNetMap = NET_LIST_USER_STRUCT (EntryNetMap, NET_MAP_ITEM, Link);
        Dns6TokenEntry = (DNS6_TOKEN_ENTRY *) (ItemNetMap->Key);
        if (Dns6TokenEntry->PacketToLive == 0 || (--Dns6TokenEntry->PacketToLive > 0)) {
          EntryNetMap = EntryNetMap->ForwardLink;
          continue;
        }

        //
        // Retransmit the packet if haven't reach the maximum retry count,
        // otherwise exit the transfer.
        //
        if (++Dns6TokenEntry->RetryCounting <= Dns6TokenEntry->Token->RetryCount) {
          DnsRetransmit (Instance, (NET_BUF *) ItemNetMap->Value);
          EntryNetMap = EntryNetMap->ForwardLink;
        } else {
          //
          // Maximum retries reached, clean the Token up.
          //
          Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);
          Dns6TokenEntry->Token->Status = EFI_TIMEOUT;
          gBS->SignalEvent (Dns6TokenEntry->Token->Event);
          DispatchDpc ();

          //
          // Free the sending packet.
          //
          if (ItemNetMap->Value != NULL) {
            NetbufFree ((NET_BUF *) (ItemNetMap->Value));
          }

          EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;
        }
      }
    }
  }
}

/**
  The timer ticking function for the DNS driver.

  @param  Event                 The ticking event
  @param  Context               NULL

**/
VOID
EFIAPI
DnsOnTimerUpdate (
  IN EFI_EVENT              Event,
  IN VOID                   *Context
  )
{
  LIST_ENTRY                 *Entry;
  LIST_ENTRY                 *Next;
  DNS4_CACHE                 *Item4;
  DNS6_CACHE                 *Item6;

  Item4 = NULL;
  Item6 = NULL;

  //
  // Iterate through all the DNS4 cache list.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {
    Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
    Item4->DnsCache.Timeout--;
  }

  Entry = mDriverData->Dns4CacheList.ForwardLink;
  while (Entry != &mDriverData->Dns4CacheList) {
    Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
    if (Item4->DnsCache.Timeout == 0) {
      RemoveEntryList (&Item4->AllCacheLink);
      FreePool (Item4->DnsCache.HostName);
      FreePool (Item4->DnsCache.IpAddress);
      FreePool (Item4);
      Entry = mDriverData->Dns4CacheList.ForwardLink;
    } else {
      Entry = Entry->ForwardLink;
    }
  }

  //
  // Iterate through all the DNS6 cache list.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {
    Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
    Item6->DnsCache.Timeout--;
  }

  Entry = mDriverData->Dns6CacheList.ForwardLink;
  while (Entry != &mDriverData->Dns6CacheList) {
    Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
    if (Item6->DnsCache.Timeout == 0) {
      RemoveEntryList (&Item6->AllCacheLink);
      FreePool (Item6->DnsCache.HostName);
      FreePool (Item6->DnsCache.IpAddress);
      FreePool (Item6);
      Entry = mDriverData->Dns6CacheList.ForwardLink;
    } else {
      Entry = Entry->ForwardLink;
    }
  }
}

