diff options
-rw-r--r-- | NetworkPkg/DnsDxe/DnsImpl.c | 81 |
1 files changed, 52 insertions, 29 deletions
diff --git a/NetworkPkg/DnsDxe/DnsImpl.c b/NetworkPkg/DnsDxe/DnsImpl.c index 360f68e1a4..cfaa4c78a9 100644 --- a/NetworkPkg/DnsDxe/DnsImpl.c +++ b/NetworkPkg/DnsDxe/DnsImpl.c @@ -1127,6 +1127,7 @@ ParseDnsResponse ( UINT32 IpCount;
UINT32 RRCount;
UINT32 AnswerSectionNum;
+ UINT32 CNameTtl;
EFI_IPv4_ADDRESS *HostAddr4;
EFI_IPv6_ADDRESS *HostAddr6;
@@ -1148,6 +1149,7 @@ ParseDnsResponse ( IpCount = 0;
RRCount = 0;
AnswerSectionNum = 0;
+ CNameTtl = 0;
HostAddr4 = NULL;
HostAddr6 = NULL;
@@ -1233,13 +1235,6 @@ ParseDnsResponse ( Status = EFI_ABORTED;
goto ON_EXIT;
}
-
- //
- // Free the sending packet.
- //
- if (Item->Value != NULL) {
- NetbufFree ((NET_BUF *) (Item->Value));
- }
//
// Do some buffer allocations.
@@ -1290,12 +1285,12 @@ ParseDnsResponse ( //
Dns6TokenEntry->Token->RspData.GLookupData = AllocatePool (sizeof (DNS_RESOURCE_RECORD));
if (Dns6TokenEntry->Token->RspData.GLookupData == NULL) {
- Status = EFI_UNSUPPORTED;
+ Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
Dns6TokenEntry->Token->RspData.GLookupData->RRList = AllocatePool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));
if (Dns6TokenEntry->Token->RspData.GLookupData->RRList == NULL) {
- Status = EFI_UNSUPPORTED;
+ Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
} else {
@@ -1305,12 +1300,12 @@ ParseDnsResponse ( if (QuerySection->Type == DNS_TYPE_AAAA) {
Dns6TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));
if (Dns6TokenEntry->Token->RspData.H2AData == NULL) {
- Status = EFI_UNSUPPORTED;
+ Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocatePool (DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));
if (Dns6TokenEntry->Token->RspData.H2AData->IpList == NULL) {
- Status = EFI_UNSUPPORTED;
+ Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
} else {
@@ -1320,6 +1315,8 @@ ParseDnsResponse ( }
}
+ Status = EFI_NOT_FOUND;
+
//
// Processing AnswerSection.
//
@@ -1350,7 +1347,7 @@ ParseDnsResponse ( //
Dns4RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);
if (Dns4RR[RRCount].QName == NULL) {
- Status = EFI_UNSUPPORTED;
+ Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
CopyMem (Dns4RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));
@@ -1360,12 +1357,13 @@ ParseDnsResponse ( Dns4RR[RRCount].DataLength = AnswerSection->DataLength;
Dns4RR[RRCount].RData = AllocateZeroPool (Dns4RR[RRCount].DataLength);
if (Dns4RR[RRCount].RData == NULL) {
- Status = EFI_UNSUPPORTED;
+ 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);
@@ -1375,7 +1373,7 @@ ParseDnsResponse ( //
Dns6RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);
if (Dns6RR[RRCount].QName == NULL) {
- Status = EFI_UNSUPPORTED;
+ Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
CopyMem (Dns6RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));
@@ -1385,12 +1383,13 @@ ParseDnsResponse ( Dns6RR[RRCount].DataLength = AnswerSection->DataLength;
Dns6RR[RRCount].RData = AllocateZeroPool (Dns6RR[RRCount].DataLength);
if (Dns6RR[RRCount].RData == NULL) {
- Status = EFI_UNSUPPORTED;
+ 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.
@@ -1427,26 +1426,32 @@ ParseDnsResponse ( //
Dns4CacheEntry = AllocateZeroPool (sizeof (EFI_DNS4_CACHE_ENTRY));
if (Dns4CacheEntry == NULL) {
- Status = EFI_UNSUPPORTED;
+ Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
Dns4CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));
if (Dns4CacheEntry->HostName == NULL) {
- Status = EFI_UNSUPPORTED;
+ 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_UNSUPPORTED;
+ Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
CopyMem (Dns4CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv4_ADDRESS));
- Dns4CacheEntry->Timeout = AnswerSection->Ttl;
+
+ 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);
- IpCount ++;
+ IpCount ++;
+ Status = EFI_SUCCESS;
break;
case DNS_TYPE_AAAA:
//
@@ -1478,26 +1483,40 @@ ParseDnsResponse ( //
Dns6CacheEntry = AllocateZeroPool (sizeof (EFI_DNS6_CACHE_ENTRY));
if (Dns6CacheEntry == NULL) {
- Status = EFI_UNSUPPORTED;
+ Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
Dns6CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));
if (Dns6CacheEntry->HostName == NULL) {
- Status = EFI_UNSUPPORTED;
+ 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_UNSUPPORTED;
+ Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
CopyMem (Dns6CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv6_ADDRESS));
- Dns6CacheEntry->Timeout = AnswerSection->Ttl;
+
+ 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);
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;
@@ -1541,12 +1560,16 @@ ParseDnsResponse ( }
//
- // Parsing is complete, SignalEvent here.
+ // 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 = EFI_SUCCESS;
+ Dns4TokenEntry->Token->Status = Status;
if (Dns4TokenEntry->Token->Event != NULL) {
gBS->SignalEvent (Dns4TokenEntry->Token->Event);
DispatchDpc ();
@@ -1554,7 +1577,7 @@ ParseDnsResponse ( } else {
ASSERT (Dns6TokenEntry != NULL);
Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);
- Dns6TokenEntry->Token->Status = EFI_SUCCESS;
+ Dns6TokenEntry->Token->Status = Status;
if (Dns6TokenEntry->Token->Event != NULL) {
gBS->SignalEvent (Dns6TokenEntry->Token->Event);
DispatchDpc ();
@@ -2037,7 +2060,7 @@ DnsOnTimerUpdate ( Entry = mDriverData->Dns4CacheList.ForwardLink;
while (Entry != &mDriverData->Dns4CacheList) {
Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
- if (Item4->DnsCache.Timeout<=0) {
+ if (Item4->DnsCache.Timeout == 0) {
RemoveEntryList (&Item4->AllCacheLink);
Entry = mDriverData->Dns4CacheList.ForwardLink;
} else {
@@ -2056,7 +2079,7 @@ DnsOnTimerUpdate ( Entry = mDriverData->Dns6CacheList.ForwardLink;
while (Entry != &mDriverData->Dns6CacheList) {
Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
- if (Item6->DnsCache.Timeout<=0) {
+ if (Item6->DnsCache.Timeout == 0) {
RemoveEntryList (&Item6->AllCacheLink);
Entry = mDriverData->Dns6CacheList.ForwardLink;
} else {
|