Datagram Guard Options

Read time 3 minutes Package: Nalix.Network / Nalix.Runtime
On this page

DatagramGuardOptions configures the bounded source-window tracking used by the UDP listener’s DatagramGuard. The guard limits per-source packet rate through ConnectionGuardOptions.MaxPacketPerSecond, while this options type controls how many IPv4/IPv6 source windows can be tracked and how stale windows are cleaned up.

Source Mapping

  • src/Nalix.Network/Options/DatagramGuardOptions.cs
  • src/Nalix.Network/RateLimiting/Datagram.Guard.cs
  • src/Nalix.Network/Listeners/UdpListener/UdpListener.Core.cs

UDP Listener Wiring

UdpListenerBase loads and validates these options in its static constructor:

s_datagramGuardOptions = ConfigurationManager.Instance.Get<DatagramGuardOptions>();
s_datagramGuardOptions.Validate();

Each listener instance then constructs a DatagramGuard with:

  • ConnectionGuardOptions.MaxPacketPerSecond
  • DatagramGuardOptions.IPv4Windows
  • DatagramGuardOptions.IPv6Windows
  • DatagramGuardOptions.CleanupInterval
  • DatagramGuardOptions.IdleTimeout
  • DatagramGuardOptions.IPv4Capacity
  • DatagramGuardOptions.IPv6Capacity
Architecture Diagram
flowchart LR
    A["UdpListenerBase"] --> B["ConnectionGuardOptions.MaxPacketPerSecond"]
    A --> C["DatagramGuardOptions"]
    B --> D["DatagramGuard"]
    C --> D
    D --> E["TryAccept(IPEndPoint)"]
    E --> F["IPv4/IPv6 source window"]
    F --> G["CAS packet count per second"]

Defaults and Validation

PropertyDefaultValid rangeSource behavior
IPv4Windows65_5361..10_000_000Maximum number of IPv4 source windows tracked at once.
IPv6Windows16_3841..10_000_000Maximum number of IPv6 source windows tracked at once.
IPv4Capacity10241..10_000_000Initial capacity hint for the IPv4 source map.
IPv6Capacity641..10_000_000Initial capacity hint for the IPv6 source map.
CleanupInterval00:01:0000:00:01..01:00:00Delay between stale-window eviction passes.
IdleTimeout00:00:1000:00:01..01:00:00Inactive source-window retention before eviction.
FailOpenWhenFullfalseBooleanWhen true, allows packets through when the tracking map is full, preventing legitimate-user lockout during spoofed-source floods. When false (default), the guard rejects incoming packets when the map is full (fail-closed).

Validate() runs DataAnnotation validation and throws ValidationException when constraints are violated.

Runtime Behavior

DatagramGuard.TryAccept(IPEndPoint) returns false when:

  • the guard has been disposed;
  • the endpoint is null;
  • the IPv4 or IPv6 source-window map has reached its configured limit;
  • the source has already reached MaxPacketPerSecond in the current second.

The guard stores each source in a WindowSlot with a single packed long:

Packed fieldMeaning
high 32 bitscurrent second token from Environment.TickCount64 / 1000
low 32 bitspacket count in that second

Updates use Interlocked.CompareExchange, so the hot path avoids locks while still preserving a precise one-second packet counter per source.

IPv4 and IPv6 Tracking

Address familyKey typeSource note
IPv4uint from IPAddress.AddressChosen to avoid IPAddress key allocations and hashing overhead.
IPv6string from IPAddress.ToString()Used as the less-common fallback path for UDP DDoS scenarios.

Cleanup and Disposal

The constructor starts CleanupLoopAsync immediately. The loop waits for CleanupInterval, then evicts windows whose last-seen second is older than IdleTimeout.

Dispose() marks the guard disposed, cancels and disposes the cleanup token source, and clears both IPv4 and IPv6 maps.

Operational Guidance

  • Increase IPv4Windows / IPv6Windows only when legitimate source cardinality is high enough to require it.

  • Keep IdleTimeout short for public UDP endpoints under spoofed-source pressure.

  • Tune ConnectionGuardOptions.MaxPacketPerSecond separately; it is the per-source packet-rate limit consumed by DatagramGuard.