mirror of
https://github.com/reactos/reactos.git
synced 2025-08-01 21:33:25 +00:00
[TCPIP]
- Avoid an extra copy operation when receiving packets - Optimize loopback code a bit - Make IP receive independent of the location of the data and continuity of buffers in the NDIS packet for ProtocolReceivePacket support (part 1 of x) svn path=/trunk/; revision=54593
This commit is contained in:
parent
37dc00b136
commit
3b2e97595e
5 changed files with 60 additions and 73 deletions
|
@ -278,22 +278,21 @@ VOID LanReceiveWorker( PVOID Context ) {
|
||||||
("Ether Type = %x ContigSize = %d Total = %d\n",
|
("Ether Type = %x ContigSize = %d Total = %d\n",
|
||||||
PacketType, IPPacket.ContigSize, IPPacket.TotalSize));
|
PacketType, IPPacket.ContigSize, IPPacket.TotalSize));
|
||||||
|
|
||||||
|
/* NDIS packet is freed in all of these cases */
|
||||||
switch (PacketType) {
|
switch (PacketType) {
|
||||||
case ETYPE_IPv4:
|
case ETYPE_IPv4:
|
||||||
case ETYPE_IPv6:
|
case ETYPE_IPv6:
|
||||||
TI_DbgPrint(MID_TRACE,("Received IP Packet\n"));
|
TI_DbgPrint(MID_TRACE,("Received IP Packet\n"));
|
||||||
IPReceive(Adapter->Context, &IPPacket);
|
IPReceive(Adapter->Context, &IPPacket);
|
||||||
break;
|
break;
|
||||||
case ETYPE_ARP:
|
case ETYPE_ARP:
|
||||||
TI_DbgPrint(MID_TRACE,("Received ARP Packet\n"));
|
TI_DbgPrint(MID_TRACE,("Received ARP Packet\n"));
|
||||||
ARPReceive(Adapter->Context, &IPPacket);
|
ARPReceive(Adapter->Context, &IPPacket);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
IPPacket.Free(&IPPacket);
|
IPPacket.Free(&IPPacket);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeNdisPacket( Packet );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID LanSubmitReceiveWork(
|
VOID LanSubmitReceiveWork(
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
/* IP datagram fragment descriptor. Used to store IP datagram fragments */
|
/* IP datagram fragment descriptor. Used to store IP datagram fragments */
|
||||||
typedef struct IP_FRAGMENT {
|
typedef struct IP_FRAGMENT {
|
||||||
LIST_ENTRY ListEntry; /* Entry on list */
|
LIST_ENTRY ListEntry; /* Entry on list */
|
||||||
PVOID Data; /* Pointer to fragment data */
|
PNDIS_PACKET Packet; /* NDIS packet containing fragment data */
|
||||||
|
UINT PacketOffset; /* Offset into NDIS packet where data is */
|
||||||
UINT Offset; /* Offset into datagram where this fragment is */
|
UINT Offset; /* Offset into datagram where this fragment is */
|
||||||
UINT Size; /* Size of this fragment */
|
UINT Size; /* Size of this fragment */
|
||||||
} IP_FRAGMENT, *PIP_FRAGMENT;
|
} IP_FRAGMENT, *PIP_FRAGMENT;
|
||||||
|
|
|
@ -30,14 +30,22 @@ TCPRegisterInterface(PIP_INTERFACE IF);
|
||||||
VOID
|
VOID
|
||||||
TCPUnregisterInterface(PIP_INTERFACE IF);
|
TCPUnregisterInterface(PIP_INTERFACE IF);
|
||||||
|
|
||||||
VOID DontFreePacket(
|
VOID DeinitializePacket(
|
||||||
PVOID Object)
|
PVOID Object)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Do nothing for when the IPPacket struct is part of another
|
* FUNCTION: Frees buffers attached to the packet
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* Object = Pointer to an IP packet structure
|
* Object = Pointer to an IP packet structure
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
PIP_PACKET IPPacket = Object;
|
||||||
|
|
||||||
|
/* Detect double free */
|
||||||
|
ASSERT(IPPacket->Type != 0xFF);
|
||||||
|
IPPacket->Type = 0xFF;
|
||||||
|
|
||||||
|
if (IPPacket->NdisPacket != NULL)
|
||||||
|
FreeNdisPacket(IPPacket->NdisPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FreeIF(
|
VOID FreeIF(
|
||||||
|
@ -62,10 +70,9 @@ PIP_PACKET IPInitializePacket(
|
||||||
* Pointer to the created IP packet. NULL if there was not enough free resources.
|
* Pointer to the created IP packet. NULL if there was not enough free resources.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* FIXME: Is this needed? */
|
|
||||||
RtlZeroMemory(IPPacket, sizeof(IP_PACKET));
|
RtlZeroMemory(IPPacket, sizeof(IP_PACKET));
|
||||||
|
|
||||||
IPPacket->Free = DontFreePacket;
|
IPPacket->Free = DeinitializePacket;
|
||||||
IPPacket->Type = Type;
|
IPPacket->Type = Type;
|
||||||
|
|
||||||
return IPPacket;
|
return IPPacket;
|
||||||
|
|
|
@ -17,10 +17,10 @@ VOID LoopPassiveWorker(
|
||||||
{
|
{
|
||||||
PIP_PACKET IPPacket = Context;
|
PIP_PACKET IPPacket = Context;
|
||||||
|
|
||||||
|
/* IPReceive() takes care of the NDIS packet */
|
||||||
IPReceive(Loopback, IPPacket);
|
IPReceive(Loopback, IPPacket);
|
||||||
FreeNdisPacket(IPPacket->NdisPacket);
|
|
||||||
|
|
||||||
ExFreePool(Context);
|
ExFreePool(IPPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID LoopTransmit(
|
VOID LoopTransmit(
|
||||||
|
@ -43,9 +43,8 @@ VOID LoopTransmit(
|
||||||
UINT PacketLength;
|
UINT PacketLength;
|
||||||
PNDIS_PACKET XmitPacket;
|
PNDIS_PACKET XmitPacket;
|
||||||
NDIS_STATUS NdisStatus;
|
NDIS_STATUS NdisStatus;
|
||||||
IP_PACKET IPPacket;
|
PIP_PACKET IPPacket;
|
||||||
PNDIS_BUFFER NdisBuffer;
|
PNDIS_BUFFER NdisBuffer;
|
||||||
PVOID WorkerBuffer;
|
|
||||||
|
|
||||||
ASSERT_KM_POINTER(NdisPacket);
|
ASSERT_KM_POINTER(NdisPacket);
|
||||||
ASSERT_KM_POINTER(PC(NdisPacket));
|
ASSERT_KM_POINTER(PC(NdisPacket));
|
||||||
|
@ -59,24 +58,23 @@ VOID LoopTransmit(
|
||||||
( &XmitPacket, PacketBuffer, PacketLength );
|
( &XmitPacket, PacketBuffer, PacketLength );
|
||||||
|
|
||||||
if( NT_SUCCESS(NdisStatus) ) {
|
if( NT_SUCCESS(NdisStatus) ) {
|
||||||
IPInitializePacket(&IPPacket, 0);
|
IPPacket = ExAllocatePool(NonPagedPool, sizeof(IP_PACKET));
|
||||||
|
if (IPPacket)
|
||||||
IPPacket.NdisPacket = XmitPacket;
|
|
||||||
|
|
||||||
NdisGetFirstBufferFromPacket(XmitPacket,
|
|
||||||
&NdisBuffer,
|
|
||||||
&IPPacket.Header,
|
|
||||||
&IPPacket.ContigSize,
|
|
||||||
&IPPacket.TotalSize);
|
|
||||||
|
|
||||||
|
|
||||||
WorkerBuffer = ExAllocatePool(NonPagedPool, sizeof(IPPacket));
|
|
||||||
if (WorkerBuffer)
|
|
||||||
{
|
{
|
||||||
RtlCopyMemory(WorkerBuffer, &IPPacket, sizeof(IPPacket));
|
IPInitializePacket(IPPacket, 0);
|
||||||
if (!ChewCreate(LoopPassiveWorker, WorkerBuffer))
|
|
||||||
|
IPPacket->NdisPacket = XmitPacket;
|
||||||
|
|
||||||
|
NdisGetFirstBufferFromPacket(XmitPacket,
|
||||||
|
&NdisBuffer,
|
||||||
|
&IPPacket->Header,
|
||||||
|
&IPPacket->ContigSize,
|
||||||
|
&IPPacket->TotalSize);
|
||||||
|
|
||||||
|
if (!ChewCreate(LoopPassiveWorker, IPPacket))
|
||||||
{
|
{
|
||||||
ExFreePool(WorkerBuffer);
|
IPPacket->Free(IPPacket);
|
||||||
|
ExFreePool(IPPacket);
|
||||||
NdisStatus = NDIS_STATUS_RESOURCES;
|
NdisStatus = NDIS_STATUS_RESOURCES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,10 +89,10 @@ VOID FreeIPDR(
|
||||||
/* Unlink it from the list */
|
/* Unlink it from the list */
|
||||||
RemoveEntryList(CurrentEntry);
|
RemoveEntryList(CurrentEntry);
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_IP, ("Freeing fragment data at (0x%X).\n", CurrentF->Data));
|
TI_DbgPrint(DEBUG_IP, ("Freeing fragment packet at (0x%X).\n", CurrentF->Packet));
|
||||||
|
|
||||||
/* Free the fragment data buffer */
|
/* Free the fragment data buffer */
|
||||||
ExFreePoolWithTag(CurrentF->Data, FRAGMENT_DATA_TAG);
|
FreeNdisPacket(CurrentF->Packet);
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_IP, ("Freeing fragment at (0x%X).\n", CurrentF));
|
TI_DbgPrint(DEBUG_IP, ("Freeing fragment at (0x%X).\n", CurrentF));
|
||||||
|
|
||||||
|
@ -186,20 +186,16 @@ ReassembleDatagram(
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PIP_FRAGMENT Current;
|
PIP_FRAGMENT Fragment;
|
||||||
PVOID Data;
|
PCHAR Data;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_IP, ("Reassembling datagram from IPDR at (0x%X).\n", IPDR));
|
TI_DbgPrint(DEBUG_IP, ("Reassembling datagram from IPDR at (0x%X).\n", IPDR));
|
||||||
TI_DbgPrint(DEBUG_IP, ("IPDR->HeaderSize = %d\n", IPDR->HeaderSize));
|
TI_DbgPrint(DEBUG_IP, ("IPDR->HeaderSize = %d\n", IPDR->HeaderSize));
|
||||||
TI_DbgPrint(DEBUG_IP, ("IPDR->DataSize = %d\n", IPDR->DataSize));
|
TI_DbgPrint(DEBUG_IP, ("IPDR->DataSize = %d\n", IPDR->DataSize));
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_IP, ("Fragment header:\n"));
|
|
||||||
//OskitDumpBuffer((PCHAR)IPDR->IPv4Header, IPDR->HeaderSize);
|
|
||||||
|
|
||||||
IPPacket->TotalSize = IPDR->HeaderSize + IPDR->DataSize;
|
IPPacket->TotalSize = IPDR->HeaderSize + IPDR->DataSize;
|
||||||
IPPacket->ContigSize = IPPacket->TotalSize;
|
IPPacket->ContigSize = IPPacket->TotalSize;
|
||||||
IPPacket->HeaderSize = IPDR->HeaderSize;
|
IPPacket->HeaderSize = IPDR->HeaderSize;
|
||||||
/*IPPacket->Position = IPDR->HeaderSize;*/
|
|
||||||
|
|
||||||
RtlCopyMemory(&IPPacket->SrcAddr, &IPDR->SrcAddr, sizeof(IP_ADDRESS));
|
RtlCopyMemory(&IPPacket->SrcAddr, &IPDR->SrcAddr, sizeof(IP_ADDRESS));
|
||||||
RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS));
|
RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS));
|
||||||
|
@ -221,15 +217,14 @@ ReassembleDatagram(
|
||||||
/* Copy data from all fragments into buffer */
|
/* Copy data from all fragments into buffer */
|
||||||
CurrentEntry = IPDR->FragmentListHead.Flink;
|
CurrentEntry = IPDR->FragmentListHead.Flink;
|
||||||
while (CurrentEntry != &IPDR->FragmentListHead) {
|
while (CurrentEntry != &IPDR->FragmentListHead) {
|
||||||
Current = CONTAINING_RECORD(CurrentEntry, IP_FRAGMENT, ListEntry);
|
Fragment = CONTAINING_RECORD(CurrentEntry, IP_FRAGMENT, ListEntry);
|
||||||
|
|
||||||
|
/* Copy fragment data into datagram buffer */
|
||||||
|
CopyPacketToBuffer(Data + Fragment->Offset,
|
||||||
|
Fragment->Packet,
|
||||||
|
Fragment->PacketOffset,
|
||||||
|
Fragment->Size);
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_IP, ("Copying (%d) bytes of fragment data from (0x%X) to offset (%d).\n",
|
|
||||||
Current->Size, Data, Current->Offset));
|
|
||||||
/* Copy fragment data to the destination buffer at the correct offset */
|
|
||||||
RtlCopyMemory((PVOID)((ULONG_PTR)Data + Current->Offset),
|
|
||||||
Current->Data,
|
|
||||||
Current->Size);
|
|
||||||
//OskitDumpBuffer( Data, Current->Offset + Current->Size );
|
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,25 +405,13 @@ VOID ProcessFragment(
|
||||||
TI_DbgPrint(DEBUG_IP, ("Fragment descriptor allocated at (0x%X).\n", Fragment));
|
TI_DbgPrint(DEBUG_IP, ("Fragment descriptor allocated at (0x%X).\n", Fragment));
|
||||||
|
|
||||||
Fragment->Size = IPPacket->TotalSize - IPPacket->HeaderSize;
|
Fragment->Size = IPPacket->TotalSize - IPPacket->HeaderSize;
|
||||||
Fragment->Data = ExAllocatePoolWithTag(NonPagedPool, Fragment->Size, FRAGMENT_DATA_TAG);
|
Fragment->Packet = IPPacket->NdisPacket;
|
||||||
if (!Fragment->Data) {
|
Fragment->PacketOffset = IPPacket->Position + IPPacket->HeaderSize;
|
||||||
/* We don't have the resources to process this packet, discard it */
|
|
||||||
ExFreeToNPagedLookasideList(&IPFragmentList, Fragment);
|
|
||||||
Cleanup(&IPDR->Lock, OldIrql, IPDR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Position here is an offset from the NdisPacket start, not the header */
|
|
||||||
TI_DbgPrint(DEBUG_IP, ("Fragment data buffer allocated at (0x%X) Size (%d) Pos (%d).\n",
|
|
||||||
Fragment->Data, Fragment->Size, IPPacket->Position));
|
|
||||||
|
|
||||||
/* Copy datagram data into fragment buffer */
|
|
||||||
CopyPacketToBuffer(Fragment->Data,
|
|
||||||
IPPacket->NdisPacket,
|
|
||||||
IPPacket->HeaderSize,
|
|
||||||
Fragment->Size);
|
|
||||||
Fragment->Offset = FragFirst;
|
Fragment->Offset = FragFirst;
|
||||||
|
|
||||||
|
/* Disassociate the NDIS packet so it isn't freed upon return from IPReceive() */
|
||||||
|
IPPacket->NdisPacket = NULL;
|
||||||
|
|
||||||
/* If this is the last fragment, compute and save the datagram data size */
|
/* If this is the last fragment, compute and save the datagram data size */
|
||||||
if (!MoreFragments)
|
if (!MoreFragments)
|
||||||
IPDR->DataSize = FragFirst + Fragment->Size;
|
IPDR->DataSize = FragFirst + Fragment->Size;
|
||||||
|
@ -581,7 +564,6 @@ VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
|
||||||
AddrInitIPv4(&IPPacket->SrcAddr, ((PIPv4_HEADER)IPPacket->Header)->SrcAddr);
|
AddrInitIPv4(&IPPacket->SrcAddr, ((PIPv4_HEADER)IPPacket->Header)->SrcAddr);
|
||||||
AddrInitIPv4(&IPPacket->DstAddr, ((PIPv4_HEADER)IPPacket->Header)->DstAddr);
|
AddrInitIPv4(&IPPacket->DstAddr, ((PIPv4_HEADER)IPPacket->Header)->DstAddr);
|
||||||
|
|
||||||
IPPacket->Position += IPPacket->HeaderSize;
|
|
||||||
IPPacket->Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPPacket->HeaderSize);
|
IPPacket->Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPPacket->HeaderSize);
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE,("IPPacket->Position = %d\n",
|
TI_DbgPrint(MID_TRACE,("IPPacket->Position = %d\n",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue