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