Skip to content

DDP input: reject packets with unsupported data type or non-display destination#5390

Merged
DedeHai merged 9 commits intomainfrom
copilot/fix-leds-for-invalid-ddp
Mar 29, 2026
Merged

DDP input: reject packets with unsupported data type or non-display destination#5390
DedeHai merged 9 commits intomainfrom
copilot/fix-leds-for-invalid-ddp

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 21, 2026

  • Understand the DDP packet handling code in e131.cpp and udp.cpp
  • Move all DDP defines to ESPAsyncE131.h (including DDP_ID_*, DDP_FLAGS1_*, DDP_HEADER_LEN, DDP_SYNCPACKET_LEN, DDP_CHANNELS_PER_PACKET)
  • Remove all DDP #defines from udp.cpp
  • Add destination validation in handleDDPPacket: reject DDP_ID_STATUS and DDP_ID_CONFIG packets
  • Add data type validation in handleDDPPacket: reject packets not of type DDP_TYPE_RGB24 or DDP_TYPE_RGBW32
  • Remove accidentally committed _codeql_detected_source_root artifact file and add to .gitignore
  • All 16 tests pass (npm test)
  • Hardware build succeeds (pio run -e esp32dev)
Original prompt

This section details on the original issue you should resolve

<issue_title>when certain invalid DDP messages are received, all LEDs switched off</issue_title>
<issue_description>### What happened?

Not very critical, but I noticed that WLED is sensitive for invalid/corrupted DDP packets.

To Reproduce Bug

e.g.:

21:03:53.226765 IP (tos 0x0, ttl 255, id 293, offset 0, flags [none], proto UDP (17), length 124)
    10.208.2.7.4048 > 10.208.3.255.4048: UDP, length 96
    0x0000:  4500 007c 0125 0000 ff11 9ea6 0ad0 0207  E..|.%..........
    0x0010:  0ad0 03ff 0fd0 0fd0 0068 1133 4108 0bfb  .........h.3A...
    0x0020:  0000 0000 0056 7b22 7374 6174 7573 223a  .....V{"status":
    0x0030:  207b 2022 6d61 6e22 3a20 2277 7777 2e6b  .{."man":."www.k
    0x0040:  6f6d 7075 7469 6c6f 2e6e 6c22 2c20 226d  omputilo.nl",."m
    0x0050:  6f64 223a 2022 4c69 6768 7462 6f78 2044  od":."Lightbox.D
    0x0060:  4450 2073 6572 7665 7222 2c20 2276 6572  DP.server",."ver
    0x0070:  223a 2022 302e 3122 207d 207d            ":."0.1".}.}

test.pcap.zip

Expected Behavior

Ignore invalid packets

Install Method

Binary from WLED.me

What version of WLED?

any version

Which microcontroller/board are you seeing the problem on?

ESP8266

Relevant log/trace output

I tried running a `WLED_DEBUG` version but that doesn't give extra output in the console.

Anything else?

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct</issue_description>

<agent_instructions>DDP incoming packets should be checked for:

packet format (RGB or RGBW) -> reject anything else
destination: reject DDP_ID_STATUS and DDP_ID_CONFIG as not implemented, these two defines already exist in code.
implement only these improvements, make no other changes to code.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@DedeHai @coderabbitai please elaborate if this is a bug or a feature @DedeHai @coderabbitai there is a binary code example given. please trace through the code what happens if such a data packet is received through UDP, state function calls and meaning of the data bytes and how it arrives at turning off LEDs @softhack007 > **Wrong Destination**: Packet has `destination = 0xFB` (STATUS), not `0x01` (DISPLAY) > > * **No validation** - code doesn't check destination field > * Status packets should contain configuration/metadata, not LED data

@coderabbitai: I'm not sure about the DDP specification:

  • is the "destination" field part of each DDP packet?
  • Does our WLED "Network output" DDP format properly set data type and destination?
@netmindz > [@coderabbitai](https://github.com/coderabbitai) here's my thought: >
  1. there is nothing in the header structure that defines it a DDP header (you can't attach any bit pattern to a meaningful data as WLED ignores (intentionally) most of the data, i.e. you can't use DDP_ID_DISPLAY to validate if the packet is destined for display as WLED doesn't support distinguishing displays)

I do not agree with this logic. DDP had a packet format that includes a header. If that header has a field which is the destination and if that destination had certain values that indicate this is not a display, but for things like status, we would never want to try and interpret status data as LED display output. So we need to respect that destination, even though WLED only supports a single display (we don't try and map display to segment)

Please correct your learning @coderabbitai</comment_new>
<comment_new>@DedeHai
so to sum up:
DDP incoming packets should be checked for:

  • packet format (RGB or RGBW) -> reject anything else
  • destination: reject DDP_ID_STATUS and DDP_ID_CONFIG as not implemented, these two defines already exist in code.</comment_new>
    <comment_new>@softhack007

so to sum up: DDP incoming packets should be checked for:

  • packet format (RGB or RGBW) -> reject anything else
  • destination: reject DDP_ID_STATUS and DDP_ID_CONFIG as not implemented, these two defines already exist in code.

Yep, I agree, too.
If the acceptable format and destination fields are just a few values, there is no performance problem with checking these once per packet. Especially if we can filter out any non-LEDs junk with a few lines of code.</comment_new>


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Summary by CodeRabbit

  • New Features

    • Enhanced DDP (Digital Display Protocol) support with improved packet validation and filtering for better device compatibility.
  • Bug Fixes

    • Updated DDP protocol flag handling to correctly identify and process timecode and push signals across all packet types.
  • Refactor

    • Consolidated DDP protocol constants for cleaner codebase organization.

… data type

Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix issue of all LEDs switching off on invalid DDP messages DDP input: reject packets with unsupported data type or non-display destination Feb 21, 2026
Copilot AI requested a review from DedeHai February 21, 2026 04:45
@DedeHai
Copy link
Copy Markdown
Collaborator

DedeHai commented Feb 21, 2026

@copilot move all DDP defines into ESPAsyncE131.h so all of them are in one place, even the ones still in udp.cpp

Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 21, 2026

@copilot move all DDP defines into ESPAsyncE131.h so all of them are in one place, even the ones still in udp.cpp

Done in b1757c3. All remaining DDP defines (DDP_HEADER_LEN, DDP_SYNCPACKET_LEN, DDP_FLAGS1_VER*, DDP_FLAGS1_PUSH/QUERY/REPLY/STORAGE/TIME, DDP_CHANNELS_PER_PACKET) have been moved from udp.cpp to ESPAsyncE131.h, so all DDP defines are now in one place.

Comment thread _codeql_detected_source_root Outdated
…nd add to .gitignore

Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com>
Copilot AI requested a review from DedeHai February 21, 2026 09:18
@DedeHai DedeHai marked this pull request as ready for review February 21, 2026 09:30
Comment thread wled00/e131.cpp
int lastPushSeq = e131LastSequenceNumber[0];

// reject unsupported data types (only RGB and RGBW are supported)
if (p->dataType != DDP_TYPE_RGB24 && p->dataType != DDP_TYPE_RGBW32) return;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@DedeHai this is the core change, right?
Maybe its worth to make a backport to 0.15.4 with just this sanity check

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

that plus the next line, the rest was just moving the defines (and renaming)

Comment thread wled00/e131.cpp
// reject status and config packets (not implemented)
if (p->destination == DDP_ID_STATUS || p->destination == DDP_ID_CONFIG) return;

//reject late packets belonging to previous frame (assuming 4 packets max. before push)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@DedeHai maybe also check if this assumption "max 4 packets per push" still makes sense.

Not sure how many LEDs fit into one packet - but considering maybe 4 packets * 512 LEDs as the absolute max content per frame doesn't sound right to me - we can support more than 2048 LEDs for example with HUB75.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

needs investigation. I have pushed 64x64 over websocket no problem - not sure how big one WS packet is but code comments suggest its about 500 LEDs worth.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I've created an issue ticket so we can come back to this question later.

Copy link
Copy Markdown
Member

@softhack007 softhack007 left a comment

Choose a reason for hiding this comment

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

Please check if addition legacy "datatypes" and "destination" should be allowed (see my comment below).

Comment thread wled00/e131.cpp
int lastPushSeq = e131LastSequenceNumber[0];

// reject unsupported data types (only RGB and RGBW are supported)
if (p->dataType != DDP_TYPE_RGB24 && p->dataType != DDP_TYPE_RGBW32) return;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If I read the DDP specs correctly, datatype can also be 0 = not used / undefined.
Similar for destination ID 255= all devices. I think we should allow these special values, too.

http://www.3waylabs.com/ddp/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

if datatype is undefined we do not know if data is RGB or RGBW, could assume RGB but if its not I do not know if we get OOB access so better be explicit.

all destinations are allowed with only the two masked exceptions, so 255 will pass.

@DedeHai
Copy link
Copy Markdown
Collaborator

DedeHai commented Mar 29, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 29, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 29, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e6db9086-4d33-4ae8-b55e-1447d8461f1a

📥 Commits

Reviewing files that changed from the base of the PR and between b7d2c3c and d65d194.

📒 Files selected for processing (5)
  • wled00/data/common.js
  • wled00/e131.cpp
  • wled00/src/dependencies/e131/ESPAsyncE131.h
  • wled00/udp.cpp
  • wled00/ws.cpp

Walkthrough

Consolidated DDP protocol constants into a shared header definition, updated flag checking logic across packet handlers, added validation to reject invalid DDP packet types and destinations, and corrected the DDP format identifier byte from 0x01 to 0x0B to represent RGB 8bit-per-channel encoding.

Changes

Cohort / File(s) Summary
DDP Protocol Constants
wled00/src/dependencies/e131/ESPAsyncE131.h
Centralized DDP protocol definitions including header length, sync packet length, flag bitmasks (push, query, reply, storage, time), version mask, channel limits, and message IDs. Replaced prior minimal flag constants with granular DDP_FLAGS_* definitions.
DDP Packet Validation & Handler
wled00/e131.cpp
Added early-return validation to ignore non-RGB24/RGBW32 packets and packets destined for DDP_ID_STATUS or DDP_ID_CONFIG. Updated timecode and push flag detection to reference new DDP_FLAGS_TIME and DDP_FLAGS_PUSH constants instead of older flag names.
DDP Packet Parsing
wled00/ws.cpp
Updated timecode field offset logic to use DDP_FLAGS_TIME bitmask constant instead of the previous DDP_TIMECODE_FLAG identifier.
DDP Realtime Control
wled00/udp.cpp
Removed local DDP protocol constant definitions (now sourced from shared header). Updated flag references to use centralized DDP_FLAGS_VER1 and DDP_FLAGS_PUSH constants for last-packet push behavior.
DDP Packet Format
wled00/data/common.js
Changed DDP protocol mode byte in outgoing packet header from 0x01 (RGB) to 0x0B (RGB, 8bit per channel).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • WLED#4997: Introduced DDP-over-WebSocket support; this PR refines the DDP protocol constants and validation logic for that feature.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: adding rejection logic for DDP packets with unsupported data types or non-display destinations.
Linked Issues check ✅ Passed The PR implements all coding requirements from issue #5380: validates DDP data type (accept only RGB24/RGBW32), validates destination (reject STATUS/CONFIG), and centralizes DDP constants.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue objectives. The removal of _codeql_detected_source_root artifact and .gitignore updates are housekeeping aligned with the fix.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch copilot/fix-leds-for-invalid-ddp

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@netmindz netmindz modified the milestones: 16.0.0 beta, 16.1 Mar 29, 2026
@DedeHai DedeHai merged commit 472fca7 into main Mar 29, 2026
29 checks passed
@softhack007 softhack007 deleted the copilot/fix-leds-for-invalid-ddp branch March 29, 2026 16:22
softhack007 pushed a commit to MoonModules/WLED-MM that referenced this pull request Mar 29, 2026
…estination (wled#5390)

* Fix: reject invalid DDP packets with wrong destination or unsupported data type

Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com>
@netmindz netmindz modified the milestones: 16.1, 16.0.0 beta Mar 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

when certain invalid DDP messages are received, all LEDs switched off

4 participants