Add batched recv/send to WinDivert (#156).

This change allows multiple packets to be
received/sent at once, reducing overheads.  To
exploit this feature, applications need to use
the WinDivertRecvEx()/WinDivertSendEx()
functions with the new addrLen parameter.  The
passthru example has been modified to use
batching.

The DEBUG flag has been retired since it
conflicts with batching, and was not very
useful anyway.
This commit is contained in:
basil00
2018-11-03 08:40:34 +08:00
parent 3966ec1287
commit 4f7ff88664
8 changed files with 478 additions and 331 deletions
+26 -10
View File
@@ -47,7 +47,10 @@
#include "windivert.h"
#define MAXBUF 0xFFFF
#define MAXBUF 0xFFFF
#define MAXBATCH 0xFF
static int batch = 1;
static DWORD passthru(LPVOID arg);
@@ -59,9 +62,10 @@ int __cdecl main(int argc, char **argv)
int num_threads, priority = 0, i;
HANDLE handle, thread;
if (argc != 3 && argc != 4)
if (argc < 3 || argc > 5)
{
fprintf(stderr, "usage: %s filter num-threads [priority]\n", argv[0]);
fprintf(stderr, "usage: %s filter num-threads [batch] [priority]\n",
argv[0]);
exit(EXIT_FAILURE);
}
num_threads = atoi(argv[2]);
@@ -70,9 +74,18 @@ int __cdecl main(int argc, char **argv)
fprintf(stderr, "error: invalid number of threads\n");
exit(EXIT_FAILURE);
}
if (argc == 4)
if (argc >= 4)
{
priority = atoi(argv[3]);
batch = atoi(argv[3]);
}
if (batch <= 0 || batch > MAXBATCH)
{
fprintf(stderr, "error: invalid batch size\n");
exit(EXIT_FAILURE);
}
if (argc >= 5)
{
priority = atoi(argv[4]);
}
// Divert traffic matching the filter:
@@ -112,16 +125,18 @@ int __cdecl main(int argc, char **argv)
// Passthru thread.
static DWORD passthru(LPVOID arg)
{
unsigned char packet[MAXBUF];
UINT packet_len;
WINDIVERT_ADDRESS addr;
UINT8 packet[MAXBUF];
UINT packet_len, addr_len;
WINDIVERT_ADDRESS addr[MAXBATCH];
HANDLE handle = (HANDLE)arg;
// Main loop:
while (TRUE)
{
// Read a matching packet.
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
addr_len = batch * sizeof(WINDIVERT_ADDRESS);
if (!WinDivertRecvEx(handle, packet, sizeof(packet), &packet_len, 0,
addr, &addr_len, NULL))
{
fprintf(stderr, "warning: failed to read packet (%d)\n",
GetLastError());
@@ -129,7 +144,8 @@ static DWORD passthru(LPVOID arg)
}
// Re-inject the matching packet.
if (!WinDivertSend(handle, packet, packet_len, &addr, NULL))
if (!WinDivertSendEx(handle, packet, packet_len, NULL, 0, addr,
addr_len, NULL))
{
fprintf(stderr, "warning: failed to reinject packet (%d)\n",
GetLastError());
+4 -4
View File
@@ -227,8 +227,8 @@ int __cdecl main(int argc, char **argv)
memset(&overlapped, 0, sizeof(overlapped));
ResetEvent(event);
overlapped.hEvent = event;
if (!WinDivertRecvEx(handle, packet, sizeof(packet), 0, &addr,
&packet_len, &overlapped))
if (!WinDivertRecvEx(handle, packet, sizeof(packet), &packet_len, 0,
&addr, NULL, &overlapped))
{
if (GetLastError() != ERROR_IO_PENDING)
{
@@ -299,8 +299,8 @@ read_failed:
error("failed to allocate memory");
}
memset(poverlapped, 0, sizeof(OVERLAPPED));
if (WinDivertSendEx(handle, packet, packet_len, 0, &addr, NULL,
poverlapped))
if (WinDivertSendEx(handle, packet, packet_len, NULL, 0, &addr,
sizeof(WINDIVERT_ADDRESS), poverlapped))
{
continue;
}
+2 -7
View File
@@ -360,14 +360,9 @@ usage:
printf("%sSEND_ONLY", (or? "|": ""));
or = TRUE;
}
if ((addr.Reflect.Flags & WINDIVERT_FLAG_DEBUG) != 0)
if ((addr.Reflect.Flags & WINDIVERT_FLAG_RECV_PARTIAL) != 0)
{
printf("%sDEBUG", (or? "|": ""));
or = TRUE;
}
if ((addr.Reflect.Flags & WINDIVERT_FLAG_PARTIAL) != 0)
{
printf("%sPARTIAL", (or? "|": ""));
printf("%sRECV_PARTIAL", (or? "|": ""));
or = TRUE;
}
if ((addr.Reflect.Flags & WINDIVERT_FLAG_NO_INSTALL) != 0)