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/n…
==============================================================================
--- 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/drive…
==============================================================================
--- 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/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] 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: