NetworkDiscovery: Fix localhost lookup and prevent usage of IPv6 on host lookup

This commit is contained in:
Simon Stürz 2025-04-14 13:48:06 +02:00
parent 00fc81405b
commit 633ee99d0b
3 changed files with 55 additions and 33 deletions

View File

@ -274,32 +274,37 @@ NetworkDeviceMonitor *NetworkDeviceDiscoveryImpl::registerMonitor(Thing *thing)
connect(reply, &NetworkDeviceDiscoveryReply::finished, reply, &NetworkDeviceDiscoveryReply::deleteLater); connect(reply, &NetworkDeviceDiscoveryReply::finished, reply, &NetworkDeviceDiscoveryReply::deleteLater);
} }
// Find and set the network device info if (address == QHostAddress::LocalHost || hostName == "localhost") {
for (int i = 0; i < m_networkInfoCache.count(); i++) { // Special case, we create for localhost a networkdevice info, since we are not discovering localhost
const NetworkDeviceInfo networkDeviceInfo = m_networkInfoCache.at(i); internalMonitor->setNetworkDeviceInfo(NetworkDeviceInfo(QHostAddress("127.0.0.1")));
} else {
// Find and set the network device info
for (int i = 0; i < m_networkInfoCache.count(); i++) {
const NetworkDeviceInfo networkDeviceInfo = m_networkInfoCache.at(i);
switch (internalMonitor->monitorMode()) { switch (internalMonitor->monitorMode()) {
case NetworkDeviceInfo::MonitorModeMac: case NetworkDeviceInfo::MonitorModeMac:
// Search the unique mac address // Search the unique mac address
if (networkDeviceInfo.macAddressInfos().hasMacAddress(internalMonitor->macAddress())) { if (networkDeviceInfo.macAddressInfos().hasMacAddress(internalMonitor->macAddress())) {
qCDebug(dcNetworkDeviceDiscovery()) << "MAC monitor:" << networkDeviceInfo; qCDebug(dcNetworkDeviceDiscovery()) << "MAC monitor:" << networkDeviceInfo;
internalMonitor->setNetworkDeviceInfo(networkDeviceInfo); internalMonitor->setNetworkDeviceInfo(networkDeviceInfo);
}
break;
case NetworkDeviceInfo::MonitorModeHostName:
// Search the hostname in the cache
if (networkDeviceInfo.hostName() == internalMonitor->hostName()) {
qCDebug(dcNetworkDeviceDiscovery()) << "Host name monitor:" << networkDeviceInfo;
internalMonitor->setNetworkDeviceInfo(networkDeviceInfo);
}
break;
case NetworkDeviceInfo::MonitorModeIp:
// Search the IP in the cache
if (networkDeviceInfo.address() == internalMonitor->address()) {
qCDebug(dcNetworkDeviceDiscovery()) << "IP monitor:" << networkDeviceInfo;
internalMonitor->setNetworkDeviceInfo(networkDeviceInfo);
}
break;
} }
break;
case NetworkDeviceInfo::MonitorModeHostName:
// Search the hostname in the cache
if (networkDeviceInfo.hostName() == internalMonitor->hostName()) {
qCDebug(dcNetworkDeviceDiscovery()) << "Host name monitor:" << networkDeviceInfo;
internalMonitor->setNetworkDeviceInfo(networkDeviceInfo);
}
break;
case NetworkDeviceInfo::MonitorModeIp:
// Search the IP in the cache
if (networkDeviceInfo.address() == internalMonitor->address()) {
qCDebug(dcNetworkDeviceDiscovery()) << "IP monitor:" << networkDeviceInfo;
internalMonitor->setNetworkDeviceInfo(networkDeviceInfo);
}
break;
} }
} }
@ -609,6 +614,11 @@ void NetworkDeviceDiscoveryImpl::loadNetworkDeviceCache()
qCInfo(dcNetworkDeviceDiscovery()) << "Loaded" << m_networkInfoCache.count() << "network device infos from cache."; qCInfo(dcNetworkDeviceDiscovery()) << "Loaded" << m_networkInfoCache.count() << "network device infos from cache.";
// Add the localhost
NetworkDeviceInfo localhostInfo(QHostAddress::LocalHost);
localhostInfo.setHostName("localhost");
m_networkInfoCache.append(localhostInfo);
// We just did some housekeeping while loading from the cache // We just did some housekeeping while loading from the cache
m_lastCacheHousekeeping = QDateTime::currentDateTime(); m_lastCacheHousekeeping = QDateTime::currentDateTime();
} }
@ -630,7 +640,7 @@ void NetworkDeviceDiscoveryImpl::removeFromNetworkDeviceCache(const QHostAddress
void NetworkDeviceDiscoveryImpl::saveNetworkDeviceCache(const NetworkDeviceInfo &deviceInfo) void NetworkDeviceDiscoveryImpl::saveNetworkDeviceCache(const NetworkDeviceInfo &deviceInfo)
{ {
if (!deviceInfo.isValid() || !deviceInfo.isComplete()) if (!deviceInfo.isValid() || !deviceInfo.isComplete() || deviceInfo.address() == QHostAddress::LocalHost)
return; return;
m_cacheSettings->beginGroup("NetworkDeviceInfos"); m_cacheSettings->beginGroup("NetworkDeviceInfos");

View File

@ -139,8 +139,6 @@ 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());

View File

@ -162,7 +162,9 @@ void Ping::sendNextReply()
return; return;
m_currentReply = m_replyQueue.dequeue(); m_currentReply = m_replyQueue.dequeue();
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"; 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)
@ -195,8 +197,6 @@ void Ping::performPing(PingReply *reply)
pingAddress.sin_port = 0; pingAddress.sin_port = 0;
pingAddress.sin_addr.s_addr = *(long*)hostname->h_addr; pingAddress.sin_addr.s_addr = *(long*)hostname->h_addr;
QHostAddress targetHostAddress = QHostAddress(qFromBigEndian(pingAddress.sin_addr.s_addr));
// Build the ICMP echo request packet // Build the ICMP echo request packet
struct icmpPacket requestPacket; struct icmpPacket requestPacket;
memset(&requestPacket, 0, sizeof(requestPacket)); memset(&requestPacket, 0, sizeof(requestPacket));
@ -593,9 +593,23 @@ void Ping::onHostLookupFinished(const QHostInfo &info)
qCWarning(dcPing()) << "Looked up address finished succesfully but there are no addresses available for" << info.hostName(); qCWarning(dcPing()) << "Looked up address finished succesfully but there are no addresses available for" << info.hostName();
pingError = PingReply::ErrorHostNameNotFound; pingError = PingReply::ErrorHostNameNotFound;
} else { } else {
reply->m_targetHostAddress = info.addresses().first(); QHostAddress targetHostAddress;
reply->m_networkInterface = NetworkUtils::getInterfaceForHostaddress(reply->targetHostAddress()); foreach (const QHostAddress &lookedUpAddress, info.addresses()) {
pingError = PingReply::ErrorNoError; // Select the first valid IPv4 address, skip IPv6
if (!lookedUpAddress.isNull() && lookedUpAddress.protocol() == QAbstractSocket::IPv4Protocol) {
targetHostAddress = lookedUpAddress;
break;
}
}
if (targetHostAddress.isNull()) {
qCDebug(dcPing()) << "No IPv4 address found in looked up addresses:" << reply->hostName() << info.addresses();
pingError = PingReply::ErrorHostNameNotFound;
} else {
reply->m_targetHostAddress = targetHostAddress;
reply->m_networkInterface = NetworkUtils::getInterfaceForHostaddress(reply->targetHostAddress());
pingError = PingReply::ErrorNoError;
}
} }
break; break;
case QHostInfo::HostNotFound: case QHostInfo::HostNotFound: