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/driver... ============================================================================== --- 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/driver... ============================================================================== --- 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");