From 5ddabe85b2e3e4fd08d06980719d71a2aed77a5b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 28 Feb 2019 20:34:36 +0100 Subject: [PATCH] threaded-resolver: shutdown the resolver thread without error message When a transfer is done, the resolver thread will be brought down. That could accidentally generate an error message in the error buffer even though this is not an error situationand the transfer would still return OK. An application that still reads the error buffer could find a "Could not resolve host: [host name]" message there and get confused. Reported-by: Michael Schmid Fixes #3629 Closes #3630 Upstream-commit: 754ae103989a6ad0869d23a6a427d652b5b4a2fe Signed-off-by: Kamil Dudka --- lib/asyn-thread.c | 68 ++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index a9679d0..55e0811 100644 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -461,6 +461,42 @@ static CURLcode resolver_error(struct connectdata *conn) return result; } +static CURLcode thread_wait_resolv(struct connectdata *conn, + struct Curl_dns_entry **entry, + bool report) +{ + struct thread_data *td = (struct thread_data*) conn->async.os_specific; + CURLcode result = CURLE_OK; + + DEBUGASSERT(conn && td); + DEBUGASSERT(td->thread_hnd != curl_thread_t_null); + + /* wait for the thread to resolve the name */ + if(Curl_thread_join(&td->thread_hnd)) { + if(entry) + result = getaddrinfo_complete(conn); + } + else + DEBUGASSERT(0); + + conn->async.done = TRUE; + + if(entry) + *entry = conn->async.dns; + + if(!conn->async.dns && report) + /* a name was not resolved, report error */ + result = resolver_error(conn); + + destroy_async_data(&conn->async); + + if(!conn->async.dns && report) + connclose(conn, "asynch resolve failed"); + + return result; +} + + /* * Until we gain a way to signal the resolver threads to stop early, we must * simply wait for them and ignore their results. @@ -473,7 +509,7 @@ void Curl_resolver_kill(struct connectdata *conn) unfortunately. Otherwise, we can simply cancel to clean up any resolver data. */ if(td && td->thread_hnd != curl_thread_t_null) - (void)Curl_resolver_wait_resolv(conn, NULL); + (void)thread_wait_resolv(conn, NULL, FALSE); else Curl_resolver_cancel(conn); } @@ -494,35 +530,7 @@ void Curl_resolver_kill(struct connectdata *conn) CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, struct Curl_dns_entry **entry) { - struct thread_data *td = (struct thread_data*) conn->async.os_specific; - CURLcode result = CURLE_OK; - - DEBUGASSERT(conn && td); - DEBUGASSERT(td->thread_hnd != curl_thread_t_null); - - /* wait for the thread to resolve the name */ - if(Curl_thread_join(&td->thread_hnd)) { - if(entry) - result = getaddrinfo_complete(conn); - } - else - DEBUGASSERT(0); - - conn->async.done = TRUE; - - if(entry) - *entry = conn->async.dns; - - if(!conn->async.dns) - /* a name was not resolved, report error */ - result = resolver_error(conn); - - destroy_async_data(&conn->async); - - if(!conn->async.dns) - connclose(conn, "asynch resolve failed"); - - return result; + return thread_wait_resolv(conn, entry, TRUE); } /* -- 2.17.2