From 47b16dc884992d9c100bc0161d4ca6776a3cd507 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Mon, 12 Apr 2021 13:08:42 +0200 Subject: Allow packet over-allocation on send Should client desire to prepare packets for Wintun inside the ring memory (e.g. to reduce memory copying), the final sending packet size is not always known at the WintunAllocateSendPacket() time. This commit modifies Wintun to calculate the packet size on delivery to NDIS. The packet size is derived from IPv4/IPv6 packet header. Signed-off-by: Simon Rozman --- driver/wintun.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'driver') diff --git a/driver/wintun.c b/driver/wintun.c index 4224642..b9a3bb8 100644 --- a/driver/wintun.c +++ b/driver/wintun.c @@ -532,15 +532,19 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx) if (AlignedPacketSize > RingContent) break; + ULONG Layer3PacketSize; ULONG NblFlags; USHORT NblProto; const UCHAR *PacketData = Packet->Data + Ctx->Device.Receive.LeadPadding; - if (PacketSize >= 20 && PacketData[0] >> 4 == 4) + if (PacketSize >= 20 && PacketData[0] >> 4 == 4 && + (Layer3PacketSize = RtlUshortByteSwap(*(USHORT *)&PacketData[2])) >= 20 && Layer3PacketSize <= PacketSize) { NblFlags = NDIS_NBL_FLAGS_IS_IPV4; NblProto = HTONS(NDIS_ETH_TYPE_IPV4); } - else if (PacketSize >= 40 && PacketData[0] >> 4 == 6) + else if ( + PacketSize >= 40 && PacketData[0] >> 4 == 6 && + (Layer3PacketSize = 40ul + RtlUshortByteSwap(*(USHORT *)&PacketData[4])) <= PacketSize) { NblFlags = NDIS_NBL_FLAGS_IS_IPV6; NblProto = HTONS(NDIS_ETH_TYPE_IPV6); @@ -549,15 +553,15 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx) break; RingHead = TUN_RING_WRAP(RingHead + AlignedPacketSize, RingCapacity); - MDL *Mdl = IoAllocateMdl(NULL, PacketSize, FALSE, FALSE, NULL); + MDL *Mdl = IoAllocateMdl(NULL, Layer3PacketSize, FALSE, FALSE, NULL); if (!Mdl) goto skipNbl; IoBuildPartialMdl( Ctx->Device.Receive.Mdl, Mdl, (UCHAR *)MmGetMdlVirtualAddress(Ctx->Device.Receive.Mdl) + (ULONG)(PacketData - (UCHAR *)Ring), - PacketSize); - NET_BUFFER_LIST *Nbl = NdisAllocateNetBufferAndNetBufferList(Ctx->NblPool, 0, 0, Mdl, 0, PacketSize); + Layer3PacketSize); + NET_BUFFER_LIST *Nbl = NdisAllocateNetBufferAndNetBufferList(Ctx->NblPool, 0, 0, Mdl, 0, Layer3PacketSize); if (!Nbl) goto cleanupMdl; Nbl->SourceHandle = Ctx->MiniportAdapterHandle; -- cgit v1.2.3-59-g8ed1b