[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
This commit is contained in:
Cameron Gutman 2009-12-31 23:33:24 +00:00
parent 175500c30b
commit 8dd3966ba9
15 changed files with 302 additions and 320 deletions

View file

@ -189,8 +189,6 @@ NTSTATUS NTAPI ReceiveComplete
AFD_DbgPrint(MID_TRACE,("Called\n"));
ASSERT_IRQL(APC_LEVEL);
if( !SocketAcquireStateLock( FCB ) )
return STATUS_FILE_CLOSED;

View file

@ -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;

View file

@ -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

View file

@ -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 */

View file

@ -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)); \
}
/*
* 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)); \
}
#else /* DBG */
/*
* VOID ReferenceObject(
* PVOID Object)
*/
#define ReferenceObject(Object) \
{ \
InterlockedIncrement(&((Object)->RefCount)); \
#define ReferenceObject(Object) \
{ \
InterlockedIncrement(&((Object)->RefCount)); \
}
/*
* VOID DereferenceObject(
* PVOID Object)
*/
#define DereferenceObject(Object) \
{ \
if (InterlockedDecrement(&((Object)->RefCount)) == 0) \
(((Object)->Free)(Object)); \
#define DereferenceObject(Object) \
{ \
if (InterlockedDecrement(&((Object)->RefCount)) == 0) \
(((Object)->Free)(Object)); \
}
/*
* VOID LockObject(PVOID Object, PKIRQL OldIrql)
*/
#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); \
}
/*
* VOID UnlockObjectFromDpcLevel(PVOID Object)
*/
#define UnlockObjectFromDpcLevel(Object) \
{ \
KeReleaseSpinLockFromDpcLevel(&((Object)->Lock)); \
DereferenceObject(Object); \
}
#endif /* DBG */
#include <ip.h>
@ -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;

View file

@ -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;
}

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
if (Connection->SocketContext)
{
HandleSignalledConnection(Connection);
KeReleaseSpinLock(&Connection->Lock, OldIrql);
TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
RemoveEntryList(&Connection->ListEntry);
TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
ProcessCompletions(Connection);
}
else
{
KeReleaseSpinLock(&Connection->Lock, 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;
}

View file

@ -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;
}

View file

@ -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();

View file

@ -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;
}