Update ping and monitor handling
This commit is contained in:
parent
abb656016d
commit
341a07cd85
@ -89,7 +89,7 @@ NetworkDeviceDiscoveryImpl::NetworkDeviceDiscoveryImpl(QObject *parent) :
|
|||||||
|
|
||||||
// Timer for updating the monitors
|
// Timer for updating the monitors
|
||||||
m_monitorTimer = new QTimer(this);
|
m_monitorTimer = new QTimer(this);
|
||||||
m_monitorTimer->setInterval(5000);
|
m_monitorTimer->setInterval(10000);
|
||||||
m_monitorTimer->setSingleShot(false);
|
m_monitorTimer->setSingleShot(false);
|
||||||
connect(m_monitorTimer, &QTimer::timeout, this, &NetworkDeviceDiscoveryImpl::evaluateMonitors);
|
connect(m_monitorTimer, &QTimer::timeout, this, &NetworkDeviceDiscoveryImpl::evaluateMonitors);
|
||||||
|
|
||||||
@ -218,58 +218,6 @@ bool NetworkDeviceDiscoveryImpl::running() const
|
|||||||
return m_running;
|
return m_running;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkDeviceMonitor *NetworkDeviceDiscoveryImpl::registerMonitor(const MacAddress &macAddress)
|
|
||||||
// {
|
|
||||||
// if (macAddress.isNull()) {
|
|
||||||
// qCWarning(dcNetworkDeviceDiscovery()) << "Could not register monitor for invalid" << macAddress;
|
|
||||||
// return nullptr;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Make sure we create only one monitor per MAC and keep track how many user
|
|
||||||
// // have access to this monitor otherwise an unregister could cause a crash in
|
|
||||||
// // an other plugin plugin which might still need it
|
|
||||||
// if (m_monitors.contains(macAddress)) {
|
|
||||||
// m_monitorsReferenceCount[macAddress] += 1;
|
|
||||||
// qCInfo(dcNetworkDeviceDiscovery()) << "Register network device monitor for" << macAddress << "which already exists. Returning existing monitor having now" << m_monitorsReferenceCount[macAddress] << "references.";
|
|
||||||
// return m_monitors.value(macAddress);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// qCInfo(dcNetworkDeviceDiscovery()) << "Register new network device monitor for" << macAddress;
|
|
||||||
|
|
||||||
// // Fill in cached information
|
|
||||||
// NetworkDeviceInfo info;
|
|
||||||
// if (m_networkInfoCache.contains(macAddress)) {
|
|
||||||
// info = m_networkInfoCache.value(macAddress);
|
|
||||||
// } else {
|
|
||||||
// info.setMacAddress(macAddress.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// NetworkDeviceMonitorImpl *monitor = new NetworkDeviceMonitorImpl(macAddress, this);
|
|
||||||
// monitor->setNetworkDeviceInfo(info);
|
|
||||||
// monitor->setLastSeen(m_lastSeen.value(macAddress, QDateTime()));
|
|
||||||
// m_monitors.insert(macAddress, monitor);
|
|
||||||
// m_monitorsReferenceCount[macAddress] = 1;
|
|
||||||
|
|
||||||
// if (!available()) {
|
|
||||||
// qCWarning(dcNetworkDeviceDiscovery()) << "Registered monitor but the hardware resource is not available. The monitor will not work as expected" << monitor;
|
|
||||||
// return monitor;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Restart the monitor timer since we evaluate this one now
|
|
||||||
// m_monitorTimer->start();
|
|
||||||
|
|
||||||
// if (!monitor->networkDeviceInfo().isValid()) {
|
|
||||||
// qCDebug(dcNetworkDeviceDiscovery()) << "Adding network device monitor for unresolved mac address. Starting a discovery...";
|
|
||||||
// NetworkDeviceDiscoveryReply *reply = discover();
|
|
||||||
// connect(reply, &NetworkDeviceDiscoveryReply::finished, reply, &NetworkDeviceDiscoveryReply::deleteLater);
|
|
||||||
// } else {
|
|
||||||
// evaluateMonitor(monitor);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// qCDebug(dcNetworkDeviceDiscovery()) << "Registered successfully" << monitor;
|
|
||||||
// return monitor;
|
|
||||||
// }
|
|
||||||
|
|
||||||
NetworkDeviceMonitor *NetworkDeviceDiscoveryImpl::registerMonitor(Thing *thing)
|
NetworkDeviceMonitor *NetworkDeviceDiscoveryImpl::registerMonitor(Thing *thing)
|
||||||
{
|
{
|
||||||
if (!thing->thingClass().interfaces().contains("networkdevice")) {
|
if (!thing->thingClass().interfaces().contains("networkdevice")) {
|
||||||
@ -308,11 +256,14 @@ NetworkDeviceMonitor *NetworkDeviceDiscoveryImpl::registerMonitor(Thing *thing)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool newMonitor = true;
|
||||||
if (internalMonitor) {
|
if (internalMonitor) {
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << "Already have an internal monitor for this network device" << internalMonitor;
|
qCDebug(dcNetworkDeviceDiscovery()) << "Already have an internal monitor for this network device" << internalMonitor;
|
||||||
|
newMonitor = false;
|
||||||
} else {
|
} else {
|
||||||
// Create a new monitor for the internal use
|
// Create a new monitor for the internal use
|
||||||
internalMonitor = new NetworkDeviceMonitorImpl(macAddress, hostName, address, this);
|
internalMonitor = new NetworkDeviceMonitorImpl(macAddress, hostName, address, this);
|
||||||
|
m_monitors.insert(internalMonitor, QVector<NetworkDeviceMonitorImpl*>());
|
||||||
}
|
}
|
||||||
|
|
||||||
internalMonitor->setMonitorMode(mode);
|
internalMonitor->setMonitorMode(mode);
|
||||||
@ -354,7 +305,13 @@ NetworkDeviceMonitor *NetworkDeviceDiscoveryImpl::registerMonitor(Thing *thing)
|
|||||||
|
|
||||||
// Create a new plugin monitor object we are going to return...
|
// Create a new plugin monitor object we are going to return...
|
||||||
NetworkDeviceMonitorImpl *pluginMonitor = createPluginMonitor(internalMonitor);
|
NetworkDeviceMonitorImpl *pluginMonitor = createPluginMonitor(internalMonitor);
|
||||||
|
m_monitors[internalMonitor].append(pluginMonitor);
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << "Registered successfully" << pluginMonitor;
|
qCDebug(dcNetworkDeviceDiscovery()) << "Registered successfully" << pluginMonitor;
|
||||||
|
|
||||||
|
// In case this is a new monitor, let's evaluate it right the way so know asap if the device is reachable or not
|
||||||
|
if (newMonitor)
|
||||||
|
evaluateMonitor(internalMonitor);
|
||||||
|
|
||||||
return pluginMonitor;
|
return pluginMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,6 +331,14 @@ PingReply *NetworkDeviceDiscoveryImpl::ping(const QHostAddress &address, uint re
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PingReply *NetworkDeviceDiscoveryImpl::ping(const QString &hostName, uint retries)
|
||||||
|
{
|
||||||
|
PingReply *reply = m_ping->ping(hostName, retries);
|
||||||
|
// Note: we use any ping used trough this method also for the monitor evaluation
|
||||||
|
watchPingReply(reply);
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
PingReply *NetworkDeviceDiscoveryImpl::ping(const QHostAddress &address, bool lookupHost, uint retries)
|
PingReply *NetworkDeviceDiscoveryImpl::ping(const QHostAddress &address, bool lookupHost, uint retries)
|
||||||
{
|
{
|
||||||
PingReply *reply = m_ping->ping(address, lookupHost, retries);
|
PingReply *reply = m_ping->ping(address, lookupHost, retries);
|
||||||
@ -521,7 +486,35 @@ void NetworkDeviceDiscoveryImpl::processMonitorPingResult(PingReply *reply, Netw
|
|||||||
// Save the last time we tried to communicate
|
// Save the last time we tried to communicate
|
||||||
if (reply->error() == PingReply::ErrorNoError) {
|
if (reply->error() == PingReply::ErrorNoError) {
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << "Ping response from" << monitor << reply->duration() << "ms";
|
qCDebug(dcNetworkDeviceDiscovery()) << "Ping response from" << monitor << reply->duration() << "ms";
|
||||||
monitor->setLastSeen(QDateTime::currentDateTime());
|
|
||||||
|
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||||
|
m_lastSeen[reply->targetHostAddress()] = currentDateTime;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_networkInfoCache.count(); i++) {
|
||||||
|
|
||||||
|
if (monitor->monitorMode() == NetworkDeviceInfo::MonitorModeHostName) {
|
||||||
|
if (m_networkInfoCache.at(i).hostName() == monitor->hostName() && m_networkInfoCache.at(i).address() != reply->targetHostAddress()) {
|
||||||
|
QHostAddress oldAddress = m_networkInfoCache.at(i).address();
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Hostname" << monitor->hostName() << "changed the IP address from"
|
||||||
|
<< oldAddress.toString()
|
||||||
|
<< "-->"
|
||||||
|
<< reply->targetHostAddress().toString();
|
||||||
|
|
||||||
|
removeFromNetworkDeviceCache(oldAddress);
|
||||||
|
|
||||||
|
NetworkDeviceInfo info = m_networkInfoCache.at(i);
|
||||||
|
info.setAddress(reply->targetHostAddress());
|
||||||
|
|
||||||
|
monitor->setNetworkDeviceInfo(info);
|
||||||
|
m_networkInfoCache[i] = info;
|
||||||
|
m_networkInfoCache.sortNetworkDevices();
|
||||||
|
saveNetworkDeviceCache(info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor->setLastSeen(currentDateTime);
|
||||||
monitor->setReachable(true);
|
monitor->setReachable(true);
|
||||||
} else {
|
} else {
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << "Failed to ping device from" << monitor << "retrying" << reply->retries() << "times:" << reply->error();
|
qCDebug(dcNetworkDeviceDiscovery()) << "Failed to ping device from" << monitor << "retrying" << reply->retries() << "times:" << reply->error();
|
||||||
@ -531,29 +524,25 @@ void NetworkDeviceDiscoveryImpl::processMonitorPingResult(PingReply *reply, Netw
|
|||||||
|
|
||||||
void NetworkDeviceDiscoveryImpl::watchPingReply(PingReply *reply)
|
void NetworkDeviceDiscoveryImpl::watchPingReply(PingReply *reply)
|
||||||
{
|
{
|
||||||
connect(reply, &PingReply::finished, this, [=](){
|
connect(reply, &PingReply::finished, this, [this, reply](){
|
||||||
// Search cache for mac address and update last seen
|
if (reply->error() == PingReply::ErrorNoError) {
|
||||||
|
|
||||||
// FIXME
|
int index = m_networkInfoCache.indexFromHostAddress(reply->targetHostAddress());
|
||||||
// if (reply->error() == PingReply::ErrorNoError) {
|
if (index < 0)
|
||||||
// foreach (const NetworkDeviceInfo &info, m_networkInfoCache) {
|
return;
|
||||||
// if (info.address() == reply->targetHostAddress()) {
|
|
||||||
// // Found info for this ip, update the cache
|
|
||||||
// MacAddress macAddress(info.macAddress());
|
|
||||||
// if (!macAddress.isNull() && m_networkInfoCache.contains(macAddress)) {
|
|
||||||
// m_lastSeen[macAddress] = QDateTime::currentDateTime();
|
|
||||||
// saveNetworkDeviceCache(m_networkInfoCache.value(macAddress));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Update any monitor
|
m_lastSeen[reply->targetHostAddress()] = QDateTime::currentDateTime();
|
||||||
// foreach (NetworkDeviceMonitorImpl *monitor, m_monitors.values()) {
|
saveNetworkDeviceCache(m_networkInfoCache.at(index));
|
||||||
// if (monitor->networkDeviceInfo().address() == reply->targetHostAddress()) {
|
}
|
||||||
// processMonitorPingResult(reply, monitor);
|
|
||||||
// }
|
// Update any relevant monitor
|
||||||
// }
|
foreach (NetworkDeviceMonitorImpl *monitor, m_monitors.keys()) {
|
||||||
|
if ((monitor->monitorMode() == NetworkDeviceInfo::MonitorModeIp && reply->targetHostAddress() == monitor->address()) ||
|
||||||
|
(monitor->monitorMode() == NetworkDeviceInfo::MonitorModeHostName && reply->hostName() == monitor->hostName()) ||
|
||||||
|
(monitor->monitorMode() == NetworkDeviceInfo::MonitorModeMac && reply->targetHostAddress() == monitor->networkDeviceInfo().address())) {
|
||||||
|
processMonitorPingResult(reply, monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,7 +551,7 @@ void NetworkDeviceDiscoveryImpl::loadNetworkDeviceCache()
|
|||||||
qCInfo(dcNetworkDeviceDiscovery()) << "Loading cached network device information from" << m_cacheSettings->fileName();
|
qCInfo(dcNetworkDeviceDiscovery()) << "Loading cached network device information from" << m_cacheSettings->fileName();
|
||||||
|
|
||||||
m_networkInfoCache.clear();
|
m_networkInfoCache.clear();
|
||||||
QDateTime now = QDateTime::currentDateTime();
|
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||||
|
|
||||||
uint cacheVersion = m_cacheSettings->value("version", 0).toUInt();
|
uint cacheVersion = m_cacheSettings->value("version", 0).toUInt();
|
||||||
|
|
||||||
@ -579,7 +568,7 @@ void NetworkDeviceDiscoveryImpl::loadNetworkDeviceCache()
|
|||||||
QDateTime lastSeen = QDateTime::fromMSecsSinceEpoch(m_cacheSettings->value("lastSeen").toLongLong());
|
QDateTime lastSeen = QDateTime::fromMSecsSinceEpoch(m_cacheSettings->value("lastSeen").toLongLong());
|
||||||
|
|
||||||
// Remove the info from the cache if not seen fo the last 30 days...
|
// Remove the info from the cache if not seen fo the last 30 days...
|
||||||
if (lastSeen.date().addDays(m_cacheCleanupPeriod) < now.date()) {
|
if (lastSeen.date().addDays(m_cacheCleanupPeriod) < currentDateTime.date()) {
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << "Removing network device cache entry since it did not show up within the last" << m_cacheCleanupPeriod << "days" << address.toString();
|
qCDebug(dcNetworkDeviceDiscovery()) << "Removing network device cache entry since it did not show up within the last" << m_cacheCleanupPeriod << "days" << address.toString();
|
||||||
m_cacheSettings->remove("");
|
m_cacheSettings->remove("");
|
||||||
m_cacheSettings->endGroup(); // mac address
|
m_cacheSettings->endGroup(); // mac address
|
||||||
@ -624,21 +613,6 @@ void NetworkDeviceDiscoveryImpl::loadNetworkDeviceCache()
|
|||||||
m_lastCacheHousekeeping = QDateTime::currentDateTime();
|
m_lastCacheHousekeeping = QDateTime::currentDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkDeviceDiscoveryImpl::removeFromNetworkDeviceCache(const MacAddress &macAddress)
|
|
||||||
{
|
|
||||||
if (macAddress.isNull())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// m_networkInfoCache.remove(macAddress);
|
|
||||||
// m_lastSeen.remove(macAddress);
|
|
||||||
// m_cacheSettings->beginGroup("NetworkDeviceInfos");
|
|
||||||
// m_cacheSettings->beginGroup(macAddress.toString());
|
|
||||||
// m_cacheSettings->remove("");
|
|
||||||
// m_cacheSettings->endGroup(); // mac address
|
|
||||||
// m_cacheSettings->endGroup(); // NetworkDeviceInfos
|
|
||||||
// m_cacheSettings->sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkDeviceDiscoveryImpl::removeFromNetworkDeviceCache(const QHostAddress &address)
|
void NetworkDeviceDiscoveryImpl::removeFromNetworkDeviceCache(const QHostAddress &address)
|
||||||
{
|
{
|
||||||
if (address.isNull())
|
if (address.isNull())
|
||||||
@ -707,17 +681,23 @@ void NetworkDeviceDiscoveryImpl::updateCache(const NetworkDeviceInfo &deviceInfo
|
|||||||
|
|
||||||
void NetworkDeviceDiscoveryImpl::evaluateMonitor(NetworkDeviceMonitorImpl *monitor)
|
void NetworkDeviceDiscoveryImpl::evaluateMonitor(NetworkDeviceMonitorImpl *monitor)
|
||||||
{
|
{
|
||||||
// if (!monitor->networkDeviceInfo().isValid())
|
if (monitor->currentPingReply()) {
|
||||||
// return;
|
qCDebug(dcNetworkDeviceDiscovery()) << "Monitor has still a ping reply pending:" << monitor;
|
||||||
|
|
||||||
|
|
||||||
if (monitor->currentPingReply())
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Evaluate monitor" << monitor;
|
||||||
|
|
||||||
// Start action if we have not seen the device for gracePeriod seconds
|
// Start action if we have not seen the device for gracePeriod seconds
|
||||||
QDateTime currentDateTime = QDateTime::currentDateTime();
|
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||||
|
|
||||||
bool requiresRefresh = false;
|
bool requiresRefresh = false;
|
||||||
|
|
||||||
|
if (!monitor->networkDeviceInfo().isValid()) {
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Network device info not valid for" << monitor;
|
||||||
|
requiresRefresh = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (monitor->lastSeen().isNull()) {
|
if (monitor->lastSeen().isNull()) {
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << monitor << "requires refresh. Not seen since application start.";
|
qCDebug(dcNetworkDeviceDiscovery()) << monitor << "requires refresh. Not seen since application start.";
|
||||||
requiresRefresh = true;
|
requiresRefresh = true;
|
||||||
@ -744,57 +724,85 @@ void NetworkDeviceDiscoveryImpl::evaluateMonitor(NetworkDeviceMonitorImpl *monit
|
|||||||
if (!requiresRefresh)
|
if (!requiresRefresh)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Try to ping first
|
// Try to ping first.
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << monitor << "try to ping" << monitor->networkDeviceInfo().address().toString();
|
|
||||||
PingReply *reply = m_ping->ping(monitor->networkDeviceInfo().address(), monitor->pingRetries());
|
// IMPORTANT: use the ping methods from this object, so the result will automatically
|
||||||
|
// be evaluated for the monitors and cache
|
||||||
|
PingReply *reply = nullptr;
|
||||||
|
if (monitor->monitorMode() == NetworkDeviceInfo::MonitorModeHostName) {
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << monitor << "try to ping" << monitor->hostName();
|
||||||
|
reply = ping(monitor->hostName(), monitor->pingRetries());
|
||||||
|
} else {
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << monitor << "try to ping" << monitor->networkDeviceInfo().address().toString();
|
||||||
|
reply = ping(monitor->networkDeviceInfo().address(), monitor->pingRetries());
|
||||||
|
}
|
||||||
|
|
||||||
monitor->setCurrentPingReply(reply);
|
monitor->setCurrentPingReply(reply);
|
||||||
monitor->setLastConnectionAttempt(currentDateTime);
|
monitor->setLastConnectionAttempt(currentDateTime);
|
||||||
|
|
||||||
connect(reply, &PingReply::retry, monitor, [=](PingReply::Error error, uint retryCount){
|
connect(reply, &PingReply::retry, monitor, [monitor](PingReply::Error error, uint retryCount){
|
||||||
Q_UNUSED(error)
|
Q_UNUSED(error)
|
||||||
Q_UNUSED(retryCount)
|
Q_UNUSED(retryCount)
|
||||||
monitor->setLastConnectionAttempt(QDateTime::currentDateTime());
|
monitor->setLastConnectionAttempt(QDateTime::currentDateTime());
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(reply, &PingReply::destroyed, monitor, [=](){
|
connect(reply, &PingReply::destroyed, monitor, [monitor, reply](){
|
||||||
monitor->setCurrentPingReply(nullptr);
|
if (monitor->currentPingReply() == reply) {
|
||||||
|
monitor->setCurrentPingReply(nullptr);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(reply, &PingReply::finished, monitor, [=](){
|
connect(reply, &PingReply::finished, monitor, [monitor, reply](){
|
||||||
processMonitorPingResult(reply, monitor);
|
if (monitor->currentPingReply() == reply) {
|
||||||
|
monitor->setCurrentPingReply(nullptr);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkDeviceDiscoveryImpl::processArpTraffic(const QNetworkInterface &interface, const QHostAddress &address, const MacAddress &macAddress)
|
void NetworkDeviceDiscoveryImpl::processArpTraffic(const QNetworkInterface &interface, const QHostAddress &address, const MacAddress &macAddress)
|
||||||
{
|
{
|
||||||
QDateTime now = QDateTime::currentDateTime();
|
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||||
// m_lastSeen[macAddress] = now;
|
m_lastSeen[address] = currentDateTime;
|
||||||
|
|
||||||
// FIXME
|
// Update monitors and cache
|
||||||
|
for (int i = 0; i < m_networkInfoCache.count(); i++) {
|
||||||
|
switch (m_networkInfoCache.at(i).monitorMode()) {
|
||||||
|
case NetworkDeviceInfo::MonitorModeMac:
|
||||||
|
if (m_networkInfoCache.at(i).macAddressInfos().hasMacAddress(macAddress) &&
|
||||||
|
m_networkInfoCache.at(i).address() != address) {
|
||||||
|
|
||||||
// if (m_networkInfoCache.hasMacAddress(macAddress)) {
|
QHostAddress oldAddress = m_networkInfoCache.at(i).address();
|
||||||
// if (m_networkInfoCache.value(macAddress).address() != address) {
|
qCDebug(dcNetworkDeviceDiscovery()) << "Host" << macAddress.toString() << "changed the IP address from"
|
||||||
// m_networkInfoCache[macAddress].setAddress(address);
|
<< oldAddress.toString()
|
||||||
// saveNetworkDeviceCache(m_networkInfoCache.value(macAddress));
|
<< "-->"
|
||||||
// }
|
<< address.toString();
|
||||||
// }
|
|
||||||
|
|
||||||
// Update the monitors
|
removeFromNetworkDeviceCache(oldAddress);
|
||||||
// NetworkDeviceMonitorImpl *monitor = m_monitors.value(macAddress);
|
|
||||||
// if (monitor) {
|
|
||||||
// monitor->setLastSeen(now);
|
|
||||||
// if (monitor->networkDeviceInfo().address() != address) {
|
|
||||||
// NetworkDeviceInfo info = monitor->networkDeviceInfo();
|
|
||||||
// info.setAddress(address);
|
|
||||||
// monitor->setNetworkDeviceInfo(info);
|
|
||||||
// qCDebug(dcNetworkDeviceDiscovery()) << "NetworkDeviceMonitor" << monitor << "ip address changed";
|
|
||||||
// emit monitor->networkDeviceInfoChanged(monitor->networkDeviceInfo());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (monitor->networkDeviceInfo().isComplete()) {
|
NetworkDeviceInfo info = m_networkInfoCache.at(i);
|
||||||
// monitor->setReachable(true);
|
info.setAddress(address);
|
||||||
// }
|
|
||||||
// }
|
m_networkInfoCache[i] = info;
|
||||||
|
m_networkInfoCache.sortNetworkDevices();
|
||||||
|
saveNetworkDeviceCache(info);
|
||||||
|
|
||||||
|
foreach (NetworkDeviceMonitorImpl *monitor, m_monitors.keys()) {
|
||||||
|
if (monitor->macAddress() == macAddress) {
|
||||||
|
monitor->setNetworkDeviceInfo(info);
|
||||||
|
monitor->setLastSeen(currentDateTime);
|
||||||
|
monitor->setReachable(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NetworkDeviceInfo::MonitorModeHostName:
|
||||||
|
case NetworkDeviceInfo::MonitorModeIp:
|
||||||
|
saveNetworkDeviceCache(m_networkInfoCache.at(i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if we have currently reply running
|
// Check if we have currently reply running
|
||||||
if (!m_currentDiscoveryReply)
|
if (!m_currentDiscoveryReply)
|
||||||
@ -910,6 +918,7 @@ void NetworkDeviceDiscoveryImpl::cleanupPluginMonitor(NetworkDeviceMonitorImpl *
|
|||||||
foreach (NetworkDeviceMonitorImpl *internalMonitor, m_monitors.keys()) {
|
foreach (NetworkDeviceMonitorImpl *internalMonitor, m_monitors.keys()) {
|
||||||
if (m_monitors.value(internalMonitor).contains(pluginMonitor)) {
|
if (m_monitors.value(internalMonitor).contains(pluginMonitor)) {
|
||||||
m_monitors[internalMonitor].removeAll(pluginMonitor);
|
m_monitors[internalMonitor].removeAll(pluginMonitor);
|
||||||
|
pluginMonitor->deleteLater();
|
||||||
|
|
||||||
if (m_monitors.value(internalMonitor).isEmpty()) {
|
if (m_monitors.value(internalMonitor).isEmpty()) {
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << "No monitor registered for this network device any more. Unregister internal monitor" << internalMonitor;
|
qCDebug(dcNetworkDeviceDiscovery()) << "No monitor registered for this network device any more. Unregister internal monitor" << internalMonitor;
|
||||||
@ -952,7 +961,7 @@ void NetworkDeviceDiscoveryImpl::evaluateMonitors()
|
|||||||
evaluateMonitor(monitor);
|
evaluateMonitor(monitor);
|
||||||
|
|
||||||
// Check if there is any monitor which has not be seen since
|
// Check if there is any monitor which has not be seen since
|
||||||
if (!monitor->reachable() /*&& monitor->lastConnectionAttempt().isValid()*/ && longerAgoThan(monitor->lastSeen(), m_monitorInterval)) {
|
if (!monitor->reachable() && monitor->lastConnectionAttempt().isValid() && longerAgoThan(monitor->lastSeen(), m_monitorInterval)) {
|
||||||
monitorRequiresRediscovery = true;
|
monitorRequiresRediscovery = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -967,7 +976,7 @@ void NetworkDeviceDiscoveryImpl::evaluateMonitors()
|
|||||||
// // Do some cache housekeeping if required
|
// // Do some cache housekeeping if required
|
||||||
// if (m_lastCacheHousekeeping.addDays(1) < QDateTime::currentDateTime()) {
|
// if (m_lastCacheHousekeeping.addDays(1) < QDateTime::currentDateTime()) {
|
||||||
// qCInfo(dcNetworkDeviceDiscovery()) << "Starting cache housekeeping since it is more than one day since the last clanup...";
|
// qCInfo(dcNetworkDeviceDiscovery()) << "Starting cache housekeeping since it is more than one day since the last clanup...";
|
||||||
// QDateTime now = QDateTime::currentDateTime();
|
// QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||||
// foreach (const MacAddress &mac, m_lastSeen.keys()) {
|
// foreach (const MacAddress &mac, m_lastSeen.keys()) {
|
||||||
// // Remove the info from the cache if not seen fo the last 30 days...
|
// // Remove the info from the cache if not seen fo the last 30 days...
|
||||||
// if (m_lastSeen.value(mac).date().addDays(m_cacheCleanupPeriod) < QDateTime::currentDateTime().date()) {
|
// if (m_lastSeen.value(mac).date().addDays(m_cacheCleanupPeriod) < QDateTime::currentDateTime().date()) {
|
||||||
@ -975,7 +984,7 @@ void NetworkDeviceDiscoveryImpl::evaluateMonitors()
|
|||||||
// removeFromNetworkDeviceCache(mac);
|
// removeFromNetworkDeviceCache(mac);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// m_lastCacheHousekeeping = now;
|
// m_lastCacheHousekeeping = currentDateTime;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -71,6 +71,7 @@ public:
|
|||||||
void unregisterMonitor(NetworkDeviceMonitor *networkDeviceMonitor) override;
|
void unregisterMonitor(NetworkDeviceMonitor *networkDeviceMonitor) override;
|
||||||
|
|
||||||
PingReply *ping(const QHostAddress &address, uint retries = 3) override;
|
PingReply *ping(const QHostAddress &address, uint retries = 3) override;
|
||||||
|
PingReply *ping(const QString &hostName, uint retries = 3) override;
|
||||||
PingReply *ping(const QHostAddress &address, bool lookupHost, uint retries = 3);
|
PingReply *ping(const QHostAddress &address, bool lookupHost, uint retries = 3);
|
||||||
|
|
||||||
MacAddressDatabaseReply *lookupMacAddress(const QString &macAddress) override;
|
MacAddressDatabaseReply *lookupMacAddress(const QString &macAddress) override;
|
||||||
@ -138,6 +139,8 @@ private:
|
|||||||
|
|
||||||
void processArpTraffic(const QNetworkInterface &interface, const QHostAddress &address, const MacAddress &macAddress);
|
void processArpTraffic(const QNetworkInterface &interface, const QHostAddress &address, const MacAddress &macAddress);
|
||||||
|
|
||||||
|
void testPingMonitor(NetworkDeviceMonitorImpl *monitor);
|
||||||
|
|
||||||
// Time helpers
|
// Time helpers
|
||||||
bool longerAgoThan(const QDateTime &dateTime, uint minutes);
|
bool longerAgoThan(const QDateTime &dateTime, uint minutes);
|
||||||
QDateTime convertMinuteBased(const QDateTime &dateTime = QDateTime());
|
QDateTime convertMinuteBased(const QDateTime &dateTime = QDateTime());
|
||||||
|
|||||||
@ -61,6 +61,7 @@ public:
|
|||||||
virtual void unregisterMonitor(NetworkDeviceMonitor *networkDeviceMonitor) = 0;
|
virtual void unregisterMonitor(NetworkDeviceMonitor *networkDeviceMonitor) = 0;
|
||||||
|
|
||||||
virtual PingReply *ping(const QHostAddress &address, uint retries = 3) = 0;
|
virtual PingReply *ping(const QHostAddress &address, uint retries = 3) = 0;
|
||||||
|
virtual PingReply *ping(const QString &hostName, uint retries = 3) = 0;
|
||||||
|
|
||||||
virtual MacAddressDatabaseReply *lookupMacAddress(const QString &macAddress) = 0;
|
virtual MacAddressDatabaseReply *lookupMacAddress(const QString &macAddress) = 0;
|
||||||
virtual MacAddressDatabaseReply *lookupMacAddress(const MacAddress &macAddress) = 0;
|
virtual MacAddressDatabaseReply *lookupMacAddress(const MacAddress &macAddress) = 0;
|
||||||
|
|||||||
@ -56,6 +56,17 @@ int NetworkDeviceInfos::indexFromHostAddress(const QHostAddress &address)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int NetworkDeviceInfos::indexFromHostName(const QString &hostName)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < this->size(); i++) {
|
||||||
|
if (at(i).hostName() == hostName) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
QList<int> NetworkDeviceInfos::indexFromMacAddress(const QString &macAddress)
|
QList<int> NetworkDeviceInfos::indexFromMacAddress(const QString &macAddress)
|
||||||
{
|
{
|
||||||
return indexFromMacAddress(MacAddress(macAddress));
|
return indexFromMacAddress(MacAddress(macAddress));
|
||||||
|
|||||||
@ -44,6 +44,7 @@ public:
|
|||||||
NetworkDeviceInfos(const QVector<NetworkDeviceInfo> &other);
|
NetworkDeviceInfos(const QVector<NetworkDeviceInfo> &other);
|
||||||
|
|
||||||
int indexFromHostAddress(const QHostAddress &address);
|
int indexFromHostAddress(const QHostAddress &address);
|
||||||
|
int indexFromHostName(const QString &hostName);
|
||||||
QList<int> indexFromMacAddress(const QString &macAddress);
|
QList<int> indexFromMacAddress(const QString &macAddress);
|
||||||
QList<int> indexFromMacAddress(const MacAddress &macAddress);
|
QList<int> indexFromMacAddress(const MacAddress &macAddress);
|
||||||
|
|
||||||
|
|||||||
@ -141,6 +141,18 @@ PingReply *Ping::ping(const QHostAddress &hostAddress, bool lookupHost, uint ret
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PingReply *Ping::ping(const QString &hostName, uint retries)
|
||||||
|
{
|
||||||
|
// Make first the host lookup, then the ping the first address and save it in the reply
|
||||||
|
PingReply *reply = createReply(hostName);
|
||||||
|
reply->m_retries = retries;
|
||||||
|
|
||||||
|
// Note: due to a Qt bug < 5.9 we need to use old SLOT style and cannot make use of lambda here
|
||||||
|
int lookupId = QHostInfo::lookupHost(hostName, this, SLOT(onHostLookupFinished(QHostInfo)));
|
||||||
|
m_pendingHostAddressLookups.insert(lookupId, reply);
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
void Ping::sendNextReply()
|
void Ping::sendNextReply()
|
||||||
{
|
{
|
||||||
if (m_queueTimer->isActive())
|
if (m_queueTimer->isActive())
|
||||||
@ -150,7 +162,7 @@ void Ping::sendNextReply()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_currentReply = m_replyQueue.dequeue();
|
m_currentReply = m_replyQueue.dequeue();
|
||||||
qCDebug(dcPing()) << "Send next reply " << m_currentReply->targetHostAddress().toString() << QString("0x%1").arg(m_currentReply->requestId(), 4, 16, QChar('0')) << ", " << m_replyQueue.count() << "left in queue";
|
qCDebug(dcPing()).nospace().noquote() << "Send next reply " << m_currentReply->targetHostAddress().toString() << " ID: " << QString("0x%1").arg(m_currentReply->requestId(), 4, 16, QChar('0')) << ", " << m_replyQueue.count() << "left in queue";
|
||||||
m_queueTimer->start();
|
m_queueTimer->start();
|
||||||
QTimer::singleShot(0, this, [=]() {
|
QTimer::singleShot(0, this, [=]() {
|
||||||
if (!m_currentReply)
|
if (!m_currentReply)
|
||||||
@ -209,8 +221,8 @@ void Ping::performPing(PingReply *reply)
|
|||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcPingTraffic()) << "Send ICMP echo request" << reply->targetHostAddress().toString() << ICMP_PACKET_SIZE << "[Bytes]"
|
qCDebug(dcPingTraffic()) << "Send ICMP echo request" << reply->targetHostAddress().toString() << ICMP_PACKET_SIZE << "[Bytes]"
|
||||||
<< "ID:" << QString("0x%1").arg(reply->requestId(), 4, 16, QChar('0'))
|
<< "ID:" << QString("0x%1").arg(reply->requestId(), 4, 16, QChar('0'))
|
||||||
<< "Sequence:" << reply->sequenceNumber();
|
<< "Sequence:" << reply->sequenceNumber();
|
||||||
|
|
||||||
// Send packet to the target ip
|
// Send packet to the target ip
|
||||||
int bytesSent = sendto(m_socketDescriptor, &requestPacket, sizeof(requestPacket), 0, (struct sockaddr *)&pingAddress, sizeof(pingAddress));
|
int bytesSent = sendto(m_socketDescriptor, &requestPacket, sizeof(requestPacket), 0, (struct sockaddr *)&pingAddress, sizeof(pingAddress));
|
||||||
@ -329,14 +341,43 @@ PingReply *Ping::createReply(const QHostAddress &hostAddress)
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PingReply *Ping::createReply(const QString &hostName)
|
||||||
|
{
|
||||||
|
PingReply *reply = new PingReply(this);
|
||||||
|
reply->m_hostName = hostName;
|
||||||
|
|
||||||
|
connect(reply, &PingReply::timeout, this, [=](){
|
||||||
|
// Note: this is not the ICMP timeout, here we actually got nothing from anybody...
|
||||||
|
finishReply(reply, PingReply::ErrorTimeout);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(reply, &PingReply::aborted, this, [=](){
|
||||||
|
finishReply(reply, PingReply::ErrorAborted);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(reply, &PingReply::finished, this, [=](){
|
||||||
|
cleanUpReply(reply);
|
||||||
|
reply->deleteLater();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Just in case the reply get's deleted before beeing able to finish ...
|
||||||
|
connect(reply, &PingReply::destroyed, this, [this, reply](){
|
||||||
|
cleanUpReply(reply);
|
||||||
|
});
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
void Ping::finishReply(PingReply *reply, PingReply::Error error)
|
void Ping::finishReply(PingReply *reply, PingReply::Error error)
|
||||||
{
|
{
|
||||||
// Check if we should retry
|
// Check if we should retry
|
||||||
if (reply->m_retryCount >= reply->m_retries ||
|
if (reply->m_retryCount >= reply->m_retries ||
|
||||||
error == PingReply::ErrorNoError ||
|
error == PingReply::ErrorNoError ||
|
||||||
error == PingReply::ErrorAborted ||
|
error == PingReply::ErrorAborted ||
|
||||||
error == PingReply::ErrorInvalidHostAddress ||
|
error == PingReply::ErrorInvalidHostAddress ||
|
||||||
error == PingReply::ErrorPermissionDenied) {
|
error == PingReply::ErrorPermissionDenied||
|
||||||
|
error == PingReply::ErrorHostNameLookupFailed ||
|
||||||
|
error == PingReply::ErrorHostNameNotFound) {
|
||||||
// No retry, we are done
|
// No retry, we are done
|
||||||
reply->m_error = error;
|
reply->m_error = error;
|
||||||
reply->m_timer->stop();
|
reply->m_timer->stop();
|
||||||
@ -374,11 +415,11 @@ void Ping::cleanUpReply(PingReply *reply)
|
|||||||
m_pendingReplies.remove(reply->requestId());
|
m_pendingReplies.remove(reply->requestId());
|
||||||
m_replyQueue.removeAll(reply);
|
m_replyQueue.removeAll(reply);
|
||||||
|
|
||||||
if (m_pendingHostLookups.values().contains(reply)) {
|
if (m_pendingHostNameLookups.values().contains(reply)) {
|
||||||
// Abort any pending host lookups, the reply has been finished
|
// Abort any pending host lookups, the reply has been finished
|
||||||
int lookupId = m_pendingHostLookups.key(reply);
|
int lookupId = m_pendingHostNameLookups.key(reply);
|
||||||
QHostInfo::abortHostLookup(lookupId);
|
QHostInfo::abortHostLookup(lookupId);
|
||||||
m_pendingHostLookups.remove(lookupId);
|
m_pendingHostNameLookups.remove(lookupId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,19 +445,19 @@ void Ping::onSocketReadyRead(int socketDescriptor)
|
|||||||
QHostAddress destinationAddress(qFromBigEndian(ipHeader->daddr));
|
QHostAddress destinationAddress(qFromBigEndian(ipHeader->daddr));
|
||||||
|
|
||||||
qCDebug(dcPingTraffic()) << "IP header: Lenght" << ipHeaderLength
|
qCDebug(dcPingTraffic()) << "IP header: Lenght" << ipHeaderLength
|
||||||
<< "Sender:" << senderAddress.toString()
|
<< "Sender:" << senderAddress.toString()
|
||||||
<< "Destination:" << destinationAddress.toString()
|
<< "Destination:" << destinationAddress.toString()
|
||||||
<< "Size:" << htons(ipHeader->tot_len) << "B"
|
<< "Size:" << htons(ipHeader->tot_len) << "B"
|
||||||
<< "TTL" << ipHeader->ttl;
|
<< "TTL" << ipHeader->ttl;
|
||||||
|
|
||||||
struct icmp *responsePacket = reinterpret_cast<struct icmp *>(receiveBuffer + ipHeaderLength);
|
struct icmp *responsePacket = reinterpret_cast<struct icmp *>(receiveBuffer + ipHeaderLength);
|
||||||
quint16 icmpId = htons(responsePacket->icmp_id);
|
quint16 icmpId = htons(responsePacket->icmp_id);
|
||||||
quint16 icmpSequnceNumber = htons(responsePacket->icmp_seq);
|
quint16 icmpSequnceNumber = htons(responsePacket->icmp_seq);
|
||||||
qCDebug(dcPingTraffic()) << "ICMP packt (Size:" << icmpPacketSize << "Bytes):"
|
qCDebug(dcPingTraffic()) << "ICMP packt (Size:" << icmpPacketSize << "Bytes):"
|
||||||
<< "Type" << responsePacket->icmp_type
|
<< "Type" << responsePacket->icmp_type
|
||||||
<< "Code:" << responsePacket->icmp_code
|
<< "Code:" << responsePacket->icmp_code
|
||||||
<< "ID:" << QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
|
<< "ID:" << QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
|
||||||
<< "Sequence:" << icmpSequnceNumber;
|
<< "Sequence:" << icmpSequnceNumber;
|
||||||
|
|
||||||
if (responsePacket->icmp_type == ICMP_ECHOREPLY) {
|
if (responsePacket->icmp_type == ICMP_ECHOREPLY) {
|
||||||
|
|
||||||
@ -447,14 +488,14 @@ void Ping::onSocketReadyRead(int socketDescriptor)
|
|||||||
reply->m_duration = qRound((receiveTimeValue.tv_sec * 1000 + (double)receiveTimeValue.tv_usec / 1000) * 100) / 100.0;
|
reply->m_duration = qRound((receiveTimeValue.tv_sec * 1000 + (double)receiveTimeValue.tv_usec / 1000) * 100) / 100.0;
|
||||||
|
|
||||||
qCDebug(dcPing()) << "Received ICMP response" << reply->targetHostAddress().toString() << ICMP_PACKET_SIZE << "[Bytes]"
|
qCDebug(dcPing()) << "Received ICMP response" << reply->targetHostAddress().toString() << ICMP_PACKET_SIZE << "[Bytes]"
|
||||||
<< "ID:" << QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
|
<< "ID:" << QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
|
||||||
<< "Sequence:" << icmpSequnceNumber
|
<< "Sequence:" << icmpSequnceNumber
|
||||||
<< "Time:" << reply->duration() << "[ms]";
|
<< "Time:" << reply->duration() << "[ms]";
|
||||||
|
|
||||||
if (reply->doHostLookup()) {
|
if (reply->doHostLookup()) {
|
||||||
// Note: due to a Qt bug < 5.9 we need to use old SLOT style and cannot make use of lambda here
|
// Note: due to a Qt bug < 5.9 we need to use old SLOT style and cannot make use of lambda here
|
||||||
int lookupId = QHostInfo::lookupHost(senderAddress.toString(), this, SLOT(onHostLookupFinished(QHostInfo)));
|
int lookupId = QHostInfo::lookupHost(senderAddress.toString(), this, SLOT(onHostLookupFinished(QHostInfo)));
|
||||||
m_pendingHostLookups.insert(lookupId, reply);
|
m_pendingHostNameLookups.insert(lookupId, reply);
|
||||||
// Finish the reply after the host lookup has finished
|
// Finish the reply after the host lookup has finished
|
||||||
} else {
|
} else {
|
||||||
finishReply(reply, PingReply::ErrorNoError);
|
finishReply(reply, PingReply::ErrorNoError);
|
||||||
@ -472,20 +513,20 @@ void Ping::onSocketReadyRead(int socketDescriptor)
|
|||||||
QHostAddress nestedDestinationAddress(qFromBigEndian(nestedIpHeader->daddr));
|
QHostAddress nestedDestinationAddress(qFromBigEndian(nestedIpHeader->daddr));
|
||||||
|
|
||||||
qCDebug(dcPingTraffic()) << "++ IP header: Lenght" << nestedIpHeaderLength
|
qCDebug(dcPingTraffic()) << "++ IP header: Lenght" << nestedIpHeaderLength
|
||||||
<< "Sender:" << nestedSenderAddress.toString()
|
<< "Sender:" << nestedSenderAddress.toString()
|
||||||
<< "Destination:" << nestedDestinationAddress.toString()
|
<< "Destination:" << nestedDestinationAddress.toString()
|
||||||
<< "Size:" << htons(nestedIpHeader->tot_len) << "B"
|
<< "Size:" << htons(nestedIpHeader->tot_len) << "B"
|
||||||
<< "TTL" << ipHeader->ttl;
|
<< "TTL" << ipHeader->ttl;
|
||||||
|
|
||||||
struct icmp *nestedResponsePacket = reinterpret_cast<struct icmp *>(receiveBuffer + messageOffset + nestedIpHeaderLength);
|
struct icmp *nestedResponsePacket = reinterpret_cast<struct icmp *>(receiveBuffer + messageOffset + nestedIpHeaderLength);
|
||||||
icmpId = htons(nestedResponsePacket->icmp_id);
|
icmpId = htons(nestedResponsePacket->icmp_id);
|
||||||
icmpSequnceNumber = htons(nestedResponsePacket->icmp_seq);
|
icmpSequnceNumber = htons(nestedResponsePacket->icmp_seq);
|
||||||
|
|
||||||
qCDebug(dcPingTraffic()) << "++ ICMP packt (Size:" << nestedIcmpPacketSize << "Bytes):"
|
qCDebug(dcPingTraffic()) << "++ ICMP packt (Size:" << nestedIcmpPacketSize << "Bytes):"
|
||||||
<< "Type" << nestedResponsePacket->icmp_type
|
<< "Type" << nestedResponsePacket->icmp_type
|
||||||
<< "Code:" << nestedResponsePacket->icmp_code
|
<< "Code:" << nestedResponsePacket->icmp_code
|
||||||
<< "ID:" << QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
|
<< "ID:" << QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
|
||||||
<< "Sequence:" << icmpSequnceNumber;
|
<< "Sequence:" << icmpSequnceNumber;
|
||||||
|
|
||||||
qCDebug(dcPing()) << "ICMP destination unreachable" << nestedDestinationAddress.toString()
|
qCDebug(dcPing()) << "ICMP destination unreachable" << nestedDestinationAddress.toString()
|
||||||
<< "Code:" << nestedResponsePacket->icmp_code
|
<< "Code:" << nestedResponsePacket->icmp_code
|
||||||
@ -495,9 +536,9 @@ void Ping::onSocketReadyRead(int socketDescriptor)
|
|||||||
PingReply *reply = m_pendingReplies.value(icmpId);
|
PingReply *reply = m_pendingReplies.value(icmpId);
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
qCDebug(dcPingTraffic()) << "No pending reply for ping echo response unreachable with ID"
|
qCDebug(dcPingTraffic()) << "No pending reply for ping echo response unreachable with ID"
|
||||||
<< QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
|
<< QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
|
||||||
<< "Sequence:" << icmpSequnceNumber
|
<< "Sequence:" << icmpSequnceNumber
|
||||||
<< "from" << nestedSenderAddress.toString() << "to" << nestedDestinationAddress.toString();
|
<< "from" << nestedSenderAddress.toString() << "to" << nestedDestinationAddress.toString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,20 +549,74 @@ void Ping::onSocketReadyRead(int socketDescriptor)
|
|||||||
|
|
||||||
void Ping::onHostLookupFinished(const QHostInfo &info)
|
void Ping::onHostLookupFinished(const QHostInfo &info)
|
||||||
{
|
{
|
||||||
PingReply *reply = m_pendingHostLookups.value(info.lookupId());
|
if (m_pendingHostNameLookups.contains(info.lookupId())) {
|
||||||
if (!reply) {
|
|
||||||
qCWarning(dcPing()) << "Could not find reply after host lookup.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.error() != QHostInfo::NoError) {
|
PingReply *reply = m_pendingHostNameLookups.take(info.lookupId());
|
||||||
qCWarning(dcPing()) << "Failed to look up hostname after successfull ping" << reply->targetHostAddress().toString() << info.error();
|
if (!reply) {
|
||||||
} else {
|
qCWarning(dcPing()) << "Could not find ping reply after finished host lookup" << info.hostName() << info.addresses() << info.errorString();
|
||||||
qCDebug(dcPing()) << "Looked up hostname after successfull ping" << reply->targetHostAddress().toString() << info.hostName();
|
return;
|
||||||
if (info.hostName() != reply->targetHostAddress().toString()) {
|
|
||||||
reply->m_hostName = info.hostName();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
finishReply(reply, PingReply::ErrorNoError);
|
PingReply::Error pingError = PingReply::ErrorNoError;
|
||||||
|
switch(info.error()) {
|
||||||
|
case QHostInfo::NoError:
|
||||||
|
qCDebug(dcPing()) << "Looked up hostname after successfull ping" << reply->targetHostAddress().toString() << info.hostName();
|
||||||
|
if (info.hostName() != reply->targetHostAddress().toString())
|
||||||
|
reply->m_hostName = info.hostName();
|
||||||
|
|
||||||
|
break;
|
||||||
|
case QHostInfo::HostNotFound:
|
||||||
|
qCWarning(dcPing()) << "Unable to find hostname:" << reply->hostName() << info.errorString();
|
||||||
|
pingError = PingReply::ErrorHostNameNotFound;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qCWarning(dcPing()) << "Failed to lookup hostname" << (reply->targetHostAddress().isNull() ? reply->hostName() : reply->targetHostAddress().toString()) << info.errorString();
|
||||||
|
pingError = PingReply::ErrorHostNameLookupFailed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
finishReply(reply, pingError);
|
||||||
|
|
||||||
|
} else if (m_pendingHostAddressLookups.contains(info.lookupId())) {
|
||||||
|
|
||||||
|
PingReply *reply = m_pendingHostAddressLookups.take(info.lookupId());
|
||||||
|
if (!reply) {
|
||||||
|
qCWarning(dcPing()) << "Could not find ping reply after finished host lookup" << info.hostName() << info.addresses() << info.errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PingReply::Error pingError = PingReply::ErrorNoError;
|
||||||
|
switch(info.error()) {
|
||||||
|
case QHostInfo::NoError:
|
||||||
|
qCDebug(dcPing()) << "Looked up address for hostname finished successfully" << info.hostName() << info.addresses();
|
||||||
|
if (info.addresses().isEmpty()) {
|
||||||
|
qCWarning(dcPing()) << "Looked up address finished succesfully but there are no addresses available for" << info.hostName();
|
||||||
|
pingError = PingReply::ErrorHostNameNotFound;
|
||||||
|
} else {
|
||||||
|
reply->m_targetHostAddress = info.addresses().first();
|
||||||
|
reply->m_networkInterface = NetworkUtils::getInterfaceForHostaddress(reply->targetHostAddress());
|
||||||
|
pingError = PingReply::ErrorNoError;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QHostInfo::HostNotFound:
|
||||||
|
qCDebug(dcPing()) << "Unable to find hostname:" << reply->hostName() << info.errorString();
|
||||||
|
pingError = PingReply::ErrorHostNameNotFound;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qCWarning(dcPing()) << "Failed to lookup hostname" << (reply->targetHostAddress().isNull() ? reply->hostName() : reply->targetHostAddress().toString()) << info.errorString();
|
||||||
|
pingError = PingReply::ErrorHostNameLookupFailed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pingError != PingReply::ErrorNoError) {
|
||||||
|
// Host lookup failed, we cannot continue, nothing to ping
|
||||||
|
finishReply(reply, pingError);
|
||||||
|
} else {
|
||||||
|
// Ping the resolved host address
|
||||||
|
m_replyQueue.enqueue(reply);
|
||||||
|
sendNextReply();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qCWarning(dcPing()) << "Host name lookup finished but we have no ping reply for it. Ignoring looked up information" << info.hostName() << info.addresses() << info.error();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,6 +67,8 @@ public:
|
|||||||
PingReply *ping(const QHostAddress &hostAddress, uint retries = 3);
|
PingReply *ping(const QHostAddress &hostAddress, uint retries = 3);
|
||||||
PingReply *ping(const QHostAddress &hostAddress, bool lookupHost, uint retries = 3);
|
PingReply *ping(const QHostAddress &hostAddress, bool lookupHost, uint retries = 3);
|
||||||
|
|
||||||
|
PingReply *ping(const QString &hostName, uint retries = 3);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void availableChanged(bool available);
|
void availableChanged(bool available);
|
||||||
|
|
||||||
@ -91,7 +93,8 @@ private:
|
|||||||
QTimer *m_queueTimer = nullptr;
|
QTimer *m_queueTimer = nullptr;
|
||||||
PingReply *m_currentReply = nullptr;
|
PingReply *m_currentReply = nullptr;
|
||||||
void sendNextReply();
|
void sendNextReply();
|
||||||
QHash<int, PingReply *> m_pendingHostLookups;
|
QHash<int, PingReply *> m_pendingHostNameLookups;
|
||||||
|
QHash<int, PingReply *> m_pendingHostAddressLookups;
|
||||||
|
|
||||||
//Error performPing(const QString &address);
|
//Error performPing(const QString &address);
|
||||||
void performPing(PingReply *reply);
|
void performPing(PingReply *reply);
|
||||||
@ -104,13 +107,13 @@ private:
|
|||||||
quint16 calculateRequestId();
|
quint16 calculateRequestId();
|
||||||
|
|
||||||
PingReply *createReply(const QHostAddress &hostAddress);
|
PingReply *createReply(const QHostAddress &hostAddress);
|
||||||
|
PingReply *createReply(const QString &hostName);
|
||||||
void finishReply(PingReply *reply, PingReply::Error error);
|
void finishReply(PingReply *reply, PingReply::Error error);
|
||||||
void cleanUpReply(PingReply *reply);
|
void cleanUpReply(PingReply *reply);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onSocketReadyRead(int socketDescriptor);
|
void onSocketReadyRead(int socketDescriptor);
|
||||||
void onHostLookupFinished(const QHostInfo &info);
|
void onHostLookupFinished(const QHostInfo &info);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PING_H
|
#endif // PING_H
|
||||||
|
|||||||
@ -59,7 +59,9 @@ public:
|
|||||||
ErrorSocketError,
|
ErrorSocketError,
|
||||||
ErrorTimeout,
|
ErrorTimeout,
|
||||||
ErrorHostUnreachable,
|
ErrorHostUnreachable,
|
||||||
ErrorInvalidHostAddress
|
ErrorInvalidHostAddress,
|
||||||
|
ErrorHostNameLookupFailed,
|
||||||
|
ErrorHostNameNotFound
|
||||||
};
|
};
|
||||||
Q_ENUM(Error)
|
Q_ENUM(Error)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user