[Pianod] /etc/resolv.conf issue
Peter Li
chinasaurli at gmail.com
Fri Sep 6 01:33:49 PDT 2013
So I finally tracked down a long-standing issue I've had on my Arch
Linux ARM RasPi. Gets back to the bad old days of getaddrinfo()! Not
sure if this is related to problems other people had, but on my system
the issue appears to be:
1) pianod starts at boot before the network stack
2) As a result, the first call to getaddrinfo() calls res_init() to
load DNS servers from /etc/resolv.conf but they haven't been written
into there yet by DHCP. Bad DNS info gets stored in the process's
global _res (I think, or maybe it's _res_state or _res_status or
somesuch name)
3) pianod is well behaved and keeps trying to reconnect at 60
second intervals, but it never manages to shake the bad DNS info loaded
into the process's globals, so getaddrinfo() continues to return
EAI_NONAME ad infinitum
Patching waitress.c to manually re-call res_init() after a getaddrinfo()
failure seems to fix things, i.e. pianod can successfully connect on its
first 60 second retry after boot. While Mac OS doesn't seem to have the
problem in the first place (probably because it's easier to make sure
that pianod doesn't start before the network stack) I believe this patch
should be safe in terms of not messing up pianod on Mac OS. The only
thing I'm not sure about is whether we need to link libwaitress against
libresolv; it doesn't seem necessary on my Linux, but probably should be
in the Makefile to be safe. Perette maybe you can try it, or else I'll
try on a Mac this weekend.
This does make me wonder why this didn't come up with WSGW, where I
recall there being a similar issue...
I'll look into submitting patch upstream; apparently pianobar is on GitHub?
P
Index: libwaitress/waitress.c
===================================================================
--- libwaitress/waitress.c (revision 149)
+++ libwaitress/waitress.c (working copy)
@@ -40,6 +40,7 @@
#include <errno.h>
#include <assert.h>
#include <stdint.h>
+#include <resolv.h>
#include <gnutls/x509.h>
@@ -779,17 +780,27 @@
hints.ai_socktype = SOCK_STREAM;
/* Use proxy? */
+ int gaierror;
if (WaitressProxyEnabled (waith)) {
- if (getaddrinfo (waith->proxy.host,
- WaitressDefaultPort (&waith->proxy), &hints, &res)
!= 0) {
- return WAITRESS_RET_GETADDR_ERR;
- }
+ gaierror = getaddrinfo (waith->proxy.host,
+ WaitressDefaultPort (&waith->proxy), &hints, &res);
} else {
- if (getaddrinfo (waith->url.host,
- WaitressDefaultPort (&waith->url), &hints, &res) !=
0) {
- return WAITRESS_RET_GETADDR_ERR;
- }
+ gaierror = getaddrinfo (waith->url.host,
+ WaitressDefaultPort (&waith->url), &hints, &res);
}
+ if (gaierror != 0) {
+ /* If process started at boot, before network stack, it can get
into a
+ * persistent state of getaddrinfo fail with EAI_NONAME. I
believe this
+ * is because /etc/resolv.conf was not initialized when the
first DNS
+ * attempt was made and the process gets stuck with bad DNS
server info.
+ *
+ * res_init() normally runs on the first DNS query and then is
cached by
+ * the process in global _res. Rerunning res_init() manually
seems to fix
+ * the issue.
+ */
+ res_init();
+ return WAITRESS_RET_GETADDR_ERR;
+ }
if ((waith->request.sockfd = socket (res->ai_family,
res->ai_socktype,
res->ai_protocol)) == -1) {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.deviousfish.com/pipermail/pianod-deviousfish.com/attachments/20130906/f12e2129/attachment-0002.htm>
More information about the Pianod
mailing list