]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/DnsDxe/DnsImpl.c
BaseTools: resolve initialization order errors in VfrFormPkg.h
[mirror_edk2.git] / NetworkPkg / DnsDxe / DnsImpl.c
index cfaa4c78a936cb9aac9e4cfea577c9be7d266e39..7057bfbbec9c5a91655c586ab42a09d2ff4d611b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 DnsDxe support functions implementation.\r
   \r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2016 - 2017, 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
@@ -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
@@ -643,9 +643,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
@@ -790,6 +792,10 @@ UpdateDns4Cache (
         // Delete matching DNS Cache entry\r
         //\r
         RemoveEntryList (&Item->AllCacheLink);\r
+\r
+        FreePool (Item->DnsCache.HostName);\r
+        FreePool (Item->DnsCache.IpAddress);\r
+        FreePool (Item);\r
         \r
         return EFI_SUCCESS;\r
       } else if (Override) {\r
@@ -817,13 +823,16 @@ UpdateDns4Cache (
    \r
   NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));\r
   if (NewDnsCache->DnsCache.HostName == NULL) { \r
+    FreePool (NewDnsCache);\r
     return EFI_OUT_OF_RESOURCES;\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
@@ -882,6 +891,10 @@ UpdateDns6Cache (
         //\r
         RemoveEntryList (&Item->AllCacheLink);\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
@@ -908,13 +921,16 @@ UpdateDns6Cache (
    \r
   NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));\r
   if (NewDnsCache->DnsCache.HostName == NULL) { \r
+    FreePool (NewDnsCache);\r
     return EFI_OUT_OF_RESOURCES;\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
@@ -1232,8 +1248,16 @@ ParseDnsResponse (
   //\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
@@ -1246,12 +1270,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 +1285,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 +1307,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 +1322,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
@@ -1322,9 +1346,12 @@ ParseDnsResponse (
   //\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
@@ -1400,29 +1427,19 @@ 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
@@ -1448,7 +1465,19 @@ ParseDnsResponse (
           Dns4CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\r
         }\r
         \r
-        UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);  \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 +1486,19 @@ ParseDnsResponse (
         //\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
@@ -1505,7 +1524,19 @@ ParseDnsResponse (
           Dns6CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\r
         }\r
         \r
-        UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);  \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
@@ -1558,7 +1589,8 @@ ParseDnsResponse (
       }\r
     }\r
   }\r
-\r
+  \r
+ON_COMPLETE:\r
   //\r
   // Parsing is complete, free the sending packet and signal Event here.\r
   //\r
@@ -1584,34 +1616,98 @@ ParseDnsResponse (
     }\r
   }\r
 \r
-  // \r
-  // Free allocated CacheEntry pool.\r
+ON_EXIT:\r
+  //\r
+  // Free the allocated buffer if error happen.\r
   //\r
-  if (Dns4CacheEntry != NULL) {\r
-    if (Dns4CacheEntry->HostName != NULL) {\r
-      FreePool (Dns4CacheEntry->HostName);\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
-    }\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
-    if (Dns6CacheEntry->IpAddress != NULL) {\r
-      FreePool (Dns6CacheEntry->IpAddress);\r
+      FreePool (Dns4CacheEntry);\r
     }\r
-  \r
-    FreePool (Dns6CacheEntry);\r
-  }\r
 \r
-ON_EXIT:\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
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
@@ -1957,7 +2053,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
@@ -2001,7 +2097,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
@@ -2062,6 +2158,9 @@ DnsOnTimerUpdate (
     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
@@ -2081,6 +2180,9 @@ DnsOnTimerUpdate (
     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