Sockets and OSError: -2

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
warren
Posts: 73
Joined: Tue Jul 12, 2016 5:47 pm

Sockets and OSError: -2

Post by warren » Mon Aug 22, 2016 5:57 am

I have an ESP8266 board which is clearly connected to my AP and thence to the wider internet. For example it is using the socket interface to regularly upload sensor values to Thingspeak. But I can only do this if I hard-code the Thingspeak i/p address in my socket code.

Attempts to use gethostbyaddr or getaddrinfo fail.

For example, using even the simple code from the tutorial ( http://docs.micropython.org/en/latest/e ... et-request ):

Code: Select all

>>> import socket
>>> addr_info = socket.getaddrinfo("towel.blinkenlights.nl", 23)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: -2
>>> 
I guess it is some kind of DNS error, but if I search for "OSError: -2" on this forum I don't get any clues...

Any suggestions?

jms
Posts: 108
Joined: Thu May 05, 2016 8:29 pm
Contact:

Re: Sockets and OSError: -2

Post by jms » Mon Aug 22, 2016 8:54 am

Look in the source code of the socket module.

My guess is either general flakiness or the fact that the host (also) has an IPv6 address but this should not have been queried.

warren
Posts: 73
Joined: Tue Jul 12, 2016 5:47 pm

Re: Sockets and OSError: -2

Post by warren » Mon Aug 22, 2016 10:29 am

jms wrote:Look in the source code of the socket module.
Thanks, but I cant see anything in that short file that sheds any light on this error code...

I get this problem with ANY host - which is why I think it is some weird generic DNS tyype error...

??

Beta_Ravener
Posts: 35
Joined: Tue Aug 09, 2016 6:56 pm

Re: Sockets and OSError: -2

Post by Beta_Ravener » Mon Aug 22, 2016 10:41 am

I have first tried running your command without network connection and indeed got the same error as you:

Code: Select all

>>> socket.getaddrinfo("towel.blinkenlights.nl", 23)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: -2
However, when I connected to my home AP all went good:

Code: Select all

>>> socket.getaddrinfo("towel.blinkenlights.nl", 23)
[(2, 1, 0, '', ('94.142.241.111', 23))]
Are you absolutely sure that you are using STA(tion) mode and you're connected to AP with internet connection? I have also noticed that there's a small time window after connecting to AP in which the `getaddrinfo` also fails with OSError: -2, probably because the connection was not yet fully established. If you're trying to get address info right after restarting ESP (for example in main.py), this might be the source of problems and putting some sleep before the call might solve it. Otherwise, I'm out of ideas for now.

warren
Posts: 73
Joined: Tue Jul 12, 2016 5:47 pm

Re: Sockets and OSError: -2

Post by warren » Mon Aug 22, 2016 11:50 am

Beta_Ravener wrote:I have first tried running your command without network connection and indeed got the same error as you:
Hmmm...that could help me try a few ideas.
Are you absolutely sure that you are using STA(tion) mode and you're connected to AP with internet connection?
Yes. My original line of code read like this:

Code: Select all

ai = socket.getaddrinfo("api.thingspeak.com", 80)
To make the Thingspeak updating work, I replaced this with a hard-coded line:

Code: Select all

ai=[(2, 1, 0, '', ('52.200.157.52', 80))] #hardwired for now
After that the code works flawlessly - every 15 seconds it updates Thingspeak...

But, in fact, it shows the problem in REPL - forget about scripts, and running too soon after a reset etc..

And my initialisation of the wlan is:

Code: Select all

wlan = network.WLAN(network.STA_IF)
I need to find a human readable version of "OSError: -2".......

jms
Posts: 108
Joined: Thu May 05, 2016 8:29 pm
Contact:

Re: Sockets and OSError: -2

Post by jms » Mon Aug 22, 2016 2:19 pm

Remember the API can claim you're connected and at some level (specifically layer 2) you might be but otherwise not (layer 3+, broken subsystem).

The source file you want to look at is probably called something like modusocket.c or just search for getaddrinfo.

My quick look suggests it's a buffer (thus memory ?) issue.

Does getaddrinfo() work with other hosts ? If so maybe it just doesn't for this host because of something about the answer (that one could investigate if so inclined). In which case live with it or fix it.

Beta_Ravener
Posts: 35
Joined: Tue Aug 09, 2016 6:56 pm

Re: Sockets and OSError: -2

Post by Beta_Ravener » Mon Aug 22, 2016 2:40 pm

warren wrote: I need to find a human readable version of "OSError: -2".......
I did some searching and I don't think this is possible. I think that `getaddrinfo` calls `lwip_getaddrinfo` from `micropython/extmod/modlwip.c` (because even ESP8266 readme says that "Sockets using modlwip"). So let's look at this call, the main part is a call to ` dns_gethostbyname`. Now this is not defined anywhere so it must be a library call. Sure it is, let's look here: http://lwip.wikia.com/wiki/DNS.

So now we know that if the information was cached, it would just return ERR_OK but because we are searching for it, it will return ERR_INPROGRESS. That takes us to the switch where sockets are being polled. Once there is a DNS response, the callback function `lwip_getaddrinfo_cb` gets called. And now we get to the source of the error. As you can see `ip_addr` must be NULL to get -2 as status, which in turn (back in `lwip_getaddrinfo`) produces exception `nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(state.status)));`

So there you go, it means that there was no ip_addr in call back. What does that mean?

Code: Select all

@param ipaddr pointer to a struct ip_addr containing the IP address of the hostname,
*        or NULL if the name could not be found (or on any other error).

warren
Posts: 73
Joined: Tue Jul 12, 2016 5:47 pm

Re: Sockets and OSError: -2

Post by warren » Mon Aug 22, 2016 3:04 pm

jms wrote:Does getaddrinfo() work with other hosts ?
It does not work with ANY host.

If I run exactly the same code in python on my Linux box (connected to the same AP as the ESP8266), It works perfectly..

warren
Posts: 73
Joined: Tue Jul 12, 2016 5:47 pm

Re: Sockets and OSError: -2

Post by warren » Mon Aug 22, 2016 3:08 pm

Beta_Ravener wrote:
warren wrote: I need to find a human readable version of "OSError: -2".......
I did some searching and I don't think this is possible.
Thanks for tracking down where the error comes from...I appreciate the guidance.
So there you go, it means that there was no ip_addr in call back. What does that mean?
Hmmm....I guess it means that the lookup failed for some reason....still thinking if it might be some weird DNS lookup glitch.

Is there any way of forcing the ESP8266 to use a specific server rather than just delegating it to the AP to which it is connected??

jms
Posts: 108
Joined: Thu May 05, 2016 8:29 pm
Contact:

Re: Sockets and OSError: -2

Post by jms » Mon Aug 22, 2016 3:34 pm

Is there any way of forcing the ESP8266 to use a specific server rather than just delegating it to the AP to which it is connected??[/quote]

Only if you use an undocumented function or tweak it to do so.

The fact you can't make it work for any host suggests a problem with your setup or code. One possibility is that your ISP mucks around with DNS (some do) and causes the problem. You could inspect the response in detail on your PC.

But the bottom line is as I have said before the only reliable way of using the ESP in the field is when it talks the simplest possible protocol to a server you control and don't bother with TLS. I would now add to that "don't even rely on DNS".

Post Reply