Modified: trunk/reactos/drivers/lib/ip/network/receive.c
Modified: trunk/reactos/drivers/lib/ip/transport/tcp/tcp.c
Modified: trunk/reactos/drivers/net/tcpip/include/tcp.h
Modified: trunk/reactos/drivers/net/tcpip/include/tcpip.h
Modified: trunk/reactos/drivers/net/tcpip/include/titypes.h
Modified: trunk/reactos/drivers/net/tcpip/tcpip/dispatch.c
Modified: trunk/reactos/drivers/net/tcpip/tcpip/fileobjs.c
Modified: trunk/reactos/drivers/net/tcpip/tcpip/main.c
--- trunk/reactos/drivers/lib/ip/network/receive.c 2005-12-07 00:06:27 UTC (rev 19942)
+++ trunk/reactos/drivers/lib/ip/network/receive.c 2005-12-07 08:50:27 UTC (rev 19943)
@@ -521,6 +521,8 @@
* IPPacket = Pointer to IP packet
*/
{
+ IP_ADDRESS Address;
+
TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n"));
IPPacket->HeaderSize = (((PIPv4_HEADER)IPPacket->Header)->VerIHL & 0x0F) << 2;
@@ -562,7 +564,16 @@
/* FIXME: Should we allow packets to be received on the wrong interface? */
/* XXX Find out if this packet is destined for us */
- ProcessFragment(IF, IPPacket);
+
+ if( AddrLocateADEv4( IPPacket->DstAddr.Address.IPv4Address, &Address ) ) {
+ ProcessFragment( IF, IPPacket );
+ } else {
+ PNEIGHBOR_CACHE_ENTRY NCE;
+
+ if((NCE = RouteGetRouteToDestination( &IPPacket->DstAddr ))) {
+ IPSendDatagram( IPPacket, NCE, NULL, NULL );
+ }
+ }
#if 0
} else {
/* This packet is not destined for us. If we are a router,
--- trunk/reactos/drivers/lib/ip/transport/tcp/tcp.c 2005-12-07 00:06:27 UTC (rev 19942)
+++ trunk/reactos/drivers/lib/ip/transport/tcp/tcp.c 2005-12-07 08:50:27 UTC (rev 19943)
@@ -647,4 +647,8 @@
return STATUS_SUCCESS;
}
+void TCPMarkForDisconnect( PCONNECTION_ENDPOINT Context, BOOLEAN Marked ) {
+ Context->Disconnecting = Marked;
+}
+
/* EOF */
--- trunk/reactos/drivers/net/tcpip/include/tcp.h 2005-12-07 00:06:27 UTC (rev 19942)
+++ trunk/reactos/drivers/net/tcpip/include/tcp.h 2005-12-07 08:50:27 UTC (rev 19943)
@@ -38,6 +38,9 @@
#define TCPOPTLEN_MAX_SEG_SIZE 0x4
+#define TCP_CANCEL_DISCONNECT 0
+#define TCP_CANCEL_CLOSE 1
+
/* Data offset; 32-bit words (leftmost 4 bits); convert to bytes */
#define TCP_DATA_OFFSET(DataOffset)(((DataOffset) & 0xF0) >> (4-2))
@@ -57,6 +60,13 @@
KEVENT Event;
} SLEEPING_THREAD, *PSLEEPING_THREAD;
+typedef struct _CANCEL_REQUEST {
+ LIST_ENTRY Entry;
+ PVOID Context;
+ PIRP Irp;
+ UINT Flags, Type;
+} CANCEL_REQUEST, *PCANCEL_REQUEST;
+
/* Retransmission timeout constants */
/* Lower bound for retransmission timeout in TCP timer ticks */
@@ -176,4 +186,7 @@
NTSTATUS TCPShutdown(
VOID);
+void TCPMarkForDisconnect(
+ PCONNECTION_ENDPOINT Connection, BOOLEAN Marked );
+
#endif /* __TCP_H */
--- trunk/reactos/drivers/net/tcpip/include/tcpip.h 2005-12-07 00:06:27 UTC (rev 19942)
+++ trunk/reactos/drivers/net/tcpip/include/tcpip.h 2005-12-07 08:50:27 UTC (rev 19943)
@@ -188,6 +188,9 @@
extern KSPIN_LOCK InterfaceListLock;
extern LIST_ENTRY AddressFileListHead;
extern KSPIN_LOCK AddressFileListLock;
+extern LIST_ENTRY CancelQueue;
+extern KSPIN_LOCK CancelQueueLock;
+extern WORK_QUEUE_ITEM CancelQueueWork;
extern NDIS_HANDLE GlobalPacketPool;
extern NDIS_HANDLE GlobalBufferPool;
extern KSPIN_LOCK EntityListLock;
--- trunk/reactos/drivers/net/tcpip/include/titypes.h 2005-12-07 00:06:27 UTC (rev 19942)
+++ trunk/reactos/drivers/net/tcpip/include/titypes.h 2005-12-07 08:50:27 UTC (rev 19943)
@@ -308,6 +308,8 @@
* notification service to the client */
UINT SignalState; /* Active signals from oskit */
BOOLEAN Signalled; /* Are we a member of the signal list */
+ BOOLEAN Disconnecting; /* Cancelling an irp .. we need to leave it
+ * alone for now */
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
--- trunk/reactos/drivers/net/tcpip/tcpip/dispatch.c 2005-12-07 00:06:27 UTC (rev 19942)
+++ trunk/reactos/drivers/net/tcpip/tcpip/dispatch.c 2005-12-07 08:50:27 UTC (rev 19943)
@@ -12,6 +12,8 @@
#include "precomp.h"
#include <pseh/pseh.h>
+extern VOID DeleteConnectionEndpoint( PCONNECTION_ENDPOINT Endpoint );
+
NTSTATUS DispPrepareIrpForCancel(
PTRANSPORT_CONTEXT Context,
PIRP Irp,
@@ -135,7 +137,56 @@
TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n"));
}
+VOID DDKAPI CancelQueuePassiveHandler( PVOID CancelRequestVoid )
+{
+ KIRQL OldIrql;
+ PCANCEL_REQUEST CancelReq;
+ PLIST_ENTRY CqEntry;
+ KeAcquireSpinLock( &CancelQueueLock, &OldIrql );
+
+ TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE: Starting\n"));
+
+ for( CqEntry = CancelQueue.Flink;
+ CqEntry != &CancelQueue;
+ ) {
+ CancelReq = CONTAINING_RECORD(CqEntry, CANCEL_REQUEST, Entry);
+ ExInterlockedRemoveHeadList( &CancelQueue, &CancelQueueLock );
+ CqEntry = CancelQueue.Flink;
+
+ KeReleaseSpinLock( &CancelQueueLock, OldIrql );
+
+ TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE: Executing %x\n", CancelReq));
+
+ switch( CancelReq->Type ) {
+ case TCP_CANCEL_DISCONNECT:
+ TCPDisconnect
+ ( CancelReq->Context,
+ CancelReq->Flags,
+ NULL,
+ NULL,
+ DispDataRequestComplete,
+ CancelReq->Irp );
+ break;
+
+ case TCP_CANCEL_CLOSE:
+ TCPClose( CancelReq->Context );
+ DeleteConnectionEndpoint( CancelReq->Context );
+ break;
+ }
+
+ TCPMarkForDisconnect( CancelReq->Context, FALSE );
+
+ ExFreePool( CancelReq );
+
+ KeAcquireSpinLock( &CancelQueueLock, &OldIrql );
+ }
+
+ TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE: Ending\n"));
+
+ KeReleaseSpinLock( &CancelQueueLock, OldIrql );
+}
+
VOID DDKAPI DispCancelRequest(
PDEVICE_OBJECT Device,
PIRP Irp)
@@ -150,6 +201,7 @@
PTRANSPORT_CONTEXT TranContext;
PFILE_OBJECT FileObject;
UCHAR MinorFunction;
+ PCANCEL_REQUEST CancelRequest;
/*NTSTATUS Status = STATUS_SUCCESS;*/
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@@ -169,23 +221,21 @@
/* Try canceling the request */
switch(MinorFunction) {
case TDI_SEND:
- TCPDisconnect
- ( TranContext->Handle.ConnectionContext,
- TDI_DISCONNECT_RELEASE,
- NULL,
- NULL,
- DispDataRequestComplete,
- Irp );
- break;
-
case TDI_RECEIVE:
- TCPDisconnect
- ( TranContext->Handle.ConnectionContext,
- TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE,
- NULL,
- NULL,
- DispDataRequestComplete,
- Irp );
+ CancelRequest = ExAllocatePoolWithTag
+ ( sizeof(CANCEL_REQUEST), NonPagedPool, FOURCC('T','c','k','O') );
+ TCPMarkForDisconnect( TranContext->Handle.ConnectionContext, TRUE );
+ if( CancelRequest ) {
+ TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE:-> %x\n", CancelRequest));
+ CancelRequest->Flags = TDI_DISCONNECT_RELEASE |
+ (MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0;
+ CancelRequest->Context = TranContext->Handle.ConnectionContext;
+ CancelRequest->Irp = Irp;
+ CancelRequest->Type = TCP_CANCEL_DISCONNECT;
+ ExInterlockedInsertTailList
+ ( &CancelQueue, &CancelRequest->Entry, &CancelQueueLock );
+ ExQueueWorkItem( &CancelQueueWork, CriticalWorkQueue );
+ }
break;
case TDI_SEND_DATAGRAM:
--- trunk/reactos/drivers/net/tcpip/tcpip/fileobjs.c 2005-12-07 00:06:27 UTC (rev 19942)
+++ trunk/reactos/drivers/net/tcpip/tcpip/fileobjs.c 2005-12-07 08:50:27 UTC (rev 19943)
@@ -10,7 +10,6 @@
#include "precomp.h"
-
/* List of all address file objects managed by this driver */
LIST_ENTRY AddressFileListHead;
KSPIN_LOCK AddressFileListLock;
@@ -352,6 +351,7 @@
KIRQL OldIrql;
PADDRESS_FILE AddrFile;
NTSTATUS Status = STATUS_SUCCESS;
+ PCANCEL_REQUEST CancelReq;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
@@ -369,8 +369,16 @@
switch (AddrFile->Protocol) {
case IPPROTO_TCP:
TCPFreePort( AddrFile->Port );
- if( AddrFile->Listener )
- TCPClose( AddrFile->Listener );
+ if( AddrFile->Listener ) {
+ CancelReq = ExAllocatePoolWithTag
+ ( sizeof(CANCEL_REQUEST), NonPagedPool, FOURCC('T','c','l','s') );
+ if( CancelReq ) {
+ CancelReq->Type = TCP_CANCEL_CLOSE;
+ CancelReq->Context = AddrFile->Listener;
+ AddrFile->Listener = NULL;
+ ExQueueWorkItem( &CancelQueueWork, CriticalWorkQueue );
+ }
+ }
break;
case IPPROTO_UDP:
@@ -466,15 +474,19 @@
{
PCONNECTION_ENDPOINT Connection;
NTSTATUS Status = STATUS_SUCCESS;
+ PCANCEL_REQUEST CancelReq;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Connection = Request->Handle.ConnectionContext;
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
- TCPClose(Connection);
- DeleteConnectionEndpoint(Connection);
- TcpipRecursiveMutexLeave( &TCPLock );
+ CancelReq = ExAllocatePoolWithTag
+ ( sizeof(CANCEL_REQUEST), NonPagedPool, FOURCC('T','c','l','s') );
+ if( CancelReq ) {
+ CancelReq->Type = TCP_CANCEL_CLOSE;
+ CancelReq->Context = Connection;
+ ExQueueWorkItem( &CancelQueueWork, CriticalWorkQueue );
+ }
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
--- trunk/reactos/drivers/net/tcpip/tcpip/main.c 2005-12-07 00:06:27 UTC (rev 19942)
+++ trunk/reactos/drivers/net/tcpip/tcpip/main.c 2005-12-07 08:50:27 UTC (rev 19943)
@@ -14,7 +14,7 @@
#ifndef NDEBUG
DWORD DebugTraceLevel = DEBUG_ULTRA & ~(DEBUG_LOCK | DEBUG_PBUFFER);
#else
-DWORD DebugTraceLevel = 0;
+DWORD DebugTraceLevel = DEBUG_IRP;
#endif /* NDEBUG */
PDEVICE_OBJECT TCPDeviceObject = NULL;
@@ -35,6 +35,12 @@
KSPIN_LOCK IpWorkLock;
WORK_QUEUE_ITEM IpWorkItem;
+/* Cancel Queue */
+LIST_ENTRY CancelQueue;
+KSPIN_LOCK CancelQueueLock;
+WORK_QUEUE_ITEM CancelQueueWork;
+extern VOID DDKAPI CancelQueuePassiveHandler( PVOID Context );
+
VOID TiWriteErrorLog(
PDRIVER_OBJECT DriverContext,
NTSTATUS ErrorCode,
@@ -809,6 +815,11 @@
InitializeListHead(&InterfaceListHead);
KeInitializeSpinLock(&InterfaceListLock);
+ /* Initialize cancellation queue */
+ InitializeListHead(&CancelQueue);
+ KeInitializeSpinLock(&CancelQueueLock);
+ ExInitializeWorkItem( &CancelQueueWork, CancelQueuePassiveHandler, NULL );
+
/* Initialize network level protocol subsystem */
IPStartup(RegistryPath);