Resolving host names

Hello,

Googling for a ns lookup client for arduino, i couldn't find but one, the adafruit CC3000 MDNS. Can someone suggest other alternatives? My purpose is to be able to ping (Internet hosts in addition to local machines) using the icmp lib in the playground.

Many thanks in advance

Guy

I use dns lookup with the ethernet shield. Is that the device you are using? I will presume it is by your prior posts.

Here is the code I use to resolve pool.ntp.org for my NTP client sketch. The include goes at the top of the sketch with the other ethernet includes, the timeServer variable goes in global variable declarations, and the rest goes in setup after the Ethernet.begin() call.

#include <Dns.h>
IPAddress timeServer;

  DNSClient dns;
  dns.begin(Ethernet.dnsServerIP());
  
  if(dns.getHostByName("pool.ntp.org",timeServer) == 1) {
    Serial.print(F("ntp = "));
    Serial.println(timeServer);
  }
  else Serial.print(F("dns lookup failed"));

But this is a piece of cake :slight_smile: I'll try it as soon as I'm back home. I was not aware of the existence of this DNSClient thing and it's strange I missed it. Where is it documented?

It isn't documented. I found it while looking for something else in the ethernet library.

This is from EthernetClient.cpp. It is the connect function that uses a domain name rather than an IP.

int EthernetClient::connect(const char* host, uint16_t port) {
  // Look up the host first
  int ret = 0;
  DNSClient dns;
  IPAddress remote_addr;

  dns.begin(Ethernet.dnsServerIP());
  ret = dns.getHostByName(host, remote_addr);
  if (ret == 1) {
    return connect(remote_addr, port);
  } else {
    return ret;
  }
}

here is the whole code and it says dns failed. The Arduino ping test (to google) gives 100% OK (i resolve with wins ns lookup). What's wrong??
BTW, why did you want to resolve your time server?

#include <Dns.h>
#include <SPI.h>         
#include <Ethernet.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 
IPAddress ip(10,0,0,7);
IPAddress myDNS(10,0,0,138);
IPAddress gateway(10,0,0,138);
IPAddress subnet(255,255,255,0);
IPAddress timeServer;
void setup() {
  Ethernet.begin(mac, ip, myDNS, gateway,subnet); 
  DNSClient dns;
  Serial.begin(9600);
  while (!Serial);
  dns.begin(Ethernet.dnsServerIP());
  if(dns.getHostByName("www.google.com",timeServer) == 1) {
    Serial.print(F("ntp = "));
    Serial.println(timeServer);
  }
  else Serial.print(F("dns lookup failed"));
}
void loop(){;}

NTP servers come and go. I want to use a current one, so I resolve pool.ntp.org to get a current active NTP server.

If your code fails the dns, then I suggest you use DHCP to get your network settings. Maybe your router isn't resolving the domains correctly, or isn't a dns server.

Thanks, Will redo Sunday from home

Retried on my network: it worked perfectly. And I appreciate the way you print the IP :slight_smile: short and elegant

Strange, it seems that if

DNSClient dns;
dns.begin(Ethernet.dnsServerIP());

goes in setup after ethernet.begin
and

 if(dns.getHostByName("pool.ntp.org",timeServer) == 1)

is in a another function
then the compiler complains that
error: request for member 'getHostByName' in 'dns', which is of non-class type ''

But I need to use the name resolution as an Internet connectivity check and it's done in a function which is called many times

Thanks

Don't call it dns then. Rename it to dnClient.

// put this in global variables
DNSClient dnClient;

// put this in setup
dnClient.begin(Ethernet.dnsServerIP());

// call this any time you want
 if(dnClient.getHostByName("pool.ntp.org",timeServer) == 1)

It works! Thank you very much

Oops...
I was sure everything worked fine but today I am witnessing that I am getting Internet OK even when my router-modem link is removed, as if my router was caching name resolutions
here is my net

ISP - coax - modem - router - arduino
|
wifi
If I brake the router link to arduino link I am getting the Inet fail status
If I brake the router link to the modem I get Inet ok !!!
Below is the code

What would you recommend?
Thanks youTim

void manageRouter(){
/*How does this work
every 10 minutes resolve the server to confirm we have internet access
if we succeed, we log to phant the OK result and this serves as system health check 
if we fail, 
->we log the failure to the eeprom then we log no more till first subsequant success
->obviusely we log nothing to phant which will shaw holes in the given slot but as holes aren't 
as noticeable,we;'ll log the epoch of the first failure once the failures are over
*/
  static long failureStart;  
  static boolean slotChecked=false;
  char server1[]= "www.google.com";
  String timeString;
  IPAddress ip;
  if ((hmsLocal[1]%10)==0){ // round minute
    if(!slotChecked){
      slotChecked=true; 
      if(nsClient.getHostByName(server1,ip) == 1){// inet ok
        if(inetFailed){
          inetFailed=false;
          logger(__LINE__,version,0);// stamp end of shortage
          epoch2string(failureStart, timeString);
          post2phant("!Inet_failure_since"+timeString);
//          post2phant("!Inet_failure_since"+timeString);
        }
        epoch2string(epochLocal, timeString);
        Serial.println("dns ok at "+timeString); 
        post2phant("Inet_ok_at_"+timeString);
        return;
      }
      else {//inet failure
        if (!inetFailed){//start of failure
          inetFailed=true;
          failureStart=epochLocal;
          logger(__LINE__,version,0);
        }
        Serial.println("dns failed at "+timeString=+"-> cycling router");cycleRouter(); 
        return;
      }
    }
    else return; // slot checked
  }
  else{//not round minute
    slotChecked=false;
    return;
  }
}

You aren't by chance connecting to someone elses network are you? That can result in a bit of confusion.

SurferTim:
I use dns lookup with the ethernet shield. Is that the device you are using? I will presume it is by your prior posts.

Here is the code I use to resolve pool.ntp.org for my NTP client sketch. The include goes at the top of the sketch with the other ethernet includes, the timeServer variable goes in global variable declarations, and the rest goes in setup after the Ethernet.begin() call.

Thanks for this. Worked for me, and confirmed why my UDP send was taking so long, it was the DNS Lookup. Interestingly, my informal timing seemed to indicate that the DNS lookup happening as part of

UdpNTP.beginPacket(address, 123);

was generally faster. I'm not really sure why, and given that there is variation it could be nothing. I expect, and haven't looked, that it should call the same code.

In attempting to estimate the round trip delay for my NTP reply, I am now starting my timer after the UdpNTP.beginPacket() statement.

Many thanks again.