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

pull/699/head
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);
}
// Find and set the network device info
for (int i = 0; i < m_networkInfoCache.count(); i++) {
const NetworkDeviceInfo networkDeviceInfo = m_networkInfoCache.at(i);
if (address == QHostAddress::LocalHost || hostName == "localhost") {
// Special case, we create for localhost a networkdevice info, since we are not discovering localhost
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()) {
case NetworkDeviceInfo::MonitorModeMac:
// Search the unique mac address
if (networkDeviceInfo.macAddressInfos().hasMacAddress(internalMonitor->macAddress())) {
qCDebug(dcNetworkDeviceDiscovery()) << "MAC monitor:" << networkDeviceInfo;
internalMonitor->setNetworkDeviceInfo(networkDeviceInfo);
switch (internalMonitor->monitorMode()) {
case NetworkDeviceInfo::MonitorModeMac:
// Search the unique mac address
if (networkDeviceInfo.macAddressInfos().hasMacAddress(internalMonitor->macAddress())) {
qCDebug(dcNetworkDeviceDiscovery()) << "MAC monitor:" << 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.";
// Add the localhost
NetworkDeviceInfo localhostInfo(QHostAddress::LocalHost);
localhostInfo.setHostName("localhost");
m_networkInfoCache.append(localhostInfo);
// We just did some housekeeping while loading from the cache
m_lastCacheHousekeeping = QDateTime::currentDateTime();
}
@ -630,7 +640,7 @@ void NetworkDeviceDiscoveryImpl::removeFromNetworkDeviceCache(const QHostAddress
void NetworkDeviceDiscoveryImpl::saveNetworkDeviceCache(const NetworkDeviceInfo &deviceInfo)
{
if (!deviceInfo.isValid() || !deviceInfo.isComplete())
if (!deviceInfo.isValid() || !deviceInfo.isComplete() || deviceInfo.address() == QHostAddress::LocalHost)
return;
m_cacheSettings->beginGroup("NetworkDeviceInfos");

View File

@ -139,8 +139,6 @@ private:
void processArpTraffic(const QNetworkInterface &interface, const QHostAddress &address, const MacAddress &macAddress);
void testPingMonitor(NetworkDeviceMonitorImpl *monitor);
// Time helpers
bool longerAgoThan(const QDateTime &dateTime, uint minutes);
QDateTime convertMinuteBased(const QDateTime &dateTime = QDateTime());

View File

@ -162,7 +162,9 @@ void Ping::sendNextReply()
return;
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();
QTimer::singleShot(0, this, [=]() {
if (!m_currentReply)
@ -195,8 +197,6 @@ void Ping::performPing(PingReply *reply)
pingAddress.sin_port = 0;
pingAddress.sin_addr.s_addr = *(long*)hostname->h_addr;
QHostAddress targetHostAddress = QHostAddress(qFromBigEndian(pingAddress.sin_addr.s_addr));
// Build the ICMP echo request packet
struct icmpPacket 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();
pingError = PingReply::ErrorHostNameNotFound;
} else {
reply->m_targetHostAddress = info.addresses().first();
reply->m_networkInterface = NetworkUtils::getInterfaceForHostaddress(reply->targetHostAddress());
pingError = PingReply::ErrorNoError;
QHostAddress targetHostAddress;
foreach (const QHostAddress &lookedUpAddress, info.addresses()) {
// 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;
case QHostInfo::HostNotFound: