summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlpleahy <lpleahy@6f19259b-4bc3-4df7-8a09-765794883524>2011-09-26 22:43:18 +0000
committerlpleahy <lpleahy@6f19259b-4bc3-4df7-8a09-765794883524>2011-09-26 22:43:18 +0000
commit0b5da0afa6d233e48965f08e0dfef7bb3eaeef69 (patch)
tree0abfaf9b8babe98432a323ff8fa497eff0fd1f07
parenta994db796666660bd19fd070525532225dc0cc35 (diff)
downloadedk2-0b5da0afa6d233e48965f08e0dfef7bb3eaeef69.zip
edk2-0b5da0afa6d233e48965f08e0dfef7bb3eaeef69.tar.gz
edk2-0b5da0afa6d233e48965f08e0dfef7bb3eaeef69.tar.bz2
Fixes for Auber's test cases:
* accept 4.3.6 - accept.c, return -1 * accept 4.3.3 - accept.c, determine if socket supports listen * bind 4.4.2 - socket.c, socket.h, ip4.c, tcp4.c, udp4.c, test and reset the configuration to check for duplicate port addresses * bind 4.4.5 - socket.c, return EINVAL if socket already bound * connect 4.2.1 - tcp4.c, decode error status to set errno * getsockopt 4.5.3 - ip4.c, return ENOPROTOOPT * getsockopt 4.5.3 - socket.c, return EINVAL and ENOPROTOOPT * listen 4.6.5 - socket.c - return EOPNOTSUPP for invalid socket types * listen - socket.c - return EINVAL for socket not in listen state * listen - socket.c * socket 4.1.4 - socket.c, return EPROTONOSUPPORT * socket 4.1.5 - socket.c, return EPROTOTYPE Signed-off by: Lee Leahy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/branches/EADK@12444 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--StdLib/BsdSocketLib/accept.c14
-rw-r--r--StdLib/EfiSocketLib/Ip4.c10
-rw-r--r--StdLib/EfiSocketLib/Socket.c372
-rw-r--r--StdLib/EfiSocketLib/Socket.h33
-rw-r--r--StdLib/EfiSocketLib/Tcp4.c39
-rw-r--r--StdLib/EfiSocketLib/Udp4.c2
6 files changed, 336 insertions, 134 deletions
diff --git a/StdLib/BsdSocketLib/accept.c b/StdLib/BsdSocketLib/accept.c
index 1b93357..3d1e89f 100644
--- a/StdLib/BsdSocketLib/accept.c
+++ b/StdLib/BsdSocketLib/accept.c
@@ -75,12 +75,14 @@ AcceptWork (
//
// Convert the protocol to a socket
//
- NewSocketFd = BslSocketProtocolToFd ( pNewSocket, &errno );
- if ( -1 == NewSocketFd ) {
- //
- // Close the socket
- //
- BslSocketCloseWork ( pNewSocket, NULL );
+ if ( !EFI_ERROR ( Status )) {
+ NewSocketFd = BslSocketProtocolToFd ( pNewSocket, &errno );
+ if ( -1 == NewSocketFd ) {
+ //
+ // Close the socket
+ //
+ BslSocketCloseWork ( pNewSocket, NULL );
+ }
}
}
diff --git a/StdLib/EfiSocketLib/Ip4.c b/StdLib/EfiSocketLib/Ip4.c
index 9c431f6..bc76c75 100644
--- a/StdLib/EfiSocketLib/Ip4.c
+++ b/StdLib/EfiSocketLib/Ip4.c
@@ -165,8 +165,8 @@ EslIp4OptionGet (
//
// Protocol level not supported
//
- pSocket->errno = ENOTSUP;
- Status = EFI_UNSUPPORTED;
+ pSocket->errno = ENOPROTOOPT;
+ Status = EFI_INVALID_PARAMETER;
break;
case IPPROTO_IP:
@@ -175,8 +175,8 @@ EslIp4OptionGet (
//
// Option not supported
//
- pSocket->errno = ENOTSUP;
- Status = EFI_UNSUPPORTED;
+ pSocket->errno = ENOPROTOOPT;
+ Status = EFI_INVALID_PARAMETER;
break;
case IP_HDRINCL:
@@ -388,6 +388,7 @@ EslIp4PortAllocate (
//
// Save the cancel, receive and transmit addresses
//
+ pPort->pfnConfigure = (PFN_NET_CONFIGURE)pPort->pProtocol.IPv4->Configure;
pPort->pfnRxCancel = (PFN_NET_IO_START)pPort->pProtocol.IPv4->Cancel;
pPort->pfnRxStart = (PFN_NET_IO_START)pPort->pProtocol.IPv4->Receive;
pPort->pfnTxStart = (PFN_NET_IO_START)pPort->pProtocol.IPv4->Transmit;
@@ -1226,6 +1227,7 @@ EslIp4TxComplete (
**/
CONST ESL_PROTOCOL_API cEslIp4Api = {
IPPROTO_IP,
+ OFFSET_OF ( ESL_PORT, Context.Ip4.ModeData.ConfigData ),
OFFSET_OF ( ESL_LAYER, pIp4List ),
OFFSET_OF ( struct sockaddr_in, sin_zero ),
sizeof ( struct sockaddr_in ),
diff --git a/StdLib/EfiSocketLib/Socket.c b/StdLib/EfiSocketLib/Socket.c
index d2cafee..36d35a0 100644
--- a/StdLib/EfiSocketLib/Socket.c
+++ b/StdLib/EfiSocketLib/Socket.c
@@ -564,6 +564,7 @@ EslSocket (
{
CONST ESL_PROTOCOL_API * pApi;
CONST ESL_PROTOCOL_API ** ppApiArray;
+ CONST ESL_PROTOCOL_API ** ppApiArrayEnd;
int ApiArraySize;
ESL_SOCKET * pSocket;
EFI_STATUS Status;
@@ -635,8 +636,11 @@ EslSocket (
|| ( NULL == ppApiArray[ type ])) {
DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,
"ERROR - Invalid type value\r\n" ));
+ //
+ // The socket type is not supported
+ //
Status = EFI_INVALID_PARAMETER;
- errno = EINVAL;
+ errno = EPROTOTYPE;
break;
}
@@ -653,10 +657,48 @@ EslSocket (
//
if (( pApi->DefaultProtocol != protocol )
&& ( SOCK_RAW != type )) {
- DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,
- "ERROR - Invalid protocol value" ));
Status = EFI_INVALID_PARAMETER;
- errno = EINVAL;
+
+ //
+ // Assume that the driver supports this protocol
+ //
+ ppApiArray = &cEslAfInetApi[0];
+ ppApiArrayEnd = &ppApiArray [ cEslAfInetApiSize ];
+ while ( ppApiArrayEnd > ppApiArray ) {
+ pApi = *ppApiArray;
+ if ( protocol == pApi->DefaultProtocol ) {
+ break;
+ }
+ ppApiArray += 1;
+ }
+ if ( ppApiArrayEnd <= ppApiArray ) {
+ //
+ // Verify against the IPv6 table
+ //
+ ppApiArray = &cEslAfInet6Api[0];
+ ppApiArrayEnd = &ppApiArray [ cEslAfInet6ApiSize ];
+ while ( ppApiArrayEnd > ppApiArray ) {
+ pApi = *ppApiArray;
+ if ( protocol == pApi->DefaultProtocol ) {
+ break;
+ }
+ ppApiArray += 1;
+ }
+ }
+ if ( ppApiArrayEnd <= ppApiArray ) {
+ DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,
+ "ERROR - The protocol is not supported!" ));
+ errno = EPROTONOSUPPORT;
+ break;
+ }
+
+ //
+ // The driver does not support this protocol
+ //
+ DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,
+ "ERROR - The protocol does not support this socket type!" ));
+ errno = EPROTONOSUPPORT;
+ errno = EPROTOTYPE;
break;
}
@@ -775,8 +817,20 @@ EslSocketAccept (
if ( SOCKET_STATE_LISTENING != pSocket->State ) {
DEBUG (( DEBUG_ACCEPT,
"ERROR - Socket is not listening!\r\n" ));
- Status = EFI_NOT_STARTED;
- pSocket->errno = EOPNOTSUPP;
+ if ( NULL == pSocket->pApi->pfnAccept ) {
+ //
+ // Socket does not support listen
+ //
+ pSocket->errno = EOPNOTSUPP;
+ Status = EFI_UNSUPPORTED;
+ }
+ else {
+ //
+ // Socket supports listen, but not in listen state
+ //
+ pSocket->errno = EINVAL;
+ Status = EFI_NOT_STARTED;
+ }
}
else {
//
@@ -1090,91 +1144,113 @@ EslSocketBind (
Status = EFI_INVALID_PARAMETER;
pSocket->errno = EFAULT;
}
- else{
+
+ //
+ // Validate the local address length
+ //
+ else if (( SockAddrLength < pSocket->pApi->MinimumAddressLength )
+ || ( pSockAddr->sa_len < pSocket->pApi->MinimumAddressLength )) {
+ DEBUG (( DEBUG_BIND,
+ "ERROR - Invalid bind name length: %d, sa_len: %d\r\n",
+ SockAddrLength,
+ pSockAddr->sa_len ));
+ Status = EFI_INVALID_PARAMETER;
+ pSocket->errno = EINVAL;
+ }
+
+ //
+ // Validate the shutdown state
+ //
+ else if ( pSocket->bRxDisable || pSocket->bTxDisable ) {
+ DEBUG (( DEBUG_BIND,
+ "ERROR - Shutdown has been called on socket 0x%08x\r\n",
+ pSocket ));
+ pSocket->errno = EINVAL;
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Verify the socket state
+ //
+ else if ( SOCKET_STATE_NOT_CONFIGURED != pSocket->State ) {
+ DEBUG (( DEBUG_BIND,
+ "ERROR - The socket 0x%08x is already configured!\r\n",
+ pSocket ));
+ pSocket->errno = EINVAL;
+ Status = EFI_ALREADY_STARTED;
+ }
+ else {
//
- // Validate the local address length
+ // Synchronize with the socket layer
//
- if (( SockAddrLength < pSocket->pApi->MinimumAddressLength )
- || ( pSockAddr->sa_len < pSocket->pApi->MinimumAddressLength )) {
- DEBUG (( DEBUG_BIND,
- "ERROR - Invalid bind name length: %d, sa_len: %d\r\n",
- SockAddrLength,
- pSockAddr->sa_len ));
- Status = EFI_INVALID_PARAMETER;
- pSocket->errno = EINVAL;
- }
- else {
- //
- // Synchronize with the socket layer
- //
- RAISE_TPL ( TplPrevious, TPL_SOCKETS );
+ RAISE_TPL ( TplPrevious, TPL_SOCKETS );
+ //
+ // Walk the list of services
+ //
+ pBuffer = (UINT8 *)&mEslLayer;
+ pBuffer = &pBuffer[ pSocket->pApi->ServiceListOffset ];
+ ppServiceListHead = (ESL_SERVICE **)pBuffer;
+ pService = *ppServiceListHead;
+ while ( NULL != pService ) {
//
- // Walk the list of services
+ // Create the port
//
- pBuffer = (UINT8 *)&mEslLayer;
- pBuffer = &pBuffer[ pSocket->pApi->ServiceListOffset ];
- ppServiceListHead = (ESL_SERVICE **)pBuffer;
- pService = *ppServiceListHead;
- while ( NULL != pService ) {
- //
- // Create the port
- //
- pServiceBinding = pService->pServiceBinding;
- ChildHandle = NULL;
- Status = pServiceBinding->CreateChild ( pServiceBinding,
- &ChildHandle );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DEBUG_BIND | DEBUG_POOL,
- "0x%08x: %s port handle created\r\n",
- ChildHandle,
- pService->pSocketBinding->pName ));
-
- //
- // Open the port
- //
- Status = EslSocketPortAllocate ( pSocket,
- pService,
- ChildHandle,
- pSockAddr,
- DEBUG_BIND,
- &pPort );
- }
- else {
- DEBUG (( DEBUG_BIND | DEBUG_POOL,
- "ERROR - Failed to open %s port handle, Status: %r\r\n",
- pService->pSocketBinding->pName,
- Status ));
- }
-
+ pServiceBinding = pService->pServiceBinding;
+ ChildHandle = NULL;
+ Status = pServiceBinding->CreateChild ( pServiceBinding,
+ &ChildHandle );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_BIND | DEBUG_POOL,
+ "0x%08x: %s port handle created\r\n",
+ ChildHandle,
+ pService->pSocketBinding->pName ));
+
//
- // Set the next service
+ // Open the port
//
- pService = pService->pNext;
+ Status = EslSocketPortAllocate ( pSocket,
+ pService,
+ ChildHandle,
+ pSockAddr,
+ TRUE,
+ DEBUG_BIND,
+ &pPort );
}
-
- //
- // Verify that at least one network connection was found
- //
- if ( NULL == pSocket->pPortList ) {
- DEBUG (( DEBUG_BIND | DEBUG_POOL | DEBUG_INIT,
- "Socket address is not available!\r\n" ));
- pSocket->errno = EADDRNOTAVAIL;
- Status = EFI_INVALID_PARAMETER;
+ else {
+ DEBUG (( DEBUG_BIND | DEBUG_POOL,
+ "ERROR - Failed to open %s port handle, Status: %r\r\n",
+ pService->pSocketBinding->pName,
+ Status ));
}
//
- // Mark this socket as bound if successful
+ // Set the next service
//
- if ( !EFI_ERROR ( Status )) {
- pSocket->State = SOCKET_STATE_BOUND;
- }
+ pService = pService->pNext;
+ }
- //
- // Release the socket layer synchronization
- //
- RESTORE_TPL ( TplPrevious );
+ //
+ // Verify that at least one network connection was found
+ //
+ if ( NULL == pSocket->pPortList ) {
+ DEBUG (( DEBUG_BIND | DEBUG_POOL | DEBUG_INIT,
+ "Socket address is not available!\r\n" ));
+ pSocket->errno = EADDRNOTAVAIL;
+ Status = EFI_INVALID_PARAMETER;
}
+
+ //
+ // Mark this socket as bound if successful
+ //
+ if ( !EFI_ERROR ( Status )) {
+ pSocket->State = SOCKET_STATE_BOUND;
+ }
+
+ //
+ // Release the socket layer synchronization
+ //
+ RESTORE_TPL ( TplPrevious );
}
}
@@ -1196,6 +1272,66 @@ EslSocketBind (
/**
+ Test the bind configuration.
+
+ @param [in] pPort Address of the ::ESL_PORT structure.
+
+ @retval EFI_SUCCESS The connection was successfully established.
+ @retval Others The connection attempt failed.
+
+ **/
+EFI_STATUS
+EslSocketBindTest (
+ IN ESL_PORT * pPort
+ )
+{
+ UINT8 * pBuffer;
+ VOID * pConfigData;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Locate the configuration data
+ //
+ pBuffer = (UINT8 *)pPort;
+ pBuffer = &pBuffer [ pPort->pSocket->pApi->ConfigDataOffset ];
+ pConfigData = (VOID *)pBuffer;
+
+ //
+ // Attempt to use this configuration
+ //
+ Status = pPort->pfnConfigure ( pPort->pProtocol.v, pConfigData );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_WARN | DEBUG_BIND,
+ "WARNING - Port 0x%08x failed configuration, Status: %r\r\n",
+ pPort,
+ Status ));
+ pPort->pSocket->errno = EADDRINUSE;
+ }
+ else {
+ //
+ // Reset the port
+ //
+ Status = pPort->pfnConfigure ( pPort->pProtocol.v, NULL );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR | DEBUG_BIND,
+ "ERROR - Port 0x%08x failed configuration reset, Status: %r\r\n",
+ pPort,
+ Status ));
+ ASSERT ( EFI_SUCCESS == Status );
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
Determine if the socket is closed
This routine checks the state of the socket to determine if
@@ -2429,6 +2565,7 @@ EslSocketListen (
//
if ( !EFI_ERROR ( Status )) {
pSocket->State = SOCKET_STATE_LISTENING;
+ pSocket->bListenCalled = TRUE;
}
else {
//
@@ -2464,7 +2601,9 @@ EslSocketListen (
else {
DEBUG (( DEBUG_ERROR | DEBUG_LISTEN,
"ERROR - Bind operation must be performed first!\r\n" ));
- pSocket->errno = EDESTADDRREQ;
+ pSocket->errno = ( SOCKET_STATE_NOT_CONFIGURED == pSocket->State ) ? EDESTADDRREQ
+ : EINVAL;
+ Status = EFI_NO_MAPPING;
}
}
}
@@ -2559,9 +2698,9 @@ EslSocketOptionGet (
//
// Protocol level not supported
//
- DEBUG (( DEBUG_INFO | DEBUG_OPTION, "ERROR - Invalid option level\r\n" ));
- errno = ENOTSUP;
- Status = EFI_UNSUPPORTED;
+ DEBUG (( DEBUG_INFO | DEBUG_OPTION, "ERROR - Invalid protocol option\r\n" ));
+ errno = ENOPROTOOPT;
+ Status = EFI_INVALID_PARAMETER;
}
break;
@@ -2569,27 +2708,25 @@ EslSocketOptionGet (
switch ( OptionName ) {
default:
//
- // See if the protocol will handle the socket option
+ // Socket option not supported
//
- if ( NULL != pSocket->pApi->pfnOptionGet ) {
- Status = pSocket->pApi->pfnOptionGet ( pSocket,
- level,
- OptionName,
- &pOptionData,
- &LengthInBytes );
- errno = pSocket->errno;
- }
- else {
- //
- // Socket option not supported
- //
- DEBUG (( DEBUG_INFO | DEBUG_OPTION, "ERROR - Invalid socket option\r\n" ));
- errno = ENOTSUP;
- Status = EFI_UNSUPPORTED;
- }
+ DEBUG (( DEBUG_INFO | DEBUG_OPTION, "ERROR - Invalid socket option\r\n" ));
+ errno = EINVAL;
+ Status = EFI_INVALID_PARAMETER;
+ break;
+
+ case SO_ACCEPTCONN:
+ //
+ // Return the listen flag
+ //
+ pOptionData = (UINT8 *)&pSocket->bListenCalled;
+ LengthInBytes = sizeof ( pSocket->bListenCalled );
break;
case SO_OOBINLINE:
+ //
+ // Return the out-of-band inline flag
+ //
pOptionData = (UINT8 *)&pSocket->bOobInLine;
LengthInBytes = sizeof ( pSocket->bOobInLine );
break;
@@ -2721,7 +2858,9 @@ EslSocketOptionSet (
//
pSocket = NULL;
if (( NULL != pSocketProtocol )
- && ( NULL != pOptionValue )) {
+ && ( NULL != pOptionValue )
+ && ( !pSocket->bRxDisable )
+ && ( !pSocket->bTxDisable )) {
pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
LengthInBytes = 0;
pOptionData = NULL;
@@ -2742,8 +2881,8 @@ EslSocketOptionSet (
//
// Protocol level not supported
//
- errno = ENOTSUP;
- Status = EFI_UNSUPPORTED;
+ errno = ENOPROTOOPT;
+ Status = EFI_INVALID_PARAMETER;
}
break;
@@ -2751,23 +2890,10 @@ EslSocketOptionSet (
switch ( OptionName ) {
default:
//
- // See if the protocol will handle the socket option
+ // Option not supported
//
- if ( NULL != pSocket->pApi->pfnOptionSet ) {
- Status = pSocket->pApi->pfnOptionSet ( pSocket,
- level,
- OptionName,
- pOptionValue,
- OptionLength );
- errno = pSocket->errno;
- }
- else {
- //
- // Option not supported
- //
- errno = ENOTSUP;
- Status = EFI_UNSUPPORTED;
- }
+ errno = EINVAL;
+ Status = EFI_INVALID_PARAMETER;
break;
case SO_OOBINLINE:
@@ -3157,6 +3283,7 @@ EslSocketPoll (
for the port causes the network layer to assign a port
number from the dynamic range. Specifying a specific
port number causes the network layer to use that port.
+ @param [in] bBindTest TRUE if EslSocketBindTest should be called
@param [in] DebugFlags Flags for debug messages
@param [out] ppPort Buffer to receive new ::ESL_PORT structure address
@@ -3169,6 +3296,7 @@ EslSocketPortAllocate (
IN ESL_SERVICE * pService,
IN EFI_HANDLE ChildHandle,
IN CONST struct sockaddr * pSockAddr,
+ IN BOOLEAN bBindTest,
IN UINTN DebugFlags,
OUT ESL_PORT ** ppPort
)
@@ -3262,6 +3390,16 @@ EslSocketPortAllocate (
pSocket->pApi->pfnLocalAddrSet ( pPort, pSockAddr );
//
+ // Test the configuration
+ //
+ if ( bBindTest ) {
+ Status = EslSocketBindTest ( pPort );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
// Initialize the receive structures
//
pBuffer = (UINT8 *)&pPort[ 1 ];
diff --git a/StdLib/EfiSocketLib/Socket.h b/StdLib/EfiSocketLib/Socket.h
index d7bde5c..17eff10 100644
--- a/StdLib/EfiSocketLib/Socket.h
+++ b/StdLib/EfiSocketLib/Socket.h
@@ -270,6 +270,22 @@ typedef struct {
/**
+ Configure the network layer.
+
+ @param [in] pProtocol Protocol structure address
+ @param [in] pConfigData Address of the confiuration data
+
+ @return Returns EFI_SUCCESS if the operation is successfully
+ started.
+**/
+typedef
+EFI_STATUS
+(* PFN_NET_CONFIGURE) (
+ IN VOID * pProtocol,
+ IN VOID * pConfigData
+ );
+
+/**
Hand an I/O operation to the network layer.
@param [in] pProtocol Protocol structure address
@@ -315,11 +331,12 @@ typedef struct _ESL_PORT {
//
// Port management
//
- EFI_HANDLE Handle; ///< Network port handle
- PORT_STATE State; ///< State of the port
- UINTN DebugFlags; ///< Debug flags used to close the port
- BOOLEAN bCloseNow; ///< TRUE = Close the port immediately
- BOOLEAN bConfigured; ///< TRUE = Configure call made to network layer
+ EFI_HANDLE Handle; ///< Network port handle
+ PORT_STATE State; ///< State of the port
+ UINTN DebugFlags; ///< Debug flags used to close the port
+ BOOLEAN bCloseNow; ///< TRUE = Close the port immediately
+ BOOLEAN bConfigured; ///< TRUE = Configure call made to network layer
+ PFN_NET_CONFIGURE pfnConfigure; ///< Configure the network layer
//
// Transmit data management
@@ -382,7 +399,7 @@ EFI_STATUS
/**
Poll for completion of the connection attempt.
- @param [in] pSocket Address of the socket structure.
+ @param [in] pSocket Address of an ::ESL_SOCKET structure.
@retval EFI_SUCCESS The connection was successfully established.
@retval EFI_NOT_READY The connection is in progress, call this routine again.
@@ -805,6 +822,7 @@ VOID
**/
typedef struct {
int DefaultProtocol; ///< Default protocol
+ UINTN ConfigDataOffset; ///< Offset in ::ESL_PORT to the configuration data
UINTN ServiceListOffset; ///< Offset in ::ESL_LAYER for the list of services
socklen_t MinimumAddressLength; ///< Minimum address length in bytes
socklen_t AddressLength; ///< Address length in bytes
@@ -863,6 +881,7 @@ typedef struct _ESL_SOCKET {
//
// Socket options
//
+ BOOLEAN bListenCalled; ///< TRUE if listen was successfully called
BOOLEAN bOobSupported; ///< TRUE if out-of-band messages are supported
BOOLEAN bOobInLine; ///< TRUE if out-of-band messages are to be received inline with normal data
BOOLEAN bIncludeHeader; ///< TRUE if including the IP header
@@ -1188,6 +1207,7 @@ EslSocketPacketFree (
for the port causes the network layer to assign a port
number from the dynamic range. Specifying a specific
port number causes the network layer to use that port.
+ @param [in] bBindTest TRUE if EslSocketBindTest should be called
@param [in] DebugFlags Flags for debug messages
@param [out] ppPort Buffer to receive new ::ESL_PORT structure address
@@ -1200,6 +1220,7 @@ EslSocketPortAllocate (
IN ESL_SERVICE * pService,
IN EFI_HANDLE ChildHandle,
IN CONST struct sockaddr * pSockAddr,
+ IN BOOLEAN bBindTest,
IN UINTN DebugFlags,
OUT ESL_PORT ** ppPort
);
diff --git a/StdLib/EfiSocketLib/Tcp4.c b/StdLib/EfiSocketLib/Tcp4.c
index 3a7a4a2..6245f2b 100644
--- a/StdLib/EfiSocketLib/Tcp4.c
+++ b/StdLib/EfiSocketLib/Tcp4.c
@@ -532,11 +532,44 @@ EslTcp4ConnectStart (
//
// Connection error
//
- pSocket->errno = EINVAL;
DEBUG (( DEBUG_CONNECT,
"ERROR - Port 0x%08x not connected, Status: %r\r\n",
pPort,
Status ));
+ //
+ // Determine the errno value
+ //
+ switch ( Status ) {
+ default:
+ pSocket->errno = EIO;
+ break;
+
+ case EFI_OUT_OF_RESOURCES:
+ pSocket->errno = ENOBUFS;
+ break;
+
+ case EFI_TIMEOUT:
+ pSocket->errno = ETIMEDOUT;
+ break;
+
+ case EFI_NETWORK_UNREACHABLE:
+ pSocket->errno = ENETDOWN;
+ break;
+
+ case EFI_HOST_UNREACHABLE:
+ pSocket->errno = EHOSTUNREACH;
+ break;
+
+ case EFI_PORT_UNREACHABLE:
+ case EFI_PROTOCOL_UNREACHABLE:
+ case EFI_CONNECTION_REFUSED:
+ pSocket->errno = ECONNREFUSED;
+ break;
+
+ case EFI_CONNECTION_RESET:
+ pSocket->errno = ECONNRESET;
+ break;
+ }
}
}
}
@@ -851,11 +884,13 @@ EslTcp4ListenComplete (
//
// Allocate a port for this connection
+ // Note in this instance Configure may not be called with NULL!
//
Status = EslSocketPortAllocate ( pNewSocket,
pPort->pService,
TcpPortHandle,
(struct sockaddr *)&LocalAddress,
+ FALSE,
DEBUG_CONNECTION,
&pNewPort );
if ( !EFI_ERROR ( Status )) {
@@ -1231,6 +1266,7 @@ EslTcp4PortAllocate (
// Save the cancel, receive and transmit addresses
// pPort->pfnRxCancel = NULL; since the UEFI implementation returns EFI_UNSUPPORTED
//
+ pPort->pfnConfigure = (PFN_NET_CONFIGURE)pPort->pProtocol.TCPv4->Configure;
pPort->pfnRxStart = (PFN_NET_IO_START)pPort->pProtocol.TCPv4->Receive;
pPort->pfnTxStart = (PFN_NET_IO_START)pPort->pProtocol.TCPv4->Transmit;
@@ -2114,6 +2150,7 @@ EslTcp4TxOobComplete (
**/
CONST ESL_PROTOCOL_API cEslTcp4Api = {
IPPROTO_TCP,
+ OFFSET_OF ( ESL_PORT, Context.Tcp4.ConfigData ),
OFFSET_OF ( ESL_LAYER, pTcp4List ),
OFFSET_OF ( struct sockaddr_in, sin_zero ),
sizeof ( struct sockaddr_in ),
diff --git a/StdLib/EfiSocketLib/Udp4.c b/StdLib/EfiSocketLib/Udp4.c
index 38dc904..15e3bd0 100644
--- a/StdLib/EfiSocketLib/Udp4.c
+++ b/StdLib/EfiSocketLib/Udp4.c
@@ -208,6 +208,7 @@ EslUdp4PortAllocate (
//
// Save the cancel, receive and transmit addresses
//
+ pPort->pfnConfigure = (PFN_NET_CONFIGURE)pPort->pProtocol.UDPv4->Configure;
pPort->pfnRxCancel = (PFN_NET_IO_START)pPort->pProtocol.UDPv4->Cancel;
pPort->pfnRxStart = (PFN_NET_IO_START)pPort->pProtocol.UDPv4->Receive;
pPort->pfnTxStart = (PFN_NET_IO_START)pPort->pProtocol.UDPv4->Transmit;
@@ -968,6 +969,7 @@ EslUdp4TxComplete (
**/
CONST ESL_PROTOCOL_API cEslUdp4Api = {
IPPROTO_UDP,
+ OFFSET_OF ( ESL_PORT, Context.Udp4.ConfigData ),
OFFSET_OF ( ESL_LAYER, pUdp4List ),
OFFSET_OF ( struct sockaddr_in, sin_zero ),
sizeof ( struct sockaddr_in ),