No evdns will do caching by default (with respect to TTL), to disable this set EVDNS_BASE_NO_CACHE
There are also helpers for manually manage the cache:
- evdns_cache_write()
- evdns_cache_lookup()
Initial PR: #571Fixes: #1715
Co-authored-by: Greg Hazel <ghazel@gmail.com>
Co-authored-by: Keith Moore <kmoore@clostra.com>
I faced with strange problem: event loop doesn't exit after dns resolving with
`EVDNS_BASE_DISABLE_WHEN_INACTIVE`.
Stand:
- Ubuntu 22;
- libevent release-2.1.12-stable
- `resolve.conf` contains 2 nameservers;
- I use `evdns_base_new` with `EVDNS_BASE_DISABLE_WHEN_INACTIVE | EVDNS_BASE_INITIALIZE_NAMESERVERS` to avoid OS specific code.
After small investigation, look like events related with dns sockets added to
event_base before `evdns->disable_when_inactive` was initialized. `libevent`
did epoll_ctl(DEL) after resolving completed on the first socket, but the
second socket remained in the `epoll` interest list.
It is not a thankless task to fix such issues on and on, let's just
prohibit this cases, and our build with -Werror on CI will show new
issues from now on.
Fixes: #1434
If resolv.conf has no nameservers, evdns_base_new can still succeed with
the default of using the name server from localhost matching the man
page documentation for resolv.conf.
Previously evdns was using HOST_NAME_MAX, and define it to 255 *only* if
it not set, however it does set on linux:
$ egrep -r define.*HOST_NAME_MAX /usr/include/bits
/usr/include/bits/local_lim.h:#define HOST_NAME_MAX 64
/usr/include/bits/posix1_lim.h:#define _POSIX_HOST_NAME_MAX 255
/usr/include/bits/confname.h:#define _SC_HOST_NAME_MAX _SC_HOST_NAME_MAX
But 64 should be the limit of the host component, not for the whole
hostname, as also noted by @ploxiln
So use our own EVDNS_NAME_MAX const, which is set to 255.
Fixes: #1280
Add new flag (DNS_CNAME_CALLBACK) for
evdns_base_resolve_ipv4()/evdns_base_resolve_ipv6().
If set, you will get one more callback with type == DNS_CNAME and CNAME
in addrs argument.
I recently found that when the network status changed when calling
bufferevent_socket_connect_hostname (e.g. switching between several
WIFIs), all DNS servers would fail, and the timeout of probe would be
very long if there were many DNS requests. I want libevent to support
manual setting of MAX_PROBE_TIMEOUT and TIMEOUT_BACKOFF_FACTOR
So move hardcoded MAX_PROBE_TIMEOUT and TIMEOUT_BACKOFF_FACTOR into
struct, and allow changing them.
Was not noticed since it is reported only with optimization enabled, as
stated in gcc(1):
The effectiveness of some warnings depends on optimizations also
being enabled. For example -Wsuggest-final-types is more effective with
link-time optimization and -Wmaybe-uninitialized does not warn at all
unless optimization is enabled.
And interesting thing is that it is reported only for -O2, not for -O3,
that's why I did not catched it in both cmake env that I had:
- debug (it has -O0)
- release (it has -O3)
While autoconf has -O2.
Added new option `edns-udp-size` for evdns_base which allows
to control maximum allowed size of UDP DNS messages. This
maximum size is passed to the DNS server via edns mechanism.
Fix undefined behaviour and application crash that might take
place in some rare cases after calling evdns_base_free when
there are requests in the waiting queue.
Current cleanup procedure in evdns_base_free_and_unlock
function includes 2 steps:
1. Finish all inflight requests.
2. Finish all waiting requests.
During the first step we iterate over each list in req_heads
structure and finish all requests in these lists. With current
logic finishing an inflight request (function request_finished)
removes it from the inflight requests container and forces
a wating connection to be sent (by calling
evdns_requests_pump_waiting_queue). When these new requests are
sent it is possible that they will be inserted to the list in
req_heads that we've already cleaned.
So in some cases container of the inflight requests is not empty
after this procedure and some requests are not finished and
deleted. When timeouts for these requests expire
evdns_request_timeout_callback is called but corresponding
evdns_base has been already deleted which causes undefined
behaviour and possible applicaton crash.
It is interesting to note that in old versions of libevent such
situation was not possible. This bug was introduced by the commit
14f84bbdc77d90b1d936076661443cdbf516c593. Before this commit
nameservers were deleted before finishing the requests. Therefore
it was not possible that requests from the waiting queue be sent
while we finish the inflight requests.
This will allow to customize SO_RCVBUF/SO_SNDBUF for nameservers in this
evdns_base, you may want to adjust them if the kernel starts dropping
udp packages.
To avoid possible confusion
But there is still one test that has some messages on windows:
main/methods
Because this test needs >1 of avaiable methods, otherwise it will warn.
- DNS_OPTION_NAMESERVERS_NO_DEFAULT
Do not "default" nameserver (i.e. "127.0.0.1:53") if there is no nameservers
in resolv.conf, (iff DNS_OPTION_NAMESERVERS is set)
- EVDNS_BASE_NAMESERVERS_NO_DEFAULT
If EVDNS_BASE_INITIALIZE_NAMESERVERS isset, do not add default
nameserver if there are no nameservers in resolv.conf (just set
DNS_OPTION_NAMESERVERS_NO_DEFAULT internally)
Fixes: #569
There is only one test that uses service name getaddrinfo_async, which
manually check whether it works or not, other should not assume that it
is available and works.
There was already an attempt to overcome some possible limitations, like
lack of "http" in /etc/services in
d6bafbbeb27ff3943d6f3b6783bcded76384c31e ("test/dns: replace servname
since solaris does not have "http"")
When there is no /etc/services file evdns_getaddrinfo() will fail (with
service="ssh") and hence it will go to then "end" label with locked
rp.lock which in case of debug locking checks will bail with:
[err] ../evthread.c:220: Assertion lock->count == 0 failed in debug_lock_free
So add rp.locked flag, and unlock the lock before freeing it if it is in
locked state.
And here is how you can reproduce the issue:
$ docker run -e LD_LIBRARY_PATH=$PWD/lib -e PATH=/usr/bin:/bin:$PWD/bin -v $PWD:$PWD --rm -it debian:testing regress dns/getaddrinfo_race_gotresolve
(since debian:testing does not have /etc/services)
If system resolver (sync one) will respond too slow, then we can fail async
request and evdns will retransmit tham again, but evdns server will accept that
failed requets, so we will have not 2 requests but 4.
Reproduced on centos box sometimes.