Found this yesterday while playing with a dnsbl filter for smtpd during
network outage and found that gethostbyname returns HOST_NOT_FOUND.
Glibc, musl, and FreeBSD return TRY_AGAIN.
This is annoying because for a DNSBL I need to be able to differentiate
between a resolver not being available and an entry not existing in the
upstream database.
The reason is that in gethostnamadr_async.c for case ASR_STATE_NOT_FOUND
the ar_h_errno is set to HOST_NOT_FOUND if we don't have a subq_h_errno.
Looking at case ASR_STATE_SUBQUERY we don't copy subq_h_errno from
ar->ar_h_errno, while res_send_async.c (which is used by gethostnamaddr
as a backend) always sets ar_h_errno and ar_count in case
ASR_STATE_HALT.
I've looked at the code but I can't find any reason why not getting a
reply gets this special treatment.
Assuming I haven't missed anything the diff below uses the fact that
no packet also has ar_count set to 0 (res_send_async.c:268) and always
copy the ar_h_errno from the subquery.
This both reduces the LoC and fixes the issue for me.
OK?
martijn@
Index: gethostnamadr_async.c
===================================================================
RCS file: /cvs/src/lib/libc/asr/gethostnamadr_async.c,v
retrieving revision 1.44
diff -u -p -r1.44 gethostnamadr_async.c
--- gethostnamadr_async.c 28 Apr 2018 15:16:49 -0000 1.44
+++ gethostnamadr_async.c 26 Jun 2019 09:55:02 -0000
@@ -289,12 +289,10 @@ gethostnamadr_async_run(struct asr_query
/* Done. */
as->as_subq = NULL;
- if (ar->ar_datalen == -1) {
- async_set_state(as, ASR_STATE_NEXT_DB);
- break;
- }
-
- /* If we got a packet but no anwser, use the next DB. */
+ /*
+ * We either got no packet or a packet without an answer.
+ * Saveguard the h_errno and use the next DB.
+ */
if (ar->ar_count == 0) {
free(ar->ar_data);
as->as.hostnamadr.subq_h_errno = ar->ar_h_errno;