mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-28 16:14:04 +02:00
MdeModulePkg: Delete Tcp4Dxe in MdeModulePkg.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1278 This patch is to delete the Tcp4Dxe driver in MdeModulePkg. The driver will not be maintained and can't co-work with the dual-stack TcpDxe in NetworkPkg. People should use below NetworkPkg drivers instead: NetworkPkg/TcpDxe/TcpDxe.inf Which is actively maintained with more bug fixes and new feature support. Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Hao Wu <hao.a.wu@intel.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Jiaxin Wu <jiaxin.wu@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Siyuan Fu <siyuan.fu@intel.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
This commit is contained in:
parent
41203b9ab5
commit
376a5dbe97
@ -359,7 +359,6 @@
|
|||||||
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
|
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
|
||||||
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
|
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
|
||||||
MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
|
MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
|
||||||
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
|
|
||||||
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
|
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
|
||||||
|
|
||||||
MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf
|
MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf
|
||||||
|
@ -1,433 +0,0 @@
|
|||||||
/** @file
|
|
||||||
UEFI Component Name(2) protocol implementation for Tcp4Dxe driver.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "Tcp4Main.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
Retrieves a Unicode string that is the user readable name of the driver.
|
|
||||||
|
|
||||||
This function retrieves the user readable name of a driver in the form of a
|
|
||||||
Unicode string. If the driver specified by This has a user readable name in
|
|
||||||
the language specified by Language, then a pointer to the driver name is
|
|
||||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
|
||||||
by This does not support the language specified by Language,
|
|
||||||
then EFI_UNSUPPORTED is returned.
|
|
||||||
|
|
||||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
|
||||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
|
||||||
|
|
||||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
|
||||||
array indicating the language. This is the
|
|
||||||
language of the driver name that the caller is
|
|
||||||
requesting, and it must match one of the
|
|
||||||
languages specified in SupportedLanguages. The
|
|
||||||
number of languages supported by a driver is up
|
|
||||||
to the driver writer. Language is specified
|
|
||||||
in RFC 4646 or ISO 639-2 language code format.
|
|
||||||
|
|
||||||
@param[out] DriverName A pointer to the Unicode string to return.
|
|
||||||
This Unicode string is the name of the
|
|
||||||
driver specified by This in the language
|
|
||||||
specified by Language.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
|
||||||
This and the language specified by Language was
|
|
||||||
returned in DriverName.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
|
||||||
|
|
||||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
|
||||||
the language specified by Language.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
TcpComponentNameGetDriverName (
|
|
||||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
|
||||||
IN CHAR8 *Language,
|
|
||||||
OUT CHAR16 **DriverName
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Retrieves a Unicode string that is the user readable name of the controller
|
|
||||||
that is being managed by a driver.
|
|
||||||
|
|
||||||
This function retrieves the user readable name of the controller specified by
|
|
||||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
|
||||||
driver specified by This has a user readable name in the language specified by
|
|
||||||
Language, then a pointer to the controller name is returned in ControllerName,
|
|
||||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
|
||||||
managing the controller specified by ControllerHandle and ChildHandle,
|
|
||||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
|
||||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
|
||||||
|
|
||||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
|
||||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
|
||||||
|
|
||||||
@param[in] ControllerHandle The handle of a controller that the driver
|
|
||||||
specified by This is managing. This handle
|
|
||||||
specifies the controller whose name is to be
|
|
||||||
returned.
|
|
||||||
|
|
||||||
@param[in] ChildHandle The handle of the child controller to retrieve
|
|
||||||
the name of. This is an optional parameter that
|
|
||||||
may be NULL. It will be NULL for device
|
|
||||||
drivers. It will also be NULL for a bus drivers
|
|
||||||
that wish to retrieve the name of the bus
|
|
||||||
controller. It will not be NULL for a bus
|
|
||||||
driver that wishes to retrieve the name of a
|
|
||||||
child controller.
|
|
||||||
|
|
||||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
|
||||||
array indicating the language. This is the
|
|
||||||
language of the driver name that the caller is
|
|
||||||
requesting, and it must match one of the
|
|
||||||
languages specified in SupportedLanguages. The
|
|
||||||
number of languages supported by a driver is up
|
|
||||||
to the driver writer. Language is specified in
|
|
||||||
RFC 4646 or ISO 639-2 language code format.
|
|
||||||
|
|
||||||
@param[out] ControllerName A pointer to the Unicode string to return.
|
|
||||||
This Unicode string is the name of the
|
|
||||||
controller specified by ControllerHandle and
|
|
||||||
ChildHandle in the language specified by
|
|
||||||
Language from the point of view of the driver
|
|
||||||
specified by This.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The Unicode string for the user readable name in
|
|
||||||
the language specified by Language for the
|
|
||||||
driver specified by This was returned in
|
|
||||||
DriverName.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
|
|
||||||
EFI_HANDLE.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
|
||||||
|
|
||||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
|
||||||
managing the controller specified by
|
|
||||||
ControllerHandle and ChildHandle.
|
|
||||||
|
|
||||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
|
||||||
the language specified by Language.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
TcpComponentNameGetControllerName (
|
|
||||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
|
||||||
IN CHAR8 *Language,
|
|
||||||
OUT CHAR16 **ControllerName
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// EFI Component Name Protocol
|
|
||||||
///
|
|
||||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName = {
|
|
||||||
TcpComponentNameGetDriverName,
|
|
||||||
TcpComponentNameGetControllerName,
|
|
||||||
"eng"
|
|
||||||
};
|
|
||||||
|
|
||||||
///
|
|
||||||
/// EFI Component Name 2 Protocol
|
|
||||||
///
|
|
||||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gTcp4ComponentName2 = {
|
|
||||||
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) TcpComponentNameGetDriverName,
|
|
||||||
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) TcpComponentNameGetControllerName,
|
|
||||||
"en"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mTcpDriverNameTable[] = {
|
|
||||||
{
|
|
||||||
"eng;en",
|
|
||||||
L"Tcp Network Service Driver"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable = NULL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Retrieves a Unicode string that is the user readable name of the driver.
|
|
||||||
|
|
||||||
This function retrieves the user readable name of a driver in the form of a
|
|
||||||
Unicode string. If the driver specified by This has a user readable name in
|
|
||||||
the language specified by Language, then a pointer to the driver name is
|
|
||||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
|
||||||
by This does not support the language specified by Language,
|
|
||||||
then EFI_UNSUPPORTED is returned.
|
|
||||||
|
|
||||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
|
||||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
|
||||||
|
|
||||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
|
||||||
array indicating the language. This is the
|
|
||||||
language of the driver name that the caller is
|
|
||||||
requesting, and it must match one of the
|
|
||||||
languages specified in SupportedLanguages. The
|
|
||||||
number of languages supported by a driver is up
|
|
||||||
to the driver writer. Language is specified
|
|
||||||
in RFC 4646 or ISO 639-2 language code format.
|
|
||||||
|
|
||||||
@param[out] DriverName A pointer to the Unicode string to return.
|
|
||||||
This Unicode string is the name of the
|
|
||||||
driver specified by This in the language
|
|
||||||
specified by Language.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
|
||||||
This and the language specified by Language was
|
|
||||||
returned in DriverName.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
|
||||||
|
|
||||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
|
||||||
the language specified by Language.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
TcpComponentNameGetDriverName (
|
|
||||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
|
||||||
IN CHAR8 *Language,
|
|
||||||
OUT CHAR16 **DriverName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return LookupUnicodeString2 (
|
|
||||||
Language,
|
|
||||||
This->SupportedLanguages,
|
|
||||||
mTcpDriverNameTable,
|
|
||||||
DriverName,
|
|
||||||
(BOOLEAN) (This == &gTcp4ComponentName)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Update the component name for the Tcp4 child handle.
|
|
||||||
|
|
||||||
@param Tcp4[in] A pointer to the EFI_TCP4_PROTOCOL.
|
|
||||||
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
|
|
||||||
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
UpdateName (
|
|
||||||
IN EFI_TCP4_PROTOCOL *Tcp4
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
CHAR16 HandleName[80];
|
|
||||||
EFI_TCP4_CONFIG_DATA Tcp4ConfigData;
|
|
||||||
|
|
||||||
if (Tcp4 == NULL) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Format the child name into the string buffer as:
|
|
||||||
// TCPv4 (SrcPort=59, DestPort=60, ActiveFlag=TRUE)
|
|
||||||
//
|
|
||||||
ZeroMem (&Tcp4ConfigData, sizeof (Tcp4ConfigData));
|
|
||||||
Status = Tcp4->GetModeData (Tcp4, NULL, &Tcp4ConfigData, NULL, NULL, NULL);
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
UnicodeSPrint (HandleName, sizeof (HandleName),
|
|
||||||
L"TCPv4 (SrcPort=%d, DestPort=%d, ActiveFlag=%s)",
|
|
||||||
Tcp4ConfigData.AccessPoint.StationPort,
|
|
||||||
Tcp4ConfigData.AccessPoint.RemotePort,
|
|
||||||
(Tcp4ConfigData.AccessPoint.ActiveFlag ? L"TRUE" : L"FALSE")
|
|
||||||
);
|
|
||||||
} else if (Status == EFI_NOT_STARTED) {
|
|
||||||
UnicodeSPrint (
|
|
||||||
HandleName,
|
|
||||||
sizeof (HandleName),
|
|
||||||
L"TCPv4 (Not started)"
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gTcpControllerNameTable != NULL) {
|
|
||||||
FreeUnicodeStringTable (gTcpControllerNameTable);
|
|
||||||
gTcpControllerNameTable = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = AddUnicodeString2 (
|
|
||||||
"eng",
|
|
||||||
gTcp4ComponentName.SupportedLanguages,
|
|
||||||
&gTcpControllerNameTable,
|
|
||||||
HandleName,
|
|
||||||
TRUE
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return AddUnicodeString2 (
|
|
||||||
"en",
|
|
||||||
gTcp4ComponentName2.SupportedLanguages,
|
|
||||||
&gTcpControllerNameTable,
|
|
||||||
HandleName,
|
|
||||||
FALSE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Retrieves a Unicode string that is the user readable name of the controller
|
|
||||||
that is being managed by a driver.
|
|
||||||
|
|
||||||
This function retrieves the user readable name of the controller specified by
|
|
||||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
|
||||||
driver specified by This has a user readable name in the language specified by
|
|
||||||
Language, then a pointer to the controller name is returned in ControllerName,
|
|
||||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
|
||||||
managing the controller specified by ControllerHandle and ChildHandle,
|
|
||||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
|
||||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
|
||||||
|
|
||||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
|
||||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
|
||||||
|
|
||||||
@param[in] ControllerHandle The handle of a controller that the driver
|
|
||||||
specified by This is managing. This handle
|
|
||||||
specifies the controller whose name is to be
|
|
||||||
returned.
|
|
||||||
|
|
||||||
@param[in] ChildHandle The handle of the child controller to retrieve
|
|
||||||
the name of. This is an optional parameter that
|
|
||||||
may be NULL. It will be NULL for device
|
|
||||||
drivers. It will also be NULL for a bus drivers
|
|
||||||
that wish to retrieve the name of the bus
|
|
||||||
controller. It will not be NULL for a bus
|
|
||||||
driver that wishes to retrieve the name of a
|
|
||||||
child controller.
|
|
||||||
|
|
||||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
|
||||||
array indicating the language. This is the
|
|
||||||
language of the driver name that the caller is
|
|
||||||
requesting, and it must match one of the
|
|
||||||
languages specified in SupportedLanguages. The
|
|
||||||
number of languages supported by a driver is up
|
|
||||||
to the driver writer. Language is specified in
|
|
||||||
RFC 4646 or ISO 639-2 language code format.
|
|
||||||
|
|
||||||
@param[out] ControllerName A pointer to the Unicode string to return.
|
|
||||||
This Unicode string is the name of the
|
|
||||||
controller specified by ControllerHandle and
|
|
||||||
ChildHandle in the language specified by
|
|
||||||
Language from the point of view of the driver
|
|
||||||
specified by This.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The Unicode string for the user readable name in
|
|
||||||
the language specified by Language for the
|
|
||||||
driver specified by This was returned in
|
|
||||||
DriverName.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
|
|
||||||
EFI_HANDLE.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
|
||||||
|
|
||||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
|
||||||
managing the controller specified by
|
|
||||||
ControllerHandle and ChildHandle.
|
|
||||||
|
|
||||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
|
||||||
the language specified by Language.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
TcpComponentNameGetControllerName (
|
|
||||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
|
||||||
IN CHAR8 *Language,
|
|
||||||
OUT CHAR16 **ControllerName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_TCP4_PROTOCOL *Tcp4;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Only provide names for child handles.
|
|
||||||
//
|
|
||||||
if (ChildHandle == NULL) {
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Make sure this driver produced ChildHandle
|
|
||||||
//
|
|
||||||
Status = EfiTestChildHandle (
|
|
||||||
ControllerHandle,
|
|
||||||
ChildHandle,
|
|
||||||
&gEfiIp4ProtocolGuid
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Retrieve an instance of a produced protocol from ChildHandle
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
ChildHandle,
|
|
||||||
&gEfiTcp4ProtocolGuid,
|
|
||||||
(VOID **)&Tcp4,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Update the component name for this child handle.
|
|
||||||
//
|
|
||||||
Status = UpdateName (Tcp4);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return LookupUnicodeString2 (
|
|
||||||
Language,
|
|
||||||
This->SupportedLanguages,
|
|
||||||
gTcpControllerNameTable,
|
|
||||||
ControllerName,
|
|
||||||
(BOOLEAN)(This == &gTcp4ComponentName)
|
|
||||||
);
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,131 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Socket implementation header file.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#ifndef _SOCK_IMPL_H_
|
|
||||||
#define _SOCK_IMPL_H_
|
|
||||||
|
|
||||||
#include "Socket.h"
|
|
||||||
#include "Tcp4Main.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
Signal a event with the given status.
|
|
||||||
|
|
||||||
@param Token The token's event is to be signaled.
|
|
||||||
@param TokenStatus The status to be sent with the event.
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SIGNAL_TOKEN(Token, TokenStatus) \
|
|
||||||
do { \
|
|
||||||
(Token)->Status = (TokenStatus); \
|
|
||||||
gBS->SignalEvent ((Token)->Event); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Supporting function for both SockImpl and SockInterface.
|
|
||||||
|
|
||||||
@param Event The Event this notify function registered to, ignored.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
SockFreeFoo (
|
|
||||||
IN EFI_EVENT Event
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Process the TCP send data, buffer the tcp txdata and append
|
|
||||||
the buffer to socket send buffer,then try to send it.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket.
|
|
||||||
@param TcpTxData Pointer to the tcp txdata.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The operation is completed successfully.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockProcessTcpSndData (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *TcpTxData
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Copy data from socket buffer to application provided receive buffer.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket.
|
|
||||||
@param TcpRxData Pointer to the application provided receive buffer.
|
|
||||||
@param RcvdBytes The maximum length of the data can be copied.
|
|
||||||
@param IsOOB If TRUE the data is OOB, else the data is normal.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SockSetTcpRxData (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *TcpRxData,
|
|
||||||
IN UINT32 RcvdBytes,
|
|
||||||
IN BOOLEAN IsOOB
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get received data from the socket layer to the receive token.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket.
|
|
||||||
@param RcvToken Pointer to the application provided receive token.
|
|
||||||
|
|
||||||
@return The length of data received in this token.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT32
|
|
||||||
SockProcessRcvToken (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN OUT SOCK_IO_TOKEN *RcvToken
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Flush the socket.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SockConnFlush (
|
|
||||||
IN OUT SOCKET *Sock
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create a socket with initial data SockInitData.
|
|
||||||
|
|
||||||
@param SockInitData Pointer to the initial data of the socket.
|
|
||||||
|
|
||||||
@return Pointer to the newly created socket.
|
|
||||||
|
|
||||||
**/
|
|
||||||
SOCKET *
|
|
||||||
SockCreate (
|
|
||||||
IN SOCK_INIT_DATA *SockInitData
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Destroy a socket.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SockDestroy (
|
|
||||||
IN OUT SOCKET *Sock
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,990 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Interface function of the Socket.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SockImpl.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the Event is in the List.
|
|
||||||
|
|
||||||
@param List Pointer to the token list to be searched.
|
|
||||||
@param Event The event to be checked.
|
|
||||||
|
|
||||||
@retval TRUE The specific Event exists in the List.
|
|
||||||
@retval FALSE The specific Event is not in the List.
|
|
||||||
|
|
||||||
**/
|
|
||||||
BOOLEAN
|
|
||||||
SockTokenExistedInList (
|
|
||||||
IN LIST_ENTRY *List,
|
|
||||||
IN EFI_EVENT Event
|
|
||||||
)
|
|
||||||
{
|
|
||||||
LIST_ENTRY *ListEntry;
|
|
||||||
SOCK_TOKEN *SockToken;
|
|
||||||
|
|
||||||
NET_LIST_FOR_EACH (ListEntry, List) {
|
|
||||||
SockToken = NET_LIST_USER_STRUCT (
|
|
||||||
ListEntry,
|
|
||||||
SOCK_TOKEN,
|
|
||||||
TokenList
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Event == SockToken->Token->Event) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Call SockTokenExistedInList() to check whether the Event is
|
|
||||||
in the related socket's lists.
|
|
||||||
|
|
||||||
@param Sock Pointer to the instance's socket.
|
|
||||||
@param Event The event to be checked.
|
|
||||||
|
|
||||||
@retval TRUE The Event exists in related socket's lists.
|
|
||||||
@retval FALSE The Event is not in related socket's lists.
|
|
||||||
|
|
||||||
**/
|
|
||||||
BOOLEAN
|
|
||||||
SockTokenExisted (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN EFI_EVENT Event
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (SockTokenExistedInList (&Sock->SndTokenList, Event) ||
|
|
||||||
SockTokenExistedInList (&Sock->ProcessingSndTokenList, Event) ||
|
|
||||||
SockTokenExistedInList (&Sock->RcvTokenList, Event) ||
|
|
||||||
SockTokenExistedInList (&Sock->ListenTokenList, Event)) {
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((Sock->ConnectionToken != NULL) &&
|
|
||||||
(Sock->ConnectionToken->Event == Event)) {
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((Sock->CloseToken != NULL) && (Sock->CloseToken->Event == Event)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Buffer a token into the specific list of socket Sock.
|
|
||||||
|
|
||||||
@param Sock Pointer to the instance's socket.
|
|
||||||
@param List Pointer to the list to store the token.
|
|
||||||
@param Token Pointer to the token to be buffered.
|
|
||||||
@param DataLen The data length of the buffer contained in Token.
|
|
||||||
|
|
||||||
@return Pointer to the token that wraps Token. If NULL, error condition occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
SOCK_TOKEN *
|
|
||||||
SockBufferToken (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN LIST_ENTRY *List,
|
|
||||||
IN VOID *Token,
|
|
||||||
IN UINT32 DataLen
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCK_TOKEN *SockToken;
|
|
||||||
|
|
||||||
SockToken = AllocatePool (sizeof (SOCK_TOKEN));
|
|
||||||
if (NULL == SockToken) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockBufferIOToken: No Memory "
|
|
||||||
"to allocate SockToken\n"));
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
SockToken->Sock = Sock;
|
|
||||||
SockToken->Token = (SOCK_COMPLETION_TOKEN *) Token;
|
|
||||||
SockToken->RemainDataLen = DataLen;
|
|
||||||
InsertTailList (List, &SockToken->TokenList);
|
|
||||||
|
|
||||||
return SockToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Destroy the socket Sock and its associated protocol control block.
|
|
||||||
|
|
||||||
@param Sock The socket to be destroyed.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The socket Sock is destroyed successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockDestroyChild (
|
|
||||||
IN SOCKET *Sock
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
TCP4_PROTO_DATA *ProtoData;
|
|
||||||
TCP_CB *Tcb;
|
|
||||||
VOID *SockProtocol;
|
|
||||||
|
|
||||||
ASSERT ((Sock != NULL) && (Sock->ProtoHandler != NULL));
|
|
||||||
|
|
||||||
if (Sock->InDestroy) {
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock->InDestroy = TRUE;
|
|
||||||
|
|
||||||
ProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
|
||||||
Tcb = ProtoData->TcpPcb;
|
|
||||||
|
|
||||||
ASSERT (Tcb != NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Close the IP protocol.
|
|
||||||
//
|
|
||||||
gBS->CloseProtocol (
|
|
||||||
Tcb->IpInfo->ChildHandle,
|
|
||||||
&gEfiIp4ProtocolGuid,
|
|
||||||
ProtoData->TcpService->IpIo->Image,
|
|
||||||
Sock->SockHandle
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Sock->DestroyCallback != NULL) {
|
|
||||||
Sock->DestroyCallback (Sock, Sock->Context);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Retrieve the protocol installed on this sock
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
Sock->SockHandle,
|
|
||||||
&gEfiTcp4ProtocolGuid,
|
|
||||||
&SockProtocol,
|
|
||||||
Sock->DriverBinding,
|
|
||||||
Sock->SockHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
||||||
);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockDestroyChild: Open protocol installed "
|
|
||||||
"on socket failed with %r\n", Status));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Uninstall the protocol installed on this sock
|
|
||||||
// in the light of Sock->SockType
|
|
||||||
//
|
|
||||||
gBS->UninstallMultipleProtocolInterfaces (
|
|
||||||
Sock->SockHandle,
|
|
||||||
&gEfiTcp4ProtocolGuid,
|
|
||||||
SockProtocol,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
Status = EfiAcquireLockOrFail (&(Sock->Lock));
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockDestroyChild: Get the lock to "
|
|
||||||
"access socket failed with %r\n", Status));
|
|
||||||
|
|
||||||
return EFI_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// force protocol layer to detach the PCB
|
|
||||||
//
|
|
||||||
Status = Sock->ProtoHandler (Sock, SOCK_DETACH, NULL);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockDestroyChild: Protocol detach socket"
|
|
||||||
" failed with %r\n", Status));
|
|
||||||
|
|
||||||
Sock->InDestroy = FALSE;
|
|
||||||
} else if (SOCK_IS_CONFIGURED (Sock)) {
|
|
||||||
|
|
||||||
SockConnFlush (Sock);
|
|
||||||
SockSetState (Sock, SO_CLOSED);
|
|
||||||
|
|
||||||
Sock->ConfigureState = SO_UNCONFIGURED;
|
|
||||||
}
|
|
||||||
|
|
||||||
EfiReleaseLock (&(Sock->Lock));
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
SockDestroy (Sock);
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create a socket and its associated protocol control block
|
|
||||||
with the intial data SockInitData and protocol specific
|
|
||||||
data ProtoData.
|
|
||||||
|
|
||||||
@param SockInitData Inital data to setting the socket.
|
|
||||||
|
|
||||||
@return Pointer to the newly created socket. If NULL, error condition occured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
SOCKET *
|
|
||||||
SockCreateChild (
|
|
||||||
IN SOCK_INIT_DATA *SockInitData
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
VOID *SockProtocol;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
//
|
|
||||||
// create a new socket
|
|
||||||
//
|
|
||||||
Sock = SockCreate (SockInitData);
|
|
||||||
if (NULL == Sock) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockCreateChild: No resource to "
|
|
||||||
"create a new socket\n"));
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = EfiAcquireLockOrFail (&(Sock->Lock));
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockCreateChild: Get the lock to "
|
|
||||||
"access socket failed with %r\n", Status));
|
|
||||||
|
|
||||||
goto ERROR;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// inform the protocol layer to attach the socket
|
|
||||||
// with a new protocol control block
|
|
||||||
//
|
|
||||||
Status = Sock->ProtoHandler (Sock, SOCK_ATTACH, NULL);
|
|
||||||
EfiReleaseLock (&(Sock->Lock));
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockCreateChild: Protocol failed to"
|
|
||||||
" attach a socket with %r\n", Status));
|
|
||||||
|
|
||||||
goto ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Sock;
|
|
||||||
|
|
||||||
ERROR:
|
|
||||||
|
|
||||||
if (Sock->DestroyCallback != NULL) {
|
|
||||||
Sock->DestroyCallback (Sock, Sock->Context);
|
|
||||||
}
|
|
||||||
|
|
||||||
gBS->OpenProtocol (
|
|
||||||
Sock->SockHandle,
|
|
||||||
&gEfiTcp4ProtocolGuid,
|
|
||||||
&SockProtocol,
|
|
||||||
Sock->DriverBinding,
|
|
||||||
Sock->SockHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
||||||
);
|
|
||||||
//
|
|
||||||
// Uninstall the protocol installed on this sock
|
|
||||||
//
|
|
||||||
gBS->UninstallMultipleProtocolInterfaces (
|
|
||||||
Sock->SockHandle,
|
|
||||||
&gEfiTcp4ProtocolGuid,
|
|
||||||
SockProtocol,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
SockDestroy (Sock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Configure the specific socket Sock using configuration data ConfigData.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to be configured.
|
|
||||||
@param ConfigData Pointer to the configuration data.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The socket is configured successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket or the
|
|
||||||
socket is already configured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockConfigure (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *ConfigData
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
Status = EfiAcquireLockOrFail (&(Sock->Lock));
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockConfigure: Get the access for "
|
|
||||||
"socket failed with %r", Status));
|
|
||||||
|
|
||||||
return EFI_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_CONFIGURED (Sock)) {
|
|
||||||
Status = EFI_ACCESS_DENIED;
|
|
||||||
goto OnExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT (Sock->State == SO_CLOSED);
|
|
||||||
|
|
||||||
Status = Sock->ProtoHandler (Sock, SOCK_CONFIGURE, ConfigData);
|
|
||||||
|
|
||||||
OnExit:
|
|
||||||
EfiReleaseLock (&(Sock->Lock));
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initiate a connection establishment process.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to initiate the initate the
|
|
||||||
connection.
|
|
||||||
@param Token Pointer to the token used for the connection
|
|
||||||
operation.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The connection is initialized successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
|
||||||
socket is closed, or the socket is not configured to
|
|
||||||
be an active one, or the token is already in one of
|
|
||||||
this socket's lists.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockConnect (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *Token
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_EVENT Event;
|
|
||||||
|
|
||||||
Status = EfiAcquireLockOrFail (&(Sock->Lock));
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockConnect: Get the access for "
|
|
||||||
"socket failed with %r", Status));
|
|
||||||
|
|
||||||
return EFI_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
|
||||||
Status = EFI_NO_MAPPING;
|
|
||||||
goto OnExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
|
||||||
|
|
||||||
Status = EFI_NOT_STARTED;
|
|
||||||
goto OnExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SOCK_IS_CLOSED (Sock) || !SOCK_IS_CONFIGURED_ACTIVE (Sock)) {
|
|
||||||
|
|
||||||
Status = EFI_ACCESS_DENIED;
|
|
||||||
goto OnExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;
|
|
||||||
|
|
||||||
if (SockTokenExisted (Sock, Event)) {
|
|
||||||
|
|
||||||
Status = EFI_ACCESS_DENIED;
|
|
||||||
goto OnExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock->ConnectionToken = (SOCK_COMPLETION_TOKEN *) Token;
|
|
||||||
SockSetState (Sock, SO_CONNECTING);
|
|
||||||
Status = Sock->ProtoHandler (Sock, SOCK_CONNECT, NULL);
|
|
||||||
|
|
||||||
OnExit:
|
|
||||||
EfiReleaseLock (&(Sock->Lock));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Issue a listen token to get an existed connected network instance
|
|
||||||
or wait for a connection if there is none.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to accept connections.
|
|
||||||
@param Token The token to accept a connection.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Either a connection is accpeted or the Token is
|
|
||||||
buffered for further acception.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
|
||||||
socket is closed, or the socket is not configured to
|
|
||||||
be a passive one, or the token is already in one of
|
|
||||||
this socket's lists.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
@retval EFI_OUT_OF_RESOURCE Failed to buffer the Token due to memory limit.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockAccept (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *Token
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_TCP4_LISTEN_TOKEN *ListenToken;
|
|
||||||
LIST_ENTRY *ListEntry;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
SOCKET *Socket;
|
|
||||||
EFI_EVENT Event;
|
|
||||||
|
|
||||||
ASSERT (SockStream == Sock->Type);
|
|
||||||
|
|
||||||
Status = EfiAcquireLockOrFail (&(Sock->Lock));
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockAccept: Get the access for socket"
|
|
||||||
" failed with %r", Status));
|
|
||||||
|
|
||||||
return EFI_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
|
||||||
Status = EFI_NO_MAPPING;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
|
||||||
|
|
||||||
Status = EFI_NOT_STARTED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SOCK_IS_LISTENING (Sock)) {
|
|
||||||
|
|
||||||
Status = EFI_ACCESS_DENIED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;
|
|
||||||
|
|
||||||
if (SockTokenExisted (Sock, Event)) {
|
|
||||||
|
|
||||||
Status = EFI_ACCESS_DENIED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListenToken = (EFI_TCP4_LISTEN_TOKEN *) Token;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if a connection has already in this Sock->ConnectionList
|
|
||||||
//
|
|
||||||
NET_LIST_FOR_EACH (ListEntry, &Sock->ConnectionList) {
|
|
||||||
|
|
||||||
Socket = NET_LIST_USER_STRUCT (ListEntry, SOCKET, ConnectionList);
|
|
||||||
|
|
||||||
if (SOCK_IS_CONNECTED (Socket)) {
|
|
||||||
ListenToken->NewChildHandle = Socket->SockHandle;
|
|
||||||
SIGNAL_TOKEN (&(ListenToken->CompletionToken), EFI_SUCCESS);
|
|
||||||
|
|
||||||
RemoveEntryList (ListEntry);
|
|
||||||
|
|
||||||
ASSERT (Socket->Parent != NULL);
|
|
||||||
|
|
||||||
Socket->Parent->ConnCnt--;
|
|
||||||
|
|
||||||
DEBUG (
|
|
||||||
(EFI_D_NET,
|
|
||||||
"SockAccept: Accept a socket, now conncount is %d",
|
|
||||||
Socket->Parent->ConnCnt)
|
|
||||||
);
|
|
||||||
Socket->Parent = NULL;
|
|
||||||
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Buffer this token for latter incoming connection request
|
|
||||||
//
|
|
||||||
if (NULL == SockBufferToken (Sock, &(Sock->ListenTokenList), Token, 0)) {
|
|
||||||
|
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
EfiReleaseLock (&(Sock->Lock));
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Issue a token with data to the socket to send out.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to process the token with
|
|
||||||
data.
|
|
||||||
@param Token The token with data that needs to send out.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The token is processed successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
|
||||||
socket is closed, or the socket is not in a
|
|
||||||
synchronized state , or the token is already in one
|
|
||||||
of this socket's lists.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
@retval EFI_OUT_OF_RESOURCE Failed to buffer the token due to memory limit.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockSend (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *Token
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCK_IO_TOKEN *SndToken;
|
|
||||||
EFI_EVENT Event;
|
|
||||||
UINT32 FreeSpace;
|
|
||||||
EFI_TCP4_TRANSMIT_DATA *TxData;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
SOCK_TOKEN *SockToken;
|
|
||||||
UINT32 DataLen;
|
|
||||||
|
|
||||||
ASSERT (SockStream == Sock->Type);
|
|
||||||
|
|
||||||
Status = EfiAcquireLockOrFail (&(Sock->Lock));
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockSend: Get the access for socket"
|
|
||||||
" failed with %r", Status));
|
|
||||||
|
|
||||||
return EFI_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
|
||||||
Status = EFI_NO_MAPPING;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
SndToken = (SOCK_IO_TOKEN *) Token;
|
|
||||||
TxData = (EFI_TCP4_TRANSMIT_DATA *) SndToken->Packet.TxData;
|
|
||||||
|
|
||||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
|
||||||
Status = EFI_NOT_STARTED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(SOCK_IS_CONNECTING (Sock) || SOCK_IS_CONNECTED (Sock))) {
|
|
||||||
|
|
||||||
Status = EFI_ACCESS_DENIED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// check if a token is already in the token buffer
|
|
||||||
//
|
|
||||||
Event = SndToken->Token.Event;
|
|
||||||
|
|
||||||
if (SockTokenExisted (Sock, Event)) {
|
|
||||||
Status = EFI_ACCESS_DENIED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataLen = (UINT32) TxData->DataLength;
|
|
||||||
|
|
||||||
//
|
|
||||||
// process this sending token now or buffer it only?
|
|
||||||
//
|
|
||||||
FreeSpace = SockGetFreeSpace (Sock, SOCK_SND_BUF);
|
|
||||||
|
|
||||||
if ((FreeSpace < Sock->SndBuffer.LowWater) || !SOCK_IS_CONNECTED (Sock)) {
|
|
||||||
|
|
||||||
SockToken = SockBufferToken (
|
|
||||||
Sock,
|
|
||||||
&Sock->SndTokenList,
|
|
||||||
SndToken,
|
|
||||||
DataLen
|
|
||||||
);
|
|
||||||
|
|
||||||
if (NULL == SockToken) {
|
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
SockToken = SockBufferToken (
|
|
||||||
Sock,
|
|
||||||
&Sock->ProcessingSndTokenList,
|
|
||||||
SndToken,
|
|
||||||
DataLen
|
|
||||||
);
|
|
||||||
|
|
||||||
if (NULL == SockToken) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockSend: Failed to buffer IO token into"
|
|
||||||
" socket processing SndToken List\n", Status));
|
|
||||||
|
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = SockProcessTcpSndData (Sock, TxData);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockSend: Failed to process "
|
|
||||||
"Snd Data\n", Status));
|
|
||||||
|
|
||||||
RemoveEntryList (&(SockToken->TokenList));
|
|
||||||
FreePool (SockToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
EfiReleaseLock (&(Sock->Lock));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Issue a token to get data from the socket.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to get data from.
|
|
||||||
@param Token The token to store the received data from the
|
|
||||||
socket.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The token is processed successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
|
||||||
socket is closed, or the socket is not in a
|
|
||||||
synchronized state , or the token is already in one
|
|
||||||
of this socket's lists.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
@retval EFI_CONNECTION_FIN The connection is closed and there is no more data.
|
|
||||||
@retval EFI_OUT_OF_RESOURCE Failed to buffer the token due to memory limit.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockRcv (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *Token
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCK_IO_TOKEN *RcvToken;
|
|
||||||
UINT32 RcvdBytes;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_EVENT Event;
|
|
||||||
|
|
||||||
ASSERT (SockStream == Sock->Type);
|
|
||||||
|
|
||||||
Status = EfiAcquireLockOrFail (&(Sock->Lock));
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockRcv: Get the access for socket"
|
|
||||||
" failed with %r", Status));
|
|
||||||
|
|
||||||
return EFI_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
|
||||||
|
|
||||||
Status = EFI_NO_MAPPING;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
|
||||||
|
|
||||||
Status = EFI_NOT_STARTED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(SOCK_IS_CONNECTED (Sock) || SOCK_IS_CONNECTING (Sock))) {
|
|
||||||
|
|
||||||
Status = EFI_ACCESS_DENIED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
RcvToken = (SOCK_IO_TOKEN *) Token;
|
|
||||||
|
|
||||||
//
|
|
||||||
// check if a token is already in the token buffer of this socket
|
|
||||||
//
|
|
||||||
Event = RcvToken->Token.Event;
|
|
||||||
if (SockTokenExisted (Sock, Event)) {
|
|
||||||
Status = EFI_ACCESS_DENIED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
RcvToken = (SOCK_IO_TOKEN *) Token;
|
|
||||||
RcvdBytes = GET_RCV_DATASIZE (Sock);
|
|
||||||
|
|
||||||
//
|
|
||||||
// check whether an error has happened before
|
|
||||||
//
|
|
||||||
if (EFI_ABORTED != Sock->SockError) {
|
|
||||||
|
|
||||||
SIGNAL_TOKEN (&(RcvToken->Token), Sock->SockError);
|
|
||||||
Sock->SockError = EFI_ABORTED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// check whether can not receive and there is no any
|
|
||||||
// data buffered in Sock->RcvBuffer
|
|
||||||
//
|
|
||||||
if (SOCK_IS_NO_MORE_DATA (Sock) && (0 == RcvdBytes)) {
|
|
||||||
|
|
||||||
Status = EFI_CONNECTION_FIN;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RcvdBytes != 0) {
|
|
||||||
SockProcessRcvToken (Sock, RcvToken);
|
|
||||||
|
|
||||||
Status = Sock->ProtoHandler (Sock, SOCK_CONSUMED, NULL);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (NULL == SockBufferToken (Sock, &Sock->RcvTokenList, RcvToken, 0)) {
|
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
EfiReleaseLock (&(Sock->Lock));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Reset the socket and its associated protocol control block.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to be flushed.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The socket is flushed successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockFlush (
|
|
||||||
IN SOCKET *Sock
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
ASSERT (SockStream == Sock->Type);
|
|
||||||
|
|
||||||
Status = EfiAcquireLockOrFail (&(Sock->Lock));
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockFlush: Get the access for socket"
|
|
||||||
" failed with %r", Status));
|
|
||||||
|
|
||||||
return EFI_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SOCK_IS_CONFIGURED (Sock)) {
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = Sock->ProtoHandler (Sock, SOCK_FLUSH, NULL);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockFlush: Protocol failed handling"
|
|
||||||
" SOCK_FLUSH with %r", Status));
|
|
||||||
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
SOCK_ERROR (Sock, EFI_ABORTED);
|
|
||||||
SockConnFlush (Sock);
|
|
||||||
SockSetState (Sock, SO_CLOSED);
|
|
||||||
|
|
||||||
Sock->ConfigureState = SO_UNCONFIGURED;
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
EfiReleaseLock (&(Sock->Lock));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Close or abort the socket associated connection.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket of the connection to close or
|
|
||||||
abort.
|
|
||||||
@param Token The token for close operation.
|
|
||||||
@param OnAbort TRUE for aborting the connection, FALSE to close it.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The close or abort operation is initialized
|
|
||||||
successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
|
||||||
socket is closed, or the socket is not in a
|
|
||||||
synchronized state , or the token is already in one
|
|
||||||
of this socket's lists.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockClose (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *Token,
|
|
||||||
IN BOOLEAN OnAbort
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_EVENT Event;
|
|
||||||
|
|
||||||
ASSERT (SockStream == Sock->Type);
|
|
||||||
|
|
||||||
Status = EfiAcquireLockOrFail (&(Sock->Lock));
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockClose: Get the access for socket"
|
|
||||||
" failed with %r", Status));
|
|
||||||
|
|
||||||
return EFI_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
|
||||||
Status = EFI_NO_MAPPING;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
|
||||||
Status = EFI_NOT_STARTED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_DISCONNECTING (Sock)) {
|
|
||||||
Status = EFI_ACCESS_DENIED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;
|
|
||||||
|
|
||||||
if (SockTokenExisted (Sock, Event)) {
|
|
||||||
Status = EFI_ACCESS_DENIED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock->CloseToken = Token;
|
|
||||||
SockSetState (Sock, SO_DISCONNECTING);
|
|
||||||
|
|
||||||
if (OnAbort) {
|
|
||||||
Status = Sock->ProtoHandler (Sock, SOCK_ABORT, NULL);
|
|
||||||
} else {
|
|
||||||
Status = Sock->ProtoHandler (Sock, SOCK_CLOSE, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
EfiReleaseLock (&(Sock->Lock));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the mode data of the low layer protocol.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to get mode data from.
|
|
||||||
@param Mode Pointer to the data to store the low layer mode
|
|
||||||
information.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The mode data is got successfully.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockGetMode (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN OUT VOID *Mode
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return Sock->ProtoHandler (Sock, SOCK_MODE, Mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Add or remove route information in IP route table associated
|
|
||||||
with this socket.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket associated with the IP route
|
|
||||||
table to operate on.
|
|
||||||
@param RouteInfo Pointer to the route information to be processed.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The route table is updated successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockRoute (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *RouteInfo
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
Status = EfiAcquireLockOrFail (&(Sock->Lock));
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "SockRoute: Get the access for socket"
|
|
||||||
" failed with %r", Status));
|
|
||||||
|
|
||||||
return EFI_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
|
||||||
Status = EFI_NO_MAPPING;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
|
||||||
Status = EFI_NOT_STARTED;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = Sock->ProtoHandler (Sock, SOCK_ROUTE, RouteInfo);
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
EfiReleaseLock (&(Sock->Lock));
|
|
||||||
return Status;
|
|
||||||
}
|
|
@ -1,954 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Socket header file.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#ifndef _SOCKET_H_
|
|
||||||
#define _SOCKET_H_
|
|
||||||
|
|
||||||
#include <Uefi.h>
|
|
||||||
|
|
||||||
#include <Protocol/Ip4.h>
|
|
||||||
#include <Protocol/Tcp4.h>
|
|
||||||
#include <Protocol/Udp4.h>
|
|
||||||
|
|
||||||
#include <Library/NetLib.h>
|
|
||||||
#include <Library/DebugLib.h>
|
|
||||||
#include <Library/BaseMemoryLib.h>
|
|
||||||
#include <Library/MemoryAllocationLib.h>
|
|
||||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
|
||||||
#include <Library/UefiDriverEntryPoint.h>
|
|
||||||
#include <Library/UefiLib.h>
|
|
||||||
#include <Library/DpcLib.h>
|
|
||||||
#include <Library/PrintLib.h>
|
|
||||||
|
|
||||||
#define SOCK_SND_BUF 0
|
|
||||||
#define SOCK_RCV_BUF 1
|
|
||||||
|
|
||||||
#define SOCK_BUFF_LOW_WATER (2 * 1024)
|
|
||||||
#define SOCK_RCV_BUFF_SIZE (8 * 1024)
|
|
||||||
#define SOCK_SND_BUFF_SIZE (8 * 1024)
|
|
||||||
#define SOCK_BACKLOG 5
|
|
||||||
|
|
||||||
#define PROTO_RESERVED_LEN 20
|
|
||||||
|
|
||||||
#define SO_NO_MORE_DATA 0x0001
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// When a socket is created it enters into SO_UNCONFIGURED,
|
|
||||||
// no actions can be taken on this socket, only after calling
|
|
||||||
// SockConfigure. The state transition diagram of socket is
|
|
||||||
// as following:
|
|
||||||
//
|
|
||||||
// SO_UNCONFIGURED --- SO_CONFIGURED --- SO_CONNECTING
|
|
||||||
// ^ | |
|
|
||||||
// | ---> SO_LISTENING |
|
|
||||||
// | |
|
|
||||||
// |------------------SO_DISCONNECTING<-- SO_CONNECTED
|
|
||||||
//
|
|
||||||
// A passive socket can only go into SO_LISTENING and
|
|
||||||
// SO_UNCONFIGURED state. SO_XXXING state is a middle state
|
|
||||||
// when a socket is undergoing a protocol procedure such
|
|
||||||
// as requesting a TCP connection.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Socket state
|
|
||||||
///
|
|
||||||
#define SO_CLOSED 0
|
|
||||||
#define SO_LISTENING 1
|
|
||||||
#define SO_CONNECTING 2
|
|
||||||
#define SO_CONNECTED 3
|
|
||||||
#define SO_DISCONNECTING 4
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Socket configure state
|
|
||||||
///
|
|
||||||
#define SO_UNCONFIGURED 0
|
|
||||||
#define SO_CONFIGURED_ACTIVE 1
|
|
||||||
#define SO_CONFIGURED_PASSIVE 2
|
|
||||||
#define SO_NO_MAPPING 3
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set socket SO_NO_MORE_DATA flag.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_NO_MORE_DATA(Sock) ((Sock)->Flag |= SO_NO_MORE_DATA)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the socket is unconfigured.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@retval True The socket is unconfigued
|
|
||||||
@retval False The socket is not unconfigued
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_IS_UNCONFIGURED(Sock) ((Sock)->ConfigureState == SO_UNCONFIGURED)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the socket is configured.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@retval True The socket is configued
|
|
||||||
@retval False The socket is not configued
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_IS_CONFIGURED(Sock) \
|
|
||||||
(((Sock)->ConfigureState == SO_CONFIGURED_ACTIVE) || \
|
|
||||||
((Sock)->ConfigureState == SO_CONFIGURED_PASSIVE))
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the socket is configured to active mode.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@retval True The socket is configued to active mode
|
|
||||||
@retval False The socket is not configued to active mode
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_IS_CONFIGURED_ACTIVE(Sock) \
|
|
||||||
((Sock)->ConfigureState == SO_CONFIGURED_ACTIVE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the socket is configured to passive mode.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@retval True The socket is configued to passive mode
|
|
||||||
@retval False The socket is not configued to passive mode
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_IS_CONNECTED_PASSIVE(Sock) \
|
|
||||||
((Sock)->ConfigureState == SO_CONFIGURED_PASSIVE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the socket is mapped.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@retval True The socket is no mapping
|
|
||||||
@retval False The socket is mapped
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_IS_NO_MAPPING(Sock) \
|
|
||||||
((Sock)->ConfigureState == SO_NO_MAPPING)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the socket is closed.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@retval True The socket is closed
|
|
||||||
@retval False The socket is not closed
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_IS_CLOSED(Sock) ((Sock)->State == SO_CLOSED)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the socket is listening.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@retval True The socket is listening
|
|
||||||
@retval False The socket is not listening
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_IS_LISTENING(Sock) ((Sock)->State == SO_LISTENING)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the socket is connecting.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@retval True The socket is connecting
|
|
||||||
@retval False The socket is not connecting
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_IS_CONNECTING(Sock) ((Sock)->State == SO_CONNECTING)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the socket has connected.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@retval True The socket has connected
|
|
||||||
@retval False The socket has not connected
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_IS_CONNECTED(Sock) ((Sock)->State == SO_CONNECTED)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the socket is disconnecting.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@retval True The socket is disconnecting
|
|
||||||
@retval False The socket is not disconnecting
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_IS_DISCONNECTING(Sock) ((Sock)->State == SO_DISCONNECTING)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the socket is no more data.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@retval True The socket is no more data
|
|
||||||
@retval False The socket still has data
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_IS_NO_MORE_DATA(Sock) (0 != ((Sock)->Flag & SO_NO_MORE_DATA))
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set the size of the receive buffer.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
@param Size The size to set
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SET_RCV_BUFFSIZE(Sock, Size) ((Sock)->RcvBuffer.HighWater = (Size))
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the size of the receive buffer.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@return The receive buffer size
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define GET_RCV_BUFFSIZE(Sock) ((Sock)->RcvBuffer.HighWater)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the size of the receive data.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@return The received data size
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define GET_RCV_DATASIZE(Sock) (((Sock)->RcvBuffer.DataQueue)->BufSize)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set the size of the send buffer.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
@param Size The size to set
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SET_SND_BUFFSIZE(Sock, Size) ((Sock)->SndBuffer.HighWater = (Size))
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the size of the send buffer.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@return The send buffer size
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define GET_SND_BUFFSIZE(Sock) ((Sock)->SndBuffer.HighWater)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the size of the send data.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@return The send data size
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define GET_SND_DATASIZE(Sock) (((Sock)->SndBuffer.DataQueue)->BufSize)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set the backlog value of the socket.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
@param Value The value to set
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SET_BACKLOG(Sock, Value) ((Sock)->BackLog = (Value))
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the backlog value of the socket.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
|
|
||||||
@return The backlog value
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define GET_BACKLOG(Sock) ((Sock)->BackLog)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set the socket with error state.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket
|
|
||||||
@param Error The error state
|
|
||||||
|
|
||||||
**/
|
|
||||||
#define SOCK_ERROR(Sock, Error) ((Sock)->SockError = (Error))
|
|
||||||
|
|
||||||
#define SND_BUF_HDR_LEN(Sock) \
|
|
||||||
((SockBufFirst (&((Sock)->SndBuffer)))->TotalSize)
|
|
||||||
|
|
||||||
#define RCV_BUF_HDR_LEN(Sock) \
|
|
||||||
((SockBufFirst (&((Sock)->RcvBuffer)))->TotalSize)
|
|
||||||
|
|
||||||
#define SOCK_SIGNATURE SIGNATURE_32 ('S', 'O', 'C', 'K')
|
|
||||||
|
|
||||||
#define SOCK_FROM_THIS(a) CR ((a), SOCKET, NetProtocol, SOCK_SIGNATURE)
|
|
||||||
|
|
||||||
#define SOCK_FROM_TOKEN(Token) (((SOCK_TOKEN *) (Token))->Sock)
|
|
||||||
|
|
||||||
#define PROTO_TOKEN_FORM_SOCK(SockToken, Type) \
|
|
||||||
((Type *) (((SOCK_TOKEN *) (SockToken))->Token))
|
|
||||||
|
|
||||||
typedef struct _SOCKET SOCKET;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Socket completion token
|
|
||||||
///
|
|
||||||
typedef struct _SOCK_COMPLETION_TOKEN {
|
|
||||||
EFI_EVENT Event; ///< The event to be issued
|
|
||||||
EFI_STATUS Status; ///< The status to be issued
|
|
||||||
} SOCK_COMPLETION_TOKEN;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
VOID *RxData;
|
|
||||||
VOID *TxData;
|
|
||||||
} SOCK_IO_DATA;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The application token with data packet
|
|
||||||
///
|
|
||||||
typedef struct _SOCK_IO_TOKEN {
|
|
||||||
SOCK_COMPLETION_TOKEN Token;
|
|
||||||
SOCK_IO_DATA Packet;
|
|
||||||
} SOCK_IO_TOKEN;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The request issued from socket layer to protocol layer.
|
|
||||||
///
|
|
||||||
#define SOCK_ATTACH 0 ///< Attach current socket to a new PCB
|
|
||||||
#define SOCK_DETACH 1 ///< Detach current socket from the PCB
|
|
||||||
#define SOCK_CONFIGURE 2 ///< Configure attached PCB
|
|
||||||
#define SOCK_FLUSH 3 ///< Flush attached PCB
|
|
||||||
#define SOCK_SND 4 ///< Need protocol to send something
|
|
||||||
#define SOCK_SNDPUSH 5 ///< Need protocol to send pushed data
|
|
||||||
#define SOCK_SNDURG 6 ///< Need protocol to send urgent data
|
|
||||||
#define SOCK_CONSUMED 7 ///< Application has retrieved data from socket
|
|
||||||
#define SOCK_CONNECT 8 ///< Need to connect to a peer
|
|
||||||
#define SOCK_CLOSE 9 ///< Need to close the protocol process
|
|
||||||
#define SOCK_ABORT 10 ///< Need to reset the protocol process
|
|
||||||
#define SOCK_POLL 11 ///< Need to poll to the protocol layer
|
|
||||||
#define SOCK_ROUTE 12 ///< Need to add a route information
|
|
||||||
#define SOCK_MODE 13 ///< Need to get the mode data of the protocol
|
|
||||||
#define SOCK_GROUP 14 ///< Need to join a mcast group
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The socket type.
|
|
||||||
///
|
|
||||||
typedef enum {
|
|
||||||
SockDgram, ///< This socket providing datagram service
|
|
||||||
SockStream ///< This socket providing stream service
|
|
||||||
} SOCK_TYPE;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The buffer structure of rcvd data and send data used by socket.
|
|
||||||
///
|
|
||||||
typedef struct _SOCK_BUFFER {
|
|
||||||
UINT32 HighWater; ///< The buffersize upper limit of sock_buffer
|
|
||||||
UINT32 LowWater; ///< The low water mark of sock_buffer
|
|
||||||
NET_BUF_QUEUE *DataQueue; ///< The queue to buffer data
|
|
||||||
} SOCK_BUFFER;
|
|
||||||
|
|
||||||
/**
|
|
||||||
The handler of protocol for request from socket.
|
|
||||||
|
|
||||||
@param Socket The socket issuing the request to protocol
|
|
||||||
@param Request The request issued by socket
|
|
||||||
@param RequestData The request related data
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The socket request is completed successfully.
|
|
||||||
@retval other The error status returned by the corresponding TCP
|
|
||||||
layer function.
|
|
||||||
|
|
||||||
**/
|
|
||||||
typedef
|
|
||||||
EFI_STATUS
|
|
||||||
(*SOCK_PROTO_HANDLER) (
|
|
||||||
IN SOCKET *Socket,
|
|
||||||
IN UINT8 Request,
|
|
||||||
IN VOID *RequestData
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Socket provided oprerations for low layer protocol
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Socket provided operations for user interface
|
|
||||||
//
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set the state of the socket.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket.
|
|
||||||
@param State The new socket state to be set.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SockSetState (
|
|
||||||
IN OUT SOCKET *Sock,
|
|
||||||
IN UINT8 State
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Called by the low layer protocol to indicate the socket a connection is
|
|
||||||
established.
|
|
||||||
|
|
||||||
This function just changes the socket's state to SO_CONNECTED
|
|
||||||
and signals the token used for connection establishment.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket associated with the
|
|
||||||
established connection.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SockConnEstablished (
|
|
||||||
IN SOCKET *Sock
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Called by the low layer protocol to indicate the connection is closed.
|
|
||||||
|
|
||||||
This function flushes the socket, sets the state to SO_CLOSED and signals
|
|
||||||
the close token.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket associated with the closed
|
|
||||||
connection.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SockConnClosed (
|
|
||||||
IN OUT SOCKET *Sock
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Called by low layer protocol to indicate that some data is sent or processed.
|
|
||||||
|
|
||||||
This function trims the sent data in the socket send buffer, signals the data
|
|
||||||
token if proper.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket.
|
|
||||||
@param Count The length of the data processed or sent, in bytes.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SockDataSent (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN UINT32 Count
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Called by the low layer protocol to copy some data in socket send
|
|
||||||
buffer starting from the specific offset to a buffer provided by
|
|
||||||
the caller.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket.
|
|
||||||
@param Offset The start point of the data to be copied.
|
|
||||||
@param Len The length of the data to be copied.
|
|
||||||
@param Dest Pointer to the destination to copy the data.
|
|
||||||
|
|
||||||
@return The data size copied.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT32
|
|
||||||
SockGetDataToSend (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN UINT32 Offset,
|
|
||||||
IN UINT32 Len,
|
|
||||||
IN UINT8 *Dest
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Called by the low layer protocol to indicate that there
|
|
||||||
will be no more data from the communication peer.
|
|
||||||
|
|
||||||
This function set the socket's state to SO_NO_MORE_DATA and
|
|
||||||
signal all queued IO tokens with the error status EFI_CONNECTION_FIN.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SockNoMoreData (
|
|
||||||
IN OUT SOCKET *Sock
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Called by the low layer protocol to deliver received data to socket layer.
|
|
||||||
|
|
||||||
This function will append the data to the socket receive buffer, set ther
|
|
||||||
urgent data length and then check if any receive token can be signaled.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket.
|
|
||||||
@param NetBuffer Pointer to the buffer that contains the received
|
|
||||||
data.
|
|
||||||
@param UrgLen The length of the urgent data in the received data.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SockDataRcvd (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN OUT NET_BUF *NetBuffer,
|
|
||||||
IN UINT32 UrgLen
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the length of the free space of the specific socket buffer.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket.
|
|
||||||
@param Which Flag to indicate which socket buffer to check,
|
|
||||||
either send buffer or receive buffer.
|
|
||||||
|
|
||||||
@return The length of the free space, in bytes.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT32
|
|
||||||
SockGetFreeSpace (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN UINT32 Which
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Clone a new socket including its associated protocol control block.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to be cloned.
|
|
||||||
|
|
||||||
@return Pointer to the newly cloned socket. If NULL, error condition occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
SOCKET *
|
|
||||||
SockClone (
|
|
||||||
IN SOCKET *Sock
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Proto type of the create callback
|
|
||||||
///
|
|
||||||
typedef
|
|
||||||
EFI_STATUS
|
|
||||||
(*SOCK_CREATE_CALLBACK) (
|
|
||||||
IN SOCKET *This,
|
|
||||||
IN VOID *Context
|
|
||||||
);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Proto type of the destroy callback
|
|
||||||
///
|
|
||||||
typedef
|
|
||||||
VOID
|
|
||||||
(*SOCK_DESTROY_CALLBACK) (
|
|
||||||
IN SOCKET *This,
|
|
||||||
IN VOID *Context
|
|
||||||
);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The initialize data for create a new socket.
|
|
||||||
///
|
|
||||||
typedef struct _SOCK_INIT_DATA {
|
|
||||||
SOCK_TYPE Type;
|
|
||||||
UINT8 State;
|
|
||||||
|
|
||||||
SOCKET *Parent; ///< The parent of this socket
|
|
||||||
UINT32 BackLog; ///< The connection limit for listening socket
|
|
||||||
UINT32 SndBufferSize; ///< The high water mark of send buffer
|
|
||||||
UINT32 RcvBufferSize; ///< The high water mark of receive buffer
|
|
||||||
VOID *Protocol; ///< The pointer to protocol function template
|
|
||||||
///< wanted to install on socket
|
|
||||||
|
|
||||||
//
|
|
||||||
// Callbacks after socket is created and before socket is to be destroyed.
|
|
||||||
//
|
|
||||||
SOCK_CREATE_CALLBACK CreateCallback; ///< Callback after created
|
|
||||||
SOCK_DESTROY_CALLBACK DestroyCallback; ///< Callback before destroied
|
|
||||||
VOID *Context; ///< The context of the callback
|
|
||||||
|
|
||||||
//
|
|
||||||
// Opaque protocol data.
|
|
||||||
//
|
|
||||||
VOID *ProtoData;
|
|
||||||
UINT32 DataSize;
|
|
||||||
|
|
||||||
SOCK_PROTO_HANDLER ProtoHandler; ///< The handler of protocol for socket request
|
|
||||||
|
|
||||||
EFI_HANDLE DriverBinding; ///< The driver binding handle
|
|
||||||
} SOCK_INIT_DATA;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The union type of TCP and UDP protocol.
|
|
||||||
///
|
|
||||||
typedef union _NET_PROTOCOL {
|
|
||||||
EFI_TCP4_PROTOCOL TcpProtocol; ///< Tcp protocol
|
|
||||||
EFI_UDP4_PROTOCOL UdpProtocol; ///< Udp protocol
|
|
||||||
} NET_PROTOCOL;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The socket structure representing a network service access point
|
|
||||||
///
|
|
||||||
struct _SOCKET {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Socket description information
|
|
||||||
//
|
|
||||||
UINT32 Signature; ///< Signature of the socket
|
|
||||||
EFI_HANDLE SockHandle; ///< The virtual handle of the socket
|
|
||||||
EFI_HANDLE DriverBinding; ///< Socket's driver binding protocol
|
|
||||||
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
|
||||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
|
||||||
LIST_ENTRY Link;
|
|
||||||
UINT8 ConfigureState;
|
|
||||||
SOCK_TYPE Type;
|
|
||||||
UINT8 State;
|
|
||||||
UINT16 Flag;
|
|
||||||
EFI_LOCK Lock; ///< The lock of socket
|
|
||||||
SOCK_BUFFER SndBuffer; ///< Send buffer of application's data
|
|
||||||
SOCK_BUFFER RcvBuffer; ///< Receive buffer of received data
|
|
||||||
EFI_STATUS SockError; ///< The error returned by low layer protocol
|
|
||||||
BOOLEAN InDestroy;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Fields used to manage the connection request
|
|
||||||
//
|
|
||||||
UINT32 BackLog; ///< the limit of connection to this socket
|
|
||||||
UINT32 ConnCnt; ///< the current count of connections to it
|
|
||||||
SOCKET *Parent; ///< listening parent that accept the connection
|
|
||||||
LIST_ENTRY ConnectionList; ///< the connections maintained by this socket
|
|
||||||
|
|
||||||
//
|
|
||||||
// The queue to buffer application's asynchronous token
|
|
||||||
//
|
|
||||||
LIST_ENTRY ListenTokenList;
|
|
||||||
LIST_ENTRY RcvTokenList;
|
|
||||||
LIST_ENTRY SndTokenList;
|
|
||||||
LIST_ENTRY ProcessingSndTokenList;
|
|
||||||
|
|
||||||
SOCK_COMPLETION_TOKEN *ConnectionToken; ///< app's token to signal if connected
|
|
||||||
SOCK_COMPLETION_TOKEN *CloseToken; ///< app's token to signal if closed
|
|
||||||
|
|
||||||
//
|
|
||||||
// Interface for low level protocol
|
|
||||||
//
|
|
||||||
SOCK_PROTO_HANDLER ProtoHandler; ///< The request handler of protocol
|
|
||||||
UINT8 ProtoReserved[PROTO_RESERVED_LEN]; ///< Data fields reserved for protocol
|
|
||||||
NET_PROTOCOL NetProtocol; ///< TCP or UDP protocol socket used
|
|
||||||
|
|
||||||
//
|
|
||||||
// Callbacks after socket is created and before socket is to be destroyed.
|
|
||||||
//
|
|
||||||
SOCK_CREATE_CALLBACK CreateCallback; ///< Callback after created
|
|
||||||
SOCK_DESTROY_CALLBACK DestroyCallback; ///< Callback before destroied
|
|
||||||
VOID *Context; ///< The context of the callback
|
|
||||||
};
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The token structure buffered in socket layer.
|
|
||||||
///
|
|
||||||
typedef struct _SOCK_TOKEN {
|
|
||||||
LIST_ENTRY TokenList; ///< The entry to add in the token list
|
|
||||||
SOCK_COMPLETION_TOKEN *Token; ///< The application's token
|
|
||||||
UINT32 RemainDataLen; ///< Unprocessed data length
|
|
||||||
SOCKET *Sock; ///< The poninter to the socket this token
|
|
||||||
///< belongs to
|
|
||||||
} SOCK_TOKEN;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Reserved data to access the NET_BUF delivered by UDP driver.
|
|
||||||
///
|
|
||||||
typedef struct _UDP_RSV_DATA {
|
|
||||||
EFI_TIME TimeStamp;
|
|
||||||
EFI_UDP4_SESSION_DATA Session;
|
|
||||||
} UDP_RSV_DATA;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Reserved data to access the NET_BUF delivered by TCP driver.
|
|
||||||
///
|
|
||||||
typedef struct _TCP_RSV_DATA {
|
|
||||||
UINT32 UrgLen;
|
|
||||||
} TCP_RSV_DATA;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create a socket and its associated protocol control block
|
|
||||||
with the intial data SockInitData and protocol specific
|
|
||||||
data ProtoData.
|
|
||||||
|
|
||||||
@param SockInitData Inital data to setting the socket.
|
|
||||||
|
|
||||||
@return Pointer to the newly created socket. If NULL, error condition occured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
SOCKET *
|
|
||||||
SockCreateChild (
|
|
||||||
IN SOCK_INIT_DATA *SockInitData
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Destroy the socket Sock and its associated protocol control block.
|
|
||||||
|
|
||||||
@param Sock The socket to be destroyed.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The socket Sock is destroyed successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockDestroyChild (
|
|
||||||
IN SOCKET *Sock
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Configure the specific socket Sock using configuration data ConfigData.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to be configured.
|
|
||||||
@param ConfigData Pointer to the configuration data.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The socket is configured successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket or the
|
|
||||||
socket is already configured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockConfigure (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *ConfigData
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initiate a connection establishment process.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to initiate the initate the
|
|
||||||
connection.
|
|
||||||
@param Token Pointer to the token used for the connection
|
|
||||||
operation.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The connection is initialized successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
|
||||||
socket is closed, or the socket is not configured to
|
|
||||||
be an active one, or the token is already in one of
|
|
||||||
this socket's lists.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockConnect (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *Token
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Issue a listen token to get an existed connected network instance
|
|
||||||
or wait for a connection if there is none.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to accept connections.
|
|
||||||
@param Token The token to accept a connection.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Either a connection is accpeted or the Token is
|
|
||||||
buffered for further acception.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
|
||||||
socket is closed, or the socket is not configured to
|
|
||||||
be a passive one, or the token is already in one of
|
|
||||||
this socket's lists.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
@retval EFI_OUT_OF_RESOURCE Failed to buffer the Token due to memory limit.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockAccept (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *Token
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Issue a token with data to the socket to send out.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to process the token with
|
|
||||||
data.
|
|
||||||
@param Token The token with data that needs to send out.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The token is processed successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
|
||||||
socket is closed, or the socket is not in a
|
|
||||||
synchronized state , or the token is already in one
|
|
||||||
of this socket's lists.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
@retval EFI_OUT_OF_RESOURCE Failed to buffer the token due to memory limit.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockSend (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *Token
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Issue a token to get data from the socket.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to get data from.
|
|
||||||
@param Token The token to store the received data from the
|
|
||||||
socket.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The token is processed successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
|
||||||
socket is closed, or the socket is not in a
|
|
||||||
synchronized state , or the token is already in one
|
|
||||||
of this socket's lists.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
@retval EFI_CONNECTION_FIN The connection is closed and there is no more data.
|
|
||||||
@retval EFI_OUT_OF_RESOURCE Failed to buffer the token due to memory limit.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockRcv (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *Token
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Reset the socket and its associated protocol control block.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to be flushed.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The socket is flushed successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockFlush (
|
|
||||||
IN SOCKET *Sock
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Close or abort the socket associated connection.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket of the connection to close or
|
|
||||||
abort.
|
|
||||||
@param Token The token for close operation.
|
|
||||||
@param OnAbort TRUE for aborting the connection, FALSE to close it.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The close or abort operation is initialized
|
|
||||||
successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
|
||||||
socket is closed, or the socket is not in a
|
|
||||||
synchronized state , or the token is already in one
|
|
||||||
of this socket's lists.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockClose (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *Token,
|
|
||||||
IN BOOLEAN OnAbort
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the mode data of the low layer protocol.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to get mode data from.
|
|
||||||
@param Mode Pointer to the data to store the low layer mode
|
|
||||||
information.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The mode data is got successfully.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockGetMode (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN OUT VOID *Mode
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Add or remove route information in IP route table associated
|
|
||||||
with this socket.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket associated with the IP route
|
|
||||||
table to operate on.
|
|
||||||
@param RouteInfo Pointer to the route information to be processed.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The route table is updated successfully.
|
|
||||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
|
|
||||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_NOT_STARTED The socket is not configured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
SockRoute (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN VOID *RouteInfo
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Supporting function to operate on socket buffer
|
|
||||||
//
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the first buffer block in the specific socket buffer.
|
|
||||||
|
|
||||||
@param Sockbuf Pointer to the socket buffer.
|
|
||||||
|
|
||||||
@return Pointer to the first buffer in the queue. NULL if the queue is empty.
|
|
||||||
|
|
||||||
**/
|
|
||||||
NET_BUF *
|
|
||||||
SockBufFirst (
|
|
||||||
IN SOCK_BUFFER *Sockbuf
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the next buffer block in the specific socket buffer.
|
|
||||||
|
|
||||||
@param Sockbuf Pointer to the socket buffer.
|
|
||||||
@param SockEntry Pointer to the buffer block prior to the required
|
|
||||||
one.
|
|
||||||
|
|
||||||
@return Pointer to the buffer block next to SockEntry. NULL if SockEntry is
|
|
||||||
the tail or head entry.
|
|
||||||
|
|
||||||
**/
|
|
||||||
NET_BUF *
|
|
||||||
SockBufNext (
|
|
||||||
IN SOCK_BUFFER *Sockbuf,
|
|
||||||
IN NET_BUF *SockEntry
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,717 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Tcp request dispatcher implementation.
|
|
||||||
|
|
||||||
(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "Tcp4Main.h"
|
|
||||||
|
|
||||||
#define TCP_COMP_VAL(Min, Max, Default, Val) \
|
|
||||||
((((Val) <= (Max)) && ((Val) >= (Min))) ? (Val) : (Default))
|
|
||||||
|
|
||||||
/**
|
|
||||||
Add or remove a route entry in the IP route table associated with this TCP instance.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param RouteInfo Pointer to the route info to be processed.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The operation completed successfully.
|
|
||||||
@retval EFI_NOT_STARTED The driver instance has not been started.
|
|
||||||
@retval EFI_NO_MAPPING When using the default address, configuration(DHCP,
|
|
||||||
BOOTP, RARP, etc.) is not finished yet.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table.
|
|
||||||
@retval EFI_NOT_FOUND This route is not in the routing table
|
|
||||||
(when RouteInfo->DeleteRoute is TRUE).
|
|
||||||
@retval EFI_ACCESS_DENIED The route is already defined in the routing table
|
|
||||||
(when RouteInfo->DeleteRoute is FALSE).
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4Route (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN TCP4_ROUTE_INFO *RouteInfo
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_IP4_PROTOCOL *Ip4;
|
|
||||||
|
|
||||||
Ip4 = Tcb->IpInfo->Ip.Ip4;
|
|
||||||
|
|
||||||
ASSERT (Ip4 != NULL);
|
|
||||||
|
|
||||||
return Ip4->Routes (
|
|
||||||
Ip4,
|
|
||||||
RouteInfo->DeleteRoute,
|
|
||||||
RouteInfo->SubnetAddress,
|
|
||||||
RouteInfo->SubnetMask,
|
|
||||||
RouteInfo->GatewayAddress
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the operational settings of this TCP instance.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Mode Pointer to the buffer to store the operational
|
|
||||||
settings.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The mode data is read.
|
|
||||||
@retval EFI_NOT_STARTED No configuration data is available because this
|
|
||||||
instance hasn't been started.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4GetMode (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN OUT TCP4_MODE_DATA *Mode
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
EFI_TCP4_CONFIG_DATA *ConfigData;
|
|
||||||
EFI_TCP4_ACCESS_POINT *AccessPoint;
|
|
||||||
EFI_TCP4_OPTION *Option;
|
|
||||||
EFI_IP4_PROTOCOL *Ip;
|
|
||||||
|
|
||||||
Sock = Tcb->Sk;
|
|
||||||
|
|
||||||
if (!SOCK_IS_CONFIGURED (Sock) && (Mode->Tcp4ConfigData != NULL)) {
|
|
||||||
return EFI_NOT_STARTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Mode->Tcp4State != NULL) {
|
|
||||||
*(Mode->Tcp4State) = (EFI_TCP4_CONNECTION_STATE) Tcb->State;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Mode->Tcp4ConfigData != NULL) {
|
|
||||||
|
|
||||||
ConfigData = Mode->Tcp4ConfigData;
|
|
||||||
AccessPoint = &(ConfigData->AccessPoint);
|
|
||||||
Option = ConfigData->ControlOption;
|
|
||||||
|
|
||||||
ConfigData->TypeOfService = Tcb->Tos;
|
|
||||||
ConfigData->TimeToLive = Tcb->Ttl;
|
|
||||||
|
|
||||||
AccessPoint->UseDefaultAddress = Tcb->UseDefaultAddr;
|
|
||||||
|
|
||||||
IP4_COPY_ADDRESS (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip);
|
|
||||||
IP4_COPY_ADDRESS (&AccessPoint->SubnetMask, &Tcb->SubnetMask);
|
|
||||||
AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);
|
|
||||||
|
|
||||||
IP4_COPY_ADDRESS (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip);
|
|
||||||
AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port);
|
|
||||||
AccessPoint->ActiveFlag = (BOOLEAN) (Tcb->State != TCP_LISTEN);
|
|
||||||
|
|
||||||
if (Option != NULL) {
|
|
||||||
Option->ReceiveBufferSize = GET_RCV_BUFFSIZE (Tcb->Sk);
|
|
||||||
Option->SendBufferSize = GET_SND_BUFFSIZE (Tcb->Sk);
|
|
||||||
Option->MaxSynBackLog = GET_BACKLOG (Tcb->Sk);
|
|
||||||
|
|
||||||
Option->ConnectionTimeout = Tcb->ConnectTimeout / TCP_TICK_HZ;
|
|
||||||
Option->DataRetries = Tcb->MaxRexmit;
|
|
||||||
Option->FinTimeout = Tcb->FinWait2Timeout / TCP_TICK_HZ;
|
|
||||||
Option->TimeWaitTimeout = Tcb->TimeWaitTimeout / TCP_TICK_HZ;
|
|
||||||
Option->KeepAliveProbes = Tcb->MaxKeepAlive;
|
|
||||||
Option->KeepAliveTime = Tcb->KeepAliveIdle / TCP_TICK_HZ;
|
|
||||||
Option->KeepAliveInterval = Tcb->KeepAlivePeriod / TCP_TICK_HZ;
|
|
||||||
|
|
||||||
Option->EnableNagle = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE));
|
|
||||||
Option->EnableTimeStamp = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS));
|
|
||||||
Option->EnableWindowScaling = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS));
|
|
||||||
|
|
||||||
Option->EnableSelectiveAck = FALSE;
|
|
||||||
Option->EnablePathMtuDiscovery = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ip = Tcb->IpInfo->Ip.Ip4;
|
|
||||||
ASSERT (Ip != NULL);
|
|
||||||
|
|
||||||
return Ip->GetModeData (Ip, Mode->Ip4ModeData, Mode->MnpConfigData, Mode->SnpModeData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
If AP->StationPort isn't zero, check whether the access point
|
|
||||||
is registered, else generate a random station port for this
|
|
||||||
access point.
|
|
||||||
|
|
||||||
@param AP Pointer to the access point.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The check is passed or the port is assigned.
|
|
||||||
@retval EFI_INVALID_PARAMETER The non-zero station port is already used.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES No port can be allocated.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4Bind (
|
|
||||||
IN EFI_TCP4_ACCESS_POINT *AP
|
|
||||||
)
|
|
||||||
{
|
|
||||||
BOOLEAN Cycle;
|
|
||||||
|
|
||||||
if (0 != AP->StationPort) {
|
|
||||||
//
|
|
||||||
// check if a same endpoint is bound
|
|
||||||
//
|
|
||||||
if (TcpFindTcbByPeer (&AP->StationAddress, AP->StationPort)) {
|
|
||||||
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// generate a random port
|
|
||||||
//
|
|
||||||
Cycle = FALSE;
|
|
||||||
|
|
||||||
if (TCP4_PORT_USER_RESERVED == mTcp4RandomPort) {
|
|
||||||
mTcp4RandomPort = TCP4_PORT_KNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
mTcp4RandomPort++;
|
|
||||||
|
|
||||||
while (TcpFindTcbByPeer (&AP->StationAddress, mTcp4RandomPort)) {
|
|
||||||
|
|
||||||
mTcp4RandomPort++;
|
|
||||||
|
|
||||||
if (mTcp4RandomPort <= TCP4_PORT_KNOWN) {
|
|
||||||
|
|
||||||
if (Cycle) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "Tcp4Bind: no port can be allocated "
|
|
||||||
"for this pcb\n"));
|
|
||||||
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
mTcp4RandomPort = TCP4_PORT_KNOWN + 1;
|
|
||||||
|
|
||||||
Cycle = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
AP->StationPort = mTcp4RandomPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Flush the Tcb add its associated protocols.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB to be flushed.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
Tcp4FlushPcb (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
|
|
||||||
IpIoConfigIp (Tcb->IpInfo, NULL);
|
|
||||||
|
|
||||||
Sock = Tcb->Sk;
|
|
||||||
|
|
||||||
if (SOCK_IS_CONFIGURED (Sock)) {
|
|
||||||
RemoveEntryList (&Tcb->List);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Uninstall the device path protocol.
|
|
||||||
//
|
|
||||||
if (Sock->DevicePath != NULL) {
|
|
||||||
gBS->UninstallProtocolInterface (
|
|
||||||
Sock->SockHandle,
|
|
||||||
&gEfiDevicePathProtocolGuid,
|
|
||||||
Sock->DevicePath
|
|
||||||
);
|
|
||||||
FreePool (Sock->DevicePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NetbufFreeList (&Tcb->SndQue);
|
|
||||||
NetbufFreeList (&Tcb->RcvQue);
|
|
||||||
Tcb->State = TCP_CLOSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Attach a Pcb to the socket.
|
|
||||||
|
|
||||||
@param Sk Pointer to the socket of this TCP instance.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The operation is completed successfully.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4AttachPcb (
|
|
||||||
IN SOCKET *Sk
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP_CB *Tcb;
|
|
||||||
TCP4_PROTO_DATA *ProtoData;
|
|
||||||
IP_IO *IpIo;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
VOID *Ip;
|
|
||||||
|
|
||||||
Tcb = AllocateZeroPool (sizeof (TCP_CB));
|
|
||||||
|
|
||||||
if (Tcb == NULL) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: failed to allocate a TCB\n"));
|
|
||||||
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;
|
|
||||||
IpIo = ProtoData->TcpService->IpIo;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Create an IpInfo for this Tcb.
|
|
||||||
//
|
|
||||||
Tcb->IpInfo = IpIoAddIp (IpIo);
|
|
||||||
if (Tcb->IpInfo == NULL) {
|
|
||||||
|
|
||||||
FreePool (Tcb);
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Open the new created IP instance BY_CHILD.
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
Tcb->IpInfo->ChildHandle,
|
|
||||||
&gEfiIp4ProtocolGuid,
|
|
||||||
&Ip,
|
|
||||||
IpIo->Image,
|
|
||||||
Sk->SockHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
IpIoRemoveIp (IpIo, Tcb->IpInfo);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeListHead (&Tcb->List);
|
|
||||||
InitializeListHead (&Tcb->SndQue);
|
|
||||||
InitializeListHead (&Tcb->RcvQue);
|
|
||||||
|
|
||||||
Tcb->State = TCP_CLOSED;
|
|
||||||
Tcb->Sk = Sk;
|
|
||||||
ProtoData->TcpPcb = Tcb;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Detach the Pcb of the socket.
|
|
||||||
|
|
||||||
@param Sk Pointer to the socket of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
Tcp4DetachPcb (
|
|
||||||
IN SOCKET *Sk
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP4_PROTO_DATA *ProtoData;
|
|
||||||
TCP_CB *Tcb;
|
|
||||||
|
|
||||||
ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;
|
|
||||||
Tcb = ProtoData->TcpPcb;
|
|
||||||
|
|
||||||
ASSERT (Tcb != NULL);
|
|
||||||
|
|
||||||
Tcp4FlushPcb (Tcb);
|
|
||||||
|
|
||||||
IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);
|
|
||||||
|
|
||||||
FreePool (Tcb);
|
|
||||||
|
|
||||||
ProtoData->TcpPcb = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Configure the Pcb using CfgData.
|
|
||||||
|
|
||||||
@param Sk Pointer to the socket of this TCP instance.
|
|
||||||
@param CfgData Pointer to the TCP configuration data.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The operation is completed successfully.
|
|
||||||
@retval EFI_INVALID_PARAMETER A same access point has been configured in
|
|
||||||
another TCP instance.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4ConfigurePcb (
|
|
||||||
IN SOCKET *Sk,
|
|
||||||
IN EFI_TCP4_CONFIG_DATA *CfgData
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_IP4_CONFIG_DATA IpCfgData;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_TCP4_OPTION *Option;
|
|
||||||
TCP4_PROTO_DATA *TcpProto;
|
|
||||||
TCP_CB *Tcb;
|
|
||||||
|
|
||||||
ASSERT ((CfgData != NULL) && (Sk != NULL) && (Sk->SockHandle != NULL));
|
|
||||||
|
|
||||||
TcpProto = (TCP4_PROTO_DATA *) Sk->ProtoReserved;
|
|
||||||
Tcb = TcpProto->TcpPcb;
|
|
||||||
|
|
||||||
ASSERT (Tcb != NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add Ip for send pkt to the peer
|
|
||||||
//
|
|
||||||
CopyMem (&IpCfgData, &mIp4IoDefaultIpConfigData, sizeof (IpCfgData));
|
|
||||||
IpCfgData.DefaultProtocol = EFI_IP_PROTO_TCP;
|
|
||||||
IpCfgData.UseDefaultAddress = CfgData->AccessPoint.UseDefaultAddress;
|
|
||||||
IpCfgData.StationAddress = CfgData->AccessPoint.StationAddress;
|
|
||||||
IpCfgData.SubnetMask = CfgData->AccessPoint.SubnetMask;
|
|
||||||
IpCfgData.ReceiveTimeout = (UINT32) (-1);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Configure the IP instance this Tcb consumes.
|
|
||||||
//
|
|
||||||
Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto OnExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the default address info if the instance is configured to use default address.
|
|
||||||
//
|
|
||||||
if (CfgData->AccessPoint.UseDefaultAddress) {
|
|
||||||
CfgData->AccessPoint.StationAddress = IpCfgData.StationAddress;
|
|
||||||
CfgData->AccessPoint.SubnetMask = IpCfgData.SubnetMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// check if we can bind this endpoint in CfgData
|
|
||||||
//
|
|
||||||
Status = Tcp4Bind (&(CfgData->AccessPoint));
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: Bind endpoint failed "
|
|
||||||
"with %r\n", Status));
|
|
||||||
|
|
||||||
goto OnExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initalize the operating information in this Tcb
|
|
||||||
//
|
|
||||||
ASSERT (Tcb->State == TCP_CLOSED &&
|
|
||||||
IsListEmpty (&Tcb->SndQue) &&
|
|
||||||
IsListEmpty (&Tcb->RcvQue));
|
|
||||||
|
|
||||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);
|
|
||||||
Tcb->State = TCP_CLOSED;
|
|
||||||
|
|
||||||
Tcb->SndMss = 536;
|
|
||||||
Tcb->RcvMss = TcpGetRcvMss (Sk);
|
|
||||||
|
|
||||||
Tcb->SRtt = 0;
|
|
||||||
Tcb->Rto = 3 * TCP_TICK_HZ;
|
|
||||||
|
|
||||||
Tcb->CWnd = Tcb->SndMss;
|
|
||||||
Tcb->Ssthresh = 0xffffffff;
|
|
||||||
|
|
||||||
Tcb->CongestState = TCP_CONGEST_OPEN;
|
|
||||||
|
|
||||||
Tcb->KeepAliveIdle = TCP_KEEPALIVE_IDLE_MIN;
|
|
||||||
Tcb->KeepAlivePeriod = TCP_KEEPALIVE_PERIOD;
|
|
||||||
Tcb->MaxKeepAlive = TCP_MAX_KEEPALIVE;
|
|
||||||
Tcb->MaxRexmit = TCP_MAX_LOSS;
|
|
||||||
Tcb->FinWait2Timeout = TCP_FIN_WAIT2_TIME;
|
|
||||||
Tcb->TimeWaitTimeout = TCP_TIME_WAIT_TIME;
|
|
||||||
Tcb->ConnectTimeout = TCP_CONNECT_TIME;
|
|
||||||
|
|
||||||
//
|
|
||||||
// initialize Tcb in the light of CfgData
|
|
||||||
//
|
|
||||||
Tcb->Ttl = CfgData->TimeToLive;
|
|
||||||
Tcb->Tos = CfgData->TypeOfService;
|
|
||||||
|
|
||||||
Tcb->UseDefaultAddr = CfgData->AccessPoint.UseDefaultAddress;
|
|
||||||
|
|
||||||
CopyMem (&Tcb->LocalEnd.Ip, &CfgData->AccessPoint.StationAddress, sizeof (IP4_ADDR));
|
|
||||||
Tcb->LocalEnd.Port = HTONS (CfgData->AccessPoint.StationPort);
|
|
||||||
IP4_COPY_ADDRESS (&Tcb->SubnetMask, &CfgData->AccessPoint.SubnetMask);
|
|
||||||
|
|
||||||
if (CfgData->AccessPoint.ActiveFlag) {
|
|
||||||
CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));
|
|
||||||
Tcb->RemoteEnd.Port = HTONS (CfgData->AccessPoint.RemotePort);
|
|
||||||
} else {
|
|
||||||
Tcb->RemoteEnd.Ip = 0;
|
|
||||||
Tcb->RemoteEnd.Port = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Option = CfgData->ControlOption;
|
|
||||||
|
|
||||||
if (Option != NULL) {
|
|
||||||
SET_RCV_BUFFSIZE (
|
|
||||||
Sk,
|
|
||||||
(UINT32) (TCP_COMP_VAL (
|
|
||||||
TCP_RCV_BUF_SIZE_MIN,
|
|
||||||
TCP_RCV_BUF_SIZE,
|
|
||||||
TCP_RCV_BUF_SIZE,
|
|
||||||
Option->ReceiveBufferSize
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
SET_SND_BUFFSIZE (
|
|
||||||
Sk,
|
|
||||||
(UINT32) (TCP_COMP_VAL (
|
|
||||||
TCP_SND_BUF_SIZE_MIN,
|
|
||||||
TCP_SND_BUF_SIZE,
|
|
||||||
TCP_SND_BUF_SIZE,
|
|
||||||
Option->SendBufferSize
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
SET_BACKLOG (
|
|
||||||
Sk,
|
|
||||||
(UINT32) (TCP_COMP_VAL (
|
|
||||||
TCP_BACKLOG_MIN,
|
|
||||||
TCP_BACKLOG,
|
|
||||||
TCP_BACKLOG,
|
|
||||||
Option->MaxSynBackLog
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Tcb->MaxRexmit = (UINT16) TCP_COMP_VAL (
|
|
||||||
TCP_MAX_LOSS_MIN,
|
|
||||||
TCP_MAX_LOSS,
|
|
||||||
TCP_MAX_LOSS,
|
|
||||||
Option->DataRetries
|
|
||||||
);
|
|
||||||
Tcb->FinWait2Timeout = TCP_COMP_VAL (
|
|
||||||
TCP_FIN_WAIT2_TIME,
|
|
||||||
TCP_FIN_WAIT2_TIME_MAX,
|
|
||||||
TCP_FIN_WAIT2_TIME,
|
|
||||||
(UINT32) (Option->FinTimeout * TCP_TICK_HZ)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Option->TimeWaitTimeout != 0) {
|
|
||||||
Tcb->TimeWaitTimeout = TCP_COMP_VAL (
|
|
||||||
TCP_TIME_WAIT_TIME,
|
|
||||||
TCP_TIME_WAIT_TIME_MAX,
|
|
||||||
TCP_TIME_WAIT_TIME,
|
|
||||||
(UINT32) (Option->TimeWaitTimeout * TCP_TICK_HZ)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
Tcb->TimeWaitTimeout = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Option->KeepAliveProbes != 0) {
|
|
||||||
TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);
|
|
||||||
|
|
||||||
Tcb->MaxKeepAlive = (UINT8) TCP_COMP_VAL (
|
|
||||||
TCP_MAX_KEEPALIVE_MIN,
|
|
||||||
TCP_MAX_KEEPALIVE,
|
|
||||||
TCP_MAX_KEEPALIVE,
|
|
||||||
Option->KeepAliveProbes
|
|
||||||
);
|
|
||||||
Tcb->KeepAliveIdle = TCP_COMP_VAL (
|
|
||||||
TCP_KEEPALIVE_IDLE_MIN,
|
|
||||||
TCP_KEEPALIVE_IDLE_MAX,
|
|
||||||
TCP_KEEPALIVE_IDLE_MIN,
|
|
||||||
(UINT32) (Option->KeepAliveTime * TCP_TICK_HZ)
|
|
||||||
);
|
|
||||||
Tcb->KeepAlivePeriod = TCP_COMP_VAL (
|
|
||||||
TCP_KEEPALIVE_PERIOD_MIN,
|
|
||||||
TCP_KEEPALIVE_PERIOD,
|
|
||||||
TCP_KEEPALIVE_PERIOD,
|
|
||||||
(UINT32) (Option->KeepAliveInterval * TCP_TICK_HZ)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Tcb->ConnectTimeout = TCP_COMP_VAL (
|
|
||||||
TCP_CONNECT_TIME_MIN,
|
|
||||||
TCP_CONNECT_TIME,
|
|
||||||
TCP_CONNECT_TIME,
|
|
||||||
(UINT32) (Option->ConnectionTimeout * TCP_TICK_HZ)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!Option->EnableNagle) {
|
|
||||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Option->EnableTimeStamp) {
|
|
||||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Option->EnableWindowScaling) {
|
|
||||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is
|
|
||||||
// determined, construct the IP device path and install it.
|
|
||||||
//
|
|
||||||
Status = TcpInstallDevicePath (Sk);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto OnExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// update state of Tcb and socket
|
|
||||||
//
|
|
||||||
if (!CfgData->AccessPoint.ActiveFlag) {
|
|
||||||
|
|
||||||
TcpSetState (Tcb, TCP_LISTEN);
|
|
||||||
SockSetState (Sk, SO_LISTENING);
|
|
||||||
|
|
||||||
Sk->ConfigureState = SO_CONFIGURED_PASSIVE;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
Sk->ConfigureState = SO_CONFIGURED_ACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpInsertTcb (Tcb);
|
|
||||||
|
|
||||||
OnExit:
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
The procotol handler provided to the socket layer, used to
|
|
||||||
dispatch the socket level requests by calling the corresponding
|
|
||||||
TCP layer functions.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket of this TCP instance.
|
|
||||||
@param Request The code of this operation request.
|
|
||||||
@param Data Pointer to the operation specific data passed in
|
|
||||||
together with the operation request.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The socket request is completed successfully.
|
|
||||||
@retval other The error status returned by the corresponding TCP
|
|
||||||
layer function.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4Dispatcher (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN UINT8 Request,
|
|
||||||
IN VOID *Data OPTIONAL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP_CB *Tcb;
|
|
||||||
TCP4_PROTO_DATA *ProtoData;
|
|
||||||
EFI_IP4_PROTOCOL *Ip;
|
|
||||||
|
|
||||||
ProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
|
||||||
Tcb = ProtoData->TcpPcb;
|
|
||||||
|
|
||||||
switch (Request) {
|
|
||||||
case SOCK_POLL:
|
|
||||||
Ip = ProtoData->TcpService->IpIo->Ip.Ip4;
|
|
||||||
Ip->Poll (Ip);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOCK_CONSUMED:
|
|
||||||
//
|
|
||||||
// After user received data from socket buffer, socket will
|
|
||||||
// notify TCP using this message to give it a chance to send out
|
|
||||||
// window update information
|
|
||||||
//
|
|
||||||
ASSERT (Tcb != NULL);
|
|
||||||
TcpOnAppConsume (Tcb);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOCK_SND:
|
|
||||||
|
|
||||||
ASSERT (Tcb != NULL);
|
|
||||||
TcpOnAppSend (Tcb);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOCK_CLOSE:
|
|
||||||
|
|
||||||
TcpOnAppClose (Tcb);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOCK_ABORT:
|
|
||||||
|
|
||||||
TcpOnAppAbort (Tcb);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOCK_SNDPUSH:
|
|
||||||
Tcb->SndPsh = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk);
|
|
||||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_PSH);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOCK_SNDURG:
|
|
||||||
Tcb->SndUp = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk) - 1;
|
|
||||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_URG);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOCK_CONNECT:
|
|
||||||
|
|
||||||
TcpOnAppConnect (Tcb);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOCK_ATTACH:
|
|
||||||
|
|
||||||
return Tcp4AttachPcb (Sock);
|
|
||||||
|
|
||||||
case SOCK_FLUSH:
|
|
||||||
|
|
||||||
Tcp4FlushPcb (Tcb);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOCK_DETACH:
|
|
||||||
|
|
||||||
Tcp4DetachPcb (Sock);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOCK_CONFIGURE:
|
|
||||||
|
|
||||||
return Tcp4ConfigurePcb (
|
|
||||||
Sock,
|
|
||||||
(EFI_TCP4_CONFIG_DATA *) Data
|
|
||||||
);
|
|
||||||
|
|
||||||
case SOCK_MODE:
|
|
||||||
|
|
||||||
ASSERT ((Data != NULL) && (Tcb != NULL));
|
|
||||||
|
|
||||||
return Tcp4GetMode (Tcb, (TCP4_MODE_DATA *) Data);
|
|
||||||
|
|
||||||
case SOCK_ROUTE:
|
|
||||||
|
|
||||||
ASSERT ((Data != NULL) && (Tcb != NULL));
|
|
||||||
|
|
||||||
return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *) Data);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
|
|
||||||
}
|
|
@ -1,782 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Tcp driver function.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "Tcp4Main.h"
|
|
||||||
|
|
||||||
|
|
||||||
UINT16 mTcp4RandomPort;
|
|
||||||
extern EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName;
|
|
||||||
extern EFI_COMPONENT_NAME2_PROTOCOL gTcp4ComponentName2;
|
|
||||||
extern EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable;
|
|
||||||
|
|
||||||
TCP4_HEARTBEAT_TIMER mTcp4Timer = {
|
|
||||||
NULL,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
EFI_TCP4_PROTOCOL mTcp4ProtocolTemplate = {
|
|
||||||
Tcp4GetModeData,
|
|
||||||
Tcp4Configure,
|
|
||||||
Tcp4Routes,
|
|
||||||
Tcp4Connect,
|
|
||||||
Tcp4Accept,
|
|
||||||
Tcp4Transmit,
|
|
||||||
Tcp4Receive,
|
|
||||||
Tcp4Close,
|
|
||||||
Tcp4Cancel,
|
|
||||||
Tcp4Poll
|
|
||||||
};
|
|
||||||
|
|
||||||
SOCK_INIT_DATA mTcp4DefaultSockData = {
|
|
||||||
SockStream,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
TCP_BACKLOG,
|
|
||||||
TCP_SND_BUF_SIZE,
|
|
||||||
TCP_RCV_BUF_SIZE,
|
|
||||||
&mTcp4ProtocolTemplate,
|
|
||||||
Tcp4CreateSocketCallback,
|
|
||||||
Tcp4DestroySocketCallback,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
Tcp4Dispatcher,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
EFI_DRIVER_BINDING_PROTOCOL mTcp4DriverBinding = {
|
|
||||||
Tcp4DriverBindingSupported,
|
|
||||||
Tcp4DriverBindingStart,
|
|
||||||
Tcp4DriverBindingStop,
|
|
||||||
0xa,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
EFI_SERVICE_BINDING_PROTOCOL mTcp4ServiceBinding = {
|
|
||||||
Tcp4ServiceBindingCreateChild,
|
|
||||||
Tcp4ServiceBindingDestroyChild
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create and start the heartbeat timer for TCP driver.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The timer is successfully created and started.
|
|
||||||
@retval other The timer is not created.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4CreateTimer (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
|
|
||||||
if (mTcp4Timer.RefCnt == 0) {
|
|
||||||
|
|
||||||
Status = gBS->CreateEvent (
|
|
||||||
EVT_TIMER | EVT_NOTIFY_SIGNAL,
|
|
||||||
TPL_NOTIFY,
|
|
||||||
TcpTicking,
|
|
||||||
NULL,
|
|
||||||
&mTcp4Timer.TimerEvent
|
|
||||||
);
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
Status = gBS->SetTimer (
|
|
||||||
mTcp4Timer.TimerEvent,
|
|
||||||
TimerPeriodic,
|
|
||||||
(UINT64) (TICKS_PER_SECOND / TCP_TICK_HZ)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
mTcp4Timer.RefCnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Stop and destroy the heartbeat timer for TCP driver.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
Tcp4DestroyTimer (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ASSERT (mTcp4Timer.RefCnt > 0);
|
|
||||||
|
|
||||||
mTcp4Timer.RefCnt--;
|
|
||||||
|
|
||||||
if (mTcp4Timer.RefCnt > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gBS->SetTimer (mTcp4Timer.TimerEvent, TimerCancel, 0);
|
|
||||||
gBS->CloseEvent (mTcp4Timer.TimerEvent);
|
|
||||||
mTcp4Timer.TimerEvent = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Callback function which provided by user to remove one node in NetDestroyLinkList process.
|
|
||||||
|
|
||||||
@param[in] Entry The entry to be removed.
|
|
||||||
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The entry has been removed successfully.
|
|
||||||
@retval Others Fail to remove the entry.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4DestroyChildEntryInHandleBuffer (
|
|
||||||
IN LIST_ENTRY *Entry,
|
|
||||||
IN VOID *Context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
|
||||||
UINTN NumberOfChildren;
|
|
||||||
EFI_HANDLE *ChildHandleBuffer;
|
|
||||||
|
|
||||||
if (Entry == NULL || Context == NULL) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE);
|
|
||||||
ServiceBinding = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
|
|
||||||
NumberOfChildren = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
|
|
||||||
ChildHandleBuffer = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
|
|
||||||
|
|
||||||
if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) {
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
The entry point for Tcp4 driver, used to install Tcp4 driver on the ImageHandle.
|
|
||||||
|
|
||||||
@param ImageHandle The firmware allocated handle for this
|
|
||||||
driver image.
|
|
||||||
@param SystemTable Pointer to the EFI system table.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Driver loaded.
|
|
||||||
@retval other Driver not loaded.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4DriverEntryPoint (
|
|
||||||
IN EFI_HANDLE ImageHandle,
|
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
UINT32 Seed;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Install the TCP4 Driver Binding Protocol
|
|
||||||
//
|
|
||||||
Status = EfiLibInstallDriverBindingComponentName2 (
|
|
||||||
ImageHandle,
|
|
||||||
SystemTable,
|
|
||||||
&mTcp4DriverBinding,
|
|
||||||
ImageHandle,
|
|
||||||
&gTcp4ComponentName,
|
|
||||||
&gTcp4ComponentName2
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
//
|
|
||||||
// Initialize ISS and random port.
|
|
||||||
//
|
|
||||||
Seed = NetRandomInitSeed ();
|
|
||||||
mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;
|
|
||||||
mTcp4RandomPort = (UINT16) (TCP4_PORT_KNOWN +
|
|
||||||
(UINT16) (NET_RANDOM(Seed) % TCP4_PORT_KNOWN));
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Tests to see if this driver supports a given controller.
|
|
||||||
|
|
||||||
If a child device is provided, it further tests to see if this driver supports
|
|
||||||
creating a handle for the specified child device.
|
|
||||||
|
|
||||||
@param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
|
||||||
@param ControllerHandle The handle of the controller to test. This handle
|
|
||||||
must support a protocol interface that supplies
|
|
||||||
an I/O abstraction to the driver.
|
|
||||||
@param RemainingDevicePath A pointer to the remaining portion of a device path.
|
|
||||||
This parameter is ignored by device drivers, and is optional for bus drivers.
|
|
||||||
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
|
||||||
RemainingDevicePath is supported by the driver
|
|
||||||
specified by This.
|
|
||||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
|
||||||
RemainingDevicePath is already being managed by
|
|
||||||
the driver specified by This.
|
|
||||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
|
||||||
RemainingDevicePath is already being managed by a
|
|
||||||
different driver or an application that requires
|
|
||||||
exclusive access.
|
|
||||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
|
||||||
RemainingDevicePath is not supported by the driver
|
|
||||||
specified by This.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4DriverBindingSupported (
|
|
||||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Test for the Tcp4ServiceBinding Protocol
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
|
||||||
NULL,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
|
||||||
);
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
return EFI_ALREADY_STARTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Test for the Ip4 Protocol
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiIp4ServiceBindingProtocolGuid,
|
|
||||||
NULL,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
|
||||||
);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Start this driver on ControllerHandle.
|
|
||||||
|
|
||||||
The Start() function is designed to be invoked from the EFI boot service
|
|
||||||
ConnectController(). As a result, much of the error checking on the parameters
|
|
||||||
to Start() has been moved into this common boot service. It is legal to call
|
|
||||||
Start() from other locations, but the following calling restrictions must be
|
|
||||||
followed or the system behavior will not be deterministic.
|
|
||||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
|
||||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally
|
|
||||||
aligned EFI_DEVICE_PATH_PROTOCOL.
|
|
||||||
3. Prior to calling Start(), the Supported() function for the driver specified
|
|
||||||
by This must have been called with the same calling parameters, and Supported()
|
|
||||||
must have returned EFI_SUCCESS.
|
|
||||||
|
|
||||||
@param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
|
||||||
@param ControllerHandle The handle of the controller to start. This handle
|
|
||||||
must support a protocol interface that supplies
|
|
||||||
an I/O abstraction to the driver.
|
|
||||||
@param RemainingDevicePath A pointer to the remaining portion of a device path.
|
|
||||||
This parameter is ignored by device drivers, and is
|
|
||||||
optional for bus drivers.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The device was started.
|
|
||||||
@retval EFI_ALREADY_STARTED The device could not be started due to a device error.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
|
|
||||||
of resources.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4DriverBindingStart (
|
|
||||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
TCP4_SERVICE_DATA *TcpServiceData;
|
|
||||||
IP_IO_OPEN_DATA OpenData;
|
|
||||||
|
|
||||||
TcpServiceData = AllocateZeroPool (sizeof (TCP4_SERVICE_DATA));
|
|
||||||
|
|
||||||
if (NULL == TcpServiceData) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"
|
|
||||||
" resource to create a Tcp Servcie Data\n"));
|
|
||||||
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Create a new IP IO to Consume it
|
|
||||||
//
|
|
||||||
TcpServiceData->IpIo = IpIoCreate (
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle,
|
|
||||||
IP_VERSION_4
|
|
||||||
);
|
|
||||||
if (NULL == TcpServiceData->IpIo) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"
|
|
||||||
" resource to create an Ip Io\n"));
|
|
||||||
|
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
|
||||||
goto ON_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Configure and start IpIo.
|
|
||||||
//
|
|
||||||
ZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA));
|
|
||||||
|
|
||||||
CopyMem (
|
|
||||||
&OpenData.IpConfigData.Ip4CfgData,
|
|
||||||
&mIp4IoDefaultIpConfigData,
|
|
||||||
sizeof (EFI_IP4_CONFIG_DATA)
|
|
||||||
);
|
|
||||||
|
|
||||||
OpenData.IpConfigData.Ip4CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;
|
|
||||||
|
|
||||||
OpenData.PktRcvdNotify = Tcp4RxCallback;
|
|
||||||
Status = IpIoOpen (TcpServiceData->IpIo, &OpenData);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto ON_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Create the timer event used by TCP driver
|
|
||||||
//
|
|
||||||
Status = Tcp4CreateTimer ();
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Create TcpTimer"
|
|
||||||
" Event failed with %r\n", Status));
|
|
||||||
|
|
||||||
goto ON_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Install the Tcp4ServiceBinding Protocol on the
|
|
||||||
// controller handle
|
|
||||||
//
|
|
||||||
TcpServiceData->Tcp4ServiceBinding = mTcp4ServiceBinding;
|
|
||||||
|
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
||||||
&ControllerHandle,
|
|
||||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
|
||||||
&TcpServiceData->Tcp4ServiceBinding,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Install Tcp4 Service Binding"
|
|
||||||
" Protocol failed for %r\n", Status));
|
|
||||||
|
|
||||||
Tcp4DestroyTimer ();
|
|
||||||
goto ON_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize member in TcpServiceData
|
|
||||||
//
|
|
||||||
TcpServiceData->ControllerHandle = ControllerHandle;
|
|
||||||
TcpServiceData->Signature = TCP4_DRIVER_SIGNATURE;
|
|
||||||
TcpServiceData->DriverBindingHandle = This->DriverBindingHandle;
|
|
||||||
|
|
||||||
InitializeListHead (&TcpServiceData->SocketList);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
|
|
||||||
ON_ERROR:
|
|
||||||
|
|
||||||
if (TcpServiceData->IpIo != NULL) {
|
|
||||||
IpIoDestroy (TcpServiceData->IpIo);
|
|
||||||
TcpServiceData->IpIo = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FreePool (TcpServiceData);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Stop this driver on ControllerHandle.
|
|
||||||
|
|
||||||
The Stop() function is designed to be invoked from the EFI boot service
|
|
||||||
DisconnectController(). As a result, much of the error checking on the parameters
|
|
||||||
to Stop() has been moved into this common boot service. It is legal to call Stop()
|
|
||||||
from other locations, but the following calling restrictions must be followed
|
|
||||||
or the system behavior will not be deterministic.
|
|
||||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call
|
|
||||||
to this same driver's Start() function.
|
|
||||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
|
||||||
EFI_HANDLE. In addition, all of these handles must have been created in this
|
|
||||||
driver's Start() function, and the Start() function must have called OpenProtocol()
|
|
||||||
on ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
|
||||||
|
|
||||||
@param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
|
||||||
@param ControllerHandle A handle to the device being stopped. The handle must
|
|
||||||
support a bus specific I/O protocol for the driver
|
|
||||||
to use to stop the device.
|
|
||||||
@param NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
|
||||||
@param ChildHandleBuffer An array of child handles to be freed. May be NULL if
|
|
||||||
NumberOfChildren is 0.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The device was stopped.
|
|
||||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4DriverBindingStop (
|
|
||||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN UINTN NumberOfChildren,
|
|
||||||
IN EFI_HANDLE *ChildHandleBuffer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_HANDLE NicHandle;
|
|
||||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
|
||||||
TCP4_SERVICE_DATA *TcpServiceData;
|
|
||||||
LIST_ENTRY *List;
|
|
||||||
TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
|
|
||||||
|
|
||||||
// Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
|
|
||||||
//
|
|
||||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
|
|
||||||
if (NicHandle == NULL) {
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Retrieve the TCP driver Data Structure
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
NicHandle,
|
|
||||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
|
||||||
(VOID **) &ServiceBinding,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStop: Locate Tcp4 Service "
|
|
||||||
" Binding Protocol failed with %r\n", Status));
|
|
||||||
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpServiceData = TCP4_FROM_THIS (ServiceBinding);
|
|
||||||
|
|
||||||
if (NumberOfChildren != 0) {
|
|
||||||
List = &TcpServiceData->SocketList;
|
|
||||||
Context.ServiceBinding = ServiceBinding;
|
|
||||||
Context.NumberOfChildren = NumberOfChildren;
|
|
||||||
Context.ChildHandleBuffer = ChildHandleBuffer;
|
|
||||||
Status = NetDestroyLinkList (
|
|
||||||
List,
|
|
||||||
Tcp4DestroyChildEntryInHandleBuffer,
|
|
||||||
&Context,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
} else if (IsListEmpty (&TcpServiceData->SocketList)) {
|
|
||||||
//
|
|
||||||
// Uninstall TCP servicebinding protocol
|
|
||||||
//
|
|
||||||
gBS->UninstallMultipleProtocolInterfaces (
|
|
||||||
NicHandle,
|
|
||||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
|
||||||
ServiceBinding,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Destroy the IpIO consumed by TCP driver
|
|
||||||
//
|
|
||||||
IpIoDestroy (TcpServiceData->IpIo);
|
|
||||||
TcpServiceData->IpIo = NULL;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Destroy the heartbeat timer.
|
|
||||||
//
|
|
||||||
Tcp4DestroyTimer ();
|
|
||||||
|
|
||||||
if (gTcpControllerNameTable != NULL) {
|
|
||||||
FreeUnicodeStringTable (gTcpControllerNameTable);
|
|
||||||
gTcpControllerNameTable = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Release the TCP service data
|
|
||||||
//
|
|
||||||
FreePool (TcpServiceData);
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Open Ip4 and device path protocols for a created socket, and insert it in
|
|
||||||
socket list.
|
|
||||||
|
|
||||||
@param This Pointer to the socket just created
|
|
||||||
@param Context Context of the socket
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS This protocol is installed successfully.
|
|
||||||
@retval other Some error occured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4CreateSocketCallback (
|
|
||||||
IN SOCKET *This,
|
|
||||||
IN VOID *Context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
TCP4_SERVICE_DATA *TcpServiceData;
|
|
||||||
EFI_IP4_PROTOCOL *Ip4;
|
|
||||||
|
|
||||||
TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Open the default Ip4 protocol of IP_IO BY_DRIVER.
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
TcpServiceData->IpIo->ChildHandle,
|
|
||||||
&gEfiIp4ProtocolGuid,
|
|
||||||
(VOID **) &Ip4,
|
|
||||||
TcpServiceData->DriverBindingHandle,
|
|
||||||
This->SockHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Open the device path on the handle where service binding resides on.
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
TcpServiceData->ControllerHandle,
|
|
||||||
&gEfiDevicePathProtocolGuid,
|
|
||||||
(VOID **) &This->ParentDevicePath,
|
|
||||||
TcpServiceData->DriverBindingHandle,
|
|
||||||
This->SockHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
gBS->CloseProtocol (
|
|
||||||
TcpServiceData->IpIo->ChildHandle,
|
|
||||||
&gEfiIp4ProtocolGuid,
|
|
||||||
TcpServiceData->DriverBindingHandle,
|
|
||||||
This->SockHandle
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// Insert this socket into the SocketList.
|
|
||||||
//
|
|
||||||
InsertTailList (&TcpServiceData->SocketList, &This->Link);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Close Ip4 and device path protocols for a socket, and remove it from socket list.
|
|
||||||
|
|
||||||
@param This Pointer to the socket to be removed
|
|
||||||
@param Context Context of the socket
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
Tcp4DestroySocketCallback (
|
|
||||||
IN SOCKET *This,
|
|
||||||
IN VOID *Context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP4_SERVICE_DATA *TcpServiceData;
|
|
||||||
|
|
||||||
TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Remove this node from the list.
|
|
||||||
//
|
|
||||||
RemoveEntryList (&This->Link);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Close the Ip4 protocol.
|
|
||||||
//
|
|
||||||
gBS->CloseProtocol (
|
|
||||||
TcpServiceData->IpIo->ChildHandle,
|
|
||||||
&gEfiIp4ProtocolGuid,
|
|
||||||
TcpServiceData->DriverBindingHandle,
|
|
||||||
This->SockHandle
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Creates a child handle and installs a protocol.
|
|
||||||
|
|
||||||
The CreateChild() function installs a protocol on ChildHandle. If ChildHandle
|
|
||||||
is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
|
||||||
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing
|
|
||||||
ChildHandle.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
|
||||||
@param ChildHandle Pointer to the handle of the child to create. If it is NULL, then
|
|
||||||
a new handle is created. If it is a pointer to an existing UEFI
|
|
||||||
handle, then the protocol is added to the existing UEFI handle.
|
|
||||||
|
|
||||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
|
||||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
|
||||||
the child.
|
|
||||||
@retval other The child handle was not created.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4ServiceBindingCreateChild (
|
|
||||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
|
||||||
IN OUT EFI_HANDLE *ChildHandle
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
TCP4_SERVICE_DATA *TcpServiceData;
|
|
||||||
TCP4_PROTO_DATA TcpProto;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_TPL OldTpl;
|
|
||||||
|
|
||||||
if (NULL == This || NULL == ChildHandle) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
TcpServiceData = TCP4_FROM_THIS (This);
|
|
||||||
TcpProto.TcpService = TcpServiceData;
|
|
||||||
TcpProto.TcpPcb = NULL;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Create a tcp instance with defualt Tcp default
|
|
||||||
// sock init data and TcpProto
|
|
||||||
//
|
|
||||||
mTcp4DefaultSockData.ProtoData = &TcpProto;
|
|
||||||
mTcp4DefaultSockData.DataSize = sizeof (TCP4_PROTO_DATA);
|
|
||||||
mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;
|
|
||||||
|
|
||||||
Sock = SockCreateChild (&mTcp4DefaultSockData);
|
|
||||||
if (NULL == Sock) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingCreateChild: "
|
|
||||||
"No resource to create a Tcp Child\n"));
|
|
||||||
|
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
|
||||||
} else {
|
|
||||||
*ChildHandle = Sock->SockHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
mTcp4DefaultSockData.ProtoData = NULL;
|
|
||||||
|
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Destroys a child handle with a protocol installed on it.
|
|
||||||
|
|
||||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
|
||||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
|
||||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
|
||||||
@param ChildHandle Handle of the child to destroy
|
|
||||||
|
|
||||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
|
||||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is
|
|
||||||
being removed.
|
|
||||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
|
||||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
|
||||||
because its services are being used.
|
|
||||||
@retval other The child handle was not destroyed.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4ServiceBindingDestroyChild (
|
|
||||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ChildHandle
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_TCP4_PROTOCOL *Tcp4;
|
|
||||||
SOCKET *Sock;
|
|
||||||
|
|
||||||
if (NULL == This || NULL == ChildHandle) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// retrieve the Tcp4 protocol from ChildHandle
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
ChildHandle,
|
|
||||||
&gEfiTcp4ProtocolGuid,
|
|
||||||
(VOID **) &Tcp4,
|
|
||||||
mTcp4DriverBinding.DriverBindingHandle,
|
|
||||||
ChildHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
Status = EFI_UNSUPPORTED;
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// destroy this sock and related Tcp protocol control
|
|
||||||
// block
|
|
||||||
//
|
|
||||||
Sock = SOCK_FROM_THIS (Tcp4);
|
|
||||||
|
|
||||||
SockDestroyChild (Sock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
@ -1,342 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Tcp driver function header.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#ifndef _TCP4_DRIVER_H_
|
|
||||||
#define _TCP4_DRIVER_H_
|
|
||||||
|
|
||||||
#include <Protocol/ServiceBinding.h>
|
|
||||||
#include <Library/IpIoLib.h>
|
|
||||||
|
|
||||||
#define TCP4_DRIVER_SIGNATURE SIGNATURE_32 ('T', 'C', 'P', '4')
|
|
||||||
|
|
||||||
#define TCP4_PORT_KNOWN 1024
|
|
||||||
#define TCP4_PORT_USER_RESERVED 65535
|
|
||||||
|
|
||||||
#define TCP4_FROM_THIS(a) \
|
|
||||||
CR ( \
|
|
||||||
(a), \
|
|
||||||
TCP4_SERVICE_DATA, \
|
|
||||||
Tcp4ServiceBinding, \
|
|
||||||
TCP4_DRIVER_SIGNATURE \
|
|
||||||
)
|
|
||||||
|
|
||||||
///
|
|
||||||
/// TCP heartbeat tick timer.
|
|
||||||
///
|
|
||||||
typedef struct _TCP4_HEARTBEAT_TIMER {
|
|
||||||
EFI_EVENT TimerEvent; ///< The event assoiated with the timer
|
|
||||||
INTN RefCnt; ///< Number of reference
|
|
||||||
} TCP4_HEARTBEAT_TIMER;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// TCP service data
|
|
||||||
///
|
|
||||||
typedef struct _TCP4_SERVICE_DATA {
|
|
||||||
UINT32 Signature;
|
|
||||||
EFI_HANDLE ControllerHandle;
|
|
||||||
IP_IO *IpIo; // IP Io consumed by TCP4
|
|
||||||
EFI_SERVICE_BINDING_PROTOCOL Tcp4ServiceBinding;
|
|
||||||
EFI_HANDLE DriverBindingHandle;
|
|
||||||
LIST_ENTRY SocketList;
|
|
||||||
} TCP4_SERVICE_DATA;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// TCP protocol data
|
|
||||||
///
|
|
||||||
typedef struct _TCP4_PROTO_DATA {
|
|
||||||
TCP4_SERVICE_DATA *TcpService;
|
|
||||||
TCP_CB *TcpPcb;
|
|
||||||
} TCP4_PROTO_DATA;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Packet receive callback function provided to IP_IO, used to call
|
|
||||||
the proper function to handle the packet received by IP.
|
|
||||||
|
|
||||||
@param Status Status of the received packet.
|
|
||||||
@param IcmpErr ICMP error number.
|
|
||||||
@param NetSession Pointer to the net session of this packet.
|
|
||||||
@param Pkt Pointer to the recieved packet.
|
|
||||||
@param Context Pointer to the context configured in IpIoOpen(), not used
|
|
||||||
now.
|
|
||||||
|
|
||||||
@return None
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
Tcp4RxCallback (
|
|
||||||
IN EFI_STATUS Status,
|
|
||||||
IN UINT8 IcmpErr,
|
|
||||||
IN EFI_NET_SESSION_DATA *NetSession,
|
|
||||||
IN NET_BUF *Pkt,
|
|
||||||
IN VOID *Context OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Send the segment to IP via IpIo function.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Nbuf Pointer to the TCP segment to be sent.
|
|
||||||
@param Src Source address of the TCP segment.
|
|
||||||
@param Dest Destination address of the TCP segment.
|
|
||||||
|
|
||||||
@retval 0 The segment was sent out successfully.
|
|
||||||
@retval -1 The segment was failed to send.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpSendIpPacket (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN NET_BUF *Nbuf,
|
|
||||||
IN UINT32 Src,
|
|
||||||
IN UINT32 Dest
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
The procotol handler provided to the socket layer, used to
|
|
||||||
dispatch the socket level requests by calling the corresponding
|
|
||||||
TCP layer functions.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket of this TCP instance.
|
|
||||||
@param Request The code of this operation request.
|
|
||||||
@param Data Pointer to the operation specific data passed in
|
|
||||||
together with the operation request.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The socket request is completed successfully.
|
|
||||||
@retval other The error status returned by the corresponding TCP
|
|
||||||
layer function.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4Dispatcher (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN UINT8 Request,
|
|
||||||
IN VOID *Data OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
The entry point for Tcp4 driver, used to install Tcp4 driver on the ImageHandle.
|
|
||||||
|
|
||||||
@param ImageHandle The firmware allocated handle for this
|
|
||||||
driver image.
|
|
||||||
@param SystemTable Pointer to the EFI system table.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Driver loaded.
|
|
||||||
@retval other Driver not loaded.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4DriverEntryPoint (
|
|
||||||
IN EFI_HANDLE ImageHandle,
|
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Tests to see if this driver supports a given controller.
|
|
||||||
|
|
||||||
If a child device is provided, it further tests to see if this driver supports
|
|
||||||
creating a handle for the specified child device.
|
|
||||||
|
|
||||||
@param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
|
||||||
@param ControllerHandle The handle of the controller to test. This handle
|
|
||||||
must support a protocol interface that supplies
|
|
||||||
an I/O abstraction to the driver.
|
|
||||||
@param RemainingDevicePath A pointer to the remaining portion of a device path.
|
|
||||||
This parameter is ignored by device drivers, and is optional for bus drivers.
|
|
||||||
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
|
||||||
RemainingDevicePath is supported by the driver
|
|
||||||
specified by This.
|
|
||||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
|
||||||
RemainingDevicePath is already being managed by
|
|
||||||
the driver specified by This.
|
|
||||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
|
||||||
RemainingDevicePath is already being managed by a
|
|
||||||
different driver or an application that requires
|
|
||||||
exclusive access.
|
|
||||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
|
||||||
RemainingDevicePath is not supported by the driver
|
|
||||||
specified by This.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4DriverBindingSupported (
|
|
||||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Start this driver on ControllerHandle.
|
|
||||||
|
|
||||||
The Start() function is designed to be invoked from the EFI boot service
|
|
||||||
ConnectController(). As a result, much of the error checking on the parameters
|
|
||||||
to Start() has been moved into this common boot service. It is legal to call
|
|
||||||
Start() from other locations, but the following calling restrictions must be
|
|
||||||
followed or the system behavior will not be deterministic.
|
|
||||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
|
||||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally
|
|
||||||
aligned EFI_DEVICE_PATH_PROTOCOL.
|
|
||||||
3. Prior to calling Start(), the Supported() function for the driver specified
|
|
||||||
by This must have been called with the same calling parameters, and Supported()
|
|
||||||
must have returned EFI_SUCCESS.
|
|
||||||
|
|
||||||
@param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
|
||||||
@param ControllerHandle The handle of the controller to start. This handle
|
|
||||||
must support a protocol interface that supplies
|
|
||||||
an I/O abstraction to the driver.
|
|
||||||
@param RemainingDevicePath A pointer to the remaining portion of a device path.
|
|
||||||
This parameter is ignored by device drivers, and is
|
|
||||||
optional for bus drivers.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The device was started.
|
|
||||||
@retval EFI_ALREADY_STARTED The device could not be started due to a device error.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
|
|
||||||
of resources.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4DriverBindingStart (
|
|
||||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Stop this driver on ControllerHandle.
|
|
||||||
|
|
||||||
The Stop() function is designed to be invoked from the EFI boot service
|
|
||||||
DisconnectController(). As a result, much of the error checking on the parameters
|
|
||||||
to Stop() has been moved into this common boot service. It is legal to call Stop()
|
|
||||||
from other locations, but the following calling restrictions must be followed
|
|
||||||
or the system behavior will not be deterministic.
|
|
||||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call
|
|
||||||
to this same driver's Start() function.
|
|
||||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
|
||||||
EFI_HANDLE. In addition, all of these handles must have been created in this
|
|
||||||
driver's Start() function, and the Start() function must have called OpenProtocol()
|
|
||||||
on ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
|
||||||
|
|
||||||
@param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
|
||||||
@param ControllerHandle A handle to the device being stopped. The handle must
|
|
||||||
support a bus specific I/O protocol for the driver
|
|
||||||
to use to stop the device.
|
|
||||||
@param NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
|
||||||
@param ChildHandleBuffer An array of child handles to be freed. May be NULL if
|
|
||||||
NumberOfChildren is 0.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The device was stopped.
|
|
||||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4DriverBindingStop (
|
|
||||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN UINTN NumberOfChildren,
|
|
||||||
IN EFI_HANDLE *ChildHandleBuffer
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Open Ip4 and device path protocols for a created socket, and insert it in
|
|
||||||
socket list.
|
|
||||||
|
|
||||||
@param This Pointer to the socket just created
|
|
||||||
@param Context Context of the socket
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS This protocol is installed successfully.
|
|
||||||
@retval other Some error occured.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4CreateSocketCallback (
|
|
||||||
IN SOCKET *This,
|
|
||||||
IN VOID *Context
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Close Ip4 and device path protocols for a socket, and remove it from socket list.
|
|
||||||
|
|
||||||
@param This Pointer to the socket to be removed
|
|
||||||
@param Context Context of the socket
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
Tcp4DestroySocketCallback (
|
|
||||||
IN SOCKET *This,
|
|
||||||
IN VOID *Context
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Creates a child handle and installs a protocol.
|
|
||||||
|
|
||||||
The CreateChild() function installs a protocol on ChildHandle. If ChildHandle
|
|
||||||
is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
|
||||||
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing
|
|
||||||
ChildHandle.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
|
||||||
@param ChildHandle Pointer to the handle of the child to create. If it is NULL, then
|
|
||||||
a new handle is created. If it is a pointer to an existing UEFI
|
|
||||||
handle, then the protocol is added to the existing UEFI handle.
|
|
||||||
|
|
||||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
|
||||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
|
||||||
the child.
|
|
||||||
@retval other The child handle was not created.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4ServiceBindingCreateChild (
|
|
||||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
|
||||||
IN OUT EFI_HANDLE *ChildHandle
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Destroys a child handle with a protocol installed on it.
|
|
||||||
|
|
||||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
|
||||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
|
||||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
|
||||||
@param ChildHandle Handle of the child to destroy
|
|
||||||
|
|
||||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
|
||||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is
|
|
||||||
being removed.
|
|
||||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
|
||||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
|
||||||
because its services are being used.
|
|
||||||
@retval other The child handle was not destroyed.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4ServiceBindingDestroyChild (
|
|
||||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ChildHandle
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,94 +0,0 @@
|
|||||||
## @file
|
|
||||||
# This module produces EFI TCPv4 Protocol and EFI TCPv4 Service Binding Protocol.
|
|
||||||
#
|
|
||||||
# This module produces EFI TCPv4(Transmission Control Protocol version 4) Protocol
|
|
||||||
# upon EFI IPv4 Protocol, to provide basic TCPv4 I/O services. This driver only
|
|
||||||
# supports IPv4 network stack.
|
|
||||||
#
|
|
||||||
# Notes:
|
|
||||||
# 1) This driver can't co-work with the TcpDxe driver in NetworkPkg.
|
|
||||||
# 2) This driver might have some issues that have been fixed in the TcpDxe driver
|
|
||||||
# in NetworkPkg.
|
|
||||||
# 3) This driver supports fewer features than the TcpDxe driver in NetworkPkg (e.g. IPv6,
|
|
||||||
# TCP Cancel function).
|
|
||||||
# 4) TcpDxe driver in NetworkPkg is recommended for use instead of this one even though
|
|
||||||
# both of them can be used.
|
|
||||||
#
|
|
||||||
# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
# This program and the accompanying materials
|
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
# which accompanies this distribution. The full text of the license may be found at
|
|
||||||
# http://opensource.org/licenses/bsd-license.php
|
|
||||||
#
|
|
||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
##
|
|
||||||
|
|
||||||
[Defines]
|
|
||||||
INF_VERSION = 0x00010005
|
|
||||||
BASE_NAME = Tcp4Dxe
|
|
||||||
MODULE_UNI_FILE = Tcp4Dxe.uni
|
|
||||||
FILE_GUID = 6d6963ab-906d-4a65-a7ca-bd40e5d6af4d
|
|
||||||
MODULE_TYPE = UEFI_DRIVER
|
|
||||||
VERSION_STRING = 1.0
|
|
||||||
ENTRY_POINT = Tcp4DriverEntryPoint
|
|
||||||
UNLOAD_IMAGE = NetLibDefaultUnload
|
|
||||||
#
|
|
||||||
# The following information is for reference only and not required by the build tools.
|
|
||||||
#
|
|
||||||
# VALID_ARCHITECTURES = IA32 X64 EBC
|
|
||||||
#
|
|
||||||
# DRIVER_BINDING = mTcp4DriverBinding
|
|
||||||
# COMPONENT_NAME = gTcp4ComponentName
|
|
||||||
# COMPONENT_NAME2 = gTcp4ComponentName2
|
|
||||||
#
|
|
||||||
|
|
||||||
[Sources]
|
|
||||||
SockImpl.c
|
|
||||||
SockInterface.c
|
|
||||||
Tcp4Proto.h
|
|
||||||
Tcp4Main.h
|
|
||||||
SockImpl.h
|
|
||||||
Tcp4Output.c
|
|
||||||
Tcp4Timer.c
|
|
||||||
Tcp4Option.h
|
|
||||||
Tcp4Dispatcher.c
|
|
||||||
Tcp4Input.c
|
|
||||||
Tcp4Misc.c
|
|
||||||
Tcp4Main.c
|
|
||||||
Socket.h
|
|
||||||
ComponentName.c
|
|
||||||
Tcp4Driver.h
|
|
||||||
Tcp4Io.c
|
|
||||||
Tcp4Driver.c
|
|
||||||
Tcp4Func.h
|
|
||||||
Tcp4Option.c
|
|
||||||
|
|
||||||
|
|
||||||
[Packages]
|
|
||||||
MdePkg/MdePkg.dec
|
|
||||||
MdeModulePkg/MdeModulePkg.dec
|
|
||||||
|
|
||||||
[LibraryClasses]
|
|
||||||
UefiLib
|
|
||||||
UefiBootServicesTableLib
|
|
||||||
UefiDriverEntryPoint
|
|
||||||
UefiRuntimeServicesTableLib
|
|
||||||
BaseMemoryLib
|
|
||||||
MemoryAllocationLib
|
|
||||||
DebugLib
|
|
||||||
NetLib
|
|
||||||
IpIoLib
|
|
||||||
DevicePathLib
|
|
||||||
DpcLib
|
|
||||||
|
|
||||||
[Protocols]
|
|
||||||
gEfiTcp4ServiceBindingProtocolGuid ## BY_START
|
|
||||||
gEfiIp4ServiceBindingProtocolGuid ## TO_START
|
|
||||||
gEfiTcp4ProtocolGuid ## BY_START
|
|
||||||
gEfiIp4ProtocolGuid ## TO_START
|
|
||||||
|
|
||||||
[UserExtensions.TianoCore."ExtraFiles"]
|
|
||||||
Tcp4DxeExtra.uni
|
|
@ -1,23 +0,0 @@
|
|||||||
// /** @file
|
|
||||||
// This module produces EFI TCPv4 Protocol and EFI TCPv4 Service Binding Protocol.
|
|
||||||
//
|
|
||||||
// This module produces EFI TCPv4(Transmission Control Protocol version 4) Protocol
|
|
||||||
// upon EFI IPv4 Protocol, to provide basic TCPv4 I/O services.
|
|
||||||
//
|
|
||||||
// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials
|
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
// which accompanies this distribution. The full text of the license may be found at
|
|
||||||
// http://opensource.org/licenses/bsd-license.php
|
|
||||||
//
|
|
||||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
//
|
|
||||||
// **/
|
|
||||||
|
|
||||||
|
|
||||||
#string STR_MODULE_ABSTRACT #language en-US "Produces EFI TCPv4 Protocol and EFI TCPv4 Service Binding Protocol"
|
|
||||||
|
|
||||||
#string STR_MODULE_DESCRIPTION #language en-US "This module produces EFI TCPv4(Transmission Control Protocol version 4) Protocol upon EFI IPv4 Protocol to provide basic TCPv4 I/O services."
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
|||||||
// /** @file
|
|
||||||
// Tcp4Dxe Localized Strings and Content
|
|
||||||
//
|
|
||||||
// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials
|
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
// which accompanies this distribution. The full text of the license may be found at
|
|
||||||
// http://opensource.org/licenses/bsd-license.php
|
|
||||||
//
|
|
||||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
//
|
|
||||||
// **/
|
|
||||||
|
|
||||||
#string STR_PROPERTIES_MODULE_NAME
|
|
||||||
#language en-US
|
|
||||||
"TCP v4 DXE Driver"
|
|
||||||
|
|
||||||
|
|
@ -1,781 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Tcp function header file.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#ifndef _TCP4_FUNC_H_
|
|
||||||
#define _TCP4_FUNC_H_
|
|
||||||
|
|
||||||
//
|
|
||||||
// Declaration of all the functions in TCP
|
|
||||||
// protocol. It is intended to keep tcp.h
|
|
||||||
// clear.
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Functions in tcp.c
|
|
||||||
//
|
|
||||||
|
|
||||||
/**
|
|
||||||
Try to find one Tcb whose <Ip, Port> equals to <IN Addr, IN Port>.
|
|
||||||
|
|
||||||
@param Addr Pointer to the IP address needs to match.
|
|
||||||
@param Port The port number needs to match.
|
|
||||||
|
|
||||||
@return The Tcb which matches the <Addr Port> paire exists or not.
|
|
||||||
|
|
||||||
**/
|
|
||||||
BOOLEAN
|
|
||||||
TcpFindTcbByPeer (
|
|
||||||
IN EFI_IPv4_ADDRESS *Addr,
|
|
||||||
IN TCP_PORTNO Port
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Locate the TCP_CB related to the socket pair.
|
|
||||||
|
|
||||||
@param LocalPort The local port number.
|
|
||||||
@param LocalIp The local IP address.
|
|
||||||
@param RemotePort The remote port number.
|
|
||||||
@param RemoteIp The remote IP address.
|
|
||||||
@param Syn Whether to search the listen sockets, if TRUE, the
|
|
||||||
listen sockets are searched.
|
|
||||||
|
|
||||||
@return Pointer to the related TCP_CB, if NULL no match is found.
|
|
||||||
|
|
||||||
**/
|
|
||||||
TCP_CB *
|
|
||||||
TcpLocateTcb (
|
|
||||||
IN TCP_PORTNO LocalPort,
|
|
||||||
IN UINT32 LocalIp,
|
|
||||||
IN TCP_PORTNO RemotePort,
|
|
||||||
IN UINT32 RemoteIp,
|
|
||||||
IN BOOLEAN Syn
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Insert a Tcb into the proper queue.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB to be inserted.
|
|
||||||
|
|
||||||
@retval 0 The Tcb is inserted successfully.
|
|
||||||
@retval -1 Error condition occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpInsertTcb (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Clone a TCP_CB from Tcb.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB to be cloned.
|
|
||||||
|
|
||||||
@return Pointer to the new cloned TCP_CB, if NULL error condition occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
TCP_CB *
|
|
||||||
TcpCloneTcb (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compute an ISS to be used by a new connection.
|
|
||||||
|
|
||||||
@return The result ISS.
|
|
||||||
|
|
||||||
**/
|
|
||||||
TCP_SEQNO
|
|
||||||
TcpGetIss (
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initialize the Tcb local related members.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpInitTcbLocal (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initialize the peer related members.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Seg Pointer to the segment that contains the peer's
|
|
||||||
intial info.
|
|
||||||
@param Opt Pointer to the options announced by the peer.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpInitTcbPeer (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN TCP_SEG *Seg,
|
|
||||||
IN TCP_OPTION *Opt
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the local mss.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to get mss
|
|
||||||
|
|
||||||
@return The mss size.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT16
|
|
||||||
TcpGetRcvMss (
|
|
||||||
IN SOCKET *Sock
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set the Tcb's state.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param State The state to be set.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpSetState (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN UINT8 State
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Functions in Tcp4Output.c
|
|
||||||
//
|
|
||||||
/**
|
|
||||||
Send the segment to IP via IpIo function.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Nbuf Pointer to the TCP segment to be sent.
|
|
||||||
@param Src Source address of the TCP segment.
|
|
||||||
@param Dest Destination address of the TCP segment.
|
|
||||||
|
|
||||||
@retval 0 The segment was sent out successfully.
|
|
||||||
@retval -1 The segment was failed to send.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpSendIpPacket (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN NET_BUF *Nbuf,
|
|
||||||
IN UINT32 Src,
|
|
||||||
IN UINT32 Dest
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether to send data/SYN/FIN and piggy back an ACK.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Force Whether to ignore the sender's SWS avoidance algorithm and send
|
|
||||||
out data by force.
|
|
||||||
|
|
||||||
@return The number of bytes sent.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpToSendData (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN INTN Force
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether to send an ACK or delayed ACK.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpToSendAck (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Send an ACK immediately.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpSendAck (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Send a zero probe segment. It can be used by keepalive and zero window probe.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
@retval 0 The zero probe segment was sent out successfully.
|
|
||||||
@retval other Error condition occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpSendZeroProbe (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Process the data and FIN flag, check whether to deliver
|
|
||||||
data to the socket layer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
@retval 0 No error occurred to deliver data.
|
|
||||||
@retval -1 Error condition occurred. Proper response is to reset the
|
|
||||||
connection.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpDeliverData (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Send a RESET segment in response to the segment received.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance, may be NULL.
|
|
||||||
@param Head TCP header of the segment that triggers the reset.
|
|
||||||
@param Len Length of the segment that triggers the reset.
|
|
||||||
@param Local Local IP address.
|
|
||||||
@param Remote Remote peer's IP address.
|
|
||||||
|
|
||||||
@retval 0 A reset is sent or no need to send it.
|
|
||||||
@retval -1 No reset is sent.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpSendReset (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN TCP_HEAD *Head,
|
|
||||||
IN INT32 Len,
|
|
||||||
IN UINT32 Local,
|
|
||||||
IN UINT32 Remote
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compute the sequence space left in the old receive window.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
@return The sequence space left in the old receive window.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT32
|
|
||||||
TcpRcvWinOld (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compute the current receive window.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
@return The size of the current receive window, in bytes.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT32
|
|
||||||
TcpRcvWinNow (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Retransmit the segment from sequence Seq.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Seq The sequence number of the segment to be retransmitted.
|
|
||||||
|
|
||||||
@retval 0 Retransmission succeeded.
|
|
||||||
@retval -1 Error condition occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpRetransmit (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN TCP_SEQNO Seq
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compute how much data to send.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Force Whether to ignore the sender's SWS avoidance algorithm and send
|
|
||||||
out data by force.
|
|
||||||
|
|
||||||
@return The length of the data can be sent, if 0, no data can be sent.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT32
|
|
||||||
TcpDataToSend (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN INTN Force
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Verify that the segment is in good shape.
|
|
||||||
|
|
||||||
@param Nbuf Buffer that contains the segment to be checked.
|
|
||||||
|
|
||||||
@retval 0 The segment is broken.
|
|
||||||
@retval 1 The segment is in good shape.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpVerifySegment (
|
|
||||||
IN NET_BUF *Nbuf
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Verify that all the segments in SndQue are in good shape.
|
|
||||||
|
|
||||||
@param Head Pointer to the head node of the SndQue.
|
|
||||||
|
|
||||||
@retval 0 At least one segment is broken.
|
|
||||||
@retval 1 All segments in the specific queue are in good shape.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpCheckSndQue (
|
|
||||||
IN LIST_ENTRY *Head
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get a segment from the Tcb's SndQue.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Seq The sequence number of the segment.
|
|
||||||
@param Len The maximum length of the segment.
|
|
||||||
|
|
||||||
@return Pointer to the segment, if NULL some error occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
NET_BUF *
|
|
||||||
TcpGetSegmentSndQue (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN TCP_SEQNO Seq,
|
|
||||||
IN UINT32 Len
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get a segment from the Tcb's socket buffer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Seq The sequence number of the segment.
|
|
||||||
@param Len The maximum length of the segment.
|
|
||||||
|
|
||||||
@return Pointer to the segment, if NULL some error occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
NET_BUF *
|
|
||||||
TcpGetSegmentSock (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN TCP_SEQNO Seq,
|
|
||||||
IN UINT32 Len
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get a segment starting from sequence Seq of a maximum
|
|
||||||
length of Len.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Seq The sequence number of the segment.
|
|
||||||
@param Len The maximum length of the segment.
|
|
||||||
|
|
||||||
@return Pointer to the segment, if NULL some error occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
NET_BUF *
|
|
||||||
TcpGetSegment (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN TCP_SEQNO Seq,
|
|
||||||
IN UINT32 Len
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the maximum SndNxt.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
@return The sequence number of the maximum SndNxt.
|
|
||||||
|
|
||||||
**/
|
|
||||||
TCP_SEQNO
|
|
||||||
TcpGetMaxSndNxt (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Functions from Tcp4Input.c
|
|
||||||
//
|
|
||||||
/**
|
|
||||||
Process the received ICMP error messages for TCP.
|
|
||||||
|
|
||||||
@param Nbuf Buffer that contains part of the TCP segment without IP header
|
|
||||||
truncated from the ICMP error packet.
|
|
||||||
@param IcmpErr The ICMP error code interpreted from ICMP error packet.
|
|
||||||
@param Src Source address of the ICMP error message.
|
|
||||||
@param Dst Destination address of the ICMP error message.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpIcmpInput (
|
|
||||||
IN NET_BUF *Nbuf,
|
|
||||||
IN UINT8 IcmpErr,
|
|
||||||
IN UINT32 Src,
|
|
||||||
IN UINT32 Dst
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Process the received TCP segments.
|
|
||||||
|
|
||||||
@param Nbuf Buffer that contains received TCP segment without IP header.
|
|
||||||
@param Src Source address of the segment, or the peer's IP address.
|
|
||||||
@param Dst Destination address of the segment, or the local end's IP
|
|
||||||
address.
|
|
||||||
|
|
||||||
@retval 0 Segment is processed successfully. It is either accepted or
|
|
||||||
discarded. But no connection is reset by the segment.
|
|
||||||
@retval -1 A connection is reset by the segment.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpInput (
|
|
||||||
IN NET_BUF *Nbuf,
|
|
||||||
IN UINT32 Src,
|
|
||||||
IN UINT32 Dst
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the sequence number of the incoming segment is acceptable.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Seg Pointer to the incoming segment.
|
|
||||||
|
|
||||||
@retval 1 The sequence number is acceptable.
|
|
||||||
@retval 0 The sequence number is not acceptable.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpSeqAcceptable (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN TCP_SEG *Seg
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
NewReno fast recovery, RFC3782.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Seg Segment that triggers the fast recovery.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpFastRecover (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN TCP_SEG *Seg
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
NewReno fast loss recovery, RFC3792.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Seg Segment that triggers the fast loss recovery.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpFastLossRecover (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN TCP_SEG *Seg
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compute the RTT as specified in RFC2988.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Measure Currently measured RTT in heart beats.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpComputeRtt (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN UINT32 Measure
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Trim off the data outside the tcb's receive window.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Nbuf Pointer to the NET_BUF containing the received tcp segment.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpTrimInWnd (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN NET_BUF *Nbuf
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Store the data into the reassemble queue.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Nbuf Pointer to the buffer containing the data to be queued.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpQueueData (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN NET_BUF *Nbuf
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Ajust the send queue or the retransmit queue.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Ack The acknowledge seuqence number of the received segment.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpAdjustSndQue (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN TCP_SEQNO Ack
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Functions from Tcp4Misc.c
|
|
||||||
//
|
|
||||||
/**
|
|
||||||
Compute the TCP segment's checksum.
|
|
||||||
|
|
||||||
@param Nbuf Pointer to the buffer that contains the TCP
|
|
||||||
segment.
|
|
||||||
@param HeadSum The checksum value of the fixed part of pseudo
|
|
||||||
header.
|
|
||||||
|
|
||||||
@return The checksum value.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT16
|
|
||||||
TcpChecksum (
|
|
||||||
IN NET_BUF *Nbuf,
|
|
||||||
IN UINT16 HeadSum
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Translate the information from the head of the received TCP
|
|
||||||
segment Nbuf contains and fill it into a TCP_SEG structure.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Nbuf Pointer to the buffer contains the TCP segment.
|
|
||||||
|
|
||||||
@return Pointer to the TCP_SEG that contains the translated TCP head information.
|
|
||||||
|
|
||||||
**/
|
|
||||||
TCP_SEG *
|
|
||||||
TcpFormatNetbuf (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN OUT NET_BUF *Nbuf
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initialize an active connection.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB that wants to initiate a
|
|
||||||
connection.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpOnAppConnect (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Application has consumed some data, check whether
|
|
||||||
to send a window updata ack or a delayed ack.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpOnAppConsume (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initiate the connection close procedure, called when
|
|
||||||
applications want to close the connection.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpOnAppClose (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the application's newly delivered data can be sent out.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
@retval 0 Whether the data is sent out or is buffered for
|
|
||||||
further sending.
|
|
||||||
@retval -1 The Tcb is not in a state that data is permitted to
|
|
||||||
be sent out.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpOnAppSend (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Abort the connection by sending a reset segment, called
|
|
||||||
when the application wants to abort the connection.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of the TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpOnAppAbort (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Reset the connection related with Tcb.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of the connection to be
|
|
||||||
reset.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpResetConnection (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Functions in Tcp4Timer.c
|
|
||||||
//
|
|
||||||
/**
|
|
||||||
Close the TCP connection.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpClose (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Heart beat timer handler, queues the DPC at TPL_CALLBACK.
|
|
||||||
|
|
||||||
@param Event Timer event signaled, ignored.
|
|
||||||
@param Context Context of the timer event, ignored.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
TcpTicking (
|
|
||||||
IN EFI_EVENT Event,
|
|
||||||
IN VOID *Context
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Enable a TCP timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Timer The index of the timer to be enabled.
|
|
||||||
@param TimeOut The timeout value of this timer.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpSetTimer (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN UINT16 Timer,
|
|
||||||
IN UINT32 TimeOut
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Clear one TCP timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Timer The index of the timer to be cleared.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpClearTimer (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN UINT16 Timer
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Clear all TCP timers.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpClearAllTimer (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Enable the window prober timer and set the timeout value.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpSetProbeTimer (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Enable the keepalive timer and set the timeout value.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpSetKeepaliveTimer (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Backoff the RTO.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpBackoffRto (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Install the device path protocol on the TCP instance.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket representing the TCP instance.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The device path protocol is installed.
|
|
||||||
@retval other Failed to install the device path protocol.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
TcpInstallDevicePath (
|
|
||||||
IN SOCKET *Sock
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
@ -1,112 +0,0 @@
|
|||||||
/** @file
|
|
||||||
I/O interfaces between TCP and IpIo.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "Tcp4Main.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Packet receive callback function provided to IP_IO, used to call
|
|
||||||
the proper function to handle the packet received by IP.
|
|
||||||
|
|
||||||
@param Status Status of the received packet.
|
|
||||||
@param IcmpErr ICMP error number.
|
|
||||||
@param NetSession Pointer to the net session of this packet.
|
|
||||||
@param Pkt Pointer to the recieved packet.
|
|
||||||
@param Context Pointer to the context configured in IpIoOpen(), not used
|
|
||||||
now.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
Tcp4RxCallback (
|
|
||||||
IN EFI_STATUS Status,
|
|
||||||
IN UINT8 IcmpErr,
|
|
||||||
IN EFI_NET_SESSION_DATA *NetSession,
|
|
||||||
IN NET_BUF *Pkt,
|
|
||||||
IN VOID *Context OPTIONAL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (EFI_SUCCESS == Status) {
|
|
||||||
TcpInput (Pkt, NetSession->Source.Addr[0], NetSession->Dest.Addr[0]);
|
|
||||||
} else {
|
|
||||||
TcpIcmpInput (Pkt, IcmpErr, NetSession->Source.Addr[0], NetSession->Dest.Addr[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Send the segment to IP via IpIo function.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Nbuf Pointer to the TCP segment to be sent.
|
|
||||||
@param Src Source address of the TCP segment.
|
|
||||||
@param Dest Destination address of the TCP segment.
|
|
||||||
|
|
||||||
@retval 0 The segment was sent out successfully.
|
|
||||||
@retval -1 The segment was failed to send.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpSendIpPacket (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN NET_BUF *Nbuf,
|
|
||||||
IN UINT32 Src,
|
|
||||||
IN UINT32 Dest
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
IP_IO *IpIo;
|
|
||||||
IP_IO_OVERRIDE Override;
|
|
||||||
SOCKET *Sock;
|
|
||||||
VOID *IpSender;
|
|
||||||
TCP4_PROTO_DATA *TcpProto;
|
|
||||||
EFI_IP_ADDRESS Source;
|
|
||||||
EFI_IP_ADDRESS Destination;
|
|
||||||
|
|
||||||
Source.Addr[0] = Src;
|
|
||||||
Destination.Addr[0] = Dest;
|
|
||||||
|
|
||||||
if (NULL == Tcb) {
|
|
||||||
|
|
||||||
IpIo = NULL;
|
|
||||||
IpSender = IpIoFindSender (&IpIo, IP_VERSION_4, &Source);
|
|
||||||
|
|
||||||
if (IpSender == NULL) {
|
|
||||||
DEBUG ((EFI_D_WARN, "TcpSendIpPacket: No appropriate IpSender.\n"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
Sock = Tcb->Sk;
|
|
||||||
TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
|
||||||
IpIo = TcpProto->TcpService->IpIo;
|
|
||||||
IpSender = Tcb->IpInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
Override.Ip4OverrideData.TypeOfService = 0;
|
|
||||||
Override.Ip4OverrideData.TimeToLive = 255;
|
|
||||||
Override.Ip4OverrideData.DoNotFragment = FALSE;
|
|
||||||
Override.Ip4OverrideData.Protocol = EFI_IP_PROTO_TCP;
|
|
||||||
ZeroMem (&Override.Ip4OverrideData.GatewayAddress, sizeof (EFI_IPv4_ADDRESS));
|
|
||||||
CopyMem (&Override.Ip4OverrideData.SourceAddress, &Src, sizeof (EFI_IPv4_ADDRESS));
|
|
||||||
|
|
||||||
Status = IpIoSend (IpIo, Nbuf, IpSender, NULL, NULL, &Destination, &Override);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "TcpSendIpPacket: return %r error\n", Status));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,674 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Implementation of TCP4 protocol services.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
|
|
||||||
#include "Tcp4Main.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check the integrity of the data buffer.
|
|
||||||
|
|
||||||
@param DataLen The total length of the data buffer.
|
|
||||||
@param FragmentCount The fragment count of the fragment table.
|
|
||||||
@param FragmentTable Pointer to the fragment table of the data
|
|
||||||
buffer.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The integrity check is passed.
|
|
||||||
@retval EFI_INVALID_PARAMETER The integrity check is failed.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4ChkDataBuf (
|
|
||||||
IN UINT32 DataLen,
|
|
||||||
IN UINT32 FragmentCount,
|
|
||||||
IN EFI_TCP4_FRAGMENT_DATA *FragmentTable
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 Index;
|
|
||||||
|
|
||||||
UINT32 Len;
|
|
||||||
|
|
||||||
for (Index = 0, Len = 0; Index < FragmentCount; Index++) {
|
|
||||||
Len = Len + (UINT32) FragmentTable[Index].FragmentLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DataLen != Len) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the current operational status.
|
|
||||||
|
|
||||||
The GetModeData() function copies the current operational settings of this
|
|
||||||
EFI TCPv4 Protocol instance into user-supplied buffers. This function can
|
|
||||||
also be used to retrieve the operational setting of underlying drivers
|
|
||||||
such as IPv4, MNP, or SNP.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param Tcp4State Pointer to the buffer to receive the current TCP
|
|
||||||
state.
|
|
||||||
@param Tcp4ConfigData Pointer to the buffer to receive the current TCP
|
|
||||||
configuration.
|
|
||||||
@param Ip4ModeData Pointer to the buffer to receive the current IPv4
|
|
||||||
configuration data used by the TCPv4 instance.
|
|
||||||
@param MnpConfigData Pointer to the buffer to receive the current MNP
|
|
||||||
configuration data indirectly used by the TCPv4
|
|
||||||
Instance.
|
|
||||||
@param SnpModeData Pointer to the buffer to receive the current SNP
|
|
||||||
configuration data indirectly used by the TCPv4
|
|
||||||
Instance.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The mode data was read.
|
|
||||||
@retval EFI_NOT_STARTED No configuration data is available because this
|
|
||||||
instance hasn't been started.
|
|
||||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4GetModeData (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
OUT EFI_TCP4_CONNECTION_STATE *Tcp4State OPTIONAL,
|
|
||||||
OUT EFI_TCP4_CONFIG_DATA *Tcp4ConfigData OPTIONAL,
|
|
||||||
OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL,
|
|
||||||
OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
|
|
||||||
OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP4_MODE_DATA TcpMode;
|
|
||||||
SOCKET *Sock;
|
|
||||||
|
|
||||||
if (NULL == This) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock = SOCK_FROM_THIS (This);
|
|
||||||
|
|
||||||
TcpMode.Tcp4State = Tcp4State;
|
|
||||||
TcpMode.Tcp4ConfigData = Tcp4ConfigData;
|
|
||||||
TcpMode.Ip4ModeData = Ip4ModeData;
|
|
||||||
TcpMode.MnpConfigData = MnpConfigData;
|
|
||||||
TcpMode.SnpModeData = SnpModeData;
|
|
||||||
|
|
||||||
return SockGetMode (Sock, &TcpMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initialize or brutally reset the operational parameters for
|
|
||||||
this EFI TCPv4 instance.
|
|
||||||
|
|
||||||
The Configure() function does the following:
|
|
||||||
* Initialize this EFI TCPv4 instance, i.e., initialize the communication end
|
|
||||||
setting, specify active open or passive open for an instance.
|
|
||||||
* Reset this TCPv4 instance brutally, i.e., cancel all pending asynchronous
|
|
||||||
tokens, flush transmission and receiving buffer directly without informing
|
|
||||||
the communication peer.
|
|
||||||
No other TCPv4 Protocol operation can be executed by this instance
|
|
||||||
until it is configured properly. For an active TCP4 instance, after a proper
|
|
||||||
configuration it may call Connect() to initiates the three-way handshake.
|
|
||||||
For a passive TCP4 instance, its state will transit to Tcp4StateListen after
|
|
||||||
configuration, and Accept() may be called to listen the incoming TCP connection
|
|
||||||
request. If TcpConfigData is set to NULL, the instance is reset. Resetting
|
|
||||||
process will be done brutally, the state machine will be set to Tcp4StateClosed
|
|
||||||
directly, the receive queue and transmit queue will be flushed, and no traffic is
|
|
||||||
allowed through this instance.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param TcpConfigData Pointer to the configure data to configure the
|
|
||||||
instance.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The operational settings are set, changed, or
|
|
||||||
reset successfully.
|
|
||||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
|
||||||
(through DHCP, BOOTP, RARP, etc.) is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_ACCESS_DENIED Configuring TCP instance when it is already
|
|
||||||
configured.
|
|
||||||
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
|
|
||||||
@retval EFI_UNSUPPORTED One or more of the control options are not
|
|
||||||
supported in the implementation.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Configure (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_CONFIG_DATA *TcpConfigData OPTIONAL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_TCP4_OPTION *Option;
|
|
||||||
SOCKET *Sock;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
IP4_ADDR Ip;
|
|
||||||
IP4_ADDR SubnetMask;
|
|
||||||
|
|
||||||
if (NULL == This) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Tcp protocol related parameter check will be conducted here
|
|
||||||
//
|
|
||||||
if (NULL != TcpConfigData) {
|
|
||||||
|
|
||||||
CopyMem (&Ip, &TcpConfigData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));
|
|
||||||
if (IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TcpConfigData->AccessPoint.ActiveFlag &&
|
|
||||||
(0 == TcpConfigData->AccessPoint.RemotePort || (Ip == 0))) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TcpConfigData->AccessPoint.UseDefaultAddress) {
|
|
||||||
|
|
||||||
CopyMem (&Ip, &TcpConfigData->AccessPoint.StationAddress, sizeof (IP4_ADDR));
|
|
||||||
CopyMem (&SubnetMask, &TcpConfigData->AccessPoint.SubnetMask, sizeof (IP4_ADDR));
|
|
||||||
if (!IP4_IS_VALID_NETMASK (NTOHL (SubnetMask)) ||
|
|
||||||
(SubnetMask != 0 && !NetIp4IsUnicast (NTOHL (Ip), NTOHL (SubnetMask)))) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Option = TcpConfigData->ControlOption;
|
|
||||||
if ((NULL != Option) &&
|
|
||||||
(Option->EnableSelectiveAck || Option->EnablePathMtuDiscovery)) {
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock = SOCK_FROM_THIS (This);
|
|
||||||
|
|
||||||
if (NULL == TcpConfigData) {
|
|
||||||
return SockFlush (Sock);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = SockConfigure (Sock, TcpConfigData);
|
|
||||||
|
|
||||||
if (EFI_NO_MAPPING == Status) {
|
|
||||||
Sock->ConfigureState = SO_NO_MAPPING;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Add or delete routing entries.
|
|
||||||
|
|
||||||
The Routes() function adds or deletes a route from the instance's routing table.
|
|
||||||
The most specific route is selected by comparing the SubnetAddress with the
|
|
||||||
destination IP address's arithmetical AND to the SubnetMask.
|
|
||||||
The default route is added with both SubnetAddress and SubnetMask set to 0.0.0.0.
|
|
||||||
The default route matches all destination IP addresses if there is no more specific route.
|
|
||||||
Direct route is added with GatewayAddress set to 0.0.0.0. Packets are sent to
|
|
||||||
the destination host if its address can be found in the Address Resolution Protocol (ARP)
|
|
||||||
cache or it is on the local subnet. If the instance is configured to use default
|
|
||||||
address, a direct route to the local network will be added automatically.
|
|
||||||
Each TCP instance has its own independent routing table. Instance that uses the
|
|
||||||
default IP address will have a copy of the EFI_IP4_CONFIG_PROTOCOL's routing table.
|
|
||||||
The copy will be updated automatically whenever the IP driver reconfigures its
|
|
||||||
instance. As a result, the previous modification to the instance's local copy
|
|
||||||
will be lost. The priority of checking the route table is specific with IP
|
|
||||||
implementation and every IP implementation must comply with RFC 1122.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param DeleteRoute If TRUE, delete the specified route from routing
|
|
||||||
table; if FALSE, add the specified route to
|
|
||||||
routing table.
|
|
||||||
DestinationAddress and SubnetMask are used as
|
|
||||||
the keywords to search route entry.
|
|
||||||
@param SubnetAddress The destination network.
|
|
||||||
@param SubnetMask The subnet mask for the destination network.
|
|
||||||
@param GatewayAddress The gateway address for this route.
|
|
||||||
It must be on the same subnet with the station
|
|
||||||
address unless a direct route is specified.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The operation completed successfully.
|
|
||||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance has not been
|
|
||||||
configured.
|
|
||||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
|
||||||
(through DHCP, BOOTP, RARP, etc.) is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to add the
|
|
||||||
entry to the routing table.
|
|
||||||
@retval EFI_NOT_FOUND This route is not in the routing table.
|
|
||||||
@retval EFI_ACCESS_DENIED This route is already in the routing table.
|
|
||||||
@retval EFI_UNSUPPORTED The TCP driver does not support this operation.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Routes (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN BOOLEAN DeleteRoute,
|
|
||||||
IN EFI_IPv4_ADDRESS *SubnetAddress,
|
|
||||||
IN EFI_IPv4_ADDRESS *SubnetMask,
|
|
||||||
IN EFI_IPv4_ADDRESS *GatewayAddress
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
TCP4_ROUTE_INFO RouteInfo;
|
|
||||||
|
|
||||||
if (NULL == This) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock = SOCK_FROM_THIS (This);
|
|
||||||
|
|
||||||
RouteInfo.DeleteRoute = DeleteRoute;
|
|
||||||
RouteInfo.SubnetAddress = SubnetAddress;
|
|
||||||
RouteInfo.SubnetMask = SubnetMask;
|
|
||||||
RouteInfo.GatewayAddress = GatewayAddress;
|
|
||||||
|
|
||||||
return SockRoute (Sock, &RouteInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initiate a nonblocking TCP connection request for an active TCP instance.
|
|
||||||
|
|
||||||
The Connect() function will initiate an active open to the remote peer configured
|
|
||||||
in current TCP instance if it is configured active. If the connection succeeds
|
|
||||||
or fails due to any error, the ConnectionToken->CompletionToken.Event will be
|
|
||||||
signaled and ConnectionToken->CompletionToken.Status will be updated accordingly.
|
|
||||||
This function can only be called for the TCP instance in Tcp4StateClosed state.
|
|
||||||
The instance will transfer into Tcp4StateSynSent if the function returns EFI_SUCCESS.
|
|
||||||
If TCP three way handshake succeeds, its state will become Tcp4StateEstablished,
|
|
||||||
otherwise, the state will return to Tcp4StateClosed.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance
|
|
||||||
@param ConnectionToken Pointer to the connection token to return when
|
|
||||||
the TCP three way handshake finishes.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The connection request is successfully initiated
|
|
||||||
and the state of this TCPv4 instance has
|
|
||||||
been changed to Tcp4StateSynSent.
|
|
||||||
@retval EFI_NOT_STARTED This EFI_TCP4_PROTOCOL instance hasn't been
|
|
||||||
configured.
|
|
||||||
@retval EFI_ACCESS_DENIED The instance is not configured as an active one
|
|
||||||
or it is not in Tcp4StateClosed state.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES The driver can't allocate enough resource to
|
|
||||||
initiate the active open.
|
|
||||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Connect (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_CONNECTION_TOKEN *ConnectionToken
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
|
|
||||||
if (NULL == This ||
|
|
||||||
NULL == ConnectionToken ||
|
|
||||||
NULL == ConnectionToken->CompletionToken.Event) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock = SOCK_FROM_THIS (This);
|
|
||||||
|
|
||||||
return SockConnect (Sock, ConnectionToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Listen on the passive instance to accept an incoming connection request.
|
|
||||||
|
|
||||||
The Accept() function initiates an asynchronous accept request to wait for an
|
|
||||||
incoming connection on the passive TCP instance. If a remote peer successfully
|
|
||||||
establishes a connection with this instance, a new TCP instance will be created
|
|
||||||
and its handle will be returned in ListenToken->NewChildHandle. The newly created
|
|
||||||
instance is configured by inheriting the passive instance's configuration and is
|
|
||||||
ready for use upon return. The instance is in the Tcp4StateEstablished state.
|
|
||||||
The ListenToken->CompletionToken.Event will be signaled when a new connection
|
|
||||||
is accepted, user aborts the listen or connection is reset. This function only
|
|
||||||
can be called when current TCP instance is in Tcp4StateListen state.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance
|
|
||||||
@param ListenToken Pointer to the listen token to return when
|
|
||||||
operation finishes.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The listen token has been queued successfully.
|
|
||||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
|
||||||
configured.
|
|
||||||
@retval EFI_ACCESS_DENIED The instatnce is not a passive one or it is not
|
|
||||||
in Tcp4StateListen state or a same listen token
|
|
||||||
has already existed in the listen token queue of
|
|
||||||
this TCP instance.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to finish
|
|
||||||
the operation.
|
|
||||||
@retval EFI_DEVICE_ERROR Any unexpected and not belonged to above category error.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Accept (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_LISTEN_TOKEN *ListenToken
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
|
|
||||||
if (NULL == This ||
|
|
||||||
NULL == ListenToken ||
|
|
||||||
NULL == ListenToken->CompletionToken.Event) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock = SOCK_FROM_THIS (This);
|
|
||||||
|
|
||||||
return SockAccept (Sock, ListenToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Queues outgoing data into the transmit queue.
|
|
||||||
|
|
||||||
The Transmit() function queues a sending request to this TCPv4 instance along
|
|
||||||
with the user data. The status of the token is updated and the event in the token
|
|
||||||
will be signaled once the data is sent out or some error occurs.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance
|
|
||||||
@param Token Pointer to the completion token to queue to the
|
|
||||||
transmit queue
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The data has been queued for transmission.
|
|
||||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
|
||||||
configured.
|
|
||||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
|
||||||
(DHCP, BOOTP, RARP, etc.) is not finished yet.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE:
|
|
||||||
* A transmit completion token with the same
|
|
||||||
Token-> CompletionToken.Event was already in the
|
|
||||||
transmission queue.
|
|
||||||
* The current instance is in Tcp4StateClosed state
|
|
||||||
* The current instance is a passive one and
|
|
||||||
it is in Tcp4StateListen state.
|
|
||||||
* User has called Close() to disconnect this
|
|
||||||
connection.
|
|
||||||
@retval EFI_NOT_READY The completion token could not be queued because
|
|
||||||
the transmit queue is full.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Could not queue the transmit data because of
|
|
||||||
resource shortage.
|
|
||||||
@retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or
|
|
||||||
address.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Transmit (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_IO_TOKEN *Token
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
if (NULL == This ||
|
|
||||||
NULL == Token ||
|
|
||||||
NULL == Token->CompletionToken.Event ||
|
|
||||||
NULL == Token->Packet.TxData ||
|
|
||||||
0 == Token->Packet.TxData->FragmentCount ||
|
|
||||||
0 == Token->Packet.TxData->DataLength
|
|
||||||
) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = Tcp4ChkDataBuf (
|
|
||||||
(UINT32) Token->Packet.TxData->DataLength,
|
|
||||||
(UINT32) Token->Packet.TxData->FragmentCount,
|
|
||||||
Token->Packet.TxData->FragmentTable
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock = SOCK_FROM_THIS (This);
|
|
||||||
|
|
||||||
return SockSend (Sock, Token);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Place an asynchronous receive request into the receiving queue.
|
|
||||||
|
|
||||||
The Receive() function places a completion token into the receive packet queue.
|
|
||||||
This function is always asynchronous. The caller must allocate the
|
|
||||||
Token->CompletionToken.Event and the FragmentBuffer used to receive data. He also
|
|
||||||
must fill the DataLength which represents the whole length of all FragmentBuffer.
|
|
||||||
When the receive operation completes, the EFI TCPv4 Protocol driver updates the
|
|
||||||
Token->CompletionToken.Status and Token->Packet.RxData fields and the
|
|
||||||
Token->CompletionToken.Event is signaled. If got data the data and its length
|
|
||||||
will be copy into the FragmentTable, in the same time the full length of received
|
|
||||||
data will be recorded in the DataLength fields. Providing a proper notification
|
|
||||||
function and context for the event will enable the user to receive the notification
|
|
||||||
and receiving status. That notification function is guaranteed to not be re-entered.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param Token Pointer to a token that is associated with the
|
|
||||||
receive data descriptor.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The receive completion token was cached.
|
|
||||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
|
||||||
configured.
|
|
||||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
|
||||||
(DHCP, BOOTP, RARP, etc.) is not finished yet.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued
|
|
||||||
due to a lack of system resources.
|
|
||||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
|
||||||
The EFI TCPv4 Protocol instance has been reset
|
|
||||||
to startup defaults.
|
|
||||||
@retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE:
|
|
||||||
* A receive completion token with the same
|
|
||||||
Token->CompletionToken.Event was already in
|
|
||||||
the receive queue.
|
|
||||||
* The current instance is in Tcp4StateClosed state.
|
|
||||||
* The current instance is a passive one and it
|
|
||||||
is in Tcp4StateListen state.
|
|
||||||
* User has called Close() to disconnect this
|
|
||||||
connection.
|
|
||||||
@retval EFI_CONNECTION_FIN The communication peer has closed the connection
|
|
||||||
and there is no any buffered data in the receive
|
|
||||||
buffer of this instance.
|
|
||||||
@retval EFI_NOT_READY The receive request could not be queued because
|
|
||||||
the receive queue is full.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Receive (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_IO_TOKEN *Token
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
if (NULL == This ||
|
|
||||||
NULL == Token ||
|
|
||||||
NULL == Token->CompletionToken.Event ||
|
|
||||||
NULL == Token->Packet.RxData ||
|
|
||||||
0 == Token->Packet.RxData->FragmentCount ||
|
|
||||||
0 == Token->Packet.RxData->DataLength
|
|
||||||
) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = Tcp4ChkDataBuf (
|
|
||||||
(UINT32) Token->Packet.RxData->DataLength,
|
|
||||||
(UINT32) Token->Packet.RxData->FragmentCount,
|
|
||||||
Token->Packet.RxData->FragmentTable
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock = SOCK_FROM_THIS (This);
|
|
||||||
|
|
||||||
return SockRcv (Sock, Token);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Disconnecting a TCP connection gracefully or reset a TCP connection.
|
|
||||||
|
|
||||||
Initiate an asynchronous close token to TCP driver. After Close() is called,
|
|
||||||
any buffered transmission data will be sent by TCP driver and the current
|
|
||||||
instance will have a graceful close working flow described as RFC 793 if
|
|
||||||
AbortOnClose is set to FALSE, otherwise, a rest packet will be sent by TCP
|
|
||||||
driver to fast disconnect this connection. When the close operation completes
|
|
||||||
successfully the TCP instance is in Tcp4StateClosed state, all pending
|
|
||||||
asynchronous operation is signaled and any buffers used for TCP network traffic
|
|
||||||
is flushed.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param CloseToken Pointer to the close token to return when
|
|
||||||
operation finishes.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The operation completed successfully.
|
|
||||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
|
||||||
configured.
|
|
||||||
@retval EFI_ACCESS_DENIED One or more of the following are TRUE:
|
|
||||||
* Configure() has been called with TcpConfigData
|
|
||||||
set to NULL and this function has not returned.
|
|
||||||
* Previous Close() call on this instance has not
|
|
||||||
finished.
|
|
||||||
@retval EFI_INVALID_PARAMETER One ore more parameters are invalid.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the
|
|
||||||
operation.
|
|
||||||
@retval EFI_DEVICE_ERROR Any unexpected and not belonged to above
|
|
||||||
category error.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Close (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_CLOSE_TOKEN *CloseToken
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
|
|
||||||
if (NULL == This ||
|
|
||||||
NULL == CloseToken ||
|
|
||||||
NULL == CloseToken->CompletionToken.Event) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock = SOCK_FROM_THIS (This);
|
|
||||||
|
|
||||||
return SockClose (Sock, CloseToken, CloseToken->AbortOnClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Abort an asynchronous connection, listen, transmission or receive request.
|
|
||||||
|
|
||||||
The Cancel() function aborts a pending connection, listen, transmit or receive
|
|
||||||
request. If Token is not NULL and the token is in the connection, listen,
|
|
||||||
transmission or receive queue when it is being cancelled, its Token->Status
|
|
||||||
will be set to EFI_ABORTED and then Token->Event will be signaled. If the token
|
|
||||||
is not in one of the queues, which usually means that the asynchronous operation
|
|
||||||
has completed, EFI_NOT_FOUND is returned. If Token is NULL all asynchronous token
|
|
||||||
issued by Connect(), Accept(), Transmit() and Receive()will be aborted.
|
|
||||||
NOTE: It has not been implemented currently.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param Token Pointer to a token that has been issued by
|
|
||||||
Connect(), Accept(), Transmit() or Receive(). If
|
|
||||||
NULL, all pending tokens issued by above four
|
|
||||||
functions will be aborted.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The asynchronous I/O request is aborted and Token->Event
|
|
||||||
is signaled.
|
|
||||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
|
||||||
@retval EFI_NOT_STARTED This instance hasn's been configured.
|
|
||||||
@retval EFI_NO_MAPPING When using the default address, configuration
|
|
||||||
(DHCP, BOOTP,RARP, etc.) hasn's finished yet.
|
|
||||||
@retval EFI_NOT_FOUND The asynchronous I/O request isn's found in the
|
|
||||||
transmission or receive queue. It has either
|
|
||||||
completed or wasn's issued by Transmit() and Receive().
|
|
||||||
@retval EFI_UNSUPPORTED The operation is not supported in current
|
|
||||||
implementation.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Cancel (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_COMPLETION_TOKEN *Token OPTIONAL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Poll to receive incoming data and transmit outgoing segments.
|
|
||||||
|
|
||||||
The Poll() function increases the rate that data is moved between the network
|
|
||||||
and application and can be called when the TCP instance is created successfully.
|
|
||||||
Its use is optional. In some implementations, the periodical timer in the MNP
|
|
||||||
driver may not poll the underlying communications device fast enough to avoid
|
|
||||||
drop packets. Drivers and applications that are experiencing packet loss should
|
|
||||||
try calling the Poll() function in a high frequency.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Incoming or outgoing data was processed.
|
|
||||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
|
||||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
|
||||||
@retval EFI_NOT_READY No incoming or outgoing data was processed.
|
|
||||||
@retval EFI_TIMEOUT Data was dropped out of the transmission or
|
|
||||||
receive queue. Consider increasing the polling
|
|
||||||
rate.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Poll (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SOCKET *Sock;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
if (NULL == This) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sock = SOCK_FROM_THIS (This);
|
|
||||||
|
|
||||||
Status = Sock->ProtoHandler (Sock, SOCK_POLL, NULL);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
@ -1,494 +0,0 @@
|
|||||||
/** @file
|
|
||||||
TCP4 protocol services header file.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#ifndef _TCP4_MAIN_H_
|
|
||||||
#define _TCP4_MAIN_H_
|
|
||||||
|
|
||||||
#include "Socket.h"
|
|
||||||
|
|
||||||
#include "Tcp4Proto.h"
|
|
||||||
#include "Tcp4Func.h"
|
|
||||||
#include "Tcp4Driver.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern UINT16 mTcp4RandomPort;
|
|
||||||
extern CHAR16 *mTcpStateName[];
|
|
||||||
|
|
||||||
//
|
|
||||||
// Driver Produced Protocol Prototypes
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Function prototype for the Tcp4 socket request handler
|
|
||||||
//
|
|
||||||
/**
|
|
||||||
The procotol handler provided to the socket layer, used to
|
|
||||||
dispatch the socket level requests by calling the corresponding
|
|
||||||
TCP layer functions.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket of this TCP instance.
|
|
||||||
@param Request The code of this operation request.
|
|
||||||
@param Data Pointer to the operation specific data passed in
|
|
||||||
together with the operation request.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The socket request is completed successfully.
|
|
||||||
@retval other The error status returned by the corresponding TCP
|
|
||||||
layer function.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
Tcp4Dispatcher (
|
|
||||||
IN SOCKET *Sock,
|
|
||||||
IN UINT8 Request,
|
|
||||||
IN VOID *Data OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// TCP mode data
|
|
||||||
///
|
|
||||||
typedef struct _TCP4_MODE_DATA {
|
|
||||||
EFI_TCP4_CONNECTION_STATE *Tcp4State;
|
|
||||||
EFI_TCP4_CONFIG_DATA *Tcp4ConfigData;
|
|
||||||
EFI_IP4_MODE_DATA *Ip4ModeData;
|
|
||||||
EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData;
|
|
||||||
EFI_SIMPLE_NETWORK_MODE *SnpModeData;
|
|
||||||
} TCP4_MODE_DATA;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// TCP route infomation data
|
|
||||||
///
|
|
||||||
typedef struct _TCP4_ROUTE_INFO {
|
|
||||||
BOOLEAN DeleteRoute;
|
|
||||||
EFI_IPv4_ADDRESS *SubnetAddress;
|
|
||||||
EFI_IPv4_ADDRESS *SubnetMask;
|
|
||||||
EFI_IPv4_ADDRESS *GatewayAddress;
|
|
||||||
} TCP4_ROUTE_INFO;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
|
||||||
UINTN NumberOfChildren;
|
|
||||||
EFI_HANDLE *ChildHandleBuffer;
|
|
||||||
} TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the current operational status of a TCP instance.
|
|
||||||
|
|
||||||
The GetModeData() function copies the current operational settings of this
|
|
||||||
EFI TCPv4 Protocol instance into user-supplied buffers. This function can
|
|
||||||
also be used to retrieve the operational setting of underlying drivers
|
|
||||||
such as IPv4, MNP, or SNP.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param Tcp4State Pointer to the buffer to receive the current TCP
|
|
||||||
state.
|
|
||||||
@param Tcp4ConfigData Pointer to the buffer to receive the current TCP
|
|
||||||
configuration.
|
|
||||||
@param Ip4ModeData Pointer to the buffer to receive the current IPv4
|
|
||||||
configuration data used by the TCPv4 instance.
|
|
||||||
@param MnpConfigData Pointer to the buffer to receive the current MNP
|
|
||||||
configuration data indirectly used by the TCPv4
|
|
||||||
Instance.
|
|
||||||
@param SnpModeData Pointer to the buffer to receive the current SNP
|
|
||||||
configuration data indirectly used by the TCPv4
|
|
||||||
Instance.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The mode data was read.
|
|
||||||
@retval EFI_NOT_STARTED No configuration data is available because this
|
|
||||||
instance hasn't been started.
|
|
||||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4GetModeData (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
OUT EFI_TCP4_CONNECTION_STATE *Tcp4State OPTIONAL,
|
|
||||||
OUT EFI_TCP4_CONFIG_DATA *Tcp4ConfigData OPTIONAL,
|
|
||||||
OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL,
|
|
||||||
OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
|
|
||||||
OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initialize or brutally reset the operational parameters for
|
|
||||||
this EFI TCPv4 instance.
|
|
||||||
|
|
||||||
The Configure() function does the following:
|
|
||||||
* Initialize this EFI TCPv4 instance, i.e., initialize the communication end
|
|
||||||
setting, specify active open or passive open for an instance.
|
|
||||||
* Reset this TCPv4 instance brutally, i.e., cancel all pending asynchronous
|
|
||||||
tokens, flush transmission and receiving buffer directly without informing
|
|
||||||
the communication peer.
|
|
||||||
No other TCPv4 Protocol operation can be executed by this instance
|
|
||||||
until it is configured properly. For an active TCP4 instance, after a proper
|
|
||||||
configuration it may call Connect() to initiates the three-way handshake.
|
|
||||||
For a passive TCP4 instance, its state will transit to Tcp4StateListen after
|
|
||||||
configuration, and Accept() may be called to listen the incoming TCP connection
|
|
||||||
request. If TcpConfigData is set to NULL, the instance is reset. Resetting
|
|
||||||
process will be done brutally, the state machine will be set to Tcp4StateClosed
|
|
||||||
directly, the receive queue and transmit queue will be flushed, and no traffic is
|
|
||||||
allowed through this instance.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param TcpConfigData Pointer to the configure data to configure the
|
|
||||||
instance.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The operational settings are set, changed, or
|
|
||||||
reset successfully.
|
|
||||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
|
||||||
(through DHCP, BOOTP, RARP, etc.) is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_ACCESS_DENIED Configuring TCP instance when it is already
|
|
||||||
configured.
|
|
||||||
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
|
|
||||||
@retval EFI_UNSUPPORTED One or more of the control options are not
|
|
||||||
supported in the implementation.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Configure (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_CONFIG_DATA *TcpConfigData OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Add or delete routing entries.
|
|
||||||
|
|
||||||
The Routes() function adds or deletes a route from the instance's routing table.
|
|
||||||
The most specific route is selected by comparing the SubnetAddress with the
|
|
||||||
destination IP address's arithmetical AND to the SubnetMask.
|
|
||||||
The default route is added with both SubnetAddress and SubnetMask set to 0.0.0.0.
|
|
||||||
The default route matches all destination IP addresses if there is no more specific route.
|
|
||||||
Direct route is added with GatewayAddress set to 0.0.0.0. Packets are sent to
|
|
||||||
the destination host if its address can be found in the Address Resolution Protocol (ARP)
|
|
||||||
cache or it is on the local subnet. If the instance is configured to use default
|
|
||||||
address, a direct route to the local network will be added automatically.
|
|
||||||
Each TCP instance has its own independent routing table. Instance that uses the
|
|
||||||
default IP address will have a copy of the EFI_IP4_CONFIG_PROTOCOL's routing table.
|
|
||||||
The copy will be updated automatically whenever the IP driver reconfigures its
|
|
||||||
instance. As a result, the previous modification to the instance's local copy
|
|
||||||
will be lost. The priority of checking the route table is specific with IP
|
|
||||||
implementation and every IP implementation must comply with RFC 1122.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param DeleteRoute If TRUE, delete the specified route from routing
|
|
||||||
table; if FALSE, add the specified route to
|
|
||||||
routing table.
|
|
||||||
DestinationAddress and SubnetMask are used as
|
|
||||||
the keywords to search route entry.
|
|
||||||
@param SubnetAddress The destination network.
|
|
||||||
@param SubnetMask The subnet mask for the destination network.
|
|
||||||
@param GatewayAddress The gateway address for this route.
|
|
||||||
It must be on the same subnet with the station
|
|
||||||
address unless a direct route is specified.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The operation completed successfully.
|
|
||||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance has not been
|
|
||||||
configured.
|
|
||||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
|
||||||
(through DHCP, BOOTP, RARP, etc.) is not
|
|
||||||
finished.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to add the
|
|
||||||
entry to the routing table.
|
|
||||||
@retval EFI_NOT_FOUND This route is not in the routing table.
|
|
||||||
@retval EFI_ACCESS_DENIED This route is already in the routing table.
|
|
||||||
@retval EFI_UNSUPPORTED The TCP driver does not support this operation.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Routes (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN BOOLEAN DeleteRoute,
|
|
||||||
IN EFI_IPv4_ADDRESS *SubnetAddress,
|
|
||||||
IN EFI_IPv4_ADDRESS *SubnetMask,
|
|
||||||
IN EFI_IPv4_ADDRESS *GatewayAddress
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initiate a nonblocking TCP connection request for an active TCP instance.
|
|
||||||
|
|
||||||
The Connect() function will initiate an active open to the remote peer configured
|
|
||||||
in current TCP instance if it is configured active. If the connection succeeds
|
|
||||||
or fails due to any error, the ConnectionToken->CompletionToken.Event will be
|
|
||||||
signaled and ConnectionToken->CompletionToken.Status will be updated accordingly.
|
|
||||||
This function can only be called for the TCP instance in Tcp4StateClosed state.
|
|
||||||
The instance will transfer into Tcp4StateSynSent if the function returns EFI_SUCCESS.
|
|
||||||
If TCP three way handshake succeeds, its state will become Tcp4StateEstablished,
|
|
||||||
otherwise, the state will return to Tcp4StateClosed.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance
|
|
||||||
@param ConnectionToken Pointer to the connection token to return when
|
|
||||||
the TCP three way handshake finishes.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The connection request is successfully initiated
|
|
||||||
and the state of this TCPv4 instance has
|
|
||||||
been changed to Tcp4StateSynSent.
|
|
||||||
@retval EFI_NOT_STARTED This EFI_TCP4_PROTOCOL instance hasn't been
|
|
||||||
configured.
|
|
||||||
@retval EFI_ACCESS_DENIED The instance is not configured as an active one
|
|
||||||
or it is not in Tcp4StateClosed state.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES The driver can't allocate enough resource to
|
|
||||||
initiate the active open.
|
|
||||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Connect (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_CONNECTION_TOKEN *ConnectionToken
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Listen on the passive instance to accept an incoming connection request.
|
|
||||||
|
|
||||||
The Accept() function initiates an asynchronous accept request to wait for an
|
|
||||||
incoming connection on the passive TCP instance. If a remote peer successfully
|
|
||||||
establishes a connection with this instance, a new TCP instance will be created
|
|
||||||
and its handle will be returned in ListenToken->NewChildHandle. The newly created
|
|
||||||
instance is configured by inheriting the passive instance's configuration and is
|
|
||||||
ready for use upon return. The instance is in the Tcp4StateEstablished state.
|
|
||||||
The ListenToken->CompletionToken.Event will be signaled when a new connection
|
|
||||||
is accepted, user aborts the listen or connection is reset. This function only
|
|
||||||
can be called when current TCP instance is in Tcp4StateListen state.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance
|
|
||||||
@param ListenToken Pointer to the listen token to return when
|
|
||||||
operation finishes.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The listen token has been queued successfully.
|
|
||||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
|
||||||
configured.
|
|
||||||
@retval EFI_ACCESS_DENIED The instatnce is not a passive one or it is not
|
|
||||||
in Tcp4StateListen state or a same listen token
|
|
||||||
has already existed in the listen token queue of
|
|
||||||
this TCP instance.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to finish
|
|
||||||
the operation.
|
|
||||||
@retval EFI_DEVICE_ERROR Any unexpected and not belonged to above category error.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Accept (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_LISTEN_TOKEN *ListenToken
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Queues outgoing data into the transmit queue.
|
|
||||||
|
|
||||||
The Transmit() function queues a sending request to this TCPv4 instance along
|
|
||||||
with the user data. The status of the token is updated and the event in the token
|
|
||||||
will be signaled once the data is sent out or some error occurs.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance
|
|
||||||
@param Token Pointer to the completion token to queue to the
|
|
||||||
transmit queue
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The data has been queued for transmission.
|
|
||||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
|
||||||
configured.
|
|
||||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
|
||||||
(DHCP, BOOTP, RARP, etc.) is not finished yet.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE:
|
|
||||||
* A transmit completion token with the same
|
|
||||||
Token-> CompletionToken.Event was already in the
|
|
||||||
transmission queue.
|
|
||||||
* The current instance is in Tcp4StateClosed state
|
|
||||||
* The current instance is a passive one and
|
|
||||||
it is in Tcp4StateListen state.
|
|
||||||
* User has called Close() to disconnect this
|
|
||||||
connection.
|
|
||||||
@retval EFI_NOT_READY The completion token could not be queued because
|
|
||||||
the transmit queue is full.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Could not queue the transmit data because of
|
|
||||||
resource shortage.
|
|
||||||
@retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or
|
|
||||||
address.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Transmit (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_IO_TOKEN *Token
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Place an asynchronous receive request into the receiving queue.
|
|
||||||
|
|
||||||
The Receive() function places a completion token into the receive packet queue.
|
|
||||||
This function is always asynchronous. The caller must allocate the
|
|
||||||
Token->CompletionToken.Event and the FragmentBuffer used to receive data. He also
|
|
||||||
must fill the DataLength which represents the whole length of all FragmentBuffer.
|
|
||||||
When the receive operation completes, the EFI TCPv4 Protocol driver updates the
|
|
||||||
Token->CompletionToken.Status and Token->Packet.RxData fields and the
|
|
||||||
Token->CompletionToken.Event is signaled. If got data the data and its length
|
|
||||||
will be copy into the FragmentTable, in the same time the full length of received
|
|
||||||
data will be recorded in the DataLength fields. Providing a proper notification
|
|
||||||
function and context for the event will enable the user to receive the notification
|
|
||||||
and receiving status. That notification function is guaranteed to not be re-entered.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param Token Pointer to a token that is associated with the
|
|
||||||
receive data descriptor.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The receive completion token was cached.
|
|
||||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
|
||||||
configured.
|
|
||||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
|
||||||
(DHCP, BOOTP, RARP, etc.) is not finished yet.
|
|
||||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued
|
|
||||||
due to a lack of system resources.
|
|
||||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
|
||||||
The EFI TCPv4 Protocol instance has been reset
|
|
||||||
to startup defaults.
|
|
||||||
@retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE:
|
|
||||||
* A receive completion token with the same
|
|
||||||
Token->CompletionToken.Event was already in
|
|
||||||
the receive queue.
|
|
||||||
* The current instance is in Tcp4StateClosed state.
|
|
||||||
* The current instance is a passive one and it
|
|
||||||
is in Tcp4StateListen state.
|
|
||||||
* User has called Close() to disconnect this
|
|
||||||
connection.
|
|
||||||
@retval EFI_CONNECTION_FIN The communication peer has closed the connection
|
|
||||||
and there is no any buffered data in the receive
|
|
||||||
buffer of this instance.
|
|
||||||
@retval EFI_NOT_READY The receive request could not be queued because
|
|
||||||
the receive queue is full.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Receive (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_IO_TOKEN *Token
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Disconnecting a TCP connection gracefully or reset a TCP connection.
|
|
||||||
|
|
||||||
Initiate an asynchronous close token to TCP driver. After Close() is called,
|
|
||||||
any buffered transmission data will be sent by TCP driver and the current
|
|
||||||
instance will have a graceful close working flow described as RFC 793 if
|
|
||||||
AbortOnClose is set to FALSE, otherwise, a rest packet will be sent by TCP
|
|
||||||
driver to fast disconnect this connection. When the close operation completes
|
|
||||||
successfully the TCP instance is in Tcp4StateClosed state, all pending
|
|
||||||
asynchronous operation is signaled and any buffers used for TCP network traffic
|
|
||||||
is flushed.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param CloseToken Pointer to the close token to return when
|
|
||||||
operation finishes.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The operation completed successfully.
|
|
||||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
|
||||||
configured.
|
|
||||||
@retval EFI_ACCESS_DENIED One or more of the following are TRUE:
|
|
||||||
* Configure() has been called with TcpConfigData
|
|
||||||
set to NULL and this function has not returned.
|
|
||||||
* Previous Close() call on this instance has not
|
|
||||||
finished.
|
|
||||||
@retval EFI_INVALID_PARAMETER One ore more parameters are invalid.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the
|
|
||||||
operation.
|
|
||||||
@retval EFI_DEVICE_ERROR Any unexpected and not belonged to above
|
|
||||||
category error.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Close (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_CLOSE_TOKEN *CloseToken
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Abort an asynchronous connection, listen, transmission or receive request.
|
|
||||||
|
|
||||||
The Cancel() function aborts a pending connection, listen, transmit or receive
|
|
||||||
request. If Token is not NULL and the token is in the connection, listen,
|
|
||||||
transmission or receive queue when it is being cancelled, its Token->Status
|
|
||||||
will be set to EFI_ABORTED and then Token->Event will be signaled. If the token
|
|
||||||
is not in one of the queues, which usually means that the asynchronous operation
|
|
||||||
has completed, EFI_NOT_FOUND is returned. If Token is NULL all asynchronous token
|
|
||||||
issued by Connect(), Accept(), Transmit() and Receive()will be aborted.
|
|
||||||
NOTE: It has not been implemented currently.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
@param Token Pointer to a token that has been issued by
|
|
||||||
Connect(), Accept(), Transmit() or Receive(). If
|
|
||||||
NULL, all pending tokens issued by above four
|
|
||||||
functions will be aborted.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The asynchronous I/O request is aborted and Token->Event
|
|
||||||
is signaled.
|
|
||||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
|
||||||
@retval EFI_NOT_STARTED This instance hasn's been configured.
|
|
||||||
@retval EFI_NO_MAPPING When using the default address, configuration
|
|
||||||
(DHCP, BOOTP,RARP, etc.) hasn's finished yet.
|
|
||||||
@retval EFI_NOT_FOUND The asynchronous I/O request isn's found in the
|
|
||||||
transmission or receive queue. It has either
|
|
||||||
completed or wasn's issued by Transmit() and Receive().
|
|
||||||
@retval EFI_UNSUPPORTED The operation is not supported in current
|
|
||||||
implementation.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Cancel (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This,
|
|
||||||
IN EFI_TCP4_COMPLETION_TOKEN *Token OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Poll to receive incoming data and transmit outgoing segments.
|
|
||||||
|
|
||||||
The Poll() function increases the rate that data is moved between the network
|
|
||||||
and application and can be called when the TCP instance is created successfully.
|
|
||||||
Its use is optional. In some implementations, the periodical timer in the MNP
|
|
||||||
driver may not poll the underlying communications device fast enough to avoid
|
|
||||||
drop packets. Drivers and applications that are experiencing packet loss should
|
|
||||||
try calling the Poll() function in a high frequency.
|
|
||||||
|
|
||||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Incoming or outgoing data was processed.
|
|
||||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
|
||||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
|
||||||
@retval EFI_NOT_READY No incoming or outgoing data was processed.
|
|
||||||
@retval EFI_TIMEOUT Data was dropped out of the transmission or
|
|
||||||
receive queue. Consider increasing the polling
|
|
||||||
rate.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
Tcp4Poll (
|
|
||||||
IN EFI_TCP4_PROTOCOL *This
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,940 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Misc support routines for tcp.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
|
|
||||||
#include "Tcp4Main.h"
|
|
||||||
|
|
||||||
#include <Library/DevicePathLib.h>
|
|
||||||
|
|
||||||
LIST_ENTRY mTcpRunQue = {
|
|
||||||
&mTcpRunQue,
|
|
||||||
&mTcpRunQue
|
|
||||||
};
|
|
||||||
|
|
||||||
LIST_ENTRY mTcpListenQue = {
|
|
||||||
&mTcpListenQue,
|
|
||||||
&mTcpListenQue
|
|
||||||
};
|
|
||||||
|
|
||||||
TCP_SEQNO mTcpGlobalIss = 0x4d7e980b;
|
|
||||||
|
|
||||||
CHAR16 *mTcpStateName[] = {
|
|
||||||
L"TCP_CLOSED",
|
|
||||||
L"TCP_LISTEN",
|
|
||||||
L"TCP_SYN_SENT",
|
|
||||||
L"TCP_SYN_RCVD",
|
|
||||||
L"TCP_ESTABLISHED",
|
|
||||||
L"TCP_FIN_WAIT_1",
|
|
||||||
L"TCP_FIN_WAIT_2",
|
|
||||||
L"TCP_CLOSING",
|
|
||||||
L"TCP_TIME_WAIT",
|
|
||||||
L"TCP_CLOSE_WAIT",
|
|
||||||
L"TCP_LAST_ACK"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initialize the Tcb local related members.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpInitTcbLocal (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Compute the checksum of the fixed parts of pseudo header
|
|
||||||
//
|
|
||||||
Tcb->HeadSum = NetPseudoHeadChecksum (
|
|
||||||
Tcb->LocalEnd.Ip,
|
|
||||||
Tcb->RemoteEnd.Ip,
|
|
||||||
0x06,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
Tcb->Iss = TcpGetIss ();
|
|
||||||
Tcb->SndUna = Tcb->Iss;
|
|
||||||
Tcb->SndNxt = Tcb->Iss;
|
|
||||||
|
|
||||||
Tcb->SndWl2 = Tcb->Iss;
|
|
||||||
Tcb->SndWnd = 536;
|
|
||||||
|
|
||||||
Tcb->RcvWnd = GET_RCV_BUFFSIZE (Tcb->Sk);
|
|
||||||
|
|
||||||
//
|
|
||||||
// First window size is never scaled
|
|
||||||
//
|
|
||||||
Tcb->RcvWndScale = 0;
|
|
||||||
Tcb->RetxmitSeqMax = 0;
|
|
||||||
|
|
||||||
Tcb->ProbeTimerOn = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initialize the peer related members.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Seg Pointer to the segment that contains the peer's
|
|
||||||
intial info.
|
|
||||||
@param Opt Pointer to the options announced by the peer.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpInitTcbPeer (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN TCP_SEG *Seg,
|
|
||||||
IN TCP_OPTION *Opt
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT16 RcvMss;
|
|
||||||
|
|
||||||
ASSERT ((Tcb != NULL) && (Seg != NULL) && (Opt != NULL));
|
|
||||||
ASSERT (TCP_FLG_ON (Seg->Flag, TCP_FLG_SYN));
|
|
||||||
|
|
||||||
Tcb->SndWnd = Seg->Wnd;
|
|
||||||
Tcb->SndWndMax = Tcb->SndWnd;
|
|
||||||
Tcb->SndWl1 = Seg->Seq;
|
|
||||||
|
|
||||||
if (TCP_FLG_ON (Seg->Flag, TCP_FLG_ACK)) {
|
|
||||||
Tcb->SndWl2 = Seg->Ack;
|
|
||||||
} else {
|
|
||||||
Tcb->SndWl2 = Tcb->Iss + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TCP_FLG_ON (Opt->Flag, TCP_OPTION_RCVD_MSS)) {
|
|
||||||
Tcb->SndMss = (UINT16) MAX (64, Opt->Mss);
|
|
||||||
|
|
||||||
RcvMss = TcpGetRcvMss (Tcb->Sk);
|
|
||||||
if (Tcb->SndMss > RcvMss) {
|
|
||||||
Tcb->SndMss = RcvMss;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// One end doesn't support MSS option, use default.
|
|
||||||
//
|
|
||||||
Tcb->RcvMss = 536;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tcb->CWnd = Tcb->SndMss;
|
|
||||||
|
|
||||||
Tcb->Irs = Seg->Seq;
|
|
||||||
Tcb->RcvNxt = Tcb->Irs + 1;
|
|
||||||
|
|
||||||
Tcb->RcvWl2 = Tcb->RcvNxt;
|
|
||||||
|
|
||||||
if (TCP_FLG_ON (Opt->Flag, TCP_OPTION_RCVD_WS) &&
|
|
||||||
!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS)) {
|
|
||||||
|
|
||||||
Tcb->SndWndScale = Opt->WndScale;
|
|
||||||
|
|
||||||
Tcb->RcvWndScale = TcpComputeScale (Tcb);
|
|
||||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_RCVD_WS);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// One end doesn't support window scale option. use zero.
|
|
||||||
//
|
|
||||||
Tcb->RcvWndScale = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TCP_FLG_ON (Opt->Flag, TCP_OPTION_RCVD_TS) &&
|
|
||||||
!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS)) {
|
|
||||||
|
|
||||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_TS);
|
|
||||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_RCVD_TS);
|
|
||||||
|
|
||||||
Tcb->TsRecent = Opt->TSVal;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Compute the effective SndMss per RFC1122
|
|
||||||
// section 4.2.2.6. If timestamp option is
|
|
||||||
// enabled, it will always occupy 12 bytes.
|
|
||||||
//
|
|
||||||
Tcb->SndMss -= TCP_OPTION_TS_ALIGNED_LEN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Locate a listen TCB that matchs the Local and Remote.
|
|
||||||
|
|
||||||
@param Local Pointer to the local (IP, Port).
|
|
||||||
@param Remote Pointer to the remote (IP, Port).
|
|
||||||
|
|
||||||
@return Pointer to the TCP_CB with the least number of wildcard,
|
|
||||||
if NULL no match is found.
|
|
||||||
|
|
||||||
**/
|
|
||||||
TCP_CB *
|
|
||||||
TcpLocateListenTcb (
|
|
||||||
IN TCP_PEER *Local,
|
|
||||||
IN TCP_PEER *Remote
|
|
||||||
)
|
|
||||||
{
|
|
||||||
LIST_ENTRY *Entry;
|
|
||||||
TCP_CB *Node;
|
|
||||||
TCP_CB *Match;
|
|
||||||
INTN Last;
|
|
||||||
INTN Cur;
|
|
||||||
|
|
||||||
Last = 4;
|
|
||||||
Match = NULL;
|
|
||||||
|
|
||||||
NET_LIST_FOR_EACH (Entry, &mTcpListenQue) {
|
|
||||||
Node = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
|
|
||||||
|
|
||||||
if ((Local->Port != Node->LocalEnd.Port) ||
|
|
||||||
!TCP_PEER_MATCH (Remote, &Node->RemoteEnd) ||
|
|
||||||
!TCP_PEER_MATCH (Local, &Node->LocalEnd)) {
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Compute the number of wildcard
|
|
||||||
//
|
|
||||||
Cur = 0;
|
|
||||||
if (Node->RemoteEnd.Ip == 0) {
|
|
||||||
Cur++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Node->RemoteEnd.Port == 0) {
|
|
||||||
Cur++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Node->LocalEnd.Ip == 0) {
|
|
||||||
Cur++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Cur < Last) {
|
|
||||||
if (Cur == 0) {
|
|
||||||
return Node;
|
|
||||||
}
|
|
||||||
|
|
||||||
Last = Cur;
|
|
||||||
Match = Node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Match;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Try to find one Tcb whose <Ip, Port> equals to <IN Addr, IN Port>.
|
|
||||||
|
|
||||||
@param Addr Pointer to the IP address needs to match.
|
|
||||||
@param Port The port number needs to match.
|
|
||||||
|
|
||||||
@return The Tcb which matches the <Addr Port> paire exists or not.
|
|
||||||
|
|
||||||
**/
|
|
||||||
BOOLEAN
|
|
||||||
TcpFindTcbByPeer (
|
|
||||||
IN EFI_IPv4_ADDRESS *Addr,
|
|
||||||
IN TCP_PORTNO Port
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP_PORTNO LocalPort;
|
|
||||||
LIST_ENTRY *Entry;
|
|
||||||
TCP_CB *Tcb;
|
|
||||||
|
|
||||||
ASSERT ((Addr != NULL) && (Port != 0));
|
|
||||||
|
|
||||||
LocalPort = HTONS (Port);
|
|
||||||
|
|
||||||
NET_LIST_FOR_EACH (Entry, &mTcpListenQue) {
|
|
||||||
Tcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
|
|
||||||
|
|
||||||
if (EFI_IP4_EQUAL (Addr, &Tcb->LocalEnd.Ip) &&
|
|
||||||
(LocalPort == Tcb->LocalEnd.Port)) {
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NET_LIST_FOR_EACH (Entry, &mTcpRunQue) {
|
|
||||||
Tcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
|
|
||||||
|
|
||||||
if (EFI_IP4_EQUAL (Addr, &Tcb->LocalEnd.Ip) &&
|
|
||||||
(LocalPort == Tcb->LocalEnd.Port)) {
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Locate the TCP_CB related to the socket pair.
|
|
||||||
|
|
||||||
@param LocalPort The local port number.
|
|
||||||
@param LocalIp The local IP address.
|
|
||||||
@param RemotePort The remote port number.
|
|
||||||
@param RemoteIp The remote IP address.
|
|
||||||
@param Syn Whether to search the listen sockets, if TRUE, the
|
|
||||||
listen sockets are searched.
|
|
||||||
|
|
||||||
@return Pointer to the related TCP_CB, if NULL no match is found.
|
|
||||||
|
|
||||||
**/
|
|
||||||
TCP_CB *
|
|
||||||
TcpLocateTcb (
|
|
||||||
IN TCP_PORTNO LocalPort,
|
|
||||||
IN UINT32 LocalIp,
|
|
||||||
IN TCP_PORTNO RemotePort,
|
|
||||||
IN UINT32 RemoteIp,
|
|
||||||
IN BOOLEAN Syn
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP_PEER Local;
|
|
||||||
TCP_PEER Remote;
|
|
||||||
LIST_ENTRY *Entry;
|
|
||||||
TCP_CB *Tcb;
|
|
||||||
|
|
||||||
Local.Port = LocalPort;
|
|
||||||
Local.Ip = LocalIp;
|
|
||||||
|
|
||||||
Remote.Port = RemotePort;
|
|
||||||
Remote.Ip = RemoteIp;
|
|
||||||
|
|
||||||
//
|
|
||||||
// First check for exact match.
|
|
||||||
//
|
|
||||||
NET_LIST_FOR_EACH (Entry, &mTcpRunQue) {
|
|
||||||
Tcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
|
|
||||||
|
|
||||||
if (TCP_PEER_EQUAL (&Remote, &Tcb->RemoteEnd) &&
|
|
||||||
TCP_PEER_EQUAL (&Local, &Tcb->LocalEnd)) {
|
|
||||||
|
|
||||||
RemoveEntryList (&Tcb->List);
|
|
||||||
InsertHeadList (&mTcpRunQue, &Tcb->List);
|
|
||||||
|
|
||||||
return Tcb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Only check listen queue when SYN flag is on
|
|
||||||
//
|
|
||||||
if (Syn) {
|
|
||||||
return TcpLocateListenTcb (&Local, &Remote);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Insert a Tcb into the proper queue.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB to be inserted.
|
|
||||||
|
|
||||||
@retval 0 The Tcb is inserted successfully.
|
|
||||||
@retval -1 Error condition occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpInsertTcb (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
LIST_ENTRY *Entry;
|
|
||||||
LIST_ENTRY *Head;
|
|
||||||
TCP_CB *Node;
|
|
||||||
|
|
||||||
ASSERT (
|
|
||||||
(Tcb != NULL) &&
|
|
||||||
((Tcb->State == TCP_LISTEN) ||
|
|
||||||
(Tcb->State == TCP_SYN_SENT) ||
|
|
||||||
(Tcb->State == TCP_SYN_RCVD) ||
|
|
||||||
(Tcb->State == TCP_CLOSED))
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Tcb->LocalEnd.Port == 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Head = &mTcpRunQue;
|
|
||||||
|
|
||||||
if (Tcb->State == TCP_LISTEN) {
|
|
||||||
Head = &mTcpListenQue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check that Tcb isn't already on the list.
|
|
||||||
//
|
|
||||||
NET_LIST_FOR_EACH (Entry, Head) {
|
|
||||||
Node = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
|
|
||||||
|
|
||||||
if (TCP_PEER_EQUAL (&Tcb->LocalEnd, &Node->LocalEnd) &&
|
|
||||||
TCP_PEER_EQUAL (&Tcb->RemoteEnd, &Node->RemoteEnd)) {
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InsertHeadList (Head, &Tcb->List);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Clone a TCB_CB from Tcb.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB to be cloned.
|
|
||||||
|
|
||||||
@return Pointer to the new cloned TCP_CB, if NULL error condition occurred.
|
|
||||||
|
|
||||||
**/
|
|
||||||
TCP_CB *
|
|
||||||
TcpCloneTcb (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP_CB *Clone;
|
|
||||||
|
|
||||||
Clone = AllocatePool (sizeof (TCP_CB));
|
|
||||||
|
|
||||||
if (Clone == NULL) {
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
CopyMem (Clone, Tcb, sizeof (TCP_CB));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Increate the reference count of the shared IpInfo.
|
|
||||||
//
|
|
||||||
NET_GET_REF (Tcb->IpInfo);
|
|
||||||
|
|
||||||
InitializeListHead (&Clone->List);
|
|
||||||
InitializeListHead (&Clone->SndQue);
|
|
||||||
InitializeListHead (&Clone->RcvQue);
|
|
||||||
|
|
||||||
Clone->Sk = SockClone (Tcb->Sk);
|
|
||||||
if (Clone->Sk == NULL) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "TcpCloneTcb: failed to clone a sock\n"));
|
|
||||||
FreePool (Clone);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpPcb = Clone;
|
|
||||||
|
|
||||||
return Clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compute an ISS to be used by a new connection.
|
|
||||||
|
|
||||||
@return The result ISS.
|
|
||||||
|
|
||||||
**/
|
|
||||||
TCP_SEQNO
|
|
||||||
TcpGetIss (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
mTcpGlobalIss += 2048;
|
|
||||||
return mTcpGlobalIss;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the local mss.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket to get mss
|
|
||||||
|
|
||||||
@return The mss size.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT16
|
|
||||||
TcpGetRcvMss (
|
|
||||||
IN SOCKET *Sock
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_IP4_MODE_DATA Ip4Mode;
|
|
||||||
TCP4_PROTO_DATA *TcpProto;
|
|
||||||
EFI_IP4_PROTOCOL *Ip;
|
|
||||||
|
|
||||||
ASSERT (Sock != NULL);
|
|
||||||
|
|
||||||
TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
|
||||||
Ip = TcpProto->TcpService->IpIo->Ip.Ip4;
|
|
||||||
ASSERT (Ip != NULL);
|
|
||||||
|
|
||||||
Ip->GetModeData (Ip, &Ip4Mode, NULL, NULL);
|
|
||||||
|
|
||||||
return (UINT16) (Ip4Mode.MaxPacketSize - sizeof (TCP_HEAD));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set the Tcb's state.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param State The state to be set.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpSetState (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN UINT8 State
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ASSERT (Tcb->State < (sizeof (mTcpStateName) / sizeof (CHAR16 *)));
|
|
||||||
ASSERT (State < (sizeof (mTcpStateName) / sizeof (CHAR16 *)));
|
|
||||||
|
|
||||||
DEBUG (
|
|
||||||
(EFI_D_NET,
|
|
||||||
"Tcb (%p) state %s --> %s\n",
|
|
||||||
Tcb,
|
|
||||||
mTcpStateName[Tcb->State],
|
|
||||||
mTcpStateName[State])
|
|
||||||
);
|
|
||||||
|
|
||||||
Tcb->State = State;
|
|
||||||
|
|
||||||
switch (State) {
|
|
||||||
case TCP_ESTABLISHED:
|
|
||||||
|
|
||||||
SockConnEstablished (Tcb->Sk);
|
|
||||||
|
|
||||||
if (Tcb->Parent != NULL) {
|
|
||||||
//
|
|
||||||
// A new connection is accepted by a listening socket, install
|
|
||||||
// the device path.
|
|
||||||
//
|
|
||||||
TcpInstallDevicePath (Tcb->Sk);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TCP_CLOSED:
|
|
||||||
|
|
||||||
SockConnClosed (Tcb->Sk);
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compute the TCP segment's checksum.
|
|
||||||
|
|
||||||
@param Nbuf Pointer to the buffer that contains the TCP
|
|
||||||
segment.
|
|
||||||
@param HeadSum The checksum value of the fixed part of pseudo
|
|
||||||
header.
|
|
||||||
|
|
||||||
@return The checksum value.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT16
|
|
||||||
TcpChecksum (
|
|
||||||
IN NET_BUF *Nbuf,
|
|
||||||
IN UINT16 HeadSum
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT16 Checksum;
|
|
||||||
|
|
||||||
Checksum = NetbufChecksum (Nbuf);
|
|
||||||
Checksum = NetAddChecksum (Checksum, HeadSum);
|
|
||||||
|
|
||||||
Checksum = NetAddChecksum (
|
|
||||||
Checksum,
|
|
||||||
HTONS ((UINT16) Nbuf->TotalSize)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (UINT16) ~Checksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Translate the information from the head of the received TCP
|
|
||||||
segment Nbuf contains and fill it into a TCP_SEG structure.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Nbuf Pointer to the buffer contains the TCP segment.
|
|
||||||
|
|
||||||
@return Pointer to the TCP_SEG that contains the translated TCP head information.
|
|
||||||
|
|
||||||
**/
|
|
||||||
TCP_SEG *
|
|
||||||
TcpFormatNetbuf (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN OUT NET_BUF *Nbuf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP_SEG *Seg;
|
|
||||||
TCP_HEAD *Head;
|
|
||||||
|
|
||||||
Seg = TCPSEG_NETBUF (Nbuf);
|
|
||||||
Head = (TCP_HEAD *) NetbufGetByte (Nbuf, 0, NULL);
|
|
||||||
ASSERT (Head != NULL);
|
|
||||||
Nbuf->Tcp = Head;
|
|
||||||
|
|
||||||
Seg->Seq = NTOHL (Head->Seq);
|
|
||||||
Seg->Ack = NTOHL (Head->Ack);
|
|
||||||
Seg->End = Seg->Seq + (Nbuf->TotalSize - (Head->HeadLen << 2));
|
|
||||||
|
|
||||||
Seg->Urg = NTOHS (Head->Urg);
|
|
||||||
Seg->Wnd = (NTOHS (Head->Wnd) << Tcb->SndWndScale);
|
|
||||||
Seg->Flag = Head->Flag;
|
|
||||||
|
|
||||||
//
|
|
||||||
// SYN and FIN flag occupy one sequence space each.
|
|
||||||
//
|
|
||||||
if (TCP_FLG_ON (Seg->Flag, TCP_FLG_SYN)) {
|
|
||||||
//
|
|
||||||
// RFC requires that initial window not be scaled
|
|
||||||
//
|
|
||||||
Seg->Wnd = NTOHS (Head->Wnd);
|
|
||||||
Seg->End++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TCP_FLG_ON (Seg->Flag, TCP_FLG_FIN)) {
|
|
||||||
Seg->End++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Seg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Reset the connection related with Tcb.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of the connection to be
|
|
||||||
reset.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpResetConnection (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
NET_BUF *Nbuf;
|
|
||||||
TCP_HEAD *Nhead;
|
|
||||||
|
|
||||||
Nbuf = NetbufAlloc (TCP_MAX_HEAD);
|
|
||||||
|
|
||||||
if (Nbuf == NULL) {
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
Nhead = (TCP_HEAD *) NetbufAllocSpace (
|
|
||||||
Nbuf,
|
|
||||||
sizeof (TCP_HEAD),
|
|
||||||
NET_BUF_TAIL
|
|
||||||
);
|
|
||||||
|
|
||||||
ASSERT (Nhead != NULL);
|
|
||||||
|
|
||||||
Nbuf->Tcp = Nhead;
|
|
||||||
|
|
||||||
Nhead->Flag = TCP_FLG_RST;
|
|
||||||
Nhead->Seq = HTONL (Tcb->SndNxt);
|
|
||||||
Nhead->Ack = HTONL (Tcb->RcvNxt);
|
|
||||||
Nhead->SrcPort = Tcb->LocalEnd.Port;
|
|
||||||
Nhead->DstPort = Tcb->RemoteEnd.Port;
|
|
||||||
Nhead->HeadLen = (UINT8) (sizeof (TCP_HEAD) >> 2);
|
|
||||||
Nhead->Res = 0;
|
|
||||||
Nhead->Wnd = HTONS (0xFFFF);
|
|
||||||
Nhead->Checksum = 0;
|
|
||||||
Nhead->Urg = 0;
|
|
||||||
Nhead->Checksum = TcpChecksum (Nbuf, Tcb->HeadSum);
|
|
||||||
|
|
||||||
TcpSendIpPacket (Tcb, Nbuf, Tcb->LocalEnd.Ip, Tcb->RemoteEnd.Ip);
|
|
||||||
|
|
||||||
NetbufFree (Nbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initialize an active connection.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB that wants to initiate a
|
|
||||||
connection.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpOnAppConnect (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TcpInitTcbLocal (Tcb);
|
|
||||||
TcpSetState (Tcb, TCP_SYN_SENT);
|
|
||||||
|
|
||||||
TcpSetTimer (Tcb, TCP_TIMER_CONNECT, Tcb->ConnectTimeout);
|
|
||||||
TcpToSendData (Tcb, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initiate the connection close procedure, called when
|
|
||||||
applications want to close the connection.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpOnAppClose (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ASSERT (Tcb != NULL);
|
|
||||||
|
|
||||||
if (!IsListEmpty (&Tcb->RcvQue) || GET_RCV_DATASIZE (Tcb->Sk) != 0) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_WARN, "TcpOnAppClose: connection reset "
|
|
||||||
"because data is lost for TCB %p\n", Tcb));
|
|
||||||
|
|
||||||
TcpResetConnection (Tcb);
|
|
||||||
TcpClose (Tcb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Tcb->State) {
|
|
||||||
case TCP_CLOSED:
|
|
||||||
case TCP_LISTEN:
|
|
||||||
case TCP_SYN_SENT:
|
|
||||||
TcpSetState (Tcb, TCP_CLOSED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TCP_SYN_RCVD:
|
|
||||||
case TCP_ESTABLISHED:
|
|
||||||
TcpSetState (Tcb, TCP_FIN_WAIT_1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TCP_CLOSE_WAIT:
|
|
||||||
TcpSetState (Tcb, TCP_LAST_ACK);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpToSendData (Tcb, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check whether the application's newly delivered data can be sent out.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
@retval 0 Whether the data is sent out or is buffered for
|
|
||||||
further sending.
|
|
||||||
@retval -1 The Tcb is not in a state that data is permitted to
|
|
||||||
be sent out.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpOnAppSend (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
switch (Tcb->State) {
|
|
||||||
case TCP_CLOSED:
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
case TCP_LISTEN:
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
case TCP_SYN_SENT:
|
|
||||||
case TCP_SYN_RCVD:
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case TCP_ESTABLISHED:
|
|
||||||
case TCP_CLOSE_WAIT:
|
|
||||||
TcpToSendData (Tcb, 0);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case TCP_FIN_WAIT_1:
|
|
||||||
case TCP_FIN_WAIT_2:
|
|
||||||
case TCP_CLOSING:
|
|
||||||
case TCP_LAST_ACK:
|
|
||||||
case TCP_TIME_WAIT:
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Application has consumed some data, check whether
|
|
||||||
to send a window updata ack or a delayed ack.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpOnAppConsume (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 TcpOld;
|
|
||||||
|
|
||||||
switch (Tcb->State) {
|
|
||||||
case TCP_CLOSED:
|
|
||||||
return;
|
|
||||||
|
|
||||||
case TCP_LISTEN:
|
|
||||||
return;
|
|
||||||
|
|
||||||
case TCP_SYN_SENT:
|
|
||||||
case TCP_SYN_RCVD:
|
|
||||||
return;
|
|
||||||
|
|
||||||
case TCP_ESTABLISHED:
|
|
||||||
TcpOld = TcpRcvWinOld (Tcb);
|
|
||||||
if (TcpRcvWinNow (Tcb) > TcpOld) {
|
|
||||||
|
|
||||||
if (TcpOld < Tcb->RcvMss) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_NET, "TcpOnAppConsume: send a window"
|
|
||||||
" update for a window closed Tcb %p\n", Tcb));
|
|
||||||
|
|
||||||
TcpSendAck (Tcb);
|
|
||||||
} else if (Tcb->DelayedAck == 0) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_NET, "TcpOnAppConsume: scheduled a delayed"
|
|
||||||
" ACK to update window for Tcb %p\n", Tcb));
|
|
||||||
|
|
||||||
Tcb->DelayedAck = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TCP_CLOSE_WAIT:
|
|
||||||
return;
|
|
||||||
|
|
||||||
case TCP_FIN_WAIT_1:
|
|
||||||
case TCP_FIN_WAIT_2:
|
|
||||||
case TCP_CLOSING:
|
|
||||||
case TCP_LAST_ACK:
|
|
||||||
case TCP_TIME_WAIT:
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Abort the connection by sending a reset segment, called
|
|
||||||
when the application wants to abort the connection.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of the TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpOnAppAbort (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DEBUG ((EFI_D_WARN, "TcpOnAppAbort: connection reset "
|
|
||||||
"issued by application for TCB %p\n", Tcb));
|
|
||||||
|
|
||||||
switch (Tcb->State) {
|
|
||||||
case TCP_SYN_RCVD:
|
|
||||||
case TCP_ESTABLISHED:
|
|
||||||
case TCP_FIN_WAIT_1:
|
|
||||||
case TCP_FIN_WAIT_2:
|
|
||||||
case TCP_CLOSE_WAIT:
|
|
||||||
TcpResetConnection (Tcb);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpSetState (Tcb, TCP_CLOSED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Install the device path protocol on the TCP instance.
|
|
||||||
|
|
||||||
@param Sock Pointer to the socket representing the TCP instance.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The device path protocol is installed.
|
|
||||||
@retval other Failed to install the device path protocol.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
TcpInstallDevicePath (
|
|
||||||
IN SOCKET *Sock
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP4_PROTO_DATA *TcpProto;
|
|
||||||
TCP4_SERVICE_DATA *TcpService;
|
|
||||||
TCP_CB *Tcb;
|
|
||||||
IPv4_DEVICE_PATH Ip4DPathNode;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
TCP_PORTNO LocalPort;
|
|
||||||
TCP_PORTNO RemotePort;
|
|
||||||
|
|
||||||
TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
|
||||||
TcpService = TcpProto->TcpService;
|
|
||||||
Tcb = TcpProto->TcpPcb;
|
|
||||||
|
|
||||||
LocalPort = NTOHS (Tcb->LocalEnd.Port);
|
|
||||||
RemotePort = NTOHS (Tcb->RemoteEnd.Port);
|
|
||||||
NetLibCreateIPv4DPathNode (
|
|
||||||
&Ip4DPathNode,
|
|
||||||
TcpService->ControllerHandle,
|
|
||||||
Tcb->LocalEnd.Ip,
|
|
||||||
LocalPort,
|
|
||||||
Tcb->RemoteEnd.Ip,
|
|
||||||
RemotePort,
|
|
||||||
EFI_IP_PROTO_TCP,
|
|
||||||
Tcb->UseDefaultAddr
|
|
||||||
);
|
|
||||||
|
|
||||||
IP4_COPY_ADDRESS (&Ip4DPathNode.SubnetMask, &Tcb->SubnetMask);
|
|
||||||
|
|
||||||
Sock->DevicePath = AppendDevicePathNode (
|
|
||||||
Sock->ParentDevicePath,
|
|
||||||
(EFI_DEVICE_PATH_PROTOCOL *) &Ip4DPathNode
|
|
||||||
);
|
|
||||||
if (Sock->DevicePath == NULL) {
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = gBS->InstallProtocolInterface (
|
|
||||||
&Sock->SockHandle,
|
|
||||||
&gEfiDevicePathProtocolGuid,
|
|
||||||
EFI_NATIVE_INTERFACE,
|
|
||||||
Sock->DevicePath
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
FreePool (Sock->DevicePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
@ -1,352 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Routines to process TCP option.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "Tcp4Main.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get a UINT16 value from buffer.
|
|
||||||
|
|
||||||
@param Buf Pointer to input buffer.
|
|
||||||
|
|
||||||
@return The UINT16 value get from buffer.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT16
|
|
||||||
TcpGetUint16 (
|
|
||||||
IN UINT8 *Buf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT16 Value;
|
|
||||||
CopyMem (&Value, Buf, sizeof (UINT16));
|
|
||||||
return NTOHS (Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get a UINT32 value from buffer.
|
|
||||||
|
|
||||||
@param Buf Pointer to input buffer.
|
|
||||||
|
|
||||||
@return The UINT32 value get from buffer.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT32
|
|
||||||
TcpGetUint32 (
|
|
||||||
IN UINT8 *Buf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 Value;
|
|
||||||
CopyMem (&Value, Buf, sizeof (UINT32));
|
|
||||||
return NTOHL (Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Put a UINT32 value in buffer.
|
|
||||||
|
|
||||||
@param Buf Pointer to the buffer.
|
|
||||||
@param Data The UINT32 Date to put in buffer
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpPutUint32 (
|
|
||||||
OUT UINT8 *Buf,
|
|
||||||
IN UINT32 Data
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Data = HTONL (Data);
|
|
||||||
CopyMem (Buf, &Data, sizeof (UINT32));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compute the window scale value according to the given buffer size.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
@return The scale value.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT8
|
|
||||||
TcpComputeScale (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT8 Scale;
|
|
||||||
UINT32 BufSize;
|
|
||||||
|
|
||||||
ASSERT ((Tcb != NULL) && (Tcb->Sk != NULL));
|
|
||||||
|
|
||||||
BufSize = GET_RCV_BUFFSIZE (Tcb->Sk);
|
|
||||||
|
|
||||||
Scale = 0;
|
|
||||||
while ((Scale < TCP_OPTION_MAX_WS) &&
|
|
||||||
((UINT32) (TCP_OPTION_MAX_WIN << Scale) < BufSize)) {
|
|
||||||
|
|
||||||
Scale++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Build the TCP option in three-way handshake.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Nbuf Pointer to the buffer to store the options.
|
|
||||||
|
|
||||||
@return The total length of the TCP option field.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT16
|
|
||||||
TcpSynBuildOption (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN NET_BUF *Nbuf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT8 *Data;
|
|
||||||
UINT16 Len;
|
|
||||||
|
|
||||||
ASSERT ((Tcb != NULL) && (Nbuf != NULL) && (Nbuf->Tcp == NULL));
|
|
||||||
|
|
||||||
Len = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add timestamp option if not disabled by application
|
|
||||||
// and it is the first SYN segment or the peer has sent
|
|
||||||
// us its timestamp.
|
|
||||||
//
|
|
||||||
if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS) &&
|
|
||||||
(!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_ACK) ||
|
|
||||||
TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_TS))) {
|
|
||||||
|
|
||||||
Data = NetbufAllocSpace (
|
|
||||||
Nbuf,
|
|
||||||
TCP_OPTION_TS_ALIGNED_LEN,
|
|
||||||
NET_BUF_HEAD
|
|
||||||
);
|
|
||||||
|
|
||||||
ASSERT (Data != NULL);
|
|
||||||
Len += TCP_OPTION_TS_ALIGNED_LEN;
|
|
||||||
|
|
||||||
TcpPutUint32 (Data, TCP_OPTION_TS_FAST);
|
|
||||||
TcpPutUint32 (Data + 4, mTcpTick);
|
|
||||||
TcpPutUint32 (Data + 8, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Build window scale option, only when are configured
|
|
||||||
// to send WS option, and either we are doing active
|
|
||||||
// open or we have received WS option from peer.
|
|
||||||
//
|
|
||||||
if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS) &&
|
|
||||||
(!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_ACK) ||
|
|
||||||
TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_WS))) {
|
|
||||||
|
|
||||||
Data = NetbufAllocSpace (
|
|
||||||
Nbuf,
|
|
||||||
TCP_OPTION_WS_ALIGNED_LEN,
|
|
||||||
NET_BUF_HEAD
|
|
||||||
);
|
|
||||||
|
|
||||||
ASSERT (Data != NULL);
|
|
||||||
|
|
||||||
Len += TCP_OPTION_WS_ALIGNED_LEN;
|
|
||||||
TcpPutUint32 (Data, TCP_OPTION_WS_FAST | TcpComputeScale (Tcb));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Build MSS option
|
|
||||||
//
|
|
||||||
Data = NetbufAllocSpace (Nbuf, TCP_OPTION_MSS_LEN, 1);
|
|
||||||
ASSERT (Data != NULL);
|
|
||||||
|
|
||||||
Len += TCP_OPTION_MSS_LEN;
|
|
||||||
TcpPutUint32 (Data, TCP_OPTION_MSS_FAST | Tcb->RcvMss);
|
|
||||||
|
|
||||||
return Len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Build the TCP option in synchronized states.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Nbuf Pointer to the buffer to store the options.
|
|
||||||
|
|
||||||
@return The total length of the TCP option field.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT16
|
|
||||||
TcpBuildOption (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN NET_BUF *Nbuf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT8 *Data;
|
|
||||||
UINT16 Len;
|
|
||||||
|
|
||||||
ASSERT ((Tcb != NULL) && (Nbuf != NULL) && (Nbuf->Tcp == NULL));
|
|
||||||
Len = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Build Timestamp option
|
|
||||||
//
|
|
||||||
if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_SND_TS) &&
|
|
||||||
!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_RST)) {
|
|
||||||
|
|
||||||
Data = NetbufAllocSpace (
|
|
||||||
Nbuf,
|
|
||||||
TCP_OPTION_TS_ALIGNED_LEN,
|
|
||||||
NET_BUF_HEAD
|
|
||||||
);
|
|
||||||
|
|
||||||
ASSERT (Data != NULL);
|
|
||||||
Len += TCP_OPTION_TS_ALIGNED_LEN;
|
|
||||||
|
|
||||||
TcpPutUint32 (Data, TCP_OPTION_TS_FAST);
|
|
||||||
TcpPutUint32 (Data + 4, mTcpTick);
|
|
||||||
TcpPutUint32 (Data + 8, Tcb->TsRecent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Parse the supported options.
|
|
||||||
|
|
||||||
@param Tcp Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Option Pointer to the TCP_OPTION used to store the successfully pasrsed
|
|
||||||
options.
|
|
||||||
|
|
||||||
@retval 0 The options are successfully pasrsed.
|
|
||||||
@retval -1 Ilegal option was found.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpParseOption (
|
|
||||||
IN TCP_HEAD *Tcp,
|
|
||||||
IN OUT TCP_OPTION *Option
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT8 *Head;
|
|
||||||
UINT8 TotalLen;
|
|
||||||
UINT8 Cur;
|
|
||||||
UINT8 Type;
|
|
||||||
UINT8 Len;
|
|
||||||
|
|
||||||
ASSERT ((Tcp != NULL) && (Option != NULL));
|
|
||||||
|
|
||||||
Option->Flag = 0;
|
|
||||||
|
|
||||||
TotalLen = (UINT8) ((Tcp->HeadLen << 2) - sizeof (TCP_HEAD));
|
|
||||||
if (TotalLen <= 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Head = (UINT8 *) (Tcp + 1);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Fast process of timestamp option
|
|
||||||
//
|
|
||||||
if ((TotalLen == TCP_OPTION_TS_ALIGNED_LEN) &&
|
|
||||||
(TcpGetUint32 (Head) == TCP_OPTION_TS_FAST)) {
|
|
||||||
|
|
||||||
Option->TSVal = TcpGetUint32 (Head + 4);
|
|
||||||
Option->TSEcr = TcpGetUint32 (Head + 8);
|
|
||||||
Option->Flag = TCP_OPTION_RCVD_TS;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Slow path to process the options.
|
|
||||||
//
|
|
||||||
Cur = 0;
|
|
||||||
|
|
||||||
while (Cur < TotalLen) {
|
|
||||||
Type = Head[Cur];
|
|
||||||
|
|
||||||
switch (Type) {
|
|
||||||
case TCP_OPTION_MSS:
|
|
||||||
Len = Head[Cur + 1];
|
|
||||||
|
|
||||||
if ((Len != TCP_OPTION_MSS_LEN) ||
|
|
||||||
(TotalLen - Cur < TCP_OPTION_MSS_LEN)) {
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Option->Mss = TcpGetUint16 (&Head[Cur + 2]);
|
|
||||||
TCP_SET_FLG (Option->Flag, TCP_OPTION_RCVD_MSS);
|
|
||||||
|
|
||||||
Cur += TCP_OPTION_MSS_LEN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TCP_OPTION_WS:
|
|
||||||
Len = Head[Cur + 1];
|
|
||||||
|
|
||||||
if ((Len != TCP_OPTION_WS_LEN) ||
|
|
||||||
(TotalLen - Cur < TCP_OPTION_WS_LEN)) {
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Option->WndScale = (UINT8) MIN (14, Head[Cur + 2]);
|
|
||||||
TCP_SET_FLG (Option->Flag, TCP_OPTION_RCVD_WS);
|
|
||||||
|
|
||||||
Cur += TCP_OPTION_WS_LEN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TCP_OPTION_TS:
|
|
||||||
Len = Head[Cur + 1];
|
|
||||||
|
|
||||||
if ((Len != TCP_OPTION_TS_LEN) ||
|
|
||||||
(TotalLen - Cur < TCP_OPTION_TS_LEN)) {
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Option->TSVal = TcpGetUint32 (&Head[Cur + 2]);
|
|
||||||
Option->TSEcr = TcpGetUint32 (&Head[Cur + 6]);
|
|
||||||
TCP_SET_FLG (Option->Flag, TCP_OPTION_RCVD_TS);
|
|
||||||
|
|
||||||
Cur += TCP_OPTION_TS_LEN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TCP_OPTION_NOP:
|
|
||||||
Cur++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TCP_OPTION_EOP:
|
|
||||||
Cur = TotalLen;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Len = Head[Cur + 1];
|
|
||||||
|
|
||||||
if ((TotalLen - Cur) < Len || Len < 2) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cur = (UINT8) (Cur + Len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,130 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Tcp option's routine header file.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#ifndef _TCP4_OPTION_H_
|
|
||||||
#define _TCP4_OPTION_H_
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The structure to store the parse option value.
|
|
||||||
/// ParseOption only parse the options, don't process them.
|
|
||||||
///
|
|
||||||
typedef struct _TCP_OPTION {
|
|
||||||
UINT8 Flag; ///< Flag such as TCP_OPTION_RCVD_MSS
|
|
||||||
UINT8 WndScale; ///< The WndScale received
|
|
||||||
UINT16 Mss; ///< The Mss received
|
|
||||||
UINT32 TSVal; ///< The TSVal field in a timestamp option
|
|
||||||
UINT32 TSEcr; ///< The TSEcr field in a timestamp option
|
|
||||||
} TCP_OPTION;
|
|
||||||
|
|
||||||
//
|
|
||||||
// supported TCP option type and their length
|
|
||||||
//
|
|
||||||
#define TCP_OPTION_EOP 0 ///< End Of oPtion
|
|
||||||
#define TCP_OPTION_NOP 1 ///< No-Option.
|
|
||||||
#define TCP_OPTION_MSS 2 ///< Maximum Segment Size
|
|
||||||
#define TCP_OPTION_WS 3 ///< Window scale
|
|
||||||
#define TCP_OPTION_TS 8 ///< Timestamp
|
|
||||||
#define TCP_OPTION_MSS_LEN 4 ///< Length of MSS option
|
|
||||||
#define TCP_OPTION_WS_LEN 3 ///< Length of window scale option
|
|
||||||
#define TCP_OPTION_TS_LEN 10 ///< Length of timestamp option
|
|
||||||
#define TCP_OPTION_WS_ALIGNED_LEN 4 ///< Length of window scale option, aligned
|
|
||||||
#define TCP_OPTION_TS_ALIGNED_LEN 12 ///< Length of timestamp option, aligned
|
|
||||||
|
|
||||||
//
|
|
||||||
// recommend format of timestamp window scale
|
|
||||||
// option for fast process.
|
|
||||||
//
|
|
||||||
#define TCP_OPTION_TS_FAST ((TCP_OPTION_NOP << 24) | \
|
|
||||||
(TCP_OPTION_NOP << 16) | \
|
|
||||||
(TCP_OPTION_TS << 8) | \
|
|
||||||
(TCP_OPTION_TS_LEN))
|
|
||||||
|
|
||||||
#define TCP_OPTION_WS_FAST ((TCP_OPTION_NOP << 24) | \
|
|
||||||
(TCP_OPTION_WS << 16) | \
|
|
||||||
(TCP_OPTION_WS_LEN << 8))
|
|
||||||
|
|
||||||
#define TCP_OPTION_MSS_FAST ((TCP_OPTION_MSS << 24) | (TCP_OPTION_MSS_LEN << 16))
|
|
||||||
|
|
||||||
//
|
|
||||||
// Other misc definations
|
|
||||||
//
|
|
||||||
#define TCP_OPTION_RCVD_MSS 0x01
|
|
||||||
#define TCP_OPTION_RCVD_WS 0x02
|
|
||||||
#define TCP_OPTION_RCVD_TS 0x04
|
|
||||||
#define TCP_OPTION_MAX_WS 14 ///< Maxium window scale value
|
|
||||||
#define TCP_OPTION_MAX_WIN 0xffff ///< Max window size in TCP header
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compute the window scale value according to the given buffer size.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
@return The scale value.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT8
|
|
||||||
TcpComputeScale (
|
|
||||||
IN TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Build the TCP option in three-way handshake.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Nbuf Pointer to the buffer to store the options.
|
|
||||||
|
|
||||||
@return The total length of the TCP option field.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT16
|
|
||||||
TcpSynBuildOption (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN NET_BUF *Nbuf
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Build the TCP option in synchronized states.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Nbuf Pointer to the buffer to store the options.
|
|
||||||
|
|
||||||
@return The total length of the TCP option field.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT16
|
|
||||||
TcpBuildOption (
|
|
||||||
IN TCP_CB *Tcb,
|
|
||||||
IN NET_BUF *Nbuf
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Parse the supported options.
|
|
||||||
|
|
||||||
@param Tcp Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Option Pointer to the TCP_OPTION used to store the successfully pasrsed
|
|
||||||
options.
|
|
||||||
|
|
||||||
@retval 0 The options are successfully pasrsed.
|
|
||||||
@retval -1 Ilegal option was found.
|
|
||||||
|
|
||||||
**/
|
|
||||||
INTN
|
|
||||||
TcpParseOption (
|
|
||||||
IN TCP_HEAD *Tcp,
|
|
||||||
IN OUT TCP_OPTION *Option
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
@ -1,357 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Tcp Protocol header file.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#ifndef _TCP4_PROTO_H_
|
|
||||||
#define _TCP4_PROTO_H_
|
|
||||||
|
|
||||||
typedef struct _TCP_CB TCP_CB;
|
|
||||||
|
|
||||||
#include "Tcp4Driver.h"
|
|
||||||
#include "Socket.h"
|
|
||||||
#include "Tcp4Option.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Tcp states, Don't change their order, it is used as
|
|
||||||
/// index to mTcpOutFlag and other macros
|
|
||||||
///
|
|
||||||
#define TCP_CLOSED 0
|
|
||||||
#define TCP_LISTEN 1
|
|
||||||
#define TCP_SYN_SENT 2
|
|
||||||
#define TCP_SYN_RCVD 3
|
|
||||||
#define TCP_ESTABLISHED 4
|
|
||||||
#define TCP_FIN_WAIT_1 5
|
|
||||||
#define TCP_FIN_WAIT_2 6
|
|
||||||
#define TCP_CLOSING 7
|
|
||||||
#define TCP_TIME_WAIT 8
|
|
||||||
#define TCP_CLOSE_WAIT 9
|
|
||||||
#define TCP_LAST_ACK 10
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Flags in the TCP header
|
|
||||||
///
|
|
||||||
#define TCP_FLG_FIN 0x01
|
|
||||||
#define TCP_FLG_SYN 0x02
|
|
||||||
#define TCP_FLG_RST 0x04
|
|
||||||
#define TCP_FLG_PSH 0x08
|
|
||||||
#define TCP_FLG_ACK 0x10
|
|
||||||
#define TCP_FLG_URG 0x20
|
|
||||||
|
|
||||||
//
|
|
||||||
// mask for all the flags
|
|
||||||
//
|
|
||||||
#define TCP_FLG_FLAG 0x3F
|
|
||||||
|
|
||||||
|
|
||||||
#define TCP_CONNECT_REFUSED (-1) ///< TCP error status
|
|
||||||
#define TCP_CONNECT_RESET (-2) ///< TCP error status
|
|
||||||
#define TCP_CONNECT_CLOSED (-3) ///< TCP error status
|
|
||||||
|
|
||||||
//
|
|
||||||
// Current congestion status as suggested by RFC3782.
|
|
||||||
//
|
|
||||||
#define TCP_CONGEST_RECOVER 1 ///< During the NewReno fast recovery
|
|
||||||
#define TCP_CONGEST_LOSS 2 ///< Retxmit because of retxmit time out
|
|
||||||
#define TCP_CONGEST_OPEN 3 ///< TCP is opening its congestion window
|
|
||||||
|
|
||||||
//
|
|
||||||
// TCP control flags
|
|
||||||
//
|
|
||||||
#define TCP_CTRL_NO_NAGLE 0x0001 ///< Disable Nagle algorithm
|
|
||||||
#define TCP_CTRL_NO_KEEPALIVE 0x0002 ///< Disable keepalive timer
|
|
||||||
#define TCP_CTRL_NO_WS 0x0004 ///< Disable window scale option
|
|
||||||
#define TCP_CTRL_RCVD_WS 0x0008 ///< Received a wnd scale option in syn
|
|
||||||
#define TCP_CTRL_NO_TS 0x0010 ///< Disable Timestamp option
|
|
||||||
#define TCP_CTRL_RCVD_TS 0x0020 ///< Received a Timestamp option in syn
|
|
||||||
#define TCP_CTRL_SND_TS 0x0040 ///< Send Timestamp option to remote
|
|
||||||
#define TCP_CTRL_SND_URG 0x0080 ///< In urgent send mode
|
|
||||||
#define TCP_CTRL_RCVD_URG 0x0100 ///< In urgent receive mode
|
|
||||||
#define TCP_CTRL_SND_PSH 0x0200 ///< In PUSH send mode
|
|
||||||
#define TCP_CTRL_FIN_SENT 0x0400 ///< FIN is sent
|
|
||||||
#define TCP_CTRL_FIN_ACKED 0x0800 ///< FIN is ACKed.
|
|
||||||
#define TCP_CTRL_TIMER_ON 0x1000 ///< At least one of the timer is on
|
|
||||||
#define TCP_CTRL_RTT_ON 0x2000 ///< The RTT measurement is on
|
|
||||||
#define TCP_CTRL_ACK_NOW 0x4000 ///< Send the ACK now, don't delay
|
|
||||||
|
|
||||||
//
|
|
||||||
// Timer related values
|
|
||||||
//
|
|
||||||
#define TCP_TIMER_CONNECT 0 ///< Connection establishment timer
|
|
||||||
#define TCP_TIMER_REXMIT 1 ///< Retransmit timer
|
|
||||||
#define TCP_TIMER_PROBE 2 ///< Window probe timer
|
|
||||||
#define TCP_TIMER_KEEPALIVE 3 ///< Keepalive timer
|
|
||||||
#define TCP_TIMER_FINWAIT2 4 ///< FIN_WAIT_2 timer
|
|
||||||
#define TCP_TIMER_2MSL 5 ///< TIME_WAIT tiemr
|
|
||||||
#define TCP_TIMER_NUMBER 6 ///< The total number of TCP timer.
|
|
||||||
#define TCP_TICK 200 ///< Every TCP tick is 200ms
|
|
||||||
#define TCP_TICK_HZ 5 ///< The frequence of TCP tick
|
|
||||||
#define TCP_RTT_SHIFT 3 ///< SRTT & RTTVAR scaled by 8
|
|
||||||
#define TCP_RTO_MIN TCP_TICK_HZ ///< The minium value of RTO
|
|
||||||
#define TCP_RTO_MAX (TCP_TICK_HZ * 60) ///< The maxium value of RTO
|
|
||||||
#define TCP_FOLD_RTT 4 ///< Timeout threshod to fold RTT
|
|
||||||
|
|
||||||
//
|
|
||||||
// Default values for some timers
|
|
||||||
//
|
|
||||||
#define TCP_MAX_LOSS 12 ///< Default max times to retxmit
|
|
||||||
#define TCP_KEEPALIVE_IDLE_MIN (TCP_TICK_HZ * 60 * 60 * 2) ///< First keep alive
|
|
||||||
#define TCP_KEEPALIVE_PERIOD (TCP_TICK_HZ * 60)
|
|
||||||
#define TCP_MAX_KEEPALIVE 8
|
|
||||||
#define TCP_FIN_WAIT2_TIME (2 * TCP_TICK_HZ)
|
|
||||||
#define TCP_TIME_WAIT_TIME (2 * TCP_TICK_HZ)
|
|
||||||
#define TCP_PAWS_24DAY (24 * 24 * 60 * 60 * TCP_TICK_HZ)
|
|
||||||
#define TCP_CONNECT_TIME (75 * TCP_TICK_HZ)
|
|
||||||
|
|
||||||
//
|
|
||||||
// The header space to be reserved before TCP data to accomodate :
|
|
||||||
// 60byte IP head + 60byte TCP head + link layer head
|
|
||||||
//
|
|
||||||
#define TCP_MAX_HEAD 192
|
|
||||||
|
|
||||||
//
|
|
||||||
// Value ranges for some control option
|
|
||||||
//
|
|
||||||
#define TCP_RCV_BUF_SIZE (2 * 1024 * 1024)
|
|
||||||
#define TCP_RCV_BUF_SIZE_MIN (8 * 1024)
|
|
||||||
#define TCP_SND_BUF_SIZE (2 * 1024 * 1024)
|
|
||||||
#define TCP_SND_BUF_SIZE_MIN (8 * 1024)
|
|
||||||
#define TCP_BACKLOG 10
|
|
||||||
#define TCP_BACKLOG_MIN 5
|
|
||||||
#define TCP_MAX_LOSS_MIN 6
|
|
||||||
#define TCP_CONNECT_TIME_MIN (60 * TCP_TICK_HZ)
|
|
||||||
#define TCP_MAX_KEEPALIVE_MIN 4
|
|
||||||
#define TCP_KEEPALIVE_IDLE_MAX (TCP_TICK_HZ * 60 * 60 * 4)
|
|
||||||
#define TCP_KEEPALIVE_PERIOD_MIN (TCP_TICK_HZ * 30)
|
|
||||||
#define TCP_FIN_WAIT2_TIME_MAX (4 * TCP_TICK_HZ)
|
|
||||||
#define TCP_TIME_WAIT_TIME_MAX (60 * TCP_TICK_HZ)
|
|
||||||
|
|
||||||
///
|
|
||||||
/// TCP segmentation data
|
|
||||||
///
|
|
||||||
typedef struct _TCP_SEG {
|
|
||||||
TCP_SEQNO Seq; ///< Starting sequence number
|
|
||||||
TCP_SEQNO End; ///< The sequence of the last byte + 1, include SYN/FIN. End-Seq = SEG.LEN
|
|
||||||
TCP_SEQNO Ack; ///< ACK field in the segment
|
|
||||||
UINT8 Flag; ///< TCP header flags
|
|
||||||
UINT16 Urg; ///< Valid if URG flag is set.
|
|
||||||
UINT32 Wnd; ///< TCP window size field
|
|
||||||
} TCP_SEG;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Network endpoint, IP+Port structure
|
|
||||||
///
|
|
||||||
typedef struct _TCP_PEER {
|
|
||||||
UINT32 Ip; ///< IP address, network byte order
|
|
||||||
TCP_PORTNO Port; ///< Port number, network byte order
|
|
||||||
} TCP_PEER;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// TCP control block, it includes various states
|
|
||||||
///
|
|
||||||
struct _TCP_CB {
|
|
||||||
LIST_ENTRY List; ///< Back and forward link entry
|
|
||||||
TCP_CB *Parent; ///< The parent TCP_CB structure
|
|
||||||
|
|
||||||
SOCKET *Sk; ///< The socket it controled.
|
|
||||||
TCP_PEER LocalEnd; ///< Local endpoint
|
|
||||||
TCP_PEER RemoteEnd;///< Remote endpoint
|
|
||||||
|
|
||||||
LIST_ENTRY SndQue; ///< Retxmission queue
|
|
||||||
LIST_ENTRY RcvQue; ///< Reassemble queue
|
|
||||||
UINT32 CtrlFlag; ///< Control flags, such as NO_NAGLE
|
|
||||||
INT32 Error; ///< Soft error status, such as TCP_CONNECT_RESET
|
|
||||||
|
|
||||||
//
|
|
||||||
// RFC793 and RFC1122 defined variables
|
|
||||||
//
|
|
||||||
UINT8 State; ///< TCP state, such as SYN_SENT, LISTEN
|
|
||||||
UINT8 DelayedAck; ///< Number of delayed ACKs
|
|
||||||
UINT16 HeadSum; ///< Checksum of the fixed parts of pesudo
|
|
||||||
///< header: Src IP, Dst IP, 0, Protocol,
|
|
||||||
///< not include the TCP length.
|
|
||||||
|
|
||||||
TCP_SEQNO Iss; ///< Initial Sending Sequence
|
|
||||||
TCP_SEQNO SndUna; ///< First unacknowledged data
|
|
||||||
TCP_SEQNO SndNxt; ///< Next data sequence to send.
|
|
||||||
TCP_SEQNO SndPsh; ///< Send PUSH point
|
|
||||||
TCP_SEQNO SndUp; ///< Send urgent point
|
|
||||||
UINT32 SndWnd; ///< Window advertised by the remote peer
|
|
||||||
UINT32 SndWndMax; ///< Max send window advertised by the peer
|
|
||||||
TCP_SEQNO SndWl1; ///< Seq number used for last window update
|
|
||||||
TCP_SEQNO SndWl2; ///< Ack no of last window update
|
|
||||||
UINT16 SndMss; ///< Max send segment size
|
|
||||||
TCP_SEQNO RcvNxt; ///< Next sequence no to receive
|
|
||||||
UINT32 RcvWnd; ///< Window advertised by the local peer
|
|
||||||
TCP_SEQNO RcvWl2; ///< The RcvNxt (or ACK) of last window update.
|
|
||||||
///< It is necessary because of delayed ACK
|
|
||||||
|
|
||||||
TCP_SEQNO RcvUp; ///< Urgent point;
|
|
||||||
TCP_SEQNO Irs; ///< Initial Receiving Sequence
|
|
||||||
UINT16 RcvMss; ///< Max receive segment size
|
|
||||||
UINT16 EnabledTimer; ///< Which timer is currently enabled
|
|
||||||
UINT32 Timer[TCP_TIMER_NUMBER]; ///< When the timer will expire
|
|
||||||
INT32 NextExpire; ///< Count down offset for the nearest timer
|
|
||||||
UINT32 Idle; ///< How long the connection is in idle
|
|
||||||
UINT32 ProbeTime; ///< The time out value for current window prober
|
|
||||||
BOOLEAN ProbeTimerOn;///< If TRUE, the probe time is on.
|
|
||||||
|
|
||||||
//
|
|
||||||
// RFC1323 defined variables, about window scale,
|
|
||||||
// timestamp and PAWS
|
|
||||||
//
|
|
||||||
UINT8 SndWndScale; ///< Wndscale received from the peer
|
|
||||||
UINT8 RcvWndScale; ///< Wndscale used to scale local buffer
|
|
||||||
UINT32 TsRecent; ///< TsRecent to echo to the remote peer
|
|
||||||
UINT32 TsRecentAge; ///< When this TsRecent is updated
|
|
||||||
|
|
||||||
//
|
|
||||||
// RFC2988 defined variables. about RTT measurement
|
|
||||||
//
|
|
||||||
TCP_SEQNO RttSeq; ///< The seq of measured segment now
|
|
||||||
UINT32 RttMeasure; ///< Currently measured RTT in heart beats
|
|
||||||
UINT32 SRtt; ///< Smoothed RTT, scaled by 8
|
|
||||||
UINT32 RttVar; ///< RTT variance, scaled by 8
|
|
||||||
UINT32 Rto; ///< Current RTO, not scaled
|
|
||||||
|
|
||||||
//
|
|
||||||
// RFC2581, and 3782 variables.
|
|
||||||
// Congestion control + NewReno fast recovery.
|
|
||||||
//
|
|
||||||
UINT32 CWnd; ///< Sender's congestion window
|
|
||||||
UINT32 Ssthresh; ///< Slow start threshold.
|
|
||||||
TCP_SEQNO Recover; ///< Recover point for NewReno
|
|
||||||
UINT16 DupAck; ///< Number of duplicate ACKs
|
|
||||||
UINT8 CongestState; ///< The current congestion state(RFC3782)
|
|
||||||
UINT8 LossTimes; ///< Number of retxmit timeouts in a row
|
|
||||||
TCP_SEQNO LossRecover; ///< Recover point for retxmit
|
|
||||||
|
|
||||||
//
|
|
||||||
// configuration parameters, for EFI_TCP4_PROTOCOL specification
|
|
||||||
//
|
|
||||||
UINT32 KeepAliveIdle; ///< Idle time before sending first probe
|
|
||||||
UINT32 KeepAlivePeriod; ///< Interval for subsequent keep alive probe
|
|
||||||
UINT8 MaxKeepAlive; ///< Maxium keep alive probe times.
|
|
||||||
UINT8 KeepAliveProbes; ///< The number of keep alive probe.
|
|
||||||
UINT16 MaxRexmit; ///< The maxium number of retxmit before abort
|
|
||||||
UINT32 FinWait2Timeout; ///< The FIN_WAIT_2 time out
|
|
||||||
UINT32 TimeWaitTimeout; ///< The TIME_WAIT time out
|
|
||||||
UINT32 ConnectTimeout; ///< The connect establishment time out
|
|
||||||
|
|
||||||
//
|
|
||||||
// RFC7323
|
|
||||||
// Addressing Window Retraction for TCP Window Scale Option.
|
|
||||||
//
|
|
||||||
TCP_SEQNO RetxmitSeqMax; ///< Max Seq number in previous retransmission.
|
|
||||||
|
|
||||||
//
|
|
||||||
// configuration for tcp provided by user
|
|
||||||
//
|
|
||||||
BOOLEAN UseDefaultAddr;
|
|
||||||
UINT8 Tos;
|
|
||||||
UINT8 Ttl;
|
|
||||||
EFI_IPv4_ADDRESS SubnetMask;
|
|
||||||
|
|
||||||
IP_IO_IP_INFO *IpInfo; ///<pointer reference to Ip used to send pkt
|
|
||||||
};
|
|
||||||
|
|
||||||
extern LIST_ENTRY mTcpRunQue;
|
|
||||||
extern LIST_ENTRY mTcpListenQue;
|
|
||||||
extern TCP_SEQNO mTcpGlobalIss;
|
|
||||||
extern UINT32 mTcpTick;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// TCP_CONNECTED: both ends have synchronized their ISN.
|
|
||||||
///
|
|
||||||
#define TCP_CONNECTED(state) ((state) > TCP_SYN_RCVD)
|
|
||||||
|
|
||||||
#define TCP_FIN_RCVD(State) \
|
|
||||||
(((State) == TCP_CLOSE_WAIT) || \
|
|
||||||
((State) == TCP_LAST_ACK) || \
|
|
||||||
((State) == TCP_CLOSING) || \
|
|
||||||
((State) == TCP_TIME_WAIT))
|
|
||||||
|
|
||||||
#define TCP_LOCAL_CLOSED(State) \
|
|
||||||
(((State) == TCP_FIN_WAIT_1) || \
|
|
||||||
((State) == TCP_FIN_WAIT_2) || \
|
|
||||||
((State) == TCP_CLOSING) || \
|
|
||||||
((State) == TCP_TIME_WAIT) || \
|
|
||||||
((State) == TCP_LAST_ACK))
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the TCP_SEG point from a net buffer's ProtoData
|
|
||||||
//
|
|
||||||
#define TCPSEG_NETBUF(NBuf) ((TCP_SEG *) ((NBuf)->ProtoData))
|
|
||||||
|
|
||||||
//
|
|
||||||
// macros to compare sequence no
|
|
||||||
//
|
|
||||||
#define TCP_SEQ_LT(SeqA, SeqB) ((INT32) ((SeqA) - (SeqB)) < 0)
|
|
||||||
#define TCP_SEQ_LEQ(SeqA, SeqB) ((INT32) ((SeqA) - (SeqB)) <= 0)
|
|
||||||
#define TCP_SEQ_GT(SeqA, SeqB) ((INT32) ((SeqB) - (SeqA)) < 0)
|
|
||||||
#define TCP_SEQ_GEQ(SeqA, SeqB) ((INT32) ((SeqB) - (SeqA)) <= 0)
|
|
||||||
|
|
||||||
//
|
|
||||||
// TCP_SEQ_BETWEEN return whether b <= m <= e
|
|
||||||
//
|
|
||||||
#define TCP_SEQ_BETWEEN(b, m, e) ((e) - (b) >= (m) - (b))
|
|
||||||
|
|
||||||
//
|
|
||||||
// TCP_SUB_SEQ returns Seq1 - Seq2. Make sure Seq1 >= Seq2
|
|
||||||
//
|
|
||||||
#define TCP_SUB_SEQ(Seq1, Seq2) ((UINT32) ((Seq1) - (Seq2)))
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check whether Flag is on
|
|
||||||
//
|
|
||||||
#define TCP_FLG_ON(Value, Flag) ((BOOLEAN) (((Value) & (Flag)) != 0))
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set and Clear operation on a Flag
|
|
||||||
//
|
|
||||||
#define TCP_SET_FLG(Value, Flag) ((Value) |= (Flag))
|
|
||||||
#define TCP_CLEAR_FLG(Value, Flag) ((Value) &= ~(Flag))
|
|
||||||
|
|
||||||
//
|
|
||||||
// Test whether two peers are equal
|
|
||||||
//
|
|
||||||
#define TCP_PEER_EQUAL(Pa, Pb) \
|
|
||||||
(((Pa)->Ip == (Pb)->Ip) && ((Pa)->Port == (Pb)->Port))
|
|
||||||
|
|
||||||
//
|
|
||||||
// Test whether Pa matches Pb, or Pa is more specific
|
|
||||||
// than pb. Zero means wildcard.
|
|
||||||
//
|
|
||||||
#define TCP_PEER_MATCH(Pa, Pb) \
|
|
||||||
((((Pb)->Ip == 0) || ((Pb)->Ip == (Pa)->Ip)) && \
|
|
||||||
(((Pb)->Port == 0) || ((Pb)->Port == (Pa)->Port)))
|
|
||||||
|
|
||||||
#define TCP_TIMER_ON(Flag, Timer) ((Flag) & (1 << (Timer)))
|
|
||||||
#define TCP_SET_TIMER(Flag, Timer) ((Flag) = (UINT16) ((Flag) | (1 << (Timer))))
|
|
||||||
#define TCP_CLEAR_TIMER(Flag, Timer) ((Flag) = (UINT16) ((Flag) & (~(1 << (Timer)))))
|
|
||||||
|
|
||||||
#define TCP_TIME_LT(Ta, Tb) ((INT32) ((Ta) - (Tb)) < 0)
|
|
||||||
#define TCP_TIME_LEQ(Ta, Tb) ((INT32) ((Ta) - (Tb)) <= 0)
|
|
||||||
#define TCP_SUB_TIME(Ta, Tb) ((UINT32) ((Ta) - (Tb)))
|
|
||||||
|
|
||||||
#define TCP_MAX_WIN 0xFFFFU
|
|
||||||
|
|
||||||
typedef
|
|
||||||
VOID
|
|
||||||
(*TCP_TIMER_HANDLER) (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,584 +0,0 @@
|
|||||||
/** @file
|
|
||||||
TCP timer related functions.
|
|
||||||
|
|
||||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php<BR>
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "Tcp4Main.h"
|
|
||||||
|
|
||||||
UINT32 mTcpTick = 1000;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Connect timeout handler.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpConnectTimeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Timeout handler for TCP retransmission timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpRexmitTimeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Timeout handler for window probe timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpProbeTimeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Timeout handler for keepalive timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpKeepaliveTimeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Timeout handler for FIN_WAIT_2 timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpFinwait2Timeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Timeout handler for 2MSL timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
Tcp2MSLTimeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
);
|
|
||||||
|
|
||||||
TCP_TIMER_HANDLER mTcpTimerHandler[TCP_TIMER_NUMBER] = {
|
|
||||||
TcpConnectTimeout,
|
|
||||||
TcpRexmitTimeout,
|
|
||||||
TcpProbeTimeout,
|
|
||||||
TcpKeepaliveTimeout,
|
|
||||||
TcpFinwait2Timeout,
|
|
||||||
Tcp2MSLTimeout,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
Close the TCP connection.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpClose (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
NetbufFreeList (&Tcb->SndQue);
|
|
||||||
NetbufFreeList (&Tcb->RcvQue);
|
|
||||||
|
|
||||||
TcpSetState (Tcb, TCP_CLOSED);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Connect timeout handler.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpConnectTimeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (!TCP_CONNECTED (Tcb->State)) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "TcpConnectTimeout: connection closed "
|
|
||||||
"because conenction timer timeout for TCB %p\n", Tcb));
|
|
||||||
|
|
||||||
if (EFI_ABORTED == Tcb->Sk->SockError) {
|
|
||||||
SOCK_ERROR (Tcb->Sk, EFI_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TCP_SYN_RCVD == Tcb->State) {
|
|
||||||
DEBUG ((EFI_D_WARN, "TcpConnectTimeout: send reset because "
|
|
||||||
"connection timer timeout for TCB %p\n", Tcb));
|
|
||||||
|
|
||||||
TcpResetConnection (Tcb);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpClose (Tcb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Timeout handler for TCP retransmission timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpRexmitTimeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 FlightSize;
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_WARN, "TcpRexmitTimeout: transmission "
|
|
||||||
"timeout for TCB %p\n", Tcb));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set the congestion window. FlightSize is the
|
|
||||||
// amount of data that has been sent but not
|
|
||||||
// yet ACKed.
|
|
||||||
//
|
|
||||||
FlightSize = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna);
|
|
||||||
Tcb->Ssthresh = MAX ((UINT32) (2 * Tcb->SndMss), FlightSize / 2);
|
|
||||||
|
|
||||||
Tcb->CWnd = Tcb->SndMss;
|
|
||||||
Tcb->LossRecover = Tcb->SndNxt;
|
|
||||||
|
|
||||||
Tcb->LossTimes++;
|
|
||||||
if ((Tcb->LossTimes > Tcb->MaxRexmit) &&
|
|
||||||
!TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_CONNECT)) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_ERROR, "TcpRexmitTimeout: connection closed "
|
|
||||||
"because too many timeouts for TCB %p\n", Tcb));
|
|
||||||
|
|
||||||
if (EFI_ABORTED == Tcb->Sk->SockError) {
|
|
||||||
SOCK_ERROR (Tcb->Sk, EFI_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpClose (Tcb);
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpBackoffRto (Tcb);
|
|
||||||
TcpRetransmit (Tcb, Tcb->SndUna);
|
|
||||||
TcpSetTimer (Tcb, TCP_TIMER_REXMIT, Tcb->Rto);
|
|
||||||
|
|
||||||
Tcb->CongestState = TCP_CONGEST_LOSS;
|
|
||||||
TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_RTT_ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Timeout handler for window probe timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpProbeTimeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// This is the timer for sender's SWSA. RFC1122 requires
|
|
||||||
// a timer set for sender's SWSA, and suggest combine it
|
|
||||||
// with window probe timer. If data is sent, don't set
|
|
||||||
// the probe timer, since retransmit timer is on.
|
|
||||||
//
|
|
||||||
if ((TcpDataToSend (Tcb, 1) != 0) && (TcpToSendData (Tcb, 1) > 0)) {
|
|
||||||
|
|
||||||
ASSERT (TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_REXMIT) != 0);
|
|
||||||
Tcb->ProbeTimerOn = FALSE;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpSendZeroProbe (Tcb);
|
|
||||||
TcpSetProbeTimer (Tcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Timeout handler for keepalive timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpKeepaliveTimeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Tcb->KeepAliveProbes++;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Too many Keep-alive probes, drop the connection
|
|
||||||
//
|
|
||||||
if (Tcb->KeepAliveProbes > Tcb->MaxKeepAlive) {
|
|
||||||
|
|
||||||
if (EFI_ABORTED == Tcb->Sk->SockError) {
|
|
||||||
SOCK_ERROR (Tcb->Sk, EFI_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpClose (Tcb);
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpSendZeroProbe (Tcb);
|
|
||||||
TcpSetKeepaliveTimer (Tcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Timeout handler for FIN_WAIT_2 timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpFinwait2Timeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DEBUG ((EFI_D_WARN, "TcpFinwait2Timeout: connection closed "
|
|
||||||
"because FIN_WAIT2 timer timeouts for TCB %p\n", Tcb));
|
|
||||||
|
|
||||||
TcpClose (Tcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Timeout handler for 2MSL timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
Tcp2MSLTimeout (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DEBUG ((EFI_D_WARN, "Tcp2MSLTimeout: connection closed "
|
|
||||||
"because TIME_WAIT timer timeouts for TCB %p\n", Tcb));
|
|
||||||
|
|
||||||
TcpClose (Tcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Update the timer status and the next expire time according to the timers
|
|
||||||
to expire in a specific future time slot.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpUpdateTimer (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT16 Index;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Don't use a too large value to init NextExpire
|
|
||||||
// since mTcpTick wraps around as sequence no does.
|
|
||||||
//
|
|
||||||
Tcb->NextExpire = 65535;
|
|
||||||
TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_TIMER_ON);
|
|
||||||
|
|
||||||
for (Index = 0; Index < TCP_TIMER_NUMBER; Index++) {
|
|
||||||
|
|
||||||
if (TCP_TIMER_ON (Tcb->EnabledTimer, Index) &&
|
|
||||||
TCP_TIME_LT (Tcb->Timer[Index], mTcpTick + Tcb->NextExpire)) {
|
|
||||||
|
|
||||||
Tcb->NextExpire = TCP_SUB_TIME (Tcb->Timer[Index], mTcpTick);
|
|
||||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_TIMER_ON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Enable a TCP timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Timer The index of the timer to be enabled.
|
|
||||||
@param TimeOut The timeout value of this timer.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpSetTimer (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN UINT16 Timer,
|
|
||||||
IN UINT32 TimeOut
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP_SET_TIMER (Tcb->EnabledTimer, Timer);
|
|
||||||
Tcb->Timer[Timer] = mTcpTick + TimeOut;
|
|
||||||
|
|
||||||
TcpUpdateTimer (Tcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Clear one TCP timer.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
@param Timer The index of the timer to be cleared.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpClearTimer (
|
|
||||||
IN OUT TCP_CB *Tcb,
|
|
||||||
IN UINT16 Timer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TCP_CLEAR_TIMER (Tcb->EnabledTimer, Timer);
|
|
||||||
TcpUpdateTimer (Tcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Clear all TCP timers.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpClearAllTimer (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Tcb->EnabledTimer = 0;
|
|
||||||
TcpUpdateTimer (Tcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Enable the window prober timer and set the timeout value.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpSetProbeTimer (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (!Tcb->ProbeTimerOn) {
|
|
||||||
Tcb->ProbeTime = Tcb->Rto;
|
|
||||||
Tcb->ProbeTimerOn = TRUE;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Tcb->ProbeTime <<= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Tcb->ProbeTime < TCP_RTO_MIN) {
|
|
||||||
|
|
||||||
Tcb->ProbeTime = TCP_RTO_MIN;
|
|
||||||
} else if (Tcb->ProbeTime > TCP_RTO_MAX) {
|
|
||||||
|
|
||||||
Tcb->ProbeTime = TCP_RTO_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpSetTimer (Tcb, TCP_TIMER_PROBE, Tcb->ProbeTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Enable the keepalive timer and set the timeout value.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpSetKeepaliveTimer (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE)) {
|
|
||||||
return ;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set the timer to KeepAliveIdle if either
|
|
||||||
// 1. the keepalive timer is off
|
|
||||||
// 2. The keepalive timer is on, but the idle
|
|
||||||
// is less than KeepAliveIdle, that means the
|
|
||||||
// connection is alive since our last probe.
|
|
||||||
//
|
|
||||||
if (!TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_KEEPALIVE) ||
|
|
||||||
(Tcb->Idle < Tcb->KeepAliveIdle)) {
|
|
||||||
|
|
||||||
TcpSetTimer (Tcb, TCP_TIMER_KEEPALIVE, Tcb->KeepAliveIdle);
|
|
||||||
Tcb->KeepAliveProbes = 0;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
TcpSetTimer (Tcb, TCP_TIMER_KEEPALIVE, Tcb->KeepAlivePeriod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Backoff the RTO.
|
|
||||||
|
|
||||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TcpBackoffRto (
|
|
||||||
IN OUT TCP_CB *Tcb
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Fold the RTT estimate if too many times, the estimate
|
|
||||||
// may be wrong, fold it. So the next time a valid
|
|
||||||
// measurement is sampled, we can start fresh.
|
|
||||||
//
|
|
||||||
if ((Tcb->LossTimes >= TCP_FOLD_RTT) && (Tcb->SRtt != 0)) {
|
|
||||||
Tcb->RttVar += Tcb->SRtt >> 2;
|
|
||||||
Tcb->SRtt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tcb->Rto <<= 1;
|
|
||||||
|
|
||||||
if (Tcb->Rto < TCP_RTO_MIN) {
|
|
||||||
|
|
||||||
Tcb->Rto = TCP_RTO_MIN;
|
|
||||||
} else if (Tcb->Rto > TCP_RTO_MAX) {
|
|
||||||
|
|
||||||
Tcb->Rto = TCP_RTO_MAX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Heart beat timer handler.
|
|
||||||
|
|
||||||
@param Context Context of the timer event, ignored.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
TcpTickingDpc (
|
|
||||||
IN VOID *Context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
LIST_ENTRY *Entry;
|
|
||||||
LIST_ENTRY *Next;
|
|
||||||
TCP_CB *Tcb;
|
|
||||||
INT16 Index;
|
|
||||||
|
|
||||||
mTcpTick++;
|
|
||||||
mTcpGlobalIss += 100;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Don't use LIST_FOR_EACH, which isn't delete safe.
|
|
||||||
//
|
|
||||||
for (Entry = mTcpRunQue.ForwardLink; Entry != &mTcpRunQue; Entry = Next) {
|
|
||||||
|
|
||||||
Next = Entry->ForwardLink;
|
|
||||||
|
|
||||||
Tcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
|
|
||||||
|
|
||||||
if (Tcb->State == TCP_CLOSED) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// The connection is doing RTT measurement.
|
|
||||||
//
|
|
||||||
if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RTT_ON)) {
|
|
||||||
Tcb->RttMeasure++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tcb->Idle++;
|
|
||||||
|
|
||||||
if (Tcb->DelayedAck != 0) {
|
|
||||||
TcpSendAck (Tcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// No timer is active or no timer expired
|
|
||||||
//
|
|
||||||
if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_TIMER_ON) ||
|
|
||||||
((--Tcb->NextExpire) > 0)) {
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Call the timeout handler for each expired timer.
|
|
||||||
//
|
|
||||||
for (Index = 0; Index < TCP_TIMER_NUMBER; Index++) {
|
|
||||||
|
|
||||||
if (TCP_TIMER_ON (Tcb->EnabledTimer, Index) &&
|
|
||||||
TCP_TIME_LEQ (Tcb->Timer[Index], mTcpTick)) {
|
|
||||||
//
|
|
||||||
// disable the timer before calling the handler
|
|
||||||
// in case the handler enables it again.
|
|
||||||
//
|
|
||||||
TCP_CLEAR_TIMER (Tcb->EnabledTimer, Index);
|
|
||||||
mTcpTimerHandler[Index](Tcb);
|
|
||||||
|
|
||||||
//
|
|
||||||
// The Tcb may have been deleted by the timer, or
|
|
||||||
// no other timer is set.
|
|
||||||
//
|
|
||||||
if ((Next->BackLink != Entry) ||
|
|
||||||
(Tcb->EnabledTimer == 0)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// If the Tcb still exist or some timer is set, update the timer
|
|
||||||
//
|
|
||||||
if (Index == TCP_TIMER_NUMBER) {
|
|
||||||
TcpUpdateTimer (Tcb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Heart beat timer handler, queues the DPC at TPL_CALLBACK.
|
|
||||||
|
|
||||||
@param Event Timer event signaled, ignored.
|
|
||||||
@param Context Context of the timer event, ignored.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
TcpTicking (
|
|
||||||
IN EFI_EVENT Event,
|
|
||||||
IN VOID *Context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
QueueDpc (TPL_CALLBACK, TcpTickingDpc, Context);
|
|
||||||
}
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user