From dabb3e9f9808ae2a4b08b357328cce9f4138e9f6 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 27 Jun 2009 03:23:10 +0000 Subject: [PATCH] - Don't leave the listen IRP in the queue when cancelling the listen request - Kill all the requests before closing the socket - Notify oskittcp when we are cancelling requests so it can properly close the socket svn path=/trunk/; revision=41630 --- .../drivers/network/tcpip/include/dispatch.h | 9 +++ .../drivers/network/tcpip/tcpip/dispatch.c | 10 +-- reactos/lib/drivers/ip/transport/tcp/tcp.c | 76 ++++++++++++++----- 3 files changed, 71 insertions(+), 24 deletions(-) diff --git a/reactos/drivers/network/tcpip/include/dispatch.h b/reactos/drivers/network/tcpip/include/dispatch.h index bd559517b11..b6aada9058a 100644 --- a/reactos/drivers/network/tcpip/include/dispatch.h +++ b/reactos/drivers/network/tcpip/include/dispatch.h @@ -7,6 +7,12 @@ #ifndef __DISPATCH_H #define __DISPATCH_H +typedef struct _DISCONNECT_TYPE { + UINT Type; + PVOID Context; + PIRP Irp; + PFILE_OBJECT FileObject; +} DISCONNECT_TYPE, *PDISCONNECT_TYPE; NTSTATUS DispTdiAccept( PIRP Irp); @@ -64,6 +70,9 @@ NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp); +VOID DispDoDisconnect( + PVOID Data); + #endif /* __DISPATCH_H */ /* EOF */ diff --git a/reactos/drivers/network/tcpip/tcpip/dispatch.c b/reactos/drivers/network/tcpip/tcpip/dispatch.c index ba33f68f760..b40a3900c2d 100644 --- a/reactos/drivers/network/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/network/tcpip/tcpip/dispatch.c @@ -111,13 +111,6 @@ VOID DispDataRequestComplete( TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n")); } -typedef struct _DISCONNECT_TYPE { - UINT Type; - PVOID Context; - PIRP Irp; - PFILE_OBJECT FileObject; -} DISCONNECT_TYPE, *PDISCONNECT_TYPE; - VOID DispDoDisconnect( PVOID Data ) { PDISCONNECT_TYPE DisType = (PDISCONNECT_TYPE)Data; @@ -250,6 +243,9 @@ VOID NTAPI DispCancelListenRequest( /* Try canceling the request */ Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; + + TCPRemoveIRP(Connection, Irp); + TCPAbortListenForSocket( Connection->AddressFile->Listener, Connection ); diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index 0e943f06cdb..7e2e2e290b4 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -217,24 +217,66 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection, } if( NewState & SEL_FIN ) { - PLIST_ENTRY ListsToErase[4]; - UINT i; + TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); - TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); + while (!IsListEmpty(&Connection->ReceiveRequest)) + { + DISCONNECT_TYPE DisType; + PIO_STACK_LOCATION IrpSp; + Entry = RemoveHeadList(&Connection->ReceiveRequest); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + IrpSp = IoGetCurrentIrpStackLocation((PIRP)Bucket->Request.RequestContext); - ListsToErase[0] = &Connection->ReceiveRequest; - ListsToErase[1] = &Connection->ListenRequest; - ListsToErase[2] = &Connection->ConnectRequest; - ListsToErase[3] = &Connection->SendRequest; + /* We have to notify oskittcp of the abortion */ + DisType.Type = TDI_DISCONNECT_RELEASE | TDI_DISCONNECT_ABORT; + DisType.Context = Connection; + DisType.Irp = (PIRP)Bucket->Request.RequestContext; + DisType.FileObject = IrpSp->FileObject; - for( i = 0; i < 4; i++ ) { - while( !IsListEmpty( ListsToErase[i] ) ) { - Entry = RemoveHeadList( ListsToErase[i] ); - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - exFreePool( Bucket ); - } + ChewCreate(NULL, sizeof(DISCONNECT_TYPE), + DispDoDisconnect, &DisType); + } + + while (!IsListEmpty(&Connection->SendRequest)) + { + DISCONNECT_TYPE DisType; + PIO_STACK_LOCATION IrpSp; + Entry = RemoveHeadList(&Connection->SendRequest); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + IrpSp = IoGetCurrentIrpStackLocation((PIRP)Bucket->Request.RequestContext); + + /* We have to notify oskittcp of the abortion */ + DisType.Type = TDI_DISCONNECT_RELEASE; + DisType.Context = Connection; + DisType.Irp = (PIRP)Bucket->Request.RequestContext; + DisType.FileObject = IrpSp->FileObject; + + ChewCreate(NULL, sizeof(DISCONNECT_TYPE), + DispDoDisconnect, &DisType); + } + + while (!IsListEmpty(&Connection->ListenRequest)) + { + Entry = RemoveHeadList(&Connection->ListenRequest); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + /* We have to notify oskittcp of the abortion */ + TCPAbortListenForSocket(Connection->AddressFile->Listener, + Connection); + + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + } + + while (!IsListEmpty(&Connection->ConnectRequest)) + { + Entry = RemoveHeadList(&Connection->ConnectRequest); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); } } @@ -656,12 +698,12 @@ NTSTATUS TCPClose TcpipRecursiveMutexEnter( &TCPLock, TRUE ); - Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) ); - /* Make our code remove all pending IRPs */ Connection->State |= SEL_FIN; DrainSignals(); + Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) ); + TcpipRecursiveMutexLeave( &TCPLock ); TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status));