Author: cgutman Date: Sat Dec 20 19:29:35 2008 New Revision: 38213
URL: http://svn.reactos.org/svn/reactos?rev=38213&view=rev Log: - Merge aicom-network-fixes up to r38205
Modified: trunk/reactos/drivers/network/tcpip/datalink/lan.c trunk/reactos/drivers/network/tcpip/tcpip/main.c trunk/reactos/lib/drivers/ip/network/loopback.c trunk/reactos/lib/drivers/ip/network/transmit.c trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c trunk/reactos/lib/drivers/ip/transport/tcp/event.c trunk/reactos/lib/drivers/ip/transport/udp/udp.c
Modified: trunk/reactos/drivers/network/tcpip/datalink/lan.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/datal... ============================================================================== --- trunk/reactos/drivers/network/tcpip/datalink/lan.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/datalink/lan.c [iso-8859-1] Sat Dec 20 19:29:35 2008 @@ -9,9 +9,6 @@ */
#include "precomp.h" - -/* Define this to bugcheck on double complete */ -/* #define BREAK_ON_DOUBLE_COMPLETE */
UINT TransferDataCalled = 0; UINT TransferDataCompleteCalled = 0; @@ -51,54 +48,6 @@ 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 @@ */ { 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 @@ * 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 @@
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 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 */
Modified: trunk/reactos/drivers/network/tcpip/tcpip/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip... ============================================================================== --- trunk/reactos/drivers/network/tcpip/tcpip/main.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/tcpip/main.c [iso-8859-1] Sat Dec 20 19:29:35 2008 @@ -585,9 +585,6 @@ /* Shutdown network level protocol subsystem */ IPShutdown();
- /* Shutdown the lan worker */ - LANShutdown(); - /* Free NDIS buffer descriptors */ if (GlobalBufferPool) NdisFreeBufferPool(GlobalBufferPool); @@ -827,9 +824,6 @@ 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 @@ NULL, 0, NULL); - LANShutdown(); TCPShutdown(); UDPShutdown(); RawIPShutdown(); @@ -863,7 +856,6 @@ 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();
Modified: trunk/reactos/lib/drivers/ip/network/loopback.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/loop... ============================================================================== --- trunk/reactos/lib/drivers/ip/network/loopback.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/network/loopback.c [iso-8859-1] Sat Dec 20 19:29:35 2008 @@ -22,6 +22,7 @@ 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 @@
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
- ListEntry = ExInterlockedRemoveHeadList( &LoopWorkList, &LoopWorkLock ); - WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); - - TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem)); - - Packet = WorkItem->Packet; - Adapter = WorkItem->Adapter; - BytesTransferred = WorkItem->BytesTransferred; - - ExFreePool( WorkItem ); - - IPPacket.NdisPacket = Packet; - - TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n", - Packet, Adapter, BytesTransferred)); - - 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 */ - - TI_DbgPrint(MID_TRACE, - ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n", - IPPacket.ContigSize, IPPacket.TotalSize, - BytesTransferred)); - - IPPacket.Position = 0; - - IPReceive(Loopback, &IPPacket); - - FreeNdisPacket( Packet ); + while( (ListEntry = + ExInterlockedRemoveHeadList( &LoopWorkList, &LoopWorkLock )) ) { + WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); + + TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem)); + + Packet = WorkItem->Packet; + Adapter = WorkItem->Adapter; + BytesTransferred = WorkItem->BytesTransferred; + + ExFreePool( WorkItem ); + + IPPacket.NdisPacket = Packet; + + TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n", + Packet, Adapter, BytesTransferred)); + + 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 */ + + TI_DbgPrint(MID_TRACE, + ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n", + IPPacket.ContigSize, IPPacket.TotalSize, + BytesTransferred)); + + IPPacket.Position = 0; + + IPReceive(Loopback, &IPPacket); + + FreeNdisPacket( Packet ); + } TI_DbgPrint(DEBUG_DATALINK, ("Leaving\n")); + LoopReceiveWorkerBusy = FALSE; }
VOID LoopSubmitReceiveWork( @@ -80,19 +84,34 @@ 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(
Modified: trunk/reactos/lib/drivers/ip/network/transmit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/tran... ============================================================================== --- trunk/reactos/lib/drivers/ip/network/transmit.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/network/transmit.c [iso-8859-1] Sat Dec 20 19:29:35 2008 @@ -216,7 +216,13 @@ 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,
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 Dec 20 19:29:35 2008 @@ -230,7 +230,11 @@
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"));
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 Dec 20 19:29:35 2008 @@ -102,7 +102,11 @@ 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; }
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 Dec 20 19:29:35 2008 @@ -47,8 +47,6 @@ 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; @@ -56,8 +54,6 @@ UDPHeader->Checksum = 0; /* 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, @@ -204,7 +200,11 @@ 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; }