https://git.reactos.org/?p=reactos.git;a=commitdiff;h=27fcfe66a2a7a8beb4b29…
commit 27fcfe66a2a7a8beb4b29eee18bb251a3a9aae22
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Fri May 21 09:36:27 2021 +0200
Commit: Jérôme Gardou <zefklop(a)users.noreply.github.com>
CommitDate: Mon Jun 21 11:42:01 2021 +0200
[TCPIP][IP] Use an ERESOURCE as mutex for address files & connection end points
Spinlocks are not reentrant (and this is done a lot), using them forces us to have
an horrible hack in the kernel, which unschedules threads which are at DISPATCH_LEVEL
thus allowing another thread to take ownership of the spinlock while the unscheduled
thread should already hold it.
CORE-6473
---
drivers/network/tcpip/include/tcp.h | 6 +-
drivers/network/tcpip/include/titypes.h | 52 ++----
drivers/network/tcpip/tcpip/ainfo.c | 18 +--
drivers/network/tcpip/tcpip/dispatch.c | 33 ++--
drivers/network/tcpip/tcpip/fileobjs.c | 32 ++--
drivers/network/tcpip/tcpip/icmp.c | 15 +-
sdk/lib/drivers/ip/transport/datagram/datagram.c | 27 ++--
sdk/lib/drivers/ip/transport/rawip/rawip.c | 11 +-
sdk/lib/drivers/ip/transport/tcp/accept.c | 15 +-
sdk/lib/drivers/ip/transport/tcp/event.c | 194 ++++++++--------------
sdk/lib/drivers/ip/transport/tcp/tcp.c | 197 ++++++++++++++---------
sdk/lib/drivers/ip/transport/udp/udp.c | 11 +-
sdk/lib/drivers/lwip/src/include/rosip.h | 4 +
sdk/lib/drivers/lwip/src/rostcp.c | 40 ++++-
14 files changed, 319 insertions(+), 336 deletions(-)
diff --git a/drivers/network/tcpip/include/tcp.h b/drivers/network/tcpip/include/tcp.h
index 6bb8280d5a1..65a5d11b355 100644
--- a/drivers/network/tcpip/include/tcp.h
+++ b/drivers/network/tcpip/include/tcp.h
@@ -201,13 +201,13 @@ VOID
FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status);
VOID
-FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked);
+FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status);
VOID
-FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked);
+FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status);
VOID
-FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked);
+FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status);
VOID
FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status);
diff --git a/drivers/network/tcpip/include/titypes.h
b/drivers/network/tcpip/include/titypes.h
index 14541a24a65..0290c2dd54d 100644
--- a/drivers/network/tcpip/include/titypes.h
+++ b/drivers/network/tcpip/include/titypes.h
@@ -29,44 +29,26 @@
}
/*
- * VOID LockObject(PVOID Object, PKIRQL OldIrql)
+ * VOID LockObject(PVOID Object)
*/
-#define LockObject(Object, Irql) \
-{ \
- ReferenceObject(Object); \
- KeAcquireSpinLock(&((Object)->Lock), Irql); \
- memcpy(&(Object)->OldIrql, Irql, sizeof(KIRQL)); \
-}
-
-/*
- * VOID LockObjectAtDpcLevel(PVOID Object)
- */
-#define LockObjectAtDpcLevel(Object) \
-{ \
- ReferenceObject(Object); \
- KeAcquireSpinLockAtDpcLevel(&((Object)->Lock)); \
- (Object)->OldIrql = DISPATCH_LEVEL; \
-}
-
-/*
- * VOID UnlockObject(PVOID Object, KIRQL OldIrql)
- */
-#define UnlockObject(Object, OldIrql) \
-{ \
- KeReleaseSpinLock(&((Object)->Lock), OldIrql); \
- DereferenceObject(Object); \
-}
+#define LockObject(Object) do \
+{ \
+ ReferenceObject(Object); \
+ KeEnterCriticalRegion(); \
+ ExAcquireResourceExclusiveLite(&(Object)->Resource, TRUE); \
+} while(0)
/*
- * VOID UnlockObjectFromDpcLevel(PVOID Object)
+ * VOID UnlockObject(PVOID Object)
*/
-#define UnlockObjectFromDpcLevel(Object) \
+#define UnlockObject(Object) do \
{ \
- KeReleaseSpinLockFromDpcLevel(&((Object)->Lock)); \
+ ExReleaseResourceLite(&(Object)->Resource); \
+ KeLeaveCriticalRegion(); \
DereferenceObject(Object); \
-}
-
+} while(0)
+#define ASSERT_TCPIP_OBJECT_LOCKED(Object)
ASSERT(ExIsResourceAcquiredExclusiveLite(&(Object)->Resource))
#include <ip.h>
@@ -131,8 +113,7 @@ typedef struct _ADDRESS_FILE {
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 manipulate this structure */
- KIRQL OldIrql; /* Currently not used */
+ ERESOURCE Resource; /* Resource to manipulate this structure */
IP_ADDRESS Address; /* Address of this address file */
USHORT Family; /* Address family */
USHORT Protocol; /* Protocol number */
@@ -142,7 +123,6 @@ typedef struct _ADDRESS_FILE {
UINT DF; /* Don't fragment */
UINT BCast; /* Receive broadcast packets */
UINT HeaderIncl; /* Include header in RawIP packets */
- WORK_QUEUE_ITEM WorkItem; /* Work queue item handle */
DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine for delete request */
PVOID Context; /* Delete request context */
DATAGRAM_SEND_ROUTINE Send; /* Routine to send a datagram */
@@ -262,8 +242,7 @@ 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 */
+ ERESOURCE Resource; /* The lock protecting this structure */
PVOID ClientContext; /* Pointer to client context information */
PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */
@@ -279,6 +258,7 @@ typedef struct _CONNECTION_ENDPOINT {
/* Disconnect Timer */
KTIMER DisconnectTimer;
KDPC DisconnectDpc;
+ PIO_WORKITEM DisconnectWorkItem;
/* Socket state */
BOOLEAN SendShutdown;
diff --git a/drivers/network/tcpip/tcpip/ainfo.c b/drivers/network/tcpip/tcpip/ainfo.c
index bba0affc1bc..1553149dc1e 100644
--- a/drivers/network/tcpip/tcpip/ainfo.c
+++ b/drivers/network/tcpip/tcpip/ainfo.c
@@ -13,17 +13,15 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID,
PVOID Buffer,
UINT BufferSize)
{
- KIRQL OldIrql;
-
switch (ID->toi_id)
{
case AO_OPTION_TTL:
if (BufferSize < sizeof(UINT))
return TDI_INVALID_PARAMETER;
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
AddrFile->TTL = *((PUCHAR)Buffer);
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return TDI_SUCCESS;
@@ -31,9 +29,9 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID,
if (BufferSize < sizeof(UINT))
return TDI_INVALID_PARAMETER;
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
AddrFile->DF = *((PUINT)Buffer);
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return TDI_SUCCESS;
@@ -41,9 +39,9 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID,
if (BufferSize < sizeof(UINT))
return TDI_INVALID_PARAMETER;
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
AddrFile->BCast = *((PUINT)Buffer);
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return TDI_SUCCESS;
@@ -51,9 +49,9 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID,
if (BufferSize < sizeof(UINT))
return TDI_INVALID_PARAMETER;
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
AddrFile->HeaderIncl = *((PUINT)Buffer);
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return TDI_SUCCESS;
diff --git a/drivers/network/tcpip/tcpip/dispatch.c
b/drivers/network/tcpip/tcpip/dispatch.c
index da2a00ba5bd..375c0bc5fd5 100644
--- a/drivers/network/tcpip/tcpip/dispatch.c
+++ b/drivers/network/tcpip/tcpip/dispatch.c
@@ -284,7 +284,6 @@ NTSTATUS DispTdiAssociateAddress(
PFILE_OBJECT FileObject;
PADDRESS_FILE AddrFile = NULL;
NTSTATUS Status;
- KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@@ -319,18 +318,18 @@ NTSTATUS DispTdiAssociateAddress(
return STATUS_INVALID_PARAMETER;
}
- LockObject(Connection, &OldIrql);
+ LockObject(Connection);
if (Connection->AddressFile) {
ObDereferenceObject(FileObject);
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
TI_DbgPrint(MID_TRACE, ("An address file is already associated.\n"));
return STATUS_INVALID_PARAMETER;
}
if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
ObDereferenceObject(FileObject);
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n",
FileObject->FsContext2));
return STATUS_INVALID_PARAMETER;
@@ -341,20 +340,20 @@ NTSTATUS DispTdiAssociateAddress(
TranContext = FileObject->FsContext;
if (!TranContext) {
ObDereferenceObject(FileObject);
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_PARAMETER;
}
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
if (!AddrFile) {
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
ObDereferenceObject(FileObject);
TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
return STATUS_INVALID_PARAMETER;
}
- LockObjectAtDpcLevel(AddrFile);
+ LockObject(AddrFile);
ReferenceObject(AddrFile);
Connection->AddressFile = AddrFile;
@@ -373,8 +372,8 @@ NTSTATUS DispTdiAssociateAddress(
ObDereferenceObject(FileObject);
- UnlockObjectFromDpcLevel(AddrFile);
- UnlockObject(Connection, OldIrql);
+ UnlockObject(AddrFile);
+ UnlockObject(Connection);
return STATUS_SUCCESS;
}
@@ -563,7 +562,6 @@ NTSTATUS DispTdiListen(
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status = STATUS_SUCCESS;
- KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@@ -596,17 +594,17 @@ NTSTATUS DispTdiListen(
Irp,
(PDRIVER_CANCEL)DispCancelListenRequest);
- LockObject(Connection, &OldIrql);
+ LockObject(Connection);
if (Connection->AddressFile == NULL)
{
TI_DbgPrint(MID_TRACE, ("No associated address file\n"));
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
Status = STATUS_INVALID_PARAMETER;
goto done;
}
- LockObjectAtDpcLevel(Connection->AddressFile);
+ LockObject(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
@@ -647,8 +645,8 @@ NTSTATUS DispTdiListen(
Irp );
}
- UnlockObjectFromDpcLevel(Connection->AddressFile);
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection->AddressFile);
+ UnlockObject(Connection);
done:
if (Status != STATUS_PENDING) {
@@ -1116,7 +1114,6 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
PIO_STACK_LOCATION IrpSp;
PADDRESS_FILE AddrFile;
NTSTATUS Status;
- KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@@ -1139,7 +1136,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
Status = STATUS_SUCCESS;
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
/* Set the event handler. if an event handler is associated with
a specific event, it's flag (RegisteredXxxHandler) is TRUE.
@@ -1260,7 +1257,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
Status = STATUS_INVALID_PARAMETER;
}
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return Status;
}
diff --git a/drivers/network/tcpip/tcpip/fileobjs.c
b/drivers/network/tcpip/tcpip/fileobjs.c
index 6854acc7da7..d926abed97e 100644
--- a/drivers/network/tcpip/tcpip/fileobjs.c
+++ b/drivers/network/tcpip/tcpip/fileobjs.c
@@ -310,7 +310,7 @@ VOID AddrFileFree(
PADDRESS_FILE AddrFile = Object;
KIRQL OldIrql;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
- PDATAGRAM_SEND_REQUEST SendRequest;
+ // PDATAGRAM_SEND_REQUEST SendRequest; See WTF below
PLIST_ENTRY CurrentEntry;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
@@ -330,20 +330,26 @@ VOID AddrFileFree(
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))) {
+ while (!IsListEmpty(&AddrFile->ReceiveQueue))
+ {
+ CurrentEntry = RemoveHeadList(&AddrFile->ReceiveQueue);
ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST,
ListEntry);
(*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0);
- /* ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); FIXME: WTF? */
+ ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG);
}
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at
(0x%X).\n", AddrFile));
+#if 0 /* Biggest WTF. All of this was taken care of above as DATAGRAM_RECEIVE_REQUEST.
*/
/* Go through pending send request list and cancel them all */
- while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue,
&AddrFile->Lock))) {
+ while (!IsListEmpty(&AddrFile->ReceiveQueue))
+ {
+ CurrentEntry = RemoveHeadList(&AddrFile->ReceiveQueue);
SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
(*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0);
ExFreePoolWithTag(SendRequest, DATAGRAM_SEND_TAG);
}
+#endif
/* Protocol specific handling */
switch (AddrFile->Protocol) {
@@ -361,6 +367,8 @@ VOID AddrFileFree(
RemoveEntityByContext(AddrFile);
+ ExDeleteResourceLite(&AddrFile->Resource);
+
ExFreePoolWithTag(Object, ADDR_FILE_TAG);
}
@@ -553,7 +561,7 @@ NTSTATUS FileOpenAddress(
InitializeListHead(&AddrFile->TransmitQueue);
/* Initialize spin lock that protects the address file object */
- KeInitializeSpinLock(&AddrFile->Lock);
+ ExInitializeResourceLite(&AddrFile->Resource);
/* Return address file object */
Request->Handle.AddressHandle = AddrFile;
@@ -581,27 +589,27 @@ NTSTATUS FileCloseAddress(
PTDI_REQUEST Request)
{
PADDRESS_FILE AddrFile = Request->Handle.AddressHandle;
- KIRQL OldIrql;
+ PCONNECTION_ENDPOINT Listener;
if (!Request->Handle.AddressHandle) return STATUS_INVALID_PARAMETER;
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
if (InterlockedDecrement(&AddrFile->Sharers) != 0)
{
/* Still other guys have open handles to this, so keep it around */
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return STATUS_SUCCESS;
}
/* We have to close this listener because we started it */
- if( AddrFile->Listener )
+ Listener = AddrFile->Listener;
+ UnlockObject(AddrFile);
+ if( Listener )
{
- TCPClose( AddrFile->Listener );
+ TCPClose( Listener );
}
- UnlockObject(AddrFile, OldIrql);
-
DereferenceObject(AddrFile);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
diff --git a/drivers/network/tcpip/tcpip/icmp.c b/drivers/network/tcpip/tcpip/icmp.c
index 7603e2551a5..67d77c14693 100644
--- a/drivers/network/tcpip/tcpip/icmp.c
+++ b/drivers/network/tcpip/tcpip/icmp.c
@@ -74,11 +74,9 @@ VOID
ClearReceiveHandler(
_In_ PADDRESS_FILE AddrFile)
{
- KIRQL OldIrql;
-
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
AddrFile->RegisteredReceiveDatagramHandler = FALSE;
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
}
IO_WORKITEM_ROUTINE EndRequestHandler;
@@ -95,6 +93,8 @@ EndRequestHandler(
UINT32 nReplies;
KIRQL OldIrql;
+ ClearReceiveHandler((PADDRESS_FILE)Context->TdiRequest.Handle.AddressHandle);
+
KeWaitForSingleObject(&Context->DatagramProcessedEvent, Executive, KernelMode,
FALSE, NULL);
TI_DbgPrint(DEBUG_ICMP, ("Finishing request Context: %p\n", Context));
@@ -267,8 +267,6 @@ TimeoutHandler(
_In_opt_ PVOID SystemArgument2)
{
PICMP_PACKET_CONTEXT Context = (PICMP_PACKET_CONTEXT)_Context;
- PADDRESS_FILE AddrFile = (PADDRESS_FILE)Context->TdiRequest.Handle.AddressHandle;
- ClearReceiveHandler(AddrFile);
IoQueueWorkItem(Context->FinishWorker, &EndRequestHandler, DelayedWorkQueue,
_Context);
}
@@ -290,7 +288,6 @@ DispEchoRequest(
PUCHAR Buffer;
UINT16 RequestSize;
PICMP_PACKET_CONTEXT SendContext;
- KIRQL OldIrql;
LARGE_INTEGER RequestTimeout;
UINT8 SavedTtl;
@@ -390,14 +387,14 @@ DispEchoRequest(
RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, OutputBufferLength);
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
AddrFile->TTL = SavedTtl;
AddrFile->ReceiveDatagramHandlerContext = SendContext;
AddrFile->ReceiveDatagramHandler = ReceiveDatagram;
AddrFile->RegisteredReceiveDatagramHandler = TRUE;
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
Status = AddrFile->Send(AddrFile, &ConnectionInfo, (PCHAR)Buffer, RequestSize,
&DataUsed);
diff --git a/sdk/lib/drivers/ip/transport/datagram/datagram.c
b/sdk/lib/drivers/ip/transport/datagram/datagram.c
index 053a3020894..2840dc950a7 100644
--- a/sdk/lib/drivers/ip/transport/datagram/datagram.c
+++ b/sdk/lib/drivers/ip/transport/datagram/datagram.c
@@ -16,13 +16,12 @@ BOOLEAN DGRemoveIRP(
{
PLIST_ENTRY ListEntry;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
- KIRQL OldIrql;
BOOLEAN Found = FALSE;
TI_DbgPrint(MAX_TRACE, ("Called (Cancel IRP %08x for file %08x).\n",
Irp, AddrFile));
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
for( ListEntry = AddrFile->ReceiveQueue.Flink;
ListEntry != &AddrFile->ReceiveQueue;
@@ -42,7 +41,7 @@ BOOLEAN DGRemoveIRP(
}
}
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
TI_DbgPrint(MAX_TRACE, ("Done.\n"));
@@ -73,7 +72,6 @@ DGDeliverData(
* handler if it exists, otherwise we drop the packet.
*/
{
- KIRQL OldIrql;
LONG AddressLength;
PVOID SourceAddress;
ULONG BytesTaken;
@@ -82,7 +80,7 @@ DGDeliverData(
TI_DbgPrint(MIN_TRACE, ("Called.\n"));
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
if (AddrFile->Protocol == IPPROTO_UDP)
{
@@ -145,7 +143,7 @@ DGDeliverData(
SrcAddress->Address.IPv4Address, SrcPort));
ReferenceObject(AddrFile);
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
/* Complete the receive request */
if (Current->BufferSize < DataSize)
@@ -153,12 +151,12 @@ DGDeliverData(
else
Current->Complete(Current->Context, STATUS_SUCCESS, DataSize);
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
DereferenceObject(AddrFile);
}
}
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
}
else if (AddrFile->RegisteredReceiveDatagramHandler)
{
@@ -186,7 +184,7 @@ DGDeliverData(
}
ReferenceObject(AddrFile);
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
TI_DbgPrint(MIN_TRACE, ("OptionsSize %d DataSize: %u\n", OptionsSize,
DataSize));
@@ -209,7 +207,7 @@ DGDeliverData(
}
else
{
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
}
@@ -254,11 +252,10 @@ NTSTATUS DGReceiveDatagram(
{
NTSTATUS Status;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
- KIRQL OldIrql;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
ReceiveRequest = ExAllocatePoolWithTag(NonPagedPool,
sizeof(DATAGRAM_RECEIVE_REQUEST),
DATAGRAM_RECV_TAG);
@@ -276,7 +273,7 @@ NTSTATUS DGReceiveDatagram(
if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG);
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return Status;
}
}
@@ -304,13 +301,13 @@ NTSTATUS DGReceiveDatagram(
TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest));
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return STATUS_PENDING;
}
else
{
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
Status = STATUS_INSUFFICIENT_RESOURCES;
}
diff --git a/sdk/lib/drivers/ip/transport/rawip/rawip.c
b/sdk/lib/drivers/ip/transport/rawip/rawip.c
index 7e7fb22436a..cb32d4b02e3 100644
--- a/sdk/lib/drivers/ip/transport/rawip/rawip.c
+++ b/sdk/lib/drivers/ip/transport/rawip/rawip.c
@@ -191,9 +191,8 @@ NTSTATUS RawIPSendDatagram(
USHORT RemotePort;
NTSTATUS Status;
PNEIGHBOR_CACHE_ENTRY NCE;
- KIRQL OldIrql;
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
AddrFile, ConnInfo, BufferData, DataSize));
@@ -208,7 +207,7 @@ NTSTATUS RawIPSendDatagram(
break;
default:
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return STATUS_UNSUCCESSFUL;
}
@@ -222,7 +221,7 @@ NTSTATUS RawIPSendDatagram(
* interface we're sending over
*/
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return STATUS_NETWORK_UNREACHABLE;
}
@@ -231,7 +230,7 @@ NTSTATUS RawIPSendDatagram(
else
{
if(!(NCE = NBLocateNeighbor( &LocalAddress, NULL ))) {
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return STATUS_INVALID_PARAMETER;
}
}
@@ -245,7 +244,7 @@ NTSTATUS RawIPSendDatagram(
BufferData,
DataSize );
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
if( !NT_SUCCESS(Status) )
return Status;
diff --git a/sdk/lib/drivers/ip/transport/tcp/accept.c
b/sdk/lib/drivers/ip/transport/tcp/accept.c
index aab177a94ad..19b6d4644ca 100644
--- a/sdk/lib/drivers/ip/transport/tcp/accept.c
+++ b/sdk/lib/drivers/ip/transport/tcp/accept.c
@@ -48,12 +48,11 @@ NTSTATUS TCPListen(PCONNECTION_ENDPOINT Connection, UINT Backlog)
{
NTSTATUS Status = STATUS_SUCCESS;
struct ip_addr AddressToBind;
- KIRQL OldIrql;
TA_IP_ADDRESS LocalAddress;
ASSERT(Connection);
- LockObject(Connection, &OldIrql);
+ LockObject(Connection);
ASSERT_KM_POINTER(Connection->AddressFile);
@@ -93,7 +92,7 @@ NTSTATUS TCPListen(PCONNECTION_ENDPOINT Connection, UINT Backlog)
Status = STATUS_UNSUCCESSFUL;
}
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
TI_DbgPrint(DEBUG_TCP,("[IP, TCPListen] Leaving. Status = %x\n", Status));
@@ -106,10 +105,9 @@ BOOLEAN TCPAbortListenForSocket
{
PLIST_ENTRY ListEntry;
PTDI_BUCKET Bucket;
- KIRQL OldIrql;
BOOLEAN Found = FALSE;
- LockObject(Listener, &OldIrql);
+ LockObject(Listener);
ListEntry = Listener->ListenRequest.Flink;
while (ListEntry != &Listener->ListenRequest)
@@ -128,7 +126,7 @@ BOOLEAN TCPAbortListenForSocket
ListEntry = ListEntry->Flink;
}
- UnlockObject(Listener, OldIrql);
+ UnlockObject(Listener);
return Found;
}
@@ -141,9 +139,8 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request,
{
NTSTATUS Status;
PTDI_BUCKET Bucket;
- KIRQL OldIrql;
- LockObject(Listener, &OldIrql);
+ LockObject(Listener);
Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList);
@@ -160,7 +157,7 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request,
else
Status = STATUS_NO_MEMORY;
- UnlockObject(Listener, OldIrql);
+ UnlockObject(Listener);
return Status;
}
diff --git a/sdk/lib/drivers/ip/transport/tcp/event.c
b/sdk/lib/drivers/ip/transport/tcp/event.c
index 02613c2af17..9294815d3d1 100644
--- a/sdk/lib/drivers/ip/transport/tcp/event.c
+++ b/sdk/lib/drivers/ip/transport/tcp/event.c
@@ -50,125 +50,66 @@ CompleteBucket(PCONNECTION_ENDPOINT Connection, PTDI_BUCKET Bucket,
const BOOLEA
}
VOID
-FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked)
+FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
{
PTDI_BUCKET Bucket;
PLIST_ENTRY Entry;
- ReferenceObject(Connection);
+ ASSERT_TCPIP_OBJECT_LOCKED(Connection);
- if (interlocked)
+ while (!IsListEmpty(&Connection->ReceiveRequest))
{
- 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));
+ Entry = RemoveHeadList(&Connection->ReceiveRequest);
- Bucket->Status = Status;
- Bucket->Information = 0;
+ Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
- 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;
+ Bucket->Information = 0;
+ Bucket->Status = Status;
- CompleteBucket(Connection, Bucket, FALSE);
- }
+ CompleteBucket(Connection, Bucket, FALSE);
}
-
- DereferenceObject(Connection);
}
VOID
-FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked)
+FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
{
PTDI_BUCKET Bucket;
PLIST_ENTRY Entry;
- ReferenceObject(Connection);
+ ASSERT_TCPIP_OBJECT_LOCKED(Connection);
- if (interlocked)
+ while (!IsListEmpty(&Connection->SendRequest))
{
- 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);
+ Entry = RemoveHeadList(&Connection->SendRequest);
- Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+ Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
- Bucket->Information = 0;
- Bucket->Status = Status;
+ Bucket->Information = 0;
+ Bucket->Status = Status;
- CompleteBucket(Connection, Bucket, FALSE);
- }
+ CompleteBucket(Connection, Bucket, FALSE);
}
-
- DereferenceObject(Connection);
}
VOID
-FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN
interlocked)
+FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
{
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;
+ ASSERT_TCPIP_OBJECT_LOCKED(Connection);
- CompleteBucket(Connection, Bucket, FALSE);
- }
- }
- else
+ while (!IsListEmpty(&Connection->ShutdownRequest))
{
- while (!IsListEmpty(&Connection->ShutdownRequest))
- {
- Entry = RemoveHeadList(&Connection->ShutdownRequest);
+ Entry = RemoveHeadList(&Connection->ShutdownRequest);
- Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+ Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
- Bucket->Information = 0;
- Bucket->Status = Status;
+ Bucket->Information = 0;
+ Bucket->Status = Status;
- CompleteBucket(Connection, Bucket, FALSE);
- }
+ CompleteBucket(Connection, Bucket, FALSE);
}
-
- DereferenceObject(Connection);
}
VOID
@@ -177,10 +118,11 @@ FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS
Status)
PTDI_BUCKET Bucket;
PLIST_ENTRY Entry;
- ReferenceObject(Connection);
+ ASSERT_TCPIP_OBJECT_LOCKED(Connection);
- while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest,
&Connection->Lock)))
+ while (!IsListEmpty(&Connection->ConnectRequest))
{
+ Entry = RemoveHeadList(&Connection->ConnectRequest);
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Bucket->Status = Status;
@@ -188,8 +130,6 @@ FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS
Status)
CompleteBucket(Connection, Bucket, FALSE);
}
-
- DereferenceObject(Connection);
}
VOID
@@ -198,10 +138,11 @@ FlushListenQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS
Status)
PTDI_BUCKET Bucket;
PLIST_ENTRY Entry;
- ReferenceObject(Connection);
+ ASSERT_TCPIP_OBJECT_LOCKED(Connection);
- while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest,
&Connection->Lock)))
+ while (!IsListEmpty(&Connection->ListenRequest))
{
+ Entry = RemoveHeadList(&Connection->ListenRequest);
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Bucket->Status = Status;
@@ -210,17 +151,13 @@ FlushListenQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS
Status)
DereferenceObject(Bucket->AssociatedEndpoint);
CompleteBucket(Connection, Bucket, FALSE);
}
-
- DereferenceObject(Connection);
}
VOID
FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
{
- ReferenceObject(Connection);
-
// flush receive queue
- FlushReceiveQueue(Connection, Status, TRUE);
+ FlushReceiveQueue(Connection, Status);
/* We completed the reads successfully but we need to return failure now */
if (Status == STATUS_SUCCESS)
@@ -232,15 +169,13 @@ FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
FlushListenQueue(Connection, Status);
// flush send queue
- FlushSendQueue(Connection, Status, TRUE);
+ FlushSendQueue(Connection, Status);
// flush connect queue
FlushConnectQueue(Connection, Status);
// flush shutdown queue
- FlushShutdownQueue(Connection, Status, TRUE);
-
- DereferenceObject(Connection);
+ FlushShutdownQueue(Connection, Status);
}
VOID
@@ -248,18 +183,17 @@ TCPFinEventHandler(void *arg, const err_t err)
{
PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg, LastConnection;
const NTSTATUS Status = TCPTranslateError(err);
- KIRQL OldIrql;
ASSERT(Connection->SocketContext == NULL);
ASSERT(Connection->AddressFile);
ASSERT(err != ERR_OK);
+ LockObject(Connection);
+
/* Complete all outstanding requests now */
FlushAllQueues(Connection, Status);
- LockObject(Connection, &OldIrql);
-
- LockObjectAtDpcLevel(Connection->AddressFile);
+ LockObject(Connection->AddressFile);
/* Unlink this connection from the address file */
if (Connection->AddressFile->Connection == Connection)
@@ -284,13 +218,13 @@ TCPFinEventHandler(void *arg, const err_t err)
}
}
- UnlockObjectFromDpcLevel(Connection->AddressFile);
+ UnlockObject(Connection->AddressFile);
/* Remove the address file from this connection */
DereferenceObject(Connection->AddressFile);
Connection->AddressFile = NULL;
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
}
VOID
@@ -301,14 +235,15 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb)
PLIST_ENTRY Entry;
PIRP Irp;
NTSTATUS Status;
- KIRQL OldIrql;
- ReferenceObject(Connection);
+ LockObject(Connection);
- while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest,
&Connection->Lock)))
+ while (!IsListEmpty(&Connection->ListenRequest))
{
PIO_STACK_LOCATION IrpSp;
+ Entry = RemoveHeadList(&Connection->ListenRequest);
+
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Irp = Bucket->Request.RequestContext;
@@ -326,7 +261,7 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb)
if (Status == STATUS_SUCCESS)
{
- LockObject(Bucket->AssociatedEndpoint, &OldIrql);
+ LockObject(Bucket->AssociatedEndpoint);
/* sanity assert...this should never be in anything else but a CLOSED state
*/
ASSERT( ((PTCP_PCB)Bucket->AssociatedEndpoint->SocketContext)->state
== CLOSED );
@@ -337,9 +272,9 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb)
/* free previously created socket context (we don't use it, we use
newpcb) */
Bucket->AssociatedEndpoint->SocketContext = newpcb;
- LibTCPAccept(newpcb, (PTCP_PCB)Connection->SocketContext,
Bucket->AssociatedEndpoint);
+ UnlockObject(Bucket->AssociatedEndpoint);
- UnlockObject(Bucket->AssociatedEndpoint, OldIrql);
+ LibTCPAccept(newpcb, (PTCP_PCB)Connection->SocketContext,
Bucket->AssociatedEndpoint);
}
DereferenceObject(Bucket->AssociatedEndpoint);
@@ -352,7 +287,7 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb)
}
}
- DereferenceObject(Connection);
+ UnlockObject(Connection);
}
VOID
@@ -367,12 +302,17 @@ TCPSendEventHandler(void *arg, const u16_t space)
ULONG BytesSent;
ReferenceObject(Connection);
+ LockObject(Connection);
- while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest,
&Connection->Lock)))
+ while (!IsListEmpty(&Connection->SendRequest))
{
UINT SendLen = 0;
PVOID SendBuffer = 0;
+ Entry = RemoveHeadList(&Connection->SendRequest);
+
+ UnlockObject(Connection);
+
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Irp = Bucket->Request.RequestContext;
@@ -400,9 +340,8 @@ TCPSendEventHandler(void *arg, const u16_t space)
if( Status == STATUS_PENDING )
{
- ExInterlockedInsertHeadList(&Connection->SendRequest,
- &Bucket->Entry,
- &Connection->Lock);
+ LockObject(Connection);
+ InsertHeadList(&Connection->SendRequest, &Bucket->Entry);
break;
}
else
@@ -416,13 +355,15 @@ TCPSendEventHandler(void *arg, const u16_t space)
CompleteBucket(Connection, Bucket, FALSE);
}
+
+ LockObject(Connection);
}
// 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);
+ FlushShutdownQueue(Connection, STATUS_SUCCESS);
if (KeCancelTimer(&Connection->DisconnectTimer))
{
@@ -430,6 +371,8 @@ TCPSendEventHandler(void *arg, const u16_t space)
}
}
+ UnlockObject(Connection);
+
DereferenceObject(Connection);
}
@@ -446,10 +389,11 @@ TCPRecvEventHandler(void *arg)
PUCHAR RecvBuffer;
NTSTATUS Status;
- ReferenceObject(Connection);
+ LockObject(Connection);
- while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest,
&Connection->Lock)))
+ while(!IsListEmpty(&Connection->ReceiveRequest))
{
+ Entry = RemoveHeadList(&Connection->ReceiveRequest);
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Irp = Bucket->Request.RequestContext;
@@ -460,9 +404,7 @@ TCPRecvEventHandler(void *arg)
Status = LibTCPGetDataFromConnectionQueue(Connection, RecvBuffer, RecvLen,
&Received);
if (Status == STATUS_PENDING)
{
- ExInterlockedInsertHeadList(&Connection->ReceiveRequest,
- &Bucket->Entry,
- &Connection->Lock);
+ InsertHeadList(&Connection->ReceiveRequest, &Bucket->Entry);
break;
}
@@ -471,8 +413,7 @@ TCPRecvEventHandler(void *arg)
CompleteBucket(Connection, Bucket, FALSE);
}
-
- DereferenceObject(Connection);
+ UnlockObject(Connection);
}
VOID
@@ -482,10 +423,11 @@ TCPConnectEventHandler(void *arg, const err_t err)
PTDI_BUCKET Bucket;
PLIST_ENTRY Entry;
- ReferenceObject(Connection);
+ LockObject(Connection);
- while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest,
&Connection->Lock)))
+ while (!IsListEmpty(&Connection->ConnectRequest))
{
+ Entry = RemoveHeadList(&Connection->ConnectRequest);
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
@@ -495,5 +437,5 @@ TCPConnectEventHandler(void *arg, const err_t err)
CompleteBucket(Connection, Bucket, FALSE);
}
- DereferenceObject(Connection);
+ UnlockObject(Connection);
}
diff --git a/sdk/lib/drivers/ip/transport/tcp/tcp.c
b/sdk/lib/drivers/ip/transport/tcp/tcp.c
index d18b350a967..7bdc8ab7486 100644
--- a/sdk/lib/drivers/ip/transport/tcp/tcp.c
+++ b/sdk/lib/drivers/ip/transport/tcp/tcp.c
@@ -25,21 +25,27 @@ PORT_SET TCPPorts;
NPAGED_LOOKASIDE_LIST TdiBucketLookasideList;
-VOID NTAPI
-DisconnectTimeoutDpc(PKDPC Dpc,
- PVOID DeferredContext,
- PVOID SystemArgument1,
- PVOID SystemArgument2)
+static
+IO_WORKITEM_ROUTINE
+DisconnectWorker;
+
+_Use_decl_annotations_
+VOID
+NTAPI
+DisconnectWorker(
+ _Unreferenced_parameter_ PDEVICE_OBJECT DeviceObject,
+ _In_ PVOID Context
+)
{
- PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)DeferredContext;
+ PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)Context;
PLIST_ENTRY Entry;
PTDI_BUCKET Bucket;
- LockObjectAtDpcLevel(Connection);
-
/* We timed out waiting for pending sends so force it to shutdown */
TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
+ LockObject(Connection);
+
while (!IsListEmpty(&Connection->SendRequest))
{
Entry = RemoveHeadList(&Connection->SendRequest);
@@ -64,11 +70,23 @@ DisconnectTimeoutDpc(PKDPC Dpc,
CompleteBucket(Connection, Bucket, FALSE);
}
- UnlockObjectFromDpcLevel(Connection);
+ UnlockObject(Connection);
DereferenceObject(Connection);
}
+VOID
+NTAPI
+DisconnectTimeoutDpc(PKDPC Dpc,
+ PVOID DeferredContext,
+ PVOID SystemArgument1,
+ PVOID SystemArgument2)
+{
+ PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)DeferredContext;
+
+ IoQueueWorkItem(Connection->DisconnectWorkItem, DisconnectWorker,
DelayedWorkQueue, Connection);
+}
+
VOID ConnectionFree(PVOID Object)
{
PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)Object;
@@ -80,6 +98,9 @@ VOID ConnectionFree(PVOID Object)
RemoveEntryList(&Connection->ListEntry);
TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
+ ExDeleteResourceLite(&Connection->Resource);
+ IoFreeWorkItem(Connection->DisconnectWorkItem);
+
ExFreePoolWithTag( Connection, CONN_ENDPT_TAG );
}
@@ -96,7 +117,7 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext
)
RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));
/* Initialize spin lock that protects the connection endpoint file object */
- KeInitializeSpinLock(&Connection->Lock);
+ ExInitializeResourceLite(&Connection->Resource);
InitializeListHead(&Connection->ConnectRequest);
InitializeListHead(&Connection->ListenRequest);
InitializeListHead(&Connection->ReceiveRequest);
@@ -107,6 +128,13 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID
ClientContext )
/* Initialize disconnect timer */
KeInitializeTimer(&Connection->DisconnectTimer);
KeInitializeDpc(&Connection->DisconnectDpc, DisconnectTimeoutDpc,
Connection);
+ Connection->DisconnectWorkItem = IoAllocateWorkItem(TCPDeviceObject);
+ if (!Connection->DisconnectWorkItem)
+ {
+ ExDeleteResourceLite(&Connection->Resource);
+ ExFreePoolWithTag( Connection, CONN_ENDPT_TAG );
+ return NULL;
+ }
/* Save client context pointer */
Connection->ClientContext = ClientContext;
@@ -126,9 +154,8 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
UINT Family, UINT Type, UINT Proto )
{
NTSTATUS Status;
- KIRQL OldIrql;
- LockObject(Connection, &OldIrql);
+ LockObject(Connection);
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Called: Connection %x, Family %d, Type
%d, "
"Proto %d, sizeof(CONNECTION_ENDPOINT) = %d\n",
@@ -140,7 +167,7 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
else
Status = STATUS_INSUFFICIENT_RESOURCES;
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Leaving. Status = 0x%x\n",
Status));
@@ -149,15 +176,13 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
NTSTATUS TCPClose( PCONNECTION_ENDPOINT Connection )
{
- KIRQL OldIrql;
-
- LockObject(Connection, &OldIrql);
+ LockObject(Connection);
FlushAllQueues(Connection, STATUS_CANCELLED);
- LibTCPClose(Connection, FALSE, TRUE);
+ UnlockObject(Connection);
- UnlockObject(Connection, OldIrql);
+ LibTCPClose(Connection, FALSE, TRUE);
DereferenceObject(Connection);
@@ -287,7 +312,6 @@ NTSTATUS TCPConnect
TA_IP_ADDRESS LocalAddress;
PTDI_BUCKET Bucket;
PNEIGHBOR_CACHE_ENTRY NCE;
- KIRQL OldIrql;
TI_DbgPrint(DEBUG_TCP,("[IP, TCPConnect] Called\n"));
@@ -308,11 +332,11 @@ NTSTATUS TCPConnect
RemoteAddress.Address.IPv4Address,
RemotePort));
- LockObject(Connection, &OldIrql);
+ LockObject(Connection);
if (!Connection->AddressFile)
{
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
return STATUS_INVALID_PARAMETER;
}
@@ -320,7 +344,7 @@ NTSTATUS TCPConnect
{
if (!(NCE = RouteGetRouteToDestination(&RemoteAddress)))
{
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
return STATUS_NETWORK_UNREACHABLE;
}
@@ -335,48 +359,51 @@ NTSTATUS TCPConnect
&bindaddr,
Connection->AddressFile->Port));
- if (NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
- /* Copy bind address into connection */
- Connection->AddressFile->Address.Address.IPv4Address = bindaddr.addr;
- /* Check if we had an unspecified port */
- if (!Connection->AddressFile->Port)
- {
- /* We did, so we need to copy back the port */
- Status = TCPGetSockAddress(Connection, (PTRANSPORT_ADDRESS)&LocalAddress,
FALSE);
- if (NT_SUCCESS(Status))
- {
- /* Allocate the port in the port bitmap */
- Connection->AddressFile->Port =
TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port);
-
- /* This should never fail */
- ASSERT(Connection->AddressFile->Port != 0xFFFF);
- }
- }
+ UnlockObject(Connection);
+ return Status;
+ }
- if (NT_SUCCESS(Status))
+ /* Copy bind address into connection */
+ Connection->AddressFile->Address.Address.IPv4Address = bindaddr.addr;
+ /* Check if we had an unspecified port */
+ if (!Connection->AddressFile->Port)
+ {
+ /* We did, so we need to copy back the port */
+ Status = TCPGetSockAddress(Connection, (PTRANSPORT_ADDRESS)&LocalAddress,
FALSE);
+ if (!NT_SUCCESS(Status))
{
- connaddr.addr = RemoteAddress.Address.IPv4Address;
+ UnlockObject(Connection);
+ return Status;
+ }
- Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList);
- if (!Bucket)
- {
- UnlockObject(Connection, OldIrql);
- return STATUS_NO_MEMORY;
- }
+ /* Allocate the port in the port bitmap */
+ Connection->AddressFile->Port =
TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port);
- Bucket->Request.RequestNotifyObject = (PVOID)Complete;
- Bucket->Request.RequestContext = Context;
+ /* This should never fail */
+ ASSERT(Connection->AddressFile->Port != 0xFFFF);
+ }
- InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );
+ connaddr.addr = RemoteAddress.Address.IPv4Address;
- Status = TCPTranslateError(LibTCPConnect(Connection,
- &connaddr,
- RemotePort));
- }
+ Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList);
+ if (!Bucket)
+ {
+ UnlockObject(Connection);
+ return STATUS_NO_MEMORY;
}
- UnlockObject(Connection, OldIrql);
+ Bucket->Request.RequestNotifyObject = (PVOID)Complete;
+ Bucket->Request.RequestContext = Context;
+
+ InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );
+
+ UnlockObject(Connection);
+
+ Status = TCPTranslateError(LibTCPConnect(Connection,
+ &connaddr,
+ RemotePort));
TI_DbgPrint(DEBUG_TCP,("[IP, TCPConnect] Leaving. Status = 0x%x\n",
Status));
@@ -394,12 +421,11 @@ NTSTATUS TCPDisconnect
{
NTSTATUS Status = STATUS_INVALID_PARAMETER;
PTDI_BUCKET Bucket;
- KIRQL OldIrql;
LARGE_INTEGER ActualTimeout;
TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Called\n"));
- LockObject(Connection, &OldIrql);
+ LockObject(Connection);
if (Connection->SocketContext)
{
@@ -407,12 +433,20 @@ NTSTATUS TCPDisconnect
{
if (IsListEmpty(&Connection->SendRequest))
{
+ ReferenceObject(Connection);
+ UnlockObject(Connection);
Status = TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
+ LockObject(Connection);
+ DereferenceObject(Connection);
}
else if (Timeout && Timeout->QuadPart == 0)
{
- FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE);
- TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
+ FlushSendQueue(Connection, STATUS_FILE_CLOSED);
+ ReferenceObject(Connection);
+ UnlockObject(Connection);
+ LibTCPShutdown(Connection, 0, 1);
+ LockObject(Connection);
+ DereferenceObject(Connection);
Status = STATUS_TIMEOUT;
}
else
@@ -431,7 +465,7 @@ NTSTATUS TCPDisconnect
Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList);
if (!Bucket)
{
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
return STATUS_NO_MEMORY;
}
@@ -441,11 +475,11 @@ NTSTATUS TCPDisconnect
InsertTailList(&Connection->ShutdownRequest,
&Bucket->Entry);
ReferenceObject(Connection);
- if (KeCancelTimer(&Connection->DisconnectTimer))
+ if (KeSetTimer(&Connection->DisconnectTimer, ActualTimeout,
&Connection->DisconnectDpc))
{
+ /* Timer was already in the queue. */
DereferenceObject(Connection);
}
- KeSetTimer(&Connection->DisconnectTimer, ActualTimeout,
&Connection->DisconnectDpc);
Status = STATUS_PENDING;
}
@@ -453,20 +487,26 @@ NTSTATUS TCPDisconnect
if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
{
- FlushReceiveQueue(Connection, STATUS_FILE_CLOSED, FALSE);
- FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE);
- FlushShutdownQueue(Connection, STATUS_FILE_CLOSED, FALSE);
+ FlushReceiveQueue(Connection, STATUS_FILE_CLOSED);
+ FlushSendQueue(Connection, STATUS_FILE_CLOSED);
+ FlushShutdownQueue(Connection, STATUS_FILE_CLOSED);
+ ReferenceObject(Connection);
+ UnlockObject(Connection);
Status = TCPTranslateError(LibTCPShutdown(Connection, 1, 1));
+ DereferenceObject(Connection);
+ }
+ else
+ {
+ UnlockObject(Connection);
}
}
else
{
+ UnlockObject(Connection);
/* We already got closed by the other side so just return success */
Status = STATUS_SUCCESS;
}
- UnlockObject(Connection, OldIrql);
-
TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Leaving. Status = 0x%x\n",
Status));
return Status;
@@ -506,7 +546,9 @@ NTSTATUS TCPReceiveData
Bucket->Request.RequestNotifyObject = Complete;
Bucket->Request.RequestContext = Context;
- ExInterlockedInsertTailList( &Connection->ReceiveRequest,
&Bucket->Entry, &Connection->Lock );
+ LockObject(Connection);
+ InsertTailList( &Connection->ReceiveRequest, &Bucket->Entry );
+ UnlockObject(Connection);
TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Queued read irp\n"));
TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Leaving. Status =
STATUS_PENDING\n"));
@@ -532,9 +574,8 @@ NTSTATUS TCPSendData
{
NTSTATUS Status;
PTDI_BUCKET Bucket;
- KIRQL OldIrql;
- LockObject(Connection, &OldIrql);
+ ReferenceObject(Connection);
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Called for %d bytes (on socket
%x)\n",
SendLength, Connection->SocketContext));
@@ -558,7 +599,7 @@ NTSTATUS TCPSendData
Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList);
if (!Bucket)
{
- UnlockObject(Connection, OldIrql);
+ DereferenceObject(Connection);
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Failed to allocate
bucket\n"));
return STATUS_NO_MEMORY;
}
@@ -566,13 +607,15 @@ NTSTATUS TCPSendData
Bucket->Request.RequestNotifyObject = Complete;
Bucket->Request.RequestContext = Context;
+ LockObject(Connection);
InsertTailList( &Connection->SendRequest, &Bucket->Entry );
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Queued write irp\n"));
+ UnlockObject(Connection);
}
- UnlockObject(Connection, OldIrql);
TI_DbgPrint(DEBUG_TCP, ("[IP, TCPSendData] Leaving. Status = %x\n",
Status));
+ DereferenceObject(Connection);
return Status;
}
@@ -606,13 +649,12 @@ NTSTATUS TCPGetSockAddress
PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address;
struct ip_addr ipaddr;
NTSTATUS Status;
- KIRQL OldIrql;
AddressIP->TAAddressCount = 1;
AddressIP->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
AddressIP->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
- LockObject(Connection, &OldIrql);
+ LockObject(Connection);
if (GetRemote)
{
@@ -627,7 +669,7 @@ NTSTATUS TCPGetSockAddress
&AddressIP->Address[0].Address[0].sin_port));
}
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
AddressIP->Address[0].Address[0].in_addr = ipaddr.addr;
@@ -641,7 +683,6 @@ BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp )
{
PLIST_ENTRY Entry;
PLIST_ENTRY ListHead[5];
- KIRQL OldIrql;
PTDI_BUCKET Bucket;
UINT i = 0;
BOOLEAN Found = FALSE;
@@ -652,7 +693,7 @@ BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp )
ListHead[3] = &Endpoint->ListenRequest;
ListHead[4] = &Endpoint->ShutdownRequest;
- LockObject(Endpoint, &OldIrql);
+ LockObject(Endpoint);
for( i = 0; i < 5; i++ )
{
@@ -671,7 +712,7 @@ BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp )
}
}
- UnlockObject(Endpoint, OldIrql);
+ UnlockObject(Endpoint);
return Found;
}
diff --git a/sdk/lib/drivers/ip/transport/udp/udp.c
b/sdk/lib/drivers/ip/transport/udp/udp.c
index 783dae988b9..0ad09fa7bf3 100644
--- a/sdk/lib/drivers/ip/transport/udp/udp.c
+++ b/sdk/lib/drivers/ip/transport/udp/udp.c
@@ -171,9 +171,8 @@ NTSTATUS UDPSendDatagram(
USHORT RemotePort;
NTSTATUS Status;
PNEIGHBOR_CACHE_ENTRY NCE;
- KIRQL OldIrql;
- LockObject(AddrFile, &OldIrql);
+ LockObject(AddrFile);
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
AddrFile, ConnInfo, BufferData, DataSize));
@@ -188,7 +187,7 @@ NTSTATUS UDPSendDatagram(
break;
default:
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return STATUS_UNSUCCESSFUL;
}
@@ -200,7 +199,7 @@ NTSTATUS UDPSendDatagram(
* interface we're sending over
*/
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return STATUS_NETWORK_UNREACHABLE;
}
@@ -209,7 +208,7 @@ NTSTATUS UDPSendDatagram(
else
{
if(!(NCE = NBLocateNeighbor( &LocalAddress, NULL ))) {
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
return STATUS_INVALID_PARAMETER;
}
}
@@ -223,7 +222,7 @@ NTSTATUS UDPSendDatagram(
BufferData,
DataSize );
- UnlockObject(AddrFile, OldIrql);
+ UnlockObject(AddrFile);
if( !NT_SUCCESS(Status) )
return Status;
diff --git a/sdk/lib/drivers/lwip/src/include/rosip.h
b/sdk/lib/drivers/lwip/src/include/rosip.h
index af852910d2f..701a65614da 100644
--- a/sdk/lib/drivers/lwip/src/include/rosip.h
+++ b/sdk/lib/drivers/lwip/src/include/rosip.h
@@ -31,6 +31,9 @@ struct lwip_callback_msg
struct {
PVOID Arg;
} Socket;
+ struct {
+ struct tcp_pcb* pcb;
+ } FreeSocket;
struct {
PCONNECTION_ENDPOINT Connection;
struct ip_addr *IpAddress;
@@ -99,6 +102,7 @@ extern void TCPRecvEventHandler(void *arg);
/* TCP functions */
PTCP_PCB LibTCPSocket(void *arg);
+VOID LibTCPFreeSocket(PTCP_PCB pcb);
err_t LibTCPBind(PCONNECTION_ENDPOINT Connection, struct ip_addr *const ipaddr,
const u16_t port);
PTCP_PCB LibTCPListen(PCONNECTION_ENDPOINT Connection, const u8_t backlog);
err_t LibTCPSend(PCONNECTION_ENDPOINT Connection, void *const dataptr, const u16_t
len, u32_t *sent, const int safe);
diff --git a/sdk/lib/drivers/lwip/src/rostcp.c b/sdk/lib/drivers/lwip/src/rostcp.c
index de5564642b8..cc0dd4bc0d6 100644
--- a/sdk/lib/drivers/lwip/src/rostcp.c
+++ b/sdk/lib/drivers/lwip/src/rostcp.c
@@ -81,7 +81,9 @@ void LibTCPEnqueuePacket(PCONNECTION_ENDPOINT Connection, struct pbuf
*p)
qp->p = p;
qp->Offset = 0;
- ExInterlockedInsertTailList(&Connection->PacketQueue, &qp->ListEntry,
&Connection->Lock);
+ LockObject(Connection);
+ InsertTailList(&Connection->PacketQueue, &qp->ListEntry);
+ UnlockObject(Connection);
}
PQUEUE_ENTRY LibTCPDequeuePacket(PCONNECTION_ENDPOINT Connection)
@@ -104,11 +106,10 @@ NTSTATUS LibTCPGetDataFromConnectionQueue(PCONNECTION_ENDPOINT
Connection, PUCHA
struct pbuf* p;
NTSTATUS Status;
UINT ReadLength, PayloadLength, Offset, Copied;
- KIRQL OldIrql;
(*Received) = 0;
- LockObject(Connection, &OldIrql);
+ LockObject(Connection);
if (!IsListEmpty(&Connection->PacketQueue))
{
@@ -132,13 +133,9 @@ NTSTATUS LibTCPGetDataFromConnectionQueue(PCONNECTION_ENDPOINT
Connection, PUCHA
qp = NULL;
}
- UnlockObject(Connection, OldIrql);
-
Copied = pbuf_copy_partial(p, RecvBuffer, ReadLength, Offset);
ASSERT(Copied == ReadLength);
- LockObject(Connection, &OldIrql);
-
/* Update trackers */
RecvLen -= ReadLength;
RecvBuffer += ReadLength;
@@ -172,7 +169,7 @@ NTSTATUS LibTCPGetDataFromConnectionQueue(PCONNECTION_ENDPOINT
Connection, PUCHA
Status = STATUS_PENDING;
}
- UnlockObject(Connection, OldIrql);
+ UnlockObject(Connection);
return Status;
}
@@ -364,6 +361,33 @@ LibTCPSocket(void *arg)
return NULL;
}
+static
+void
+LibTCPFreeSocketCallback(void *arg)
+{
+ struct lwip_callback_msg *msg = arg;
+
+ ASSERT(msg);
+
+ /* Calling tcp_close will free it */
+ tcp_close(msg->Input.FreeSocket.pcb);
+
+ KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE);
+}
+
+void LibTCPFreeSocket(PTCP_PCB pcb)
+{
+ struct lwip_callback_msg msg;
+
+ KeInitializeEvent(&msg.Event, NotificationEvent, FALSE);
+ msg.Input.FreeSocket.pcb = pcb;
+
+ tcpip_callback_with_block(LibTCPFreeSocketCallback, &msg, 1);
+
+ WaitForEventSafely(&msg.Event);
+}
+
+
static
void
LibTCPBindCallback(void *arg)