Skip to content

TrafficManagement: exempt traceroute from per-source rate limiting#10228

Closed
nightjoker7 wants to merge 1 commit into
meshtastic:developfrom
nightjoker7:fix/traffic-management-traceroute-exempt
Closed

TrafficManagement: exempt traceroute from per-source rate limiting#10228
nightjoker7 wants to merge 1 commit into
meshtastic:developfrom
nightjoker7:fix/traffic-management-traceroute-exempt

Conversation

@nightjoker7

Copy link
Copy Markdown
Contributor

Summary

Add TRACEROUTE_APP to the list of portnums exempt from TrafficManagementModule's rate limiter, alongside the existing ROUTING_APP and ADMIN_APP exemptions.

Problem

In TrafficManagementModule::handleReceived():

if (cfg.rate_limit_enabled && cfg.rate_limit_window_secs > 0 && cfg.rate_limit_max_packets > 0) {
    if (mp.decoded.portnum != meshtastic_PortNum_ROUTING_APP && mp.decoded.portnum != meshtastic_PortNum_ADMIN_APP) {
        if (isRateLimited(mp.from, nowMs)) {
            logAction("drop", &mp, "rate-limit");
            incrementStat(&stats.rate_limit_drops);
            ignoreRequest = true;        // Suppress NAK
            return ProcessMessage::STOP;
        }
    }
}

Traceroute packets (TRACEROUTE_APP) flow on the same node→node DM channels as user traffic and are therefore subject to the same per-source rate limit. When a router node has rate_limit_enabled = true (the intended behavior for congested deployments), traceroute responses get silently dropped whenever the originating node happens to be slightly chatty, and the initiator sees incomplete or missing paths.

The failure mode is particularly bad because:

  • It is silent — the ignoreRequest = true; return STOP; path suppresses the NAK, so the initiator cannot distinguish "no route" from "route was discovered but the reply was rate-limited on an intermediate hop."
  • Traceroute is inherently low-volume (one request + one response per invocation) and operator-initiated. Rate-limiting it does not protect the mesh from any real abuse vector, but it does make diagnosing other mesh problems much harder.
  • Fleet operators typically run traceroute because something is wrong, which is exactly when rate limits are most likely already tripping on chatty nodes.

Fix

Add TRACEROUTE_APP to the exempt list and refactor the check into a named boolean for readability:

if (cfg.rate_limit_enabled && cfg.rate_limit_window_secs > 0 && cfg.rate_limit_max_packets > 0) {
    const auto pn = mp.decoded.portnum;
    const bool rateLimitExempt = (pn == meshtastic_PortNum_ROUTING_APP ||
                                  pn == meshtastic_PortNum_ADMIN_APP ||
                                  pn == meshtastic_PortNum_TRACEROUTE_APP);
    if (!rateLimitExempt) {
        if (isRateLimited(mp.from, nowMs)) {
            ...
        }
    }
}

Also update the adjacent comment.

Testing

  • Patched firmware running on router nodes with rate_limit_enabled = true, rate_limit_window_secs = 60, rate_limit_max_packets = 8. Traceroute from neighboring nodes now reliably returns a complete path even when the source node is simultaneously sending position/telemetry.
  • Builds cleanly against develop.

Risk

Minimal. Moves one portnum from "subject to rate limit" to "exempt from rate limit." No path change for any other traffic class. Traceroute is already rate-limited elsewhere in the stack by its intrinsic once-per-operator-command cadence.

Add TRACEROUTE_APP to the list of portnums that bypass the rate
limiter in TrafficManagementModule::handleReceived(), alongside the
existing ROUTING_APP and ADMIN_APP exemptions.

Traceroute responses travel as ordinary DM-class packets from the
source being probed, so when rate_limit_enabled is true on a router
and the source has just sent any other traffic (position, telemetry,
NodeInfo broadcast), the traceroute reply is silently dropped via
ignoreRequest=true/STOP. The initiator cannot distinguish this from
a genuine routing failure, which is exactly the case traceroute is
meant to diagnose.

Refactor the portnum check into a named rateLimitExempt boolean for
clarity and update the adjacent comment to reflect the new membership.
@github-actions github-actions Bot added the bugfix Pull request that fixes bugs label Apr 21, 2026
@thebentern thebentern requested a review from Copilot April 21, 2026 21:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates TrafficManagementModule so traceroute traffic isn’t dropped by the per-source rate limiter, improving reliability of operator-initiated diagnostics on congested meshes.

Changes:

  • Exempts TRACEROUTE_APP from the per-source rate limiter (joining existing ROUTING_APP and ADMIN_APP exemptions).
  • Refactors the exemption logic into a named boolean for readability.
  • Updates the adjacent comment to reflect the expanded exemption list.

@github-actions github-actions Bot added the Stale Issues that will be closed if not triaged. label Jun 6, 2026
@github-actions github-actions Bot closed this Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Pull request that fixes bugs Stale Issues that will be closed if not triaged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants