mirror of
https://github.com/reactos/reactos.git
synced 2025-06-27 18:00:49 +00:00
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:
parent
9b0334da19
commit
90b16f9eca
5 changed files with 76 additions and 57 deletions
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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__
|
||||||
|
|
|
@ -32,49 +32,57 @@ 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 );
|
||||||
TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem));
|
TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
|
||||||
|
|
||||||
Packet = WorkItem->Packet;
|
|
||||||
Adapter = WorkItem->Adapter;
|
|
||||||
BytesTransferred = WorkItem->BytesTransferred;
|
|
||||||
|
|
||||||
exFreePool( WorkItem );
|
|
||||||
|
|
||||||
|
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;
|
IPPacket.NdisPacket = Packet;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n",
|
TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n",
|
||||||
Packet, Adapter, BytesTransferred));
|
Packet, Adapter, BytesTransferred));
|
||||||
|
|
||||||
NdisGetFirstBufferFromPacket(Packet,
|
NdisGetFirstBufferFromPacket(Packet,
|
||||||
&NdisBuffer,
|
&NdisBuffer,
|
||||||
&IPPacket.Header,
|
&IPPacket.Header,
|
||||||
&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(
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue