evdns_getaddrinfo() starts two parallel requests for A and AAAA record.
But if request is created from thread different from dns_base's, request of A record is
started immediately and may result in calling free_getaddrinfo_request() from
evdns_getaddrinfo_gotresolve() because `other_req' doesn't exist yet.
After that, request of AAAA record starts and finishes, and evdns_getaddrinfo_gotresolve()
is called again for structure that is already freed.
This commits adds locking into evdns_getaddrinfo() function.
int err;
int port = 0;
int want_cname = 0;
+ int started = 0;
if (!dns_base) {
dns_base = current_base;
* launching those requests. (XXX we don't do that yet.)
*/
+ EVDNS_LOCK(dns_base);
+
if (hints.ai_family != PF_INET6) {
log(EVDNS_LOG_DEBUG, "Sending request for %s on ipv4 as %p",
nodename, &data->ipv4_request);
evtimer_assign(&data->timeout, dns_base->event_base,
evdns_getaddrinfo_timeout_cb, data);
- if (data->ipv4_request.r || data->ipv6_request.r) {
+ started = (data->ipv4_request.r || data->ipv6_request.r);
+
+ EVDNS_UNLOCK(dns_base);
+
+ if (started) {
return data;
} else {
mm_free(data);