Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion wled00/fcn_declare.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@ size_t printSetFormValue(Print& settingsScript, const char* key, int val);
size_t printSetFormValue(Print& settingsScript, const char* key, const char* val);
size_t printSetFormIndex(Print& settingsScript, const char* key, int index);
size_t printSetClassElementHTML(Print& settingsScript, const char* key, const int index, const char* val);
void prepareHostname(char* hostname);
void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS=false); // maxLen = hostname buffer size including \0; if preferMDNSname=true, use mdns name (sanitized)
void prepareHostname(char* hostname, size_t maxLen); // legacy function - not recommended for new code
[[gnu::pure]] bool isAsterisksOnly(const char* str, byte maxLen);
bool requestJSONBufferLock(uint8_t moduleID=JSON_LOCK_UNKNOWN);
void releaseJSONBufferLock();
Expand Down
4 changes: 2 additions & 2 deletions wled00/network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,8 @@ void WiFiEvent(WiFiEvent_t event)
WiFi.disconnect(true); // disable WiFi entirely
}
// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
char hostname[64];
prepareHostname(hostname);
char hostname[64] = {'\0'}; // any "hostname" within a Fully Qualified Domain Name (FQDN) must not exceed 63 characters
getWLEDhostname(hostname, sizeof(hostname));
ETH.setHostname(hostname);
showWelcomePage = false;
break;
Expand Down
67 changes: 49 additions & 18 deletions wled00/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,30 +127,61 @@ size_t printSetClassElementHTML(Print& settingsScript, const char* key, const in
}



void prepareHostname(char* hostname)
{
sprintf_P(hostname, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6);
const char *pC = serverDescription;
unsigned pos = 5; // keep "wled-"
while (*pC && pos < 24) { // while !null and not over length
if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname
hostname[pos] = *pC;
pos++;
} else if (*pC == ' ' || *pC == '_' || *pC == '-' || *pC == '+' || *pC == '!' || *pC == '?' || *pC == '*') {
hostname[pos] = '-';
pos++;
// in-place hostname sanitizer, extracted from prepareHostname()
static void sanitizeHostname(char* hostname, size_t maxLen) {
if (hostname == nullptr || maxLen < 1 || strlen(hostname) < 1) return;

char *pC = hostname;
unsigned pos = 0;
while (*pC && pos < maxLen) {
char c = *pC;
if (isalnum((unsigned char)c)) {
hostname[pos++] = c;
} else if (c == ' ' || c == '_' || c == '-' || c == '+' || c == '!' || c == '?' || c == '*') { // convert certain characters to hyphens
if (pos > 0 && hostname[pos -1] != '-') hostname[pos++] = '-'; // keep single non-leading hyphens only
}
// else do nothing - no leading hyphens and do not include hyphens for all other characters.
// else: drop any character not valid in a DNS hostname label
pC++;
}
//last character must not be hyphen
if (pos > 5) {
while (pos > 4 && hostname[pos -1] == '-') pos--;
hostname[pos] = '\0'; // terminate string (leave at least "wled")
// Hostname must not end with a hyphen.
while (pos > 0 && hostname[pos -1] == '-') pos--;
hostname[min(pos, maxLen-1)] = '\0'; // terminate string
}

/*
* Stores sanitized hostname into buffer provided by caller
* maxLen = hostname buffer size including \0
* preferMDNSname -> use mDNS name if set, otherwise fall back to WLED "server description" name (legacy behaviour)
*/
void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS) {
if (maxLen < 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen)
if (preferMDNS && strlen(cmDNS) > 0) {
strlcpy(hostname, cmDNS, maxLen);
sanitizeHostname(hostname, maxLen); // sanitize cmDNS name
if (strlen(hostname) < 1) { // if result is empty -> fall back to wled-MAC
snprintf_P(hostname, maxLen, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6);
hostname[maxLen -1] = '\0'; // ensure string termination
}
} else {
prepareHostname(hostname, maxLen); // use legacy hostname based on "server description" - already sanitized
}
}

/* Legacy hostname construction:
* Start with "wled-" + serverDescription as suffix.
* Sanitize only the suffix (always keep wled- prefix intact).
* If the sanitized suffix ends up empty, fall back to wled-<mac>.
*/
void prepareHostname(char* hostname, size_t maxLen)
{
if (maxLen < 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen)
snprintf_P(hostname, maxLen, PSTR("wled-%s"), serverDescription);
hostname[maxLen -1] = '\0'; // ensure string termination
sanitizeHostname(hostname+5, maxLen-5); // sanitize name, keep "wled-" intact
if (strlen(hostname) <= 5)
snprintf_P(hostname, maxLen, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6); // fallback to wled-MAC
}


bool isAsterisksOnly(const char* str, byte maxLen)
{
Expand Down
11 changes: 9 additions & 2 deletions wled00/wled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -719,8 +719,8 @@ void WLED::initConnection()
DEBUG_PRINTF_P(PSTR("Connecting to %s...\n"), multiWiFi[selectedWiFi].clientSSID);

// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
char hostname[25];
prepareHostname(hostname);
char hostname[64] = {'\0'}; // any "hostname" within a Fully Qualified Domain Name (FQDN) must not exceed 63 characters
getWLEDhostname(hostname, sizeof(hostname));

#ifdef WLED_ENABLE_WPA_ENTERPRISE
if (multiWiFi[selectedWiFi].encryptionType == WIFI_ENCRYPTION_TYPE_PSK) {
Expand Down Expand Up @@ -865,6 +865,13 @@ void WLED::handleConnection()
#endif
const bool wifiConfigured = WLED_WIFI_CONFIGURED;

// The DNS name of the ESP must be set before the first connection to the DHCP server; otherwise, the default ESP name (such as "esp32s3-267D0C") will be used.
#ifdef ARDUINO_ARCH_ESP32
char hostname[64] = {'\0'}; // any "hostname" within a Fully Qualified Domain Name (FQDN) must not exceed 63 characters
getWLEDhostname(hostname, sizeof(hostname), true); // create DNS name based on mDNS name if set, or fall back to standard WLED server name
WiFi.setHostname(hostname);
#endif

// ignore connection handling if WiFi is configured and scan still running
// or within first 2s if WiFi is not configured or AP is always active
if ((wifiConfigured && multiWiFi.size() > 1 && WiFi.scanComplete() < 0) || (now < 2000 && (!wifiConfigured || apBehavior == AP_BEHAVIOR_ALWAYS)))
Expand Down
Loading