]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/DnsDxe/DnsImpl.c
NetworkPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / NetworkPkg / DnsDxe / DnsImpl.c
index cfaa4c78a936cb9aac9e4cfea577c9be7d266e39..ca4ef506a08a88085a7a232de4e7d973e3d73c6b 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
 DnsDxe support functions implementation.\r
-  \r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
 \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -45,7 +39,7 @@ Dns4RemoveTokenEntry (
 \r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -57,7 +51,7 @@ Dns4RemoveTokenEntry (
 \r
   @retval EFI_SUCCESS           Remove TokenEntry from TokenMap sucessfully.\r
   @retval EFI_NOT_FOUND         TokenEntry is not found in TokenMap.\r
-  \r
+\r
 **/\r
 EFI_STATUS\r
 Dns6RemoveTokenEntry (\r
@@ -80,7 +74,7 @@ Dns6RemoveTokenEntry (
 \r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -219,24 +213,24 @@ EFI_STATUS
 EFIAPI\r
 GetDns4TokenEntry (\r
   IN     NET_MAP                   *TokensMap,\r
-  IN     EFI_DNS4_COMPLETION_TOKEN *Token, \r
+  IN     EFI_DNS4_COMPLETION_TOKEN *Token,\r
      OUT DNS4_TOKEN_ENTRY          **TokenEntry\r
   )\r
 {\r
   LIST_ENTRY              *Entry;\r
-  \r
+\r
   NET_MAP_ITEM            *Item;\r
-  \r
+\r
   NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {\r
     Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
-    *TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);  \r
+    *TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);\r
     if ((*TokenEntry)->Token == Token) {\r
       return EFI_SUCCESS;\r
     }\r
   }\r
-  \r
+\r
   *TokenEntry = NULL;\r
-  \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -255,24 +249,24 @@ EFI_STATUS
 EFIAPI\r
 GetDns6TokenEntry (\r
   IN     NET_MAP                   *TokensMap,\r
-  IN     EFI_DNS6_COMPLETION_TOKEN *Token, \r
+  IN     EFI_DNS6_COMPLETION_TOKEN *Token,\r
      OUT DNS6_TOKEN_ENTRY          **TokenEntry\r
   )\r
 {\r
   LIST_ENTRY              *Entry;\r
-  \r
+\r
   NET_MAP_ITEM            *Item;\r
-  \r
+\r
   NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {\r
     Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
-    *TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);  \r
+    *TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);\r
     if ((*TokenEntry)->Token == Token) {\r
       return EFI_SUCCESS;\r
     }\r
   }\r
-  \r
+\r
   *TokenEntry =NULL;\r
-  \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -325,7 +319,7 @@ Dns4InstanceCancelToken (
   }\r
 \r
   ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns4TxTokens)));\r
-  \r
+\r
   if (NetMapIsEmpty (&Instance->Dns4TxTokens)) {\r
     Instance->UdpIo->Protocol.Udp4->Cancel (Instance->UdpIo->Protocol.Udp4, &Instance->UdpIo->RecvRequest->Token.Udp4);\r
   }\r
@@ -382,7 +376,7 @@ Dns6InstanceCancelToken (
   }\r
 \r
   ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns6TxTokens)));\r
-  \r
+\r
   if (NetMapIsEmpty (&Instance->Dns6TxTokens)) {\r
     Instance->UdpIo->Protocol.Udp6->Cancel (Instance->UdpIo->Protocol.Udp6, &Instance->UdpIo->RecvRequest->Token.Udp6);\r
   }\r
@@ -526,9 +520,9 @@ DnsDummyExtFree (
 \r
 /**\r
   Poll the UDP to get the IP4 default address, which may be retrieved\r
-  by DHCP. \r
-  \r
-  The default time out value is 5 seconds. If IP has retrieved the default address, \r
+  by DHCP.\r
+\r
+  The default time out value is 5 seconds. If IP has retrieved the default address,\r
   the UDP is reconfigured.\r
 \r
   @param  Instance               The DNS instance\r
@@ -565,7 +559,7 @@ Dns4GetMapping (
     return FALSE;\r
   }\r
 \r
-  while (!EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
+  while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
     Udp->Poll (Udp);\r
 \r
     if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip4Mode, NULL, NULL)) &&\r
@@ -615,7 +609,7 @@ Dns6GetMapping (
     return FALSE;\r
   }\r
 \r
-  while (!EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
+  while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
     Udp->Poll (Udp);\r
 \r
     if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip6Mode, NULL, NULL))) {\r
@@ -643,9 +637,11 @@ Dns6GetMapping (
         FreePool (Ip6Mode.IcmpTypeList);\r
       }\r
 \r
-      if (Ip6Mode.IsConfigured) {\r
+      if (!Ip6Mode.IsStarted || Ip6Mode.IsConfigured) {\r
         Udp->Configure (Udp, NULL);\r
-        return (BOOLEAN) (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);\r
+        if (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS) {\r
+          return TRUE;\r
+        }\r
       }\r
     }\r
   }\r
@@ -655,10 +651,10 @@ Dns6GetMapping (
 \r
 /**\r
   Configure the UDP.\r
-  \r
+\r
   @param  Instance               The DNS session\r
   @param  UdpIo                  The UDP_IO instance\r
-  \r
+\r
   @retval EFI_SUCCESS            The UDP is successfully configured for the\r
                                  session.\r
 \r
@@ -697,13 +693,13 @@ Dns4ConfigUdp (
   if ((Status == EFI_NO_MAPPING) && Dns4GetMapping (Instance, UdpIo, &UdpConfig)) {\r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   return Status;\r
 }\r
 \r
 /**\r
   Configure the UDP.\r
-  \r
+\r
   @param  Instance               The DNS session\r
   @param  UdpIo                  The UDP_IO instance\r
 \r
@@ -740,24 +736,24 @@ Dns6ConfigUdp (
   if ((Status == EFI_NO_MAPPING) && Dns6GetMapping (Instance, UdpIo, &UdpConfig)) {\r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   return Status;\r
 }\r
 \r
 /**\r
   Update Dns4 cache to shared list of caches of all DNSv4 instances.\r
-  \r
+\r
   @param  Dns4CacheList      All Dns4 cache list.\r
-  @param  DeleteFlag         If FALSE, this function is to add one entry to the DNS Cache. \r
-                             If TRUE, this function will delete matching DNS Cache entry. \r
-  @param  Override           If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter. \r
+  @param  DeleteFlag         If FALSE, this function is to add one entry to the DNS Cache.\r
+                             If TRUE, this function will delete matching DNS Cache entry.\r
+  @param  Override           If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.\r
                              If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.\r
   @param  DnsCacheEntry      Entry Pointer to DNS Cache entry.\r
 \r
   @retval EFI_SUCCESS        Update Dns4 cache successfully.\r
-  @retval Others             Failed to update Dns4 cache.   \r
-  \r
-**/ \r
+  @retval Others             Failed to update Dns4 cache.\r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 UpdateDns4Cache (\r
@@ -767,14 +763,14 @@ UpdateDns4Cache (
   IN EFI_DNS4_CACHE_ENTRY   DnsCacheEntry\r
   )\r
 {\r
-  DNS4_CACHE    *NewDnsCache;  \r
+  DNS4_CACHE    *NewDnsCache;\r
   DNS4_CACHE    *Item;\r
   LIST_ENTRY    *Entry;\r
   LIST_ENTRY    *Next;\r
 \r
   NewDnsCache = NULL;\r
   Item        = NULL;\r
-  \r
+\r
   //\r
   // Search the database for the matching EFI_DNS_CACHE_ENTRY\r
   //\r
@@ -790,14 +786,18 @@ UpdateDns4Cache (
         // Delete matching DNS Cache entry\r
         //\r
         RemoveEntryList (&Item->AllCacheLink);\r
-        \r
+\r
+        FreePool (Item->DnsCache.HostName);\r
+        FreePool (Item->DnsCache.IpAddress);\r
+        FreePool (Item);\r
+\r
         return EFI_SUCCESS;\r
       } else if (Override) {\r
         //\r
         // Update this one\r
         //\r
         Item->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
-        \r
+\r
         return EFI_SUCCESS;\r
       }else {\r
         return EFI_ACCESS_DENIED;\r
@@ -809,46 +809,49 @@ UpdateDns4Cache (
   // Add new one\r
   //\r
   NewDnsCache = AllocatePool (sizeof (DNS4_CACHE));\r
-  if (NewDnsCache == NULL) { \r
+  if (NewDnsCache == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   InitializeListHead (&NewDnsCache->AllCacheLink);\r
-   \r
+\r
   NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));\r
-  if (NewDnsCache->DnsCache.HostName == NULL) { \r
+  if (NewDnsCache->DnsCache.HostName == NULL) {\r
+    FreePool (NewDnsCache);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));\r
 \r
   NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv4_ADDRESS));\r
-  if (NewDnsCache->DnsCache.IpAddress == NULL) { \r
+  if (NewDnsCache->DnsCache.IpAddress == NULL) {\r
+    FreePool (NewDnsCache->DnsCache.HostName);\r
+    FreePool (NewDnsCache);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv4_ADDRESS));\r
 \r
   NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
-  \r
+\r
   InsertTailList (Dns4CacheList, &NewDnsCache->AllCacheLink);\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Update Dns6 cache to shared list of caches of all DNSv6 instances. \r
+  Update Dns6 cache to shared list of caches of all DNSv6 instances.\r
 \r
   @param  Dns6CacheList      All Dns6 cache list.\r
-  @param  DeleteFlag         If FALSE, this function is to add one entry to the DNS Cache. \r
-                             If TRUE, this function will delete matching DNS Cache entry. \r
-  @param  Override           If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter. \r
+  @param  DeleteFlag         If FALSE, this function is to add one entry to the DNS Cache.\r
+                             If TRUE, this function will delete matching DNS Cache entry.\r
+  @param  Override           If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.\r
                              If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.\r
   @param  DnsCacheEntry      Entry Pointer to DNS Cache entry.\r
-  \r
+\r
   @retval EFI_SUCCESS        Update Dns6 cache successfully.\r
   @retval Others             Failed to update Dns6 cache.\r
-**/ \r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 UpdateDns6Cache (\r
@@ -858,14 +861,14 @@ UpdateDns6Cache (
   IN EFI_DNS6_CACHE_ENTRY   DnsCacheEntry\r
   )\r
 {\r
-  DNS6_CACHE    *NewDnsCache;  \r
+  DNS6_CACHE    *NewDnsCache;\r
   DNS6_CACHE    *Item;\r
   LIST_ENTRY    *Entry;\r
   LIST_ENTRY    *Next;\r
 \r
   NewDnsCache = NULL;\r
   Item        = NULL;\r
-  \r
+\r
   //\r
   // Search the database for the matching EFI_DNS_CACHE_ENTRY\r
   //\r
@@ -881,14 +884,18 @@ UpdateDns6Cache (
         // Delete matching DNS Cache entry\r
         //\r
         RemoveEntryList (&Item->AllCacheLink);\r
-        \r
+\r
+        FreePool (Item->DnsCache.HostName);\r
+        FreePool (Item->DnsCache.IpAddress);\r
+        FreePool (Item);\r
+\r
         return EFI_SUCCESS;\r
       } else if (Override) {\r
         //\r
         // Update this one\r
         //\r
         Item->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
-        \r
+\r
         return EFI_SUCCESS;\r
       }else {\r
         return EFI_ACCESS_DENIED;\r
@@ -900,43 +907,46 @@ UpdateDns6Cache (
   // Add new one\r
   //\r
   NewDnsCache = AllocatePool (sizeof (DNS6_CACHE));\r
-  if (NewDnsCache == NULL) { \r
+  if (NewDnsCache == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   InitializeListHead (&NewDnsCache->AllCacheLink);\r
-   \r
+\r
   NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));\r
-  if (NewDnsCache->DnsCache.HostName == NULL) { \r
+  if (NewDnsCache->DnsCache.HostName == NULL) {\r
+    FreePool (NewDnsCache);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));\r
 \r
   NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv6_ADDRESS));\r
-  if (NewDnsCache->DnsCache.IpAddress == NULL) { \r
+  if (NewDnsCache->DnsCache.IpAddress == NULL) {\r
+    FreePool (NewDnsCache->DnsCache.HostName);\r
+    FreePool (NewDnsCache);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv6_ADDRESS));\r
 \r
   NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
-  \r
+\r
   InsertTailList (Dns6CacheList, &NewDnsCache->AllCacheLink);\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Add Dns4 ServerIp to common list of addresses of all configured DNSv4 server. \r
+  Add Dns4 ServerIp to common list of addresses of all configured DNSv4 server.\r
 \r
-  @param  Dns4ServerList    Common list of addresses of all configured DNSv4 server.  \r
-  @param  ServerIp          DNS server Ip.  \r
+  @param  Dns4ServerList    Common list of addresses of all configured DNSv4 server.\r
+  @param  ServerIp          DNS server Ip.\r
 \r
   @retval EFI_SUCCESS       Add Dns4 ServerIp to common list successfully.\r
   @retval Others            Failed to add Dns4 ServerIp to common list.\r
-  \r
-**/ \r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 AddDns4ServerIp (\r
@@ -944,14 +954,14 @@ AddDns4ServerIp (
   IN EFI_IPv4_ADDRESS           ServerIp\r
   )\r
 {\r
-  DNS4_SERVER_IP    *NewServerIp;  \r
+  DNS4_SERVER_IP    *NewServerIp;\r
   DNS4_SERVER_IP    *Item;\r
   LIST_ENTRY        *Entry;\r
   LIST_ENTRY        *Next;\r
 \r
   NewServerIp = NULL;\r
   Item        = NULL;\r
-  \r
+\r
   //\r
   // Search the database for the matching ServerIp\r
   //\r
@@ -960,7 +970,7 @@ AddDns4ServerIp (
     if (CompareMem (&Item->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS)) == 0) {\r
       //\r
       // Already done.\r
-      // \r
+      //\r
       return EFI_SUCCESS;\r
     }\r
   }\r
@@ -969,29 +979,29 @@ AddDns4ServerIp (
   // Add new one\r
   //\r
   NewServerIp = AllocatePool (sizeof (DNS4_SERVER_IP));\r
-  if (NewServerIp == NULL) { \r
+  if (NewServerIp == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   InitializeListHead (&NewServerIp->AllServerLink);\r
-   \r
+\r
   CopyMem (&NewServerIp->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS));\r
-  \r
+\r
   InsertTailList (Dns4ServerList, &NewServerIp->AllServerLink);\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Add Dns6 ServerIp to common list of addresses of all configured DNSv6 server. \r
+  Add Dns6 ServerIp to common list of addresses of all configured DNSv6 server.\r
 \r
-  @param  Dns6ServerList    Common list of addresses of all configured DNSv6 server.  \r
-  @param  ServerIp          DNS server Ip.  \r
+  @param  Dns6ServerList    Common list of addresses of all configured DNSv6 server.\r
+  @param  ServerIp          DNS server Ip.\r
 \r
   @retval EFI_SUCCESS       Add Dns6 ServerIp to common list successfully.\r
   @retval Others            Failed to add Dns6 ServerIp to common list.\r
-  \r
-**/ \r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 AddDns6ServerIp (\r
@@ -999,14 +1009,14 @@ AddDns6ServerIp (
   IN EFI_IPv6_ADDRESS           ServerIp\r
   )\r
 {\r
-  DNS6_SERVER_IP    *NewServerIp;  \r
+  DNS6_SERVER_IP    *NewServerIp;\r
   DNS6_SERVER_IP    *Item;\r
   LIST_ENTRY        *Entry;\r
   LIST_ENTRY        *Next;\r
 \r
   NewServerIp = NULL;\r
   Item        = NULL;\r
-  \r
+\r
   //\r
   // Search the database for the matching ServerIp\r
   //\r
@@ -1015,7 +1025,7 @@ AddDns6ServerIp (
     if (CompareMem (&Item->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS)) == 0) {\r
       //\r
       // Already done.\r
-      // \r
+      //\r
       return EFI_SUCCESS;\r
     }\r
   }\r
@@ -1024,32 +1034,32 @@ AddDns6ServerIp (
   // Add new one\r
   //\r
   NewServerIp = AllocatePool (sizeof (DNS6_SERVER_IP));\r
-  if (NewServerIp == NULL) { \r
+  if (NewServerIp == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   InitializeListHead (&NewServerIp->AllServerLink);\r
-   \r
+\r
   CopyMem (&NewServerIp->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS));\r
-  \r
+\r
   InsertTailList (Dns6ServerList, &NewServerIp->AllServerLink);\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
   Find out whether the response is valid or invalid.\r
 \r
-  @param  TokensMap       All DNS transmittal Tokens entry.  \r
-  @param  Identification  Identification for queried packet.  \r
+  @param  TokensMap       All DNS transmittal Tokens entry.\r
+  @param  Identification  Identification for queried packet.\r
   @param  Type            Type for queried packet.\r
   @param  Class           Class for queried packet.\r
   @param  Item            Return corresponding Token entry.\r
 \r
   @retval TRUE            The response is valid.\r
   @retval FALSE           The response is invalid.\r
-  \r
-**/ \r
+\r
+**/\r
 BOOLEAN\r
 IsValidDnsResponse (\r
   IN     NET_MAP      *TokensMap,\r
@@ -1071,7 +1081,7 @@ IsValidDnsResponse (
     *Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
     Packet = (NET_BUF *) ((*Item)->Value);\r
     if (Packet == NULL){\r
-      \r
+\r
       continue;\r
     } else {\r
       TxString = NetbufGetByte (Packet, 0, NULL);\r
@@ -1079,17 +1089,17 @@ IsValidDnsResponse (
       DnsHeader = (DNS_HEADER *) TxString;\r
       QueryName = (CHAR8 *) (TxString + sizeof (*DnsHeader));\r
       QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);\r
-        \r
+\r
       if (NTOHS (DnsHeader->Identification) == Identification &&\r
-          NTOHS (QuerySection->Type) == Type && \r
+          NTOHS (QuerySection->Type) == Type &&\r
           NTOHS (QuerySection->Class) == Class) {\r
         return TRUE;\r
       }\r
-    } \r
+    }\r
   }\r
-  \r
+\r
   *Item = NULL;\r
-  \r
+\r
   return FALSE;\r
 }\r
 \r
@@ -1098,24 +1108,27 @@ IsValidDnsResponse (
 \r
   @param  Instance              The DNS instance\r
   @param  RxString              Received buffer.\r
-  @param  Completed             Flag to indicate that Dns response is valid. \r
-  \r
+  @param  Length                Received buffer length.\r
+  @param  Completed             Flag to indicate that Dns response is valid.\r
+\r
   @retval EFI_SUCCESS           Parse Dns Response successfully.\r
   @retval Others                Failed to parse Dns Response.\r
-  \r
-**/ \r
+\r
+**/\r
 EFI_STATUS\r
 ParseDnsResponse (\r
   IN OUT DNS_INSTANCE              *Instance,\r
   IN     UINT8                     *RxString,\r
+  IN     UINT32                    Length,\r
      OUT BOOLEAN                   *Completed\r
   )\r
 {\r
   DNS_HEADER            *DnsHeader;\r
-  \r
+\r
   CHAR8                 *QueryName;\r
+  UINT32                QueryNameLen;\r
   DNS_QUERY_SECTION     *QuerySection;\r
-  \r
+\r
   CHAR8                 *AnswerName;\r
   DNS_ANSWER_SECTION    *AnswerSection;\r
   UINT8                 *AnswerData;\r
@@ -1123,12 +1136,12 @@ ParseDnsResponse (
   NET_MAP_ITEM          *Item;\r
   DNS4_TOKEN_ENTRY      *Dns4TokenEntry;\r
   DNS6_TOKEN_ENTRY      *Dns6TokenEntry;\r
-  \r
+\r
   UINT32                IpCount;\r
   UINT32                RRCount;\r
   UINT32                AnswerSectionNum;\r
   UINT32                CNameTtl;\r
-  \r
+\r
   EFI_IPv4_ADDRESS      *HostAddr4;\r
   EFI_IPv6_ADDRESS      *HostAddr6;\r
 \r
@@ -1139,35 +1152,47 @@ ParseDnsResponse (
   DNS6_RESOURCE_RECORD  *Dns6RR;\r
 \r
   EFI_STATUS            Status;\r
+  UINT32                RemainingLength;\r
 \r
   EFI_TPL               OldTpl;\r
-  \r
+\r
   Item             = NULL;\r
   Dns4TokenEntry   = NULL;\r
   Dns6TokenEntry   = NULL;\r
-  \r
+\r
   IpCount          = 0;\r
   RRCount          = 0;\r
   AnswerSectionNum = 0;\r
   CNameTtl         = 0;\r
-  \r
+\r
   HostAddr4        = NULL;\r
   HostAddr6        = NULL;\r
-  \r
+\r
   Dns4CacheEntry   = NULL;\r
   Dns6CacheEntry   = NULL;\r
-  \r
+\r
   Dns4RR           = NULL;\r
   Dns6RR           = NULL;\r
 \r
   *Completed       = TRUE;\r
   Status           = EFI_SUCCESS;\r
-  \r
+  RemainingLength  = Length;\r
+\r
+  //\r
+  // Check whether the remaining packet length is avaiable or not.\r
+  //\r
+  if (RemainingLength <= sizeof (DNS_HEADER)) {\r
+    *Completed = FALSE;\r
+    return EFI_ABORTED;\r
+  } else {\r
+    RemainingLength -= sizeof (DNS_HEADER);\r
+  }\r
+\r
   //\r
   // Get header\r
   //\r
   DnsHeader = (DNS_HEADER *) RxString;\r
-  \r
+\r
   DnsHeader->Identification = NTOHS (DnsHeader->Identification);\r
   DnsHeader->Flags.Uint16 = NTOHS (DnsHeader->Flags.Uint16);\r
   DnsHeader->QuestionsNum = NTOHS (DnsHeader->QuestionsNum);\r
@@ -1175,22 +1200,38 @@ ParseDnsResponse (
   DnsHeader->AuthorityNum = NTOHS (DnsHeader->AuthorityNum);\r
   DnsHeader->AditionalNum = NTOHS (DnsHeader->AditionalNum);\r
 \r
+  //\r
+  // There is always one QuestionsNum in DNS message. The capability to handle more\r
+  // than one requires to redesign the message format. Currently, it's not supported.\r
+  //\r
+  if (DnsHeader->QuestionsNum > 1) {\r
+    *Completed = FALSE;\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
   //\r
   // Get Query name\r
   //\r
   QueryName = (CHAR8 *) (RxString + sizeof (*DnsHeader));\r
 \r
+  QueryNameLen = (UINT32) AsciiStrLen (QueryName) + 1;\r
+\r
   //\r
-  // Get query section\r
+  // Check whether the remaining packet length is avaiable or not.\r
   //\r
-  QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);\r
-  QuerySection->Type = NTOHS (QuerySection->Type);\r
-  QuerySection->Class = NTOHS (QuerySection->Class);\r
+  if (RemainingLength <= QueryNameLen + sizeof (DNS_QUERY_SECTION)) {\r
+    *Completed = FALSE;\r
+    return EFI_ABORTED;\r
+  } else {\r
+    RemainingLength -= (QueryNameLen + sizeof (DNS_QUERY_SECTION));\r
+  }\r
 \r
   //\r
-  // Get Answer name\r
+  // Get query section\r
   //\r
-  AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection);\r
+  QuerySection = (DNS_QUERY_SECTION *) (QueryName + QueryNameLen);\r
+  QuerySection->Type = NTOHS (QuerySection->Type);\r
+  QuerySection->Class = NTOHS (QuerySection->Class);\r
 \r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
@@ -1199,8 +1240,8 @@ ParseDnsResponse (
   //\r
   if (Instance->Service->IpVersion == IP_VERSION_4) {\r
     if (!IsValidDnsResponse (\r
-           &Instance->Dns4TxTokens, \r
-           DnsHeader->Identification, \r
+           &Instance->Dns4TxTokens,\r
+           DnsHeader->Identification,\r
            QuerySection->Type,\r
            QuerySection->Class,\r
            &Item\r
@@ -1213,8 +1254,8 @@ ParseDnsResponse (
     Dns4TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);\r
   } else {\r
     if (!IsValidDnsResponse (\r
-           &Instance->Dns6TxTokens, \r
-           DnsHeader->Identification, \r
+           &Instance->Dns6TxTokens,\r
+           DnsHeader->Identification,\r
            QuerySection->Type,\r
            QuerySection->Class,\r
            &Item\r
@@ -1226,16 +1267,24 @@ ParseDnsResponse (
     ASSERT (Item != NULL);\r
     Dns6TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);\r
   }\r
-   \r
+\r
   //\r
   // Continue Check Some Errors.\r
   //\r
   if (DnsHeader->Flags.Bits.RCode != DNS_FLAGS_RCODE_NO_ERROR || DnsHeader->AnswersNum < 1 || \\r
       DnsHeader->Flags.Bits.QR != DNS_FLAGS_QR_RESPONSE) {\r
-      Status = EFI_ABORTED;\r
-      goto ON_EXIT;\r
+    //\r
+    // The domain name referenced in the query does not exist.\r
+    //\r
+    if (DnsHeader->Flags.Bits.RCode == DNS_FLAGS_RCODE_NAME_ERROR) {\r
+      Status = EFI_NOT_FOUND;\r
+    } else {\r
+      Status = EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    goto ON_COMPLETE;\r
   }\r
-  \r
+\r
   //\r
   // Do some buffer allocations.\r
   //\r
@@ -1246,12 +1295,12 @@ ParseDnsResponse (
       //\r
       // It's the GeneralLookUp querying.\r
       //\r
-      Dns4TokenEntry->Token->RspData.GLookupData = AllocatePool (sizeof (DNS_RESOURCE_RECORD));\r
+      Dns4TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));\r
       if (Dns4TokenEntry->Token->RspData.GLookupData == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto ON_EXIT;\r
       }\r
-      Dns4TokenEntry->Token->RspData.GLookupData->RRList = AllocatePool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));\r
+      Dns4TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));\r
       if (Dns4TokenEntry->Token->RspData.GLookupData->RRList == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto ON_EXIT;\r
@@ -1261,12 +1310,12 @@ ParseDnsResponse (
       // It's not the GeneralLookUp querying. Check the Query type.\r
       //\r
       if (QuerySection->Type == DNS_TYPE_A) {\r
-        Dns4TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof (DNS_HOST_TO_ADDR_DATA));\r
+        Dns4TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS_HOST_TO_ADDR_DATA));\r
         if (Dns4TokenEntry->Token->RspData.H2AData == NULL) {\r
           Status = EFI_OUT_OF_RESOURCES;\r
           goto ON_EXIT;\r
         }\r
-        Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocatePool (DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));\r
+        Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));\r
         if (Dns4TokenEntry->Token->RspData.H2AData->IpList == NULL) {\r
           Status = EFI_OUT_OF_RESOURCES;\r
           goto ON_EXIT;\r
@@ -1283,12 +1332,12 @@ ParseDnsResponse (
       //\r
       // It's the GeneralLookUp querying.\r
       //\r
-      Dns6TokenEntry->Token->RspData.GLookupData = AllocatePool (sizeof (DNS_RESOURCE_RECORD));\r
+      Dns6TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));\r
       if (Dns6TokenEntry->Token->RspData.GLookupData == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto ON_EXIT;\r
       }\r
-      Dns6TokenEntry->Token->RspData.GLookupData->RRList = AllocatePool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));\r
+      Dns6TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));\r
       if (Dns6TokenEntry->Token->RspData.GLookupData->RRList == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto ON_EXIT;\r
@@ -1298,12 +1347,12 @@ ParseDnsResponse (
       // It's not the GeneralLookUp querying. Check the Query type.\r
       //\r
       if (QuerySection->Type == DNS_TYPE_AAAA) {\r
-        Dns6TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
+        Dns6TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
         if (Dns6TokenEntry->Token->RspData.H2AData == NULL) {\r
           Status = EFI_OUT_OF_RESOURCES;\r
           goto ON_EXIT;\r
         }\r
-        Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocatePool (DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));\r
+        Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));\r
         if (Dns6TokenEntry->Token->RspData.H2AData->IpList == NULL) {\r
           Status = EFI_OUT_OF_RESOURCES;\r
           goto ON_EXIT;\r
@@ -1317,15 +1366,34 @@ ParseDnsResponse (
 \r
   Status = EFI_NOT_FOUND;\r
 \r
+  //\r
+  // Get Answer name\r
+  //\r
+  AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection);\r
+\r
   //\r
   // Processing AnswerSection.\r
   //\r
   while (AnswerSectionNum < DnsHeader->AnswersNum) {\r
     //\r
-    // Answer name should be PTR.\r
+    // Check whether the remaining packet length is avaiable or not.\r
+    //\r
+    if (RemainingLength <= sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION)) {\r
+      *Completed = FALSE;\r
+      Status = EFI_ABORTED;\r
+      goto ON_EXIT;\r
+    } else {\r
+      RemainingLength -= (sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION));\r
+    }\r
+\r
+    //\r
+    // Answer name should be PTR, else EFI_UNSUPPORTED returned.\r
     //\r
-    ASSERT ((*(UINT8 *) AnswerName & 0xC0) == 0xC0);\r
-    \r
+    if ((*(UINT8 *) AnswerName & 0xC0) != 0xC0) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto ON_EXIT;\r
+    }\r
+\r
     //\r
     // Get Answer section.\r
     //\r
@@ -1335,6 +1403,17 @@ ParseDnsResponse (
     AnswerSection->Ttl = NTOHL (AnswerSection->Ttl);\r
     AnswerSection->DataLength = NTOHS (AnswerSection->DataLength);\r
 \r
+    //\r
+    // Check whether the remaining packet length is avaiable or not.\r
+    //\r
+    if (RemainingLength < AnswerSection->DataLength) {\r
+      *Completed = FALSE;\r
+      Status = EFI_ABORTED;\r
+      goto ON_EXIT;\r
+    } else {\r
+      RemainingLength -= AnswerSection->DataLength;\r
+    }\r
+\r
     //\r
     // Check whether it's the GeneralLookUp querying.\r
     //\r
@@ -1361,7 +1440,7 @@ ParseDnsResponse (
         goto ON_EXIT;\r
       }\r
       CopyMem (Dns4RR[RRCount].RData, AnswerData, Dns4RR[RRCount].DataLength);\r
-      \r
+\r
       RRCount ++;\r
       Status = EFI_SUCCESS;\r
     } else if (Instance->Service->IpVersion == IP_VERSION_6 && Dns6TokenEntry->GeneralLookUp) {\r
@@ -1387,12 +1466,12 @@ ParseDnsResponse (
         goto ON_EXIT;\r
       }\r
       CopyMem (Dns6RR[RRCount].RData, AnswerData, Dns6RR[RRCount].DataLength);\r
-      \r
+\r
       RRCount ++;\r
       Status = EFI_SUCCESS;\r
     } else {\r
       //\r
-      // It's not the GeneralLookUp querying. \r
+      // It's not the GeneralLookUp querying.\r
       // Check the Query type, parse the response packet.\r
       //\r
       switch (AnswerSection->Type) {\r
@@ -1400,29 +1479,19 @@ ParseDnsResponse (
         //\r
         // This is address entry, get Data.\r
         //\r
-        ASSERT (Dns4TokenEntry != NULL && AnswerSection->DataLength == 4);\r
-        \r
+        ASSERT (Dns4TokenEntry != NULL);\r
+\r
+        if (AnswerSection->DataLength != 4) {\r
+          Status = EFI_ABORTED;\r
+          goto ON_EXIT;\r
+        }\r
+\r
         HostAddr4 = Dns4TokenEntry->Token->RspData.H2AData->IpList;\r
         AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
         CopyMem (&HostAddr4[IpCount], AnswerData, sizeof (EFI_IPv4_ADDRESS));\r
 \r
         //\r
-        // Update DNS cache dynamically.\r
-        //\r
-        if (Dns4CacheEntry != NULL) {\r
-          if (Dns4CacheEntry->HostName != NULL) {\r
-            FreePool (Dns4CacheEntry->HostName);\r
-          }\r
-\r
-          if (Dns4CacheEntry->IpAddress != NULL) {\r
-            FreePool (Dns4CacheEntry->IpAddress);\r
-          }\r
-          \r
-          FreePool (Dns4CacheEntry);\r
-        }\r
-\r
-        // \r
-        // Allocate new CacheEntry pool.\r
+        // Allocate new CacheEntry pool to update DNS cache dynamically.\r
         //\r
         Dns4CacheEntry = AllocateZeroPool (sizeof (EFI_DNS4_CACHE_ENTRY));\r
         if (Dns4CacheEntry == NULL) {\r
@@ -1447,8 +1516,20 @@ ParseDnsResponse (
         } else {\r
           Dns4CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\r
         }\r
-        \r
-        UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);  \r
+\r
+        UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);\r
+\r
+        //\r
+        // Free allocated CacheEntry pool.\r
+        //\r
+        FreePool (Dns4CacheEntry->HostName);\r
+        Dns4CacheEntry->HostName = NULL;\r
+\r
+        FreePool (Dns4CacheEntry->IpAddress);\r
+        Dns4CacheEntry->IpAddress = NULL;\r
+\r
+        FreePool (Dns4CacheEntry);\r
+        Dns4CacheEntry = NULL;\r
 \r
         IpCount ++;\r
         Status = EFI_SUCCESS;\r
@@ -1457,29 +1538,19 @@ ParseDnsResponse (
         //\r
         // This is address entry, get Data.\r
         //\r
-        ASSERT (Dns6TokenEntry != NULL && AnswerSection->DataLength == 16);\r
-        \r
+        ASSERT (Dns6TokenEntry != NULL);\r
+\r
+        if (AnswerSection->DataLength != 16) {\r
+          Status = EFI_ABORTED;\r
+          goto ON_EXIT;\r
+        }\r
+\r
         HostAddr6 = Dns6TokenEntry->Token->RspData.H2AData->IpList;\r
         AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
         CopyMem (&HostAddr6[IpCount], AnswerData, sizeof (EFI_IPv6_ADDRESS));\r
 \r
         //\r
-        // Update DNS cache dynamically.\r
-        //\r
-        if (Dns6CacheEntry != NULL) {\r
-          if (Dns6CacheEntry->HostName != NULL) {\r
-            FreePool (Dns6CacheEntry->HostName);\r
-          }\r
-\r
-          if (Dns6CacheEntry->IpAddress != NULL) {\r
-            FreePool (Dns6CacheEntry->IpAddress);\r
-          }\r
-          \r
-          FreePool (Dns6CacheEntry);\r
-        }\r
-\r
-        // \r
-        // Allocate new CacheEntry pool.\r
+        // Allocate new CacheEntry pool to update DNS cache dynamically.\r
         //\r
         Dns6CacheEntry = AllocateZeroPool (sizeof (EFI_DNS6_CACHE_ENTRY));\r
         if (Dns6CacheEntry == NULL) {\r
@@ -1504,16 +1575,28 @@ ParseDnsResponse (
         } else {\r
           Dns6CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\r
         }\r
-        \r
-        UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);  \r
-        \r
+\r
+        UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);\r
+\r
+        //\r
+        // Free allocated CacheEntry pool.\r
+        //\r
+        FreePool (Dns6CacheEntry->HostName);\r
+        Dns6CacheEntry->HostName = NULL;\r
+\r
+        FreePool (Dns6CacheEntry->IpAddress);\r
+        Dns6CacheEntry->IpAddress = NULL;\r
+\r
+        FreePool (Dns6CacheEntry);\r
+        Dns6CacheEntry = NULL;\r
+\r
         IpCount ++;\r
         Status = EFI_SUCCESS;\r
         break;\r
       case DNS_TYPE_CNAME:\r
         //\r
-        // According RFC 1034 - 3.6.2, if the query name is an alias, the name server will include the CNAME \r
-        // record in the response and restart the query at the domain name specified in the data field of the \r
+        // According RFC 1034 - 3.6.2, if the query name is an alias, the name server will include the CNAME\r
+        // record in the response and restart the query at the domain name specified in the data field of the\r
         // CNAME record. So, just record the TTL value of the CNAME, then skip to parse the next record.\r
         //\r
         CNameTtl = AnswerSection->Ttl;\r
@@ -1523,7 +1606,7 @@ ParseDnsResponse (
         goto ON_EXIT;\r
       }\r
     }\r
-    \r
+\r
     //\r
     // Find next one\r
     //\r
@@ -1533,7 +1616,7 @@ ParseDnsResponse (
 \r
   if (Instance->Service->IpVersion == IP_VERSION_4) {\r
     ASSERT (Dns4TokenEntry != NULL);\r
-    \r
+\r
     if (Dns4TokenEntry->GeneralLookUp) {\r
       Dns4TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;\r
     } else {\r
@@ -1559,13 +1642,14 @@ ParseDnsResponse (
     }\r
   }\r
 \r
+ON_COMPLETE:\r
   //\r
   // Parsing is complete, free the sending packet and signal Event here.\r
   //\r
   if (Item != NULL && Item->Value != NULL) {\r
     NetbufFree ((NET_BUF *) (Item->Value));\r
   }\r
-  \r
+\r
   if (Instance->Service->IpVersion == IP_VERSION_4) {\r
     ASSERT (Dns4TokenEntry != NULL);\r
     Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);\r
@@ -1584,34 +1668,98 @@ ParseDnsResponse (
     }\r
   }\r
 \r
-  // \r
-  // Free allocated CacheEntry pool.\r
+ON_EXIT:\r
   //\r
-  if (Dns4CacheEntry != NULL) {\r
-    if (Dns4CacheEntry->HostName != NULL) {\r
-      FreePool (Dns4CacheEntry->HostName);\r
+  // Free the allocated buffer if error happen.\r
+  //\r
+  if (EFI_ERROR (Status)) {\r
+    if (Dns4TokenEntry != NULL) {\r
+      if (Dns4TokenEntry->GeneralLookUp) {\r
+        if (Dns4TokenEntry->Token->RspData.GLookupData != NULL) {\r
+          if (Dns4TokenEntry->Token->RspData.GLookupData->RRList != NULL) {\r
+            while (RRCount != 0) {\r
+              RRCount --;\r
+              if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {\r
+                FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);\r
+              }\r
+\r
+              if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {\r
+                FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);\r
+              }\r
+            }\r
+\r
+            FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList);\r
+          }\r
+\r
+          FreePool (Dns4TokenEntry->Token->RspData.GLookupData);\r
+        }\r
+      } else {\r
+        if (QuerySection->Type == DNS_TYPE_A && Dns4TokenEntry->Token->RspData.H2AData != NULL) {\r
+          if (Dns4TokenEntry->Token->RspData.H2AData->IpList != NULL) {\r
+            FreePool (Dns4TokenEntry->Token->RspData.H2AData->IpList);\r
+          }\r
+\r
+          FreePool (Dns4TokenEntry->Token->RspData.H2AData);\r
+        }\r
+      }\r
     }\r
 \r
-    if (Dns4CacheEntry->IpAddress != NULL) {\r
-      FreePool (Dns4CacheEntry->IpAddress);\r
+    if (Dns6TokenEntry != NULL) {\r
+      if (Dns6TokenEntry->GeneralLookUp) {\r
+        if (Dns6TokenEntry->Token->RspData.GLookupData != NULL) {\r
+          if (Dns6TokenEntry->Token->RspData.GLookupData->RRList != NULL) {\r
+            while (RRCount != 0) {\r
+              RRCount --;\r
+              if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {\r
+                FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);\r
+              }\r
+\r
+              if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {\r
+                FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);\r
+              }\r
+            }\r
+\r
+            FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList);\r
+          }\r
+\r
+          FreePool (Dns6TokenEntry->Token->RspData.GLookupData);\r
+        }\r
+      } else {\r
+        if (QuerySection->Type == DNS_TYPE_AAAA && Dns6TokenEntry->Token->RspData.H2AData != NULL) {\r
+          if (Dns6TokenEntry->Token->RspData.H2AData->IpList != NULL) {\r
+            FreePool (Dns6TokenEntry->Token->RspData.H2AData->IpList);\r
+          }\r
+\r
+          FreePool (Dns6TokenEntry->Token->RspData.H2AData);\r
+        }\r
+      }\r
     }\r
 \r
-    FreePool (Dns4CacheEntry);\r
-  }\r
-  \r
-  if (Dns6CacheEntry != NULL) {\r
-    if (Dns6CacheEntry->HostName != NULL) {\r
-      FreePool (Dns6CacheEntry->HostName);\r
+    if (Dns4CacheEntry != NULL) {\r
+      if (Dns4CacheEntry->HostName != NULL) {\r
+        FreePool (Dns4CacheEntry->HostName);\r
+      }\r
+\r
+      if (Dns4CacheEntry->IpAddress != NULL) {\r
+        FreePool (Dns4CacheEntry->IpAddress);\r
+      }\r
+\r
+      FreePool (Dns4CacheEntry);\r
     }\r
 \r
-    if (Dns6CacheEntry->IpAddress != NULL) {\r
-      FreePool (Dns6CacheEntry->IpAddress);\r
+    if (Dns6CacheEntry != NULL) {\r
+      if (Dns6CacheEntry->HostName != NULL) {\r
+        FreePool (Dns6CacheEntry->HostName);\r
+      }\r
+\r
+      if (Dns6CacheEntry->IpAddress != NULL) {\r
+        FreePool (Dns6CacheEntry->IpAddress);\r
+      }\r
+\r
+      FreePool (Dns6CacheEntry);\r
     }\r
-  \r
-    FreePool (Dns6CacheEntry);\r
   }\r
 \r
-ON_EXIT:\r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
@@ -1624,7 +1772,7 @@ ON_EXIT:
   @param  IoStatus              The status of the UDP receive\r
   @param  Context               The opaque parameter to the function.\r
 \r
-**/  \r
+**/\r
 VOID\r
 EFIAPI\r
 DnsOnPacketReceived (\r
@@ -1637,9 +1785,10 @@ DnsOnPacketReceived (
   DNS_INSTANCE              *Instance;\r
 \r
   UINT8                     *RcvString;\r
+  UINT32                    Len;\r
 \r
   BOOLEAN                   Completed;\r
-  \r
+\r
   Instance  = (DNS_INSTANCE *) Context;\r
   NET_CHECK_SIGNATURE (Instance, DNS_INSTANCE_SIGNATURE);\r
 \r
@@ -1652,17 +1801,15 @@ DnsOnPacketReceived (
 \r
   ASSERT (Packet != NULL);\r
 \r
-  if (Packet->TotalSize <= sizeof (DNS_HEADER)) {\r
-    goto ON_EXIT;\r
-  }\r
-  \r
+  Len = Packet->TotalSize;\r
+\r
   RcvString = NetbufGetByte (Packet, 0, NULL);\r
   ASSERT (RcvString != NULL);\r
-  \r
+\r
   //\r
   // Parse Dns Response\r
   //\r
-  ParseDnsResponse (Instance, RcvString, &Completed);\r
+  ParseDnsResponse (Instance, RcvString, Len, &Completed);\r
 \r
 ON_EXIT:\r
 \r
@@ -1724,7 +1871,7 @@ DnsOnPacketSent (
       }\r
     }\r
   }\r
-  \r
+\r
   NetbufFree (Packet);\r
 }\r
 \r
@@ -1755,14 +1902,14 @@ DoDnsQuery (
       return Status;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Transmit the DNS packet.\r
   //\r
   NET_GET_REF (Packet);\r
 \r
   Status = UdpIoSendDatagram (Instance->UdpIo, Packet, NULL, NULL, DnsOnPacketSent, Instance);\r
-  \r
+\r
   return Status;\r
 }\r
 \r
@@ -1770,9 +1917,9 @@ DoDnsQuery (
   Construct the Packet according query section.\r
 \r
   @param  Instance              The DNS instance\r
-  @param  QueryName             Queried Name  \r
-  @param  Type                  Queried Type \r
-  @param  Class                 Queried Class \r
+  @param  QueryName             Queried Name\r
+  @param  Type                  Queried Type\r
+  @param  Class                 Queried Class\r
   @param  Packet                The packet for query\r
 \r
   @retval EFI_SUCCESS           The packet is constructed.\r
@@ -1804,7 +1951,7 @@ ConstructDNSQuery (
   //\r
   // Fill header\r
   //\r
-  DnsHeader = (DNS_HEADER *) Frag.Bulk; \r
+  DnsHeader = (DNS_HEADER *) Frag.Bulk;\r
   DnsHeader->Identification = (UINT16)NET_RANDOM (NetRandomInitSeed());\r
   DnsHeader->Flags.Uint16 = 0x0000;\r
   DnsHeader->Flags.Bits.RD = 1;\r
@@ -1831,7 +1978,7 @@ ConstructDNSQuery (
   Frag.Len = (UINT32) (Frag.Len + AsciiStrLen (QueryName));\r
   *(Frag.Bulk + Frag.Len) = 0;\r
   Frag.Len ++;\r
-  \r
+\r
   //\r
   // Rest query section\r
   //\r
@@ -1850,7 +1997,7 @@ ConstructDNSQuery (
     FreePool (Frag.Bulk);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   //\r
   // Store the UdpIo in ProtoData.\r
   //\r
@@ -1863,7 +2010,7 @@ ConstructDNSQuery (
   Retransmit the packet.\r
 \r
   @param  Instance              The DNS instance\r
-  @param  Packet                Retransmit the packet \r
+  @param  Packet                Retransmit the packet\r
 \r
   @retval EFI_SUCCESS           The packet is retransmitted.\r
   @retval Others                Failed to retransmit.\r
@@ -1876,7 +2023,7 @@ DnsRetransmit (
   )\r
 {\r
   EFI_STATUS      Status;\r
-  \r
+\r
   UINT8           *Buffer;\r
 \r
   ASSERT (Packet != NULL);\r
@@ -1957,7 +2104,7 @@ DnsOnTimerRetransmit (
         // Retransmit the packet if haven't reach the maxmium retry count,\r
         // otherwise exit the transfer.\r
         //\r
-        if (++Dns4TokenEntry->Token->RetryCount < Instance->MaxRetry) {\r
+        if (++Dns4TokenEntry->RetryCounting <= Dns4TokenEntry->Token->RetryCount) {\r
           DnsRetransmit (Instance, (NET_BUF *)ItemNetMap->Value);\r
           EntryNetMap = EntryNetMap->ForwardLink;\r
         } else {\r
@@ -1968,7 +2115,7 @@ DnsOnTimerRetransmit (
           Dns4TokenEntry->Token->Status = EFI_TIMEOUT;\r
           gBS->SignalEvent (Dns4TokenEntry->Token->Event);\r
           DispatchDpc ();\r
-          \r
+\r
           //\r
           // Free the sending packet.\r
           //\r
@@ -1979,7 +2126,7 @@ DnsOnTimerRetransmit (
           EntryNetMap = Instance->Dns4TxTokens.Used.ForwardLink;\r
         }\r
       }\r
-    } \r
+    }\r
   }else {\r
     //\r
     // Iterate through all the children of the DNS service instance. Time\r
@@ -1987,7 +2134,7 @@ DnsOnTimerRetransmit (
     //\r
     NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Dns6ChildrenList) {\r
       Instance = NET_LIST_USER_STRUCT (Entry, DNS_INSTANCE, Link);\r
-      \r
+\r
       EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;\r
       while (EntryNetMap != &Instance->Dns6TxTokens.Used) {\r
         ItemNetMap = NET_LIST_USER_STRUCT (EntryNetMap, NET_MAP_ITEM, Link);\r
@@ -2001,7 +2148,7 @@ DnsOnTimerRetransmit (
         // Retransmit the packet if haven't reach the maxmium retry count,\r
         // otherwise exit the transfer.\r
         //\r
-        if (++Dns6TokenEntry->Token->RetryCount < Instance->MaxRetry) {\r
+        if (++Dns6TokenEntry->RetryCounting <= Dns6TokenEntry->Token->RetryCount) {\r
           DnsRetransmit (Instance, (NET_BUF *) ItemNetMap->Value);\r
           EntryNetMap = EntryNetMap->ForwardLink;\r
         } else {\r
@@ -2012,7 +2159,7 @@ DnsOnTimerRetransmit (
           Dns6TokenEntry->Token->Status = EFI_TIMEOUT;\r
           gBS->SignalEvent (Dns6TokenEntry->Token->Event);\r
           DispatchDpc ();\r
-          \r
+\r
           //\r
           // Free the sending packet.\r
           //\r
@@ -2021,10 +2168,10 @@ DnsOnTimerRetransmit (
           }\r
 \r
           EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;\r
-        } \r
+        }\r
       }\r
     }\r
-  } \r
+  }\r
 }\r
 \r
 /**\r
@@ -2056,18 +2203,21 @@ DnsOnTimerUpdate (
     Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
     Item4->DnsCache.Timeout--;\r
   }\r
-  \r
+\r
   Entry = mDriverData->Dns4CacheList.ForwardLink;\r
   while (Entry != &mDriverData->Dns4CacheList) {\r
     Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
     if (Item4->DnsCache.Timeout == 0) {\r
       RemoveEntryList (&Item4->AllCacheLink);\r
+      FreePool (Item4->DnsCache.HostName);\r
+      FreePool (Item4->DnsCache.IpAddress);\r
+      FreePool (Item4);\r
       Entry = mDriverData->Dns4CacheList.ForwardLink;\r
     } else {\r
       Entry = Entry->ForwardLink;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Iterate through all the DNS6 cache list.\r
   //\r
@@ -2075,12 +2225,15 @@ DnsOnTimerUpdate (
     Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
     Item6->DnsCache.Timeout--;\r
   }\r
-  \r
+\r
   Entry = mDriverData->Dns6CacheList.ForwardLink;\r
   while (Entry != &mDriverData->Dns6CacheList) {\r
     Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
     if (Item6->DnsCache.Timeout == 0) {\r
       RemoveEntryList (&Item6->AllCacheLink);\r
+      FreePool (Item6->DnsCache.HostName);\r
+      FreePool (Item6->DnsCache.IpAddress);\r
+      FreePool (Item6);\r
       Entry = mDriverData->Dns6CacheList.ForwardLink;\r
     } else {\r
       Entry = Entry->ForwardLink;\r