Author: cmihail
Date: Fri Aug 5 21:33:20 2011
New Revision: 53092
URL:
http://svn.reactos.org/svn/reactos?rev=53092&view=rev
Log:
[lwIP]
- fix build because of missing rosip.h in sys_arch.c
[TCPIP]
- implement disconnect timer
- minor code refactoring
Modified:
branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/tcp.h
branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c
branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c
branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c
branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/tcp.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/n…
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/tcp.h [iso-8859-1]
(original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/tcp.h [iso-8859-1] Fri
Aug 5 21:33:20 2011
@@ -141,6 +141,7 @@
NTSTATUS TCPDisconnect(
PCONNECTION_ENDPOINT Connection,
UINT Flags,
+ PLARGE_INTEGER Timeout,
PTDI_CONNECTION_INFORMATION ConnInfo,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PTCP_COMPLETION_ROUTINE Complete,
@@ -192,4 +193,21 @@
TCPUpdateInterfaceIPInformation(PIP_INTERFACE IF);
VOID
-FlushAllQueues(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status);
+FlushListenQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status);
+
+VOID
+FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status);
+
+VOID
+FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked);
+
+VOID
+FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked);
+
+VOID
+FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked);
+
+VOID
+FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status);
+
+VOID CompleteBucket(PCONNECTION_ENDPOINT Connection, PTDI_BUCKET Bucket, const BOOLEAN
Synchronous);
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/n…
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] Fri
Aug 5 21:33:20 2011
@@ -518,7 +518,7 @@
{
Status = TCPDisconnect(TranContext->Handle.ConnectionContext,
DisReq->RequestFlags,
- //DisReq->RequestSpecific, /* FIXME */
+ DisReq->RequestSpecific,
DisReq->RequestConnectionInformation,
DisReq->ReturnConnectionInformation,
DispDataRequestComplete,
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] Fri
Aug 5 21:33:20 2011
@@ -46,7 +46,6 @@
ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
}
-static
VOID
CompleteBucket(PCONNECTION_ENDPOINT Connection, PTDI_BUCKET Bucket, const BOOLEAN
Synchronous)
{
@@ -63,20 +62,138 @@
}
VOID
-FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
-{
- PTDI_BUCKET Bucket;
- PLIST_ENTRY Entry;
-
- ReferenceObject(Connection);
-
- while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest,
&Connection->Lock)))
+FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked)
+{
+ PTDI_BUCKET Bucket;
+ PLIST_ENTRY Entry;
+
+ ReferenceObject(Connection);
+
+ if (interlocked)
+ {
+ while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest,
&Connection->Lock)))
+ {
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+
+ TI_DbgPrint(DEBUG_TCP,
+ ("Completing Receive request: %x %x\n",
+ Bucket->Request, Status));
+
+ Bucket->Status = Status;
+ Bucket->Information = 0;
+
+ CompleteBucket(Connection, Bucket, FALSE);
+ }
+ }
+ else
+ {
+ while (!IsListEmpty(&Connection->ReceiveRequest))
+ {
+ Entry = RemoveHeadList(&Connection->ReceiveRequest);
+
+ Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+
+ Bucket->Information = 0;
+ Bucket->Status = Status;
+
+ CompleteBucket(Connection, Bucket, FALSE);
+ }
+ }
+
+ DereferenceObject(Connection);
+}
+
+VOID
+FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked)
+{
+ PTDI_BUCKET Bucket;
+ PLIST_ENTRY Entry;
+
+ ReferenceObject(Connection);
+
+ if (interlocked)
+ {
+ while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest,
&Connection->Lock)))
+ {
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+
+ TI_DbgPrint(DEBUG_TCP,
+ ("Completing Send request: %x %x\n",
+ Bucket->Request, Status));
+
+ Bucket->Status = Status;
+ Bucket->Information = 0;
+
+ CompleteBucket(Connection, Bucket, FALSE);
+ }
+ }
+ else
+ {
+ while (!IsListEmpty(&Connection->SendRequest))
+ {
+ Entry = RemoveHeadList(&Connection->SendRequest);
+
+ Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+
+ Bucket->Information = 0;
+ Bucket->Status = Status;
+
+ CompleteBucket(Connection, Bucket, FALSE);
+ }
+ }
+
+ DereferenceObject(Connection);
+}
+
+VOID
+FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked)
+{
+ PTDI_BUCKET Bucket;
+ PLIST_ENTRY Entry;
+
+ ReferenceObject(Connection);
+
+ if (interlocked)
+ {
+ while ((Entry = ExInterlockedRemoveHeadList(&Connection->ShutdownRequest,
&Connection->Lock)))
+ {
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+
+ Bucket->Status = Status;
+ Bucket->Information = 0;
+
+ CompleteBucket(Connection, Bucket, FALSE);
+ }
+ }
+ else
+ {
+ while (!IsListEmpty(&Connection->ShutdownRequest))
+ {
+ Entry = RemoveHeadList(&Connection->ShutdownRequest);
+
+ Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+
+ Bucket->Information = 0;
+ Bucket->Status = Status;
+
+ CompleteBucket(Connection, Bucket, FALSE);
+ }
+ }
+
+ DereferenceObject(Connection);
+}
+
+VOID
+FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
+{
+ PTDI_BUCKET Bucket;
+ PLIST_ENTRY Entry;
+
+ ReferenceObject(Connection);
+
+ while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest,
&Connection->Lock)))
{
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
- TI_DbgPrint(DEBUG_TCP,
- ("Completing Receive request: %x %x\n",
- Bucket->Request, Status));
Bucket->Status = Status;
Bucket->Information = 0;
@@ -88,26 +205,37 @@
}
VOID
-FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
-{
- PTDI_BUCKET Bucket;
- PLIST_ENTRY Entry;
-
- ReferenceObject(Connection);
-
- while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest,
&Connection->Lock)))
+FlushListenQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
+{
+ PTDI_BUCKET Bucket;
+ PLIST_ENTRY Entry;
+
+ ReferenceObject(Connection);
+
+ while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest,
&Connection->Lock)))
{
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
- TI_DbgPrint(DEBUG_TCP,
- ("Completing Receive request: %x %x\n",
- Bucket->Request, Status));
Bucket->Status = Status;
Bucket->Information = 0;
+ DereferenceObject(Bucket->AssociatedEndpoint);
CompleteBucket(Connection, Bucket, FALSE);
}
+
+ DereferenceObject(Connection);
+}
+
+VOID
+FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
+{
+ PTDI_BUCKET Bucket;
+ PLIST_ENTRY Entry;
+
+ ReferenceObject(Connection);
+
+ // flush receive queue
+ FlushReceiveQueue(Connection, Status, TRUE);
/* We completed the reads successfully but we need to return failure now */
if (Status == STATUS_SUCCESS)
@@ -115,40 +243,17 @@
Status = STATUS_FILE_CLOSED;
}
- while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest,
&Connection->Lock)))
- {
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
- Bucket->Status = Status;
- Bucket->Information = 0;
-
- DereferenceObject(Bucket->AssociatedEndpoint);
- CompleteBucket(Connection, Bucket, FALSE);
- }
-
- while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest,
&Connection->Lock)))
- {
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
- TI_DbgPrint(DEBUG_TCP,
- ("Completing Send request: %x %x\n",
- Bucket->Request, Status));
-
- Bucket->Status = Status;
- Bucket->Information = 0;
-
- CompleteBucket(Connection, Bucket, FALSE);
- }
-
- while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest,
&Connection->Lock)))
- {
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
- Bucket->Status = Status;
- Bucket->Information = 0;
-
- CompleteBucket(Connection, Bucket, FALSE);
- }
+ // flush listen queue
+ FlushListenQueue(Connection, Status);
+
+ // flush send queue
+ FlushSendQueue(Connection, Status, TRUE);
+
+ // flush connect queue
+ FlushConnectQueue(Connection, Status);
+
+ // flush shutdown queue
+ FlushShutdownQueue(Connection, Status, TRUE);
DereferenceObject(Connection);
}
@@ -166,7 +271,7 @@
if (err == ERR_OK && Connection->SocketContext)
{
/* Just flush the receive queue and get out of here */
- FlushReceiveQueue(Connection, STATUS_SUCCESS);
+ FlushReceiveQueue(Connection, STATUS_SUCCESS, TRUE);
}
else
{
@@ -331,6 +436,18 @@
CompleteBucket(Connection, Bucket, FALSE);
}
}
+
+ // If we completed all outstanding send requests then finish all pending shutdown
requests,
+ // cancel the timer and dereference the connection
+ if (IsListEmpty(&Connection->SendRequest))
+ {
+ FlushShutdownQueue(Connection, STATUS_SUCCESS, FALSE);
+
+ if (KeCancelTimer(&Connection->DisconnectTimer))
+ {
+ DereferenceObject(Connection);
+ }
+ }
DereferenceObject(Connection);
}
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] Fri Aug
5 21:33:20 2011
@@ -23,6 +23,51 @@
#include "rosip.h"
+VOID NTAPI
+DisconnectTimeoutDpc(PKDPC Dpc,
+ PVOID DeferredContext,
+ PVOID SystemArgument1,
+ PVOID SystemArgument2)
+{
+ PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)DeferredContext;
+ PLIST_ENTRY Entry;
+ PTDI_BUCKET Bucket;
+ NTSTATUS Status;
+
+ LockObjectAtDpcLevel(Connection);
+
+ /* We timed out waiting for pending sends so force it to shutdown */
+ Status = TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
+
+ while (!IsListEmpty(&Connection->SendRequest))
+ {
+ Entry = RemoveHeadList(&Connection->SendRequest);
+
+ Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+
+ Bucket->Information = 0;
+ Bucket->Status = STATUS_FILE_CLOSED;
+
+ CompleteBucket(Connection, Bucket, FALSE);
+ }
+
+ while (!IsListEmpty(&Connection->ShutdownRequest))
+ {
+ Entry = RemoveHeadList( &Connection->ShutdownRequest );
+
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+
+ Bucket->Status = STATUS_TIMEOUT;
+ Bucket->Information = 0;
+
+ CompleteBucket(Connection, Bucket, FALSE);
+ }
+
+ UnlockObjectFromDpcLevel(Connection);
+
+ DereferenceObject(Connection);
+}
+
VOID ConnectionFree(PVOID Object)
{
PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)Object;
@@ -57,6 +102,10 @@
InitializeListHead(&Connection->SendRequest);
InitializeListHead(&Connection->ShutdownRequest);
InitializeListHead(&Connection->PacketQueue);
+
+ /* Initialize disconnect timer */
+ KeInitializeTimer(&Connection->DisconnectTimer);
+ KeInitializeDpc(&Connection->DisconnectDpc, DisconnectTimeoutDpc,
Connection);
/* Save client context pointer */
Connection->ClientContext = ClientContext;
@@ -331,13 +380,16 @@
NTSTATUS TCPDisconnect
( PCONNECTION_ENDPOINT Connection,
UINT Flags,
+ PLARGE_INTEGER Timeout,
PTDI_CONNECTION_INFORMATION ConnInfo,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PTCP_COMPLETION_ROUTINE Complete,
PVOID Context )
{
NTSTATUS Status = STATUS_INVALID_PARAMETER;
- KIRQL OldIrql;
+ PTDI_BUCKET Bucket;
+ KIRQL OldIrql;
+ LARGE_INTEGER ActualTimeout;
TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Called\n"));
@@ -347,11 +399,57 @@
{
if (Flags & TDI_DISCONNECT_RELEASE)
{
- Status = TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
+ if (IsListEmpty(&Connection->SendRequest))
+ {
+ Status = TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
+ }
+ else if (Timeout && Timeout->QuadPart == 0)
+ {
+ FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE);
+ TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
+ Status = STATUS_TIMEOUT;
+ }
+ else
+ {
+ /* Use the timeout specified or 1 second if none was specified */
+ if (Timeout)
+ {
+ ActualTimeout = *Timeout;
+ }
+ else
+ {
+ ActualTimeout.QuadPart = -1000000;
+ }
+
+ /* We couldn't complete the request now because we need to wait for
outstanding I/O */
+ Bucket = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Bucket),
TDI_BUCKET_TAG);
+ if (!Bucket)
+ {
+ UnlockObject(Connection, OldIrql);
+ return STATUS_NO_MEMORY;
+ }
+
+ Bucket->Request.RequestNotifyObject = (PVOID)Complete;
+ Bucket->Request.RequestContext = Context;
+
+ InsertTailList(&Connection->ShutdownRequest,
&Bucket->Entry);
+
+ ReferenceObject(Connection);
+ if (KeCancelTimer(&Connection->DisconnectTimer))
+ {
+ DereferenceObject(Connection);
+ }
+ KeSetTimer(&Connection->DisconnectTimer, ActualTimeout,
&Connection->DisconnectDpc);
+
+ Status = STATUS_PENDING;
+ }
}
if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
{
+ FlushReceiveQueue(Connection, STATUS_FILE_CLOSED, FALSE);
+ FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE);
+ FlushShutdownQueue(Connection, STATUS_FILE_CLOSED, FALSE);
Status = TCPTranslateError(LibTCPShutdown(Connection, 1, 1));
}
}
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/drive…
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c [iso-8859-1] Fri Aug 5
21:33:20 2011
@@ -3,6 +3,8 @@
#include "lwip/tcp.h"
#include "lwip/pbuf.h"
#include "lwip/err.h"
+
+#include "rosip.h"
#include <debug.h>