Skip to content

Hostname creation cleanup, and a minimal variant or PR#5397 to fix bad DNS name#5424

Open
softhack007 wants to merge 16 commits intomainfrom
hostname_cleanup
Open

Hostname creation cleanup, and a minimal variant or PR#5397 to fix bad DNS name#5424
softhack007 wants to merge 16 commits intomainfrom
hostname_cleanup

Conversation

@softhack007
Copy link
Member

@softhack007 softhack007 commented Mar 14, 2026

important: this is not a replacement for #4893. Its a fix that tries to keep the impact on existing functionalities minimal - cleaning up the implicit logic from prepareHostname(), and extracting a generic hostname sanitizer function. Its a potential fix for the 0.15_x branch, too.

@gsieben I hope you don't mind that I took the initiative to evolve your PR. It would be nice if you can test if this PR solves your problem, too.

Summary by CodeRabbit

  • Bug Fixes

    • Improved hostname sanitization for DNS-compliant names, reducing malformed identifiers.
    • Hostname is now applied earlier during network setup and on reconnects (ESP32), improving connectivity and ensuring settings take effect.
    • Added buffer-size safeguards to prevent truncation and ensure proper termination.
  • New Features

    • Hostname retrieval supports an mDNS-preference option with a clear fallback to a safe default.
    • Preserves legacy compatibility while switching to length-aware, buffer-safe hostname handling.

gsieben and others added 4 commits February 24, 2026 20:04
Add hostname configuration for WiFi connection based on cmDNS.
* refactor legacy  prepareHostname() logic, and split hostname sanitization from hostname creation.
* always use the max possible length allowed for a FQDN hostname
* hostname by cmDNS is now included in getWLEDhostname()
* ensure that the name is sanitized
* avoid using a potentially undefined macro
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 14, 2026

Walkthrough

Replaces legacy hostname preparation with a length-aware API getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS=false), introduces an in-place sanitizeHostname helper, updates prepareHostname to accept maxLen as a legacy alias, and updates call sites to populate explicit hostname buffers before setting ETH/WiFi hostnames.

Changes

Cohort / File(s) Summary
API Declaration
wled00/fcn_declare.h
Added void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS=false); replaced old prepareHostname(char* hostname) declaration with prepareHostname(char* hostname, size_t maxLen) (legacy alias).
Hostname Implementation
wled00/util.cpp
Added static sanitizeHostname(char* hostname, size_t maxLen); implemented getWLEDhostname(...) with optional MDNS preference and fallback to wled-MAC; refactored prepareHostname(...) to be buffer-size-aware and to use sanitization/fallback logic.
Network Integration
wled00/network.cpp
Replaced prepareHostname(hostname) usage with explicit buffer init and getWLEDhostname(hostname, sizeof(hostname)); sets Ethernet hostname via ETH.setHostname(hostname) and documents FQDN length considerations.
Connection Setup
wled00/wled.cpp
Generates hostname earlier (uses a fixed-size buffer) in setup and reconnect flows, calls getWLEDhostname(..., true) on ESP32 where appropriate, applies via WiFi.setHostname(hostname), and removes prior prepareHostname-based transformation of serverDescription.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: refactoring hostname creation logic and fixing DNS naming issues referenced in PR#5397.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch hostname_cleanup
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@softhack007 softhack007 added this to the 16.0.0 beta milestone Mar 14, 2026
coderabbitai[bot]

This comment was marked as resolved.

@softhack007

This comment was marked as resolved.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
wled00/util.cpp (1)

157-157: Use named constants for hostname prefix/min-size values.

The repeated 5/6 values encode protocol semantics (prefix length and minimum useful buffer). Pulling them into constants will keep both helpers aligned.

Based on learnings: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with appropriate defined constants when those constants are meaningful in the context of the PR.

Also applies to: 177-183

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wled00/util.cpp` at line 157, Replace the magic numbers used for the hostname
prefix and minimum buffer size with named constants so the logic in util.cpp is
self-documenting and consistent across helpers: introduce a HOSTNAME_PREFIX
(e.g., "wled"), a HOSTNAME_PREFIX_LEN constant (the prefix length), and a
HOSTNAME_MIN_LEN constant (minimum useful buffer, currently 6) and use those
instead of literal 5/6 in the conditional and the strlcpy call in the
hostname-generation function and the related code around the block referenced
(lines 177-183) so both helpers reference the same symbolic values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@wled00/util.cpp`:
- Line 157: The small-buffer guard in prepareHostname is too permissive: change
the checks that read "if (maxLen < 6)" to "if (maxLen <= 6)" (both occurrences
referenced in the diff around prepareHostname) so that buffers of size 6 are
treated as too small and the function returns early via strlcpy(hostname,
"wled", maxLen); to avoid producing the invalid "wled-" label for maxLen == 6.

---

Nitpick comments:
In `@wled00/util.cpp`:
- Line 157: Replace the magic numbers used for the hostname prefix and minimum
buffer size with named constants so the logic in util.cpp is self-documenting
and consistent across helpers: introduce a HOSTNAME_PREFIX (e.g., "wled"), a
HOSTNAME_PREFIX_LEN constant (the prefix length), and a HOSTNAME_MIN_LEN
constant (minimum useful buffer, currently 6) and use those instead of literal
5/6 in the conditional and the strlcpy call in the hostname-generation function
and the related code around the block referenced (lines 177-183) so both helpers
reference the same symbolic values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a347940d-93d6-4ac1-b84e-4e69c43c5667

📥 Commits

Reviewing files that changed from the base of the PR and between c3cc1a0 and a28d970.

📒 Files selected for processing (1)
  • wled00/util.cpp

@softhack007
Copy link
Member Author

softhack007 commented Mar 14, 2026

@coderabbitai please verify if the new implementation of prepareHostname() preserves the previous behaviour.
Expected improvements:

  • same behaviour as before in nominal cases
  • removed 24 chars limit
  • chains of "-" should now always collapse into a single hyphen
  • the sanitizer should always produce a valid hostname, but never overwrite array limits provided in the maxLen parameter.
  • corner cases of too-small hostname buffer (below 6 chars) are not an issue.

@coderabbitai

This comment was marked as duplicate.

coderabbitai[bot]

This comment was marked as outdated.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 14, 2026

Tip

For best results, initiate chat on the files or code changes.

@softhack007: This analysis was already completed above — here is a concise summary of the findings:

# Expected Improvement Result
1 Same behaviour in nominal cases ✅ Verified — prepareHostname still builds wled-<serverDescription> and falls back to wled-<MAC> on empty suffix, identical to the prior logic.
2 24-char limit removed ✅ Callers now allocate char hostname[64] and pass sizeof(hostname); the sanitizer enforces bounds via the caller-supplied maxLen.
3 Hyphen chains collapse to a single - ✅ The guard hostname[pos-1] != '-' in sanitizeHostname() prevents writing consecutive hyphens; leading hyphens are suppressed by pos > 0 and trailing hyphens are stripped post-loop.
4 Sanitizer respects maxLen, never overruns ✅ Loop bound pos < maxLen and the final hostname[min(pos, maxLen-1)] = '\0' guarantee bounds safety; truncation is deterministic and safe.
5 Too-small buffers (< 6 chars) are safe ✅ Both getWLEDhostname() and prepareHostname() early-exit with strlcpy(hostname, "wled", maxLen) when maxLen < 6; strlcpy handles even maxLen=1 correctly.

All expected improvements are correctly implemented. The implementation is sound and handles all listed edge cases deterministically.


🧠 Learnings used
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, verify that file operations (especially file.open()) respect LittleFS filename limitations. Assume default WLED configuration with LittleFS default filename limit of 255 bytes. Do not assume extreme configuration values like WLED_MAX_SEGNAME_LEN = 512 which would not be standard configurations.

Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, file operations (especially file.open()) should be checked to ensure they respect LittleFS filename limitations. The default LittleFS filename limit is 255 bytes (LFS_NAME_MAX). Reviews should assume default WLED configuration defines and not extreme edge-case values (e.g., WLED_MAX_SEGNAME_LEN = 512 would not be standard). File paths should be validated to stay within the 255-byte limit.

Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with appropriate defined constants when those constants are meaningful in the context of the PR. For example, the hardcoded value 32 should be replaced with WLED_MAX_SEGNAME_LEN when it represents a segment name length limit. This improves code maintainability and reduces the risk of inconsistencies.

Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with defined constants when meaningful constants exist in the codebase. For example, suggest replacing hardcoded "32" with WLED_MAX_SEGNAME_LEN if the context relates to segment name length limits.

Learnt from: DedeHai
Repo: wled/WLED PR: 4997
File: wled00/e131.cpp:33-44
Timestamp: 2025-10-10T18:34:06.550Z
Learning: In WLED's DDP packet handling (ws.cpp and e131.cpp), only prevent out-of-bounds memory access rather than enforcing DDP spec compliance. Don't check the 1440-byte spec limit—accept out-of-spec packets assuming correct encoding. The bounds check `maxDataIndex = c + numLeds * ddpChannelsPerLed; if (maxDataIndex > dataLen) reject` is sufficient and already covers the timecode flag case (when c=4) without needing separate validation.

Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.

Learnt from: willmmiles
Repo: wled/WLED PR: 4859
File: usermods/udp_name_sync/udp_name_sync.cpp:62-70
Timestamp: 2025-08-21T00:00:17.196Z
Learning: In WLED codebase, UDP packet processing code must never rely on null termination being present on the wire and must always validate packet size first. The codebase already has some vulnerabilities where malformed data can crash the software, so avoiding introduction of new ones is a priority.

Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-02-11T17:17:04.657Z
Learning: In WLED code reviews, when C-style functions or variables are added or modified, check if they are globally visible (not static). If the function/variable is not declared in any global header file (like fcn_declare.h), suggest either: (1) making it static (visible only within the translation unit) with a forward declaration if needed, or (2) adding a comment to clarify that the function/variable is intentionally global. This helps reduce global namespace pollution and enables better compiler optimizations.

Learnt from: DedeHai
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-01-03T14:38:09.949Z
Learning: In WLED code reviews, check that FastLED trigonometric function aliases are not used. Replace `sin8()` and `cos8()` with `sin8_t()` and `cos8_t()`. Replace `sin16()` and `cos16()` with `sin16_t()` and `cos16_t()`. For float versions, replace `sinf()` and `cosf()` with `sin_approx()` and `cos_approx()`. See wled_math.cpp for the proper WLED implementations.

@softhack007
Copy link
Member Author

@coderabbitai there seem to be some "implicit" constraints on where and when the WiFi (and ETH) "setHostname()" method must be called on esp32 boards, in order to avoid that the default DNS name ESP-XXXXXX gets used.

  • please review the related source code of arduino-esp32 v2.0.18, and summarize the usage constraints that are coming from the arduino-esp32 implementation.
  • please check if this PR now sets the hostname in the correct call sequnces, and suggest improvements if needed.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 14, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

I'll look at the arduino-esp32 v2.0.18 source code for setHostname() constraints and check the PR's call sequences simultaneously.


🏁 Script executed:

#!/bin/bash
echo "=== wled.cpp: hostname / setHostname / initConnection / handleConnection ==="
grep -n "setHostname\|getWLEDhostname\|prepareHostname\|WiFi.mode\|WiFi.disconnect\|WiFi.begin\|WiFi.reconnect\|initConnection\|handleConnection" wled00/wled.cpp | head -80

echo ""
echo "=== wled.cpp: initConnection() function body ==="
# Show the full function around initConnection
awk '/void.*initConnection\(\)/{found=1; count=0} found{print NR": "$0; count++; if(count>80) exit}' wled00/wled.cpp

echo ""
echo "=== wled.cpp: handleConnection() function body ==="
awk '/void.*handleConnection\(\)/{found=1; count=0} found{print NR": "$0; count++; if(count>100) exit}' wled00/wled.cpp

echo ""
echo "=== network.cpp: ETH setHostname / getWLEDhostname call ==="
grep -n -A5 -B5 "setHostname\|getWLEDhostname\|ETH\." wled00/network.cpp | head -60

Length of output: 11773


Now let me search for the arduino-esp32 v2.0.18 source to understand the setHostname() implementation constraints.

@softhack007: Here is a detailed analysis of the arduino-esp32 v2.x setHostname() constraints and an assessment of the PR's call sequences against them.


Part 1 — Constraints from the arduino-esp32 v2.x implementation

The fundamental rule

The official arduino-esp32 documentation states that setHostname() must be called BEFORE Wi-Fi is started with WiFi.begin(), WiFi.softAP(), WiFi.mode(), or WiFi.run(). To change the hostname after Wi-Fi has already been started, you must first reset Wi-Fi with WiFi.mode(WIFI_MODE_NULL), then call setHostname(), and then restart WiFi from scratch.

Why it silently fails in v2.x — the "stored but not applied" trap

setHostname() in arduino-esp32 v2.x just sets a string in memory. It is not applied to the network interface until WiFiGenericClass::mode() is called, which happens when WiFi.config(), WiFi.begin(), WiFi.enableSTA(), etc., are called.

The hostname is only physically applied at one location in WiFiGeneric.cpp during the mode transition to WIFI_MODE_STA. If the mode was already WIFI_MODE_STA, calling WiFi.mode(WIFI_MODE_STA) does nothing, because when the current mode equals the new mode, no changes are applied.

To work around this, the mode must actually change — e.g., transition through WIFI_MODE_APSTA before going back to WIFI_MODE_STA.

Summary of constraints

Constraint Implication
setHostname() before WiFi.mode() Stores the hostname value
WiFi.mode(WIFI_STA) causes the hostname to be applied Only if mode actually changes
If mode already STA, setHostname() + WiFi.mode(WIFI_STA) = no-op Hostname silently reverts to default
setHostname() after WiFi.begin() Too late — has no effect

Part 2 — Assessment of the PR's call sequences

Issue 1 🔴 — WiFi.setHostname() at line 777 is placed AFTER WiFi.begin()

Looking at the initConnection() sequence in the PR:

Line 688: WiFi.disconnect(true)
Line 712: WiFi.mode(WIFI_STA)
Line 723: getWLEDhostname(hostname, sizeof(hostname))
Line 744/771: WiFi.begin(...)         ← connection started here
Line 777: WiFi.setHostname(hostname)  ← TOO LATE, after begin()

This placement violates the fundamental constraint. The call at line 777 has no effect on the current connection's DHCP hostname.

Issue 2 🟡 — handleConnection() lines 869–873 run every loop iteration

The block:

`#ifdef` ARDUINO_ARCH_ESP32
  char hostname[64] = {'\0'};
  getWLEDhostname(hostname, sizeof(hostname), true);
  WiFi.setHostname(hostname);
`#endif`

runs on every handleConnection() call, not only on reconnect/init paths. The call stores the hostname in memory (and is before initConnection()), but per constraint above: if WiFi is already in WIFI_STA mode, the subsequent WiFi.mode(WIFI_STA) in initConnection() line 712 is a no-op, so the stored hostname won't be applied to the netif on reconnects.

Issue 3 🔴 — Mode-already-STA on reconnects

On the reconnect code path (e.g., line 921: initConnection() called after Disconnected!), the device is likely already in WIFI_STA mode. In that case:

  • WiFi.setHostname() at handleConnection line 872 stores the value ✅
  • WiFi.disconnect(true) at initConnection line 688 — does not reset mode to WIFI_MODE_NULL
  • WiFi.mode(WIFI_STA) at initConnection line 712 — no-op because mode already equals WIFI_STA
  • Result: hostname is stored in memory but never applied → DHCP will use the default ESP name 🔴

Suggested fix

The correct sequence inside initConnection() should be:

WiFi.disconnect(true);
delay(5);

// Compute hostname before mode/begin calls
char hostname[64] = {'\0'};
getWLEDhostname(hostname, sizeof(hostname));

// Reset mode to NULL to force a full STA mode transition,
// so that WiFi.mode(WIFI_STA) below actually applies the hostname.
// This is required on reconnects when mode is already WIFI_STA.
`#ifdef` ARDUINO_ARCH_ESP32
WiFi.mode(WIFI_MODE_NULL); // force mode transition
`#endif`
WiFi.setHostname(hostname); // stored; will be applied by the upcoming mode() call

WiFi.mode(WIFI_STA);        // hostname applied HERE during transition
// ... WiFi.config() ...
// ... WiFi.begin() ...     // hostname already set — this is fine

And remove the setHostname() block from handleConnection() (lines 869–873) entirely — it is both redundant and unreliable there.

The ETH hostname in network.cpp (lines 417–419) looks correct — it is set in the ARDUINO_EVENT_ETH_GOT_IP event handler after ETH.begin(), which is the appropriate event-driven approach for Ethernet.


✏️ Learnings added
Learnt from: softhack007
URL: https://github.com/wled/WLED/pull/5424

Timestamp: 2026-03-14T21:24:02.836Z
Learning: In WLED (arduino-esp32 v2.x), WiFi.setHostname() must be called BEFORE WiFi.begin() and, crucially, BEFORE WiFi.mode(WIFI_STA). The hostname stored by setHostname() is only physically applied to the netif during a WiFi mode *transition* to WIFI_STA inside WiFiGenericClass::mode(). If the device is already in WIFI_STA mode (e.g., on a reconnect), calling WiFi.mode(WIFI_STA) is a no-op (mode == current mode), so the hostname will never be applied and the default ESP name will be used in DHCP. The correct pattern is: WiFi.disconnect(true) → WiFi.mode(WIFI_MODE_NULL) → WiFi.setHostname(hostname) → WiFi.mode(WIFI_STA) → WiFi.begin(). The WiFi.mode(WIFI_MODE_NULL) step is essential on reconnects to force a genuine mode transition.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: softhack007
Repo: wled/WLED PR: 4893
File: wled00/set.cpp:95-95
Timestamp: 2026-03-14T20:56:46.543Z
Learning: In WLED (arduino-esp32), WiFi.setHostname() must be called AFTER WiFi.mode() but BEFORE WiFi.begin() to prevent the default `esp-XXXXXX` hostname from being used in DHCP requests. Calling it before WiFi.mode() (e.g. in deserializeConfig() at boot) has no effect because the STA interface does not yet exist. The correct place is inside initConnection() in wled00/wled.cpp, after WiFi.disconnect(true) and before WiFi.begin(). On ESP8266, WiFi.hostname() is more forgiving about ordering but should still be placed in initConnection() for consistency.

Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, verify that file operations (especially file.open()) respect LittleFS filename limitations. Assume default WLED configuration with LittleFS default filename limit of 255 bytes. Do not assume extreme configuration values like WLED_MAX_SEGNAME_LEN = 512 which would not be standard configurations.

Learnt from: blazoncek
Repo: wled/WLED PR: 4482
File: wled00/udp.cpp:147-149
Timestamp: 2025-02-19T12:43:34.199Z
Learning: ESP8266 and ESP32 platforms have different maximum segment name lengths in WLED, which can cause truncation when syncing segment names between devices. This platform difference affects the user experience when using the segment name sync feature.

Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with appropriate defined constants when those constants are meaningful in the context of the PR. For example, the hardcoded value 32 should be replaced with WLED_MAX_SEGNAME_LEN when it represents a segment name length limit. This improves code maintainability and reduces the risk of inconsistencies.

Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, file operations (especially file.open()) should be checked to ensure they respect LittleFS filename limitations. The default LittleFS filename limit is 255 bytes (LFS_NAME_MAX). Reviews should assume default WLED configuration defines and not extreme edge-case values (e.g., WLED_MAX_SEGNAME_LEN = 512 would not be standard). File paths should be validated to stay within the 255-byte limit.

Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with defined constants when meaningful constants exist in the codebase. For example, suggest replacing hardcoded "32" with WLED_MAX_SEGNAME_LEN if the context relates to segment name length limits.

Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/wled.cpp:385-387
Timestamp: 2026-02-08T19:33:02.648Z
Learning: In WLED ESP32 code, when checking whether USB CDC serial initialization delay is needed, rely on the ARDUINO_USB_CDC_ON_BOOT flag rather than explicit CONFIG_IDF_TARGET checks, because not all development boards for chips with native USB capability (ESP32-C3/C5/C6/S2/S3/H2/P4) actually use the native USB—many have external UART bridge chips instead. The ARDUINO_USB_CDC_ON_BOOT flag correctly indicates the board's actual USB configuration.

Learnt from: ksedgwic
Repo: wled/WLED PR: 4883
File: usermods/usermod_v2_skystrip/rest_json_client.cpp:40-46
Timestamp: 2025-08-29T00:22:34.115Z
Learning: For ESP32/ESP8266 HTTP requests in WLED, set timeouts on the underlying WiFiClient (using client.setTimeout()) before calling http_.begin(), rather than using HTTPClient::setTimeout(). This pattern is used successfully in the Klipper usermod to prevent connection hangs.

Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-02-11T17:17:04.657Z
Learning: In WLED code reviews, when C-style functions or variables are added or modified, check if they are globally visible (not static). If the function/variable is not declared in any global header file (like fcn_declare.h), suggest either: (1) making it static (visible only within the translation unit) with a forward declaration if needed, or (2) adding a comment to clarify that the function/variable is intentionally global. This helps reduce global namespace pollution and enables better compiler optimizations.

Learnt from: blazoncek
Repo: wled/WLED PR: 4482
File: wled00/udp.cpp:147-149
Timestamp: 2025-02-19T12:43:34.200Z
Learning: In WLED, maximum segment name length varies by platform:
- ESP8266: 32 characters (WLED_MAX_SEGNAME_LEN = 32)
- ESP32: 64 characters (WLED_MAX_SEGNAME_LEN = 64)
This platform difference can cause truncation when syncing longer names from ESP32 to ESP8266. Additionally, the WLED UI has limitations regarding modified maximum segment name lengths.

Learnt from: ksedgwic
Repo: wled/WLED PR: 4883
File: usermods/usermod_v2_skystrip/rest_json_client.cpp:40-46
Timestamp: 2025-08-29T00:22:34.115Z
Learning: The HTTPClient::setTimeout() method in ESP32/ESP8266 may not prevent hanging in all scenarios, particularly during connection establishment or DNS resolution phases.

@softhack007
Copy link
Member Author

I'm changing the PR back to draft, and try the suggestion by the rabbit #5424 (comment) .

@softhack007 softhack007 marked this pull request as draft March 14, 2026 21:30
@netmindz
Copy link
Member

Thanks for picking this up @softhack007

* follow the rabbit's suggestion to set the hostname before WiFi.mode(STA)
* WiFi.mode(WIFI_MODE_NULL) after WiFi.disconnect(), to ensure that all changes are applied on wifi re-start
@softhack007
Copy link
Member Author

works for me :-)

@gsieben please test if this PR solves your problem with dnsmasq

@softhack007 softhack007 marked this pull request as ready for review March 14, 2026 22:54
coderabbitai[bot]

This comment was marked as resolved.

by checking if the serverDescription also start with "wled".
coderabbitai[bot]

This comment was marked as resolved.

@softhack007 softhack007 added enhancement Awaiting testing optimization re-working an existing feature to be faster, or use less memory labels Mar 15, 2026
Copy link
Collaborator

@DedeHai DedeHai left a comment

Choose a reason for hiding this comment

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

I still do not use any dns so can't test but the code looks solid, I guess the rabbit checked for off-by-1 errors? those are hard to spot, I checked and found none.

saves 5 bytes of RAM on 8266
This was referenced Mar 15, 2026
coderabbitai[bot]

This comment was marked as resolved.

Names like WLED0 or WLEDa survive sanitization, but strlen(hostname) == 5 still sends them down the wled-<MAC> fallback path.
@softhack007 softhack007 linked an issue Mar 15, 2026 that may be closed by this pull request
1 task
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
wled00/util.cpp (1)

162-162: Consider extracting duplicate fallback hostname generation.

The wled-MAC fallback pattern appears identically at lines 162 and 187. A small helper or inline lambda could reduce duplication.

💡 Optional: Extract to static helper
// Near top of hostname section
static void setWledMacFallback(char* hostname, size_t maxLen) {
  snprintf_P(hostname, maxLen, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6);
  hostname[maxLen - 1] = '\0';
}

Then replace both occurrences with setWledMacFallback(hostname, maxLen);

Also applies to: 187-187

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wled00/util.cpp` at line 162, Duplicate fallback hostname generation using
snprintf_P("wled-%*s", 6, escapedMac.c_str() + 6) occurs twice; extract that
logic into a small static helper (or inline lambda) such as
setWledMacFallback(char* hostname, size_t maxLen) and call it from both places
instead of repeating the snprintf_P call, making sure the helper null-terminates
hostname (hostname[maxLen-1] = '\0') and uses the same escapedMac reference so
behavior is unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@wled00/util.cpp`:
- Line 162: Duplicate fallback hostname generation using snprintf_P("wled-%*s",
6, escapedMac.c_str() + 6) occurs twice; extract that logic into a small static
helper (or inline lambda) such as setWledMacFallback(char* hostname, size_t
maxLen) and call it from both places instead of repeating the snprintf_P call,
making sure the helper null-terminates hostname (hostname[maxLen-1] = '\0') and
uses the same escapedMac reference so behavior is unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 33c8dd4b-61e2-41d0-b5eb-b90f1c6d2922

📥 Commits

Reviewing files that changed from the base of the PR and between 0bc87a3 and 10dfb1f.

📒 Files selected for processing (1)
  • wled00/util.cpp

@softhack007 softhack007 removed the request for review from Aircoookie March 15, 2026 12:07
@softhack007
Copy link
Member Author

softhack007 commented Mar 15, 2026

question: ethernet DNS is still using the legacy hostname, while wifi now prefers the mDNS name. Should we keep that, or align the ethernet path to also prefer the mDNS name?

156-168: The hostname preference split between WiFi and Ethernet is confirmed and intentional.

getWLEDhostname() is called with preferMDNS=true from both WiFi paths (wled00/wled.cpp:512 and :699) and preferMDNS=false (default) from the Ethernet path (wled00/network.cpp:418). This allows a custom mDNS name to override the WiFi DHCP hostname while keeping Ethernet on the legacy serverDescription path. The design is already documented in code comments (e.g., wled00/wled.cpp:510).

@softhack007
Copy link
Member Author

softhack007 commented Mar 15, 2026

Testing: I found out that my wifi router (German telecom "speedport4") allows client DNS name registration:-) so I can test that aspect, and it works. It's the first time that my WLED devices appear with their proper name in my router's network overview 👍

avoid "x" = not set (default MDNS)
coderabbitai[bot]

This comment was marked as resolved.

@softhack007
Copy link
Member Author

softhack007 commented Mar 15, 2026

ToDO for a future PR: the mDNS startup code still uses the not-sanitized host name, which can include unicode smileys, invalid characters etc --> will not fix in this PR, to preserve legacy behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Awaiting testing enhancement optimization re-working an existing feature to be faster, or use less memory

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ESP32-S3 and C3 hostname

4 participants