summaryrefslogtreecommitdiff
path: root/lib/irs/getaddrinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/irs/getaddrinfo.c')
-rw-r--r--lib/irs/getaddrinfo.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/lib/irs/getaddrinfo.c b/lib/irs/getaddrinfo.c
index f821635e984ea..f61225c11f957 100644
--- a/lib/irs/getaddrinfo.c
+++ b/lib/irs/getaddrinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2012-2015 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -138,6 +138,7 @@
#include <isc/sockaddr.h>
#include <isc/string.h>
#include <isc/util.h>
+#include <isc/mutex.h>
#include <dns/client.h>
#include <dns/fixedname.h>
@@ -530,6 +531,7 @@ typedef struct gai_statehead {
int ai_port;
isc_appctx_t *actx;
dns_client_t *dnsclient;
+ isc_mutex_t list_lock;
ISC_LIST(struct gai_resstate) resstates;
unsigned int activestates;
} gai_statehead_t;
@@ -857,6 +859,7 @@ process_answer(isc_task_t *task, isc_event_t *event) {
* and have any answer, we can stop now by canceling the
* others.
*/
+ LOCK(&resstate->head->list_lock);
if (resstate == ISC_LIST_HEAD(resstate->head->resstates)) {
if ((resstate->trans4 != NULL &&
resstate->trans4->ai_sentinel.ai_next != NULL) ||
@@ -888,6 +891,7 @@ process_answer(isc_task_t *task, isc_event_t *event) {
resstate, link);
}
}
+ UNLOCK(&resstate->head->list_lock);
}
}
@@ -928,11 +932,19 @@ resolve_name(int family, const char *hostname, int flags,
head.ai_port = port;
head.actx = actx;
head.dnsclient = client;
+ result = isc_mutex_init(&head.list_lock);
+ if (result != ISC_R_SUCCESS) {
+ return (EAI_FAIL);
+ }
+
ISC_LIST_INIT(head.resstates);
result = make_resstates(mctx, hostname, &head, conf);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ DESTROYLOCK(&head.list_lock);
return (EAI_FAIL);
+ }
+ LOCK(&head.list_lock);
for (resstate = ISC_LIST_HEAD(head.resstates);
resstate != NULL; resstate = ISC_LIST_NEXT(resstate, link)) {
if (resstate->trans4 != NULL) {
@@ -966,6 +978,8 @@ resolve_name(int family, const char *hostname, int flags,
resstate->trans6->is_inprogress= ISC_FALSE;
}
}
+ UNLOCK(&head.list_lock);
+
if (!all_fail) {
/* Start all the events */
isc_app_ctxrun(actx);
@@ -1037,6 +1051,7 @@ resolve_name(int family, const char *hostname, int flags,
irs_context_destroy(&irsctx);
#endif
+ DESTROYLOCK(&head.list_lock);
return (error);
}
@@ -1123,10 +1138,8 @@ add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
UNUSED(flags);
ai = ai_clone(*aip, AF_INET); /* don't use ai_clone() */
- if (ai == NULL) {
- _freeaddrinfo(*aip);
+ if (ai == NULL)
return (EAI_MEMORY);
- }
*aip = ai;
ai->ai_socktype = socktype;
@@ -1246,11 +1259,8 @@ ai_clone(struct addrinfo *oai, int family) {
ai = ai_alloc(family, ((family == AF_INET6) ?
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)));
- if (ai == NULL) {
- if (oai != NULL)
- freeaddrinfo(oai);
+ if (ai == NULL)
return (NULL);
- }
if (oai == NULL)
return (ai);