diff --git a/reactos/drivers/lib/ip/makefile b/reactos/drivers/lib/ip/makefile index 4196b572198..8ec4780308a 100644 --- a/reactos/drivers/lib/ip/makefile +++ b/reactos/drivers/lib/ip/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.8 2004/11/25 23:56:58 arty Exp $ +# $Id: makefile,v 1.9 2004/11/30 00:10:40 arty Exp $ PATH_TO_TOP = ../../.. @@ -12,6 +12,7 @@ TARGET_PCH = $(PATH_TO_TOP)/drivers/lib/ip/include/precomp.h TARGET_CFLAGS = \ -D__USE_W32API \ -DMEMTRACK \ + -D__NTDRIVER__ \ -D_SEH_NO_NATIVE_NLG \ -Wall -Werror \ -Iinclude \ @@ -35,7 +36,6 @@ TARGET_OBJECTS = \ network/neighbor.o \ network/ports.o \ network/receive.o \ - network/route.o \ network/router.o \ network/routines.o \ network/transmit.o \ diff --git a/reactos/drivers/lib/ip/network/address.c b/reactos/drivers/lib/ip/network/address.c index a6e8b0ceab5..38194a34c0b 100644 --- a/reactos/drivers/lib/ip/network/address.c +++ b/reactos/drivers/lib/ip/network/address.c @@ -181,12 +181,11 @@ NTSTATUS AddrGetAddress( */ NTSTATUS AddrBuildAddress( PTRANSPORT_ADDRESS TaAddress, - PIP_ADDRESS *Address, + PIP_ADDRESS Address, PUSHORT Port) { PTDI_ADDRESS_IP ValidAddr; PTA_ADDRESS TdiAddress = &TaAddress->Address[0]; - PIP_ADDRESS IPAddress; if (TdiAddress->AddressType != TDI_ADDRESS_TYPE_IP) { TI_DbgPrint @@ -203,12 +202,7 @@ NTSTATUS AddrBuildAddress( ValidAddr = (PTDI_ADDRESS_IP)TdiAddress->Address; - IPAddress = PoolAllocateBuffer(sizeof(IP_ADDRESS)); - if (!IPAddress) - return STATUS_INSUFFICIENT_RESOURCES; - - AddrInitIPv4(IPAddress, ValidAddr->in_addr); - *Address = IPAddress; + AddrInitIPv4(Address, ValidAddr->in_addr); *Port = ValidAddr->sin_port; return STATUS_SUCCESS; diff --git a/reactos/drivers/lib/ip/network/icmp.c b/reactos/drivers/lib/ip/network/icmp.c index c978f44b7a9..8d86d588dca 100644 --- a/reactos/drivers/lib/ip/network/icmp.c +++ b/reactos/drivers/lib/ip/network/icmp.c @@ -180,7 +180,7 @@ VOID ICMPTransmit( * IPPacket = Pointer to IP packet to transmit */ { - PROUTE_CACHE_NODE RCN; + PNEIGHBOR_CACHE_ENTRY NCE; TI_DbgPrint(DEBUG_ICMP, ("Called.\n")); @@ -189,15 +189,13 @@ VOID ICMPTransmit( IPv4Checksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize, 0); /* Get a route to the destination address */ - if (RouteGetRouteToDestination(&IPPacket->DstAddr, &RCN) == IP_SUCCESS) { + if ((NCE = RouteGetRouteToDestination(&IPPacket->DstAddr))) { /* Send the packet */ - IPSendDatagram(IPPacket, RCN, Complete, Context); + IPSendDatagram(IPPacket, NCE, Complete, Context); } else { - TI_DbgPrint(MIN_TRACE, ("RCN at (0x%X).\n", RCN)); - /* No route to destination (or no free resources) */ TI_DbgPrint(DEBUG_ICMP, ("No route to destination address 0x%X.\n", - IPPacket->DstAddr.Address.IPv4Address)); + IPPacket->DstAddr.Address.IPv4Address)); /* Discard packet */ Complete( Context, IPPacket->NdisPacket, NDIS_STATUS_NOT_ACCEPTED ); } diff --git a/reactos/drivers/lib/ip/network/ip.c b/reactos/drivers/lib/ip/network/ip.c index 5b6b16a581f..8a96bc79c49 100644 --- a/reactos/drivers/lib/ip/network/ip.c +++ b/reactos/drivers/lib/ip/network/ip.c @@ -18,6 +18,7 @@ KSPIN_LOCK NetTableListLock; UINT MaxLLHeaderSize; /* Largest maximum header size */ UINT MinLLFrameSize; /* Largest minimum frame size */ BOOLEAN IPInitialized = FALSE; +BOOLEAN IpWorkItemQueued = FALSE; NPAGED_LOOKASIDE_LIST IPPacketList; /* Work around calling timer at Dpc level */ @@ -109,6 +110,8 @@ PIP_PACKET IPInitializePacket( void STDCALL IPTimeout( PVOID Context ) { + IpWorkItemQueued = FALSE; + /* Check if datagram fragments have taken too long to assemble */ IPDatagramReassemblyTimeout(); @@ -238,7 +241,6 @@ BOOLEAN IPRegisterInterface( { KIRQL OldIrql; IP_ADDRESS NetworkAddress; - PROUTE_CACHE_NODE RCN; PNEIGHBOR_CACHE_ENTRY NCE; TI_DbgPrint(MID_TRACE, ("Called. IF (0x%X).\n", IF)); @@ -261,12 +263,6 @@ BOOLEAN IPRegisterInterface( TI_DbgPrint(MIN_TRACE, ("Could not add route due to insufficient resources.\n")); } - RCN = RouteAddRouteToDestination(&NetworkAddress, IF, NCE); - if (!RCN) { - TI_DbgPrint(MIN_TRACE, ("Could not create RCN.\n")); - TcpipReleaseSpinLock(&IF->Lock, OldIrql); - } - /* Add interface to the global interface list */ ASSERT(&IF->ListEntry); TcpipInterlockedInsertTailList(&InterfaceListHead, @@ -301,8 +297,6 @@ VOID IPUnregisterInterface( NBRemoveNeighbor(NCE); TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql3); - /* Ouch...three spinlocks acquired! Fortunately - we don't unregister interfaces very often */ RemoveEntryList(&IF->ListEntry); TcpipReleaseSpinLock(&InterfaceListLock, OldIrql3); } @@ -400,9 +394,6 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath) /* Start routing subsystem */ RouterStartup(); - /* Start route cache subsystem */ - RouteStartup(); - /* Start neighbor cache subsystem */ NBStartup(); @@ -444,9 +435,6 @@ NTSTATUS IPShutdown( /* Shutdown neighbor cache subsystem */ NBShutdown(); - /* Shutdown route cache subsystem */ - RouteShutdown(); - /* Shutdown routing subsystem */ RouterShutdown(); diff --git a/reactos/drivers/lib/ip/network/neighbor.c b/reactos/drivers/lib/ip/network/neighbor.c index a71dfab8d7a..a6062aaedaf 100644 --- a/reactos/drivers/lib/ip/network/neighbor.c +++ b/reactos/drivers/lib/ip/network/neighbor.c @@ -107,11 +107,6 @@ VOID NCETimeout( /* Flush packet queue */ NBFlushPacketQueue( NCE, TRUE, NDIS_STATUS_REQUEST_ABORTED ); NCE->EventCount = 0; - - /* Remove route cache entries with references to this NCE. - Remember that neighbor cache lock is acquired before the - route cache lock */ - RouteInvalidateNCE(NCE); } else { @@ -204,9 +199,6 @@ VOID NBShutdown(VOID) CurNCE = NeighborCache[i].Cache; while (CurNCE) { NextNCE = CurNCE->Next; - - /* Remove all references from route cache */ - RouteInvalidateNCE(CurNCE); /* Flush wait queue */ NBFlushPacketQueue( CurNCE, FALSE, STATUS_SUCCESS ); @@ -501,9 +493,6 @@ VOID NBRemoveNeighbor( *PrevNCE = CurNCE->Next; NBFlushPacketQueue( CurNCE, TRUE, NDIS_STATUS_REQUEST_ABORTED ); - - /* Remove all references from route cache */ - RouteInvalidateNCE(CurNCE); ExFreePool(CurNCE); break; diff --git a/reactos/drivers/lib/ip/network/route.c b/reactos/drivers/lib/ip/network/route.c deleted file mode 100644 index 279385921ac..00000000000 --- a/reactos/drivers/lib/ip/network/route.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS TCP/IP protocol driver - * FILE: network/route.c - * PURPOSE: Route cache - * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) - * NOTES: The route cache is implemented as a binary search - * tree to obtain fast searches - * - * This data is not authoritative. It is a searchable cache that allows - * quick access to route information to selected hosts. This information - * should always defer to the FIB. - * - * REVISIONS: - * CSH 01/08-2000 Created - */ - -#include "precomp.h" - - -/* This RCN is shared by all external nodes. It complicates things, - but the memory requirements are reduced by approximately 50%. - The RCN is protected by the route cache spin lock */ -PROUTE_CACHE_NODE ExternalRCN; -PROUTE_CACHE_NODE RouteCache; -KSPIN_LOCK RouteCacheLock; -NPAGED_LOOKASIDE_LIST IPRCNList; - - -#ifdef DBG -VOID PrintTree( - PROUTE_CACHE_NODE Node) -/* - * FUNCTION: Prints all nodes on tree - * ARGUMENTS: - * Node = Pointer to root node of tree - * NOTES: - * This function must be called with the route cache lock held. - */ -{ - if (IsInternalRCN(Node)) { - /* Traverse left subtree */ - PrintTree(Node->Left); - - /* Traverse right subtree */ - PrintTree(Node->Right); - - /* Finally check the node itself */ - TI_DbgPrint(MIN_TRACE, ("(Internal) Self,Parent,Left,Right,Data = (%08X, %08X, %08X, %08X, %08X).\n", - Node, Node->Parent, Node->Left, Node->Right, (ULONG_PTR)Node->Destination.Address.IPv4Address)); - } else - TI_DbgPrint(MIN_TRACE, ("(External) Self,Parent,Left,Right = (%08X, %08X, %08X, %08X).\n", - Node, Node->Parent, Node->Left, Node->Right)); -} -#endif - -UINT CountRouteNodes( PROUTE_CACHE_NODE Node ) { - if( !Node ) Node = RouteCache; - if( IsInternalRCN(Node) ) - return - /* Traverse left subtree */ - CountRouteNodes(Node->Left) + - /* Traverse right subtree */ - CountRouteNodes(Node->Right) + 1; - else - return 0; -} - -VOID FreeRCN( - PVOID Object) -/* - * FUNCTION: Frees an route cache node object - * ARGUMENTS: - * Object = Pointer to an route cache node structure - */ -{ - ExFreeToNPagedLookasideList(&IPRCNList, Object); -} - - -VOID RemoveAboveExternal(VOID) -/* - * FUNCTION: Removes the parent node of the selected external node from the route cache tree - * NOTES: - * This function must be called with the route cache lock held. - * ExternalRCN->Parent must be initialized - */ -{ - PROUTE_CACHE_NODE Parent; - PROUTE_CACHE_NODE Sibling; - - TI_DbgPrint(DEBUG_RCACHE, ("Called.\n")); - -#if 0 - TI_DbgPrint(MIN_TRACE, ("Displaying tree (before).\n")); - PrintTree(RouteCache); -#endif - - Parent = ExternalRCN->Parent; - /* Find sibling of external node */ - if (ExternalRCN == Parent->Left) - Sibling = Parent->Right; - else - Sibling = Parent->Left; - - /* Replace parent node with sibling of external node */ - if (Parent != RouteCache) { - if (Parent->Parent->Left == Parent) - Parent->Parent->Left = Sibling; - else - Parent->Parent->Right = Sibling; - /* Give sibling a new parent */ - Sibling->Parent = Parent->Parent; - } else { - /* This is the root we're removing */ - RouteCache = Sibling; - Sibling->Parent = NULL; - } -} - - -PROUTE_CACHE_NODE SearchRouteCache( - PIP_ADDRESS Destination, - PROUTE_CACHE_NODE Node) -/* - * FUNCTION: Searches route cache for a RCN for a destination address - * ARGUMENTS: - * Destination = Pointer to destination address (key) - * Node = Pointer to start route cache node - * NOTES: - * This function must be called with the route cache lock held - * RETURNS: - * Pointer to internal node if a matching node was found, or - * external node where it should be if none was found - */ -{ - INT Value; - - TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X) Node (0x%X)\n", Destination, Node)); - - /* Is this an external node? */ - if (IsExternalRCN(Node)) - return Node; - - /* Is it this node we are looking for? */ - Value = AddrCompare(Destination, &Node->Destination); - if (Value == 0) - return Node; - - /* Traverse down the left subtree if the key is smaller than - the key of the node, otherwise traverse the right subtree */ - if (Value < 0) { - Node->Left->Parent = Node; - ExternalRCN->Left = (PROUTE_CACHE_NODE)&Node->Left; - return SearchRouteCache(Destination, Node->Left); - } else { - Node->Right->Parent = Node; - ExternalRCN->Left = (PROUTE_CACHE_NODE)&Node->Right; - return SearchRouteCache(Destination, Node->Right); - } -} - - -PROUTE_CACHE_NODE ExpandExternalRCN(VOID) -/* - * FUNCTION: Expands an external route cache node - * NOTES: - * This function must be called with the route cache lock held. - * We cheat a little here to save memory. We don't actually allocate memory - * for external nodes. We wait until they're turned into internal nodes. - * ExternalRCN->Parent must be initialized - * ExternalRCN->Left must be a pointer to the correct child link of it's parent - * RETURNS: - * Pointer to new internal node if the external node was expanded, NULL if not - */ -{ - PROUTE_CACHE_NODE RCN; - - MTMARK(); - - TI_DbgPrint(DEBUG_RCACHE, ("Called.\n")); - - RCN = ExAllocateFromNPagedLookasideList(&IPRCNList); - if (!RCN) { - TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); - return NULL; - } - - MTMARK(); - - RCN->Free = FreeRCN; - - if (ExternalRCN->Left) - /* Register RCN as a child with it's parent */ - *(PROUTE_CACHE_NODE*)ExternalRCN->Left = RCN; - - RCN->Parent = ExternalRCN->Parent; - RCN->Left = ExternalRCN; - RCN->Right = ExternalRCN; - - MTMARK(); - - return RCN; -} - -#if 0 -VOID SwapRCN( - PROUTE_CACHE_NODE *Node1, - PROUTE_CACHE_NODE *Node2) -/* - * FUNCTION: Swaps two nodes - * ARGUMENTS: - * Node1 = Address of pointer to first node - * Node2 = Address of pointer to second node - */ -{ - PROUTE_CACHE_NODE Temp; - - Temp = *Node2; - *Node2 = *Node1; - *Node1 = Temp; -} -#endif - -/* - * FUNCTION: Removes a route to a destination - * ARGUMENTS: - * RCN = Pointer to route cache node to remove - * NOTES: - * Internal version. Route cache lock must be held - */ -VOID RemoveRouteToDestination( - PROUTE_CACHE_NODE RCN) -{ - PROUTE_CACHE_NODE RemNode, Parent, SwapNode; - - TI_DbgPrint(DEBUG_RCACHE, ("Called. RCN (0x%X).\n", RCN)); - - if (IsExternalRCN(RCN->Left)) { - /* Left node is external */ - RemNode = RCN->Left; - RemNode->Parent = RCN; - } else if (IsExternalRCN(RCN->Right)) { - /* Right node is external */ - RemNode = RCN->Right; - RemNode->Parent = RCN; - } else { - /* The node has internal children */ - - /* Normally we would replace the item of RCN with the item - of the leftmost external node on the right subtree of - RCN. This we cannot do here because there may be - references directly to that node. Instead we swap pointer - values (parent, left and right) of the two nodes */ - RemNode = RCN->Right; - do { - Parent = RemNode; - RemNode = RemNode->Left; - } while (IsInternalRCN(RemNode)); - RemNode->Parent = Parent; - - SwapNode = RemNode->Parent; -#if 0 - if (RCN != RouteCache) { - /* Set SwapNode to be child of RCN's parent instead of RCN */ - Parent = RCN->Parent; - if (RCN == Parent->Left) - Parent->Left = SwapNode; - else - Parent->Right = SwapNode; - } else - /* SwapNode is the new cache root */ - RouteCache = SwapNode; - - /* Set RCN to be child of SwapNode's parent instead of SwapNode */ - Parent = SwapNode->Parent; - if (SwapNode == Parent->Left) - Parent->Left = RCN; - else - Parent->Right = RCN; - - /* Swap parents */ - SwapRCN(&SwapNode->Parent, &RCN->Parent); - /* Swap children */ - SwapRCN(&SwapNode->Left, &RCN->Left); - SwapRCN(&SwapNode->Right, &RCN->Right); -#endif - } - - ExternalRCN->Parent = RemNode->Parent; - - RemoveAboveExternal(); -} - - -VOID InvalidateNCEOnSubtree( - PNEIGHBOR_CACHE_ENTRY NCE, - PROUTE_CACHE_NODE Node) -/* - * FUNCTION: Removes all RCNs with references to an NCE on a subtree - * ARGUMENNTS: - * NCE = Pointer to NCE to invalidate - * Node = Pointer to RCN to start removing nodes at - * NOTES: - * This function must be called with the route cache lock held - */ -{ - TI_DbgPrint(DEBUG_RCACHE, ("Called. NCE (0x%X) Node (0x%X).\n", NCE, Node)); - - if (IsInternalRCN(Node)) { - /* Traverse left subtree */ - InvalidateNCEOnSubtree(NCE, Node->Left); - - /* Traverse right subtree */ - InvalidateNCEOnSubtree(NCE, Node->Right); - - /* Finally check the node itself */ - if (Node->NCE == NCE) - RemoveRouteToDestination(Node); - } -} - - -VOID RemoveSubtree( - PROUTE_CACHE_NODE Node) -/* - * FUNCTION: Removes a subtree from the tree using recursion - * ARGUMENNTS: - * Node = Pointer to RCN to start removing nodes at - * NOTES: - * This function must be called with the route cache lock held - */ -{ - TI_DbgPrint(DEBUG_RCACHE, ("Called. Node (0x%X).\n", Node)); - - if (IsInternalRCN(Node)) { - /* Traverse left subtree */ - RemoveSubtree(Node->Left); - - /* Traverse right subtree */ - RemoveSubtree(Node->Right); - } -} - - -NTSTATUS RouteStartup( - VOID) -/* - * FUNCTION: Initializes the routing subsystem - * RETURNS: - * Status of operation - */ -{ - TI_DbgPrint(DEBUG_RCACHE, ("Called.\n")); - - ExInitializeNPagedLookasideList( - &IPRCNList, /* Lookaside list */ - NULL, /* Allocate routine */ - NULL, /* Free routine */ - 0, /* Flags */ - sizeof(ROUTE_CACHE_NODE), /* Size of each entry */ - TAG('I','P','R','C'), /* Tag */ - 0); /* Depth */ - - /* Initialize the pseudo external route cache node */ - ExternalRCN = ExAllocateFromNPagedLookasideList(&IPRCNList); - if (!ExternalRCN) { - TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); - return STATUS_INSUFFICIENT_RESOURCES; - } - INIT_TAG(ExternalRCN, TAG('R','C','N',' ')); - - ExternalRCN->Free = FreeRCN; - ExternalRCN->Parent = NULL; - ExternalRCN->Left = NULL; - ExternalRCN->Right = NULL; - - /* Initialize the route cache root */ - RouteCache = ExternalRCN; - - KeInitializeSpinLock(&RouteCacheLock); - -#if 0 - TI_DbgPrint(MIN_TRACE, ("Displaying tree.\n")); - PrintTree(RouteCache); -#endif - return STATUS_SUCCESS; -} - - -NTSTATUS RouteShutdown( - VOID) -/* - * FUNCTION: Shuts down the routing subsystem - * RETURNS: - * Status of operation - */ -{ - KIRQL OldIrql; - - TI_DbgPrint(DEBUG_RCACHE, ("Called.\n")); - - TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql); -#if 0 - TI_DbgPrint(MIN_TRACE, ("Displaying tree.\n")); - PrintTree(RouteCache); -#endif - /* Clear route cache */ - RemoveSubtree(RouteCache); - - FreeRCN(ExternalRCN); - - TcpipReleaseSpinLock(&RouteCacheLock, OldIrql); - - ExDeleteNPagedLookasideList(&IPRCNList); - - return STATUS_SUCCESS; -} - - -UINT RouteGetRouteToDestination -(PIP_ADDRESS Destination, PROUTE_CACHE_NODE *RCN) -/* - * FUNCTION: Locates an RCN describing a route to a destination address - * ARGUMENTS: - * Destination = Pointer to destination address to find route to - * RCN = Address of pointer to an RCN - * RETURNS: - * Status of operation - * NOTES: - * The RCN is referenced for the caller. The caller is responsible - * for dereferencing it after use - */ -{ - KIRQL OldIrql; - PROUTE_CACHE_NODE RCN2; - PNEIGHBOR_CACHE_ENTRY NCE; - PIP_INTERFACE Interface; - - TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X)\n", Destination)); - - TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s)\n", A2S(Destination))); - - TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql); - -#if 0 - TI_DbgPrint(MIN_TRACE, ("Displaying tree (before).\n")); - PrintTree(RouteCache); -#endif - - ExternalRCN->Left = NULL; - RCN2 = SearchRouteCache(Destination, RouteCache); - if (IsExternalRCN(RCN2)) { - /* No route was found in the cache */ - - /* Check if the destination is on-link */ - Interface = FindOnLinkInterface(Destination); - if (Interface) { - /* The destination address is on-link. Check our neighbor cache */ - NCE = NBFindOrCreateNeighbor(Interface, Destination); - if (!NCE) { - TcpipReleaseSpinLock(&RouteCacheLock, OldIrql); - return IP_NO_RESOURCES; - } - } else { - /* Destination is not on any subnets we're on. Find a router to use */ - NCE = RouterGetRoute(Destination); - if (!NCE) { - /* We cannot get to the specified destination. Return error */ - TcpipReleaseSpinLock(&RouteCacheLock, OldIrql); - return IP_NO_ROUTE_TO_DESTINATION; - } - } - - /* Add the new route to the route cache */ - if (RCN2 == RouteCache) { - RCN2 = ExpandExternalRCN(); - RouteCache = RCN2; - } else - RCN2 = ExpandExternalRCN(); - if (!RCN2) { - TcpipReleaseSpinLock(&RouteCacheLock, OldIrql); - return IP_NO_RESOURCES; - } - - RCN2->State = RCN_STATE_COMPUTED; - RtlCopyMemory(&RCN2->Destination, Destination, sizeof(IP_ADDRESS)); - RCN2->PathMTU = NCE->Interface->MTU; - RCN2->NCE = NCE; - - /* The route cache node references the NTE and the NCE. The - NTE was referenced before and NCE is already referenced by - RouteGetRoute() or NBFindOrCreateNeighbor() so we don't - reference them here */ - } - - TcpipReleaseSpinLock(&RouteCacheLock, OldIrql); - - *RCN = RCN2; - TI_DbgPrint(MID_TRACE,("RCN->PathMTU: %d\n", RCN2->PathMTU)); - - return IP_SUCCESS; -} - - -PROUTE_CACHE_NODE RouteAddRouteToDestination( - PIP_ADDRESS Destination, - PIP_INTERFACE IF, - PNEIGHBOR_CACHE_ENTRY NCE) -/* - * FUNCTION: Adds a (permanent) route to a destination - * ARGUMENTS: - * Destination = Pointer to destination address - * IF = Pointer to interface to use - * NCE = Pointer to first hop to destination - * RETURNS: - * Pointer to RCN if the route was added, NULL if not. - * There can be at most one RCN per destination address / interface pair - */ -{ - KIRQL OldIrql; - PROUTE_CACHE_NODE RCN; - - TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X) IF (0x%X) NCE (0x%X).\n", - Destination, IF, NCE)); - - TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s) NCE (%s).\n", - A2S(Destination), - A2S(&NCE->Address))); - - TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql); - - /* Locate an external RCN we can expand */ - RCN = RouteCache; - ExternalRCN->Left = NULL; - for (;;) { - RCN = SearchRouteCache(Destination, RCN); - if (IsInternalRCN(RCN)) { - ExternalRCN->Left = (PROUTE_CACHE_NODE)&RCN->Right; - /* This is an internal node, continue the search to the right */ - RCN = RCN->Right; - } else - /* This is an external node, we've found an empty spot */ - break; - } - - /* Expand the external node */ - if (RCN == RouteCache) { - RCN = ExpandExternalRCN(); - RouteCache = RCN; - } else - RCN = ExpandExternalRCN(); - if (!RCN) { - TcpipReleaseSpinLock(&RouteCacheLock, OldIrql); - return NULL; - } - - /* Initialize the newly created internal node */ - - INIT_TAG(RCN, TAG('R','C','N',' ')); - - /* Reference once for beeing alive */ - RCN->State = RCN_STATE_PERMANENT; - RtlCopyMemory(&RCN->Destination, Destination, sizeof(IP_ADDRESS)); - RCN->PathMTU = IF->MTU; - RCN->NCE = NCE; - - TcpipReleaseSpinLock(&RouteCacheLock, OldIrql); - - return RCN; -} - - -VOID RouteRemoveRouteToDestination( - PROUTE_CACHE_NODE RCN) -/* - * FUNCTION: Removes a route to a destination - * ARGUMENTS: - * RCN = Pointer to route cache node to remove - */ -{ - KIRQL OldIrql; - - TI_DbgPrint(DEBUG_RCACHE, ("Called. RCN (0x%X).\n", RCN)); - - TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql); - - RemoveRouteToDestination(RCN); - - TcpipReleaseSpinLock(&RouteCacheLock, OldIrql); -} - -VOID RouteInvalidateNCE( - PNEIGHBOR_CACHE_ENTRY NCE) -/* - * FUNCTION: Removes all RCNs with references to an NCE - * ARGUMENTS: - * NCE = Pointer to neighbor cache entry to invalidate - */ -{ - KIRQL OldIrql; - - TI_DbgPrint(DEBUG_RCACHE, ("Called. NCE (0x%X).\n", NCE)); - - TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql); - InvalidateNCEOnSubtree(NCE, RouteCache); - TcpipReleaseSpinLock(&RouteCacheLock, OldIrql); -} - -/* EOF */ diff --git a/reactos/drivers/lib/ip/network/router.c b/reactos/drivers/lib/ip/network/router.c index 5414506ab65..a2f84ea46bb 100644 --- a/reactos/drivers/lib/ip/network/router.c +++ b/reactos/drivers/lib/ip/network/router.c @@ -272,6 +272,46 @@ PNEIGHBOR_CACHE_ENTRY RouterGetRoute(PIP_ADDRESS Destination) return BestNCE; } +PNEIGHBOR_CACHE_ENTRY RouteGetRouteToDestination(PIP_ADDRESS Destination) +/* + * FUNCTION: Locates an RCN describing a route to a destination address + * ARGUMENTS: + * Destination = Pointer to destination address to find route to + * RCN = Address of pointer to an RCN + * RETURNS: + * Status of operation + * NOTES: + * The RCN is referenced for the caller. The caller is responsible + * for dereferencing it after use + */ +{ + PNEIGHBOR_CACHE_ENTRY NCE = NULL; + PIP_INTERFACE Interface; + + TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X)\n", Destination)); + + TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s)\n", A2S(Destination))); + +#if 0 + TI_DbgPrint(MIN_TRACE, ("Displaying tree (before).\n")); + PrintTree(RouteCache); +#endif + + /* Check if the destination is on-link */ + Interface = FindOnLinkInterface(Destination); + if (Interface) { + /* The destination address is on-link. Check our neighbor cache */ + NCE = NBFindOrCreateNeighbor(Interface, Destination); + } else { + /* Destination is not on any subnets we're on. Find a router to use */ + NCE = RouterGetRoute(Destination); + } + + if( NCE ) + TI_DbgPrint(MID_TRACE,("Interface->MTU: %d\n", NCE->Interface->MTU)); + + return NCE; +} NTSTATUS RouterRemoveRoute(PIP_ADDRESS Target, PIP_ADDRESS Router) /* diff --git a/reactos/drivers/lib/ip/network/transmit.c b/reactos/drivers/lib/ip/network/transmit.c index 62e55aaf73a..78628319e82 100644 --- a/reactos/drivers/lib/ip/network/transmit.c +++ b/reactos/drivers/lib/ip/network/transmit.c @@ -212,7 +212,7 @@ NTSTATUS SendFragments( return STATUS_SUCCESS; } -NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PROUTE_CACHE_NODE RCN, +NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE, PIP_TRANSMIT_COMPLETE Complete, PVOID Context) /* * FUNCTION: Sends an IP datagram to a remote address @@ -227,17 +227,13 @@ NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PROUTE_CACHE_NODE RCN, * send routine (IPSendFragment) */ { - PNEIGHBOR_CACHE_ENTRY NCE; - - TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) RCN (0x%X)\n", IPPacket, RCN)); + TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) NCE (0x%X)\n", IPPacket, NCE)); DISPLAY_IP_PACKET(IPPacket); /*OskitDumpBuffer( IPPacket->Header, IPPacket->TotalSize );*/ - NCE = RCN->NCE; - /* Fetch path MTU now, because it may change */ - TI_DbgPrint(MID_TRACE,("PathMTU: %d\n", RCN->PathMTU)); + TI_DbgPrint(MID_TRACE,("PathMTU: %d\n", NCE->Interface->MTU)); if ((IPPacket->Flags & IP_PACKET_FLAG_RAW) == 0) { /* Calculate checksum of IP header */ @@ -255,7 +251,8 @@ NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PROUTE_CACHE_NODE RCN, IPPacket->Flags)); } - return SendFragments(IPPacket, NCE, RCN->PathMTU, Complete, Context); + return SendFragments(IPPacket, NCE, NCE->Interface->MTU, + Complete, Context); } /* EOF */ diff --git a/reactos/drivers/lib/ip/transport/rawip/rawip.c b/reactos/drivers/lib/ip/transport/rawip/rawip.c index c7a633ecf4f..e75d78a8325 100644 --- a/reactos/drivers/lib/ip/transport/rawip/rawip.c +++ b/reactos/drivers/lib/ip/transport/rawip/rawip.c @@ -98,7 +98,7 @@ NTSTATUS RawIPSendDatagram( { NDIS_STATUS Status; IP_PACKET Packet; - PROUTE_CACHE_NODE RCN; + PNEIGHBOR_CACHE_ENTRY NCE; IP_ADDRESS RemoteAddress; Status = AllocatePacketWithBuffer( &Packet.NdisPacket, @@ -121,14 +121,12 @@ NTSTATUS RawIPSendDatagram( BufferData + FIELD_OFFSET(IPv4_HEADER, DstAddr), sizeof(IPv4_RAW_ADDRESS) ); - Status = RouteGetRouteToDestination( &RemoteAddress, &RCN ); - - if( !NT_SUCCESS(Status) ) { + if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { FreeNdisPacket( Packet.NdisPacket ); - return Status; + return STATUS_NO_SUCH_DEVICE; } - IPSendDatagram( &Packet, RCN, RawIPSendComplete, NULL ); + IPSendDatagram( &Packet, NCE, RawIPSendComplete, NULL ); } else FreeNdisPacket( Packet.NdisPacket ); diff --git a/reactos/drivers/lib/ip/transport/tcp/event.c b/reactos/drivers/lib/ip/transport/tcp/event.c index b8702f8a639..dd011e708ef 100644 --- a/reactos/drivers/lib/ip/transport/tcp/event.c +++ b/reactos/drivers/lib/ip/transport/tcp/event.c @@ -156,9 +156,8 @@ void TCPPacketSendComplete( PVOID Context, #define STRINGIFY(x) #x int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { - NTSTATUS Status; NDIS_STATUS NdisStatus; - ROUTE_CACHE_NODE *RCN; + PNEIGHBOR_CACHE_ENTRY NCE; IP_PACKET Packet = { 0 }; IP_ADDRESS RemoteAddress, LocalAddress; PIPv4_HEADER Header; @@ -180,9 +179,8 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { LocalAddress.Address.IPv4Address, RemoteAddress.Address.IPv4Address); - Status = RouteGetRouteToDestination( &RemoteAddress, &RCN ); - - if( !NT_SUCCESS(Status) || !RCN ) return OSK_EADDRNOTAVAIL; + if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) + return OSK_EADDRNOTAVAIL; NdisStatus = AllocatePacketWithBuffer( &Packet.NdisPacket, NULL, MaxLLHeaderSize + len ); @@ -202,7 +200,7 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { Packet.SrcAddr = LocalAddress; Packet.DstAddr = RemoteAddress; - IPSendDatagram( &Packet, RCN, TCPPacketSendComplete, NULL ); + IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL ); if( !NT_SUCCESS(NdisStatus) ) return OSK_EINVAL; else return 0; diff --git a/reactos/drivers/lib/ip/transport/tcp/tcp.c b/reactos/drivers/lib/ip/transport/tcp/tcp.c index 456d0fef41f..1164c65d7f2 100644 --- a/reactos/drivers/lib/ip/transport/tcp/tcp.c +++ b/reactos/drivers/lib/ip/transport/tcp/tcp.c @@ -36,9 +36,6 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { /* Save client context pointer */ Connection->ClientContext = ClientContext; - /* Initialize received segments queue */ - InitializeListHead(&Connection->ReceivedSegments); - return Connection; } @@ -244,7 +241,7 @@ NTSTATUS TCPConnect PVOID Context ) { NTSTATUS Status; SOCKADDR_IN AddressToConnect = { 0 }, AddressToBind = { 0 }; - PIP_ADDRESS RemoteAddress; + IP_ADDRESS RemoteAddress; USHORT RemotePort; PTDI_BUCKET Bucket; @@ -267,7 +264,7 @@ NTSTATUS TCPConnect &RemotePort); DbgPrint("Connecting to address %x:%x\n", - RemoteAddress->Address.IPv4Address, + RemoteAddress.Address.IPv4Address, RemotePort); if (!NT_SUCCESS(Status)) { @@ -284,7 +281,7 @@ NTSTATUS TCPConnect sizeof(AddressToBind) ); memcpy( &AddressToConnect.sin_addr, - &RemoteAddress->Address.IPv4Address, + &RemoteAddress.Address.IPv4Address, sizeof(AddressToConnect.sin_addr) ); AddressToConnect.sin_port = RemotePort; diff --git a/reactos/drivers/lib/ip/transport/udp/udp.c b/reactos/drivers/lib/ip/transport/udp/udp.c index f0da8306e9d..5505dcabeeb 100644 --- a/reactos/drivers/lib/ip/transport/udp/udp.c +++ b/reactos/drivers/lib/ip/transport/udp/udp.c @@ -197,7 +197,7 @@ NTSTATUS UDPSendDatagram( IP_ADDRESS RemoteAddress; USHORT RemotePort; NTSTATUS Status; - PROUTE_CACHE_NODE RCN; + PNEIGHBOR_CACHE_ENTRY NCE; TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -226,12 +226,10 @@ NTSTATUS UDPSendDatagram( if( !NT_SUCCESS(Status) ) return Status; - Status = RouteGetRouteToDestination( &RemoteAddress, &RCN ); + if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) + return STATUS_UNSUCCESSFUL; - if( !NT_SUCCESS(Status) ) - return Status; - - IPSendDatagram( &Packet, RCN, UDPSendPacketComplete, NULL ); + IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL ); return STATUS_SUCCESS; } diff --git a/reactos/drivers/net/tcpip/datalink/lan.c b/reactos/drivers/net/tcpip/datalink/lan.c index 0189c6b5c40..9d7e3b2dc4d 100644 --- a/reactos/drivers/net/tcpip/datalink/lan.c +++ b/reactos/drivers/net/tcpip/datalink/lan.c @@ -734,6 +734,7 @@ VOID BindAdapter( PIP_INTERFACE IF; NDIS_STATUS NdisStatus; LLIP_BIND_INFO BindInfo; + IP_ADDRESS DefaultGateway, DefaultMask = { 0 }; ULONG Lookahead = LOOKAHEAD_SIZE; NTSTATUS Status; HANDLE RegHandle = 0; @@ -779,6 +780,14 @@ VOID BindAdapter( Status = OpenRegistryKey( RegistryPath, &RegHandle ); + if(NT_SUCCESS(Status)) + Status = ReadIPAddressFromRegistry( RegHandle, L"DefaultGateway", + &DefaultGateway ); + if(!NT_SUCCESS(Status)) { + Status = STATUS_SUCCESS; + RtlZeroMemory( &DefaultGateway, sizeof(DefaultGateway) ); + } + if(NT_SUCCESS(Status)) Status = ReadIPAddressFromRegistry( RegHandle, L"IPAddress", &IF->Unicast ); @@ -820,6 +829,20 @@ VOID BindAdapter( ("--> Our net mask on this interface: '%s'\n", A2S(&IF->Netmask))); + if( DefaultGateway.Address.IPv4Address ) { + TI_DbgPrint + (MID_TRACE, + ("--> Our gateway is: '%s'\n", + A2S(&DefaultGateway))); + + /* Create a default route */ + RouterCreateRoute( &DefaultMask, /* Zero */ + &DefaultMask, /* Zero */ + &DefaultGateway, + IF, + 1 ); + } + /* Register interface with IP layer */ IPRegisterInterface(IF); diff --git a/reactos/drivers/net/tcpip/include/address.h b/reactos/drivers/net/tcpip/include/address.h index 856de9b33ff..d8113514137 100644 --- a/reactos/drivers/net/tcpip/include/address.h +++ b/reactos/drivers/net/tcpip/include/address.h @@ -40,7 +40,7 @@ NTSTATUS AddrGetAddress( NTSTATUS AddrBuildAddress( PTRANSPORT_ADDRESS TdiAddress, - PIP_ADDRESS *Address, + PIP_ADDRESS Address, PUSHORT Port); BOOLEAN AddrIsEqual( diff --git a/reactos/drivers/net/tcpip/include/interface.h b/reactos/drivers/net/tcpip/include/interface.h index d74ace62d06..a8ad99fd1c1 100644 --- a/reactos/drivers/net/tcpip/include/interface.h +++ b/reactos/drivers/net/tcpip/include/interface.h @@ -3,6 +3,8 @@ #include +#define IFENT_SOFTWARE_LOOPBACK 24 /* This is an SNMP constant from rfc1213 */ + NTSTATUS GetInterfaceIPv4Address( PIP_INTERFACE Interface, ULONG Type, PULONG Address ); diff --git a/reactos/drivers/net/tcpip/include/ip.h b/reactos/drivers/net/tcpip/include/ip.h index 98d6361ed86..55f0d8d76f3 100644 --- a/reactos/drivers/net/tcpip/include/ip.h +++ b/reactos/drivers/net/tcpip/include/ip.h @@ -188,6 +188,7 @@ extern LIST_ENTRY NetTableListHead; extern KSPIN_LOCK NetTableListLock; extern UINT MaxLLHeaderSize; extern UINT MinLLFrameSize; +extern BOOLEAN IpWorkItemQueued; PIP_PACKET IPCreatePacket( ULONG Type); diff --git a/reactos/drivers/net/tcpip/include/route.h b/reactos/drivers/net/tcpip/include/route.h index 53b912057dd..19f1323bfbc 100644 --- a/reactos/drivers/net/tcpip/include/route.h +++ b/reactos/drivers/net/tcpip/include/route.h @@ -14,61 +14,7 @@ #include #include -/* Route Cache Node structure. - * The primary purpose of the RCN is to cache selected source and - * next-hop addresses. The routing cache is implemented as a binary - * search tree to provide fast lookups when many RCNs are in the cache. - */ -typedef struct ROUTE_CACHE_NODE { - struct ROUTE_CACHE_NODE *Parent; /* Pointer to parent */ - struct ROUTE_CACHE_NODE *Left; /* Pointer to left child */ - struct ROUTE_CACHE_NODE *Right; /* Pointer to right child */ - /* Memebers above this line must not be moved */ - DEFINE_TAG - OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */ - UCHAR State; /* RCN state (RCN_STATE_*) */ - IP_ADDRESS Destination; /* Destination address */ - PNEIGHBOR_CACHE_ENTRY NCE; /* Pointer to NCE for first hop (NULL if none) */ - UINT PathMTU; /* Path MTU to destination */ -} ROUTE_CACHE_NODE, *PROUTE_CACHE_NODE; - -/* RCN states */ -#define RCN_STATE_PERMANENT 0x00 /* RCN is permanent (properly local) */ -#define RCN_STATE_COMPUTED 0x01 /* RCN is computed */ - - -extern NPAGED_LOOKASIDE_LIST IPRCNList; - - -#define IsExternalRCN(RCN) \ - (RCN == ExternalRCN) - -#define IsInternalRCN(RCN) \ - (RCN != ExternalRCN) - - -NTSTATUS RouteStartup( - VOID); - -NTSTATUS RouteShutdown( - VOID); - -UINT RouteGetRouteToDestination( - PIP_ADDRESS Destination, - PROUTE_CACHE_NODE *RCN); - -PROUTE_CACHE_NODE RouteAddRouteToDestination( - PIP_ADDRESS Destination, - PIP_INTERFACE IF, - PNEIGHBOR_CACHE_ENTRY NCE); - -VOID RouteRemoveRouteToDestination( PROUTE_CACHE_NODE RCN ); - -VOID RouteInvalidateNCE( PNEIGHBOR_CACHE_ENTRY NCE ); - -NTSTATUS RouteFriendlyAddRoute( PIPROUTE_ENTRY ire ); - -UINT CountRouteNodes( PROUTE_CACHE_NODE Node ); +PNEIGHBOR_CACHE_ENTRY RouteGetRouteToDestination(PIP_ADDRESS Destination); #endif /* __ROUTE_H */ diff --git a/reactos/drivers/net/tcpip/include/titypes.h b/reactos/drivers/net/tcpip/include/titypes.h index a72273bfc65..1ce81946b71 100644 --- a/reactos/drivers/net/tcpip/include/titypes.h +++ b/reactos/drivers/net/tcpip/include/titypes.h @@ -321,9 +321,6 @@ typedef struct _CONNECTION_ENDPOINT { LIST_ENTRY ConnectRequest; /* Queued connect rqueusts */ LIST_ENTRY ListenRequest; /* Queued listen requests */ LIST_ENTRY ReceiveRequest; /* Queued receive requests */ - - /* Queues */ - LIST_ENTRY ReceivedSegments;/* Segments that are received */ } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT; diff --git a/reactos/drivers/net/tcpip/include/transmit.h b/reactos/drivers/net/tcpip/include/transmit.h index 2b93c1257e1..f2ab2d308b3 100644 --- a/reactos/drivers/net/tcpip/include/transmit.h +++ b/reactos/drivers/net/tcpip/include/transmit.h @@ -30,7 +30,7 @@ typedef struct IPFRAGMENT_CONTEXT { } IPFRAGMENT_CONTEXT, *PIPFRAGMENT_CONTEXT; -NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PROUTE_CACHE_NODE RCN, +NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE, PIP_TRANSMIT_COMPLETE Complete, PVOID Context); #endif /* __TRANSMIT_H */ diff --git a/reactos/drivers/net/tcpip/tcpip/fileobjs.c b/reactos/drivers/net/tcpip/tcpip/fileobjs.c index 85af857f25d..8c7fe6752f5 100644 --- a/reactos/drivers/net/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/net/tcpip/tcpip/fileobjs.c @@ -380,14 +380,6 @@ NTSTATUS FileOpenConnection( Status = TCPSocket( Connection, AF_INET, SOCK_STREAM, IPPROTO_TCP ); DbgPrint("STATUS from OSKITTCP was %08x\n", Status); - /* Initialize received segments queue */ - InitializeListHead(&Connection->ReceivedSegments); - -TI_DbgPrint(MIN_TRACE, ("X1 cur 0x%x\n", &Connection->ReceivedSegments)); -TI_DbgPrint(MIN_TRACE, ("X1 Flink 0x%x\n", Connection->ReceivedSegments.Flink)); -TI_DbgPrint(MIN_TRACE, ("X1 Blink 0x%x\n", Connection->ReceivedSegments.Blink)); - - /* Return connection endpoint file object */ Request->Handle.ConnectionContext = Connection; @@ -417,7 +409,7 @@ PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ) { KIRQL OldIrql; PCONNECTION_ENDPOINT Connection = NULL; - KeAcquireSpinLock( &ConnectionEndpointListLock, &OldIrql ); + TcpipAcquireSpinLock( &ConnectionEndpointListLock, &OldIrql ); for( Entry = ConnectionEndpointListHead.Flink; Entry != &ConnectionEndpointListHead; @@ -428,7 +420,7 @@ PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ) { else Connection = NULL; } - KeReleaseSpinLock( &ConnectionEndpointListLock, OldIrql ); + TcpipReleaseSpinLock( &ConnectionEndpointListLock, OldIrql ); return Connection; } diff --git a/reactos/drivers/net/tcpip/tcpip/iinfo.c b/reactos/drivers/net/tcpip/tcpip/iinfo.c index ac62a7243ed..d0afdfd3f18 100644 --- a/reactos/drivers/net/tcpip/tcpip/iinfo.c +++ b/reactos/drivers/net/tcpip/tcpip/iinfo.c @@ -35,7 +35,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID, OutData->Index = ID->tei_instance + 1; /* viz: tcpip keeps those indices */ - OutData->Type = IF ? 1 : 0; /* XXX other -- for now ... */ + OutData->Type = Interface == Loopback ? IFENT_SOFTWARE_LOOPBACK : 0; OutData->Mtu = Interface->MTU; TI_DbgPrint(MAX_TRACE, ("Getting interface speed\n")); diff --git a/reactos/drivers/net/tcpip/tcpip/main.c b/reactos/drivers/net/tcpip/tcpip/main.c index 6267659e050..2128710749e 100644 --- a/reactos/drivers/net/tcpip/tcpip/main.c +++ b/reactos/drivers/net/tcpip/tcpip/main.c @@ -29,6 +29,7 @@ ULONG EntityCount = 0; ULONG EntityMax = 0; UDP_STATISTICS UDPStats; +/* Network timers */ KTIMER IPTimer; KDPC IPTimeoutDpc; KSPIN_LOCK IpWorkLock; @@ -256,6 +257,7 @@ CP TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status)); + Irp->IoStatus.Status = Status; return Status; } @@ -670,7 +672,10 @@ VOID STDCALL IPTimeoutDpcFn( * This routine is dispatched once in a while to do maintainance jobs */ { - ExQueueWorkItem( &IpWorkItem, CriticalWorkQueue ); + if( !IpWorkItemQueued ) { + ExQueueWorkItem( &IpWorkItem, CriticalWorkQueue ); + IpWorkItemQueued = TRUE; + } } NTSTATUS