From 18254a95936e1f8cd9006426a069fd61c1b8afa2 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 17 Oct 2011 01:37:56 +0000 Subject: [PATCH] [TCPIP] - 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 --- reactos/drivers/network/tcpip/include/ip.h | 3 +- .../drivers/network/tcpip/include/neighbor.h | 5 ++- .../drivers/network/tcpip/include/receive.h | 4 +-- .../drivers/network/tcpip/include/transmit.h | 4 +-- reactos/lib/drivers/ip/network/arp.c | 2 +- reactos/lib/drivers/ip/network/icmp.c | 14 +++----- reactos/lib/drivers/ip/network/neighbor.c | 33 +++++++++++++++---- reactos/lib/drivers/ip/network/transmit.c | 12 ++----- .../lib/drivers/ip/transport/rawip/rawip.c | 12 ++----- reactos/lib/drivers/ip/transport/tcp/if.c | 12 +++---- reactos/lib/drivers/ip/transport/udp/udp.c | 12 ++----- 11 files changed, 53 insertions(+), 60 deletions(-) diff --git a/reactos/drivers/network/tcpip/include/ip.h b/reactos/drivers/network/tcpip/include/ip.h index 9d467e593ea..9564d6f1757 100644 --- a/reactos/drivers/network/tcpip/include/ip.h +++ b/reactos/drivers/network/tcpip/include/ip.h @@ -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; diff --git a/reactos/drivers/network/tcpip/include/neighbor.h b/reactos/drivers/network/tcpip/include/neighbor.h index d35f64143d8..9933a133eff 100644 --- a/reactos/drivers/network/tcpip/include/neighbor.h +++ b/reactos/drivers/network/tcpip/include/neighbor.h @@ -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 diff --git a/reactos/drivers/network/tcpip/include/receive.h b/reactos/drivers/network/tcpip/include/receive.h index 6f78828067a..d085a79eec2 100644 --- a/reactos/drivers/network/tcpip/include/receive.h +++ b/reactos/drivers/network/tcpip/include/receive.h @@ -9,8 +9,8 @@ #include -/* 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 { diff --git a/reactos/drivers/network/tcpip/include/transmit.h b/reactos/drivers/network/tcpip/include/transmit.h index 2466f861aea..62b69d3c808 100644 --- a/reactos/drivers/network/tcpip/include/transmit.h +++ b/reactos/drivers/network/tcpip/include/transmit.h @@ -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 */ diff --git a/reactos/lib/drivers/ip/network/arp.c b/reactos/lib/drivers/ip/network/arp.c index a24ff20740a..f19680c9543 100644 --- a/reactos/lib/drivers/ip/network/arp.c +++ b/reactos/lib/drivers/ip/network/arp.c @@ -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) diff --git a/reactos/lib/drivers/ip/network/icmp.c b/reactos/lib/drivers/ip/network/icmp.c index eda19241698..6fdc69c8513 100644 --- a/reactos/lib/drivers/ip/network/icmp.c +++ b/reactos/lib/drivers/ip/network/icmp.c @@ -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", diff --git a/reactos/lib/drivers/ip/network/neighbor.c b/reactos/lib/drivers/ip/network/neighbor.c index ebb3b2721fc..8ab72a67d55 100644 --- a/reactos/lib/drivers/ip/network/neighbor.c +++ b/reactos/lib/drivers/ip/network/neighbor.c @@ -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); } diff --git a/reactos/lib/drivers/ip/network/transmit.c b/reactos/lib/drivers/ip/network/transmit.c index 076e5376e87..f2a6edb0545 100644 --- a/reactos/lib/drivers/ip/network/transmit.c +++ b/reactos/lib/drivers/ip/network/transmit.c @@ -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 */ diff --git a/reactos/lib/drivers/ip/transport/rawip/rawip.c b/reactos/lib/drivers/ip/transport/rawip/rawip.c index e36f7a57bb4..f2718b90696 100644 --- a/reactos/lib/drivers/ip/transport/rawip/rawip.c +++ b/reactos/lib/drivers/ip/transport/rawip/rawip.c @@ -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; diff --git a/reactos/lib/drivers/ip/transport/tcp/if.c b/reactos/lib/drivers/ip/transport/tcp/if.c index 16b340a88f8..bc26c92d135 100644 --- a/reactos/lib/drivers/ip/transport/tcp/if.c +++ b/reactos/lib/drivers/ip/transport/tcp/if.c @@ -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; diff --git a/reactos/lib/drivers/ip/transport/udp/udp.c b/reactos/lib/drivers/ip/transport/udp/udp.c index 5547323ae42..dd856ee64b1 100644 --- a/reactos/lib/drivers/ip/transport/udp/udp.c +++ b/reactos/lib/drivers/ip/transport/udp/udp.c @@ -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;