Fix loopback adapter locking and make traffic work consistently.

Fix zero-address binding.
Local tcp services should work now.

svn path=/trunk/; revision=39613
This commit is contained in:
Art Yerkes 2009-02-15 21:52:56 +00:00
parent 9b0334da19
commit 90b16f9eca
5 changed files with 76 additions and 57 deletions

View file

@ -242,7 +242,6 @@ NTSTATUS FileOpenAddress(
PVOID Options) PVOID Options)
{ {
IPv4_RAW_ADDRESS IPv4Address; IPv4_RAW_ADDRESS IPv4Address;
BOOLEAN Matched;
PADDRESS_FILE AddrFile; PADDRESS_FILE AddrFile;
TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol)); TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol));
@ -260,21 +259,19 @@ NTSTATUS FileOpenAddress(
AddrFile->Free = AddrFileFree; AddrFile->Free = AddrFileFree;
/* Make sure address is a local unicast address or 0 */ /* Make sure address is a local unicast address or 0 */
/* Locate address entry. If specified address is 0, a random address is chosen */
/* FIXME: IPv4 only */ /* FIXME: IPv4 only */
AddrFile->Family = Address->Address[0].AddressType; AddrFile->Family = Address->Address[0].AddressType;
IPv4Address = Address->Address[0].Address[0].in_addr; IPv4Address = Address->Address[0].Address[0].in_addr;
if (IPv4Address == 0) if (IPv4Address != 0 &&
Matched = IPGetDefaultAddress(&AddrFile->Address); !AddrLocateADEv4(IPv4Address, &AddrFile->Address)) {
exFreePool(AddrFile);
TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address)));
return STATUS_INVALID_PARAMETER;
}
else else
Matched = AddrLocateADEv4(IPv4Address, &AddrFile->Address); {
/* Bound to the default address ... Copy the address type */
if (!Matched) { AddrFile->Address.Type = IP_ADDRESS_V4;
exFreePool(AddrFile);
TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address)));
return STATUS_INVALID_PARAMETER;
} }
TI_DbgPrint(MID_TRACE, ("Opening address %s for communication (P=%d U=%d).\n", TI_DbgPrint(MID_TRACE, ("Opening address %s for communication (P=%d U=%d).\n",

View file

@ -223,6 +223,7 @@ BOOLEAN AddrIsEqual(
{ {
if (Address1->Type != Address2->Type) { if (Address1->Type != Address2->Type) {
DbgPrint("AddrIsEqual: Unequal Address Types\n"); DbgPrint("AddrIsEqual: Unequal Address Types\n");
ASSERT(FALSE);
return FALSE; return FALSE;
} }

View file

@ -195,6 +195,8 @@ PIP_INTERFACE IPCreateInterface(
INIT_TAG(IF, TAG('F','A','C','E')); INIT_TAG(IF, TAG('F','A','C','E'));
RtlZeroMemory(IF, sizeof(IP_INTERFACE));
IF->Free = FreeIF; IF->Free = FreeIF;
IF->Context = BindInfo->Context; IF->Context = BindInfo->Context;
IF->HeaderSize = BindInfo->HeaderSize; IF->HeaderSize = BindInfo->HeaderSize;
@ -210,6 +212,11 @@ PIP_INTERFACE IPCreateInterface(
IF->AddressLength = BindInfo->AddressLength; IF->AddressLength = BindInfo->AddressLength;
IF->Transmit = BindInfo->Transmit; IF->Transmit = BindInfo->Transmit;
IF->Unicast.Type = IP_ADDRESS_V4;
IF->PointToPoint.Type = IP_ADDRESS_V4;
IF->Netmask.Type = IP_ADDRESS_V4;
IF->Broadcast.Type = IP_ADDRESS_V4;
TcpipInitializeSpinLock(&IF->Lock); TcpipInitializeSpinLock(&IF->Lock);
#ifdef __NTDRIVER__ #ifdef __NTDRIVER__

View file

@ -32,20 +32,25 @@ VOID NTAPI LoopReceiveWorker( PVOID Context ) {
UINT BytesTransferred; UINT BytesTransferred;
PNDIS_BUFFER NdisBuffer; PNDIS_BUFFER NdisBuffer;
IP_PACKET IPPacket; IP_PACKET IPPacket;
KIRQL OldIrql;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
while( (ListEntry = TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql );
ExInterlockedRemoveHeadList( &LoopWorkList, &LoopWorkLock )) ) { while( !IsListEmpty(&LoopWorkList) )
WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); {
ListEntry = RemoveHeadList( &LoopWorkList );
TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem)); WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
Packet = WorkItem->Packet; TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem));
Adapter = WorkItem->Adapter;
BytesTransferred = WorkItem->BytesTransferred;
exFreePool( WorkItem ); Packet = WorkItem->Packet;
Adapter = WorkItem->Adapter;
BytesTransferred = WorkItem->BytesTransferred;
exFreePool( WorkItem );
IPPacket.NdisPacket = Packet; IPPacket.NdisPacket = Packet;
@ -58,23 +63,26 @@ VOID NTAPI LoopReceiveWorker( PVOID Context ) {
&IPPacket.ContigSize, &IPPacket.ContigSize,
&IPPacket.TotalSize); &IPPacket.TotalSize);
IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred; IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred;
/* Determine which upper layer protocol that should receive /* Determine which upper layer protocol that should receive
this packet and pass it to the correct receive handler */ this packet and pass it to the correct receive handler */
TI_DbgPrint(MID_TRACE, TI_DbgPrint
("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n", (MID_TRACE,
IPPacket.ContigSize, IPPacket.TotalSize, ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n",
BytesTransferred)); IPPacket.ContigSize, IPPacket.TotalSize,
BytesTransferred));
IPPacket.Position = 0; IPPacket.Position = 0;
IPReceive(Loopback, &IPPacket); IPReceive(Loopback, &IPPacket);
FreeNdisPacket( Packet ); FreeNdisPacket( Packet );
TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql );
} }
TI_DbgPrint(DEBUG_DATALINK, ("Leaving\n")); TI_DbgPrint(DEBUG_DATALINK, ("Leaving\n"));
LoopReceiveWorkerBusy = FALSE; LoopReceiveWorkerBusy = FALSE;
TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
} }
VOID LoopSubmitReceiveWork( VOID LoopSubmitReceiveWork(

View file

@ -10,7 +10,6 @@
#include "precomp.h" #include "precomp.h"
BOOLEAN UDPInitialized = FALSE; BOOLEAN UDPInitialized = FALSE;
PORT_SET UDPPorts; PORT_SET UDPPorts;
@ -164,42 +163,49 @@ NTSTATUS UDPSendDatagram(
IP_PACKET Packet; IP_PACKET Packet;
PTA_IP_ADDRESS RemoteAddressTa = (PTA_IP_ADDRESS)ConnInfo->RemoteAddress; PTA_IP_ADDRESS RemoteAddressTa = (PTA_IP_ADDRESS)ConnInfo->RemoteAddress;
IP_ADDRESS RemoteAddress; IP_ADDRESS RemoteAddress;
IP_ADDRESS LocalAddress;
USHORT RemotePort; USHORT RemotePort;
NTSTATUS Status; NTSTATUS Status;
PNEIGHBOR_CACHE_ENTRY NCE; PNEIGHBOR_CACHE_ENTRY NCE;
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
AddrFile, ConnInfo, BufferData, DataSize)); AddrFile, ConnInfo, BufferData, DataSize));
TI_DbgPrint(MID_TRACE,("RemoteAddressTa: %x\n", RemoteAddressTa)); TI_DbgPrint(MID_TRACE,("RemoteAddressTa: %x\n", RemoteAddressTa));
switch( RemoteAddressTa->Address[0].AddressType ) { switch( RemoteAddressTa->Address[0].AddressType ) {
case TDI_ADDRESS_TYPE_IP: case TDI_ADDRESS_TYPE_IP:
RemoteAddress.Type = IP_ADDRESS_V4; RemoteAddress.Type = IP_ADDRESS_V4;
RemoteAddress.Address.IPv4Address = RemoteAddress.Address.IPv4Address =
RemoteAddressTa->Address[0].Address[0].in_addr; RemoteAddressTa->Address[0].Address[0].in_addr;
RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port; RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port;
break; break;
default: default:
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
Status = BuildUDPPacket( &Packet,
&RemoteAddress,
RemotePort,
&AddrFile->Address,
AddrFile->Port,
BufferData,
DataSize );
if( !NT_SUCCESS(Status) )
return Status;
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
FreeNdisPacket(Packet.NdisPacket); return STATUS_UNSUCCESSFUL;
return STATUS_UNSUCCESSFUL;
} }
LocalAddress = AddrFile->Address;
if (AddrIsUnspecified(&LocalAddress))
{
if (!IPGetDefaultAddress(&LocalAddress))
return FALSE;
}
Status = BuildUDPPacket( &Packet,
&RemoteAddress,
RemotePort,
&LocalAddress,
AddrFile->Port,
BufferData,
DataSize );
if( !NT_SUCCESS(Status) )
return Status;
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL ))) if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL )))
{ {
FreeNdisPacket(Packet.NdisPacket); FreeNdisPacket(Packet.NdisPacket);