[ros-diffs] [cgutman] 53095: [TCPIP] - Fail sends if the connection is shutdown in the send direction - Complete receives with 0 bytes if the connection is shutdown in the receive direction - Fixes hangs in ws...

cgutman at svn.reactos.org cgutman at svn.reactos.org
Sat Aug 6 08:45:47 UTC 2011


Author: cgutman
Date: Sat Aug  6 08:45:46 2011
New Revision: 53095

URL: http://svn.reactos.org/svn/reactos?rev=53095&view=rev
Log:
[TCPIP]
- Fail sends if the connection is shutdown in the send direction
- Complete receives with 0 bytes if the connection is shutdown in the receive direction
- Fixes hangs in ws2_32:sock and wininet:ftp

Modified:
    branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/titypes.h
    branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c
    branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c

Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/titypes.h
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/titypes.h?rev=53095&r1=53094&r2=53095&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/titypes.h [iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/titypes.h [iso-8859-1] Sat Aug  6 08:45:46 2011
@@ -269,13 +269,14 @@
     LIST_ENTRY ShutdownRequest;/* Queued shutdown requests */
 
     LIST_ENTRY PacketQueue;    /* Queued received packets waiting to be processed */
-
-    /* Signals */
-    UINT    SignalState;       /* Active signals from oskit */
     
     /* Disconnect Timer */
     KTIMER DisconnectTimer;
     KDPC DisconnectDpc;
+
+    /* Socket state */
+    BOOLEAN SendShutdown;
+    BOOLEAN ReceiveShutdown;
 
     struct _CONNECTION_ENDPOINT *Next; /* Next connection in address file list */
 } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;

Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c?rev=53095&r1=53094&r2=53095&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] Sat Aug  6 08:45:46 2011
@@ -486,11 +486,12 @@
 
     NdisQueryBuffer(Buffer, &DataBuffer, &DataLen);
     
+    LockObject(Connection, &OldIrql);
+
     Status = LibTCPGetDataFromConnectionQueue(Connection, DataBuffer, DataLen, &Received);
 
     if (Status == STATUS_PENDING)
     {
-        LockObject(Connection, &OldIrql);
     
         /* Freed in TCPSocketState */
         Bucket = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG);
@@ -508,8 +509,6 @@
         InsertTailList( &Connection->ReceiveRequest, &Bucket->Entry );
         TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Queued read irp\n"));
 
-        UnlockObject(Connection, OldIrql);
-
         TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Leaving. Status = STATUS_PENDING\n"));
 
         (*BytesReceived) = 0;
@@ -518,6 +517,8 @@
     {
         (*BytesReceived) = Received;
     }
+    
+    UnlockObject(Connection, OldIrql);
 
     return Status;
 }

Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c?rev=53095&r1=53094&r2=53095&view=diff
==============================================================================
--- 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] Sat Aug  6 08:45:46 2011
@@ -69,7 +69,7 @@
     PLIST_ENTRY Entry;
     PQUEUE_ENTRY qp = NULL;
 
-    Entry = ExInterlockedRemoveHeadList(&Connection->PacketQueue, &Connection->Lock);
+    Entry = RemoveHeadList(&Connection->PacketQueue);
     
     qp = CONTAINING_RECORD(Entry, QUEUE_ENTRY, ListEntry);
 
@@ -103,7 +103,12 @@
     }
     else
     {
-        Status = STATUS_PENDING;
+        if (Connection->ReceiveShutdown)
+            Status = STATUS_SUCCESS;
+        else
+            Status = STATUS_PENDING;
+
+        (*Received) = 0;
     }
 
     return Status;
@@ -150,6 +155,7 @@
 err_t
 InternalRecvEventHandler(void *arg, PTCP_PCB pcb, struct pbuf *p, const err_t err)
 {
+    PCONNECTION_ENDPOINT Connection = arg;
     u32_t len;
 
     /* Make sure the socket didn't get closed */
@@ -184,7 +190,7 @@
         }
         else
         {
-            LibTCPEnqueuePacket((PCONNECTION_ENDPOINT)arg, p);
+            LibTCPEnqueuePacket(Connection, p);
 
             tcp_recved(pcb, p->tot_len);
 
@@ -197,6 +203,7 @@
          * 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
          */
+        Connection->ReceiveShutdown = TRUE;
         TCPFinEventHandler(arg, ERR_OK);
     }
 
@@ -406,6 +413,12 @@
         goto done;
     }
     
+    if (msg->Input.Send.Connection->SendShutdown)
+    {
+        msg->Output.Send.Error = ERR_CLSD;
+        goto done;
+    }
+    
     if (tcp_sndbuf((PTCP_PCB)msg->Input.Send.Connection->SocketContext) < msg->Input.Send.DataLength)
     {
         msg->Output.Send.Error = ERR_INPROGRESS;
@@ -537,6 +550,14 @@
     if (msg->Output.Shutdown.Error)
     {
         msg->Input.Shutdown.Connection->SocketContext = pcb;
+    }
+    else
+    {
+        if (msg->Input.Shutdown.shut_rx)
+            msg->Input.Shutdown.Connection->ReceiveShutdown = TRUE;
+        
+        if (msg->Input.Shutdown.shut_tx)
+            msg->Input.Shutdown.Connection->SendShutdown = TRUE;
     }
     
 done:




More information about the Ros-diffs mailing list