- Differentiate between incomplete and complete NCEs with regard to the timeout
- Change the IP timer to fire only once each second
- Remove unneeded completion functions

svn path=/trunk/; revision=54171
This commit is contained in:
Cameron Gutman 2011-10-17 01:37:56 +00:00
parent 97eddfb464
commit 18254a9593
11 changed files with 53 additions and 60 deletions

View file

@ -197,8 +197,7 @@ typedef VOID (*IP_PROTOCOL_HANDLER)(
#define IPPROTO_UDP 17 /* User Datagram Protocol */
/* Timeout timer constants */
#define IP_TICKS_SECOND 2 /* Two ticks per second */
#define IP_TIMEOUT (1000 / IP_TICKS_SECOND) /* Timeout in milliseconds */
#define IP_TIMEOUT 1000 /* Timeout in milliseconds */
#define IP_DEFAULT_LINK_SPEED 10000
extern LIST_ENTRY InterfaceListHead;

View file

@ -42,11 +42,14 @@ typedef struct NEIGHBOR_CACHE_ENTRY {
#define NUD_PERMANENT 0x02
#define NUD_STALE 0x04
/* Timeout for incomplete NCE ARP requests */
#define ARP_INCOMPLETE_TIMEOUT 5
/* Number of seconds between ARP transmissions */
#define ARP_RATE 900
/* Number of seconds before the NCE times out */
#define ARP_TIMEOUT ARP_RATE + 15
#define ARP_COMPLETE_TIMEOUT (ARP_RATE + 15)
/* Number of seconds before retransmission */
#define ARP_TIMEOUT_RETRANSMISSION 5

View file

@ -9,8 +9,8 @@
#include <ip.h>
/* Number of timeout ticks before destroying the IPDR */
#define MAX_TIMEOUT_COUNT 10
/* Number of seconds before destroying the IPDR */
#define MAX_TIMEOUT_COUNT 5
/* IP datagram fragment descriptor. Used to store IP datagram fragments */
typedef struct IP_FRAGMENT {

View file

@ -30,7 +30,5 @@ typedef struct IPFRAGMENT_CONTEXT {
} IPFRAGMENT_CONTEXT, *PIPFRAGMENT_CONTEXT;
NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE,
PIP_TRANSMIT_COMPLETE Complete, PVOID Context);
NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE);
/* EOF */

View file

@ -229,7 +229,7 @@ VOID ARPReceive(
may want to communicate with us soon, so add his address
to our address cache */
NCE = NBAddNeighbor(Interface, &SrcAddress, SenderHWAddress,
Header->HWAddrLen, 0, ARP_TIMEOUT);
Header->HWAddrLen, 0, ARP_COMPLETE_TIMEOUT);
}
if (Header->Opcode != ARP_OPCODE_REQUEST)

View file

@ -221,11 +221,10 @@ NTSTATUS ICMPSendDatagram(
TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, ICMPSendPacketComplete, NULL )))
{
FreeNdisPacket(Packet.NdisPacket);
Status = IPSendDatagram(&Packet, NCE);
FreeNdisPacket(Packet.NdisPacket);
if (!NT_SUCCESS(Status))
return Status;
}
*DataUsed = DataSize;
@ -312,11 +311,8 @@ VOID ICMPTransmit(
/* Get a route to the destination address */
if ((NCE = RouteGetRouteToDestination(&IPPacket->DstAddr))) {
/* Send the packet */
Status = IPSendDatagram(IPPacket, NCE, Complete, Context);
if (!NT_SUCCESS(Status))
{
Complete(Context, IPPacket->NdisPacket, Status);
}
Status = IPSendDatagram(IPPacket, NCE);
Complete(Context, IPPacket->NdisPacket, Status);
} else {
/* No route to destination (or no free resources) */
TI_DbgPrint(DEBUG_ICMP, ("No route to destination address 0x%X.\n",

View file

@ -99,6 +99,7 @@ VOID NBTimeout(VOID)
UINT i;
PNEIGHBOR_CACHE_ENTRY *PrevNCE;
PNEIGHBOR_CACHE_ENTRY NCE;
NDIS_STATUS Status;
for (i = 0; i <= NB_HASHMASK; i++) {
TcpipAcquireSpinLockAtDpcLevel(&NeighborCache[i].Lock);
@ -109,7 +110,13 @@ VOID NBTimeout(VOID)
if (NCE->EventTimer > 0) {
ASSERT(!(NCE->State & NUD_PERMANENT));
NCE->EventCount++;
if ((NCE->EventCount > ARP_RATE &&
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 &&
NCE->EventCount % ARP_TIMEOUT_RETRANSMISSION == 0) ||
(NCE->EventCount == ARP_RATE))
{
@ -120,13 +127,22 @@ VOID NBTimeout(VOID)
NBSendSolicit(NCE);
}
if (NCE->EventTimer - NCE->EventCount == 0) {
/* Solicit one last time */
NBSendSolicit(NCE);
/* Unlink and destroy the NCE */
*PrevNCE = NCE->Next;
NBFlushPacketQueue(NCE, NDIS_STATUS_REQUEST_ABORTED);
/* Choose the proper failure status */
if (NCE->State & NUD_INCOMPLETE)
{
/* We couldn't get an address to this IP at all */
Status = NDIS_STATUS_NETWORK_UNREACHABLE;
}
else
{
/* This guy was stale for way too long */
Status = NDIS_STATUS_REQUEST_ABORTED;
}
NBFlushPacketQueue(NCE, Status);
ExFreePoolWithTag(NCE, NCE_TAG);
continue;
@ -314,7 +330,10 @@ VOID NBUpdateNeighbor(
TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
if( !(NCE->State & NUD_INCOMPLETE) )
NBSendPackets( NCE );
{
NCE->EventTimer = ARP_COMPLETE_TIMEOUT;
NBSendPackets( NCE );
}
}
VOID
@ -419,7 +438,7 @@ PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
Interface->AddressLength, NUD_PERMANENT, 0);
} else {
NCE = NBAddNeighbor(Interface, Address, NULL,
Interface->AddressLength, NUD_INCOMPLETE, ARP_TIMEOUT);
Interface->AddressLength, NUD_INCOMPLETE, ARP_INCOMPLETE_TIMEOUT);
if (!NCE) return NULL;
NBSendSolicit(NCE);
}

View file

@ -132,9 +132,7 @@ BOOLEAN PrepareNextFragment(
NTSTATUS SendFragments(
PIP_PACKET IPPacket,
PNEIGHBOR_CACHE_ENTRY NCE,
UINT PathMTU,
PIP_TRANSMIT_COMPLETE Complete,
PVOID Context)
UINT PathMTU)
/*
* FUNCTION: Fragments and sends the first fragment of an IP datagram
* ARGUMENTS:
@ -214,13 +212,10 @@ NTSTATUS SendFragments(
FreeNdisPacket(IFC->NdisPacket);
ExFreePoolWithTag(IFC, IFC_TAG);
Complete(Context, IPPacket->NdisPacket, NdisStatus);
return NdisStatus;
}
NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE,
PIP_TRANSMIT_COMPLETE Complete, PVOID Context)
NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE)
/*
* FUNCTION: Sends an IP datagram to a remote address
* ARGUMENTS:
@ -252,8 +247,7 @@ NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE,
NCE->Interface->Stats.OutBytes += PacketSize;
return SendFragments(IPPacket, NCE, NCE->Interface->MTU,
Complete, Context);
return SendFragments(IPPacket, NCE, NCE->Interface->MTU);
}
/* EOF */

View file

@ -167,11 +167,6 @@ NTSTATUS BuildRawIpPacket(
return STATUS_SUCCESS;
}
VOID RawIpSendPacketComplete
( PVOID Context, PNDIS_PACKET Packet, NDIS_STATUS Status ) {
FreeNdisPacket( Packet );
}
NTSTATUS RawIPSendDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
@ -256,11 +251,10 @@ NTSTATUS RawIPSendDatagram(
TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL )))
{
FreeNdisPacket(Packet.NdisPacket);
Status = IPSendDatagram(&Packet, NCE);
FreeNdisPacket(Packet.NdisPacket);
if (!NT_SUCCESS(Status))
return Status;
}
*DataUsed = DataSize;

View file

@ -7,11 +7,6 @@
#include "lwip/api.h"
#include "lwip/tcpip.h"
void TCPPacketSendComplete(PVOID Context, PNDIS_PACKET NdisPacket, NDIS_STATUS NdisStatus)
{
FreeNdisPacket(NdisPacket);
}
err_t
TCPSendDataCallback(struct netif *netif, struct pbuf *p, struct ip_addr *dest)
{
@ -64,10 +59,11 @@ TCPSendDataCallback(struct netif *netif, struct pbuf *p, struct ip_addr *dest)
Packet.SrcAddr = LocalAddress;
Packet.DstAddr = RemoteAddress;
if (!NT_SUCCESS(IPSendDatagram(&Packet, NCE, TCPPacketSendComplete, NULL)))
NdisStatus = IPSendDatagram(&Packet, NCE);
FreeNdisPacket(Packet.NdisPacket);
if (!NT_SUCCESS(NdisStatus))
{
FreeNdisPacket(Packet.NdisPacket);
return ERR_IF;
return ERR_RTE;
}
return 0;

View file

@ -143,11 +143,6 @@ NTSTATUS BuildUDPPacket(
return STATUS_SUCCESS;
}
VOID UDPSendPacketComplete
( PVOID Context, PNDIS_PACKET Packet, NDIS_STATUS Status ) {
FreeNdisPacket( Packet );
}
NTSTATUS UDPSendDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
@ -229,11 +224,10 @@ NTSTATUS UDPSendDatagram(
if( !NT_SUCCESS(Status) )
return Status;
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL )))
{
FreeNdisPacket(Packet.NdisPacket);
Status = IPSendDatagram(&Packet, NCE);
FreeNdisPacket(Packet.NdisPacket);
if (!NT_SUCCESS(Status))
return Status;
}
*DataUsed = DataSize;