diff options
Diffstat (limited to 'NetworkPkg')
24 files changed, 455 insertions, 152 deletions
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c index f38e3ee..f72bc93 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c @@ -1001,7 +1001,7 @@ Dhcp6AppendETOption ( return EFI_INVALID_PARAMETER;
}
- if ((Elapsed == NULL)) {
+ if (Elapsed == NULL) {
return EFI_INVALID_PARAMETER;
}
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c index 40f64fc..858e7c2 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootClient.c +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c @@ -923,6 +923,9 @@ HttpBootGetBootFileCallback ( BufferSize has been updated with the size needed to complete
the request.
@retval EFI_ACCESS_DENIED The server needs to authenticate the client.
+ @retval EFI_NOT_READY Data transfer has timed-out, call HttpBootGetBootFile again to resume
+ the download operation using HTTP Range headers.
+ @retval EFI_UNSUPPORTED Some HTTP response header is not supported.
@retval Others Unexpected error happened.
**/
@@ -955,6 +958,10 @@ HttpBootGetBootFile ( CHAR8 BaseAuthValue[80];
EFI_HTTP_HEADER *HttpHeader;
CHAR8 *Data;
+ UINTN HeadersCount;
+ BOOLEAN ResumingOperation;
+ CHAR8 *ContentRangeResponseValue;
+ CHAR8 RangeValue[64];
ASSERT (Private != NULL);
ASSERT (Private->HttpCreated);
@@ -985,6 +992,16 @@ HttpBootGetBootFile ( }
}
+ // Check if this is a previous download that has failed and need to be resumed
+ if ((!HeaderOnly) &&
+ (Private->PartialTransferredSize > 0) &&
+ (Private->BootFileSize == *BufferSize))
+ {
+ ResumingOperation = TRUE;
+ } else {
+ ResumingOperation = FALSE;
+ }
+
//
// Not found in cache, try to download it through HTTP.
//
@@ -1014,8 +1031,23 @@ HttpBootGetBootFile ( // Accept
// User-Agent
// [Authorization]
+ // [Range]
+ // [If-Match]|[If-Unmodified-Since]
//
- HttpIoHeader = HttpIoCreateHeader ((Private->AuthData != NULL) ? 4 : 3);
+ HeadersCount = 3;
+ if (Private->AuthData != NULL) {
+ HeadersCount++;
+ }
+
+ if (ResumingOperation) {
+ HeadersCount++;
+ if (Private->LastModifiedOrEtag) {
+ HeadersCount++;
+ }
+ }
+
+ HttpIoHeader = HttpIoCreateHeader (HeadersCount);
+
if (HttpIoHeader == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ERROR_2;
@@ -1098,6 +1130,62 @@ HttpBootGetBootFile ( }
//
+ // Add HTTP header field 5 (optional): Range
+ //
+ if (ResumingOperation) {
+ // Resuming a failed download. Prepare the HTTP Range Header
+ Status = AsciiSPrint (
+ RangeValue,
+ sizeof (RangeValue),
+ "bytes=%lu-%lu",
+ Private->PartialTransferredSize,
+ Private->BootFileSize - 1
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR_3;
+ }
+
+ Status = HttpIoSetHeader (HttpIoHeader, "Range", RangeValue);
+ if (EFI_ERROR (Status)) {
+ goto ERROR_3;
+ }
+
+ DEBUG (
+ (DEBUG_WARN | DEBUG_INFO,
+ "HttpBootGetBootFile: Resuming failed download. Range: %a\n",
+ RangeValue)
+ );
+
+ //
+ // Add HTTP header field 6 (optional): If-Match or If-Unmodified-Since
+ //
+ if (Private->LastModifiedOrEtag) {
+ if (Private->LastModifiedOrEtag[0] == '"') {
+ // An ETag value starts with "
+ DEBUG (
+ (DEBUG_WARN | DEBUG_INFO,
+ "HttpBootGetBootFile: If-Match=%a\n",
+ Private->LastModifiedOrEtag)
+ );
+ // Add If-Match header with the ETag value got from the first request.
+ Status = HttpIoSetHeader (HttpIoHeader, HTTP_HEADER_IF_MATCH, Private->LastModifiedOrEtag);
+ } else {
+ DEBUG (
+ (DEBUG_WARN | DEBUG_INFO,
+ "HttpBootGetBootFile: If-Unmodified-Since=%a\n",
+ Private->LastModifiedOrEtag)
+ );
+ // Add If-Unmodified-Since header with the timestamp value (Last-Modified) got from the first request.
+ Status = HttpIoSetHeader (HttpIoHeader, HTTP_HEADER_IF_UNMODIFIED_SINCE, Private->LastModifiedOrEtag);
+ }
+
+ if (EFI_ERROR (Status)) {
+ goto ERROR_3;
+ }
+ }
+ }
+
+ //
// 2.2 Build the rest of HTTP request info.
//
RequestData = AllocatePool (sizeof (EFI_HTTP_REQUEST_DATA));
@@ -1245,6 +1333,62 @@ HttpBootGetBootFile ( Cache->ImageType = *ImageType;
}
+ // Cache ETag or Last-Modified response header value to
+ // be used when resuming an interrupted download.
+ HttpHeader = HttpFindHeader (
+ ResponseData->HeaderCount,
+ ResponseData->Headers,
+ HTTP_HEADER_ETAG
+ );
+ if (HttpHeader == NULL) {
+ HttpHeader = HttpFindHeader (
+ ResponseData->HeaderCount,
+ ResponseData->Headers,
+ HTTP_HEADER_LAST_MODIFIED
+ );
+ }
+
+ if (HttpHeader) {
+ if (Private->LastModifiedOrEtag) {
+ FreePool (Private->LastModifiedOrEtag);
+ }
+
+ Private->LastModifiedOrEtag = AllocateCopyPool (AsciiStrSize (HttpHeader->FieldValue), HttpHeader->FieldValue);
+ }
+
+ //
+ // 3.2.2 Validate the range response. If operation is being resumed,
+ // server must respond with Content-Range.
+ //
+ if (ResumingOperation) {
+ HttpHeader = HttpFindHeader (
+ ResponseData->HeaderCount,
+ ResponseData->Headers,
+ HTTP_HEADER_CONTENT_RANGE
+ );
+ if ((HttpHeader == NULL) ||
+ (AsciiStrnCmp (HttpHeader->FieldValue, "bytes", 5) != 0))
+ {
+ Status = EFI_UNSUPPORTED;
+ goto ERROR_5;
+ }
+
+ // Gets the total size of ranged data (Content-Range: <unit> <range-start>-<range-end>/<size>)
+ // and check if it remains the same
+ ContentRangeResponseValue = AsciiStrStr (HttpHeader->FieldValue, "/");
+ if (ContentRangeResponseValue == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ERROR_5;
+ }
+
+ ContentRangeResponseValue++;
+ ContentLength = AsciiStrDecimalToUintn (ContentRangeResponseValue);
+ if (ContentLength != *BufferSize) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ERROR_5;
+ }
+ }
+
//
// 3.3 Init a message-body parser from the header information.
//
@@ -1295,10 +1439,15 @@ HttpBootGetBootFile ( // In identity transfer-coding there is no need to parse the message body,
// just download the message body to the user provided buffer directly.
//
+ if (ResumingOperation && ((ContentLength + Private->PartialTransferredSize) > *BufferSize)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ERROR_6;
+ }
+
ReceivedSize = 0;
while (ReceivedSize < ContentLength) {
- ResponseBody.Body = (CHAR8 *)Buffer + ReceivedSize;
- ResponseBody.BodyLength = *BufferSize - ReceivedSize;
+ ResponseBody.Body = (CHAR8 *)Buffer + (ReceivedSize + Private->PartialTransferredSize);
+ ResponseBody.BodyLength = *BufferSize - (ReceivedSize + Private->PartialTransferredSize);
Status = HttpIoRecvResponse (
&Private->HttpIo,
FALSE,
@@ -1309,6 +1458,20 @@ HttpBootGetBootFile ( Status = ResponseBody.Status;
}
+ if ((Status == EFI_TIMEOUT) || (Status == EFI_DEVICE_ERROR)) {
+ // For EFI_TIMEOUT and EFI_DEVICE_ERROR errors, we may resume the operation.
+ // We will not check if server sent Accept-Ranges header, because some back-ends
+ // do not report this header, even when supporting it. Know example: CloudFlare CDN Cache.
+ Private->PartialTransferredSize = ReceivedSize;
+ DEBUG (
+ (
+ DEBUG_WARN | DEBUG_INFO,
+ "HttpBootGetBootFile: Transfer error. Bytes transferred so far: %lu.\n",
+ ReceivedSize
+ )
+ );
+ }
+
goto ERROR_6;
}
@@ -1326,6 +1489,9 @@ HttpBootGetBootFile ( }
}
}
+
+ // download completed, there is no more partial data
+ Private->PartialTransferredSize = 0;
} else {
//
// In "chunked" transfer-coding mode, so we need to parse the received
@@ -1385,9 +1551,13 @@ HttpBootGetBootFile ( //
// 3.5 Message-body receive & parse is completed, we should be able to get the file size now.
//
- Status = HttpGetEntityLength (Parser, &ContentLength);
- if (EFI_ERROR (Status)) {
- goto ERROR_6;
+ if (!ResumingOperation) {
+ Status = HttpGetEntityLength (Parser, &ContentLength);
+ if (EFI_ERROR (Status)) {
+ goto ERROR_6;
+ }
+ } else {
+ ContentLength = Private->BootFileSize;
}
if (*BufferSize < ContentLength) {
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.h b/NetworkPkg/HttpBootDxe/HttpBootClient.h index 86a28bc..406eefb 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootClient.h +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.h @@ -108,6 +108,7 @@ HttpBootCreateHttpIo ( BufferSize has been updated with the size needed to complete
the request.
@retval EFI_ACCESS_DENIED The server needs to authenticate the client.
+ @retval EFI_UNSUPPORTED Some HTTP response header is not supported.
@retval Others Unexpected error happened.
**/
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.h b/NetworkPkg/HttpBootDxe/HttpBootDxe.h index 5ff8ad4..193235d 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.h +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.h @@ -214,6 +214,8 @@ struct _HTTP_BOOT_PRIVATE_DATA { CHAR8 *BootFileUri;
VOID *BootFileUriParser;
UINTN BootFileSize;
+ UINTN PartialTransferredSize;
+ CHAR8 *LastModifiedOrEtag;
BOOLEAN NoGateway;
HTTP_BOOT_IMAGE_TYPE ImageType;
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.inf b/NetworkPkg/HttpBootDxe/HttpBootDxe.inf index cffa642..3f87e58 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.inf +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.inf @@ -95,8 +95,10 @@ gEfiAdapterInfoUndiIpv6SupportGuid ## SOMETIMES_CONSUMES ## GUID
[Pcd]
- gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections ## CONSUMES
- gEfiNetworkPkgTokenSpaceGuid.PcdHttpIoTimeout ## CONSUMES
+ gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections ## CONSUMES
+ gEfiNetworkPkgTokenSpaceGuid.PcdHttpIoTimeout ## CONSUMES
+ gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpResumeRetries ## CONSUMES
+ gEfiNetworkPkgTokenSpaceGuid.PcdHttpDelayBetweenResumeRetries ## CONSUMES
[UserExtensions.TianoCore."ExtraFiles"]
HttpBootDxeExtra.uni
diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c index b4c6192..91e934c 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c @@ -77,11 +77,19 @@ HttpBootUninstallCallback ( IN HTTP_BOOT_PRIVATE_DATA *Private
)
{
+ EFI_HANDLE ControllerHandle;
+
if (Private->HttpBootCallback == &Private->LoadFileCallback) {
+ if (!Private->UsingIpv6) {
+ ControllerHandle = Private->Ip4Nic->Controller;
+ } else {
+ ControllerHandle = Private->Ip6Nic->Controller;
+ }
+
gBS->UninstallProtocolInterface (
- Private->Controller,
+ ControllerHandle,
&gEfiHttpBootCallbackProtocolGuid,
- &Private->HttpBootCallback
+ Private->HttpBootCallback
);
Private->HttpBootCallback = NULL;
}
@@ -275,6 +283,148 @@ HttpBootDhcp ( }
/**
+ Issue calls to HttpBootGetBootFile() based on current Boot File State
+ @param[in] Private The pointer to the driver's private data.
+ @param[in, out] BufferSize On input the size of Buffer in bytes. On output with a return
+ code of EFI_SUCCESS, the amount of data transferred to
+ Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
+ the size of Buffer required to retrieve the requested file.
+ @param[in] Buffer The memory buffer to transfer the file to. If Buffer is NULL,
+ then the size of the requested file is returned in
+ BufferSize.
+ @param[out] ImageType The image type of the downloaded file.
+ @retval EFI_SUCCESS The file was loaded.
+ @retval EFI_INVALID_PARAMETER BufferSize is NULL or Buffer Size is not NULL but Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.
+ BufferSize has been updated with the size needed to complete
+ the request.
+ @retval EFI_ACCESS_DENIED Server authentication failed.
+ @retval Others Unexpected error happened.
+**/
+EFI_STATUS
+HttpBootGetBootFileCaller (
+ IN HTTP_BOOT_PRIVATE_DATA *Private,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer OPTIONAL,
+ OUT HTTP_BOOT_IMAGE_TYPE *ImageType
+ )
+{
+ HTTP_GET_BOOT_FILE_STATE State;
+ EFI_STATUS Status;
+ UINT32 Retries;
+
+ if (Private->BootFileSize == 0) {
+ State = GetBootFileHead;
+ } else {
+ State = LoadBootFile;
+ }
+
+ for ( ; ;) {
+ switch (State) {
+ case GetBootFileHead:
+ //
+ // Try to use HTTP HEAD method.
+ //
+ Status = HttpBootGetBootFile (
+ Private,
+ TRUE,
+ &Private->BootFileSize,
+ NULL,
+ &Private->ImageType
+ );
+ if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ if ((Private->AuthData != NULL) && (Status == EFI_ACCESS_DENIED)) {
+ //
+ // Try to use HTTP HEAD method again since the Authentication information is provided.
+ //
+ State = GetBootFileHead;
+ } else {
+ State = GetBootFileGet;
+ }
+ } else {
+ State = LoadBootFile;
+ }
+
+ break;
+
+ case GetBootFileGet:
+ //
+ // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
+ //
+ ASSERT (Private->BootFileSize == 0);
+ Status = HttpBootGetBootFile (
+ Private,
+ FALSE,
+ &Private->BootFileSize,
+ NULL,
+ &Private->ImageType
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ State = GetBootFileError;
+ } else {
+ State = LoadBootFile;
+ }
+
+ break;
+
+ case LoadBootFile:
+ if (*BufferSize < Private->BootFileSize) {
+ *BufferSize = Private->BootFileSize;
+ *ImageType = Private->ImageType;
+ Status = EFI_BUFFER_TOO_SMALL;
+ return Status;
+ }
+
+ //
+ // Load the boot file into Buffer
+ //
+ for (Retries = 1; Retries <= PcdGet32 (PcdMaxHttpResumeRetries); Retries++) {
+ Status = HttpBootGetBootFile (
+ Private,
+ FALSE,
+ BufferSize,
+ Buffer,
+ ImageType
+ );
+ if (!EFI_ERROR (Status) ||
+ ((Status != EFI_TIMEOUT) && (Status != EFI_DEVICE_ERROR)) ||
+ (Retries >= PcdGet32 (PcdMaxHttpResumeRetries)))
+ {
+ break;
+ }
+
+ //
+ // HttpBootGetBootFile returned EFI_TIMEOUT or EFI_DEVICE_ERROR.
+ // We may attempt to resume the interrupted download.
+ //
+
+ Private->HttpCreated = FALSE;
+ HttpIoDestroyIo (&Private->HttpIo);
+ Status = HttpBootCreateHttpIo (Private);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ DEBUG ((DEBUG_WARN | DEBUG_INFO, "HttpBootGetBootFileCaller: NBP file download interrupted, will try to resume the operation.\n"));
+ gBS->Stall (1000 * 1000 * PcdGet32 (PcdHttpDelayBetweenResumeRetries));
+ }
+
+ if (EFI_ERROR (Status) && (Retries >= PcdGet32 (PcdMaxHttpResumeRetries))) {
+ DEBUG ((DEBUG_ERROR, "HttpBootGetBootFileCaller: Error downloading NBP file, even after trying to resume %d times.\n", Retries));
+ }
+
+ return Status;
+
+ case GetBootFileError:
+ default:
+ AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n");
+ return Status;
+ }
+ }
+}
+
+/**
Attempt to download the boot file through HTTP message exchange.
@param[in] Private The pointer to the driver's private data.
@@ -345,68 +495,10 @@ HttpBootLoadFile ( }
}
- if (Private->BootFileSize == 0) {
- //
- // Discover the information about the bootfile if we haven't.
- //
-
- //
- // Try to use HTTP HEAD method.
- //
- Status = HttpBootGetBootFile (
- Private,
- TRUE,
- &Private->BootFileSize,
- NULL,
- &Private->ImageType
- );
- if ((Private->AuthData != NULL) && (Status == EFI_ACCESS_DENIED)) {
- //
- // Try to use HTTP HEAD method again since the Authentication information is provided.
- //
- Status = HttpBootGetBootFile (
- Private,
- TRUE,
- &Private->BootFileSize,
- NULL,
- &Private->ImageType
- );
- } else if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) {
- //
- // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
- //
- ASSERT (Private->BootFileSize == 0);
- Status = HttpBootGetBootFile (
- Private,
- FALSE,
- &Private->BootFileSize,
- NULL,
- &Private->ImageType
- );
- if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
- AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n");
- goto ON_EXIT;
- }
- }
- }
-
- if (*BufferSize < Private->BootFileSize) {
- *BufferSize = Private->BootFileSize;
- *ImageType = Private->ImageType;
- Status = EFI_BUFFER_TOO_SMALL;
- goto ON_EXIT;
- }
-
//
- // Load the boot file into Buffer
+ // Load the boot file
//
- Status = HttpBootGetBootFile (
- Private,
- FALSE,
- BufferSize,
- Buffer,
- ImageType
- );
+ Status = HttpBootGetBootFileCaller (Private, BufferSize, Buffer, ImageType);
ON_EXIT:
HttpBootUninstallCallback (Private);
@@ -467,12 +559,13 @@ HttpBootStop ( ZeroMem (&Private->StationIp, sizeof (EFI_IP_ADDRESS));
ZeroMem (&Private->SubnetMask, sizeof (EFI_IP_ADDRESS));
ZeroMem (&Private->GatewayIp, sizeof (EFI_IP_ADDRESS));
- Private->Port = 0;
- Private->BootFileUri = NULL;
- Private->BootFileUriParser = NULL;
- Private->BootFileSize = 0;
- Private->SelectIndex = 0;
- Private->SelectProxyType = HttpOfferTypeMax;
+ Private->Port = 0;
+ Private->BootFileUri = NULL;
+ Private->BootFileUriParser = NULL;
+ Private->BootFileSize = 0;
+ Private->SelectIndex = 0;
+ Private->SelectProxyType = HttpOfferTypeMax;
+ Private->PartialTransferredSize = 0;
if (!Private->UsingIpv6) {
//
@@ -522,6 +615,11 @@ HttpBootStop ( Private->FilePathUriParser = NULL;
}
+ if (Private->LastModifiedOrEtag != NULL) {
+ FreePool (Private->LastModifiedOrEtag);
+ Private->LastModifiedOrEtag = NULL;
+ }
+
ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer));
Private->OfferNum = 0;
ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));
@@ -710,7 +808,8 @@ HttpBootCallback ( if (Data != NULL) {
HttpMessage = (EFI_HTTP_MESSAGE *)Data;
if ((HttpMessage->Data.Request->Method == HttpMethodGet) &&
- (HttpMessage->Data.Request->Url != NULL))
+ (HttpMessage->Data.Request->Url != NULL) &&
+ (Private->PartialTransferredSize == 0))
{
Print (L"\n URI: %s\n", HttpMessage->Data.Request->Url);
}
@@ -742,6 +841,16 @@ HttpBootCallback ( }
}
+ // If download was resumed, do not change progress variables
+ HttpHeader = HttpFindHeader (
+ HttpMessage->HeaderCount,
+ HttpMessage->Headers,
+ HTTP_HEADER_CONTENT_RANGE
+ );
+ if (HttpHeader) {
+ break;
+ }
+
HttpHeader = HttpFindHeader (
HttpMessage->HeaderCount,
HttpMessage->Headers,
diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.h b/NetworkPkg/HttpBootDxe/HttpBootImpl.h index 55adc9c..33da4fe 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.h +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.h @@ -11,6 +11,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define HTTP_BOOT_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20)
+typedef enum {
+ GetBootFileHead,
+ GetBootFileGet,
+ LoadBootFile,
+ GetBootFileError
+} HTTP_GET_BOOT_FILE_STATE;
+
/**
Attempt to complete a DHCPv4 D.O.R.A or DHCPv6 S.R.A.A sequence to retrieve the boot resource information.
diff --git a/NetworkPkg/Include/Library/HttpLib.h b/NetworkPkg/Include/Library/HttpLib.h index f8505ab..a6894d3 100644 --- a/NetworkPkg/Include/Library/HttpLib.h +++ b/NetworkPkg/Include/Library/HttpLib.h @@ -444,6 +444,9 @@ HttpGenRequestMessage ( Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined
in UEFI 2.5 specification.
+ The official HTTP status codes can be found here:
+ https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+
@param[in] StatusCode The status code value in HTTP message.
@return Value defined in EFI_HTTP_STATUS_CODE .
diff --git a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c index 2181346..edb8f58 100644 --- a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c +++ b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c @@ -1927,6 +1927,11 @@ HttpGenRequestMessage ( CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength);
RequestPtr += StrLength;
break;
+ case HttpMethodConnect:
+ StrLength = sizeof (HTTP_METHOD_CONNECT) - 1;
+ CopyMem (RequestPtr, HTTP_METHOD_CONNECT, StrLength);
+ RequestPtr += StrLength;
+ break;
default:
ASSERT (FALSE);
Status = EFI_INVALID_PARAMETER;
@@ -1990,6 +1995,9 @@ Exit: Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined
in UEFI 2.5 specification.
+ The official HTTP status codes can be found here:
+ https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+
@param[in] StatusCode The status code value in HTTP message.
@return Value defined in EFI_HTTP_STATUS_CODE .
@@ -2072,6 +2080,8 @@ HttpMappingToStatusCode ( return HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED;
case 417:
return HTTP_STATUS_417_EXPECTATION_FAILED;
+ case 429:
+ return HTTP_STATUS_429_TOO_MANY_REQUESTS;
case 500:
return HTTP_STATUS_500_INTERNAL_SERVER_ERROR;
case 501:
diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c index 4dfbe91..cf875d7 100644 --- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c +++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c @@ -133,10 +133,16 @@ GLOBAL_REMOVE_IF_UNREFERENCED VLAN_DEVICE_PATH mNetVlanDevicePathTemplate = { // These represent UEFI SPEC defined algorithms that should be supported by
// the RNG protocol and are generally considered secure.
//
-// The order of the algorithms in this array is important. This order is the order
-// in which the algorithms will be tried by the RNG protocol.
-// If your platform needs to use a specific algorithm for the random number generator,
-// then you should place that algorithm first in the array.
+// Assuming that PcdEnforceSecureRngAlgorithms is TRUE (the default) then
+// only the algorithms defined here will be used by the network stack, and
+// none of these being available will result in an error condition (even if
+// some other RNG implementation is available).
+//
+// If PcdEnforceSecureRngAlgorithms is FALSE this list is not consulted,
+// and the first available RNG algorithm is used.
+//
+// If your platform needs to use a specific algorithm for the random number
+// generator, then you should modify this array.
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID *mSecureHashAlgorithms[] = {
&gEfiRngAlgorithmSp80090Ctr256Guid, // SP800-90A DRBG CTR using AES-256
diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf index a8f534a..54dcb97 100644 --- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf +++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf @@ -67,7 +67,7 @@ gEfiRngProtocolGuid ## CONSUMES
[FixedPcd]
- gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES
[Depex]
gEfiRngProtocolGuid
diff --git a/NetworkPkg/MnpDxe/MnpConfig.c b/NetworkPkg/MnpDxe/MnpConfig.c index 93587d5..d0e3f82 100644 --- a/NetworkPkg/MnpDxe/MnpConfig.c +++ b/NetworkPkg/MnpDxe/MnpConfig.c @@ -234,7 +234,7 @@ MnpAddFreeTxBuf ( break;
}
- DEBUG ((DEBUG_INFO, "MnpAddFreeTxBuf: Add TxBufWrap %p, TxBuf %p\n", TxBufWrap, TxBufWrap->TxBuf));
+ DEBUG ((DEBUG_VERBOSE, "MnpAddFreeTxBuf: Add TxBufWrap %p, TxBuf %p\n", TxBufWrap, TxBufWrap->TxBuf));
TxBufWrap->Signature = MNP_TX_BUF_WRAP_SIGNATURE;
TxBufWrap->InUse = FALSE;
InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry);
diff --git a/NetworkPkg/NetworkPcds.dsc.inc b/NetworkPkg/NetworkPcds.dsc.inc index f874b38..c6299ad 100644 --- a/NetworkPkg/NetworkPcds.dsc.inc +++ b/NetworkPkg/NetworkPcds.dsc.inc @@ -11,6 +11,6 @@ #
##
-!if $(NETWORK_ALLOW_HTTP_CONNECTIONS) == TRUE
+!if ($(NETWORK_ENABLE) == TRUE) AND ($(NETWORK_ALLOW_HTTP_CONNECTIONS) == TRUE)
gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|TRUE
!endif
diff --git a/NetworkPkg/NetworkPkg.ci.yaml b/NetworkPkg/NetworkPkg.ci.yaml index 076424e..5626e94 100644 --- a/NetworkPkg/NetworkPkg.ci.yaml +++ b/NetworkPkg/NetworkPkg.ci.yaml @@ -7,6 +7,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "NetworkPkg.dsc",
+ },
"LicenseCheck": {
"IgnoreFiles": []
},
diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec index 7c4289b..5db7aa1 100644 --- a/NetworkPkg/NetworkPkg.dec +++ b/NetworkPkg/NetworkPkg.dec @@ -104,6 +104,16 @@ # @Prompt Max size of total HTTP chunk transfer. the default value is 12MB.
gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpChunkTransfer|0x0C00000|UINT32|0x0000000E
+ ## The maximum number of retries while attempting to resume an
+ # interrupted HTTP download using a HTTP Range request header.
+ # @Prompt Max number of HTTP download resume retries. Default value is 5.
+ gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpResumeRetries|0x00000005|UINT32|0x00000012
+
+ ## Delay in seconds between each attempt to resume an
+ # interrupted HTTP download.
+ # @Prompt Delay in seconds between each HTTP resume retry. Default value is 2s.
+ gEfiNetworkPkgTokenSpaceGuid.PcdHttpDelayBetweenResumeRetries|0x00000002|UINT32|0x00000013
+
[PcdsFixedAtBuild, PcdsPatchableInModule]
## Indicates whether HTTP connections (i.e., unsecured) are permitted or not.
# TRUE - HTTP connections are allowed. Both the "https://" and "http://" URI schemes are permitted.
@@ -131,12 +141,6 @@ # @Prompt Indicates whether SnpDxe creates event for ExitBootServices() call.
gEfiNetworkPkgTokenSpaceGuid.PcdSnpCreateExitBootServicesEvent|TRUE|BOOLEAN|0x1000000C
- ## Enforces the use of Secure UEFI spec defined RNG algorithms for all network connections.
- # TRUE - Enforce the use of Secure UEFI spec defined RNG algorithms.
- # FALSE - Do not enforce and depend on the default implementation of RNG algorithm from the provider.
- # @Prompt Enforce the use of Secure UEFI spec defined RNG algorithms.
- gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms|TRUE|BOOLEAN|0x1000000D
-
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
## IPv6 DHCP Unique Identifier (DUID) Type configuration (From RFCs 3315 and 6355).
# 01 = DUID Based on Link-layer Address Plus Time [DUID-LLT]
diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index 808c6bf..f008790 100644 --- a/NetworkPkg/NetworkPkg.dsc +++ b/NetworkPkg/NetworkPkg.dsc @@ -62,6 +62,10 @@ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.UEFI_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -72,13 +76,6 @@ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
[LibraryClasses.ARM, LibraryClasses.AARCH64]
- #
- # It is not possible to prevent ARM compiler calls to generic intrinsic functions.
- # This library provides the instrinsic functions generated by a given compiler.
- # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
- #
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
[LibraryClasses.ARM]
diff --git a/NetworkPkg/SnpDxe/Reset.c b/NetworkPkg/SnpDxe/Reset.c index 2ff6853..72f3142 100644 --- a/NetworkPkg/SnpDxe/Reset.c +++ b/NetworkPkg/SnpDxe/Reset.c @@ -2,6 +2,7 @@ Implementation of resetting a network adapter.
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -93,10 +94,12 @@ SnpUndi32Reset ( EFI_STATUS Status;
//
- // Resolve Warning 4 unreferenced parameter problem
+ // There is no support when ExtendedVerification is set to FALSE.
//
- ExtendedVerification = 0;
- DEBUG ((DEBUG_WARN, "ExtendedVerification = %d is not implemented!\n", ExtendedVerification));
+ if (!ExtendedVerification) {
+ DEBUG ((DEBUG_WARN, "ExtendedVerification = %d is not implemented!\n", ExtendedVerification));
+ return EFI_INVALID_PARAMETER;
+ }
if (This == NULL) {
return EFI_INVALID_PARAMETER;
diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc index 1772afb..667be95 100644 --- a/NetworkPkg/Test/NetworkPkgHostTest.dsc +++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc @@ -83,21 +83,14 @@ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
+
[LibraryClasses.common.UEFI_APPLICATION]
DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
-[LibraryClasses.ARM, LibraryClasses.AARCH64]
- #
- # It is not possible to prevent ARM compiler calls to generic intrinsic functions.
- # This library provides the instrinsic functions generated by a given compiler.
- # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
- #
-!if $(TOOL_CHAIN_TAG) != VS2017 and $(TOOL_CHAIN_TAG) != VS2015 and $(TOOL_CHAIN_TAG) != VS2019
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-!endif
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
[LibraryClasses.ARM]
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
+
[LibraryClasses.RISCV64]
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp index 61736ff..e529bc6 100644 --- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp +++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp @@ -290,15 +290,9 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptUnderflowTest) { // Test Description
// Test that we can handle recursive dns (multiple dns entries)
TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) {
- EFI_DHCP6_PACKET_OPTION Option = { 0 };
+ EFI_DHCP6_PACKET_OPTION *Option = NULL;
PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL;
- Private.SelectIndex = 1; // SelectIndex is 1-based
- Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
- Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;
- // Setup the DHCPv6 offer packet
- Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
-
EFI_IPv6_ADDRESS addresses[2] = {
// 2001:db8:85a3::8a2e:370:7334
{ 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 },
@@ -306,7 +300,18 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) { { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x78, 0x91, 0xc3, 0xec, 0xd7, 0x4f, 0xf9 }
};
- CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, &addresses, sizeof (addresses));
+ Option = (EFI_DHCP6_PACKET_OPTION *)AllocatePool (sizeof (*Option) + sizeof (addresses));
+ if (Option == NULL) {
+ ASSERT_NE (Option, nullptr);
+ }
+
+ Private.SelectIndex = 1; // SelectIndex is 1-based
+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = Option;
+ // Setup the DHCPv6 offer packet
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
+
+ CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, addresses, sizeof (addresses));
Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (sizeof (addresses));
@@ -327,6 +332,10 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) { if (Private.DnsServer) {
FreePool (Private.DnsServer);
}
+
+ if (Option) {
+ FreePool (Option);
+ }
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c index f22a151..0af791d 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c @@ -1268,5 +1268,12 @@ ON_EXIT: AsciiPrint ("\n PXE-E99: Unexpected network error.\n");
}
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_ERROR_CODE,
+ (EFI_STATUS_CODE_VALUE)(EFI_IO_BUS_IP_NETWORK | EFI_OEM_SPECIFIC | ((EFI_STATUS_CODE_VALUE)(Status & 0x1F))),
+ (VOID *)&(PxeBcMode->UsingIpv6),
+ sizeof (PxeBcMode->UsingIpv6)
+ );
+
return Status;
}
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c index 0a4baf6..e296474 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c @@ -72,6 +72,13 @@ EfiPxeBcStart ( return EFI_UNSUPPORTED;
}
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_PROGRESS_CODE,
+ EFI_IO_BUS_IP_NETWORK | EFI_IOB_PC_RECONFIG,
+ (VOID *)&(Mode->UsingIpv6),
+ sizeof (Mode->UsingIpv6)
+ );
+
if (Mode->UsingIpv6) {
AsciiPrint ("\n>>Start PXE over IPv6");
//
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h index 732889f..cdb9b34 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h @@ -48,6 +48,7 @@ #include <Library/DpcLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PcdLib.h>
+#include <Library/ReportStatusCodeLib.h>
typedef struct _PXEBC_PRIVATE_DATA PXEBC_PRIVATE_DATA;
typedef struct _PXEBC_PRIVATE_PROTOCOL PXEBC_PRIVATE_PROTOCOL;
diff --git a/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf b/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf index 3371c15..d5aba13 100644 --- a/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf +++ b/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf @@ -62,6 +62,7 @@ DpcLib
DevicePathLib
PcdLib
+ ReportStatusCodeLib
[Protocols]
## TO_START
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c index f242bdf..00804e5 100644 --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c @@ -1490,6 +1490,7 @@ WifiMgrDxeHiiConfigAccessCallback ( } else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
switch (QuestionId) {
case KEY_EAP_ENROLL_CERT_FROM_FILE:
+ case KEY_REFRESH_NETWORK_LIST:
if (Private->CurrentNic->UserSelectedProfile == NULL) {
break;
@@ -1911,39 +1912,6 @@ WifiMgrDxeHiiConfigAccessCallback ( NULL
);
}
-
- if (Private->CurrentNic->UserSelectedProfile == NULL) {
- break;
- }
-
- Profile = Private->CurrentNic->UserSelectedProfile;
-
- //
- // Enter the network connection configuration page
- // Recovery from restored data
- //
- if (HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_SSID), Profile->SSId, NULL) == 0) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- IfrNvData->SecurityType = Profile->SecurityType;
- if (HiiSetString (
- Private->RegisteredHandle,
- STRING_TOKEN (STR_SECURITY_TYPE),
- mSecurityType[IfrNvData->SecurityType],
- NULL
- ) == 0)
- {
- return EFI_OUT_OF_RESOURCES;
- }
-
- if ( (IfrNvData->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE)
- || (IfrNvData->SecurityType == SECURITY_TYPE_WPA3_ENTERPRISE))
- {
- IfrNvData->EapAuthMethod = Profile->EapAuthMethod;
- IfrNvData->EapSecondAuthMethod = Profile->EapSecondAuthMethod;
- StrCpyS (IfrNvData->EapIdentity, EAP_IDENTITY_SIZE, Profile->EapIdentity);
- }
}
break;
|