diff options
author | Simon Rozman <simon@rozman.si> | 2021-04-12 13:08:42 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-04-13 15:56:04 -0600 |
commit | 47b16dc884992d9c100bc0161d4ca6776a3cd507 (patch) | |
tree | d190ac907cc18785575f078ab8229862550d9cc6 /driver | |
parent | Allow optional padding before and after layer 3 packets (diff) | |
download | wintun-47b16dc884992d9c100bc0161d4ca6776a3cd507.tar.xz wintun-47b16dc884992d9c100bc0161d4ca6776a3cd507.zip |
Allow packet over-allocation on sendsr/api-improvements
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 <simon@rozman.si>
Diffstat (limited to 'driver')
-rw-r--r-- | driver/wintun.c | 14 |
1 files changed, 9 insertions, 5 deletions
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; |