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/ne... ============================================================================== --- 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/driver... ============================================================================== --- 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/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] 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: