]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/DnsDxe/DnsImpl.c
MdePkg/SmiHandlerProfileLibNull: Add NULL instance.
[mirror_edk2.git] / NetworkPkg / DnsDxe / DnsImpl.c
index 617e623286d86f448b77e224735c62cae6afc4d9..794df1d728f255c4ddb6c21741381aa0e73f4e5e 100644 (file)
@@ -565,7 +565,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 +615,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
@@ -1037,67 +1037,13 @@ AddDns6ServerIp (
   return EFI_SUCCESS;\r
 }\r
 \r
-/**\r
-  Fill QName for IP querying. QName is a domain name represented as \r
-  a sequence of labels, where each label consists of a length octet \r
-  followed by that number of octets. The domain name terminates with \r
-  the zero length octet for the null label of the root. Caller should \r
-  take responsibility to the buffer in QName.\r
-\r
-  @param  HostName          Queried HostName    \r
-\r
-  @retval NULL      Failed to fill QName.\r
-  @return           QName filled successfully.\r
-  \r
-**/ \r
-CHAR8 *\r
-EFIAPI\r
-DnsFillinQNameForQueryIp (\r
-  IN  CHAR16              *HostName\r
-  )\r
-{\r
-  CHAR8                 *QueryName;\r
-  CHAR8                 *Header;\r
-  CHAR8                 *Tail;\r
-  UINTN                 Len;\r
-  UINTN                 Index;\r
-\r
-  QueryName  = NULL;\r
-  Header     = NULL;\r
-  Tail       = NULL;\r
-\r
-  QueryName = AllocateZeroPool (DNS_DEFAULT_BLKSIZE);\r
-  if (QueryName == NULL) {\r
-    return NULL;\r
-  }\r
-  \r
-  Header = QueryName;\r
-  Tail = Header + 1;\r
-  Len = 0;\r
-  for (Index = 0; HostName[Index] != 0; Index++) {\r
-    *Tail = (CHAR8) HostName[Index];\r
-    if (*Tail == '.') {\r
-      *Header = (CHAR8) Len;\r
-      Header = Tail;\r
-      Tail ++;\r
-      Len = 0;\r
-    } else {\r
-      Tail++;\r
-      Len++;\r
-    }\r
-  }\r
-  *Header = (CHAR8) Len;\r
-  *Tail = 0;\r
-\r
-  return QueryName;\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  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
@@ -1109,6 +1055,7 @@ IsValidDnsResponse (
   IN     NET_MAP      *TokensMap,\r
   IN     UINT16       Identification,\r
   IN     UINT16       Type,\r
+  IN     UINT16       Class,\r
      OUT NET_MAP_ITEM **Item\r
   )\r
 {\r
@@ -1132,17 +1079,16 @@ IsValidDnsResponse (
       DnsHeader = (DNS_HEADER *) TxString;\r
       QueryName = (CHAR8 *) (TxString + sizeof (*DnsHeader));\r
       QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);\r
-\r
-      DnsHeader->Identification = NTOHS (DnsHeader->Identification);\r
-      QuerySection->Type = NTOHS (QuerySection->Type);\r
         \r
-      if (DnsHeader->Identification == Identification && QuerySection->Type == Type) {\r
+      if (NTOHS (DnsHeader->Identification) == Identification &&\r
+          NTOHS (QuerySection->Type) == Type && \r
+          NTOHS (QuerySection->Class) == Class) {\r
         return TRUE;\r
       }\r
     } \r
   }\r
   \r
-  *Item =NULL;\r
+  *Item = NULL;\r
   \r
   return FALSE;\r
 }\r
@@ -1181,6 +1127,7 @@ ParseDnsResponse (
   UINT32                IpCount;\r
   UINT32                RRCount;\r
   UINT32                AnswerSectionNum;\r
+  UINT32                CNameTtl;\r
   \r
   EFI_IPv4_ADDRESS      *HostAddr4;\r
   EFI_IPv6_ADDRESS      *HostAddr6;\r
@@ -1202,6 +1149,7 @@ ParseDnsResponse (
   IpCount          = 0;\r
   RRCount          = 0;\r
   AnswerSectionNum = 0;\r
+  CNameTtl         = 0;\r
   \r
   HostAddr4        = NULL;\r
   HostAddr6        = NULL;\r
@@ -1250,7 +1198,13 @@ ParseDnsResponse (
   // Check DnsResponse Validity, if so, also get a valid NET_MAP_ITEM.\r
   //\r
   if (Instance->Service->IpVersion == IP_VERSION_4) {\r
-    if (!IsValidDnsResponse (&Instance->Dns4TxTokens, DnsHeader->Identification, QuerySection->Type, &Item)) {\r
+    if (!IsValidDnsResponse (\r
+           &Instance->Dns4TxTokens, \r
+           DnsHeader->Identification, \r
+           QuerySection->Type,\r
+           QuerySection->Class,\r
+           &Item\r
+           )) {\r
       *Completed = FALSE;\r
       Status = EFI_ABORTED;\r
       goto ON_EXIT;\r
@@ -1258,7 +1212,13 @@ ParseDnsResponse (
     ASSERT (Item != NULL);\r
     Dns4TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);\r
   } else {\r
-    if (!IsValidDnsResponse (&Instance->Dns6TxTokens, DnsHeader->Identification, QuerySection->Type, &Item)) {\r
+    if (!IsValidDnsResponse (\r
+           &Instance->Dns6TxTokens, \r
+           DnsHeader->Identification, \r
+           QuerySection->Type,\r
+           QuerySection->Class,\r
+           &Item\r
+           )) {\r
       *Completed = FALSE;\r
       Status = EFI_ABORTED;\r
       goto ON_EXIT;\r
@@ -1271,16 +1231,17 @@ ParseDnsResponse (
   // 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 || QuerySection->Class != DNS_CLASS_INET) {\r
-      Status = EFI_ABORTED;\r
-      goto ON_EXIT;\r
-  }\r
-\r
-  //\r
-  // Free the sending packet.\r
-  //\r
-  if (Item->Value != NULL) {\r
-    NetbufFree ((NET_BUF *) (Item->Value));\r
+      DnsHeader->Flags.Bits.QR != DNS_FLAGS_QR_RESPONSE) {\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
@@ -1332,12 +1293,12 @@ ParseDnsResponse (
       //\r
       Dns6TokenEntry->Token->RspData.GLookupData = AllocatePool (sizeof (DNS_RESOURCE_RECORD));\r
       if (Dns6TokenEntry->Token->RspData.GLookupData == NULL) {\r
-        Status = EFI_UNSUPPORTED;\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
       if (Dns6TokenEntry->Token->RspData.GLookupData->RRList == NULL) {\r
-        Status = EFI_UNSUPPORTED;\r
+        Status = EFI_OUT_OF_RESOURCES;\r
         goto ON_EXIT;\r
       }\r
     } else {\r
@@ -1347,12 +1308,12 @@ ParseDnsResponse (
       if (QuerySection->Type == DNS_TYPE_AAAA) {\r
         Dns6TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
         if (Dns6TokenEntry->Token->RspData.H2AData == NULL) {\r
-          Status = EFI_UNSUPPORTED;\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
         if (Dns6TokenEntry->Token->RspData.H2AData->IpList == NULL) {\r
-          Status = EFI_UNSUPPORTED;\r
+          Status = EFI_OUT_OF_RESOURCES;\r
           goto ON_EXIT;\r
         }\r
       } else {\r
@@ -1362,14 +1323,19 @@ ParseDnsResponse (
     }\r
   }\r
 \r
+  Status = EFI_NOT_FOUND;\r
+\r
   //\r
   // Processing AnswerSection.\r
   //\r
   while (AnswerSectionNum < DnsHeader->AnswersNum) {\r
     //\r
-    // Answer name should be PTR.\r
+    // Answer name should be PTR, else EFI_UNSUPPORTED returned.\r
     //\r
-    ASSERT ((*(UINT8 *) AnswerName & 0xC0) == 0xC0);\r
+    if ((*(UINT8 *) AnswerName & 0xC0) != 0xC0) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto ON_EXIT;\r
+    }\r
     \r
     //\r
     // Get Answer section.\r
@@ -1392,7 +1358,7 @@ ParseDnsResponse (
       //\r
       Dns4RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);\r
       if (Dns4RR[RRCount].QName == NULL) {\r
-        Status = EFI_UNSUPPORTED;\r
+        Status = EFI_OUT_OF_RESOURCES;\r
         goto ON_EXIT;\r
       }\r
       CopyMem (Dns4RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));\r
@@ -1402,12 +1368,13 @@ ParseDnsResponse (
       Dns4RR[RRCount].DataLength = AnswerSection->DataLength;\r
       Dns4RR[RRCount].RData = AllocateZeroPool (Dns4RR[RRCount].DataLength);\r
       if (Dns4RR[RRCount].RData == NULL) {\r
-        Status = EFI_UNSUPPORTED;\r
+        Status = EFI_OUT_OF_RESOURCES;\r
         goto ON_EXIT;\r
       }\r
       CopyMem (Dns4RR[RRCount].RData, AnswerData, Dns4RR[RRCount].DataLength);\r
       \r
       RRCount ++;\r
+      Status = EFI_SUCCESS;\r
     } else if (Instance->Service->IpVersion == IP_VERSION_6 && Dns6TokenEntry->GeneralLookUp) {\r
       Dns6RR = Dns6TokenEntry->Token->RspData.GLookupData->RRList;\r
       AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
@@ -1417,7 +1384,7 @@ ParseDnsResponse (
       //\r
       Dns6RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);\r
       if (Dns6RR[RRCount].QName == NULL) {\r
-        Status = EFI_UNSUPPORTED;\r
+        Status = EFI_OUT_OF_RESOURCES;\r
         goto ON_EXIT;\r
       }\r
       CopyMem (Dns6RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));\r
@@ -1427,12 +1394,13 @@ ParseDnsResponse (
       Dns6RR[RRCount].DataLength = AnswerSection->DataLength;\r
       Dns6RR[RRCount].RData = AllocateZeroPool (Dns6RR[RRCount].DataLength);\r
       if (Dns6RR[RRCount].RData == NULL) {\r
-        Status = EFI_UNSUPPORTED;\r
+        Status = EFI_OUT_OF_RESOURCES;\r
         goto ON_EXIT;\r
       }\r
       CopyMem (Dns6RR[RRCount].RData, AnswerData, Dns6RR[RRCount].DataLength);\r
       \r
       RRCount ++;\r
+      Status = EFI_SUCCESS;\r
     } else {\r
       //\r
       // It's not the GeneralLookUp querying. \r
@@ -1443,103 +1411,127 @@ ParseDnsResponse (
         //\r
         // This is address entry, get Data.\r
         //\r
-        ASSERT (Dns4TokenEntry != NULL && AnswerSection->DataLength == 4);\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
-          Status = EFI_UNSUPPORTED;\r
+          Status = EFI_OUT_OF_RESOURCES;\r
           goto ON_EXIT;\r
         }\r
         Dns4CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));\r
         if (Dns4CacheEntry->HostName == NULL) {\r
-          Status = EFI_UNSUPPORTED;\r
+          Status = EFI_OUT_OF_RESOURCES;\r
           goto ON_EXIT;\r
         }\r
         CopyMem (Dns4CacheEntry->HostName, Dns4TokenEntry->QueryHostName, 2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));\r
         Dns4CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS));\r
         if (Dns4CacheEntry->IpAddress == NULL) {\r
-          Status = EFI_UNSUPPORTED;\r
+          Status = EFI_OUT_OF_RESOURCES;\r
           goto ON_EXIT;\r
         }\r
         CopyMem (Dns4CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv4_ADDRESS));\r
-        Dns4CacheEntry->Timeout = AnswerSection->Ttl;\r
+\r
+        if (CNameTtl != 0 && AnswerSection->Ttl != 0) {\r
+          Dns4CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);\r
+        } else {\r
+          Dns4CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\r
+        }\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
-        UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);  \r
+        FreePool (Dns4CacheEntry->IpAddress);\r
+        Dns4CacheEntry->IpAddress = NULL;\r
 \r
-        IpCount ++; \r
+        FreePool (Dns4CacheEntry);\r
+        Dns4CacheEntry = NULL;\r
+\r
+        IpCount ++;\r
+        Status = EFI_SUCCESS;\r
         break;\r
       case DNS_TYPE_AAAA:\r
         //\r
         // This is address entry, get Data.\r
         //\r
-        ASSERT (Dns6TokenEntry != NULL && AnswerSection->DataLength == 16);\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
-          Status = EFI_UNSUPPORTED;\r
+          Status = EFI_OUT_OF_RESOURCES;\r
           goto ON_EXIT;\r
         }\r
         Dns6CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));\r
         if (Dns6CacheEntry->HostName == NULL) {\r
-          Status = EFI_UNSUPPORTED;\r
+          Status = EFI_OUT_OF_RESOURCES;\r
           goto ON_EXIT;\r
         }\r
         CopyMem (Dns6CacheEntry->HostName, Dns6TokenEntry->QueryHostName, 2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));\r
         Dns6CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));\r
         if (Dns6CacheEntry->IpAddress == NULL) {\r
-          Status = EFI_UNSUPPORTED;\r
+          Status = EFI_OUT_OF_RESOURCES;\r
           goto ON_EXIT;\r
         }\r
         CopyMem (Dns6CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv6_ADDRESS));\r
-        Dns6CacheEntry->Timeout = AnswerSection->Ttl;\r
+\r
+        if (CNameTtl != 0 && AnswerSection->Ttl != 0) {\r
+          Dns6CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);\r
+        } else {\r
+          Dns6CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\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
-        UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);  \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
+        // CNAME record. So, just record the TTL value of the CNAME, then skip to parse the next record.\r
+        //\r
+        CNameTtl = AnswerSection->Ttl;\r
         break;\r
       default:\r
         Status = EFI_UNSUPPORTED;\r
@@ -1581,14 +1573,19 @@ ParseDnsResponse (
       }\r
     }\r
   }\r
-\r
+  \r
+ON_COMPLETE:\r
   //\r
-  // Parsing is complete, SignalEvent here.\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
   if (Instance->Service->IpVersion == IP_VERSION_4) {\r
     ASSERT (Dns4TokenEntry != NULL);\r
     Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);\r
-    Dns4TokenEntry->Token->Status = EFI_SUCCESS;\r
+    Dns4TokenEntry->Token->Status = Status;\r
     if (Dns4TokenEntry->Token->Event != NULL) {\r
       gBS->SignalEvent (Dns4TokenEntry->Token->Event);\r
       DispatchDpc ();\r
@@ -1596,40 +1593,13 @@ ParseDnsResponse (
   } else {\r
     ASSERT (Dns6TokenEntry != NULL);\r
     Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);\r
-    Dns6TokenEntry->Token->Status = EFI_SUCCESS;\r
+    Dns6TokenEntry->Token->Status = Status;\r
     if (Dns6TokenEntry->Token->Event != NULL) {\r
       gBS->SignalEvent (Dns6TokenEntry->Token->Event);\r
       DispatchDpc ();\r
     }\r
   }\r
 \r
-  // \r
-  // Free allocated CacheEntry pool.\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
-  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
 ON_EXIT:\r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
@@ -1670,6 +1640,10 @@ DnsOnPacketReceived (
   }\r
 \r
   ASSERT (Packet != NULL);\r
+\r
+  if (Packet->TotalSize <= sizeof (DNS_HEADER)) {\r
+    goto ON_EXIT;\r
+  }\r
   \r
   RcvString = NetbufGetByte (Packet, 0, NULL);\r
   ASSERT (RcvString != NULL);\r
@@ -1679,15 +1653,15 @@ DnsOnPacketReceived (
   //\r
   ParseDnsResponse (Instance, RcvString, &Completed);\r
 \r
-  ON_EXIT:\r
+ON_EXIT:\r
 \r
-    if (Packet != NULL) {\r
-      NetbufFree (Packet);\r
-    }\r
+  if (Packet != NULL) {\r
+    NetbufFree (Packet);\r
+  }\r
 \r
-    if (!Completed) {\r
-      UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);\r
-    }\r
+  if (!Completed) {\r
+    UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);\r
+  }\r
 }\r
 \r
 /**\r
@@ -1806,8 +1780,12 @@ ConstructDNSQuery (
   NET_FRAGMENT        Frag;\r
   DNS_HEADER          *DnsHeader;\r
   DNS_QUERY_SECTION   *DnsQuery;\r
-  \r
-  Frag.Bulk = AllocatePool (DNS_DEFAULT_BLKSIZE * sizeof (UINT8));\r
+\r
+  //\r
+  // Messages carried by UDP are restricted to 512 bytes (not counting the IP\r
+  // or UDP headers).\r
+  //\r
+  Frag.Bulk = AllocatePool (DNS_MAX_MESSAGE_SIZE * sizeof (UINT8));\r
   if (Frag.Bulk == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -2071,7 +2049,7 @@ DnsOnTimerUpdate (
   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
+    if (Item4->DnsCache.Timeout == 0) {\r
       RemoveEntryList (&Item4->AllCacheLink);\r
       Entry = mDriverData->Dns4CacheList.ForwardLink;\r
     } else {\r
@@ -2090,7 +2068,7 @@ DnsOnTimerUpdate (
   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
+    if (Item6->DnsCache.Timeout == 0) {\r
       RemoveEntryList (&Item6->AllCacheLink);\r
       Entry = mDriverData->Dns6CacheList.ForwardLink;\r
     } else {\r