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)
{
IPv4_RAW_ADDRESS IPv4Address;
BOOLEAN Matched;
PADDRESS_FILE AddrFile;
TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol));
@ -260,21 +259,19 @@ NTSTATUS FileOpenAddress(
AddrFile->Free = AddrFileFree;
/* 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 */
AddrFile->Family = Address->Address[0].AddressType;
IPv4Address = Address->Address[0].Address[0].in_addr;
if (IPv4Address == 0)
Matched = IPGetDefaultAddress(&AddrFile->Address);
if (IPv4Address != 0 &&
!AddrLocateADEv4(IPv4Address, &AddrFile->Address)) {
exFreePool(AddrFile);
TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address)));
return STATUS_INVALID_PARAMETER;
}
else
Matched = AddrLocateADEv4(IPv4Address, &AddrFile->Address);
if (!Matched) {
exFreePool(AddrFile);
TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address)));
return STATUS_INVALID_PARAMETER;
{
/* Bound to the default address ... Copy the address type */
AddrFile->Address.Type = IP_ADDRESS_V4;
}
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) {
DbgPrint("AddrIsEqual: Unequal Address Types\n");
ASSERT(FALSE);
return FALSE;
}

View file

@ -195,6 +195,8 @@ PIP_INTERFACE IPCreateInterface(
INIT_TAG(IF, TAG('F','A','C','E'));
RtlZeroMemory(IF, sizeof(IP_INTERFACE));
IF->Free = FreeIF;
IF->Context = BindInfo->Context;
IF->HeaderSize = BindInfo->HeaderSize;
@ -210,6 +212,11 @@ PIP_INTERFACE IPCreateInterface(
IF->AddressLength = BindInfo->AddressLength;
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);
#ifdef __NTDRIVER__

View file

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

View file

@ -10,7 +10,6 @@
#include "precomp.h"
BOOLEAN UDPInitialized = FALSE;
PORT_SET UDPPorts;
@ -164,42 +163,49 @@ NTSTATUS UDPSendDatagram(
IP_PACKET Packet;
PTA_IP_ADDRESS RemoteAddressTa = (PTA_IP_ADDRESS)ConnInfo->RemoteAddress;
IP_ADDRESS RemoteAddress;
IP_ADDRESS LocalAddress;
USHORT RemotePort;
NTSTATUS Status;
PNEIGHBOR_CACHE_ENTRY NCE;
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));
switch( RemoteAddressTa->Address[0].AddressType ) {
case TDI_ADDRESS_TYPE_IP:
RemoteAddress.Type = IP_ADDRESS_V4;
RemoteAddress.Address.IPv4Address =
RemoteAddressTa->Address[0].Address[0].in_addr;
RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port;
break;
RemoteAddress.Type = IP_ADDRESS_V4;
RemoteAddress.Address.IPv4Address =
RemoteAddressTa->Address[0].Address[0].in_addr;
RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port;
break;
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 ))) {
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 )))
{
FreeNdisPacket(Packet.NdisPacket);