Author: cgutman
Date: Fri Jul 8 16:34:49 2011
New Revision: 52572
URL:
http://svn.reactos.org/svn/reactos?rev=52572&view=rev
Log:
[IP]
- Complete waiting requests upon socket error
- Fixes connect() stall forever if the remote side is not listening
Modified:
trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c
trunk/reactos/lib/drivers/oskittcp/oskittcp/sleep.c
Modified: trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/t…
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] Fri Jul 8 16:34:49
2011
@@ -60,20 +60,31 @@
Connection, Connection->SocketContext));
/* Things that can happen when we try the initial connection */
- if( Connection->SignalState & (SEL_CONNECT | SEL_FIN) ) {
+ if( Connection->SignalState & (SEL_CONNECT | SEL_FIN | SEL_ERROR) ) {
while (!IsListEmpty(&Connection->ConnectRequest)) {
Entry = RemoveHeadList( &Connection->ConnectRequest );
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Bucket->Status = (Connection->SignalState & SEL_CONNECT) ?
STATUS_SUCCESS : STATUS_CANCELLED;
+ if (Connection->SignalState & SEL_ERROR)
+ {
+ Bucket->Status =
TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
+ }
+ else if (Connection->SignalState & SEL_FIN)
+ {
+ Bucket->Status = STATUS_CANCELLED;
+ }
+ else
+ {
+ Bucket->Status = STATUS_SUCCESS;
+ }
Bucket->Information = 0;
CompleteBucket(Connection, Bucket);
}
}
- if( Connection->SignalState & (SEL_ACCEPT | SEL_FIN) ) {
+ if( Connection->SignalState & (SEL_ACCEPT | SEL_FIN | SEL_ERROR) ) {
/* Handle readable on a listening socket --
* TODO: Implement filtering
*/
@@ -94,25 +105,28 @@
TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
- if (Connection->SignalState & SEL_ACCEPT)
+ if (Connection->SignalState & SEL_ERROR)
+ {
+ Status =
TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
+ }
+ else if (Connection->SignalState & SEL_FIN)
+ {
+ Status = STATUS_CANCELLED;
+ }
+ else
{
Status =
TCPServiceListeningSocket(Connection->AddressFile->Listener,
Bucket->AssociatedEndpoint,
(PTDI_REQUEST_KERNEL)&IrpSp->Parameters);
}
- else
- {
- /* We got here because of a SEL_FIN event */
- Status = STATUS_CANCELLED;
- }
TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
- if( Status == STATUS_PENDING && !(Connection->SignalState &
SEL_FIN) ) {
+ if( Status == STATUS_PENDING ) {
InsertHeadList( &Connection->ListenRequest,
&Bucket->Entry );
break;
} else {
- Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED :
Status;
+ Bucket->Status = Status;
Bucket->Information = 0;
DereferenceObject(Bucket->AssociatedEndpoint);
@@ -122,7 +136,7 @@
}
/* Things that happen after we're connected */
- if( Connection->SignalState & (SEL_READ | SEL_FIN) ) {
+ if( Connection->SignalState & (SEL_READ | SEL_FIN | SEL_ERROR) ) {
TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
IsListEmpty(&Connection->ReceiveRequest) ?
"empty" : "nonempty"));
@@ -153,7 +167,16 @@
Connection->SocketContext));
TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
- if (Connection->SignalState & SEL_READ)
+ if (Connection->SignalState & SEL_ERROR)
+ {
+ Status =
TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
+ }
+ else if (Connection->SignalState & SEL_FIN)
+ {
+ /* We got here because of a SEL_FIN event */
+ Status = STATUS_CANCELLED;
+ }
+ else
{
Status = TCPTranslateError(OskitTCPRecv(Connection->SocketContext,
RecvBuffer,
@@ -161,15 +184,10 @@
&Received,
0));
}
- else
- {
- /* We got here because of a SEL_FIN event */
- Status = STATUS_CANCELLED;
- }
TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
- if( Status == STATUS_PENDING && !(Connection->SignalState &
SEL_FIN) ) {
+ if( Status == STATUS_PENDING ) {
InsertHeadList( &Connection->ReceiveRequest,
&Bucket->Entry );
break;
} else {
@@ -177,14 +195,14 @@
("Completing Receive request: %x %x\n",
Bucket->Request, Status));
- Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED :
Status;
+ Bucket->Status = Status;
Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ?
Received : 0;
CompleteBucket(Connection, Bucket);
}
}
}
- if( Connection->SignalState & (SEL_WRITE | SEL_FIN) ) {
+ if( Connection->SignalState & (SEL_WRITE | SEL_FIN | SEL_ERROR) ) {
TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
IsListEmpty(&Connection->SendRequest) ?
"empty" : "nonempty"));
@@ -214,7 +232,16 @@
("Connection->SocketContext: %x\n",
Connection->SocketContext));
- if (Connection->SignalState & SEL_WRITE)
+ if (Connection->SignalState & SEL_ERROR)
+ {
+ Status =
TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
+ }
+ else if (Connection->SignalState & SEL_FIN)
+ {
+ /* We got here because of a SEL_FIN event */
+ Status = STATUS_CANCELLED;
+ }
+ else
{
Status = TCPTranslateError(OskitTCPSend(Connection->SocketContext,
SendBuffer,
@@ -222,15 +249,10 @@
&Sent,
0));
}
- else
- {
- /* We got here because of a SEL_FIN event */
- Status = STATUS_CANCELLED;
- }
TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
- if( Status == STATUS_PENDING && !(Connection->SignalState &
SEL_FIN) ) {
+ if( Status == STATUS_PENDING ) {
InsertHeadList( &Connection->SendRequest, &Bucket->Entry
);
break;
} else {
@@ -238,20 +260,29 @@
("Completing Send request: %x %x\n",
Bucket->Request, Status));
- Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED :
Status;
+ Bucket->Status = Status;
Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? Sent
: 0;
CompleteBucket(Connection, Bucket);
}
}
}
- if( Connection->SignalState & (SEL_WRITE | SEL_FIN) ) {
+ if( Connection->SignalState & (SEL_WRITE | SEL_FIN | SEL_ERROR) ) {
while (!IsListEmpty(&Connection->ShutdownRequest)) {
Entry = RemoveHeadList( &Connection->ShutdownRequest );
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
- if (!(Connection->SignalState & SEL_FIN))
+
+ if (Connection->SignalState & SEL_ERROR)
+ {
+ Status =
TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
+ }
+ else if (Connection->SignalState & SEL_FIN)
+ {
+ /* We were cancelled by a FIN */
+ Status = STATUS_CANCELLED;
+ }
+ else
{
/* See if we can satisfy this after the events */
if (IsListEmpty(&Connection->SendRequest))
@@ -265,12 +296,7 @@
Status = STATUS_PENDING;
}
}
- else
- {
- /* We were cancelled by a FIN */
- Status = STATUS_CANCELLED;
- }
-
+
if( Status == STATUS_PENDING ) {
InsertHeadList( &Connection->ShutdownRequest,
&Bucket->Entry );
break;
Modified: trunk/reactos/lib/drivers/oskittcp/oskittcp/sleep.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/oskittcp/oskit…
==============================================================================
--- trunk/reactos/lib/drivers/oskittcp/oskittcp/sleep.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/oskittcp/oskittcp/sleep.c [iso-8859-1] Fri Jul 8 16:34:49
2011
@@ -40,6 +40,10 @@
(so->so_state & SS_CANTSENDMORE)) {
OS_DbgPrint(OSK_MID_TRACE,("Socket writeable\n"));
flags |= SEL_WRITE;
+ }
+ if (so->so_error) {
+ OS_DbgPrint(OSK_MID_TRACE,("Socket error\n"));
+ flags |= SEL_ERROR;
}
if (!so->so_pcb) {
OS_DbgPrint(OSK_MID_TRACE,("Socket dying\n"));