I want to report an issue I found with your example (send ring buffer get corrupted)
Oded Katz <[email protected]> Fri, 23 Jan 2026 11:34:17 -0800
| Newsgroups | com.zx2c4.lists.wireguard |
|---|---|
| Message-ID | <CAApnxP0OicCUvxYo41sK8AnK=bxqR+qE2BTxFmE5cJbSyOJrBQ@mail.gmail.com> |
Hi,we were trying to integrate `wintun` into our product and while testing we found an issue with upload of high UDP throughput on multiple sockets. initially we thought it may be related to our integration. but we managed to find the same issue in your example code.we tried to do some debugging on the example, but it seems like the corruption is on the driver side. the way to reproduce this issue- run the example - run the `send_udp.py` (the attached python script) on 2 different command terminals - `send_udp.py 10.6.7.8 5201 1450` - `send_udp.py 10.6.7.8 5201 1400`after some time the `WintunReceivePacket` returns NULL and `GetLastError()` return 13 (`ERROR_INVALID_DATA`) many thank, and I hope you can help us. btw: in the meantime, I'll try to see if I can contribute myself with a fix Oded
send_udp.py
(text/x-python-script, 5 KB)
#!/usr/bin/env python3
"""
A Python script to send a continuous stream of UDP packets to a specified
host and port.
It prints the number of packets sent every second.
The first 4 bytes of the payload contain a packet counter (little-endian).
The remaining 60 bytes are filled with the character 'a'.
Usage:
python send_udp_flood.py <address> <port>
Example:
python send_udp_flood.py 127.0.0.1 8080
"""
import socket
import argparse
import sys
import time
def main():
# --- 1. Set up the command-line argument parser ---
parser = argparse.ArgumentParser(
description="Send a continuous UDP packet stream.",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="Example:\n python send_udp_flood.py 127.0.0.1 8080"
)
parser.add_argument("address",
help="The destination IP address or hostname (e.g., 127.0.0.1)")
parser.add_argument("port",
type=int,
help="The destination port (e.g., 8080)")
parser.add_argument("len",
type=int,
help="The padding len (e.g., 60-1350)")
args = parser.parse_args()
# --- 2. Create the packet data (padding) ---
# We create the 60-byte padding once, as it never changes.
payload_padding = (b'a' * args.len)
destination = (args.address, args.port)
print(f"Target: {args.address}:{args.port}")
print(f"Payload: {args.len + 4} bytes (4-byte counter + {args.len} 'a's)")
print("---------------------------------")
#
print(f"Starting continuous send. Press Ctrl+C to stop.")
# Statistics counters
packets_in_interval = 0
total_packets_sent = 0 # This will be our packet counter
# Use time.monotonic() for stable time interval measurements
start_time = time.monotonic()
last_print_time = start_time
try:
# Create a UDP socket
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
# --- 3. Main Send Loop ---
while True:
# --- Create the payload for *this* packet ---
# Convert the counter to 4 bytes, little-endian
counter_bytes = total_packets_sent.to_bytes(4, 'little')
# Combine the counter and the padding
payload_bytes = payload_padding + counter_bytes
# Send the packet
s.sendto(payload_bytes, destination)
# Increment counters
packets_in_interval += 1
total_packets_sent += 1
# --- 4. Statistics Loop ---
current_time = time.monotonic()
elapsed_since_last = current_time - last_print_time
# Check if 1.0 second has passed
if elapsed_since_last >= 1.0:
# Calculate the rate for this interval
rate = packets_in_interval / elapsed_since_last
# Print stats (pps = packets per second)
# We use f-strings with :>10, to right-align the packet count
# and :,.0f to format the rate with commas and no decimals.
print(f"Sent {packets_in_interval:>10,} packets. (Rate: {rate:,.0f} pps, {(packets_in_interval * (args.len + 4 + 28) * 8 / 1000 / 1000):,.3f} Mbit/sec)")
# Reset for the next interval
packets_in_interval = 0
last_print_time = current_time
except KeyboardInterrupt:
# --- 5. Handle Ctrl+C ---
print("\n---------------------------------")
print("Stopping...")
# Print final summary statistics
end_time = time.monotonic()
total_time = end_time - start_time
if total_time > 0:
avg_rate = total_packets_sent / total_time
print(f"Sent a total of {total_packets_sent:n} packets in {total_time:.2f} seconds.")
print(f"Average rate: {avg_rate:,.0f} pps, {(avg_rate * (args.len + 4 + 28) * 8 / 1000 / 1000):,.3f} Mbit/sec")
else:
print("Sent 0 packets.")
sys.exit(0)
except socket.gaierror as e:
print(f"\nError: Hostname '{args.address}' could not be resolved.", file=sys.stderr)
print(f"Details: {e}", file=sys.stderr)
sys.exit(1)
except (socket.error, OSError) as e:
print(f"\nError: Could not send packet.", file=sys.stderr)
print(f"Details: {e}", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"\nAn unexpected error occurred:", file=sys.stderr)
print(f"Details: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()