[TCPIP]
[reactos.git] / lib / drivers / ip / network / neighbor.c
index 07e7e8c..b4e3322 100644 (file)
@@ -106,17 +106,27 @@ VOID NBTimeout(VOID)
 
         for (PrevNCE = &NeighborCache[i].Cache;
              (NCE = *PrevNCE) != NULL;) {
+            if (NCE->State & NUD_INCOMPLETE)
+            {
+                /* Solicit for an address */
+                NBSendSolicit(NCE);
+                if (NCE->EventTimer == 0)
+                {
+                    NCE->EventCount++;
+                    if (NCE->EventCount == ARP_INCOMPLETE_TIMEOUT)
+                    {
+                        NBFlushPacketQueue(NCE, NDIS_STATUS_NETWORK_UNREACHABLE);
+                        NCE->EventCount = 0;
+                    }
+                }
+            }
+
             /* Check if event timer is running */
             if (NCE->EventTimer > 0)  {
                 ASSERT(!(NCE->State & NUD_PERMANENT));
                 NCE->EventCount++;
-                if (NCE->State & NUD_INCOMPLETE)
-                {
-                    /* We desperately need an address in this state or 
-                     * we timeout in 5 seconds */
-                    NBSendSolicit(NCE);
-                }
-                else if ((NCE->EventCount > ARP_RATE &&
+
+                if ((NCE->EventCount > ARP_RATE &&
                      NCE->EventCount % ARP_TIMEOUT_RETRANSMISSION == 0) ||
                     (NCE->EventCount == ARP_RATE))
                 {
@@ -129,7 +139,7 @@ VOID NBTimeout(VOID)
                 if (NCE->EventTimer - NCE->EventCount == 0) {
                     /* Unlink and destroy the NCE */
                     *PrevNCE = NCE->Next;
-
+                    
                     /* Choose the proper failure status */
                     if (NCE->State & NUD_INCOMPLETE)
                     {
@@ -141,8 +151,9 @@ VOID NBTimeout(VOID)
                         /* This guy was stale for way too long */
                         Status = NDIS_STATUS_REQUEST_ABORTED;
                     }
-
+                    
                     NBFlushPacketQueue(NCE, Status);
+
                     ExFreePoolWithTag(NCE, NCE_TAG);
 
                     continue;
@@ -367,7 +378,7 @@ VOID NBUpdateNeighbor(
 
     if( !(NCE->State & NUD_INCOMPLETE) )
     {
-        NCE->EventTimer = ARP_COMPLETE_TIMEOUT;
+        if (NCE->EventTimer) NCE->EventTimer = ARP_COMPLETE_TIMEOUT;
         NBSendPackets( NCE );
     }
 }
@@ -446,7 +457,8 @@ PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
 
 PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
   PIP_INTERFACE Interface,
-  PIP_ADDRESS Address)
+  PIP_ADDRESS Address,
+  BOOLEAN NoTimeout)
 /*
  * FUNCTION: Tries to find a neighbor and if unsuccesful, creates a new NCE
  * ARGUMENTS:
@@ -474,7 +486,7 @@ PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
                                 Interface->AddressLength, NUD_PERMANENT, 0);
         } else {
             NCE = NBAddNeighbor(Interface, Address, NULL,
-                                Interface->AddressLength, NUD_INCOMPLETE, ARP_INCOMPLETE_TIMEOUT);
+                                Interface->AddressLength, NUD_INCOMPLETE, NoTimeout ? 0 : ARP_INCOMPLETE_TIMEOUT);
             if (!NCE) return NULL;
             NBSendSolicit(NCE);
         }