From: Cameron Gutman Date: Thu, 31 Dec 2009 23:33:24 +0000 (+0000) Subject: [TCPIP, IP] X-Git-Tag: backups/aicom-network-stable@46924^2^2~13 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=8dd3966ba985aef3a1816c526537102f0c8b031c [TCPIP, IP] - Completely rewrite (again) the locking code and use references to ensure that the connection doesn't get freed while completing requests (the most frequent cause of crashes) - Remove DrainSignals and complete requests inside HandleSignalledConnection instead of doing them in a separate thread (increases speed a lot) [OSKITTCP] - Don't clear the socket context in OskitTCPClose because we would end up in HandleSignalledConnection without a connection (which we don't support anymore after eliminating DrainSignals) - Change the check performed to see if a socket is dying so we support connection dying after calling OskitTCPClose [AFD] - Remove leftover ASSERTs which fail after the changes to tcpip (they were wrong in the first place because we call into tcpip at DISPATCH_LEVEL sometimes) svn path=/branches/aicom-network-branch/; revision=44839 --- diff --git a/drivers/network/afd/afd/read.c b/drivers/network/afd/afd/read.c index 0c690733d6d..e7e9a6e67db 100644 --- a/drivers/network/afd/afd/read.c +++ b/drivers/network/afd/afd/read.c @@ -189,8 +189,6 @@ NTSTATUS NTAPI ReceiveComplete AFD_DbgPrint(MID_TRACE,("Called\n")); - ASSERT_IRQL(APC_LEVEL); - if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; diff --git a/drivers/network/afd/afd/write.c b/drivers/network/afd/afd/write.c index 16c65e4e658..427dd01d83f 100644 --- a/drivers/network/afd/afd/write.c +++ b/drivers/network/afd/afd/write.c @@ -38,8 +38,6 @@ static NTSTATUS NTAPI SendComplete Irp->IoStatus.Status, Irp->IoStatus.Information)); - ASSERT_IRQL(APC_LEVEL); - if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; diff --git a/drivers/network/afd/include/debug.h b/drivers/network/afd/include/debug.h index 705a9d0b6ae..6127fa4637e 100644 --- a/drivers/network/afd/include/debug.h +++ b/drivers/network/afd/include/debug.h @@ -53,13 +53,10 @@ extern DWORD DebugTraceLevel; #define ASSERT(x) if (!(x)) { AFD_DbgPrint(MIN_TRACE, ("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__)); DbgBreakPoint(); } #endif /* NASSERT */ -#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x)) - #else /* DBG */ #define AFD_DbgPrint(_t_, _x_) -#define ASSERT_IRQL(x) #define ASSERTKM(x) #ifndef ASSERT #define ASSERT(x) @@ -70,7 +67,6 @@ extern DWORD DebugTraceLevel; #undef assert #define assert(x) ASSERT(x) -#define assert_irql(x) ASSERT_IRQL(x) #ifdef _MSC_VER diff --git a/drivers/network/tcpip/include/tcp.h b/drivers/network/tcpip/include/tcp.h index a02c03b796e..4b5318f60bc 100644 --- a/drivers/network/tcpip/include/tcp.h +++ b/drivers/network/tcpip/include/tcp.h @@ -62,6 +62,7 @@ typedef struct _SLEEPING_THREAD { typedef struct _CLIENT_DATA { BOOLEAN Unlocked; KSPIN_LOCK Lock; + KIRQL OldIrql; } CLIENT_DATA, *PCLIENT_DATA; /* Retransmission timeout constants */ diff --git a/drivers/network/tcpip/include/titypes.h b/drivers/network/tcpip/include/titypes.h index 78584fb1391..5a921e4fd10 100644 --- a/drivers/network/tcpip/include/titypes.h +++ b/drivers/network/tcpip/include/titypes.h @@ -7,79 +7,63 @@ #ifndef __TITYPES_H #define __TITYPES_H - -#if DBG - -#define DEBUG_REFCHECK(Object) { \ - if ((Object)->RefCount <= 0) { \ - TI_DbgPrint(MIN_TRACE, ("Object at (0x%X) has invalid reference count (%d).\n", \ - (Object), (Object)->RefCount)); \ - } \ -} - /* * VOID ReferenceObject( * PVOID Object) */ -#define ReferenceObject(Object) \ -{ \ - CHAR c1, c2, c3, c4; \ - \ - c1 = ((Object)->Tag >> 24) & 0xFF; \ - c2 = ((Object)->Tag >> 16) & 0xFF; \ - c3 = ((Object)->Tag >> 8) & 0xFF; \ - c4 = ((Object)->Tag & 0xFF); \ - \ - DEBUG_REFCHECK(Object); \ - TI_DbgPrint(DEBUG_REFCOUNT, ("Referencing object of type (%c%c%c%c) at (0x%X). RefCount (%d).\n", \ - c4, c3, c2, c1, (Object), (Object)->RefCount)); \ - \ - InterlockedIncrement(&((Object)->RefCount)); \ +#define ReferenceObject(Object) \ +{ \ + InterlockedIncrement(&((Object)->RefCount)); \ } - /* +/* * VOID DereferenceObject( * PVOID Object) */ -#define DereferenceObject(Object) \ -{ \ - CHAR c1, c2, c3, c4; \ - \ - c1 = ((Object)->Tag >> 24) & 0xFF; \ - c2 = ((Object)->Tag >> 16) & 0xFF; \ - c3 = ((Object)->Tag >> 8) & 0xFF; \ - c4 = ((Object)->Tag & 0xFF); \ - \ - DEBUG_REFCHECK(Object); \ - TI_DbgPrint(DEBUG_REFCOUNT, ("Dereferencing object of type (%c%c%c%c) at (0x%X). RefCount (%d).\n", \ - c4, c3, c2, c1, (Object), (Object)->RefCount)); \ - \ - if (InterlockedDecrement(&((Object)->RefCount)) == 0) \ - (((Object)->Free)(Object)); \ +#define DereferenceObject(Object) \ +{ \ + if (InterlockedDecrement(&((Object)->RefCount)) == 0) \ + (((Object)->Free)(Object)); \ } -#else /* DBG */ +/* + * VOID LockObject(PVOID Object, PKIRQL OldIrql) + */ +#define LockObject(Object, Irql) \ +{ \ + ReferenceObject(Object); \ + KeAcquireSpinLock(&((Object)->Lock), Irql); \ + memcpy(&(Object)->OldIrql, Irql, sizeof(KIRQL)); \ +} /* - * VOID ReferenceObject( - * PVOID Object) + * VOID LockObjectAtDpcLevel(PVOID Object) */ -#define ReferenceObject(Object) \ -{ \ - InterlockedIncrement(&((Object)->RefCount)); \ +#define LockObjectAtDpcLevel(Object) \ +{ \ + ReferenceObject(Object); \ + KeAcquireSpinLockAtDpcLevel(&((Object)->Lock)); \ + (Object)->OldIrql = DISPATCH_LEVEL; \ } /* - * VOID DereferenceObject( - * PVOID Object) + * VOID UnlockObject(PVOID Object, KIRQL OldIrql) */ -#define DereferenceObject(Object) \ -{ \ - if (InterlockedDecrement(&((Object)->RefCount)) == 0) \ - (((Object)->Free)(Object)); \ +#define UnlockObject(Object, OldIrql) \ +{ \ + KeReleaseSpinLock(&((Object)->Lock), OldIrql); \ + DereferenceObject(Object); \ +} + +/* + * VOID UnlockObjectFromDpcLevel(PVOID Object) + */ +#define UnlockObjectFromDpcLevel(Object) \ +{ \ + KeReleaseSpinLockFromDpcLevel(&((Object)->Lock)); \ + DereferenceObject(Object); \ } -#endif /* DBG */ #include @@ -143,8 +127,10 @@ typedef struct _DATAGRAM_SEND_REQUEST { field holds a pointer to this structure */ typedef struct _ADDRESS_FILE { LIST_ENTRY ListEntry; /* Entry on list */ - KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */ + LONG RefCount; /* Reference count */ OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */ + KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */ + KIRQL OldIrql; /* Currently not used */ IP_ADDRESS Address; /* Address of this address file */ USHORT Family; /* Address family */ USHORT Protocol; /* Protocol number */ @@ -264,7 +250,10 @@ typedef struct _TDI_BUCKET { to this structure */ typedef struct _CONNECTION_ENDPOINT { LIST_ENTRY ListEntry; /* Entry on list */ + LONG RefCount; /* Reference count */ + OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */ KSPIN_LOCK Lock; /* Spin lock to protect this structure */ + KIRQL OldIrql; /* The old irql is stored here for use in HandleSignalledConnection */ PVOID ClientContext; /* Pointer to client context information */ PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */ PVOID SocketContext; /* Context for lower layer */ @@ -290,6 +279,8 @@ typedef struct _CONNECTION_ENDPOINT { field holds a pointer to this structure */ typedef struct _CONTROL_CHANNEL { LIST_ENTRY ListEntry; /* Entry on list */ + LONG RefCount; /* Reference count */ + OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */ KSPIN_LOCK Lock; /* Spin lock to protect this structure */ } CONTROL_CHANNEL, *PCONTROL_CHANNEL; diff --git a/drivers/network/tcpip/tcpip/dispatch.c b/drivers/network/tcpip/tcpip/dispatch.c index fe8d7664b88..fb77376d68f 100644 --- a/drivers/network/tcpip/tcpip/dispatch.c +++ b/drivers/network/tcpip/tcpip/dispatch.c @@ -89,21 +89,10 @@ VOID DispDataRequestComplete( * Count = Number of bytes sent or received */ { - PIRP Irp; - PIO_STACK_LOCATION IrpSp; - KIRQL OldIrql; + PIRP Irp = Context; TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n", - Context, Status, Count)); - - Irp = Context; - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - IoAcquireCancelSpinLock(&OldIrql); - - (void)IoSetCancelRoutine(Irp, NULL); - - IoReleaseCancelSpinLock(OldIrql); + Irp, Status, Count)); Irp->IoStatus.Status = Status; Irp->IoStatus.Information = Count; @@ -309,18 +298,18 @@ NTSTATUS DispTdiAssociateAddress( return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + LockObject(Connection, &OldIrql); if (Connection->AddressFile) { ObDereferenceObject(FileObject); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n")); return STATUS_INVALID_PARAMETER; } if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { ObDereferenceObject(FileObject); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n", FileObject->FsContext2)); return STATUS_INVALID_PARAMETER; @@ -331,31 +320,33 @@ NTSTATUS DispTdiAssociateAddress( TranContext = FileObject->FsContext; if (!TranContext) { ObDereferenceObject(FileObject); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); return STATUS_INVALID_PARAMETER; } AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; if (!AddrFile) { - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); ObDereferenceObject(FileObject); TI_DbgPrint(MID_TRACE, ("No address file object.\n")); return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLockAtDpcLevel(&AddrFile->Lock); + LockObjectAtDpcLevel(AddrFile); + ReferenceObject(AddrFile); Connection->AddressFile = AddrFile; /* Add connection endpoint to the address file */ + ReferenceObject(Connection); AddrFile->Connection = Connection; /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */ ObDereferenceObject(FileObject); - KeReleaseSpinLockFromDpcLevel(&AddrFile->Lock); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObjectFromDpcLevel(AddrFile); + UnlockObject(Connection, OldIrql); return Status; } @@ -457,25 +448,27 @@ NTSTATUS DispTdiDisassociateAddress( return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + LockObject(Connection, &OldIrql); if (!Connection->AddressFile) { - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n")); return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLockAtDpcLevel(&Connection->AddressFile->Lock); + LockObjectAtDpcLevel(Connection->AddressFile); /* Remove this connection from the address file */ + DereferenceObject(Connection->AddressFile->Connection); Connection->AddressFile->Connection = NULL; - KeReleaseSpinLockFromDpcLevel(&Connection->AddressFile->Lock); + UnlockObjectFromDpcLevel(Connection->AddressFile); /* Remove the address file from this connection */ + DereferenceObject(Connection->AddressFile); Connection->AddressFile = NULL; - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); return STATUS_SUCCESS; } @@ -584,17 +577,17 @@ NTSTATUS DispTdiListen( Irp, (PDRIVER_CANCEL)DispCancelListenRequest); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + LockObject(Connection, &OldIrql); if (Connection->AddressFile == NULL) { TI_DbgPrint(MID_TRACE, ("No associated address file\n")); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); Status = STATUS_INVALID_PARAMETER; goto done; } - KeAcquireSpinLockAtDpcLevel(&Connection->AddressFile->Lock); + LockObjectAtDpcLevel(Connection->AddressFile); /* Listening will require us to create a listening socket and store it in * the address file. It will be signalled, and attempt to complete an irp @@ -609,6 +602,7 @@ NTSTATUS DispTdiListen( Status = STATUS_NO_MEMORY; if( NT_SUCCESS(Status) ) { + ReferenceObject(Connection->AddressFile); Connection->AddressFile->Listener->AddressFile = Connection->AddressFile; @@ -632,8 +626,8 @@ NTSTATUS DispTdiListen( Irp ); } - KeReleaseSpinLockFromDpcLevel(&Connection->AddressFile->Lock); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObjectFromDpcLevel(Connection->AddressFile); + UnlockObject(Connection, OldIrql); done: if (Status != STATUS_PENDING) { @@ -1106,7 +1100,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp) Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters; Status = STATUS_SUCCESS; - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + LockObject(AddrFile, &OldIrql); /* Set the event handler. if an event handler is associated with a specific event, it's flag (RegisteredXxxHandler) is TRUE. @@ -1227,7 +1221,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp) Status = STATUS_INVALID_PARAMETER; } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return Status; } diff --git a/drivers/network/tcpip/tcpip/fileobjs.c b/drivers/network/tcpip/tcpip/fileobjs.c index 88ac1858b1e..62ca63c7686 100644 --- a/drivers/network/tcpip/tcpip/fileobjs.c +++ b/drivers/network/tcpip/tcpip/fileobjs.c @@ -153,7 +153,55 @@ VOID AddrFileFree( * Object = Pointer to address file object to free */ { - ExFreePoolWithTag(Object, ADDR_FILE_TAG); + PADDRESS_FILE AddrFile = Object; + KIRQL OldIrql; + PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; + PDATAGRAM_SEND_REQUEST SendRequest; + PLIST_ENTRY CurrentEntry; + + TI_DbgPrint(MID_TRACE, ("Called.\n")); + + /* Remove address file from the global list */ + TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql); + RemoveEntryList(&AddrFile->ListEntry); + TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); + + /* FIXME: Kill TCP connections on this address file object */ + + /* Return pending requests with error */ + + TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile)); + + /* Go through pending receive request list and cancel them all */ + while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { + ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry); + (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0); + /* ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); FIXME: WTF? */ + } + + TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile)); + + /* Go through pending send request list and cancel them all */ + while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { + SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry); + (*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0); + ExFreePoolWithTag(SendRequest, DATAGRAM_SEND_TAG); + } + + /* Protocol specific handling */ + switch (AddrFile->Protocol) { + case IPPROTO_TCP: + TCPFreePort( AddrFile->Port ); + break; + + case IPPROTO_UDP: + UDPFreePort( AddrFile->Port ); + break; + } + + RemoveEntityByContext(AddrFile); + + ExFreePoolWithTag(Object, ADDR_FILE_TAG); } @@ -200,6 +248,7 @@ NTSTATUS FileOpenAddress( RtlZeroMemory(AddrFile, sizeof(ADDRESS_FILE)); + AddrFile->RefCount = 1; AddrFile->Free = AddrFileFree; /* Set our default TTL */ @@ -321,64 +370,24 @@ NTSTATUS FileOpenAddress( NTSTATUS FileCloseAddress( PTDI_REQUEST Request) { - PADDRESS_FILE AddrFile; - NTSTATUS Status = STATUS_SUCCESS; + PADDRESS_FILE AddrFile = Request->Handle.AddressHandle; KIRQL OldIrql; - PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; - PDATAGRAM_SEND_REQUEST SendRequest; - PLIST_ENTRY CurrentEntry; - AddrFile = Request->Handle.AddressHandle; + if (!Request->Handle.AddressHandle) return STATUS_INVALID_PARAMETER; - TI_DbgPrint(MID_TRACE, ("Called.\n")); + LockObject(AddrFile, &OldIrql); + /* We have to close this connection because we started it */ + if( AddrFile->Listener ) + TCPClose( AddrFile->Listener ); + if( AddrFile->Connection ) + DereferenceObject( AddrFile->Connection ); + UnlockObject(AddrFile, OldIrql); - /* Remove address file from the global list */ - TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql); - RemoveEntryList(&AddrFile->ListEntry); - TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); - - /* FIXME: Kill TCP connections on this address file object */ - - /* Return pending requests with error */ - - TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile)); - - /* Go through pending receive request list and cancel them all */ - while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { - ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry); - (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0); - /* ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); FIXME: WTF? */ - } - - TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile)); - - /* Go through pending send request list and cancel them all */ - while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { - SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry); - (*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0); - ExFreePoolWithTag(SendRequest, DATAGRAM_SEND_TAG); - } - - /* Protocol specific handling */ - switch (AddrFile->Protocol) { - case IPPROTO_TCP: - TCPFreePort( AddrFile->Port ); - if( AddrFile->Listener ) - TCPClose( AddrFile->Listener ); - break; - - case IPPROTO_UDP: - UDPFreePort( AddrFile->Port ); - break; - } - - RemoveEntityByContext(AddrFile); - - (*AddrFile->Free)(AddrFile); + DereferenceObject(AddrFile); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); - return Status; + return STATUS_SUCCESS; } @@ -406,7 +415,7 @@ NTSTATUS FileOpenConnection( Status = TCPSocket( Connection, AF_INET, SOCK_STREAM, IPPROTO_TCP ); if( !NT_SUCCESS(Status) ) { - TCPFreeConnectionEndpoint( Connection ); + DereferenceObject( Connection ); return Status; } @@ -434,14 +443,17 @@ NTSTATUS FileCloseConnection( Connection = Request->Handle.ConnectionContext; + if (!Connection) return STATUS_INVALID_PARAMETER; + TCPClose( Connection ); + Request->Handle.ConnectionContext = NULL; + TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); return STATUS_SUCCESS; } - /* * FUNCTION: Opens a control channel file object * ARGUMENTS: @@ -475,6 +487,9 @@ NTSTATUS FileOpenControlChannel( /* Initialize spin lock that protects the address file object */ KeInitializeSpinLock(&ControlChannel->Lock); + ControlChannel->RefCount = 1; + ControlChannel->Free = ControlChannelFree; + /* Return address file object */ Request->Handle.ControlChannel = ControlChannel; @@ -493,13 +508,13 @@ NTSTATUS FileOpenControlChannel( NTSTATUS FileCloseControlChannel( PTDI_REQUEST Request) { - PCONTROL_CHANNEL ControlChannel = Request->Handle.ControlChannel; - NTSTATUS Status = STATUS_SUCCESS; + if (!Request->Handle.ControlChannel) return STATUS_INVALID_PARAMETER; + + DereferenceObject((PCONTROL_CHANNEL)Request->Handle.ControlChannel); - ExFreePoolWithTag(ControlChannel, CONTROL_CHANNEL_TAG); Request->Handle.ControlChannel = NULL; - return Status; + return STATUS_SUCCESS; } /* EOF */ diff --git a/lib/drivers/ip/transport/datagram/datagram.c b/lib/drivers/ip/transport/datagram/datagram.c index 3c92aa26002..bb608545fa3 100644 --- a/lib/drivers/ip/transport/datagram/datagram.c +++ b/lib/drivers/ip/transport/datagram/datagram.c @@ -22,7 +22,7 @@ BOOLEAN DGRemoveIRP( TI_DbgPrint(MAX_TRACE, ("Called (Cancel IRP %08x for file %08x).\n", Irp, AddrFile)); - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + LockObject(AddrFile, &OldIrql); for( ListEntry = AddrFile->ReceiveQueue.Flink; ListEntry != &AddrFile->ReceiveQueue; @@ -42,7 +42,7 @@ BOOLEAN DGRemoveIRP( } } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); TI_DbgPrint(MAX_TRACE, ("Done.\n")); @@ -83,7 +83,7 @@ VOID DGDeliverData( TI_DbgPrint(MAX_TRACE, ("Called.\n")); - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + LockObject(AddrFile, &OldIrql); if (AddrFile->Protocol == IPPROTO_UDP) { @@ -140,7 +140,8 @@ VOID DGDeliverData( &SrcAddress->Address.IPv4Address, sizeof(SrcAddress->Address.IPv4Address) ); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + ReferenceObject(AddrFile); + UnlockObject(AddrFile, OldIrql); /* Complete the receive request */ if (Current->BufferSize < DataSize) @@ -148,11 +149,12 @@ VOID DGDeliverData( else Current->Complete(Current->Context, STATUS_SUCCESS, DataSize); - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + LockObject(AddrFile, &OldIrql); + DereferenceObject(AddrFile); } } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); } else if (AddrFile->RegisteredReceiveDatagramHandler) { @@ -172,7 +174,8 @@ VOID DGDeliverData( SourceAddress = SrcAddress->Address.IPv6Address; } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + ReferenceObject(AddrFile); + UnlockObject(AddrFile, OldIrql); Status = (*ReceiveHandler)(HandlerContext, AddressLength, @@ -185,10 +188,12 @@ VOID DGDeliverData( &BytesTaken, DataBuffer, NULL); + + DereferenceObject(AddrFile); } else { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n")); } @@ -238,7 +243,7 @@ NTSTATUS DGReceiveDatagram( TI_DbgPrint(MAX_TRACE, ("Called.\n")); - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + LockObject(AddrFile, &OldIrql); ReceiveRequest = ExAllocatePoolWithTag(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST), DATAGRAM_RECV_TAG); @@ -256,7 +261,7 @@ NTSTATUS DGReceiveDatagram( if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return Status; } } @@ -284,13 +289,13 @@ NTSTATUS DGReceiveDatagram( TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest)); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return STATUS_PENDING; } else { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); Status = STATUS_INSUFFICIENT_RESOURCES; } diff --git a/lib/drivers/ip/transport/rawip/rawip.c b/lib/drivers/ip/transport/rawip/rawip.c index 44c6465ca75..288097b4d79 100644 --- a/lib/drivers/ip/transport/rawip/rawip.c +++ b/lib/drivers/ip/transport/rawip/rawip.c @@ -197,7 +197,7 @@ NTSTATUS RawIPSendDatagram( PNEIGHBOR_CACHE_ENTRY NCE; KIRQL OldIrql; - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + LockObject(AddrFile, &OldIrql); TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -212,7 +212,7 @@ NTSTATUS RawIPSendDatagram( break; default: - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return STATUS_UNSUCCESSFUL; } @@ -226,7 +226,7 @@ NTSTATUS RawIPSendDatagram( * interface we're sending over */ if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return STATUS_NETWORK_UNREACHABLE; } @@ -235,7 +235,7 @@ NTSTATUS RawIPSendDatagram( else { if(!(NCE = NBLocateNeighbor( &LocalAddress ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return STATUS_INVALID_PARAMETER; } } @@ -251,7 +251,7 @@ NTSTATUS RawIPSendDatagram( if( !NT_SUCCESS(Status) ) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return Status; } @@ -259,14 +259,14 @@ NTSTATUS RawIPSendDatagram( if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); FreeNdisPacket(Packet.NdisPacket); return Status; } TI_DbgPrint(MID_TRACE,("Leaving\n")); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return STATUS_SUCCESS; } diff --git a/lib/drivers/ip/transport/tcp/accept.c b/lib/drivers/ip/transport/tcp/accept.c index 059d109af73..643f59da208 100644 --- a/lib/drivers/ip/transport/tcp/accept.c +++ b/lib/drivers/ip/transport/tcp/accept.c @@ -72,10 +72,9 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { KIRQL OldIrql; ASSERT(Connection); - ASSERT_KM_POINTER(Connection->SocketContext); ASSERT_KM_POINTER(Connection->AddressFile); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + LockObject(Connection, &OldIrql); TI_DbgPrint(DEBUG_TCP,("TCPListen started\n")); @@ -97,7 +96,7 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { if (NT_SUCCESS(Status)) Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status)); @@ -111,7 +110,7 @@ BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, KIRQL OldIrql; BOOLEAN Found = FALSE; - KeAcquireSpinLock(&Listener->Lock, &OldIrql); + LockObject(Listener, &OldIrql); ListEntry = Listener->ListenRequest.Flink; while ( ListEntry != &Listener->ListenRequest ) { @@ -127,7 +126,7 @@ BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, ListEntry = ListEntry->Flink; } - KeReleaseSpinLock(&Listener->Lock, OldIrql); + UnlockObject(Listener, OldIrql); return Found; } @@ -144,27 +143,27 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request, TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n")); - KeAcquireSpinLock(&Listener->Lock, &OldIrql); + LockObject(Listener, &OldIrql); Status = TCPServiceListeningSocket( Listener, Connection, (PTDI_REQUEST_KERNEL)Request ); - KeReleaseSpinLock(&Listener->Lock, OldIrql); - if( Status == STATUS_PENDING ) { Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); if( Bucket ) { + ReferenceObject(Connection); Bucket->AssociatedEndpoint = Connection; Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; - ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, - &Listener->Lock ); + InsertTailList( &Listener->ListenRequest, &Bucket->Entry ); } else Status = STATUS_NO_MEMORY; } + UnlockObject(Listener, OldIrql); + TI_DbgPrint(DEBUG_TCP,("TCPAccept finished %x\n", Status)); return Status; } diff --git a/lib/drivers/ip/transport/tcp/event.c b/lib/drivers/ip/transport/tcp/event.c index 155a16ee078..5146325a620 100644 --- a/lib/drivers/ip/transport/tcp/event.c +++ b/lib/drivers/ip/transport/tcp/event.c @@ -24,26 +24,17 @@ int TCPSocketState(void *ClientData, NewState & SEL_ACCEPT ? 'A' : 'a', NewState & SEL_WRITE ? 'W' : 'w')); - if (!Connection) - { - return 0; - } - - if (ClientInfo.Unlocked) - KeAcquireSpinLockAtDpcLevel(&Connection->Lock); + ASSERT(Connection); TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n", NewState, Connection, Connection->SignalState ^ NewState, NewState)); - Connection->SignalState |= NewState; + Connection->SignalState = NewState; HandleSignalledConnection(Connection); - if (ClientInfo.Unlocked) - KeReleaseSpinLockFromDpcLevel(&Connection->Lock); - return 0; } @@ -76,8 +67,8 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { return OSK_EINVAL; } - if(!(NCE = NBLocateNeighbor( &LocalAddress ))) { - TI_DbgPrint(MIN_TRACE,("Interface doesn't exist! %s\n", A2S(&LocalAddress))); + if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { + TI_DbgPrint(MIN_TRACE,("Unable to get route to %s\n", A2S(&RemoteAddress))); return OSK_EADDRNOTAVAIL; } diff --git a/lib/drivers/ip/transport/tcp/tcp.c b/lib/drivers/ip/transport/tcp/tcp.c index 0d1710adb6c..97d051916eb 100644 --- a/lib/drivers/ip/transport/tcp/tcp.c +++ b/lib/drivers/ip/transport/tcp/tcp.c @@ -18,28 +18,6 @@ static NPAGED_LOOKASIDE_LIST TCPSegmentList; PORT_SET TCPPorts; CLIENT_DATA ClientInfo; -static VOID -ProcessCompletions(PCONNECTION_ENDPOINT Connection) -{ - PLIST_ENTRY CurrentEntry; - PTDI_BUCKET Bucket; - PTCP_COMPLETION_ROUTINE Complete; - - while ((CurrentEntry = ExInterlockedRemoveHeadList(&Connection->CompletionQueue, - &Connection->Lock))) - { - Bucket = CONTAINING_RECORD(CurrentEntry, TDI_BUCKET, Entry); - Complete = Bucket->Request.RequestNotifyObject; - - Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information); - - ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG); - } - - if (!Connection->SocketContext) - TCPFreeConnectionEndpoint(Connection); -} - VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) { PTDI_BUCKET Bucket; @@ -48,11 +26,16 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) PIRP Irp; PMDL Mdl; ULONG SocketError = 0; + KIRQL OldIrql; + PTCP_COMPLETION_ROUTINE Complete; + + if (ClientInfo.Unlocked) + LockObjectAtDpcLevel(Connection); TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", Connection, Connection->SocketContext)); - if( !Connection->SocketContext || Connection->SignalState & SEL_FIN ) { + if( Connection->SignalState & SEL_FIN ) { TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); /* If OskitTCP initiated the disconnect, try to read the socket error that occurred */ @@ -95,6 +78,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) Bucket->Status = SocketError; Bucket->Information = 0; + DereferenceObject(Bucket->AssociatedEndpoint); InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } @@ -111,7 +95,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } - Connection->SignalState = 0; + Connection->SignalState = SEL_FIN; } /* Things that can happen when we try the initial connection */ @@ -162,6 +146,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) } else { Bucket->Status = Status; Bucket->Information = 0; + DereferenceObject(Bucket->AssociatedEndpoint); InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } @@ -278,39 +263,55 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) } } } + + ReferenceObject(Connection); + if (ClientInfo.Unlocked) + { + UnlockObjectFromDpcLevel(Connection); + KeReleaseSpinLock(&ClientInfo.Lock, ClientInfo.OldIrql); + } + else + { + UnlockObject(Connection, Connection->OldIrql); + } + + while ((Entry = ExInterlockedRemoveHeadList(&Connection->CompletionQueue, + &Connection->Lock))) + { + Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry); + Complete = Bucket->Request.RequestNotifyObject; + + Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information); + + ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG); + } + + if (!ClientInfo.Unlocked) + { + LockObject(Connection, &OldIrql); + } + else + { + KeAcquireSpinLock(&ClientInfo.Lock, &ClientInfo.OldIrql); + } + DereferenceObject(Connection); + + /* If the socket is dead, remove the reference we added for oskit */ + if (Connection->SignalState & SEL_FIN) + DereferenceObject(Connection); } -static -VOID DrainSignals(VOID) { - PCONNECTION_ENDPOINT Connection; - PLIST_ENTRY CurrentEntry; +VOID ConnectionFree(PVOID Object) { + PCONNECTION_ENDPOINT Connection = Object; KIRQL OldIrql; - KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); - CurrentEntry = ConnectionEndpointListHead.Flink; - while (CurrentEntry != &ConnectionEndpointListHead) - { - Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT, - ListEntry ); - CurrentEntry = CurrentEntry->Flink; - KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); - - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - if (Connection->SocketContext) - { - HandleSignalledConnection(Connection); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n")); - ProcessCompletions(Connection); - } - else - { - KeReleaseSpinLock(&Connection->Lock, OldIrql); - } + TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); + RemoveEntryList(&Connection->ListEntry); + TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); - KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); - } - KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); + ExFreePoolWithTag( Connection, CONN_ENDPT_TAG ); } PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { @@ -335,6 +336,10 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { /* Save client context pointer */ Connection->ClientContext = ClientContext; + /* Add an extra reference for oskit */ + Connection->RefCount = 2; + Connection->Free = ConnectionFree; + /* Add connection endpoint to global list */ ExInterlockedInsertTailList(&ConnectionEndpointListHead, &Connection->ListEntry, @@ -343,24 +348,12 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { return Connection; } -VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) { - KIRQL OldIrql; - - TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n")); - - TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); - RemoveEntryList(&Connection->ListEntry); - TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); - - ExFreePoolWithTag( Connection, CONN_ENDPT_TAG ); -} - NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, UINT Family, UINT Type, UINT Proto ) { NTSTATUS Status; KIRQL OldIrql; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + LockObject(Connection, &OldIrql); TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, " "Proto %d\n", @@ -377,7 +370,7 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n", Connection->SocketContext)); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); return Status; } @@ -399,6 +392,7 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) KeAcquireSpinLock(&ClientInfo.Lock, &OldIrql); ClientInfo.Unlocked = TRUE; + ClientInfo.OldIrql = OldIrql; OskitTCPReceiveDatagram( IPPacket->Header, IPPacket->TotalSize, @@ -477,7 +471,6 @@ TimerThread(PVOID Context) } TimerOskitTCP( Next == NextFast, Next == NextSlow ); - DrainSignals(); Current = Next; if (10 <= Current) { @@ -640,11 +633,11 @@ NTSTATUS TCPConnect AddressToConnect.sin_family = AF_INET; AddressToBind = AddressToConnect; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + LockObject(Connection, &OldIrql); if (!Connection->AddressFile) { - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); return STATUS_INVALID_PARAMETER; } @@ -652,7 +645,7 @@ NTSTATUS TCPConnect { if (!(NCE = RouteGetRouteToDestination(&RemoteAddress))) { - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); return STATUS_NETWORK_UNREACHABLE; } @@ -679,26 +672,24 @@ NTSTATUS TCPConnect &AddressToConnect, sizeof(AddressToConnect) ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - if (Status == STATUS_PENDING) { 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; - ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, - &Connection->Lock ); + InsertTailList( &Connection->ConnectRequest, &Bucket->Entry ); } - } else { - KeReleaseSpinLock(&Connection->Lock, OldIrql); } + UnlockObject(Connection, OldIrql); + return Status; } @@ -714,7 +705,7 @@ NTSTATUS TCPDisconnect TI_DbgPrint(DEBUG_TCP,("started\n")); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + LockObject(Connection, &OldIrql); if (Flags & TDI_DISCONNECT_RELEASE) Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext)); @@ -722,7 +713,7 @@ NTSTATUS TCPDisconnect if ((Flags & TDI_DISCONNECT_ABORT) || !Flags) Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD)); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status)); @@ -730,24 +721,36 @@ NTSTATUS TCPDisconnect } NTSTATUS TCPClose -( PCONNECTION_ENDPOINT Connection ) { - NTSTATUS Status; +( PCONNECTION_ENDPOINT Connection ) +{ KIRQL OldIrql; + NTSTATUS Status; PVOID Socket; - TI_DbgPrint(DEBUG_TCP,("TCPClose started\n")); - - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + /* We don't rely on SocketContext == NULL for socket + * closure anymore but we still need it to determine + * if we caused the closure + */ Socket = Connection->SocketContext; Connection->SocketContext = NULL; + + /* We need to close here otherwise oskit will never indicate + * SEL_FIN and we will never fully close the connection + */ + LockObject(Connection, &OldIrql); Status = TCPTranslateError( OskitTCPClose( Socket ) ); + UnlockObject(Connection, OldIrql); + if (!NT_SUCCESS(Status)) { Connection->SocketContext = Socket; + return Status; } - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status)); + if (Connection->AddressFile) + DereferenceObject(Connection->AddressFile); + + DereferenceObject(Connection); return Status; } @@ -773,9 +776,7 @@ NTSTATUS TCPReceiveData TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen)); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - - ASSERT_KM_POINTER(Connection->SocketContext); + LockObject(Connection, &OldIrql); Status = TCPTranslateError ( OskitTCPRecv @@ -785,8 +786,6 @@ NTSTATUS TCPReceiveData &Received, ReceiveFlags ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received)); /* Keep this request around ... there was no data yet */ @@ -795,6 +794,7 @@ NTSTATUS TCPReceiveData Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); if( !Bucket ) { TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n")); + UnlockObject(Connection, OldIrql); return STATUS_NO_MEMORY; } @@ -802,14 +802,15 @@ NTSTATUS TCPReceiveData Bucket->Request.RequestContext = Context; *BytesReceived = 0; - ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, - &Connection->Lock ); + InsertTailList( &Connection->ReceiveRequest, &Bucket->Entry ); TI_DbgPrint(DEBUG_TCP,("Queued read irp\n")); } else { TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received)); *BytesReceived = Received; } + UnlockObject(Connection, OldIrql); + TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status)); return Status; @@ -828,13 +829,11 @@ NTSTATUS TCPSendData PTDI_BUCKET Bucket; KIRQL OldIrql; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + LockObject(Connection, &OldIrql); TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n", SendLength, Connection->SocketContext)); - ASSERT_KM_POINTER(Connection->SocketContext); - TI_DbgPrint(DEBUG_TCP,("Connection = %x\n", Connection)); TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n", Connection->SocketContext)); @@ -844,8 +843,6 @@ NTSTATUS TCPSendData (OSK_PCHAR)BufferData, SendLength, &Sent, 0 ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(DEBUG_TCP,("OskitTCPSend: %x, %d\n", Status, Sent)); /* Keep this request around ... there was no data yet */ @@ -853,6 +850,7 @@ NTSTATUS TCPSendData /* Freed in TCPSocketState */ Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); if( !Bucket ) { + UnlockObject(Connection, OldIrql); TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n")); return STATUS_NO_MEMORY; } @@ -861,14 +859,15 @@ NTSTATUS TCPSendData Bucket->Request.RequestContext = Context; *BytesSent = 0; - ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, - &Connection->Lock ); + InsertTailList( &Connection->SendRequest, &Bucket->Entry ); TI_DbgPrint(DEBUG_TCP,("Queued write irp\n")); } else { TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent)); *BytesSent = Sent; } - + + UnlockObject(Connection, OldIrql); + TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status)); return Status; @@ -899,13 +898,13 @@ NTSTATUS TCPGetSockAddress NTSTATUS Status; KIRQL OldIrql; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + LockObject(Connection, &OldIrql); Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext, &LocalAddress, &LocalPort, &RemoteAddress, &RemotePort)); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + UnlockObject(Connection, OldIrql); if (!NT_SUCCESS(Status)) return Status; @@ -932,7 +931,7 @@ BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { ListHead[2] = &Endpoint->ConnectRequest; ListHead[3] = &Endpoint->ListenRequest; - TcpipAcquireSpinLock( &Endpoint->Lock, &OldIrql ); + LockObject(Endpoint, &OldIrql); for( i = 0; i < 4; i++ ) { @@ -951,7 +950,7 @@ BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { } } - TcpipReleaseSpinLock( &Endpoint->Lock, OldIrql ); + UnlockObject(Endpoint, OldIrql); return Found; } diff --git a/lib/drivers/ip/transport/udp/udp.c b/lib/drivers/ip/transport/udp/udp.c index 510e8827cc8..2e86c2bded0 100644 --- a/lib/drivers/ip/transport/udp/udp.c +++ b/lib/drivers/ip/transport/udp/udp.c @@ -174,7 +174,7 @@ NTSTATUS UDPSendDatagram( PNEIGHBOR_CACHE_ENTRY NCE; KIRQL OldIrql; - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + LockObject(AddrFile, &OldIrql); TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -189,7 +189,7 @@ NTSTATUS UDPSendDatagram( break; default: - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return STATUS_UNSUCCESSFUL; } @@ -201,7 +201,7 @@ NTSTATUS UDPSendDatagram( * interface we're sending over */ if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return STATUS_NETWORK_UNREACHABLE; } @@ -210,7 +210,7 @@ NTSTATUS UDPSendDatagram( else { if(!(NCE = NBLocateNeighbor( &LocalAddress ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return STATUS_INVALID_PARAMETER; } } @@ -226,18 +226,18 @@ NTSTATUS UDPSendDatagram( if( !NT_SUCCESS(Status) ) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return Status; } if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); FreeNdisPacket(Packet.NdisPacket); return Status; } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + UnlockObject(AddrFile, OldIrql); return STATUS_SUCCESS; } diff --git a/lib/drivers/oskittcp/oskittcp/interface.c b/lib/drivers/oskittcp/oskittcp/interface.c index a925d330434..315f6ff96aa 100644 --- a/lib/drivers/oskittcp/oskittcp/interface.c +++ b/lib/drivers/oskittcp/oskittcp/interface.c @@ -285,16 +285,11 @@ int OskitTCPShutdown( void *socket, int disconn_type ) { int OskitTCPClose( void *socket ) { int error; - struct socket *so = socket; if (!socket) return OSK_ESHUTDOWN; OSKLock(); - /* We have to remove the socket context here otherwise we end up - * back in HandleSignalledConnection with a freed connection context - */ - so->so_connection = NULL; error = soclose( socket ); OSKUnlock(); diff --git a/lib/drivers/oskittcp/oskittcp/sleep.c b/lib/drivers/oskittcp/oskittcp/sleep.c index a00b2770986..5cfcdb4af56 100644 --- a/lib/drivers/oskittcp/oskittcp/sleep.c +++ b/lib/drivers/oskittcp/oskittcp/sleep.c @@ -39,8 +39,8 @@ void wakeup( struct socket *so, void *token ) { OS_DbgPrint(OSK_MID_TRACE,("Socket writeable\n")); flags |= SEL_WRITE; } - if( so->so_state & SS_CANTRCVMORE ) { - OS_DbgPrint(OSK_MID_TRACE,("Socket can't be read any longer\n")); + if (!so->so_pcb) { + OS_DbgPrint(OSK_MID_TRACE,("Socket dying\n")); flags |= SEL_FIN; }