change networkdetector discovery to do parallel scans instead of sequential ones

otherwise it will hit the timeout if scanning more than 3 target networks
This commit is contained in:
Michael Zanetti 2018-11-05 13:17:56 +01:00
parent c3c4d8c034
commit bb6ec60779
2 changed files with 33 additions and 24 deletions

View File

@ -20,23 +20,29 @@ void Discovery::discoverHosts(int timeout)
} }
m_timeoutTimer.start(timeout * 1000); m_timeoutTimer.start(timeout * 1000);
m_discoveryProcess = new QProcess(this); foreach (const QString &target, getDefaultTargets()) {
connect(m_discoveryProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(discoveryFinished(int,QProcess::ExitStatus))); QProcess *discoveryProcess = new QProcess(this);
m_discoveryProcesses.append(discoveryProcess);
connect(discoveryProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(discoveryFinished(int,QProcess::ExitStatus)));
QStringList arguments; QStringList arguments;
arguments << "-oX" << "-" << "-n" << "-sn"; arguments << "-oX" << "-" << "-n" << "-sn";
arguments << getDefaultTargets(); arguments << target;
qCDebug(dcNetworkDetector) << "Scanning network:" << "nmap" << arguments.join(" ");
discoveryProcess->start(QStringLiteral("nmap"), arguments);
}
qCDebug(dcNetworkDetector) << "Scanning network:" << "nmap" << arguments.join(" ");
m_discoveryProcess->start(QStringLiteral("nmap"), arguments);
} }
void Discovery::abort() void Discovery::abort()
{ {
if (m_discoveryProcess && m_discoveryProcess->state() == QProcess::Running) { foreach (QProcess *discoveryProcess, m_discoveryProcesses) {
qCDebug(dcNetworkDetector()) << "Kill running discovery process"; if (discoveryProcess->state() == QProcess::Running) {
m_discoveryProcess->terminate(); qCDebug(dcNetworkDetector()) << "Kill running discovery process";
m_discoveryProcess->waitForFinished(5000); discoveryProcess->terminate();
discoveryProcess->waitForFinished(5000);
}
} }
foreach (QProcess *p, m_pendingArpLookups.keys()) { foreach (QProcess *p, m_pendingArpLookups.keys()) {
p->terminate(); p->terminate();
@ -50,23 +56,26 @@ void Discovery::abort()
bool Discovery::isRunning() const bool Discovery::isRunning() const
{ {
return m_discoveryProcess != nullptr && m_pendingArpLookups.isEmpty() && m_pendingNameLookups.isEmpty(); return !m_discoveryProcesses.isEmpty() || !m_pendingArpLookups.isEmpty() || !m_pendingNameLookups.isEmpty();
} }
void Discovery::discoveryFinished(int exitCode, QProcess::ExitStatus exitStatus) void Discovery::discoveryFinished(int exitCode, QProcess::ExitStatus exitStatus)
{ {
QProcess *discoveryProcess = static_cast<QProcess*>(sender());
if (exitCode != 0 || exitStatus != QProcess::NormalExit) { if (exitCode != 0 || exitStatus != QProcess::NormalExit) {
qCWarning(dcNetworkDetector()) << "Nmap error failed. Is nmap installed correctly?"; qCWarning(dcNetworkDetector()) << "Nmap error failed. Is nmap installed correctly?";
emit finished({}); emit finished({});
m_discoveryProcess->deleteLater(); m_discoveryProcesses.removeAll(discoveryProcess);
m_discoveryProcess = nullptr; discoveryProcess->deleteLater();
discoveryProcess = nullptr;
return; return;
} }
QByteArray data = m_discoveryProcess->readAll(); QByteArray data = discoveryProcess->readAll();
m_discoveryProcess->deleteLater(); m_discoveryProcesses.removeAll(discoveryProcess);
m_discoveryProcess = nullptr; discoveryProcess->deleteLater();
discoveryProcess = nullptr;
QXmlStreamReader reader(data); QXmlStreamReader reader(data);
@ -128,7 +137,7 @@ void Discovery::discoveryFinished(int exitCode, QProcess::ExitStatus exitStatus)
} }
} }
if (foundHosts == 0) { if (foundHosts == 0 && m_discoveryProcesses.isEmpty()) {
qCDebug(dcNetworkDetector()) << "Network scan successful but no hosts found in this network"; qCDebug(dcNetworkDetector()) << "Network scan successful but no hosts found in this network";
emit finished({}); emit finished({});
} }
@ -179,11 +188,11 @@ void Discovery::arpLookupDone(int exitCode, QProcess::ExitStatus exitStatus)
void Discovery::onTimeout() void Discovery::onTimeout()
{ {
qWarning(dcNetworkDetector()) << "Timeout hit. Stopping discovery"; qWarning(dcNetworkDetector()) << "Timeout hit. Stopping discovery";
if (m_discoveryProcess && m_discoveryProcess->state() == QProcess::Running) { while (!m_discoveryProcesses.isEmpty()) {
QProcess *discoveryProcess = m_discoveryProcesses.takeFirst();
disconnect(this, SLOT(discoveryFinished(int,QProcess::ExitStatus))); disconnect(this, SLOT(discoveryFinished(int,QProcess::ExitStatus)));
m_discoveryProcess->terminate(); discoveryProcess->terminate();
delete m_discoveryProcess; delete discoveryProcess;
m_discoveryProcess = nullptr;
} }
foreach (QProcess *p, m_pendingArpLookups.keys()) { foreach (QProcess *p, m_pendingArpLookups.keys()) {
p->terminate(); p->terminate();
@ -212,7 +221,7 @@ QStringList Discovery::getDefaultTargets()
void Discovery::finishDiscovery() void Discovery::finishDiscovery()
{ {
if (m_pendingNameLookups.count() > 0 || m_pendingArpLookups.count() > 0) { if (m_discoveryProcesses.count() > 0 || m_pendingNameLookups.count() > 0 || m_pendingArpLookups.count() > 0) {
// Still busy... // Still busy...
return; return;
} }

View File

@ -35,7 +35,7 @@ private slots:
void onTimeout(); void onTimeout();
private: private:
QProcess * m_discoveryProcess = nullptr; QList<QProcess*> m_discoveryProcesses;
QTimer m_timeoutTimer; QTimer m_timeoutTimer;
QHash<QProcess*, Host*> m_pendingArpLookups; QHash<QProcess*, Host*> m_pendingArpLookups;