Skip to content

ESP8266 WiFi Client does not honor DHCP host-name option setting when using DHCP #5695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
4 of 5 tasks
dachshund-digital opened this issue Jan 29, 2019 · 12 comments · Fixed by #6680
Closed
4 of 5 tasks

Comments

@dachshund-digital
Copy link

dachshund-digital commented Jan 29, 2019

Basic Infos

  • This issue complies with the issue POLICY doc.
  • [ x I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: ModeMCU v3 LoLin Wemos.cc ESP8266
  • Core Version: ESP8266 WiFi 2.5.0-beta3
  • Development Env: Arduino IDE
  • Operating System: Windows 10

Settings in IDE

  • Module: Nodemcu
  • Flash Mode: other
  • Flash Size: 4MB
  • lwip Variant: v2
  • Reset Method: nodemcu
  • Flash Frequency: 40Mhz
  • CPU Frequency: 80Mhz
  • Upload Using: SERIAL
  • Upload Speed: 115200

Problem Description

Detailed problem description goes here.
DHCP ip address acquired by device as expected with WiFi configuration. However DHCP host-name option is not honored, the automatic host name is reported by the WiFi.hostname() call, not the name assigned in the DHCP reservation on DHCP server for said MAC address of device.


DHCP Reservation Example... Note the host-name option value of "Node01"

#--------------------
# NodeMCU...
#--------------------

host Node01 {
        hardware ethernet 68:C6:3A:D6:59:C7;
        fixed-address 192.168.1.50;
        option host-name "Node01";
}

#include <ESP8266WiFi.h>

CONST int   BAUDRATE = 115200;
CONST int   HALFSECOND = 500;
CONST char* DESCRIPTOR = "Dachshund Digital_optout_nomap";
CONST char* PASSPHRASE = "D@chshund Digit@1";

//
struct InformationStructure {
  //

  String    theMediaAccessControl;
  String    theNetwork;
  String    theKey;
  String    theId;
  IPAddress theIP;
  String    theName;
  int       theStrength;
};

void setup() {
  struct InformationStructure theInformation;

  Serial.begin(BAUDRATE);
  while (!Serial);
  //Serial.setDebugOutput(false);

  // WiFi Initialization...
  Serial.println("WiFi Initialization");

  WiFi.mode(WIFI_STA);
  WiFi.begin(DESCRIPTOR, PASSPHRASE);

  // WiFi Connection...
  Serial.print("WiFi Connection");
  
  while (WiFi.status() != WL_CONNECTED) {
    
    // WiFi Connection Wait...
    delay(HALFSECOND);
    Serial.print(".");
  }              
  
  //
  theInformation.theMediaAccessControl = WiFi.macAddress();
  theInformation.theName = WiFi.hostname();
              theInformation.theKey = WiFi.psk();
              theInformation.theId = WiFi.BSSIDstr();
              theInformation.theStrength = WiFi.RSSI();
              theInformation.theIP = WiFi.localIP();
              theInformation.theNetwork = WiFi.SSID();
              
              Serial.printf("NodeMCU (ESP8266) Web Server<br>Media Access Control %s\nHost Name %s\nKey \'%s'\\nBasic Service Set Id %s\nSignal Strength %d (dBm)\nIP Address %s\nNetwork \'%s\'\n",
                theInformation.theMediaAccessControl.c_str(), theInformation.theName.c_str(), theInformation.theKey.c_str(), theInformation.theId.c_str(), theInformation.theStrength, theInformation.theIP.toString().c_str(), theInformation.theNetwork.c_str());
              
// Host name is auto generated, DHCP option value appears to be ignored.  Host name from DHCP should be 'Node01' not ESP_D659C7.

}

void loop() {

}

Debug Messages

SDK:3.0.0-dev(c0f7b44)/Core:2.5.0-beta2=20499902/lwIP:STABLE-2_1_2_RELEASE/glue:1.0-4-gc434c6f/BearSSL:2398cc6
WiFi Initialization
scandone
WiFi Connectionscandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 2
cnt 

connected with xxx channel 2
dhcp client start...
ip:192.168.1.50,mask:255.255.255.0,gw:192.168.1.251
.NodeMCU (ESP8266) Web Server<br>Media Access Control 68:C6:3A:D6:59:C7
Host Name ESP_D659C7
Key 'xxx'\nBasic Service Set Id C8:D7:19:0F:4C:6F
Signal Strength -41 (dBm)
IP Address 192.168.1.50
Network 'Dachshund Digital_optout_nomap'
pm open,type:2 0
@devyte
Copy link
Collaborator

devyte commented Jan 30, 2019

Do I understand this correctly: you want the ESP to set its hostname as specified by the DHCP server via a received option?

On the ESP, the dns hostname can be defined from:

  • SDK's (flawed) default: ESP_XXXXXX
  • User-specified via WiFi.hostname("somestring")
  • DHCP server via an option sent with the dynamic IP //<--- this would be the new case

Network-wide, the hostname is specified with:

  • statically for static configs (DNS server)
  • msg to the DHCP server with an option during DHCP discovery (in theory could also be an inform DHCP msg after discovery, but implemented like that)
  • msg from the DHCP server to the ESP during discovery //<--- this would be the new case

If the above is correct, then I think we need to discuss priorities. One possibility:

  1. ESP sets its own hostname and informs the DHCP server
  2. If the ESP did not have its hostname specified, and the DHCP server offers an option, take the option.
  3. If the ESP did not have its hostname specified, and the DHCP server does not offer an option, use the SDK default (possibly corrected to be RFC-compliant), and inform the DHCP server.

BTW, you seem to be thinking of the ESP only as a network-attached device, Don't forget that it has a SoftAP interface, and it can serve its own network. Within that network, it's the ESP who is both the DNS and DHCP server. This case must also be taken into account.

@dachshund-digital
Copy link
Author

Yes, the priorities qualification, I believe is correct. Which I think you have qualified well above. Moreover, it mirrors typical behavior of other environments, i.e. OSes, etc.

Yes, I am aware of the different modes of use possible. I actually plan to setup DHCP/DNS services on a ESP device as recovery resource in my home network... just awaiting for the package to arrive. Typically a network services device is a static configuration as a best practice, of course.

And, yes, this would be a new case, but IMHO it should have been done as one of the default options in the original design. Consistent behavior in respect to DHCP options I believe would be a significant and valued addition to the SDK/API.

@d-a-v
Copy link
Collaborator

d-a-v commented Jan 30, 2019

And, yes, this would be a new case, but IMHO it should have been done as one of the default options in the original design. Consistent behavior in respect to DHCP options I believe would be a significant and valued addition to the SDK/API.

We are using lwIP and after checking latest stable version, which we use, lwIP itself does not honor dhcp received hostname option, but provides a way to parse received options it doesn't use.
We could do that (lwIP src).

However we would have this real DNS hostname only when the esp is a dhcp client. A static hostname will fail with the security argument you mention in #5574 (comment) .

edited: this is reverse dns lookup, see below There's another way to resolve esp's real hostname is to make a DNS request with the local IP address once dhcp lease is received/accepted, it is compatible with static IP. That also could be something we can add in the core. It fulfills this requirement for both dhcp client and static IP (when this IP is known by the DNS server). This can be a workaround in user's sketch until we do something in the core.

We must not forget about mDNS, which is a way to unilaterally claim a hostname (automatically updated when name collisions occur). mDNS names are now well known from OSes (bonjour or ahavi daemons on the three main OSes). How should we handle that dual identity ? Can we always match one to the other ?

Decisions have to be taken before going further. I'm not fully aware on how it is done on main OSes.

(inviting @LaborEtArs and @hreintke about the DNS/mDNS duality)

@LaborEtArs
Copy link
Contributor

If some kind of network admin sets a hostname for a device, then this should be respected a good as possible. In my knowledge, there are at least three options to set the hostname:

  1. name entry in a (static) DNS server (or name presets in Dynamic DNS servers)
  2. option 12 (hostname) in the DHCP server (a q&d workaround in my eyes)
  3. a hostname entry in the device itself
    For options 1. and 2. a mDNS responder in the device itself should come out with the assigned hostname (otherwise there is a network configuration error and the -as good as possible- option comes in).
    For option 3. the best case is a really user assigned hostname, which should work out like options 1./2. In the case of hostname conflicts (for user or sketch defined hostnames), again the -as good as possible- option comes in and the name is changed until a unique name is found.
    In any case, when a DNS or DHCP server assigned hostname is changed by the client (manually or via mDNS), the originator needs to be informed. To my knowledge, for dynamic name changes, a DHCP server is only a shortcut to the Dynamic DNS server behind, so the right response - after finding a unique name - would be to send a name update to the local DNS server.
    In my opinion, the hostname for a device should be unique and lead to the same IP in DNS queries as well as in mDNS queries.

@dachshund-digital
Copy link
Author

dachshund-digital commented Jan 30, 2019

@LaborEtArs,

I believe we see the scenario the same way. In a typical top down, secured environment, DHCP reservations are explicitly done, are static, thus DNS is not dynamic, and DHCP reservations mirror static DNS assignment. The expectation is that DHCP reservations are synchronized with static DNS of course.

This is the scenario being asked for, that if DHCP has set the host-name option, it is honored, unless, device device static assignment is done, i.e. SoftAP, or direct assignment via API, or Dynamic DNS owns the environment.

If Dynamic DNS is used, then explicit or static DHCP reservation would not, should not, be used, or even honored, because Dynamic DNS must inform DHCP of the applicable host-name, as applicable, as you noted. Honoring DHCP reservation, i.e. host-name option use, would not, and should not override dynamic DNS priority, if Dynamic DNS is used.

Of course, the use of Dynamic DNS in secured environments is not best practice, but I digress.

@d-a-v
Copy link
Collaborator

d-a-v commented Jan 31, 2019

Would it be then

  • set local preferred hostname (WiFi.hostname(DNS-name)),
    wait for connectivity (dhcp-client) /or/ set static IP address
  • either: (not available in our API today)
  • setup mDNS with this updated DNS/DHCP hostname
    or: setup mDNS with any other hostname (sketch policy) ?
  • check/wait for mDNS updates in case of mDNS name collision,
    • possibly update the DNS-name (WiFi.hostname(new-DNS-name))
      (only possible with compliant dhcp servers)
    • or not (sketch policy?)
  • do whatever needed with the DNS-name and (if willingly different) the mDNS-name
    (like: print it on an attached screen, post it on a remote server webpage, send an email, etc)

@dachshund-digital
Copy link
Author

Yes, seems the right strategy to me. This always for static environments (where DHCP and DNS are predefined, such as in secured environments, and also supports use of dynamic DNS environments if that is desired, needed.

@dachshund-digital
Copy link
Author

Any progress on this? Expectation of when it will be added? Just curious.

Also, just did some testing with ESP 32 devices, and the same issue results, DHCP host name option is not honored it appears. Was using the Arduino/espressif library ESP 32, and Arduino ESP8266WiFi/WiFiMulti for ESP 8266 of course.

Never mind the fact that the WiFi and WiFiMulti libraries exhibit a lot of variance between API definitions and features between the two device classes/types. It was really frustrating to have to do a lot of #defines to isolate ESP 32 and ESP 8266 coding because the same named libraries are not identical at the API definition/call level. Does not make any sense to me... but I digress.

Maybe how DHCP host name option can be consistently implemented for ESP 32 and ESP 8266? That would be a wonderful thing, IMHO.

@lindenaar
Copy link

as suggested by @d-a-v I would love to be able to define a callback / hook to use unused DHCP options (using LWIP_HOOK_DHCP_PARSE_OPTION it seems) instead. This would allow those that want to set the hostname as well and also support other scenarios in lieu of a permanent solution.

One of the things I need for example is to pick up the NTP server and timezone from the DHCP options, something that is also not possible at this moment.

Let me know if this would be a good idea, I am also more than happy to submit a patch to implement if someone could point me in the right direction w.r.t. to the procedure for that.

@d-a-v
Copy link
Collaborator

d-a-v commented May 24, 2019

Everything is feasible. Just do it ™. yakafokon. Time is needed.
Would you have a try with LWIP_HOOK_DHCP_PARSE_OPTION in lwip2 repository. The function would have to call wifi_station_set_hostname() and that's it.

NTP server and timezone from the DHCP options

This is already done and working (for NTP server, timezone I wasn't aware it is in DHCP header)

Our API is not sufficient and does not allow full genericity, either:

  • do nothing, if DHCP knows NTP then it's fine
    (after you use for example configTZ(TZ_Asia_Shanghai);)
  • use configTime() to setup timezone by hand

in the right direction w.r.t. to the procedure for that.

cd tools/sdk/lwip2
make download
# edit builder/glue-lwip/arduino/lwipopts.h and define LWIP_HOOK_DHCP_PARSE_OPTION
# create your callback in a new file in `glue-lwip/`, update the makefiles to add it
make clean
make install
# try it

@d-a-v
Copy link
Collaborator

d-a-v commented Nov 9, 2020

FWIW #6680 will add LWIP_HOOK_DHCP_PARSE_OPTION.
Function definition will be in lwipopts.h.

@dachshund-digital
Copy link
Author

Cool!

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

Successfully merging a pull request may close this issue.

5 participants