/** @file
DnsDxe support functions implementation.
  
Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#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 sucessfully.
  @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 sucessfully.
  @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 cancle 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 cancle 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 sucessfully.
  @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 sucessfully.
  @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 occured.

**/
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 occured.

**/
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  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,
     OUT BOOLEAN                   *Completed
  )
{
  DNS_HEADER            *DnsHeader;
  
  CHAR8                 *QueryName;
  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;

  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;
  
  //
  // 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);

  //
  // Get Query name
  //
  QueryName = (CHAR8 *) (RxString + sizeof (*DnsHeader));

  //
  // Get query section
  //
  QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);
  QuerySection->Type = NTOHS (QuerySection->Type);
  QuerySection->Class = NTOHS (QuerySection->Class);

  //
  // Get Answer name
  //
  AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection);

  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;

  //
  // Processing AnswerSection.
  //
  while (AnswerSectionNum < DnsHeader->AnswersNum) {
    //
    // 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 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);
        }
      }
    }

    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);
        }
      }
    }

    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;

  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);

  if (Packet->TotalSize <= sizeof (DNS_HEADER)) {
    goto ON_EXIT;
  }
  
  RcvString = NetbufGetByte (Packet, 0, NULL);
  ASSERT (RcvString != NULL);
  
  //
  // Parse Dns Response
  //
  ParseDnsResponse (Instance, RcvString, &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 maxmium 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 maxmium 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;
    }
  }
}

