add dumping start of current and queued async dns lookups

Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: Ib40a6d1e3d6e983da674c5a7051ac5e7a565d0d1
This commit is contained in:
Caolán McNamara 2024-05-17 15:05:28 +01:00 committed by Caolán McNamara
parent 3699a0109e
commit 41dc5a6cb4
4 changed files with 82 additions and 19 deletions

View file

@ -34,9 +34,13 @@ public:
static void startAsyncDNS();
static void stopAsyncDNS();
typedef std::function<void(const std::string& hostName, const std::string& exception)> DNSThreadFn;
static void dumpState(std::ostream& os);
static void canonicalHostName(const std::string& addressToCheck, const DNSThreadFn& cb);
typedef std::function<void(const std::string& hostName, const std::string& exception)> DNSThreadFn;
typedef std::function<std::string()> DNSThreadDumpStateFn;
static void canonicalHostName(const std::string& addressToCheck, const DNSThreadFn& cb,
const DNSThreadDumpStateFn& dumpState);
private:
std::atomic<bool> _exit;
@ -48,15 +52,20 @@ private:
{
std::string query;
AsyncDNS::DNSThreadFn cb;
AsyncDNS::DNSThreadDumpStateFn dumpState;
// for now just canonicalHostName lookups
};
std::queue<Lookup> _lookups;
Lookup _activeLookup;
void resolveDNS();
void addLookup(const std::string& lookup, const DNSThreadFn& cb);
void addLookup(const std::string& lookup, const DNSThreadFn& cb,
const DNSThreadDumpStateFn& dumpState);
void startThread();
void joinThread();
void dumpQueueState(std::ostream& os) const;
};
}

View file

@ -169,6 +169,26 @@ void AsyncDNS::joinThread()
_thread.reset();
}
void AsyncDNS::dumpQueueState(std::ostream& os) const
{
// NOT thread-safe
auto activeLookup = _activeLookup;
auto lookups = _lookups;
os << " active lookup: " << (activeLookup.cb ? "true" : "false") << '\n';
if (activeLookup.cb)
{
os << " lookup: " << activeLookup.query << '\n';
os << " callback: " << activeLookup.dumpState() << '\n';
}
os << " queued lookups: " << lookups.size() << '\n';
while (!lookups.empty())
{
os << " lookup: " << lookups.front().query << '\n';
os << " callback: " << lookups.front().dumpState() << '\n';
lookups.pop();
}
}
AsyncDNS::AsyncDNS()
: _resolver(std::make_unique<DNSResolver>())
{
@ -191,7 +211,7 @@ void AsyncDNS::resolveDNS()
if (_exit)
break;
Lookup lookup = _lookups.front();
_activeLookup = _lookups.front();
_lookups.pop();
// Unlock to allow entries to queue up in _lookups while
@ -202,23 +222,26 @@ void AsyncDNS::resolveDNS()
try
{
hostToCheck = _resolver->resolveDNS(lookup.query).name();
hostToCheck = _resolver->resolveDNS(_activeLookup.query).name();
}
catch (const Poco::Exception& exc)
{
exception = "net::canonicalHostName(\"" + lookup.query + "\") failed: " + exc.displayText();
exception = "net::canonicalHostName(\"" + _activeLookup.query + "\") failed: " + exc.displayText();
}
lookup.cb(hostToCheck, exception);
_activeLookup.cb(hostToCheck, exception);
_activeLookup = {};
_lock.lock();
}
}
void AsyncDNS::addLookup(const std::string& lookup, const DNSThreadFn& cb)
void AsyncDNS::addLookup(const std::string& lookup, const DNSThreadFn& cb,
const DNSThreadDumpStateFn& dumpState)
{
std::unique_lock<std::mutex> guard(_lock);
_lookups.emplace(lookup, cb);
_lookups.emplace(lookup, cb, dumpState);
guard.unlock();
_condition.notify_one();
}
@ -231,6 +254,20 @@ void AsyncDNS::startAsyncDNS()
AsyncDNSThread = std::make_unique<AsyncDNS>();
}
//static
void AsyncDNS::dumpState(std::ostream& os)
{
if (AsyncDNSThread)
{
os << "AsyncDNS:\n";
AsyncDNSThread->dumpQueueState(os);
}
else
{
os << "AsyncDNS : doesn't exist.\n";
}
}
//static
void AsyncDNS::stopAsyncDNS()
{
@ -238,9 +275,10 @@ void AsyncDNS::stopAsyncDNS()
}
//static
void AsyncDNS::canonicalHostName(const std::string& addressToCheck, const DNSThreadFn& cb)
void AsyncDNS::canonicalHostName(const std::string& addressToCheck, const DNSThreadFn& cb,
const DNSThreadDumpStateFn& dumpState)
{
AsyncDNSThread->addLookup(addressToCheck, cb);
AsyncDNSThread->addLookup(addressToCheck, cb, dumpState);
}
#endif //!MOBILEAPP

View file

@ -3977,6 +3977,9 @@ public:
// If we have any delaying work going on.
Delay::dumpState(os);
// If we have any DNS work going on.
net::AsyncDNS::dumpState(os);
COOLWSD::SavedClipboards->dumpState(os);
#endif

View file

@ -55,8 +55,8 @@
#include <map>
#include <memory>
#include <queue>
#include <string>
#include <vector>
std::map<std::string, std::string> ClientRequestDispatcher::StaticFileContentCache;
std::unordered_map<std::string, std::shared_ptr<RequestVettingStation>>
@ -375,13 +375,13 @@ getConvertToBrokerImplementation(const std::string& requestType, const std::stri
class ConvertToAddressResolver : public std::enable_shared_from_this<ConvertToAddressResolver>
{
std::shared_ptr<ConvertToAddressResolver> _selfLifecycle;
std::queue<std::string> _addressesToResolve;
std::vector<std::string> _addressesToResolve;
ClientRequestDispatcher::AsyncFn _asyncCb;
bool _allow;
public:
ConvertToAddressResolver(std::queue<std::string> addressesToResolve, ClientRequestDispatcher::AsyncFn asyncCb)
ConvertToAddressResolver(std::vector<std::string> addressesToResolve, ClientRequestDispatcher::AsyncFn asyncCb)
: _addressesToResolve(std::move(addressesToResolve))
, _asyncCb(asyncCb)
, _allow(true)
@ -424,7 +424,7 @@ public:
break;
}
_addressesToResolve.pop();
_addressesToResolve.pop_back();
}
return _allow;
}
@ -437,6 +437,15 @@ public:
dispatchNextLookup();
}
std::string toState() const
{
std::string state = "ConvertToAddressResolver: ";
for (const auto& address : _addressesToResolve)
state += address + ", ";
state += "\n";
return state;
}
void dispatchNextLookup()
{
net::AsyncDNS::DNSThreadFn pushHostnameResolvedToPoll = [this](const std::string& hostname,
@ -446,8 +455,12 @@ public:
});
};
net::AsyncDNS::DNSThreadDumpStateFn dumpState = [this]() -> std::string {
return toState();
};
const std::string& addressToCheck = _addressesToResolve.front();
net::AsyncDNS::canonicalHostName(addressToCheck, pushHostnameResolvedToPoll);
net::AsyncDNS::canonicalHostName(addressToCheck, pushHostnameResolvedToPoll, dumpState);
}
void hostnameResolved(const std::string& hostToCheck, const std::string& exception)
@ -466,7 +479,7 @@ public:
LOG_INF_S("convert-to: Requesting address is allowed: " << addressToCheck);
else
LOG_WRN_S("convert-to: Requesting address is denied: " << addressToCheck);
_addressesToResolve.pop();
_addressesToResolve.pop_back();
// If hostToCheck is not allowed, or there are no addresses
// left to check, then do callback and end
@ -524,7 +537,7 @@ bool ClientRequestDispatcher::allowConvertTo(const std::string& address,
LOG_TRC_S("convert-to: Requesting address is allowed: " << address);
std::queue<std::string> addressesToResolve;
std::vector<std::string> addressesToResolve;
// Handle forwarded header and make sure all participating IPs are allowed
if (request.has("X-Forwarded-For"))
@ -538,7 +551,7 @@ bool ClientRequestDispatcher::allowConvertTo(const std::string& address,
if (!allowPostFrom(addressToCheck))
{
// postpone resolving addresses until later
addressesToResolve.push(addressToCheck);
addressesToResolve.push_back(addressToCheck);
continue;
}