summaryrefslogtreecommitdiff
path: root/StdLib
diff options
context:
space:
mode:
authorlpleahy <lpleahy@6f19259b-4bc3-4df7-8a09-765794883524>2012-06-08 20:53:12 +0000
committerlpleahy <lpleahy@6f19259b-4bc3-4df7-8a09-765794883524>2012-06-08 20:53:12 +0000
commit44538ba5aa759c4039fc6c588d33a7fe03503c3f (patch)
treeafc8a5062d92383337914295fb7c8777f9bca3c6 /StdLib
parentf6aa14a902deba0a5aa0d260cec5edd2c9a9e9a3 (diff)
Fix port retry behavior during connect - All port error paths exit through ConnectComplete to try the next port. When the last port fails to connect, the port error status to errno translation gets done by ConnectPoll.
Testing: Using two network adapters, second one always connected to the network. 1. Eth0 not configured, not connected - short delay 2. Eth0 not configured, connected - short delay 3. Eth0 configured, not connected - short delay 4. Eth0 configured, connected to private network - long delay due to connection timeout, failover to Eth1 5. Eth1 configured, connected, no server - long delay due to connection timeout, returned timeout error. Signed-off-by: lpleahy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13436 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'StdLib')
-rw-r--r--StdLib/EfiSocketLib/Tcp4.c183
-rw-r--r--StdLib/EfiSocketLib/Tcp6.c297
2 files changed, 207 insertions, 273 deletions
diff --git a/StdLib/EfiSocketLib/Tcp4.c b/StdLib/EfiSocketLib/Tcp4.c
index 0643518f0..e7924fa42 100644
--- a/StdLib/EfiSocketLib/Tcp4.c
+++ b/StdLib/EfiSocketLib/Tcp4.c
@@ -241,15 +241,17 @@ EslTcp4ConnectComplete (
//
// The connection failed
//
- DEBUG (( DEBUG_CONNECT,
- "0x%08x: Port connection to %d.%d.%d.%d:%d failed, Status: %r\r\n",
- pPort,
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1],
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2],
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3],
- pTcp4->ConfigData.AccessPoint.RemotePort,
- Status ));
+ if ( pPort->bConfigured ) {
+ DEBUG (( DEBUG_CONNECT,
+ "0x%08x: Port connection to %d.%d.%d.%d:%d failed, Status: %r\r\n",
+ pPort,
+ pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],
+ pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1],
+ pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2],
+ pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3],
+ pTcp4->ConfigData.AccessPoint.RemotePort,
+ Status ));
+ }
//
// Close the current port
@@ -272,7 +274,6 @@ EslTcp4ConnectComplete (
//
Status = EslTcp4ConnectStart ( pSocket );
if ( EFI_NOT_READY != Status ) {
- pSocket->ConnectStatus = Status;
bRemoveFirstPort = TRUE;
}
}
@@ -374,24 +375,43 @@ EslTcp4ConnectPoll (
break;
case EFI_ABORTED:
- pSocket->errno = ECONNREFUSED;
+ pSocket->errno = ECONNABORTED;
+ break;
+
+ case EFI_ACCESS_DENIED:
+ pSocket->errno = EACCES;
+ break;
+
+ case EFI_CONNECTION_RESET:
+ pSocket->errno = ECONNRESET;
break;
case EFI_INVALID_PARAMETER:
- pSocket->errno = EINVAL;
+ pSocket->errno = EADDRNOTAVAIL;
break;
- case EFI_NO_MAPPING:
+ case EFI_HOST_UNREACHABLE:
case EFI_NO_RESPONSE:
pSocket->errno = EHOSTUNREACH;
break;
+ case EFI_NO_MAPPING:
+ pSocket->errno = EAFNOSUPPORT;
+ break;
+
case EFI_NO_MEDIA:
+ case EFI_NETWORK_UNREACHABLE:
pSocket->errno = ENETDOWN;
break;
case EFI_OUT_OF_RESOURCES:
- pSocket->errno = ENOMEM;
+ pSocket->errno = ENOBUFS;
+ break;
+
+ case EFI_PORT_UNREACHABLE:
+ case EFI_PROTOCOL_UNREACHABLE:
+ case EFI_CONNECTION_REFUSED:
+ pSocket->errno = ECONNREFUSED;
break;
case EFI_SUCCESS:
@@ -404,13 +424,17 @@ EslTcp4ConnectPoll (
break;
case EFI_UNSUPPORTED:
- pSocket->errno = ENOTSUP;
- break;
-
- case 0x80000069:
- pSocket->errno = ECONNRESET;
+ pSocket->errno = EOPNOTSUPP;
break;
}
+
+ //
+ // Display the translation
+ //
+ DEBUG (( DEBUG_CONNECT,
+ "ERROR - errno: %d, Status: %r\r\n",
+ pSocket->errno,
+ Status ));
}
//
@@ -476,32 +500,6 @@ EslTcp4ConnectStart (
DEBUG (( DEBUG_CONNECT,
"ERROR - Failed to configure the Tcp4 port, Status: %r\r\n",
Status ));
- switch ( Status ) {
- case EFI_ACCESS_DENIED:
- pSocket->errno = EACCES;
- break;
-
- default:
- case EFI_DEVICE_ERROR:
- pSocket->errno = EIO;
- break;
-
- case EFI_INVALID_PARAMETER:
- pSocket->errno = EADDRNOTAVAIL;
- break;
-
- case EFI_NO_MAPPING:
- pSocket->errno = EAFNOSUPPORT;
- break;
-
- case EFI_OUT_OF_RESOURCES:
- pSocket->errno = ENOBUFS;
- break;
-
- case EFI_UNSUPPORTED:
- pSocket->errno = EOPNOTSUPP;
- break;
- }
}
else {
DEBUG (( DEBUG_CONNECT,
@@ -524,18 +522,7 @@ EslTcp4ConnectStart (
//
// Port is not connected to the network
//
- pTcp4->ConnectToken.CompletionToken.Status = EFI_NO_MEDIA;
-
- //
- // Continue with the next port
- //
- gBS->CheckEvent ( pTcp4->ConnectToken.CompletionToken.Event );
- gBS->SignalEvent ( pTcp4->ConnectToken.CompletionToken.Event );
-
- //
- // Connection in progress
- //
- Status = EFI_SUCCESS;
+ Status = EFI_NO_MEDIA;
}
else {
//
@@ -545,22 +532,7 @@ EslTcp4ConnectStart (
&pTcp4->ConnectToken );
}
}
- if ( !EFI_ERROR ( Status )) {
- //
- // Connection in progress
- //
- pSocket->errno = EINPROGRESS;
- Status = EFI_NOT_READY;
- DEBUG (( DEBUG_CONNECT,
- "0x%08x: Port attempting connection to %d.%d.%d.%d:%d\r\n",
- pPort,
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1],
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2],
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3],
- pTcp4->ConfigData.AccessPoint.RemotePort ));
- }
- else {
+ if ( EFI_ERROR ( Status )) {
//
// Connection error
//
@@ -568,43 +540,38 @@ EslTcp4ConnectStart (
"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_NO_MEDIA:
- 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;
- }
}
}
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Connection in progress
+ //
+ pSocket->errno = EINPROGRESS;
+ DEBUG (( DEBUG_CONNECT,
+ "0x%08x: Port attempting connection to %d.%d.%d.%d:%d\r\n",
+ pPort,
+ pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],
+ pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1],
+ pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2],
+ pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3],
+ pTcp4->ConfigData.AccessPoint.RemotePort ));
+ }
+ else {
+ //
+ // Error return path is through EslTcp4ConnectComplete to
+ // enable retry on other ports
+ //
+ // Status to errno translation gets done in EslTcp4ConnectPoll
+ //
+ pTcp4->ConnectToken.CompletionToken.Status = Status;
+
+ //
+ // Continue with the next port
+ //
+ gBS->CheckEvent ( pTcp4->ConnectToken.CompletionToken.Event );
+ gBS->SignalEvent ( pTcp4->ConnectToken.CompletionToken.Event );
+ }
+ Status = EFI_NOT_READY;
}
else {
//
diff --git a/StdLib/EfiSocketLib/Tcp6.c b/StdLib/EfiSocketLib/Tcp6.c
index dd0f08648..688a256f6 100644
--- a/StdLib/EfiSocketLib/Tcp6.c
+++ b/StdLib/EfiSocketLib/Tcp6.c
@@ -247,27 +247,29 @@ EslTcp6ConnectComplete (
//
// The connection failed
//
- DEBUG (( DEBUG_CONNECT,
- "0x%08x: Port connection to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d failed, Status: %r\r\n",
- pPort,
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[0],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[1],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[2],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[3],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[4],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[5],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[6],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[7],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[8],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[9],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[10],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[11],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[12],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[13],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[14],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[15],
- pTcp6->ConfigData.AccessPoint.RemotePort,
- Status ));
+ if ( pPort->bConfigured ) {
+ DEBUG (( DEBUG_CONNECT,
+ "0x%08x: Port connection to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d failed, Status: %r\r\n",
+ pPort,
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[0],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[1],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[2],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[3],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[4],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[5],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[6],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[7],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[8],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[9],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[10],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[11],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[12],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[13],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[14],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[15],
+ pTcp6->ConfigData.AccessPoint.RemotePort,
+ Status ));
+ }
//
// Close the current port
@@ -290,7 +292,6 @@ EslTcp6ConnectComplete (
//
Status = EslTcp6ConnectStart ( pSocket );
if ( EFI_NOT_READY != Status ) {
- pSocket->ConnectStatus = Status;
bRemoveFirstPort = TRUE;
}
}
@@ -386,49 +387,72 @@ EslTcp6ConnectPoll (
//
Status = pSocket->ConnectStatus;
switch ( Status ) {
- default:
- case EFI_DEVICE_ERROR:
- pSocket->errno = EIO;
- break;
-
- case EFI_ABORTED:
- pSocket->errno = ECONNREFUSED;
- break;
-
- case EFI_INVALID_PARAMETER:
- pSocket->errno = EINVAL;
- break;
-
- case EFI_NO_MAPPING:
- case EFI_NO_RESPONSE:
- pSocket->errno = EHOSTUNREACH;
- break;
-
- case EFI_NO_MEDIA:
- pSocket->errno = ENETDOWN;
- break;
-
- case EFI_OUT_OF_RESOURCES:
- pSocket->errno = ENOMEM;
- break;
-
- case EFI_SUCCESS:
- pSocket->errno = 0;
- pSocket->bConfigured = TRUE;
- break;
-
- case EFI_TIMEOUT:
- pSocket->errno = ETIMEDOUT;
- break;
-
- case EFI_UNSUPPORTED:
- pSocket->errno = ENOTSUP;
- break;
-
- case 0x80000069:
- pSocket->errno = ECONNRESET;
- break;
+ default:
+ case EFI_DEVICE_ERROR:
+ pSocket->errno = EIO;
+ break;
+
+ case EFI_ABORTED:
+ pSocket->errno = ECONNABORTED;
+ break;
+
+ case EFI_ACCESS_DENIED:
+ pSocket->errno = EACCES;
+ break;
+
+ case EFI_CONNECTION_RESET:
+ pSocket->errno = ECONNRESET;
+ break;
+
+ case EFI_INVALID_PARAMETER:
+ pSocket->errno = EADDRNOTAVAIL;
+ break;
+
+ case EFI_HOST_UNREACHABLE:
+ case EFI_NO_RESPONSE:
+ pSocket->errno = EHOSTUNREACH;
+ break;
+
+ case EFI_NO_MAPPING:
+ pSocket->errno = EAFNOSUPPORT;
+ break;
+
+ case EFI_NO_MEDIA:
+ case EFI_NETWORK_UNREACHABLE:
+ pSocket->errno = ENETDOWN;
+ break;
+
+ case EFI_OUT_OF_RESOURCES:
+ pSocket->errno = ENOBUFS;
+ break;
+
+ case EFI_PORT_UNREACHABLE:
+ case EFI_PROTOCOL_UNREACHABLE:
+ case EFI_CONNECTION_REFUSED:
+ pSocket->errno = ECONNREFUSED;
+ break;
+
+ case EFI_SUCCESS:
+ pSocket->errno = 0;
+ pSocket->bConfigured = TRUE;
+ break;
+
+ case EFI_TIMEOUT:
+ pSocket->errno = ETIMEDOUT;
+ break;
+
+ case EFI_UNSUPPORTED:
+ pSocket->errno = EOPNOTSUPP;
+ break;
}
+
+ //
+ // Display the translation
+ //
+ DEBUG (( DEBUG_CONNECT,
+ "ERROR - errno: %d, Status: %r\r\n",
+ pSocket->errno,
+ Status ));
}
//
@@ -495,32 +519,6 @@ EslTcp6ConnectStart (
DEBUG (( DEBUG_CONNECT,
"ERROR - Failed to configure the Tcp6 port, Status: %r\r\n",
Status ));
- switch ( Status ) {
- case EFI_ACCESS_DENIED:
- pSocket->errno = EACCES;
- break;
-
- default:
- case EFI_DEVICE_ERROR:
- pSocket->errno = EIO;
- break;
-
- case EFI_INVALID_PARAMETER:
- pSocket->errno = EADDRNOTAVAIL;
- break;
-
- case EFI_NO_MAPPING:
- pSocket->errno = EAFNOSUPPORT;
- break;
-
- case EFI_OUT_OF_RESOURCES:
- pSocket->errno = ENOBUFS;
- break;
-
- case EFI_UNSUPPORTED:
- pSocket->errno = EOPNOTSUPP;
- break;
- }
}
else {
DEBUG (( DEBUG_CONNECT,
@@ -543,18 +541,7 @@ EslTcp6ConnectStart (
//
// Port is not connected to the network
//
- pTcp6->ConnectToken.CompletionToken.Status = EFI_NO_MEDIA;
-
- //
- // Continue with the next port
- //
- gBS->CheckEvent ( pTcp6->ConnectToken.CompletionToken.Event );
- gBS->SignalEvent ( pTcp6->ConnectToken.CompletionToken.Event );
-
- //
- // Connection in progress
- //
- Status = EFI_SUCCESS;
+ Status = EFI_NO_MEDIA;
}
else {
//
@@ -564,34 +551,7 @@ EslTcp6ConnectStart (
&pTcp6->ConnectToken );
}
}
- if ( !EFI_ERROR ( Status )) {
- //
- // Connection in progress
- //
- pSocket->errno = EINPROGRESS;
- Status = EFI_NOT_READY;
- DEBUG (( DEBUG_CONNECT,
- "0x%08x: Port attempting connection to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
- pPort,
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[0],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[1],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[2],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[3],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[4],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[5],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[6],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[7],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[8],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[9],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[10],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[11],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[12],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[13],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[14],
- pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[15],
- pTcp6->ConfigData.AccessPoint.RemotePort ));
- }
- else {
+ if ( EFI_ERROR ( Status )) {
//
// Connection error
//
@@ -599,43 +559,50 @@ EslTcp6ConnectStart (
"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_NO_MEDIA:
- 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;
- }
}
}
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Connection in progress
+ //
+ pSocket->errno = EINPROGRESS;
+ DEBUG (( DEBUG_CONNECT,
+ "0x%08x: Port attempting connection to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ pPort,
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[0],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[1],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[2],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[3],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[4],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[5],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[6],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[7],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[8],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[9],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[10],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[11],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[12],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[13],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[14],
+ pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[15],
+ pTcp6->ConfigData.AccessPoint.RemotePort ));
+ }
+ else {
+ //
+ // Error return path is through EslTcp6ConnectComplete to
+ // enable retry on other ports
+ //
+ // Status to errno translation gets done in EslTcp4ConnectPoll
+ //
+ pTcp6->ConnectToken.CompletionToken.Status = Status;
+
+ //
+ // Continue with the next port
+ //
+ gBS->CheckEvent ( pTcp6->ConnectToken.CompletionToken.Event );
+ gBS->SignalEvent ( pTcp6->ConnectToken.CompletionToken.Event );
+ }
+ Status = EFI_NOT_READY;
}
else {
//