- A partial fix for #41
- Decrements the TTL for reinjected packets.
- If (TTL==0), WinDivertRecv() will fail with:
ERROR_HOST_UNREACHABLE = 1232
which is better than looping.
- Immediately reinject in SNIFF mode.
- Use a NET_BUFFER pool for cloned packets.
- Fix bug caused by pool mix up for cloned packets.
- Copy NET_BUFFER_LIST info for non-matching packets.
- Keep reference to original NET_BUFFER_LIST after cloning.
(might not be necessary, but some sample drivers do).
This is a major update designed to modernize the WinDivert driver, including
optimizations, design improvements and bug fixes. The new version has not
been fully tested and should be considered **UNSTABLE**.
- Most of the packet processing is now (almost) fully out-of-band. This is a
good since the classify function runs at DISPATCH_LEVEL. The driver will
still try to match at least one packet before moving the work out-of-band.
- Re-injected non-matching packets are now clones rather than copies.
- Queued packets are still copied. This is because the driver should avoid
keeping a reference to the original packet for very long. Since we do not
trust the user application to handle the packet in a timely fashion, it is
better to copy rather than keep a reference. That said, the driver now
implements an optimization where it will service a read request immediately
if possible (saving 1 packet copy).
- SNIFF mode also now works differently. Previously, SNIFF mode would not
block the original packet. However, this is problematic under the new
design since WinDivert cannot permit the packet and retain a reference to it
at the same time. The new version will block & absorb the original packet
and re-inject a clone out-of-band.
- Packet time management has been replaced. Previously, a timer was used to
periodically wake up a function that would sweep away expired packets. The
new version explicitly timestamps every packet, and expired packets are
cleaned up by the read service routine.
- The context->filter is now deallocated in the destroy callback to avoid
possible a race condition with the callout function. It is unclear if this
is really necessary, however.
Currently, WinDivert waits until injection completes before completing the
corresponding IO request. However, packet injection may take an arbitrarily
long time, such as waiting for a user-mode application.
The new version completes the IO request immediately, provided the call to the
corresponding WFP packet injection function did not return an error, thus
eliminating the problem. The disadvantage is that some packet injection
errors may no longer be detected.
on the WinDivert handle, the driver's cleanup function cannot make FWPM
calls. The cleanup function detects this FWPM error and returns
without ever calling the Fwps cleanup functions (which are independent
of fwpm).
As a result, the driver will not unregister the callouts, which leaves
the Windows kernel confused. You can reproduce the problem by having
a user app close uncleanly, then "sc stop windivert1.2", then try to
re-run the app. You'll get "file not found" when StartService() is called.
WinDivert now treats all offloaded checksum fields as zero:
- WinDivertRecv() will zero all offloaded checksum fields.
- Filter matching will treat offloaded fields as zero.
Bump version and change magic numbers to make the driver incompatible with
older versions. Also cleanup some driver checksum code missed by previous
commit.
- As discussed in #37, the WINDIVERT_FLAG_NO_CHECKSUM behavior has become the
default. This means that outbound packets returned by WinDivertRecv() are
no longer guaranteed to have valid checksums, thanks to TCP checksum
offloading by the Windows TCP/IP stack. The checksums can still be
recovered by calling WinDivertHelperCalcChecksums() manually.
- Remove the old WinDivert1.0 legacy API, as nobody should still be using it.
by the classify function and silently dropped. This can degrade outbound
speed significantly, as it forces the Windows TCP/IP stack to re-send the
missing data. Thanks to GhalemB who found the bug & fix.
* WinDivert sublayers are created and inserted when the driver is loaded.
* All WinDivert callouts are installed at the same sublayer.
- Clean-up the implementation of priorities.
- Re-introduce deep copying for SNIFF mode. This avoids referencing the
sniffed packets.
- Fix-up the netfilter example:
* Don't send RSTs to RST/FINs, this can start a RST war.
* Don't inject ICMP outbound - this may not be a problem despite 1233 errors.
1) Remove the dependency on the WdfCoInstaller*.dll file. This file appears
to be unnecessary for Windows 7 and up, and for patched Vista+2008.
2) Remove the WinDivert.inf file (only used by the co-installer).
3) 32/64-bit versions of the driver are now explicitly named, meaning that
the two can co-exist in the same directory.
4) The 32-bit WinDivert.dll can now automatically load the 64-bit driver on
64-bit Windows. This means it is possible to write 32-bit WinDivert
applications that automatically work on 64-bit windows.
5) WinDivert.dll now schedules the WinDivert service to be deleted right
away. This should fix some cases where the service is never deleted,
even during reboot.
6) Updated build scripts to reflect the changes.