From ceeb351515abbe0df1242e5d0797e680969fc5a0 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Wed, 1 Dec 2004 08:14:15 +0000 Subject: [PATCH] - sanity check: assert DISPATCH_LEVEL for the dpc. - Added a DEBUG_LOCK that shows lock activity. - Moved crummy externs from event.c to tcp.h - Withdraw TCPCancelReceiveRequest: i didn't mean to commit that - Added signalled sockets list to TCP so that we don't do reentrant stuff from inside oskit. The signal list holds sockets that have been identified by oskit as needing service. - After packet receive and on the timer we drain this list, designalling each socket and completing relevant irps. - According to msdn, the io cancellation routine must release the cancel spin lock, but we're entered with it acquired. Our implementation in ntoskrnl matches this so the tcpip implementation was wrong. Removed acquire. - DDKAPI on DispCancelRequest. Avoid some stack corruption on DPCs that now shows up. - Make sure to IpMarkIrpPending and not edit flags by hand on Irps in dispatch. svn path=/trunk/; revision=11884 --- reactos/drivers/lib/ip/network/interface.c | 1 - reactos/drivers/lib/ip/transport/tcp/event.c | 141 ++------------ reactos/drivers/lib/ip/transport/tcp/tcp.c | 186 +++++++++++++++---- reactos/drivers/net/tcpip/datalink/lan.c | 2 + reactos/drivers/net/tcpip/include/debug.h | 1 + reactos/drivers/net/tcpip/include/tcp.h | 8 +- reactos/drivers/net/tcpip/include/titypes.h | 6 + reactos/drivers/net/tcpip/tcpip/dispatch.c | 40 ++-- reactos/drivers/net/tcpip/tcpip/fileobjs.c | 1 - reactos/drivers/net/tcpip/tcpip/lock.c | 7 +- reactos/drivers/net/tcpip/tcpip/main.c | 2 +- 11 files changed, 199 insertions(+), 196 deletions(-) diff --git a/reactos/drivers/lib/ip/network/interface.c b/reactos/drivers/lib/ip/network/interface.c index 7f478f0456e..5608a40dcf3 100644 --- a/reactos/drivers/lib/ip/network/interface.c +++ b/reactos/drivers/lib/ip/network/interface.c @@ -11,7 +11,6 @@ #include "precomp.h" - NTSTATUS GetInterfaceIPv4Address( PIP_INTERFACE Interface, ULONG TargetType, PULONG Address ) { diff --git a/reactos/drivers/lib/ip/transport/tcp/event.c b/reactos/drivers/lib/ip/transport/tcp/event.c index dd011e708ef..1ff89cf1e94 100644 --- a/reactos/drivers/lib/ip/transport/tcp/event.c +++ b/reactos/drivers/lib/ip/transport/tcp/event.c @@ -10,137 +10,34 @@ #include "precomp.h" -extern ULONG TCP_IPIdentification; -extern LIST_ENTRY SleepingThreadsList; -extern FAST_MUTEX SleepingThreadsLock; -extern RECURSIVE_MUTEX TCPLock; +extern VOID DrainSignals(); int TCPSocketState(void *ClientData, void *WhichSocket, void *WhichConnection, OSK_UINT NewState ) { - NTSTATUS Status = STATUS_SUCCESS; PCONNECTION_ENDPOINT Connection = WhichConnection; - PTCP_COMPLETION_ROUTINE Complete; - PTDI_BUCKET Bucket; - PLIST_ENTRY Entry; - TI_DbgPrint(MID_TRACE,("Called: NewState %x (Conn %x) (Change %x)\n", + TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n", NewState, Connection, Connection ? Connection->State ^ NewState : NewState)); - TcpipRecursiveMutexEnter( &TCPLock, TRUE ); - if( !Connection ) { - TI_DbgPrint(MID_TRACE,("Socket closing.\n")); + TI_DbgPrint(DEBUG_TCP,("Socket closing.\n")); Connection = FileFindConnectionByContext( WhichSocket ); if( !Connection ) { TcpipRecursiveMutexLeave( &TCPLock ); return 0; } else - TI_DbgPrint(MID_TRACE,("Found socket %x\n", Connection)); + TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection)); } - if( ((NewState & SEL_CONNECT) || (NewState & SEL_FIN)) && - !(Connection->State & (SEL_CONNECT | SEL_FIN)) ) { - while( !IsListEmpty( &Connection->ConnectRequest ) ) { - Connection->State |= NewState & (SEL_CONNECT | SEL_FIN); - Entry = RemoveHeadList( &Connection->ConnectRequest ); - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - TI_DbgPrint(MID_TRACE, - ("Completing Connect Request %x\n", Bucket->Request)); - if( NewState & SEL_FIN ) Status = STATUS_CONNECTION_REFUSED; - TcpipRecursiveMutexLeave( &TCPLock ); - Complete( Bucket->Request.RequestContext, Status, 0 ); - TcpipRecursiveMutexEnter( &TCPLock, TRUE ); - /* Frees the bucket allocated in TCPConnect */ - PoolFreeBuffer( Bucket ); - } + if( !Connection->Signalled ) { + Connection->Signalled = TRUE; + Connection->SignalState = NewState; + InsertTailList( &SignalledConnections, &Connection->SignalList ); } - if( (NewState & SEL_READ) || (NewState & SEL_FIN) ) { - TI_DbgPrint(MID_TRACE,("Readable (or closed): irp list %s\n", - IsListEmpty(&Connection->ReceiveRequest) ? - "empty" : "nonempty")); - - while( !IsListEmpty( &Connection->ReceiveRequest ) ) { - PIRP Irp; - OSK_UINT RecvLen = 0, Received = 0; - OSK_PCHAR RecvBuffer = 0; - PMDL Mdl; - NTSTATUS Status; - - Entry = RemoveHeadList( &Connection->ReceiveRequest ); - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - TI_DbgPrint(MID_TRACE, - ("Readable, Completing read request %x\n", - Bucket->Request)); - - Irp = Bucket->Request.RequestContext; - Mdl = Irp->MdlAddress; - - TI_DbgPrint(MID_TRACE, - ("Getting the user buffer from %x\n", Mdl)); - - NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen ); - - TI_DbgPrint(MID_TRACE, - ("Reading %d bytes to %x\n", RecvLen, RecvBuffer)); - - if( (NewState & SEL_FIN) && !RecvLen ) { - TI_DbgPrint(MID_TRACE, ("EOF From socket\n")); - Status = STATUS_END_OF_FILE; - Received = 0; - } else { - TI_DbgPrint(MID_TRACE, ("Connection: %x\n", Connection)); - TI_DbgPrint - (MID_TRACE, - ("Connection->SocketContext: %x\n", - Connection->SocketContext)); - TI_DbgPrint(MID_TRACE, ("RecvBuffer: %x\n", RecvBuffer)); - - Status = TCPTranslateError - ( OskitTCPRecv( Connection->SocketContext, - RecvBuffer, - RecvLen, - &Received, - 0 ) ); - } - - TI_DbgPrint(MID_TRACE,("TCP Bytes: %d\n", Received)); - - if( Status == STATUS_SUCCESS && Received != 0 ) { - TI_DbgPrint(MID_TRACE,("Received %d bytes with status %x\n", - Received, Status)); - - TI_DbgPrint(MID_TRACE, - ("Completing Receive Request: %x\n", - Bucket->Request)); - - TcpipRecursiveMutexLeave( &TCPLock ); - Complete( Bucket->Request.RequestContext, - STATUS_SUCCESS, Received ); - TcpipRecursiveMutexEnter( &TCPLock, TRUE ); - } else if( Status == STATUS_PENDING || - (Status == STATUS_SUCCESS && Received == 0) ) { - InsertHeadList( &Connection->ReceiveRequest, - &Bucket->Entry ); - break; - } else { - TI_DbgPrint(MID_TRACE, - ("Completing Receive request: %x %x\n", - Bucket->Request, Status)); - TcpipRecursiveMutexLeave( &TCPLock ); - Complete( Bucket->Request.RequestContext, Status, 0 ); - TcpipRecursiveMutexEnter( &TCPLock, TRUE ); - } - } - } - - TcpipRecursiveMutexLeave( &TCPLock ); return 0; } @@ -148,9 +45,9 @@ int TCPSocketState(void *ClientData, void TCPPacketSendComplete( PVOID Context, PNDIS_PACKET NdisPacket, NDIS_STATUS NdisStatus ) { - TI_DbgPrint(MID_TRACE,("called %x\n", NdisPacket)); + TI_DbgPrint(DEBUG_TCP,("called %x\n", NdisPacket)); FreeNdisPacket(NdisPacket); - TI_DbgPrint(MID_TRACE,("done\n")); + TI_DbgPrint(DEBUG_TCP,("done\n")); } #define STRINGIFY(x) #x @@ -175,10 +72,6 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { RemoteAddress.Type = LocalAddress.Type = IP_ADDRESS_V4; - DbgPrint("OSKIT SENDING PACKET *** %x -> %x\n", - LocalAddress.Address.IPv4Address, - RemoteAddress.Address.IPv4Address); - if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) return OSK_EADDRNOTAVAIL; @@ -186,7 +79,7 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { MaxLLHeaderSize + len ); if (NdisStatus != NDIS_STATUS_SUCCESS) { - TI_DbgPrint(MAX_TRACE, ("Error from NDIS: %08x\n", NdisStatus)); + TI_DbgPrint(DEBUG_TCP, ("Error from NDIS: %08x\n", NdisStatus)); return STATUS_NO_MEMORY; } @@ -201,7 +94,7 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { Packet.DstAddr = RemoteAddress; IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL ); - + if( !NT_SUCCESS(NdisStatus) ) return OSK_EINVAL; else return 0; } @@ -223,7 +116,7 @@ int TCPSleep( void *ClientData, void *token, int priority, char *msg, int tmio ) { PSLEEPING_THREAD SleepingThread; - TI_DbgPrint(MID_TRACE, + TI_DbgPrint(DEBUG_TCP, ("Called TSLEEP: tok = %x, pri = %d, wmesg = %s, tmio = %x\n", token, priority, msg, tmio)); @@ -236,7 +129,7 @@ int TCPSleep( void *ClientData, void *token, int priority, char *msg, InsertTailList( &SleepingThreadsList, &SleepingThread->Entry ); TcpipReleaseFastMutex( &SleepingThreadsLock ); - TI_DbgPrint(MID_TRACE,("Waiting on %x\n", token)); + TI_DbgPrint(DEBUG_TCP,("Waiting on %x\n", token)); KeWaitForSingleObject( &SleepingThread->Event, WrSuspended, KernelMode, @@ -249,7 +142,7 @@ int TCPSleep( void *ClientData, void *token, int priority, char *msg, PoolFreeBuffer( SleepingThread ); } - TI_DbgPrint(MID_TRACE,("Waiting finished: %x\n", token)); + TI_DbgPrint(DEBUG_TCP,("Waiting finished: %x\n", token)); return 0; } @@ -261,9 +154,9 @@ void TCPWakeup( void *ClientData, void *token ) { Entry = SleepingThreadsList.Flink; while( Entry != &SleepingThreadsList ) { SleepingThread = CONTAINING_RECORD(Entry, SLEEPING_THREAD, Entry); - TI_DbgPrint(MID_TRACE,("Sleeper @ %x\n", SleepingThread)); + TI_DbgPrint(DEBUG_TCP,("Sleeper @ %x\n", SleepingThread)); if( SleepingThread->SleepToken == token ) { - TI_DbgPrint(MID_TRACE,("Setting event to wake %x\n", token)); + TI_DbgPrint(DEBUG_TCP,("Setting event to wake %x\n", token)); KeSetEvent( &SleepingThread->Event, IO_NETWORK_INCREMENT, FALSE ); } Entry = Entry->Flink; diff --git a/reactos/drivers/lib/ip/transport/tcp/tcp.c b/reactos/drivers/lib/ip/transport/tcp/tcp.c index 1164c65d7f2..bbdbe367c55 100644 --- a/reactos/drivers/lib/ip/transport/tcp/tcp.c +++ b/reactos/drivers/lib/ip/transport/tcp/tcp.c @@ -13,10 +13,126 @@ LONG TCP_IPIdentification = 0; static BOOLEAN TCPInitialized = FALSE; static NPAGED_LOOKASIDE_LIST TCPSegmentList; +LIST_ENTRY SignalledConnections; LIST_ENTRY SleepingThreadsList; FAST_MUTEX SleepingThreadsLock; RECURSIVE_MUTEX TCPLock; +static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection, + ULONG NewState ) { + NTSTATUS Status = STATUS_SUCCESS; + PTCP_COMPLETION_ROUTINE Complete; + PTDI_BUCKET Bucket; + PLIST_ENTRY Entry; + + if( ((NewState & SEL_CONNECT) || (NewState & SEL_FIN)) && + + !(Connection->State & (SEL_CONNECT | SEL_FIN)) ) { + while( !IsListEmpty( &Connection->ConnectRequest ) ) { + Connection->State |= NewState & (SEL_CONNECT | SEL_FIN); + Entry = RemoveHeadList( &Connection->ConnectRequest ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + TI_DbgPrint(DEBUG_TCP, + ("Completing Connect Request %x\n", Bucket->Request)); + if( NewState & SEL_FIN ) Status = STATUS_CONNECTION_REFUSED; + Complete( Bucket->Request.RequestContext, Status, 0 ); + /* Frees the bucket allocated in TCPConnect */ + PoolFreeBuffer( Bucket ); + } + } + if( (NewState & SEL_READ) || (NewState & SEL_FIN) ) { + TI_DbgPrint(DEBUG_TCP,("Readable (or closed): irp list %s\n", + IsListEmpty(&Connection->ReceiveRequest) ? + "empty" : "nonempty")); + + while( !IsListEmpty( &Connection->ReceiveRequest ) ) { + PIRP Irp; + OSK_UINT RecvLen = 0, Received = 0; + OSK_PCHAR RecvBuffer = 0; + PMDL Mdl; + NTSTATUS Status; + + Entry = RemoveHeadList( &Connection->ReceiveRequest ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + TI_DbgPrint(DEBUG_TCP, + ("Readable, Completing read request %x\n", + Bucket->Request)); + + 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)); + + if( (NewState & SEL_FIN) && !RecvLen ) { + TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); + Status = STATUS_END_OF_FILE; + Received = 0; + } else { + 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 && Received != 0 ) { + TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n", + Received, Status)); + + TI_DbgPrint(DEBUG_TCP, + ("Completing Receive Request: %x\n", + Bucket->Request)); + + Complete( Bucket->Request.RequestContext, + STATUS_SUCCESS, Received ); + } else if( Status == STATUS_PENDING || + (Status == STATUS_SUCCESS && Received == 0) ) { + InsertHeadList( &Connection->ReceiveRequest, + &Bucket->Entry ); + break; + } else { + TI_DbgPrint(DEBUG_TCP, + ("Completing Receive request: %x %x\n", + Bucket->Request, Status)); + Complete( Bucket->Request.RequestContext, Status, 0 ); + } + } + } + + Connection->Signalled = FALSE; +} + +VOID DrainSignals() { + PCONNECTION_ENDPOINT Connection; + PLIST_ENTRY ListEntry; + + while( !IsListEmpty( &SignalledConnections ) ) { + ListEntry = RemoveHeadList( &SignalledConnections ); + Connection = CONTAINING_RECORD( ListEntry, CONNECTION_ENDPOINT, + SignalList ); + HandleSignalledConnection( Connection, Connection->SignalState ); + } +} + PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { PCONNECTION_ENDPOINT Connection = ExAllocatePool(NonPagedPool, sizeof(CONNECTION_ENDPOINT)); @@ -49,7 +165,7 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, UINT Family, UINT Type, UINT Proto ) { NTSTATUS Status; - TI_DbgPrint(MID_TRACE,("Called: Connection %x, Family %d, Type %d, " + TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, " "Proto %d\n", Connection, Family, Type, Proto)); @@ -62,7 +178,7 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, ASSERT_KM_POINTER(Connection->SocketContext); - TI_DbgPrint(MID_TRACE,("Connection->SocketContext %x\n", + TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n", Connection->SocketContext)); TcpipRecursiveMutexLeave( &TCPLock ); @@ -79,7 +195,7 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) * This is the low level interface for receiving TCP data */ { - TI_DbgPrint(MID_TRACE,("Sending packet %d (%d) to oskit\n", + TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to oskit\n", IPPacket->TotalSize, IPPacket->HeaderSize)); @@ -89,6 +205,8 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) IPPacket->TotalSize, IPPacket->HeaderSize ); + DrainSignals(); + TcpipRecursiveMutexLeave( &TCPLock ); } @@ -138,6 +256,7 @@ NTSTATUS TCPStartup(VOID) TcpipRecursiveMutexInit( &TCPLock ); ExInitializeFastMutex( &SleepingThreadsLock ); InitializeListHead( &SleepingThreadsList ); + InitializeListHead( &SignalledConnections ); RegisterOskitTCPEventHandlers( &EventHandlers ); InitOskitTCP(); @@ -196,7 +315,7 @@ NTSTATUS TCPTranslateError( int OskitError ) { default: Status = STATUS_INVALID_CONNECTION; break; } - TI_DbgPrint(MID_TRACE,("Error %d -> %x\n", OskitError, Status)); + TI_DbgPrint(DEBUG_TCP,("Error %d -> %x\n", OskitError, Status)); return Status; } @@ -209,7 +328,7 @@ NTSTATUS TCPBind PIP_ADDRESS LocalAddress; USHORT LocalPort; - TI_DbgPrint(MID_TRACE,("Called\n")); + TI_DbgPrint(DEBUG_TCP,("Called\n")); Status = AddrBuildAddress ((PTA_ADDRESS)ConnInfo->LocalAddress, @@ -227,7 +346,7 @@ NTSTATUS TCPBind &AddressToBind, sizeof(AddressToBind)); - TI_DbgPrint(MID_TRACE,("Leaving %x\n", Status)); + TI_DbgPrint(DEBUG_TCP,("Leaving %x\n", Status)); return Status; } @@ -268,7 +387,7 @@ NTSTATUS TCPConnect RemotePort); if (!NT_SUCCESS(Status)) { - TI_DbgPrint(MID_TRACE, ("Could not AddrBuildAddress in TCPConnect\n")); + TI_DbgPrint(DEBUG_TCP, ("Could not AddrBuildAddress in TCPConnect\n")); return Status; } @@ -302,15 +421,18 @@ NTSTATUS TCPClose ( PCONNECTION_ENDPOINT Connection ) { NTSTATUS Status; - TI_DbgPrint(MID_TRACE,("TCPClose started\n")); + TI_DbgPrint(DEBUG_TCP,("TCPClose started\n")); TcpipRecursiveMutexEnter( &TCPLock, TRUE ); Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) ); + if( Connection->Signalled ) + RemoveEntryList( &Connection->SignalList ); + TcpipRecursiveMutexLeave( &TCPLock ); - TI_DbgPrint(MID_TRACE,("TCPClose finished %x\n", Status)); + TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status)); return Status; } @@ -322,9 +444,9 @@ NTSTATUS TCPListen PVOID Context) { NTSTATUS Status; - TI_DbgPrint(MID_TRACE,("TCPListen started\n")); + TI_DbgPrint(DEBUG_TCP,("TCPListen started\n")); - TI_DbgPrint(MID_TRACE,("Connection->SocketContext %x\n", + TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n", Connection->SocketContext)); ASSERT(Connection); @@ -337,7 +459,7 @@ NTSTATUS TCPListen TcpipRecursiveMutexLeave( &TCPLock ); - TI_DbgPrint(MID_TRACE,("TCPListen finished %x\n", Status)); + TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status)); return Status; } @@ -347,25 +469,12 @@ NTSTATUS TCPAccept VOID **NewSocketContext ) { NTSTATUS Status; - TI_DbgPrint(MID_TRACE,("TCPAccept started\n")); + TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n")); Status = STATUS_UNSUCCESSFUL; - TI_DbgPrint(MID_TRACE,("TCPAccept finished %x\n", Status)); + TI_DbgPrint(DEBUG_TCP,("TCPAccept finished %x\n", Status)); return Status; } -VOID TCPCancelReceiveRequest( PVOID Context ) { - PLIST_ENTRY ListEntry; - PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)Context; - - TcpipRecursiveMutexEnter( &TCPLock, TRUE ); - for( ListEntry = Connection->ReceiveRequest.Flink; - ListEntry != &Connection->ReceiveRequest; - ListEntry = ListEntry->Flink ) { - - } - TcpipRecursiveMutexLeave( &TCPLock ); -} - NTSTATUS TCPReceiveData ( PCONNECTION_ENDPOINT Connection, PNDIS_BUFFER Buffer, @@ -379,7 +488,7 @@ NTSTATUS TCPReceiveData NTSTATUS Status; PTDI_BUCKET Bucket; - TI_DbgPrint(MID_TRACE,("Called for %d bytes\n", ReceiveLength)); + TI_DbgPrint(DEBUG_TCP,("Called for %d bytes\n", ReceiveLength)); ASSERT_KM_POINTER(Connection->SocketContext); @@ -387,7 +496,7 @@ NTSTATUS TCPReceiveData NdisQueryBuffer( Buffer, &DataBuffer, &DataLen ); - TI_DbgPrint(MID_TRACE,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen)); + TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen)); Status = TCPTranslateError ( OskitTCPRecv @@ -397,7 +506,7 @@ NTSTATUS TCPReceiveData &Received, ReceiveFlags ) ); - TI_DbgPrint(MID_TRACE,("OskitTCPReceive: %x, %d\n", Status, Received)); + TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received)); /* Keep this request around ... there was no data yet */ if( Status == STATUS_PENDING || @@ -405,7 +514,7 @@ NTSTATUS TCPReceiveData /* Freed in TCPSocketState */ Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) ); if( !Bucket ) { - TI_DbgPrint(MID_TRACE,("Failed to allocate bucket\n")); + TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n")); TcpipRecursiveMutexLeave( &TCPLock ); return STATUS_NO_MEMORY; } @@ -416,15 +525,15 @@ NTSTATUS TCPReceiveData InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry ); Status = STATUS_PENDING; - TI_DbgPrint(MID_TRACE,("Queued read irp\n")); + TI_DbgPrint(DEBUG_TCP,("Queued read irp\n")); } else { - TI_DbgPrint(MID_TRACE,("Got status %x, bytes %d\n", Status, Received)); + TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received)); *BytesReceived = Received; } TcpipRecursiveMutexLeave( &TCPLock ); - TI_DbgPrint(MID_TRACE,("Status %x\n", Status)); + TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status)); return Status; } @@ -441,8 +550,8 @@ NTSTATUS TCPSendData TcpipRecursiveMutexEnter( &TCPLock, TRUE ); - TI_DbgPrint(MID_TRACE,("Connection = %x\n", Connection)); - TI_DbgPrint(MID_TRACE,("Connection->SocketContext = %x\n", + TI_DbgPrint(DEBUG_TCP,("Connection = %x\n", Connection)); + TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n", Connection->SocketContext)); Status = OskitTCPSend( Connection->SocketContext, @@ -455,11 +564,12 @@ NTSTATUS TCPSendData VOID TCPTimeout(VOID) { static int Times = 0; + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); if( (Times++ % 5) == 0 ) { - TcpipRecursiveMutexEnter( &TCPLock, TRUE ); TimerOskitTCP(); - TcpipRecursiveMutexLeave( &TCPLock ); } + DrainSignals(); + TcpipRecursiveMutexLeave( &TCPLock ); } /* EOF */ diff --git a/reactos/drivers/net/tcpip/datalink/lan.c b/reactos/drivers/net/tcpip/datalink/lan.c index 9d7e3b2dc4d..341221141ac 100644 --- a/reactos/drivers/net/tcpip/datalink/lan.c +++ b/reactos/drivers/net/tcpip/datalink/lan.c @@ -276,6 +276,8 @@ VOID STDCALL ProtocolTransferDataComplete( PLAN_WQ_ITEM WQItem; PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + if( Status != NDIS_STATUS_SUCCESS ) return; WQItem = ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) ); if( !WQItem ) return; diff --git a/reactos/drivers/net/tcpip/include/debug.h b/reactos/drivers/net/tcpip/include/debug.h index a85ef448449..fc0eb72e8b3 100644 --- a/reactos/drivers/net/tcpip/include/debug.h +++ b/reactos/drivers/net/tcpip/include/debug.h @@ -31,6 +31,7 @@ #define DEBUG_RCACHE 0x00200000 #define DEBUG_NCACHE 0x00400000 #define DEBUG_CPOINT 0x00800000 +#define DEBUG_LOCK 0x01000000 #define DEBUG_ULTRA 0xFFFFFFFF #ifdef DBG diff --git a/reactos/drivers/net/tcpip/include/tcp.h b/reactos/drivers/net/tcpip/include/tcp.h index 20d65d2177b..0c0b3006de1 100644 --- a/reactos/drivers/net/tcpip/include/tcp.h +++ b/reactos/drivers/net/tcpip/include/tcp.h @@ -81,11 +81,15 @@ typedef struct _SLEEPING_THREAD { #define SRF_SYN TCP_SYN #define SRF_FIN TCP_FIN +extern LONG TCP_IPIdentification; +extern LIST_ENTRY SignalledConnections; +extern LIST_ENTRY SleepingThreadsList; +extern FAST_MUTEX SleepingThreadsLock; +extern RECURSIVE_MUTEX TCPLock; + PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ); VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ); -VOID TCPCancelReceiveRequest( PVOID Context ); - NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, UINT Family, UINT Type, UINT Proto ); diff --git a/reactos/drivers/net/tcpip/include/titypes.h b/reactos/drivers/net/tcpip/include/titypes.h index 1ce81946b71..6308bc54913 100644 --- a/reactos/drivers/net/tcpip/include/titypes.h +++ b/reactos/drivers/net/tcpip/include/titypes.h @@ -321,6 +321,12 @@ typedef struct _CONNECTION_ENDPOINT { LIST_ENTRY ConnectRequest; /* Queued connect rqueusts */ LIST_ENTRY ListenRequest; /* Queued listen requests */ LIST_ENTRY ReceiveRequest; /* Queued receive requests */ + + /* Signals */ + LIST_ENTRY SignalList; /* Entry in the list of sockets waiting for + * notification service to the client */ + UINT SignalState; /* Active signals from oskit */ + BOOLEAN Signalled; /* Are we a member of the signal list */ } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT; diff --git a/reactos/drivers/net/tcpip/tcpip/dispatch.c b/reactos/drivers/net/tcpip/tcpip/dispatch.c index f5295b2e522..c07dde5201a 100644 --- a/reactos/drivers/net/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/net/tcpip/tcpip/dispatch.c @@ -71,20 +71,18 @@ VOID DispCancelComplete( FileObject = (PFILE_OBJECT)Context; TranContext = (PTRANSPORT_CONTEXT)FileObject->FsContext; - - IoAcquireCancelSpinLock(&OldIrql); - TI_DbgPrint(DEBUG_IRP, ("Setting TranContext->CleanupEvent to signaled.\n")); /* Set the cleanup event */ KeSetEvent(&TranContext->CleanupEvent, 0, FALSE); + /* We are expected to release the cancel spin lock */ IoReleaseCancelSpinLock(OldIrql); TI_DbgPrint(DEBUG_IRP, ("Leaving.\n")); } -VOID DispCancelRequest( +VOID DDKAPI DispCancelRequest( PDEVICE_OBJECT Device, PIRP Irp) /* @@ -180,8 +178,6 @@ VOID DispDataRequestComplete( IoSetCancelRoutine(Irp, NULL); - KeSetEvent(&TranContext->CleanupEvent, 0, FALSE); - if (Irp->Cancel || TranContext->CancelIrps) { /* The IRP has been cancelled */ @@ -647,7 +643,7 @@ NTSTATUS DispTdiReceive( Status = DispPrepareIrpForCancel (TranContext->Handle.ConnectionContext, Irp, - (PDRIVER_CANCEL)TCPCancelReceiveRequest); + (PDRIVER_CANCEL)DispCancelRequest); TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress)); if (NT_SUCCESS(Status)) @@ -663,12 +659,8 @@ NTSTATUS DispTdiReceive( if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, BytesReceived); - } - } - - if (Status != STATUS_PENDING) - { - IrpSp->Control &= ~SL_PENDING_RETURNED; + } else + IoMarkIrpPending(Irp); } TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status)); @@ -735,15 +727,10 @@ NTSTATUS DispTdiReceiveDatagram( &BytesReceived, (PDATAGRAM_COMPLETION_ROUTINE)DispDataRequestComplete, Irp); - if (Status != STATUS_PENDING) - { + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, BytesReceived); - } - } - - if (Status != STATUS_PENDING) - { - IrpSp->Control &= ~SL_PENDING_RETURNED; + } else + IoMarkIrpPending(Irp); } TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status)); @@ -809,12 +796,8 @@ NTSTATUS DispTdiSend( if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, BytesReceived); - } - } - - if (Status != STATUS_PENDING) - { - IrpSp->Control &= ~SL_PENDING_RETURNED; + } else + IoMarkIrpPending( Irp ); } TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status)); @@ -883,7 +866,8 @@ NTSTATUS DispTdiSendDatagram( /* Return STATUS_PENDING because DispPrepareIrpForCancel marks Irp as pending */ Status = STATUS_PENDING; - } + } else + IoMarkIrpPending( Irp ); } TI_DbgPrint(DEBUG_IRP, ("Leaving.\n")); diff --git a/reactos/drivers/net/tcpip/tcpip/fileobjs.c b/reactos/drivers/net/tcpip/tcpip/fileobjs.c index 8c7fe6752f5..4ce6085eac0 100644 --- a/reactos/drivers/net/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/net/tcpip/tcpip/fileobjs.c @@ -378,7 +378,6 @@ NTSTATUS FileOpenConnection( if( !Connection ) return STATUS_NO_MEMORY; Status = TCPSocket( Connection, AF_INET, SOCK_STREAM, IPPROTO_TCP ); - DbgPrint("STATUS from OSKITTCP was %08x\n", Status); /* Return connection endpoint file object */ Request->Handle.ConnectionContext = Connection; diff --git a/reactos/drivers/net/tcpip/tcpip/lock.c b/reactos/drivers/net/tcpip/tcpip/lock.c index 0a37f4efb3c..d35cbfd83f9 100644 --- a/reactos/drivers/net/tcpip/tcpip/lock.c +++ b/reactos/drivers/net/tcpip/tcpip/lock.c @@ -49,9 +49,14 @@ VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { } UINT TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex, BOOL ToWrite ) { - return RecursiveMutexEnter( RecMutex, ToWrite ); + UINT Ret; + TI_DbgPrint(DEBUG_LOCK,("Locking\n")); + Ret = RecursiveMutexEnter( RecMutex, ToWrite ); + TI_DbgPrint(DEBUG_LOCK,("Locked\n")); + return Ret; } VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { + TI_DbgPrint(DEBUG_LOCK,("Unlocking\n")); RecursiveMutexLeave( RecMutex ); } diff --git a/reactos/drivers/net/tcpip/tcpip/main.c b/reactos/drivers/net/tcpip/tcpip/main.c index 2128710749e..218597f1d6c 100644 --- a/reactos/drivers/net/tcpip/tcpip/main.c +++ b/reactos/drivers/net/tcpip/tcpip/main.c @@ -12,7 +12,7 @@ #define NDEBUG #ifndef NDEBUG -DWORD DebugTraceLevel = 0x7fffffff; +DWORD DebugTraceLevel = DEBUG_TCP; #else DWORD DebugTraceLevel = 0; /*DEBUG_IP | DEBUG_PBUFFER | DEBUG_DATALINK;*/ #endif /* NDEBUG */