diff --git a/reactos/drivers/network/tcpip/datalink/lan.c b/reactos/drivers/network/tcpip/datalink/lan.c index 7928bf04ce3..5d6fdb8c12a 100644 --- a/reactos/drivers/network/tcpip/datalink/lan.c +++ b/reactos/drivers/network/tcpip/datalink/lan.c @@ -10,9 +10,6 @@ #include "precomp.h" -/* Define this to bugcheck on double complete */ -/* #define BREAK_ON_DOUBLE_COMPLETE */ - UINT TransferDataCalled = 0; UINT TransferDataCompleteCalled = 0; UINT LanReceiveWorkerCalled = 0; @@ -51,54 +48,6 @@ BOOLEAN ProtocolRegistered = FALSE; LIST_ENTRY AdapterListHead; KSPIN_LOCK AdapterListLock; -/* Double complete protection */ -KSPIN_LOCK LanSendCompleteLock; -LIST_ENTRY LanSendCompleteList; - -VOID LanChainCompletion( PLAN_ADAPTER Adapter, PNDIS_PACKET NdisPacket ) { - PLAN_WQ_ITEM PendingCompletion = - ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) ); - - if( !PendingCompletion ) return; - - PendingCompletion->Packet = NdisPacket; - PendingCompletion->Adapter = Adapter; - - ExInterlockedInsertTailList( &LanSendCompleteList, - &PendingCompletion->ListEntry, - &LanSendCompleteLock ); -} - -BOOLEAN LanShouldComplete( PLAN_ADAPTER Adapter, PNDIS_PACKET NdisPacket ) { - PLIST_ENTRY ListEntry; - PLAN_WQ_ITEM CompleteEntry; - KIRQL OldIrql; - - KeAcquireSpinLock( &LanSendCompleteLock, &OldIrql ); - for( ListEntry = LanSendCompleteList.Flink; - ListEntry != &LanSendCompleteList; - ListEntry = ListEntry->Flink ) { - CompleteEntry = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); - - if( CompleteEntry->Adapter == Adapter && - CompleteEntry->Packet == NdisPacket ) { - RemoveEntryList( ListEntry ); - KeReleaseSpinLock( &LanSendCompleteLock, OldIrql ); - ExFreePool( CompleteEntry ); - return TRUE; - } - } - KeReleaseSpinLock( &LanSendCompleteLock, OldIrql ); - - DbgPrint("NDIS completed the same send packet twice " - "(Adapter %x Packet %x)!!\n", Adapter, NdisPacket); -#ifdef BREAK_ON_DOUBLE_COMPLETE - KeBugCheck(0); -#endif - - return FALSE; -} - NDIS_STATUS NDISCall( PLAN_ADAPTER Adapter, NDIS_REQUEST_TYPE Type, @@ -283,13 +232,11 @@ VOID NTAPI ProtocolSendComplete( */ { TI_DbgPrint(DEBUG_DATALINK, ("Calling completion routine\n")); - if( LanShouldComplete( (PLAN_ADAPTER)BindingContext, Packet ) ) { - ASSERT_KM_POINTER(Packet); - ASSERT_KM_POINTER(PC(Packet)); - ASSERT_KM_POINTER(PC(Packet)->DLComplete); - (*PC(Packet)->DLComplete)( PC(Packet)->Context, Packet, Status); - TI_DbgPrint(DEBUG_DATALINK, ("Finished\n")); - } + ASSERT_KM_POINTER(Packet); + ASSERT_KM_POINTER(PC(Packet)); + ASSERT_KM_POINTER(PC(Packet)->DLComplete); + (*PC(Packet)->DLComplete)( PC(Packet)->Context, Packet, Status); + TI_DbgPrint(DEBUG_DATALINK, ("Finished\n")); } VOID LanReceiveWorker( PVOID Context ) { @@ -646,8 +593,6 @@ VOID LANTransmit( * not needed immediately */ GetDataPtr( NdisPacket, 0, &Data, &Size ); - LanChainCompletion( Adapter, NdisPacket ); - switch (Adapter->Media) { case NdisMedium802_3: EHeader = (PETH_HEADER)Data; @@ -1046,6 +991,7 @@ BOOLEAN BindAdapter( if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(DEBUG_DATALINK, ("Could not set packet filter (0x%X).\n", NdisStatus)); + IPUnregisterInterface(IF); IPDestroyInterface(IF); return FALSE; } @@ -1380,24 +1326,4 @@ VOID LANUnregisterProtocol( } } -VOID LANStartup() { - InitializeListHead( &LanSendCompleteList ); - KeInitializeSpinLock( &LanSendCompleteLock ); -} - -VOID LANShutdown() { - KIRQL OldIrql; - PLAN_WQ_ITEM WorkItem; - PLIST_ENTRY ListEntry; - - KeAcquireSpinLock( &LanSendCompleteLock, &OldIrql ); - while( !IsListEmpty( &LanSendCompleteList ) ) { - ListEntry = RemoveHeadList( &LanSendCompleteList ); - WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); - FreeNdisPacket( WorkItem->Packet ); - ExFreePool( WorkItem ); - } - KeReleaseSpinLock( &LanSendCompleteLock, OldIrql ); -} - /* EOF */ diff --git a/reactos/drivers/network/tcpip/tcpip/main.c b/reactos/drivers/network/tcpip/tcpip/main.c index a11b3c720c2..7ef1dcf8552 100644 --- a/reactos/drivers/network/tcpip/tcpip/main.c +++ b/reactos/drivers/network/tcpip/tcpip/main.c @@ -585,9 +585,6 @@ VOID NTAPI TiUnload( /* Shutdown network level protocol subsystem */ IPShutdown(); - /* Shutdown the lan worker */ - LANShutdown(); - /* Free NDIS buffer descriptors */ if (GlobalBufferPool) NdisFreeBufferPool(GlobalBufferPool); @@ -827,9 +824,6 @@ DriverEntry( return Status; } - /* Initialize the lan worker */ - LANStartup(); - /* Register protocol with NDIS */ /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */ Status = LANRegisterProtocol(&strNdisDeviceName); @@ -843,7 +837,6 @@ DriverEntry( NULL, 0, NULL); - LANShutdown(); TCPShutdown(); UDPShutdown(); RawIPShutdown(); @@ -863,7 +856,6 @@ DriverEntry( Status = LoopRegisterAdapter(NULL, NULL); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status)); - LANShutdown(); TCPShutdown(); UDPShutdown(); RawIPShutdown(); diff --git a/reactos/lib/drivers/ip/network/loopback.c b/reactos/lib/drivers/ip/network/loopback.c index cf5c4d3d287..8c331b32bf6 100644 --- a/reactos/lib/drivers/ip/network/loopback.c +++ b/reactos/lib/drivers/ip/network/loopback.c @@ -22,6 +22,7 @@ typedef struct _LAN_WQ_ITEM { KSPIN_LOCK LoopWorkLock; LIST_ENTRY LoopWorkList; WORK_QUEUE_ITEM LoopWorkItem; +BOOLEAN LoopReceiveWorkerBusy = FALSE; VOID NTAPI LoopReceiveWorker( PVOID Context ) { PLIST_ENTRY ListEntry; @@ -34,43 +35,46 @@ VOID NTAPI LoopReceiveWorker( PVOID Context ) { TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); - ListEntry = ExInterlockedRemoveHeadList( &LoopWorkList, &LoopWorkLock ); - WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); + while( (ListEntry = + ExInterlockedRemoveHeadList( &LoopWorkList, &LoopWorkLock )) ) { + WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); - TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem)); + TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem)); - Packet = WorkItem->Packet; - Adapter = WorkItem->Adapter; - BytesTransferred = WorkItem->BytesTransferred; + Packet = WorkItem->Packet; + Adapter = WorkItem->Adapter; + BytesTransferred = WorkItem->BytesTransferred; - ExFreePool( WorkItem ); + ExFreePool( WorkItem ); - IPPacket.NdisPacket = Packet; + IPPacket.NdisPacket = Packet; - TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n", - Packet, Adapter, BytesTransferred)); + TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n", + Packet, Adapter, BytesTransferred)); - NdisGetFirstBufferFromPacket(Packet, - &NdisBuffer, - &IPPacket.Header, - &IPPacket.ContigSize, - &IPPacket.TotalSize); + NdisGetFirstBufferFromPacket(Packet, + &NdisBuffer, + &IPPacket.Header, + &IPPacket.ContigSize, + &IPPacket.TotalSize); - IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred; - /* Determine which upper layer protocol that should receive - this packet and pass it to the correct receive handler */ + IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred; + /* Determine which upper layer protocol that should receive + this packet and pass it to the correct receive handler */ - TI_DbgPrint(MID_TRACE, - ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n", - IPPacket.ContigSize, IPPacket.TotalSize, - BytesTransferred)); + TI_DbgPrint(MID_TRACE, + ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n", + IPPacket.ContigSize, IPPacket.TotalSize, + BytesTransferred)); - IPPacket.Position = 0; + IPPacket.Position = 0; - IPReceive(Loopback, &IPPacket); + IPReceive(Loopback, &IPPacket); - FreeNdisPacket( Packet ); + FreeNdisPacket( Packet ); + } TI_DbgPrint(DEBUG_DATALINK, ("Leaving\n")); + LoopReceiveWorkerBusy = FALSE; } VOID LoopSubmitReceiveWork( @@ -80,19 +84,34 @@ VOID LoopSubmitReceiveWork( UINT BytesTransferred) { PLAN_WQ_ITEM WQItem; PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; + KIRQL OldIrql; + + TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql ); WQItem = ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) ); - if( !WQItem ) return; + if( !WQItem ) { + TcpipReleaseSpinLock( &LoopWorkLock, OldIrql ); + return; + } WQItem->Packet = Packet; WQItem->Adapter = Adapter; WQItem->BytesTransferred = BytesTransferred; - ExInterlockedInsertTailList( &LoopWorkList, &WQItem->ListEntry, &LoopWorkLock ); + InsertTailList( &LoopWorkList, &WQItem->ListEntry ); TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x BytesTrans %x\n", Packet, Adapter, BytesTransferred)); - ExQueueWorkItem( &LoopWorkItem, CriticalWorkQueue ); + if( !LoopReceiveWorkerBusy ) { + LoopReceiveWorkerBusy = TRUE; + ExQueueWorkItem( &LoopWorkItem, CriticalWorkQueue ); + TI_DbgPrint(DEBUG_DATALINK, + ("Work item inserted %x %x\n", &LoopWorkItem, WQItem)); + } else { + TI_DbgPrint(DEBUG_DATALINK, + ("LOOP WORKER BUSY %x %x\n", &LoopWorkItem, WQItem)); + } + TcpipReleaseSpinLock( &LoopWorkLock, OldIrql ); } VOID LoopTransmit( diff --git a/reactos/lib/drivers/ip/network/transmit.c b/reactos/lib/drivers/ip/network/transmit.c index 4684ddf487f..2c2c8d3320f 100644 --- a/reactos/lib/drivers/ip/network/transmit.c +++ b/reactos/lib/drivers/ip/network/transmit.c @@ -216,7 +216,13 @@ NTSTATUS SendFragments( return NDIS_STATUS_FAILURE; } - return IPSendFragment(IFC->NdisPacket, NCE, IFC); + if (!NT_SUCCESS((NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC)))) + { + FreeNdisPacket(IFC->NdisPacket); + ExFreePool(IFC); + } + + return NdisStatus; } NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE, diff --git a/reactos/lib/drivers/ip/transport/rawip/rawip.c b/reactos/lib/drivers/ip/transport/rawip/rawip.c index 003e2377444..818b91d0f21 100644 --- a/reactos/lib/drivers/ip/transport/rawip/rawip.c +++ b/reactos/lib/drivers/ip/transport/rawip/rawip.c @@ -230,7 +230,11 @@ NTSTATUS RawIPSendDatagram( TI_DbgPrint(MID_TRACE,("About to send datagram\n")); - IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL ); + if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL ))) + { + FreeNdisPacket(Packet.NdisPacket); + return Status; + } TI_DbgPrint(MID_TRACE,("Leaving\n")); diff --git a/reactos/lib/drivers/ip/transport/tcp/event.c b/reactos/lib/drivers/ip/transport/tcp/event.c index 1e4c571eefb..fcae4da093c 100644 --- a/reactos/lib/drivers/ip/transport/tcp/event.c +++ b/reactos/lib/drivers/ip/transport/tcp/event.c @@ -102,7 +102,11 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { Packet.SrcAddr = LocalAddress; Packet.DstAddr = RemoteAddress; - IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL ); + if (!NT_SUCCESS(IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL ))) + { + FreeNdisPacket(Packet.NdisPacket); + return OSK_EINVAL; + } return 0; } diff --git a/reactos/lib/drivers/ip/transport/udp/udp.c b/reactos/lib/drivers/ip/transport/udp/udp.c index ed39e071571..7fcd1e31c5e 100644 --- a/reactos/lib/drivers/ip/transport/udp/udp.c +++ b/reactos/lib/drivers/ip/transport/udp/udp.c @@ -47,8 +47,6 @@ NTSTATUS AddUDPHeaderIPv4( if (!NT_SUCCESS(Status)) return Status; - /* Build UDP header */ - UDPHeader = (PUDP_HEADER)((ULONG_PTR)IPPacket->Data - sizeof(UDP_HEADER)); /* Port values are already big-endian values */ UDPHeader->SourcePort = LocalPort; UDPHeader->DestPort = RemotePort; @@ -57,8 +55,6 @@ NTSTATUS AddUDPHeaderIPv4( /* Length of UDP header and data */ UDPHeader->Length = WH2N(DataLength + sizeof(UDP_HEADER)); - IPPacket->Data = ((PCHAR)UDPHeader) + sizeof(UDP_HEADER); - TI_DbgPrint(MID_TRACE, ("Packet: %d ip %d udp %d payload\n", (PCHAR)UDPHeader - (PCHAR)IPPacket->Header, (PCHAR)IPPacket->Data - (PCHAR)UDPHeader, @@ -204,7 +200,11 @@ NTSTATUS UDPSendDatagram( return STATUS_UNSUCCESSFUL; } - IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL ); + if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL ))) + { + FreeNdisPacket(Packet.NdisPacket); + return Status; + } return STATUS_SUCCESS; }