Skip to content

Commit 98052bd

Browse files
authored
Cleanups DNS cache on error in CURL (Android) (#1410)
Fixes an issue when SDK was initialised during Flight Mode enabled. DNS was stuck and after switching off Flight Mode SDL couldn't resolve DNS. Relates-To: IOTSDK-18403 Signed-off-by: Yauheni Khnykin <[email protected]>
1 parent 7b0c381 commit 98052bd

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

olp-cpp-sdk-core/src/http/curl/NetworkCurl.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -758,12 +758,14 @@ NetworkCurl::RequestHandle* NetworkCurl::GetHandle(
758758
return nullptr;
759759
}
760760

761-
void NetworkCurl::ReleaseHandle(RequestHandle* handle) {
761+
void NetworkCurl::ReleaseHandle(RequestHandle* handle,
762+
bool cleanup_easy_handle) {
762763
std::lock_guard<std::mutex> lock(event_mutex_);
763-
ReleaseHandleUnlocked(handle);
764+
ReleaseHandleUnlocked(handle, cleanup_easy_handle);
764765
}
765766

766-
void NetworkCurl::ReleaseHandleUnlocked(RequestHandle* handle) {
767+
void NetworkCurl::ReleaseHandleUnlocked(RequestHandle* handle,
768+
bool cleanup_easy_handle) {
767769
curl_easy_reset(handle->handle);
768770
if (handle->chunk) {
769771
curl_slist_free_all(handle->chunk);
@@ -775,6 +777,23 @@ void NetworkCurl::ReleaseHandleUnlocked(RequestHandle* handle) {
775777
handle->data_callback = nullptr;
776778
handle->payload.reset();
777779
handle->body.reset();
780+
781+
// When using C-Ares on Android, DNS parameters are calculated in
782+
// curl_easy_init(). Those parameters are not reset in curl_easy_reset(...),
783+
// and persist in subsequent usages of easy_handle. Problem arises, if
784+
// curl_easy_init() was called when no good network was available, eg when
785+
// "Flight mode" is On. In such case, bad DNS params are stuck in the handle
786+
// and will persist. Http requests will continue to fail after good networks
787+
// become available. When such error is encountered, perform cleanup of easy
788+
// handle to force curl_easy_init() on next easy handle use.
789+
790+
#if defined(ANDROID)
791+
if (cleanup_easy_handle) {
792+
curl_easy_cleanup(handle->handle);
793+
handle->handle = nullptr;
794+
}
795+
#endif
796+
OLP_SDK_CORE_UNUSED(cleanup_easy_handle);
778797
}
779798

780799
size_t NetworkCurl::RxFunction(void* ptr, size_t size, size_t nmemb,
@@ -871,6 +890,9 @@ size_t NetworkCurl::HeaderFunction(char* ptr, size_t size, size_t nitems,
871890
void NetworkCurl::CompleteMessage(CURL* handle, CURLcode result) {
872891
std::unique_lock<std::mutex> lock(event_mutex_);
873892

893+
const bool cleanup_easy_handle = (result == CURLE_COULDNT_RESOLVE_PROXY ||
894+
result == CURLE_COULDNT_RESOLVE_HOST);
895+
874896
int index = GetHandleIndex(handle);
875897
if (index >= 0 && index < static_cast<int>(handles_.size())) {
876898
RequestHandle& rhandle = handles_[index];
@@ -880,7 +902,7 @@ void NetworkCurl::CompleteMessage(CURL* handle, CURLcode result) {
880902
OLP_SDK_LOG_WARNING(
881903
kLogTag,
882904
"CompleteMessage - message without callback, id=" << rhandle.id);
883-
ReleaseHandleUnlocked(&rhandle);
905+
ReleaseHandleUnlocked(&rhandle, cleanup_easy_handle);
884906
return;
885907
}
886908

@@ -896,7 +918,7 @@ void NetworkCurl::CompleteMessage(CURL* handle, CURLcode result) {
896918
if (rhandle.cancelled) {
897919
response.WithStatus(static_cast<int>(ErrorCode::CANCELLED_ERROR))
898920
.WithError("Cancelled");
899-
ReleaseHandleUnlocked(&rhandle);
921+
ReleaseHandleUnlocked(&rhandle, cleanup_easy_handle);
900922

901923
lock.unlock();
902924
callback(response);
@@ -943,7 +965,7 @@ void NetworkCurl::CompleteMessage(CURL* handle, CURLcode result) {
943965
<< "ms, bytes=" << download_bytes + upload_bytes);
944966

945967
response.WithStatus(status).WithError(error);
946-
ReleaseHandleUnlocked(&rhandle);
968+
ReleaseHandleUnlocked(&rhandle, cleanup_easy_handle);
947969

948970
lock.unlock();
949971
callback(response);
@@ -1082,7 +1104,8 @@ void NetworkCurl::Run() {
10821104
}
10831105

10841106
curl_multi_remove_handle(curl_, rhandle.handle);
1085-
ReleaseHandleUnlocked(&rhandle);
1107+
const bool cleanup_easy_handle = true;
1108+
ReleaseHandleUnlocked(&rhandle, cleanup_easy_handle);
10861109
} else {
10871110
OLP_SDK_LOG_ERROR(kLogTag, "Unknown handle completed");
10881111
}

olp-cpp-sdk-core/src/http/curl/NetworkCurl.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -250,18 +250,24 @@ class NetworkCurl : public olp::http::Network,
250250
NetworkRequest::RequestBodyType body);
251251

252252
/**
253-
* @brief Release handle after network request is done.
253+
* @brief Reset handle after network request is done.
254254
* This method handles synchronization between caller's thread and worker
255255
* thread.
256256
* @param[in] handle Request handle.
257+
* @param[in] cleanup_handle If true then handle is completelly release.
258+
* Otherwise handle is reset, which preserves DNS cache, Session ID cache,
259+
* cookies and so on.
257260
*/
258-
void ReleaseHandle(RequestHandle* handle);
261+
void ReleaseHandle(RequestHandle* handle, bool cleanup_handle);
259262

260263
/**
261-
* @brief Release handle after network request is done.
264+
* @brief Reset handle after network request is done.
262265
* @param[in] handle Request handle.
266+
* @param[in] cleanup_handle If true then handle is completelly release.
267+
* Otherwise handle is reset, which preserves DNS cache, Session ID cache,
268+
* cookies and so on.
263269
*/
264-
void ReleaseHandleUnlocked(RequestHandle* handle);
270+
void ReleaseHandleUnlocked(RequestHandle* handle, bool cleanup_handle);
265271

266272
/**
267273
* @brief Routine that is called when the last bit of response is received.

0 commit comments

Comments
 (0)