Author: cgutman Date: Sat Nov 14 19:38:02 2009 New Revision: 44163
URL: http://svn.reactos.org/svn/reactos?rev=44163&view=rev Log: - Use a spin lock to protect OSKit instead of a recursive mutex - Remove the now unused recursive mutex code - Don't clear the SS_ISCONNECTING flag when soconnect returns EINPROGRESS because it causes a crash during soreceive - Lock CONNECTION_ENDPOINT and ADDRESS_FILE structs better - Remove incorrect IoMarkIrpPending calls - Remove useless ASSERT_LOCKED - Don't destroy so_connection when we close a connection - Remove useless FileFindConnectionByContext - Remove SignalledConnectionsList and SignalledConnectionsLock and simply loop through ConnectionEndpointList for signalled connections - Add connections to ConnectionEndpointList in TCPAllocateConnectionEndpoint instead of FileOpenConnection so we don't miss listeners - Remove connections from ConnectionEndpointList in TCPFreeConnectionEndpoint instead of FileCloseConnection so we don't miss listeners - Use ExInterlockedRemoveHeadList to remove entries in the address file's request lists - Remove useless members, flags, and variables in titypes.h and tcp.h - Fixes bug 4955 and 4434
Removed: trunk/reactos/drivers/network/tcpip/recmutex/ Modified: trunk/reactos/drivers/network/tcpip/include/fileobjs.h trunk/reactos/drivers/network/tcpip/include/tcp.h trunk/reactos/drivers/network/tcpip/include/titypes.h trunk/reactos/drivers/network/tcpip/tcpip.rbuild trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c trunk/reactos/drivers/network/tcpip/tcpip/lock.c trunk/reactos/drivers/network/tcpip/tcpip/mocklock.c trunk/reactos/lib/drivers/ip/transport/datagram/datagram.c trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c trunk/reactos/lib/drivers/ip/transport/tcp/accept.c trunk/reactos/lib/drivers/ip/transport/tcp/event.c trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c trunk/reactos/lib/drivers/ip/transport/udp/udp.c trunk/reactos/lib/drivers/oskittcp/include/oskittcp.h trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c
Modified: trunk/reactos/drivers/network/tcpip/include/fileobjs.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/inclu... ============================================================================== --- trunk/reactos/drivers/network/tcpip/include/fileobjs.h [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/include/fileobjs.h [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -13,7 +13,6 @@ extern LIST_ENTRY ConnectionEndpointListHead; extern KSPIN_LOCK ConnectionEndpointListLock;
- NTSTATUS FileOpenAddress( PTDI_REQUEST Request, PTA_IP_ADDRESS AddrList, @@ -27,8 +26,6 @@ PTDI_REQUEST Request, PVOID ClientContext);
-PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ); - NTSTATUS FileCloseConnection( PTDI_REQUEST Request);
Modified: trunk/reactos/drivers/network/tcpip/include/tcp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/inclu... ============================================================================== --- trunk/reactos/drivers/network/tcpip/include/tcp.h [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/include/tcp.h [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -84,11 +84,6 @@ #define SRF_FIN TCP_FIN
extern LONG TCP_IPIdentification; -extern LIST_ENTRY SignalledConnectionsList; -extern KSPIN_LOCK SignalledConnectionsLock; -extern LIST_ENTRY SleepingThreadsList; -extern FAST_MUTEX SleepingThreadsLock; -extern RECURSIVE_MUTEX TCPLock;
/* accept.c */ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, @@ -105,7 +100,6 @@ PVOID Context );
/* tcp.c */ -ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ); PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ); VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection );
Modified: trunk/reactos/drivers/network/tcpip/include/titypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/inclu... ============================================================================== --- trunk/reactos/drivers/network/tcpip/include/titypes.h [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/include/titypes.h [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -153,7 +153,6 @@ LIST_ENTRY ListEntry; /* Entry on list */ KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */ OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */ - USHORT Flags; /* Flags for address file (see below) */ IP_ADDRESS Address; /* Address of this address file */ USHORT Family; /* Address family */ USHORT Protocol; /* Protocol number */ @@ -213,29 +212,6 @@ BOOLEAN RegisteredChainedReceiveExpeditedHandler; } ADDRESS_FILE, *PADDRESS_FILE;
-/* Address File Flag constants */ -#define AFF_VALID 0x0001 /* Address file object is valid for use */ -#define AFF_BUSY 0x0002 /* Address file object is exclusive to someone */ -#define AFF_DELETE 0x0004 /* Address file object is sheduled to be deleted */ -#define AFF_SEND 0x0008 /* A send request is pending */ -#define AFF_RECEIVE 0x0010 /* A receive request is pending */ -#define AFF_PENDING 0x001C /* A request is pending */ - -/* Macros for manipulating address file object flags */ - -#define AF_IS_VALID(ADF) ((ADF)->Flags & AFF_VALID) -#define AF_SET_VALID(ADF) ((ADF)->Flags |= AFF_VALID) -#define AF_CLR_VALID(ADF) ((ADF)->Flags &= ~AFF_VALID) - -#define AF_IS_BUSY(ADF) ((ADF)->Flags & AFF_BUSY) -#define AF_SET_BUSY(ADF) ((ADF)->Flags |= AFF_BUSY) -#define AF_CLR_BUSY(ADF) ((ADF)->Flags &= ~AFF_BUSY) - -#define AF_IS_PENDING(ADF, X) (ADF->Flags & X) -#define AF_SET_PENDING(ADF, X) (ADF->Flags |= X) -#define AF_CLR_PENDING(ADF, X) (ADF->Flags &= ~X) - - /* Structure used to search through Address Files */ typedef struct _AF_SEARCH { PLIST_ENTRY Next; /* Next address file to check */ @@ -306,8 +282,6 @@ LIST_ENTRY SendRequest; /* Queued send requests */
/* Signals */ - LIST_ENTRY SignalList; /* Entry in the list of sockets waiting for - * notification service to the client */ UINT SignalState; /* Active signals from oskit */ } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
Modified: trunk/reactos/drivers/network/tcpip/tcpip.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip... ============================================================================== --- trunk/reactos/drivers/network/tcpip/tcpip.rbuild [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/tcpip.rbuild [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -21,9 +21,6 @@ <directory name="datalink"> <file>lan.c</file> </directory> - <directory name="recmutex"> - <file>recmutex.c</file> - </directory> <directory name="tcpip"> <file>ainfo.c</file> <file>buffer.c</file>
Modified: trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip... ============================================================================== --- trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -210,9 +210,8 @@
TCPRemoveIRP(Connection, Irp);
- TCPAbortListenForSocket( - Connection->AddressFile->Listener, - Connection ); + TCPAbortListenForSocket(Connection->AddressFile->Listener, + Connection);
IoReleaseCancelSpinLock(Irp->CancelIrql);
@@ -1044,7 +1043,7 @@ Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters; Status = STATUS_SUCCESS;
- TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* Set the event handler. if an event handler is associated with a specific event, it's flag (RegisteredXxxHandler) is TRUE. @@ -1165,7 +1164,7 @@ Status = STATUS_INVALID_PARAMETER; }
- TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
return Status; }
Modified: trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip... ============================================================================== --- trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -295,9 +295,6 @@ /* Initialize spin lock that protects the address file object */ KeInitializeSpinLock(&AddrFile->Lock);
- /* Set valid flag so the address can be used */ - AF_SET_VALID(AddrFile); - /* Return address file object */ Request->Handle.AddressHandle = AddrFile;
@@ -328,7 +325,7 @@ KIRQL OldIrql; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; PDATAGRAM_SEND_REQUEST SendRequest; - PLIST_ENTRY CurrentEntry, NextEntry; + PLIST_ENTRY CurrentEntry;
AddrFile = Request->Handle.AddressHandle;
@@ -339,8 +336,6 @@ RemoveEntryList(&AddrFile->ListEntry); TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
- TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); - /* FIXME: Kill TCP connections on this address file object */
/* Return pending requests with error */ @@ -348,43 +343,27 @@ TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile));
/* Go through pending receive request list and cancel them all */ - CurrentEntry = AddrFile->ReceiveQueue.Flink; - while (CurrentEntry != &AddrFile->ReceiveQueue) { - NextEntry = CurrentEntry->Flink; + while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry); - /* Abort the request and free its resources */ - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0); - TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); - CurrentEntry = NextEntry; + /* exFreePool(ReceiveRequest); 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 */ - CurrentEntry = AddrFile->TransmitQueue.Flink; - while (CurrentEntry != &AddrFile->TransmitQueue) { - NextEntry = CurrentEntry->Flink; - SendRequest = CONTAINING_RECORD(CurrentEntry, - DATAGRAM_SEND_REQUEST, ListEntry); - /* Abort the request and free its resources */ - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { + SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry); (*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0); exFreePool(SendRequest); - TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); - CurrentEntry = NextEntry; - } - - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + }
/* Protocol specific handling */ switch (AddrFile->Protocol) { case IPPROTO_TCP: TCPFreePort( AddrFile->Port ); - if( AddrFile->Listener ) { - TCPClose( AddrFile->Listener ); - exFreePool( AddrFile->Listener ); - } + if( AddrFile->Listener ) + TCPClose( AddrFile->Listener ); break;
case IPPROTO_UDP: @@ -433,46 +412,9 @@ /* Return connection endpoint file object */ Request->Handle.ConnectionContext = Connection;
- /* Add connection endpoint to global list */ - ExInterlockedInsertTailList( - &ConnectionEndpointListHead, - &Connection->ListEntry, - &ConnectionEndpointListLock); - TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return STATUS_SUCCESS; -} - - -/* - * FUNCTION: Find a connection by examining the context field. This - * is needed in some situations where a FIN reply is needed after a - * socket is formally broken. - * ARGUMENTS: - * Request = Pointer to TDI request structure for this request - * RETURNS: - * Status of operation - */ -PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ) { - PLIST_ENTRY Entry; - KIRQL OldIrql; - PCONNECTION_ENDPOINT Connection = NULL; - - TcpipAcquireSpinLock( &ConnectionEndpointListLock, &OldIrql ); - - for( Entry = ConnectionEndpointListHead.Flink; - Entry != &ConnectionEndpointListHead; - Entry = Entry->Flink ) { - Connection = - CONTAINING_RECORD( Entry, CONNECTION_ENDPOINT, ListEntry ); - if( Connection->SocketContext == Context ) break; - else Connection = NULL; - } - - TcpipReleaseSpinLock( &ConnectionEndpointListLock, OldIrql ); - - return Connection; }
/* @@ -486,19 +428,12 @@ PTDI_REQUEST Request) { PCONNECTION_ENDPOINT Connection; - KIRQL OldIrql;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Connection = Request->Handle.ConnectionContext;
- TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); - RemoveEntryList(&Connection->ListEntry); - TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); - TCPClose( Connection ); - - TCPFreeConnectionEndpoint(Connection);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
Modified: trunk/reactos/drivers/network/tcpip/tcpip/lock.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip... ============================================================================== --- trunk/reactos/drivers/network/tcpip/tcpip/lock.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/tcpip/lock.c [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -44,16 +44,3 @@ ExReleaseFastMutex( Mutex ); }
-VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { - RecursiveMutexInit( RecMutex ); -} - -VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) { - //TI_DbgPrint(DEBUG_LOCK,("Locking\n")); - RecursiveMutexEnter( RecMutex ); -} - -VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { - //TI_DbgPrint(DEBUG_LOCK,("Unlocking\n")); - RecursiveMutexLeave( RecMutex ); -}
Modified: trunk/reactos/drivers/network/tcpip/tcpip/mocklock.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip... ============================================================================== --- trunk/reactos/drivers/network/tcpip/tcpip/mocklock.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/tcpip/mocklock.c [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -45,11 +45,3 @@ VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) { }
-VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { -} - -VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) { -} - -VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { -}
Modified: trunk/reactos/lib/drivers/ip/transport/datagram/datagram.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/da... ============================================================================== --- trunk/reactos/lib/drivers/ip/transport/datagram/datagram.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/transport/datagram/datagram.c [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -79,7 +79,7 @@
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
- TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (AddrFile->Protocol == IPPROTO_UDP) { @@ -136,7 +136,7 @@ &SrcAddress->Address.IPv4Address, sizeof(SrcAddress->Address.IPv4Address) );
- TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* Complete the receive request */ if (Current->BufferSize < DataSize) @@ -144,11 +144,11 @@ else Current->Complete(Current->Context, STATUS_SUCCESS, DataSize);
- TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); } }
- TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); } else if (AddrFile->RegisteredReceiveDatagramHandler) { @@ -157,8 +157,6 @@ ReceiveHandler = AddrFile->ReceiveDatagramHandler; HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
- TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); - if (SrcAddress->Type == IP_ADDRESS_V4) { AddressLength = sizeof(IPv4_RAW_ADDRESS); @@ -169,6 +167,8 @@ AddressLength = sizeof(IPv6_RAW_ADDRESS); SourceAddress = SrcAddress->Address.IPv6Address; } + + KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
Status = (*ReceiveHandler)(HandlerContext, AddressLength, @@ -184,7 +184,7 @@ } else { - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n")); }
@@ -228,75 +228,66 @@ * This is the high level interface for receiving DG datagrams */ { - KIRQL OldIrql; NTSTATUS Status; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; + KIRQL OldIrql;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
- TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); - - if (AF_IS_VALID(AddrFile)) - { - ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST)); - if (ReceiveRequest) - { - /* Initialize a receive request */ - - /* Extract the remote address filter from the request (if any) */ - if ((ConnInfo->RemoteAddressLength != 0) && - (ConnInfo->RemoteAddress)) + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + + ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST)); + if (ReceiveRequest) + { + /* Initialize a receive request */ + + /* Extract the remote address filter from the request (if any) */ + if ((ConnInfo->RemoteAddressLength != 0) && + (ConnInfo->RemoteAddress)) + { + Status = AddrGetAddress(ConnInfo->RemoteAddress, + &ReceiveRequest->RemoteAddress, + &ReceiveRequest->RemotePort); + if (!NT_SUCCESS(Status)) { - Status = AddrGetAddress(ConnInfo->RemoteAddress, - &ReceiveRequest->RemoteAddress, - &ReceiveRequest->RemotePort); - if (!NT_SUCCESS(Status)) - { - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); - exFreePool(ReceiveRequest); - return Status; - } + exFreePool(ReceiveRequest); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + return Status; } - else - { - ReceiveRequest->RemotePort = 0; - AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0); - } - - IoMarkIrpPending(Irp); - - ReceiveRequest->ReturnInfo = ReturnInfo; - ReceiveRequest->Buffer = BufferData; - ReceiveRequest->BufferSize = ReceiveLength; - ReceiveRequest->UserComplete = Complete; - ReceiveRequest->UserContext = Context; - ReceiveRequest->Complete = + } + else + { + ReceiveRequest->RemotePort = 0; + AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0); + } + + IoMarkIrpPending(Irp); + + ReceiveRequest->ReturnInfo = ReturnInfo; + ReceiveRequest->Buffer = BufferData; + ReceiveRequest->BufferSize = ReceiveLength; + ReceiveRequest->UserComplete = Complete; + ReceiveRequest->UserContext = Context; + ReceiveRequest->Complete = (PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete; - ReceiveRequest->Context = ReceiveRequest; - ReceiveRequest->AddressFile = AddrFile; - ReceiveRequest->Irp = Irp; - - /* Queue receive request */ - InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry); - AF_SET_PENDING(AddrFile, AFF_RECEIVE); - - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); - - TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest)); - - return STATUS_PENDING; - } - else - { - Status = STATUS_INSUFFICIENT_RESOURCES; - } + ReceiveRequest->Context = ReceiveRequest; + ReceiveRequest->AddressFile = AddrFile; + ReceiveRequest->Irp = Irp; + + /* Queue receive request */ + InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry); + + TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest)); + + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + + return STATUS_PENDING; } else { - Status = STATUS_INVALID_ADDRESS; - } - - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + Status = STATUS_INSUFFICIENT_RESOURCES; + }
TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
Modified: trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/ra... ============================================================================== --- trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -195,6 +195,9 @@ USHORT RemotePort; NTSTATUS Status; PNEIGHBOR_CACHE_ENTRY NCE; + KIRQL OldIrql; + + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -209,13 +212,17 @@ break;
default: + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_UNSUCCESSFUL; }
TI_DbgPrint(MID_TRACE,("About to get route to destination\n"));
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) + { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_NETWORK_UNREACHABLE; + }
LocalAddress = AddrFile->Address; if (AddrIsUnspecified(&LocalAddress)) @@ -237,17 +244,23 @@ DataSize );
if( !NT_SUCCESS(Status) ) + { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; + }
TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL ))) { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); FreeNdisPacket(Packet.NdisPacket); return Status; }
TI_DbgPrint(MID_TRACE,("Leaving\n")); + + KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
return STATUS_SUCCESS; }
Modified: trunk/reactos/lib/drivers/ip/transport/tcp/accept.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/tc... ============================================================================== --- trunk/reactos/lib/drivers/ip/transport/tcp/accept.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/transport/tcp/accept.c [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -10,6 +10,7 @@
#include "precomp.h"
+/* Listener->Lock MUST be acquired */ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, PCONNECTION_ENDPOINT Connection, PTDI_REQUEST_KERNEL Request ) { @@ -26,17 +27,14 @@ WhoIsConnecting = (PTDI_CONNECTION_INFORMATION) Request->ReturnConnectionInformation;
- TcpipRecursiveMutexEnter(&TCPLock); - Status = TCPTranslateError ( OskitTCPAccept( Listener->SocketContext, &Connection->SocketContext, + Connection, &OutAddr, sizeof(OutAddr), &OutAddrLen, Request->RequestFlags & TDI_QUERY_ACCEPT ? 0 : 1 ) ); - - TcpipRecursiveMutexLeave(&TCPLock);
TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
@@ -71,10 +69,13 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { NTSTATUS Status = STATUS_SUCCESS; SOCKADDR_IN AddressToBind; + KIRQL OldIrql;
ASSERT(Connection); ASSERT_KM_POINTER(Connection->SocketContext); ASSERT_KM_POINTER(Connection->AddressFile); + + KeAcquireSpinLock(&Connection->Lock, &OldIrql);
TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
@@ -89,8 +90,6 @@
TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port));
- TcpipRecursiveMutexEnter( &TCPLock ); - Status = TCPTranslateError( OskitTCPBind( Connection->SocketContext, &AddressToBind, sizeof(AddressToBind) ) ); @@ -98,7 +97,7 @@ if (NT_SUCCESS(Status)) Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) );
- TcpipRecursiveMutexLeave( &TCPLock ); + KeReleaseSpinLock(&Connection->Lock, OldIrql);
TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status));
@@ -137,11 +136,16 @@ { NTSTATUS Status; PTDI_BUCKET Bucket; + KIRQL OldIrql;
TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n"));
+ KeAcquireSpinLock(&Listener->Lock, &OldIrql); + Status = TCPServiceListeningSocket( Listener, Connection, (PTDI_REQUEST_KERNEL)Request ); + + KeReleaseSpinLock(&Listener->Lock, OldIrql);
if( Status == STATUS_PENDING ) { Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); @@ -150,8 +154,8 @@ Bucket->AssociatedEndpoint = Connection; Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; - IoMarkIrpPending((PIRP)Context); - ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, &Listener->Lock ); + ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, + &Listener->Lock ); } else Status = STATUS_NO_MEMORY; }
Modified: trunk/reactos/lib/drivers/ip/transport/tcp/event.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/tc... ============================================================================== --- trunk/reactos/lib/drivers/ip/transport/tcp/event.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/transport/tcp/event.c [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -15,56 +15,30 @@ void *WhichConnection, OSK_UINT NewState ) { PCONNECTION_ENDPOINT Connection = WhichConnection; - ULONG OldState; - KIRQL OldIrql; - - ASSERT_LOCKED(&TCPLock); - - TI_DbgPrint(MID_TRACE,("Flags: %c%c%c%c\n", + + TI_DbgPrint(DEBUG_TCP,("Connection: %x Flags: %c%c%c%c%c\n", + Connection, NewState & SEL_CONNECT ? 'C' : 'c', NewState & SEL_READ ? 'R' : 'r', NewState & SEL_FIN ? 'F' : 'f', - NewState & SEL_ACCEPT ? 'A' : 'a')); + NewState & SEL_ACCEPT ? 'A' : 'a', + NewState & SEL_WRITE ? 'W' : 'w')); + + if (!Connection) + { + return 0; + } + + KeAcquireSpinLockAtDpcLevel(&Connection->Lock);
TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n", NewState, Connection, - Connection ? Connection->SignalState ^ NewState : + Connection->SignalState ^ NewState, NewState));
- if( !Connection ) { - TI_DbgPrint(DEBUG_TCP,("Socket closing.\n")); - Connection = FileFindConnectionByContext( WhichSocket ); - if( !Connection ) - return 0; - else - TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection)); - } - - OldState = Connection->SignalState; - Connection->SignalState |= NewState;
- TcpipRecursiveMutexLeave(&TCPLock); - - /* We must not be locked when handling signalled connections - * because a completion could trigger another IOCTL which - * would cause a deadlock - */ - NewState = HandleSignalledConnection(Connection); - - TcpipRecursiveMutexEnter(&TCPLock); - - KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql); - if ((NewState == 0 || NewState == SEL_FIN) && - (OldState != 0 && OldState != SEL_FIN)) - { - RemoveEntryList(&Connection->SignalList); - } - else if (NewState != 0 && NewState != SEL_FIN) - { - InsertTailList(&SignalledConnectionsList, &Connection->SignalList); - } - KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql); + KeReleaseSpinLockFromDpcLevel(&Connection->Lock);
return 0; } @@ -85,8 +59,6 @@ IP_PACKET Packet = { 0 }; IP_ADDRESS RemoteAddress, LocalAddress; PIPv4_HEADER Header; - - ASSERT_LOCKED(&TCPLock);
if( *data == 0x45 ) { /* IPv4 */ Header = (PIPv4_HEADER)data; @@ -180,8 +152,6 @@ OSK_UINT Bytes, OSK_PCHAR File, OSK_UINT Line ) { void *v; ULONG Signature; - - ASSERT_LOCKED(&TCPLock);
#if 0 != MEM_PROFILE static OSK_UINT *Sizes = NULL, *Counts = NULL, ArrayAllocated = 0; @@ -258,8 +228,6 @@ void *data, OSK_PCHAR File, OSK_UINT Line ) { ULONG Signature;
- ASSERT_LOCKED(&TCPLock); - UntrackFL( (PCHAR)File, Line, data, FOURCC('f','b','s','d') ); data = (void *)((char *) data - sizeof(ULONG)); Signature = *((ULONG *) data);
Modified: trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/tc... ============================================================================== --- trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -15,12 +15,12 @@ LONG TCP_IPIdentification = 0; static BOOLEAN TCPInitialized = FALSE; static NPAGED_LOOKASIDE_LIST TCPSegmentList; -LIST_ENTRY SignalledConnectionsList; -KSPIN_LOCK SignalledConnectionsLock; -RECURSIVE_MUTEX TCPLock; PORT_SET TCPPorts;
-ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { +static VOID DrainSignals() { + PCONNECTION_ENDPOINT Connection; + PLIST_ENTRY CurrentEntry, NextEntry; + KIRQL OldIrql; NTSTATUS Status = STATUS_SUCCESS; PTCP_COMPLETION_ROUTINE Complete; PTDI_BUCKET Bucket; @@ -28,279 +28,290 @@ PIRP Irp; PMDL Mdl;
- TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", - Connection, Connection->SocketContext)); - - if( Connection->SignalState & SEL_FIN ) { - TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); - - Connection->SignalState &= ~SEL_READ; - while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, - &Connection->Lock )) != NULL) - { - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - - exFreePool(Bucket); - } - - Connection->SignalState &= ~SEL_WRITE; - while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, - &Connection->Lock )) != NULL) - { - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - - exFreePool(Bucket); - } - - Connection->SignalState &= ~SEL_ACCEPT; - while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, - &Connection->Lock )) != NULL) - { - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - /* We have to notify oskittcp of the abortion */ - TCPAbortListenForSocket(Connection->AddressFile->Listener, - Connection); - - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - - exFreePool(Bucket); - } - - Connection->SignalState &= ~SEL_CONNECT; - while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, - &Connection->Lock )) != NULL) - { - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - - exFreePool(Bucket); - } - } - - /* Things that can happen when we try the initial connection */ - if( Connection->SignalState & SEL_CONNECT ) { - Connection->SignalState &= ~SEL_CONNECT; - while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, - &Connection->Lock )) != NULL ) { + KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); + CurrentEntry = ConnectionEndpointListHead.Flink; + while (CurrentEntry != &ConnectionEndpointListHead) + { + NextEntry = CurrentEntry->Flink; + KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); + + Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT, + ListEntry ); + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + + TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", + Connection, Connection->SocketContext)); + + if( !Connection->SocketContext || Connection->SignalState & SEL_FIN ) { + KeReleaseSpinLock(&Connection->Lock, OldIrql); + TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); + + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + + exFreePool(Bucket); + } + + while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + + exFreePool(Bucket); + } + + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + + exFreePool(Bucket); + } + + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + + exFreePool(Bucket); + } + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + } + + /* Things that can happen when we try the initial connection */ + if( Connection->SignalState & SEL_CONNECT ) { + KeReleaseSpinLock(&Connection->Lock, OldIrql); + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, + &Connection->Lock )) != NULL ) {
- TI_DbgPrint(DEBUG_TCP, ("Connect Event\n")); - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - TI_DbgPrint(DEBUG_TCP, - ("Completing Request %x\n", Bucket->Request.RequestContext)); - - Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 ); - - /* Frees the bucket allocated in TCPConnect */ - exFreePool( Bucket ); - } - } - - if( Connection->SignalState & SEL_ACCEPT ) { - /* Handle readable on a listening socket -- - * TODO: Implement filtering - */ - - TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n", - Connection, - IsListEmpty(&Connection->ListenRequest) ? - "empty" : "nonempty")); - - Connection->SignalState &= ~SEL_ACCEPT; - while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, - &Connection->Lock )) != NULL ) { - PIO_STACK_LOCATION IrpSp; - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Irp = Bucket->Request.RequestContext; - IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - TI_DbgPrint(DEBUG_TCP,("Getting the socket\n")); - Status = TCPServiceListeningSocket - ( Connection->AddressFile->Listener, - Bucket->AssociatedEndpoint, - (PTDI_REQUEST_KERNEL)&IrpSp->Parameters ); - - TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); - - if( Status == STATUS_PENDING ) { - Connection->SignalState |= SEL_ACCEPT; - ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, &Connection->Lock ); - break; - } else { - Complete( Bucket->Request.RequestContext, Status, 0 ); - exFreePool( Bucket ); - } - } - } - - /* Things that happen after we're connected */ - if( Connection->SignalState & SEL_READ ) { - TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n", - IsListEmpty(&Connection->ReceiveRequest) ? - "empty" : "nonempty")); - - Connection->SignalState &= ~SEL_READ; - while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, - &Connection->Lock )) != NULL ) { - OSK_UINT RecvLen = 0, Received = 0; - PVOID RecvBuffer = 0; - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Irp = Bucket->Request.RequestContext; - Mdl = Irp->MdlAddress; - - TI_DbgPrint(DEBUG_TCP, - ("Getting the user buffer from %x\n", Mdl)); - - NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen ); - - TI_DbgPrint(DEBUG_TCP, - ("Reading %d bytes to %x\n", RecvLen, RecvBuffer)); - - TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); - TI_DbgPrint + TI_DbgPrint(DEBUG_TCP, ("Connect Event\n")); + + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + TI_DbgPrint(DEBUG_TCP, + ("Completing Request %x\n", Bucket->Request.RequestContext)); + + Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 ); + + /* Frees the bucket allocated in TCPConnect */ + exFreePool( Bucket ); + } + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + } + + if( Connection->SignalState & SEL_ACCEPT ) { + /* Handle readable on a listening socket -- + * TODO: Implement filtering + */ + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n", + Connection, + IsListEmpty(&Connection->ListenRequest) ? + "empty" : "nonempty")); + + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, + &Connection->Lock )) != NULL ) { + PIO_STACK_LOCATION IrpSp; + + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Irp = Bucket->Request.RequestContext; + IrpSp = IoGetCurrentIrpStackLocation( Irp ); + + TI_DbgPrint(DEBUG_TCP,("Getting the socket\n")); + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + + Status = TCPServiceListeningSocket + ( Connection->AddressFile->Listener, + Bucket->AssociatedEndpoint, + (PTDI_REQUEST_KERNEL)&IrpSp->Parameters ); + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); + + if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, + &Connection->Lock ); + break; + } else { + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + } + + /* Things that happen after we're connected */ + if( Connection->SignalState & SEL_READ && + Connection->SignalState & SEL_CONNECT ) { + TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n", + IsListEmpty(&Connection->ReceiveRequest) ? + "empty" : "nonempty")); + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, + &Connection->Lock )) != NULL ) { + OSK_UINT RecvLen = 0, Received = 0; + PVOID RecvBuffer = 0; + + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Irp = Bucket->Request.RequestContext; + Mdl = Irp->MdlAddress; + + TI_DbgPrint(DEBUG_TCP, + ("Getting the user buffer from %x\n", Mdl)); + + NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen ); + + TI_DbgPrint(DEBUG_TCP, + ("Reading %d bytes to %x\n", RecvLen, RecvBuffer)); + + TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); + TI_DbgPrint + (DEBUG_TCP, + ("Connection->SocketContext: %x\n", + Connection->SocketContext)); + TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + + Status = TCPTranslateError + ( OskitTCPRecv( Connection->SocketContext, + RecvBuffer, + RecvLen, + &Received, + 0 ) ); + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); + + if( Status == STATUS_SUCCESS ) { + TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n", + Received, Status)); + Complete( Bucket->Request.RequestContext, + STATUS_SUCCESS, Received ); + exFreePool( Bucket ); + } else if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry, + &Connection->Lock ); + break; + } else { + TI_DbgPrint(DEBUG_TCP, + ("Completing Receive request: %x %x\n", + Bucket->Request, Status)); + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + } + if( Connection->SignalState & SEL_WRITE && + Connection->SignalState & SEL_CONNECT ) { + TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n", + IsListEmpty(&Connection->SendRequest) ? + "empty" : "nonempty")); + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, + &Connection->Lock )) != NULL ) { + OSK_UINT SendLen = 0, Sent = 0; + PVOID SendBuffer = 0; + + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Irp = Bucket->Request.RequestContext; + Mdl = Irp->MdlAddress; + + TI_DbgPrint(DEBUG_TCP, + ("Getting the user buffer from %x\n", Mdl)); + + NdisQueryBuffer( Mdl, &SendBuffer, &SendLen ); + + TI_DbgPrint(DEBUG_TCP, + ("Writing %d bytes to %x\n", SendLen, SendBuffer)); + + TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); + TI_DbgPrint (DEBUG_TCP, ("Connection->SocketContext: %x\n", Connection->SocketContext)); - TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); - - Status = TCPTranslateError - ( OskitTCPRecv( Connection->SocketContext, - RecvBuffer, - RecvLen, - &Received, - 0 ) ); - - TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); - - if( Status == STATUS_SUCCESS ) { - TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n", - Received, Status)); - - Complete( Bucket->Request.RequestContext, - STATUS_SUCCESS, Received ); - exFreePool( Bucket ); - } else if( Status == STATUS_PENDING ) { - ExInterlockedInsertHeadList - ( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock ); - Connection->SignalState |= SEL_READ; - break; - } else { - TI_DbgPrint(DEBUG_TCP, - ("Completing Receive request: %x %x\n", - Bucket->Request, Status)); - Complete( Bucket->Request.RequestContext, Status, 0 ); - exFreePool( Bucket ); - } - } - } - if( Connection->SignalState & SEL_WRITE ) { - TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n", - IsListEmpty(&Connection->SendRequest) ? - "empty" : "nonempty")); - - Connection->SignalState &= ~SEL_WRITE; - while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, - &Connection->Lock )) != NULL ) { - OSK_UINT SendLen = 0, Sent = 0; - PVOID SendBuffer = 0; - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Irp = Bucket->Request.RequestContext; - Mdl = Irp->MdlAddress; - - TI_DbgPrint(DEBUG_TCP, - ("Getting the user buffer from %x\n", Mdl)); - - NdisQueryBuffer( Mdl, &SendBuffer, &SendLen ); - - TI_DbgPrint(DEBUG_TCP, - ("Writing %d bytes to %x\n", SendLen, SendBuffer)); - - TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); - TI_DbgPrint - (DEBUG_TCP, - ("Connection->SocketContext: %x\n", - Connection->SocketContext)); - - Status = TCPTranslateError - ( OskitTCPSend( Connection->SocketContext, - SendBuffer, - SendLen, - &Sent, - 0 ) ); - - TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent)); - - if( Status == STATUS_SUCCESS ) { - TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n", + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + + Status = TCPTranslateError + ( OskitTCPSend( Connection->SocketContext, + SendBuffer, + SendLen, + &Sent, + 0 ) ); + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent)); + + if( Status == STATUS_SUCCESS ) { + TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n", Sent, Status)); - - Complete( Bucket->Request.RequestContext, - STATUS_SUCCESS, Sent ); - exFreePool( Bucket ); - } else if( Status == STATUS_PENDING ) { - ExInterlockedInsertHeadList - ( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock ); - Connection->SignalState |= SEL_WRITE; - break; - } else { - TI_DbgPrint(DEBUG_TCP, - ("Completing Send request: %x %x\n", - Bucket->Request, Status)); - Complete( Bucket->Request.RequestContext, Status, 0 ); - exFreePool( Bucket ); - } - } - } - - return Connection->SignalState; -} - -static VOID DrainSignals() { - PCONNECTION_ENDPOINT Connection; - PLIST_ENTRY CurrentEntry, NextEntry; - ULONG NewState; - KIRQL OldIrql; - - KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql); - CurrentEntry = SignalledConnectionsList.Flink; - while (CurrentEntry != &SignalledConnectionsList) - { - NextEntry = CurrentEntry->Flink; - Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT, - SignalList ); - - KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql); - NewState = HandleSignalledConnection(Connection); - KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql); - - if (NewState == SEL_FIN || NewState == 0) - { - RemoveEntryList(CurrentEntry); - } - - CurrentEntry = NextEntry; - } - KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql); + Complete( Bucket->Request.RequestContext, + STATUS_SUCCESS, Sent ); + exFreePool( Bucket ); + } else if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList( &Connection->SendRequest, &Bucket->Entry, + &Connection->Lock ); + break; + } else { + TI_DbgPrint(DEBUG_TCP, + ("Completing Send request: %x %x\n", + Bucket->Request, Status)); + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + } + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + if (!Connection->SocketContext) + { + TCPFreeConnectionEndpoint(Connection); + } + + CurrentEntry = NextEntry; + + KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); + } + + KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); }
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { @@ -314,7 +325,7 @@ RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));
/* Initialize spin lock that protects the connection endpoint file object */ - TcpipInitializeSpinLock(&Connection->Lock); + KeInitializeSpinLock(&Connection->Lock); InitializeListHead(&Connection->ConnectRequest); InitializeListHead(&Connection->ListenRequest); InitializeListHead(&Connection->ReceiveRequest); @@ -323,19 +334,32 @@ /* Save client context pointer */ Connection->ClientContext = ClientContext;
+ /* Add connection endpoint to global list */ + ExInterlockedInsertTailList(&ConnectionEndpointListHead, + &Connection->ListEntry, + &ConnectionEndpointListLock); + 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); + exFreePool( Connection ); }
NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, UINT Family, UINT Type, UINT Proto ) { NTSTATUS Status; - - TcpipRecursiveMutexEnter(&TCPLock); + KIRQL OldIrql; + + KeAcquireSpinLock(&Connection->Lock, &OldIrql);
TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, " "Proto %d\n", @@ -352,7 +376,7 @@ TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n", Connection->SocketContext));
- TcpipRecursiveMutexLeave(&TCPLock); + KeReleaseSpinLock(&Connection->Lock, OldIrql);
return Status; } @@ -370,13 +394,9 @@ IPPacket->TotalSize, IPPacket->HeaderSize));
- TcpipRecursiveMutexEnter( &TCPLock ); - OskitTCPReceiveDatagram( IPPacket->Header, IPPacket->TotalSize, IPPacket->HeaderSize ); - - TcpipRecursiveMutexLeave( &TCPLock ); }
/* event.c */ @@ -447,10 +467,7 @@ PsTerminateSystemThread(Status); }
- TcpipRecursiveMutexEnter( &TCPLock ); TimerOskitTCP( Next == NextFast, Next == NextSlow ); - TcpipRecursiveMutexLeave( &TCPLock ); - if (Next == NextSlow) { DrainSignals(); } @@ -483,9 +500,6 @@ { NTSTATUS Status;
- TcpipRecursiveMutexInit( &TCPLock ); - KeInitializeSpinLock( &SignalledConnectionsLock ); - InitializeListHead( &SignalledConnectionsList ); Status = TCPMemStartup(); if ( ! NT_SUCCESS(Status) ) { return Status; @@ -497,10 +511,8 @@ return Status; }
- TcpipRecursiveMutexEnter(&TCPLock); RegisterOskitTCPEventHandlers( &EventHandlers ); InitOskitTCP(); - TcpipRecursiveMutexLeave(&TCPLock);
/* Register this protocol with IP layer */ IPRegisterProtocol(IPPROTO_TCP, TCPReceive); @@ -545,9 +557,7 @@
TCPInitialized = FALSE;
- TcpipRecursiveMutexEnter(&TCPLock); DeinitOskitTCP(); - TcpipRecursiveMutexLeave(&TCPLock);
PortsShutdown( &TCPPorts );
@@ -597,6 +607,7 @@ USHORT RemotePort; PTDI_BUCKET Bucket; PNEIGHBOR_CACHE_ENTRY NCE; + KIRQL OldIrql;
TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n"));
@@ -625,7 +636,7 @@ AddressToBind = AddressToConnect; AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
- TcpipRecursiveMutexEnter(&TCPLock); + KeAcquireSpinLock(&Connection->Lock, &OldIrql);
Status = TCPTranslateError ( OskitTCPBind( Connection->SocketContext, @@ -640,25 +651,28 @@
Status = TCPTranslateError ( OskitTCPConnect( Connection->SocketContext, - Connection, &AddressToConnect, sizeof(AddressToConnect) ) ); + + KeReleaseSpinLock(&Connection->Lock, OldIrql);
if (Status == STATUS_PENDING) { Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); - if( !Bucket ) return STATUS_NO_MEMORY; + if( !Bucket ) + { + return STATUS_NO_MEMORY; + }
Bucket->Request.RequestNotifyObject = (PVOID)Complete; Bucket->Request.RequestContext = Context; - - IoMarkIrpPending((PIRP)Context); - ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, &Connection->Lock ); - } - } - - TcpipRecursiveMutexLeave(&TCPLock); + ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, + &Connection->Lock ); + } + } else { + KeReleaseSpinLock(&Connection->Lock, OldIrql); + }
return Status; } @@ -671,12 +685,11 @@ PTCP_COMPLETION_ROUTINE Complete, PVOID Context ) { NTSTATUS Status = STATUS_INVALID_PARAMETER; - - ASSERT_LOCKED(&TCPLock); + KIRQL OldIrql;
TI_DbgPrint(DEBUG_TCP,("started\n"));
- TcpipRecursiveMutexEnter(&TCPLock); + KeAcquireSpinLock(&Connection->Lock, &OldIrql);
if (Flags & TDI_DISCONNECT_RELEASE) Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext)); @@ -684,7 +697,7 @@ if ((Flags & TDI_DISCONNECT_ABORT) || !Flags) Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD));
- TcpipRecursiveMutexLeave(&TCPLock); + KeReleaseSpinLock(&Connection->Lock, OldIrql);
TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status));
@@ -694,20 +707,20 @@ NTSTATUS TCPClose ( PCONNECTION_ENDPOINT Connection ) { NTSTATUS Status; + KIRQL OldIrql; + PVOID Socket;
TI_DbgPrint(DEBUG_TCP,("TCPClose started\n"));
- /* Make our code remove all pending IRPs */ - Connection->SignalState |= SEL_FIN; - HandleSignalledConnection(Connection); - - TcpipRecursiveMutexEnter(&TCPLock); - - Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) ); - if (Status == STATUS_SUCCESS) - Connection->SocketContext = NULL; - - TcpipRecursiveMutexLeave(&TCPLock); + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + Socket = Connection->SocketContext; + Connection->SocketContext = NULL; + Status = TCPTranslateError( OskitTCPClose( Socket ) ); + if (!NT_SUCCESS(Status)) + { + Connection->SocketContext = Socket; + } + KeReleaseSpinLock(&Connection->Lock, OldIrql);
TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status));
@@ -726,17 +739,18 @@ UINT DataLen, Received = 0; NTSTATUS Status; PTDI_BUCKET Bucket; + KIRQL OldIrql;
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n", ReceiveLength, Connection->SocketContext));
+ NdisQueryBuffer( Buffer, &DataBuffer, &DataLen ); + + TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen)); + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + ASSERT_KM_POINTER(Connection->SocketContext); - - NdisQueryBuffer( Buffer, &DataBuffer, &DataLen ); - - TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen)); - - TcpipRecursiveMutexEnter(&TCPLock);
Status = TCPTranslateError ( OskitTCPRecv @@ -746,7 +760,7 @@ &Received, ReceiveFlags ) );
- TcpipRecursiveMutexLeave(&TCPLock); + KeReleaseSpinLock(&Connection->Lock, OldIrql);
TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received));
@@ -763,9 +777,8 @@ Bucket->Request.RequestContext = Context; *BytesReceived = 0;
- IoMarkIrpPending((PIRP)Context); - - ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock ); + ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, + &Connection->Lock ); TI_DbgPrint(DEBUG_TCP,("Queued read irp\n")); } else { TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received)); @@ -788,8 +801,9 @@ UINT Sent = 0; NTSTATUS Status; PTDI_BUCKET Bucket; - - ASSERT_LOCKED(&TCPLock); + KIRQL OldIrql; + + KeAcquireSpinLock(&Connection->Lock, &OldIrql);
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n", SendLength, Connection->SocketContext)); @@ -799,15 +813,13 @@ TI_DbgPrint(DEBUG_TCP,("Connection = %x\n", Connection)); TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n", Connection->SocketContext)); - - TcpipRecursiveMutexEnter(&TCPLock);
Status = TCPTranslateError ( OskitTCPSend( Connection->SocketContext, (OSK_PCHAR)BufferData, SendLength, &Sent, 0 ) );
- TcpipRecursiveMutexLeave(&TCPLock); + KeReleaseSpinLock(&Connection->Lock, OldIrql);
TI_DbgPrint(DEBUG_TCP,("OskitTCPSend: %x, %d\n", Status, Sent));
@@ -823,10 +835,9 @@ Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; *BytesSent = 0; - - IoMarkIrpPending((PIRP)Context);
- ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock ); + ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, + &Connection->Lock ); TI_DbgPrint(DEBUG_TCP,("Queued write irp\n")); } else { TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent)); @@ -865,14 +876,15 @@ OSK_UI16 LocalPort, RemotePort; PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address; NTSTATUS Status; - - TcpipRecursiveMutexEnter(&TCPLock); + KIRQL OldIrql; + + KeAcquireSpinLock(&Connection->Lock, &OldIrql);
Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext, &LocalAddress, &LocalPort, &RemoteAddress, &RemotePort));
- TcpipRecursiveMutexLeave(&TCPLock); + KeReleaseSpinLock(&Connection->Lock, OldIrql);
if (!NT_SUCCESS(Status)) return Status;
Modified: trunk/reactos/lib/drivers/ip/transport/udp/udp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/ud... ============================================================================== --- trunk/reactos/lib/drivers/ip/transport/udp/udp.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/transport/udp/udp.c [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -172,6 +172,9 @@ USHORT RemotePort; NTSTATUS Status; PNEIGHBOR_CACHE_ENTRY NCE; + KIRQL OldIrql; + + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -186,10 +189,12 @@ break;
default: + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_UNSUCCESSFUL; }
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_NETWORK_UNREACHABLE; }
@@ -213,13 +218,19 @@ DataSize );
if( !NT_SUCCESS(Status) ) + { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; + }
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL ))) { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); FreeNdisPacket(Packet.NdisPacket); return Status; } + + KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
return STATUS_SUCCESS; }
Modified: trunk/reactos/lib/drivers/oskittcp/include/oskittcp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/oskittcp/includ... ============================================================================== --- trunk/reactos/lib/drivers/oskittcp/include/oskittcp.h [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/oskittcp/include/oskittcp.h [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -123,7 +123,7 @@ OSK_UINT *OutLen, OSK_UINT Flags );
-extern int OskitTCPConnect( void *socket, void *connection, +extern int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ); extern int OskitTCPClose( void *socket );
@@ -131,7 +131,7 @@ void *nam, OSK_UINT namelen );
extern int OskitTCPAccept( void *socket, void **new_socket, - void *addr_out, + void *context, void *addr_out, OSK_UINT addr_len, OSK_UINT *out_addr_len, OSK_UINT finish_accept ); @@ -187,4 +187,27 @@ #define FREAD 0x0001 #define FWRITE 0x0002
+/* Don't define this unless your are insane or aicom */ +//#define LOCK_SPAM + +#ifdef LOCK_SPAM +#define OSKLock() if (!KeTryToAcquireSpinLockAtDpcLevel(&OSKLock)) \ + { \ + DbgPrint("OSKLock WAIT (%s)\n", __FUNCTION__); \ + KeAcquireSpinLockAtDpcLevel(&OSKLock); \ + } \ + DbgPrint("OSKLock >>>> (%s)\n", __FUNCTION__) + +#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock); \ + DbgPrint("OSKLock <<<< (%s)\n", __FUNCTION__) +#else +#define OSKLock() KeAcquireSpinLockAtDpcLevel(&OSKLock) +#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock) +#endif + +#define OSKLockAndRaise(x) KeRaiseIrql(DISPATCH_LEVEL, x); \ + OSKLock() +#define OSKUnlockAndLower(x) OSKUnlock(); \ + KeLowerIrql(x) + #endif/*OSKITTCP_H*/
Modified: trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/oskittcp/oskitt... ============================================================================== --- trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c [iso-8859-1] Sat Nov 14 19:38:02 2009 @@ -23,6 +23,8 @@ //OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA; OSK_UINT OskitDebugTraceLevel = 0;
+KSPIN_LOCK OSKLock; + /* SPL */ unsigned cpl; unsigned net_imask; @@ -45,6 +47,7 @@
void InitOskitTCP() { OS_DbgPrint(OSK_MID_TRACE,("Init Called\n")); + KeInitializeSpinLock(&OSKLock); OS_DbgPrint(OSK_MID_TRACE,("MB Init\n")); mbinit(); OS_DbgPrint(OSK_MID_TRACE,("Rawip Init\n")); @@ -66,12 +69,19 @@ }
void TimerOskitTCP( int FastTimer, int SlowTimer ) { + KIRQL OldIrql; + + /* This function is a special case in which we cannot use OSKLock/OSKUnlock + * because we don't enter with the connection lock held */ + + OSKLockAndRaise(&OldIrql); if ( SlowTimer ) { tcp_slowtimo(); } if ( FastTimer ) { tcp_fasttimo(); } + OSKUnlockAndLower(OldIrql); }
void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers ) { @@ -115,12 +125,16 @@ int proto ) { struct socket *so; + + OSKLock(); int error = socreate(domain, &so, type, proto); if( !error ) { so->so_connection = context; so->so_state |= SS_NBIO; *aso = so; } + OSKUnlock(); + return error; }
@@ -153,8 +167,11 @@
OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len));
+ OSKLock(); error = soreceive( connection, NULL, &uio, NULL, NULL /* SCM_RIGHTS */, &tcp_flags ); + OSKUnlock(); + *OutLen = Len - uio.uio_resid;
return error; @@ -182,14 +199,15 @@ addr.sa_family = addr.sa_len; addr.sa_len = sizeof(struct sockaddr);
+ OSKLock(); error = sobind(so, &sabuf); + OSKUnlock();
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); return (error); }
-int OskitTCPConnect( void *socket, void *connection, - void *nam, OSK_UINT namelen ) { +int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) { struct socket *so = socket; int error = EFAULT; struct mbuf sabuf; @@ -197,8 +215,7 @@
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
- so->so_connection = connection; - + OSKLock(); if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { error = EALREADY; goto done; @@ -217,7 +234,9 @@
error = soconnect(so, &sabuf);
- if (error) + if (error == EINPROGRESS) + goto done; + else if (error) goto bad;
if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { @@ -232,34 +251,49 @@ error = EINTR;
done: + OSKUnlock(); OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); return (error); }
int OskitTCPDisconnect(void *socket) { - if (!socket) - return OSK_ESHUTDOWN; - - return sodisconnect(socket); + int error; + + if (!socket) + return OSK_ESHUTDOWN; + + OSKLock(); + error = sodisconnect(socket); + OSKUnlock(); + + return error; }
int OskitTCPShutdown( void *socket, int disconn_type ) { - if (!socket) - return OSK_ESHUTDOWN; - - return soshutdown( socket, disconn_type ); + int error; + + if (!socket) + return OSK_ESHUTDOWN; + + OSKLock(); + error = soshutdown( socket, disconn_type ); + OSKUnlock(); + + return error; }
int OskitTCPClose( void *socket ) { - struct socket *so = socket; - - if (!socket) - return OSK_ESHUTDOWN; - - so->so_connection = 0; - soclose( so ); - return 0; + int error; + + if (!socket) + return OSK_ESHUTDOWN; + + OSKLock(); + error = soclose( socket ); + OSKUnlock(); + + return error; }
int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, @@ -281,7 +315,10 @@ uio.uio_rw = UIO_WRITE; uio.uio_procp = NULL;
+ OSKLock(); error = sosend( socket, NULL, &uio, NULL, NULL, 0 ); + OSKUnlock(); + *OutLen = Len - uio.uio_resid;
return error; @@ -289,6 +326,7 @@
int OskitTCPAccept( void *socket, void **new_socket, + void *context, void *AddrOut, OSK_UINT AddrLen, OSK_UINT *OutAddrLen, @@ -317,11 +355,12 @@ /* that's a copyin actually */ namelen = *OutAddrLen;
+ OSKLock(); + s = splnet();
#if 0 if ((head->so_options & SO_ACCEPTCONN) == 0) { - splx(s); OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: head->so_options = %x, wanted bit %x\n", head->so_options, SO_ACCEPTCONN)); error = EINVAL; @@ -333,38 +372,9 @@ head->so_q, head->so_state));
if ((head->so_state & SS_NBIO) && head->so_q == NULL) { - splx(s); error = EWOULDBLOCK; goto out; } - - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - while (head->so_q == NULL && head->so_error == 0) { - if (head->so_state & SS_CANTRCVMORE) { - head->so_error = ECONNABORTED; - break; - } - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - error = tsleep((caddr_t)&head->so_timeo, PSOCK | PCATCH, - "accept", 0); - if (error) { - splx(s); - goto out; - } - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - } - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - -#if 0 - if (head->so_error) { - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - error = head->so_error; - head->so_error = 0; - splx(s); - goto out; - } - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); -#endif
/* * At this point we know that there is at least one connection @@ -384,19 +394,20 @@ head->so_q = so->so_q; head->so_qlen--;
- *newso = so; - - /*so->so_state &= ~SS_COMP;*/ - mnam.m_data = (char *)&sa; mnam.m_len = sizeof(sa);
- (void) soaccept(so, &mnam); - - so->so_state = SS_NBIO | SS_ISCONNECTED; + error = soaccept(so, &mnam); + if (error) + goto out; + + so->so_state |= SS_NBIO | SS_ISCONNECTED; so->so_q = so->so_q0 = NULL; so->so_qlen = 0; so->so_head = 0; + so->so_connection = context; + + *newso = so;
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); if (name) { @@ -406,9 +417,10 @@ *OutAddrLen = namelen; /* copyout actually */ } OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - splx(s); } out: + splx(s); + OSKUnlock(); OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Returning %d\n", error)); return (error); } @@ -421,10 +433,20 @@
void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, OSK_UINT IpHeaderLen ) { - struct mbuf *Ip = m_devget( (char *)Data, Len, 0, NULL, NULL ); + struct mbuf *Ip; struct ip *iph; - - if( !Ip ) return; /* drop the segment */ + KIRQL OldIrql; + + /* This function is a special case in which we cannot use OSKLock/OSKUnlock + * because we don't enter with the connection lock held */ + + OSKLockAndRaise(&OldIrql); + Ip = m_devget( (char *)Data, Len, 0, NULL, NULL ); + if( !Ip ) + { + OSKUnlockAndLower(OldIrql); + return; /* drop the segment */ + }
//memcpy( Ip->m_data, Data, Len ); Ip->m_pkthdr.len = IpHeaderLen; @@ -439,6 +461,7 @@ IpHeaderLen));
tcp_input(Ip, IpHeaderLen); + OSKUnlockAndLower(OldIrql);
/* The buffer Ip is freed by tcp_input */ } @@ -450,6 +473,7 @@ int size) { struct mbuf *m; + int error;
if (!socket) return OSK_ESHUTDOWN; @@ -457,16 +481,23 @@ if (size >= MLEN) return OSK_EINVAL;
+ OSKLock(); m = m_get(M_WAIT, MT_SOOPTS); if (!m) + { + OSKUnlock(); return OSK_ENOMEM; + }
m->m_len = size;
memcpy(m->m_data, buffer, size);
/* m is freed by sosetopt */ - return sosetopt(socket, level, optname, m); + error = sosetopt(socket, level, optname, m); + OSKUnlock(); + + return error; }
int OskitTCPGetSockOpt(void *socket, @@ -481,6 +512,7 @@ if (!socket) return OSK_ESHUTDOWN;
+ OSKLock(); error = sogetopt(socket, level, optname, &m); if (!error) { @@ -489,6 +521,7 @@ if (!buffer || oldsize < m->m_len) { m_freem(m); + OSKUnlock(); return OSK_EINVAL; }
@@ -496,6 +529,7 @@
m_freem(m); } + OSKUnlock();
return error; } @@ -507,7 +541,11 @@ return OSK_ESHUTDOWN;
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket)); + + OSKLock(); error = solisten( socket, backlog ); + OSKUnlock(); + OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
return error; @@ -524,11 +562,13 @@ if (!socket) return OSK_ESHUTDOWN;
+ OSKLock(); inp = (struct inpcb *)so->so_pcb; inp->inp_laddr.s_addr = LocalAddress; inp->inp_lport = LocalPort; inp->inp_faddr.s_addr = RemoteAddress; inp->inp_fport = RemotePort; + OSKUnlock();
return 0; } @@ -544,11 +584,13 @@ if (!socket) return OSK_ESHUTDOWN;
+ OSKLock(); inp = (struct inpcb *)so->so_pcb; *LocalAddress = inp->inp_laddr.s_addr; *LocalPort = inp->inp_lport; *RemoteAddress = inp->inp_faddr.s_addr; *RemotePort = inp->inp_fport; + OSKUnlock();
return 0; }