Author: cmihail
Date: Sun Jul 10 00:38:29 2011
New Revision: 52594
URL:
http://svn.reactos.org/svn/reactos?rev=52594&view=rev
Log:
[IP/lwIP]
- Fix graceful closure hanging bug
Modified:
branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c
branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/drive…
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c [iso-8859-1] Sun
Jul 10 00:38:29 2011
@@ -90,11 +90,18 @@
Bucket->Status = Status;
Bucket->Information = 0;
- CompleteBucket(Connection, Bucket, TRUE);
- }
-
+ CompleteBucket(Connection, Bucket, FALSE);
+ }
+
+ /* Calling with Status == STATUS_SUCCESS means that we got a graceful closure
+ * so we don't want to kill everything else since send is still valid in this
state
+ */
if (Status == STATUS_SUCCESS)
- Status = STATUS_FILE_CLOSED;
+ {
+ DbgPrint("[IP, FlushAllQueues] Flushed recv only after graceful
closure\n");
+ DereferenceObject(Connection);
+ return;
+ }
while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest,
&Connection->Lock)))
{
@@ -106,7 +113,7 @@
DbgPrint("[IP, FlushAllQueues] Completing Listen request for Connection =
0x%x\n", Bucket->AssociatedEndpoint);
DereferenceObject(Bucket->AssociatedEndpoint);
- CompleteBucket(Connection, Bucket, TRUE);
+ CompleteBucket(Connection, Bucket, FALSE);
}
while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest,
&Connection->Lock)))
@@ -120,7 +127,7 @@
Bucket->Status = Status;
Bucket->Information = 0;
- CompleteBucket(Connection, Bucket, TRUE);
+ CompleteBucket(Connection, Bucket, FALSE);
}
while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest,
&Connection->Lock)))
@@ -132,7 +139,7 @@
DbgPrint("[IP, FlushAllQueues] Completing Connection request for Connection
= 0x%x\n", Bucket->AssociatedEndpoint);
- CompleteBucket(Connection, Bucket, TRUE);
+ CompleteBucket(Connection, Bucket, FALSE);
}
DereferenceObject(Connection);
@@ -145,8 +152,12 @@
{
PCONNECTION_ENDPOINT Connection = arg;
- /* We're already closed so we don't want to call lwip_close */
- Connection->SocketContext = NULL;
+ /* Only clear the pointer if the shutdown was caused by an error */
+ if (err != ERR_OK)
+ {
+ /* We're already closed by the error so we don't want to call lwip_close
*/
+ Connection->SocketContext = NULL;
+ }
DbgPrint("[IP, TCPFinEventHandler] Called for Connection( 0x%x )->
SocketContext = pcb (0x%x)\n", Connection, Connection->SocketContext);
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/drive…
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c [iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c [iso-8859-1] Sun Jul 10
00:38:29 2011
@@ -127,8 +127,11 @@
}
else if (err == ERR_OK)
{
+ /* Complete pending reads with 0 bytes to indicate a graceful closure,
+ * but note that send is still possible in this state so we don't close the
+ * whole socket here (by calling tcp_close()) as that would violate TCP specs
+ */
TCPFinEventHandler(arg, ERR_OK);
- tcp_close(pcb);
}
DbgPrint("[lwIP, InternalRecvEventHandler] Done ERR_OK 3\n");