Loading DnsTlsDispatcher.cpp +23 −3 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "resolv_cache.h" #include "resolv_cache.h" #include "resolv_private.h" #include "resolv_private.h" #include "stats.pb.h" #include "stats.pb.h" #include "util.h" #include <android-base/logging.h> #include <android-base/logging.h> Loading Loading @@ -243,7 +244,7 @@ DnsTlsTransport::Response DnsTlsDispatcher::query(const DnsTlsServer& server, un void DnsTlsDispatcher::forceCleanup(unsigned netId) { void DnsTlsDispatcher::forceCleanup(unsigned netId) { std::lock_guard guard(sLock); std::lock_guard guard(sLock); cleanup(std::chrono::steady_clock::now(), netId); cleanup(std::chrono::steady_clock::now(), std::chrono::seconds(-1), netId); } } DnsTlsTransport::Result DnsTlsDispatcher::queryInternal(Transport& xport, DnsTlsTransport::Result DnsTlsDispatcher::queryInternal(Transport& xport, Loading Loading @@ -276,22 +277,41 @@ DnsTlsTransport::Result DnsTlsDispatcher::queryInternal(Transport& xport, // This timeout effectively controls how long to keep SSL session tickets. // This timeout effectively controls how long to keep SSL session tickets. static constexpr std::chrono::minutes IDLE_TIMEOUT(5); static constexpr std::chrono::minutes IDLE_TIMEOUT(5); void DnsTlsDispatcher::maybeCleanup(std::chrono::time_point<std::chrono::steady_clock> now) { void DnsTlsDispatcher::maybeCleanup(std::chrono::time_point<std::chrono::steady_clock> now) { // Make the timeout tunable via experiment flag for testing. std::chrono::seconds unusable_xport_idle_timeout{-1}; const int value = Experiments::getInstance()->getFlag("dot_keep_unusable_xport_sec", -1); if (value > -1 && isUserDebugBuild() && std::chrono::seconds(value) < IDLE_TIMEOUT) { unusable_xport_idle_timeout = std::chrono::seconds(value); } // To avoid scanning mStore after every query, return early if a cleanup has been // To avoid scanning mStore after every query, return early if a cleanup has been // performed recently. // performed recently. if (now - mLastCleanup < IDLE_TIMEOUT) { const std::chrono::seconds timeout = (unusable_xport_idle_timeout < IDLE_TIMEOUT) ? unusable_xport_idle_timeout : IDLE_TIMEOUT; if (now - mLastCleanup < timeout) { return; return; } } cleanup(now, std::nullopt); cleanup(now, unusable_xport_idle_timeout, std::nullopt); mLastCleanup = now; mLastCleanup = now; } } void DnsTlsDispatcher::cleanup(std::chrono::time_point<std::chrono::steady_clock> now, void DnsTlsDispatcher::cleanup(std::chrono::time_point<std::chrono::steady_clock> now, std::chrono::seconds unusable_xport_idle_timeout, std::optional<unsigned> netId) { std::optional<unsigned> netId) { std::erase_if(mStore, [&](const auto& item) REQUIRES(sLock) { std::erase_if(mStore, [&](const auto& item) REQUIRES(sLock) { auto const& [_, xport] = item; auto const& [_, xport] = item; if (xport->useCount == 0) { if (xport->useCount == 0) { // Remove the Transports of the associated network. if (netId.has_value() && xport->mNetId == netId.value()) return true; if (netId.has_value() && xport->mNetId == netId.value()) return true; // Remove all expired Transports. if (now - xport->lastUsed > IDLE_TIMEOUT) return true; if (now - xport->lastUsed > IDLE_TIMEOUT) return true; // Unusable Transports should be removed earlier. if (!xport->usable() && unusable_xport_idle_timeout.count() >= 0 && now - xport->lastUsed > unusable_xport_idle_timeout) return true; } } return false; return false; }); }); Loading DnsTlsDispatcher.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -165,7 +165,8 @@ class DnsTlsDispatcher : public PrivateDnsValidationObserver { // Drop any cache entries whose useCount is zero and which have not been used recently. // Drop any cache entries whose useCount is zero and which have not been used recently. // This function performs a linear scan of mStore. // This function performs a linear scan of mStore. void cleanup(std::chrono::time_point<std::chrono::steady_clock> now, void cleanup(std::chrono::time_point<std::chrono::steady_clock> now, std::optional<unsigned> netId) REQUIRES(sLock); std::chrono::seconds unusable_xport_idle_timeout, std::optional<unsigned> netId) REQUIRES(sLock); // Return a sorted list of usable DnsTlsServers in preference order. // Return a sorted list of usable DnsTlsServers in preference order. std::list<DnsTlsServer> getOrderedAndUsableServerList(const std::list<DnsTlsServer>& tlsServers, std::list<DnsTlsServer> getOrderedAndUsableServerList(const std::list<DnsTlsServer>& tlsServers, Loading Experiments.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -55,6 +55,7 @@ class Experiments { "sort_nameservers", "sort_nameservers", "dot_async_handshake", "dot_async_handshake", "dot_connect_timeout_ms", "dot_connect_timeout_ms", "dot_keep_unusable_xport_sec", "dot_maxtries", "dot_maxtries", "dot_revalidation_threshold", "dot_revalidation_threshold", "dot_xport_unusable_threshold", "dot_xport_unusable_threshold", Loading apex/manifest.json +1 −1 Original line number Original line Diff line number Diff line { { "name": "com.android.resolv", "name": "com.android.resolv", "version": 330510000 "version": 330511000 } } tests/doh/src/dns_https_frontend.rs +4 −2 Original line number Original line Diff line number Diff line Loading @@ -35,8 +35,7 @@ use tokio::task::JoinHandle; lazy_static! { lazy_static! { static ref RUNTIME_STATIC: Arc<Runtime> = Arc::new( static ref RUNTIME_STATIC: Arc<Runtime> = Arc::new( Builder::new_multi_thread() Builder::new_multi_thread() .worker_threads(2) .worker_threads(1) .max_blocking_threads(1) .enable_all() .enable_all() .thread_name("DohFrontend") .thread_name("DohFrontend") .build() .build() Loading Loading @@ -144,6 +143,9 @@ impl DohFrontend { } } worker_thread.abort(); worker_thread.abort(); RUNTIME_STATIC.block_on(async { debug!("worker_thread result: {:?}", worker_thread.await); }) } } debug!("DohFrontend: stopped: {:?}", self); debug!("DohFrontend: stopped: {:?}", self); Loading Loading
DnsTlsDispatcher.cpp +23 −3 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "resolv_cache.h" #include "resolv_cache.h" #include "resolv_private.h" #include "resolv_private.h" #include "stats.pb.h" #include "stats.pb.h" #include "util.h" #include <android-base/logging.h> #include <android-base/logging.h> Loading Loading @@ -243,7 +244,7 @@ DnsTlsTransport::Response DnsTlsDispatcher::query(const DnsTlsServer& server, un void DnsTlsDispatcher::forceCleanup(unsigned netId) { void DnsTlsDispatcher::forceCleanup(unsigned netId) { std::lock_guard guard(sLock); std::lock_guard guard(sLock); cleanup(std::chrono::steady_clock::now(), netId); cleanup(std::chrono::steady_clock::now(), std::chrono::seconds(-1), netId); } } DnsTlsTransport::Result DnsTlsDispatcher::queryInternal(Transport& xport, DnsTlsTransport::Result DnsTlsDispatcher::queryInternal(Transport& xport, Loading Loading @@ -276,22 +277,41 @@ DnsTlsTransport::Result DnsTlsDispatcher::queryInternal(Transport& xport, // This timeout effectively controls how long to keep SSL session tickets. // This timeout effectively controls how long to keep SSL session tickets. static constexpr std::chrono::minutes IDLE_TIMEOUT(5); static constexpr std::chrono::minutes IDLE_TIMEOUT(5); void DnsTlsDispatcher::maybeCleanup(std::chrono::time_point<std::chrono::steady_clock> now) { void DnsTlsDispatcher::maybeCleanup(std::chrono::time_point<std::chrono::steady_clock> now) { // Make the timeout tunable via experiment flag for testing. std::chrono::seconds unusable_xport_idle_timeout{-1}; const int value = Experiments::getInstance()->getFlag("dot_keep_unusable_xport_sec", -1); if (value > -1 && isUserDebugBuild() && std::chrono::seconds(value) < IDLE_TIMEOUT) { unusable_xport_idle_timeout = std::chrono::seconds(value); } // To avoid scanning mStore after every query, return early if a cleanup has been // To avoid scanning mStore after every query, return early if a cleanup has been // performed recently. // performed recently. if (now - mLastCleanup < IDLE_TIMEOUT) { const std::chrono::seconds timeout = (unusable_xport_idle_timeout < IDLE_TIMEOUT) ? unusable_xport_idle_timeout : IDLE_TIMEOUT; if (now - mLastCleanup < timeout) { return; return; } } cleanup(now, std::nullopt); cleanup(now, unusable_xport_idle_timeout, std::nullopt); mLastCleanup = now; mLastCleanup = now; } } void DnsTlsDispatcher::cleanup(std::chrono::time_point<std::chrono::steady_clock> now, void DnsTlsDispatcher::cleanup(std::chrono::time_point<std::chrono::steady_clock> now, std::chrono::seconds unusable_xport_idle_timeout, std::optional<unsigned> netId) { std::optional<unsigned> netId) { std::erase_if(mStore, [&](const auto& item) REQUIRES(sLock) { std::erase_if(mStore, [&](const auto& item) REQUIRES(sLock) { auto const& [_, xport] = item; auto const& [_, xport] = item; if (xport->useCount == 0) { if (xport->useCount == 0) { // Remove the Transports of the associated network. if (netId.has_value() && xport->mNetId == netId.value()) return true; if (netId.has_value() && xport->mNetId == netId.value()) return true; // Remove all expired Transports. if (now - xport->lastUsed > IDLE_TIMEOUT) return true; if (now - xport->lastUsed > IDLE_TIMEOUT) return true; // Unusable Transports should be removed earlier. if (!xport->usable() && unusable_xport_idle_timeout.count() >= 0 && now - xport->lastUsed > unusable_xport_idle_timeout) return true; } } return false; return false; }); }); Loading
DnsTlsDispatcher.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -165,7 +165,8 @@ class DnsTlsDispatcher : public PrivateDnsValidationObserver { // Drop any cache entries whose useCount is zero and which have not been used recently. // Drop any cache entries whose useCount is zero and which have not been used recently. // This function performs a linear scan of mStore. // This function performs a linear scan of mStore. void cleanup(std::chrono::time_point<std::chrono::steady_clock> now, void cleanup(std::chrono::time_point<std::chrono::steady_clock> now, std::optional<unsigned> netId) REQUIRES(sLock); std::chrono::seconds unusable_xport_idle_timeout, std::optional<unsigned> netId) REQUIRES(sLock); // Return a sorted list of usable DnsTlsServers in preference order. // Return a sorted list of usable DnsTlsServers in preference order. std::list<DnsTlsServer> getOrderedAndUsableServerList(const std::list<DnsTlsServer>& tlsServers, std::list<DnsTlsServer> getOrderedAndUsableServerList(const std::list<DnsTlsServer>& tlsServers, Loading
Experiments.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -55,6 +55,7 @@ class Experiments { "sort_nameservers", "sort_nameservers", "dot_async_handshake", "dot_async_handshake", "dot_connect_timeout_ms", "dot_connect_timeout_ms", "dot_keep_unusable_xport_sec", "dot_maxtries", "dot_maxtries", "dot_revalidation_threshold", "dot_revalidation_threshold", "dot_xport_unusable_threshold", "dot_xport_unusable_threshold", Loading
apex/manifest.json +1 −1 Original line number Original line Diff line number Diff line { { "name": "com.android.resolv", "name": "com.android.resolv", "version": 330510000 "version": 330511000 } }
tests/doh/src/dns_https_frontend.rs +4 −2 Original line number Original line Diff line number Diff line Loading @@ -35,8 +35,7 @@ use tokio::task::JoinHandle; lazy_static! { lazy_static! { static ref RUNTIME_STATIC: Arc<Runtime> = Arc::new( static ref RUNTIME_STATIC: Arc<Runtime> = Arc::new( Builder::new_multi_thread() Builder::new_multi_thread() .worker_threads(2) .worker_threads(1) .max_blocking_threads(1) .enable_all() .enable_all() .thread_name("DohFrontend") .thread_name("DohFrontend") .build() .build() Loading Loading @@ -144,6 +143,9 @@ impl DohFrontend { } } worker_thread.abort(); worker_thread.abort(); RUNTIME_STATIC.block_on(async { debug!("worker_thread result: {:?}", worker_thread.await); }) } } debug!("DohFrontend: stopped: {:?}", self); debug!("DohFrontend: stopped: {:?}", self); Loading