X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FHttpDxe%2FHttpProto.c;h=5356cd35c0f3d972bf987aad0cc8d36ed61aa2a5;hb=728f8950d6aa5c050ee028eccaab47f0b3a06872;hp=2e784def4c01e7f4f6927f394e644b842c2ea9e6;hpb=12b96a93f3f4f6827242f83f108a8d9c209dc6d0;p=mirror_edk2.git diff --git a/NetworkPkg/HttpDxe/HttpProto.c b/NetworkPkg/HttpDxe/HttpProto.c index 2e784def4c..5356cd35c0 100644 --- a/NetworkPkg/HttpDxe/HttpProto.c +++ b/NetworkPkg/HttpDxe/HttpProto.c @@ -1,7 +1,7 @@ /** @file Miscellaneous routines for HttpDxe driver. -Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -16,7 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "HttpDriver.h" /** - The common notify function used in HTTP driver. + The common notify function used in HTTP driver. @param[in] Event The event signaled. @param[in] Context The context. @@ -54,10 +54,10 @@ HttpTcpTransmitNotifyDpc ( if (Context == NULL) { return ; } - + Wrap = (HTTP_TOKEN_WRAP *) Context; HttpInstance = Wrap->HttpInstance; - + if (!HttpInstance->LocalAddressIsIPv6) { Wrap->HttpToken->Status = Wrap->TcpWrap.Tx4Token.CompletionToken.Status; gBS->SignalEvent (Wrap->HttpToken->Event); @@ -72,11 +72,11 @@ HttpTcpTransmitNotifyDpc ( if (Wrap->TcpWrap.Tx4Token.CompletionToken.Event != NULL) { gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event); } - + } else { Wrap->HttpToken->Status = Wrap->TcpWrap.Tx6Token.CompletionToken.Status; gBS->SignalEvent (Wrap->HttpToken->Event); - + // // Free resources. // @@ -86,7 +86,7 @@ HttpTcpTransmitNotifyDpc ( if (Wrap->TcpWrap.Tx6Token.CompletionToken.Event != NULL) { gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event); - } + } } @@ -145,11 +145,11 @@ HttpTcpReceiveNotifyDpc ( Wrap = (HTTP_TOKEN_WRAP *) Context; HttpInstance = Wrap->HttpInstance; UsingIpv6 = HttpInstance->LocalAddressIsIPv6; - + if (UsingIpv6) { gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event); Wrap->TcpWrap.Rx6Token.CompletionToken.Event = NULL; - + if (EFI_ERROR (Wrap->TcpWrap.Rx6Token.CompletionToken.Status)) { DEBUG ((EFI_D_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx6Token.CompletionToken.Status)); Wrap->HttpToken->Status = Wrap->TcpWrap.Rx6Token.CompletionToken.Status; @@ -159,30 +159,30 @@ HttpTcpReceiveNotifyDpc ( if (Item != NULL) { NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL); } - + FreePool (Wrap); Wrap = NULL; - + return ; } } else { gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event); Wrap->TcpWrap.Rx4Token.CompletionToken.Event = NULL; - + if (EFI_ERROR (Wrap->TcpWrap.Rx4Token.CompletionToken.Status)) { DEBUG ((EFI_D_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx4Token.CompletionToken.Status)); Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status; gBS->SignalEvent (Wrap->HttpToken->Event); - + Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken); if (Item != NULL) { NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL); } - + FreePool (Wrap); Wrap = NULL; - + return ; } } @@ -220,7 +220,7 @@ HttpTcpReceiveNotifyDpc ( // We receive part of header of next HTTP msg. // if (HttpInstance->NextMsg != NULL) { - Wrap->HttpToken->Message->BodyLength = HttpInstance->NextMsg - + Wrap->HttpToken->Message->BodyLength = HttpInstance->NextMsg - (CHAR8 *) Wrap->HttpToken->Message->Body; HttpInstance->CacheLen = Length - Wrap->HttpToken->Message->BodyLength; if (HttpInstance->CacheLen != 0) { @@ -246,7 +246,7 @@ HttpTcpReceiveNotifyDpc ( } else { Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status; } - + gBS->SignalEvent (Wrap->HttpToken->Event); @@ -323,7 +323,7 @@ HttpCreateTcpConnCloseEvent ( if (EFI_ERROR (Status)) { goto ERROR; } - + } else { // // Create events for variuos asynchronous operations. @@ -353,7 +353,7 @@ HttpCreateTcpConnCloseEvent ( goto ERROR; } } - + return EFI_SUCCESS; ERROR: @@ -401,7 +401,7 @@ HttpCloseTcpConnCloseEvent ( HttpInstance->Tcp4CloseToken.CompletionToken.Event = NULL; } } - + } /** @@ -436,7 +436,7 @@ HttpCreateTcpTxEvent ( if (EFI_ERROR (Status)) { return Status; } - + TcpWrap->Tx4Data.Push = TRUE; TcpWrap->Tx4Data.Urgent = FALSE; TcpWrap->Tx4Data.FragmentCount = 1; @@ -460,9 +460,9 @@ HttpCreateTcpTxEvent ( TcpWrap->Tx6Data.FragmentCount = 1; TcpWrap->Tx6Token.Packet.TxData = &Wrap->TcpWrap.Tx6Data; TcpWrap->Tx6Token.CompletionToken.Status =EFI_NOT_READY; - + } - + return EFI_SUCCESS; } @@ -493,7 +493,7 @@ HttpCreateTcpRxEventForHeader ( if (EFI_ERROR (Status)) { return Status; } - + HttpInstance->Rx4Data.FragmentCount = 1; HttpInstance->Rx4Token.Packet.RxData = &HttpInstance->Rx4Data; HttpInstance->Rx4Token.CompletionToken.Status = EFI_NOT_READY; @@ -513,7 +513,7 @@ HttpCreateTcpRxEventForHeader ( HttpInstance->Rx6Data.FragmentCount =1; HttpInstance->Rx6Token.Packet.RxData = &HttpInstance->Rx6Data; HttpInstance->Rx6Token.CompletionToken.Status = EFI_NOT_READY; - + } @@ -531,7 +531,7 @@ HttpCreateTcpRxEventForHeader ( **/ EFI_STATUS HttpCreateTcpRxEvent ( - IN HTTP_TOKEN_WRAP *Wrap + IN HTTP_TOKEN_WRAP *Wrap ) { EFI_STATUS Status; @@ -551,7 +551,7 @@ HttpCreateTcpRxEvent ( if (EFI_ERROR (Status)) { return Status; } - + TcpWrap->Rx4Data.FragmentCount = 1; TcpWrap->Rx4Token.Packet.RxData = &Wrap->TcpWrap.Rx4Data; TcpWrap->Rx4Token.CompletionToken.Status = EFI_NOT_READY; @@ -563,7 +563,7 @@ HttpCreateTcpRxEvent ( HttpTcpReceiveNotify, Wrap, &TcpWrap->Rx6Token.CompletionToken.Event - ); + ); if (EFI_ERROR (Status)) { return Status; } @@ -572,7 +572,7 @@ HttpCreateTcpRxEvent ( TcpWrap->Rx6Token.Packet.RxData = &Wrap->TcpWrap.Rx6Data; TcpWrap->Rx6Token.CompletionToken.Status = EFI_NOT_READY; } - + return EFI_SUCCESS; } @@ -580,7 +580,7 @@ HttpCreateTcpRxEvent ( Close Events for Tcp Receive Tokens for HTTP body and HTTP header. @param[in] Wrap Pointer to HTTP token's wrap data. - + **/ VOID HttpCloseTcpRxEvent ( @@ -591,7 +591,7 @@ HttpCloseTcpRxEvent ( ASSERT (Wrap != NULL); HttpInstance = Wrap->HttpInstance; - + if (HttpInstance->LocalAddressIsIPv6) { if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) { gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event); @@ -605,7 +605,7 @@ HttpCloseTcpRxEvent ( if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) { gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event); } - + if (HttpInstance->Rx4Token.CompletionToken.Event != NULL) { gBS->CloseEvent (HttpInstance->Rx4Token.CompletionToken.Event); HttpInstance->Rx4Token.CompletionToken.Event = NULL; @@ -619,7 +619,7 @@ HttpCloseTcpRxEvent ( @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. @param[in] IpVersion Indicate us TCP4 protocol or TCP6 protocol. - @retval EFI_SUCCESS HTTP_PROTOCOL structure is initialized successfully. + @retval EFI_SUCCESS HTTP_PROTOCOL structure is initialized successfully. @retval Others Other error as indicated. **/ @@ -632,17 +632,17 @@ HttpInitProtocol ( EFI_STATUS Status; VOID *Interface; BOOLEAN UsingIpv6; - + ASSERT (HttpInstance != NULL); UsingIpv6 = IpVersion; - + if (!UsingIpv6) { // // Create TCP4 child. // Status = NetLibCreateServiceChild ( HttpInstance->Service->ControllerHandle, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, &gEfiTcp4ServiceBindingProtocolGuid, &HttpInstance->Tcp4ChildHandle ); @@ -655,11 +655,11 @@ HttpInitProtocol ( HttpInstance->Tcp4ChildHandle, &gEfiTcp4ProtocolGuid, (VOID **) &Interface, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, HttpInstance->Service->ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER ); - + if (EFI_ERROR (Status)) { goto ON_ERROR; } @@ -668,7 +668,7 @@ HttpInitProtocol ( HttpInstance->Tcp4ChildHandle, &gEfiTcp4ProtocolGuid, (VOID **) &HttpInstance->Tcp4, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, HttpInstance->Handle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); @@ -680,7 +680,7 @@ HttpInitProtocol ( HttpInstance->Service->Tcp4ChildHandle, &gEfiTcp4ProtocolGuid, (VOID **) &Interface, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, HttpInstance->Handle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); @@ -693,7 +693,7 @@ HttpInitProtocol ( // Status = NetLibCreateServiceChild ( HttpInstance->Service->ControllerHandle, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, &gEfiTcp6ServiceBindingProtocolGuid, &HttpInstance->Tcp6ChildHandle ); @@ -706,11 +706,11 @@ HttpInitProtocol ( HttpInstance->Tcp6ChildHandle, &gEfiTcp6ProtocolGuid, (VOID **) &Interface, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, HttpInstance->Service->ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER ); - + if (EFI_ERROR (Status)) { goto ON_ERROR; } @@ -719,20 +719,20 @@ HttpInitProtocol ( HttpInstance->Tcp6ChildHandle, &gEfiTcp6ProtocolGuid, (VOID **) &HttpInstance->Tcp6, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, HttpInstance->Handle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); - + if (EFI_ERROR(Status)) { goto ON_ERROR; - } + } Status = gBS->OpenProtocol ( HttpInstance->Service->Tcp6ChildHandle, &gEfiTcp6ProtocolGuid, (VOID **) &Interface, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, HttpInstance->Handle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); @@ -741,7 +741,7 @@ HttpInitProtocol ( goto ON_ERROR; } } - + HttpInstance->Url = AllocateZeroPool (HTTP_URL_BUFFER_LEN); if (HttpInstance->Url == NULL) { Status = EFI_OUT_OF_RESOURCES; @@ -751,73 +751,73 @@ HttpInitProtocol ( return EFI_SUCCESS; ON_ERROR: - + if (HttpInstance->Tcp4ChildHandle != NULL) { gBS->CloseProtocol ( HttpInstance->Tcp4ChildHandle, &gEfiTcp4ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, HttpInstance->Service->ControllerHandle ); gBS->CloseProtocol ( HttpInstance->Tcp4ChildHandle, &gEfiTcp4ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, HttpInstance->Handle - ); - + ); + NetLibDestroyServiceChild ( HttpInstance->Service->ControllerHandle, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, &gEfiTcp4ServiceBindingProtocolGuid, HttpInstance->Tcp4ChildHandle ); } - + if (HttpInstance->Service->Tcp4ChildHandle != NULL) { gBS->CloseProtocol ( HttpInstance->Service->Tcp4ChildHandle, &gEfiTcp4ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, HttpInstance->Handle ); } - + if (HttpInstance->Tcp6ChildHandle != NULL) { gBS->CloseProtocol ( HttpInstance->Tcp6ChildHandle, &gEfiTcp6ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, HttpInstance->Service->ControllerHandle ); gBS->CloseProtocol ( HttpInstance->Tcp6ChildHandle, &gEfiTcp6ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, HttpInstance->Handle ); - + NetLibDestroyServiceChild ( HttpInstance->Service->ControllerHandle, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, &gEfiTcp6ServiceBindingProtocolGuid, HttpInstance->Tcp6ChildHandle ); } - + if (HttpInstance->Service->Tcp6ChildHandle != NULL) { gBS->CloseProtocol ( HttpInstance->Service->Tcp6ChildHandle, &gEfiTcp6ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, HttpInstance->Handle ); } return EFI_UNSUPPORTED; - + } /** @@ -832,7 +832,7 @@ HttpCleanProtocol ( ) { HttpCloseConnection (HttpInstance); - + HttpCloseTcpConnCloseEvent (HttpInstance); if (HttpInstance->TimeoutEvent != NULL) { @@ -855,33 +855,40 @@ HttpCleanProtocol ( HttpFreeMsgParser (HttpInstance->MsgParser); HttpInstance->MsgParser = NULL; } - + if (HttpInstance->Url != NULL) { FreePool (HttpInstance->Url); HttpInstance->Url = NULL; } - + NetMapClean (&HttpInstance->TxTokens); NetMapClean (&HttpInstance->RxTokens); + if (HttpInstance->TlsSb != NULL && HttpInstance->TlsChildHandle != NULL) { + // + // Destroy the TLS instance. + // + HttpInstance->TlsSb->DestroyChild (HttpInstance->TlsSb, HttpInstance->TlsChildHandle); + } + if (HttpInstance->Tcp4ChildHandle != NULL) { gBS->CloseProtocol ( HttpInstance->Tcp4ChildHandle, &gEfiTcp4ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, HttpInstance->Service->ControllerHandle ); gBS->CloseProtocol ( HttpInstance->Tcp4ChildHandle, &gEfiTcp4ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, HttpInstance->Handle ); - + NetLibDestroyServiceChild ( HttpInstance->Service->ControllerHandle, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, &gEfiTcp4ServiceBindingProtocolGuid, HttpInstance->Tcp4ChildHandle ); @@ -891,44 +898,44 @@ HttpCleanProtocol ( gBS->CloseProtocol ( HttpInstance->Service->Tcp4ChildHandle, &gEfiTcp4ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip4DriverBindingHandle, HttpInstance->Handle ); - } + } if (HttpInstance->Tcp6ChildHandle != NULL) { gBS->CloseProtocol ( HttpInstance->Tcp6ChildHandle, &gEfiTcp6ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, HttpInstance->Service->ControllerHandle ); gBS->CloseProtocol ( HttpInstance->Tcp6ChildHandle, &gEfiTcp6ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, HttpInstance->Handle ); - + NetLibDestroyServiceChild ( HttpInstance->Service->ControllerHandle, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, &gEfiTcp6ServiceBindingProtocolGuid, HttpInstance->Tcp6ChildHandle ); } - + if (HttpInstance->Service->Tcp6ChildHandle != NULL) { gBS->CloseProtocol ( HttpInstance->Service->Tcp6ChildHandle, &gEfiTcp6ProtocolGuid, - HttpInstance->Service->ImageHandle, + HttpInstance->Service->Ip6DriverBindingHandle, HttpInstance->Handle ); } - TlsCloseTxRxEvent (HttpInstance); + TlsCloseTxRxEvent (HttpInstance); } /** @@ -958,13 +965,13 @@ HttpCreateConnection ( DEBUG ((EFI_D_ERROR, "HttpCreateConnection: Tcp4->Connect() = %r\n", Status)); return Status; } - + while (!HttpInstance->IsTcp4ConnDone) { HttpInstance->Tcp4->Poll (HttpInstance->Tcp4); } - + Status = HttpInstance->Tcp4ConnToken.CompletionToken.Status; - + } else { HttpInstance->IsTcp6ConnDone = FALSE; HttpInstance->Tcp6ConnToken.CompletionToken.Status = EFI_NOT_READY; @@ -978,9 +985,9 @@ HttpCreateConnection ( HttpInstance->Tcp6->Poll (HttpInstance->Tcp6); } - Status = HttpInstance->Tcp6ConnToken.CompletionToken.Status; + Status = HttpInstance->Tcp6ConnToken.CompletionToken.Status; } - + if (!EFI_ERROR (Status)) { HttpInstance->State = HTTP_STATE_TCP_CONNECTED; } @@ -1017,7 +1024,7 @@ HttpCloseConnection ( while (!HttpInstance->IsTcp6CloseDone) { HttpInstance->Tcp6->Poll (HttpInstance->Tcp6); } - + } else { HttpInstance->Tcp4CloseToken.AbortOnClose = TRUE; HttpInstance->IsTcp4CloseDone = FALSE; @@ -1063,7 +1070,7 @@ HttpConfigureTcp4 ( Tcp4CfgData = &HttpInstance->Tcp4CfgData; ZeroMem (Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA)); - + Tcp4CfgData->TypeOfService = HTTP_TOS_DEAULT; Tcp4CfgData->TimeToLive = HTTP_TTL_DEAULT; Tcp4CfgData->ControlOption = &HttpInstance->Tcp4Option; @@ -1074,7 +1081,7 @@ HttpConfigureTcp4 ( IP4_COPY_ADDRESS (&Tcp4AP->StationAddress, &HttpInstance->IPv4Node.LocalAddress); IP4_COPY_ADDRESS (&Tcp4AP->SubnetMask, &HttpInstance->IPv4Node.LocalSubnet); } - + Tcp4AP->StationPort = HttpInstance->IPv4Node.LocalPort; Tcp4AP->RemotePort = HttpInstance->RemotePort; Tcp4AP->ActiveFlag = TRUE; @@ -1134,16 +1141,16 @@ HttpConfigureTcp6 ( EFI_TCP6_CONFIG_DATA *Tcp6CfgData; EFI_TCP6_ACCESS_POINT *Tcp6Ap; EFI_TCP6_OPTION *Tcp6Option; - + ASSERT (HttpInstance != NULL); - + Tcp6CfgData = &HttpInstance->Tcp6CfgData; ZeroMem (Tcp6CfgData, sizeof (EFI_TCP6_CONFIG_DATA)); Tcp6CfgData->TrafficClass = 0; Tcp6CfgData->HopLimit = 255; Tcp6CfgData->ControlOption = &HttpInstance->Tcp6Option; - + Tcp6Ap = &Tcp6CfgData->AccessPoint; Tcp6Ap->ActiveFlag = TRUE; Tcp6Ap->StationPort = HttpInstance->Ipv6Node.LocalPort; @@ -1168,7 +1175,7 @@ HttpConfigureTcp6 ( DEBUG ((EFI_D_ERROR, "HttpConfigureTcp6 - %r\n", Status)); return Status; } - + Status = HttpCreateTcpConnCloseEvent (HttpInstance); if (EFI_ERROR (Status)) { return Status; @@ -1182,11 +1189,11 @@ HttpConfigureTcp6 ( HttpInstance->State = HTTP_STATE_TCP_CONFIGED; return EFI_SUCCESS; - + } /** - Check existing TCP connection, if in error state, recover TCP4 connection. Then, + Check existing TCP connection, if in error state, recover TCP4 connection. Then, connect one TLS session if required. @param[in] HttpInstance The HTTP instance private data. @@ -1210,8 +1217,8 @@ HttpConnectTcp4 ( } Status = HttpInstance->Tcp4->GetModeData( - HttpInstance->Tcp4, - &Tcp4State, + HttpInstance->Tcp4, + &Tcp4State, NULL, NULL, NULL, @@ -1233,7 +1240,7 @@ HttpConnectTcp4 ( DEBUG ((EFI_D_ERROR, "Tcp4 Connection fail - %x\n", Status)); return Status; } - + // // Tls session connection. // @@ -1263,11 +1270,11 @@ HttpConnectTcp4 ( TlsCloseTxRxEvent (HttpInstance); return Status; } - + Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent); gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0); - + if (EFI_ERROR (Status)) { TlsCloseTxRxEvent (HttpInstance); return Status; @@ -1278,7 +1285,7 @@ HttpConnectTcp4 ( } /** - Check existing TCP connection, if in error state, recover TCP6 connection. Then, + Check existing TCP connection, if in error state, recover TCP6 connection. Then, connect one TLS session if required. @param[in] HttpInstance The HTTP instance private data. @@ -1308,7 +1315,7 @@ HttpConnectTcp6 ( NULL, NULL ); - + if (EFI_ERROR(Status)){ DEBUG ((EFI_D_ERROR, "Tcp6 GetModeData fail - %x\n", Status)); return Status; @@ -1325,7 +1332,7 @@ HttpConnectTcp6 ( DEBUG ((EFI_D_ERROR, "Tcp6 Connection fail - %x\n", Status)); return Status; } - + // // Tls session connection. // @@ -1355,11 +1362,11 @@ HttpConnectTcp6 ( TlsCloseTxRxEvent (HttpInstance); return Status; } - + Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent); gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0); - + if (EFI_ERROR (Status)) { TlsCloseTxRxEvent (HttpInstance); return Status; @@ -1377,7 +1384,7 @@ HttpConnectTcp6 ( @param[in] Configure The Flag indicates whether need to initialize session. @param[in] TlsConfigure The Flag indicates whether it's the new Tls session. - @retval EFI_SUCCESS The initialization of session is done. + @retval EFI_SUCCESS The initialization of session is done. @retval Others Other error as indicated. **/ @@ -1439,9 +1446,9 @@ HttpInitSession ( return Status; } } - + return EFI_SUCCESS; - + } /** @@ -1469,99 +1476,152 @@ HttpTransmitTcp ( EFI_TCP4_PROTOCOL *Tcp4; EFI_TCP6_IO_TOKEN *Tx6Token; EFI_TCP6_PROTOCOL *Tcp6; - UINT8 *Buffer; - UINTN BufferSize; + UINT8 *TlsRecord; + UINT16 PayloadSize; NET_FRAGMENT TempFragment; + NET_FRAGMENT Fragment; + UINTN RecordCount; + UINTN RemainingLen; Status = EFI_SUCCESS; - Buffer = NULL; + TlsRecord = NULL; + PayloadSize = 0; TempFragment.Len = 0; TempFragment.Bulk = NULL; + Fragment.Len = 0; + Fragment.Bulk = NULL; + RecordCount = 0; + RemainingLen = 0; // // Need to encrypt data. // if (HttpInstance->UseHttps) { // - // Build BufferOut data + // Allocate enough buffer for each TLS plaintext records. // - BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen; - Buffer = AllocateZeroPool (BufferSize); - if (Buffer == NULL) { + TlsRecord = AllocateZeroPool (TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH); + if (TlsRecord == NULL) { Status = EFI_OUT_OF_RESOURCES; return Status; } - ((TLS_RECORD_HEADER *) Buffer)->ContentType = TLS_CONTENT_TYPE_APPLICATION_DATA; - ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance->TlsConfigData.Version.Major; - ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor; - ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen); - CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen); - + // - // Encrypt Packet. + // Allocate enough buffer for all TLS ciphertext records. // - Status = TlsProcessMessage ( - HttpInstance, - Buffer, - BufferSize, - EfiTlsEncrypt, - &TempFragment - ); - - FreePool (Buffer); + RecordCount = TxStringLen / TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH + 1; + Fragment.Bulk = AllocateZeroPool (RecordCount * (TLS_RECORD_HEADER_LENGTH + TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH)); + if (Fragment.Bulk == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_ERROR; + } - if (EFI_ERROR (Status)) { - return Status; + // + // Encrypt each TLS plaintext records. + // + RemainingLen = TxStringLen; + while (RemainingLen != 0) { + PayloadSize = (UINT16) MIN (TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH, RemainingLen); + + ((TLS_RECORD_HEADER *) TlsRecord)->ContentType = TlsContentTypeApplicationData; + ((TLS_RECORD_HEADER *) TlsRecord)->Version.Major = HttpInstance->TlsConfigData.Version.Major; + ((TLS_RECORD_HEADER *) TlsRecord)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor; + ((TLS_RECORD_HEADER *) TlsRecord)->Length = PayloadSize; + + CopyMem (TlsRecord + TLS_RECORD_HEADER_LENGTH, TxString + (TxStringLen - RemainingLen), PayloadSize); + + Status = TlsProcessMessage ( + HttpInstance, + TlsRecord, + TLS_RECORD_HEADER_LENGTH + PayloadSize, + EfiTlsEncrypt, + &TempFragment + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + // + // Record the processed/encrypted Packet. + // + CopyMem (Fragment.Bulk + Fragment.Len, TempFragment.Bulk, TempFragment.Len); + Fragment.Len += TempFragment.Len; + + FreePool (TempFragment.Bulk); + TempFragment.Len = 0; + TempFragment.Bulk = NULL; + + RemainingLen -= (UINTN) PayloadSize; + ZeroMem (TlsRecord, TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH); } + + FreePool (TlsRecord); + TlsRecord = NULL; } - + if (!HttpInstance->LocalAddressIsIPv6) { Tcp4 = HttpInstance->Tcp4; Tx4Token = &Wrap->TcpWrap.Tx4Token; if (HttpInstance->UseHttps) { - Tx4Token->Packet.TxData->DataLength = TempFragment.Len; - Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len; - Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk; + Tx4Token->Packet.TxData->DataLength = Fragment.Len; + Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len; + Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) Fragment.Bulk; } else { Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen; Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen; Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString; } - - Tx4Token->CompletionToken.Status = EFI_NOT_READY; - + + Tx4Token->CompletionToken.Status = EFI_NOT_READY; + Wrap->TcpWrap.IsTxDone = FALSE; Status = Tcp4->Transmit (Tcp4, Tx4Token); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status)); - return Status; + goto ON_ERROR; } } else { Tcp6 = HttpInstance->Tcp6; Tx6Token = &Wrap->TcpWrap.Tx6Token; - + if (HttpInstance->UseHttps) { - Tx6Token->Packet.TxData->DataLength = TempFragment.Len; - Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len; - Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk; + Tx6Token->Packet.TxData->DataLength = Fragment.Len; + Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len; + Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) Fragment.Bulk; } else { Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen; Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen; Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString; } - + Tx6Token->CompletionToken.Status = EFI_NOT_READY; Wrap->TcpWrap.IsTxDone = FALSE; Status = Tcp6->Transmit (Tcp6, Tx6Token); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status)); - return Status; + goto ON_ERROR; } } - + + return Status; + +ON_ERROR: + + if (HttpInstance->UseHttps) { + if (TlsRecord != NULL) { + FreePool (TlsRecord); + TlsRecord = NULL; + } + + if (Fragment.Bulk != NULL) { + FreePool (Fragment.Bulk); + Fragment.Bulk = NULL; + } + } + return Status; } @@ -1626,7 +1686,7 @@ HttpTcpNotReady ( if (!ValueInItem->TcpWrap.IsTxDone) { return EFI_NOT_READY; } - + return EFI_SUCCESS; } @@ -1738,8 +1798,8 @@ HttpTcpReceive ( @param[in, out] SizeofHeaders The HTTP header length. @param[in, out] BufferSize The size of buffer to cacahe the header message. @param[in] Timeout The time to wait for receiving the header packet. - - @retval EFI_SUCCESS The HTTP header is received. + + @retval EFI_SUCCESS The HTTP header is received. @retval Others Other errors as indicated. **/ @@ -1772,7 +1832,7 @@ HttpTcpReceiveHeader ( Rx6Token = NULL; Fragment.Len = 0; Fragment.Bulk = NULL; - + if (HttpInstance->LocalAddressIsIPv6) { ASSERT (Tcp6 != NULL); } else { @@ -1795,7 +1855,7 @@ HttpTcpReceiveHeader ( return Status; } } - + // // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL. // @@ -1827,7 +1887,7 @@ HttpTcpReceiveHeader ( if (EFI_ERROR (Status)) { return Status; } - + Fragment.Len = Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength; Fragment.Bulk = (UINT8 *) Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer; } else { @@ -1835,7 +1895,7 @@ HttpTcpReceiveHeader ( FreePool (Fragment.Bulk); Fragment.Bulk = NULL; } - + Status = HttpsReceive (HttpInstance, &Fragment, Timeout); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status)); @@ -1869,9 +1929,9 @@ HttpTcpReceiveHeader ( // // Check whether we received end of HTTP headers. // - *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR); + *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR); }; - + // // Free the buffer. // @@ -1884,7 +1944,7 @@ HttpTcpReceiveHeader ( if (Fragment.Bulk != NULL) { FreePool (Fragment.Bulk); Fragment.Bulk = NULL; - } + } } else { if (!HttpInstance->UseHttps) { Rx6Token = &HttpInstance->Rx6Token; @@ -1894,7 +1954,7 @@ HttpTcpReceiveHeader ( return Status; } } - + // // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL. // @@ -1926,7 +1986,7 @@ HttpTcpReceiveHeader ( if (EFI_ERROR (Status)) { return Status; } - + Fragment.Len = Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength; Fragment.Bulk = (UINT8 *) Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer; } else { @@ -1934,7 +1994,7 @@ HttpTcpReceiveHeader ( FreePool (Fragment.Bulk); Fragment.Bulk = NULL; } - + Status = HttpsReceive (HttpInstance, &Fragment, Timeout); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status)); @@ -1968,7 +2028,7 @@ HttpTcpReceiveHeader ( // // Check whether we received end of HTTP headers. // - *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR); + *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR); }; // @@ -1984,12 +2044,14 @@ HttpTcpReceiveHeader ( FreePool (Fragment.Bulk); Fragment.Bulk = NULL; } - } + } // // Skip the CRLF after the HTTP headers. // - *EndofHeader = *EndofHeader + AsciiStrLen (HTTP_END_OF_HDR_STR); + *EndofHeader = *EndofHeader + AsciiStrLen (HTTP_END_OF_HDR_STR); + + *SizeofHeaders = *EndofHeader - *HttpHeaders; return EFI_SUCCESS; } @@ -2000,7 +2062,7 @@ HttpTcpReceiveHeader ( @param[in] Wrap The HTTP token's wrap data. @param[in] HttpMsg The HTTP message data. - @retval EFI_SUCCESS The HTTP body is received. + @retval EFI_SUCCESS The HTTP body is received. @retval Others Other error as indicated. **/ @@ -2016,23 +2078,23 @@ HttpTcpReceiveBody ( EFI_TCP6_IO_TOKEN *Rx6Token; EFI_TCP4_PROTOCOL *Tcp4; EFI_TCP4_IO_TOKEN *Rx4Token; - + HttpInstance = Wrap->HttpInstance; Tcp4 = HttpInstance->Tcp4; Tcp6 = HttpInstance->Tcp6; Rx4Token = NULL; Rx6Token = NULL; - + if (HttpInstance->LocalAddressIsIPv6) { ASSERT (Tcp6 != NULL); } else { ASSERT (Tcp4 != NULL); } - + if (HttpInstance->LocalAddressIsIPv6) { Rx6Token = &Wrap->TcpWrap.Rx6Token; - Rx6Token ->Packet.RxData->DataLength = (UINT32) HttpMsg->BodyLength; - Rx6Token ->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) HttpMsg->BodyLength; + Rx6Token ->Packet.RxData->DataLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength); + Rx6Token ->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength); Rx6Token ->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *) HttpMsg->Body; Rx6Token->CompletionToken.Status = EFI_NOT_READY; @@ -2043,10 +2105,10 @@ HttpTcpReceiveBody ( } } else { Rx4Token = &Wrap->TcpWrap.Rx4Token; - Rx4Token->Packet.RxData->DataLength = (UINT32) HttpMsg->BodyLength; - Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) HttpMsg->BodyLength; + Rx4Token->Packet.RxData->DataLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength); + Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength); Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *) HttpMsg->Body; - + Rx4Token->CompletionToken.Status = EFI_NOT_READY; Status = Tcp4->Receive (Tcp4, Rx4Token); if (EFI_ERROR (Status)) { @@ -2063,13 +2125,13 @@ HttpTcpReceiveBody ( Clean up Tcp Tokens while the Tcp transmission error occurs. @param[in] Wrap Pointer to HTTP token's wrap data. - + **/ VOID HttpTcpTokenCleanup ( IN HTTP_TOKEN_WRAP *Wrap ) -{ +{ HTTP_PROTOCOL *HttpInstance; EFI_TCP4_IO_TOKEN *Rx4Token; EFI_TCP6_IO_TOKEN *Rx6Token; @@ -2078,10 +2140,10 @@ HttpTcpTokenCleanup ( HttpInstance = Wrap->HttpInstance; Rx4Token = NULL; Rx6Token = NULL; - + if (HttpInstance->LocalAddressIsIPv6) { Rx6Token = &Wrap->TcpWrap.Rx6Token; - + if (Rx6Token->CompletionToken.Event != NULL) { gBS->CloseEvent (Rx6Token->CompletionToken.Event); Rx6Token->CompletionToken.Event = NULL; @@ -2090,25 +2152,25 @@ HttpTcpTokenCleanup ( FreePool (Wrap); Rx6Token = &HttpInstance->Rx6Token; - + if (Rx6Token->CompletionToken.Event != NULL) { gBS->CloseEvent (Rx6Token->CompletionToken.Event); Rx6Token->CompletionToken.Event = NULL; } - + if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) { FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer); Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL; } - + } else { Rx4Token = &Wrap->TcpWrap.Rx4Token; - + if (Rx4Token->CompletionToken.Event != NULL) { gBS->CloseEvent (Rx4Token->CompletionToken.Event); Rx4Token->CompletionToken.Event = NULL; } - + FreePool (Wrap); Rx4Token = &HttpInstance->Rx4Token; @@ -2117,8 +2179,8 @@ HttpTcpTokenCleanup ( gBS->CloseEvent (Rx4Token->CompletionToken.Event); Rx4Token->CompletionToken.Event = NULL; } - - + + if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) { FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer); Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;