void ServerPool::SelectDefaultListen(bool force) { if (!force) { QReadLocker rlock(&naLock); if (!naList_4.isEmpty() || !naList_6.isEmpty()) // lists are already populated, do nothing return; } QWriteLocker wlock(&naLock); naList_4.clear(); naList_6.clear(); // populate stored IPv4 and IPv6 addresses QHostAddress config_v4(gCoreContext->resolveSettingAddress( "BackendServerIP", QString(), gCoreContext->ResolveIPv4, true)); bool v4IsSet = config_v4.isNull() ? true : false; #if !defined(QT_NO_IPV6) QHostAddress config_v6(gCoreContext->resolveSettingAddress( "BackendServerIP6", QString(), gCoreContext->ResolveIPv6, true)); bool v6IsSet = config_v6.isNull() ? true : false; #endif bool allowLinkLocal = gCoreContext->GetNumSetting("AllowLinkLocal", true) > 0; // loop through all available interfaces QList<QNetworkInterface> IFs = QNetworkInterface::allInterfaces(); QList<QNetworkInterface>::const_iterator qni; for (qni = IFs.begin(); qni != IFs.end(); ++qni) { if ((qni->flags() & QNetworkInterface::IsRunning) == 0) continue; QList<QNetworkAddressEntry> IPs = qni->addressEntries(); QList<QNetworkAddressEntry>::iterator qnai; for (qnai = IPs.begin(); qnai != IPs.end(); ++qnai) { QHostAddress ip = qnai->ip(); #if !defined(QT_NO_IPV6) if (ip.protocol() == QAbstractSocket::IPv4Protocol) { #endif if (naList_4.contains(*qnai)) // already defined, skip continue; else if (!config_v4.isNull() && (ip == config_v4)) { // IPv4 address is defined, add it LOG(VB_GENERAL, LOG_DEBUG, QString("Adding BackendServerIP to address list.")); naList_4.append(*qnai); v4IsSet = true; } else if (ip == QHostAddress::LocalHost) { // always listen on LocalHost LOG(VB_GENERAL, LOG_DEBUG, QString("Adding IPv4 loopback to address list.")); naList_4.append(*qnai); if (!v4IsSet && (config_v4 == ip)) v4IsSet = true; } else if (ip.isInSubnet(kLinkLocal) && allowLinkLocal) { // optionally listen on linklocal // the next clause will enable it anyway if no IP address // has been set LOG(VB_GENERAL, LOG_DEBUG, QString("Adding link-local '%1' to address list.") .arg(PRETTYIP_(ip))); naList_4.append(*qnai); } else if (config_v4.isNull()) { // IPv4 address is not defined, populate one // restrict autoconfiguration to RFC1918 private networks static QPair<QHostAddress, int> privNet1 = QHostAddress::parseSubnet("10.0.0.0/8"), privNet2 = QHostAddress::parseSubnet("172.16.0.0/12"), privNet3 = QHostAddress::parseSubnet("192.168.0.0/16"); if (ip.isInSubnet(privNet1) || ip.isInSubnet(privNet2) || ip.isInSubnet(privNet3)) { LOG(VB_GENERAL, LOG_DEBUG, QString("Adding '%1' to address list.") .arg(PRETTYIP_(ip))); naList_4.append(*qnai); } else if (ip.isInSubnet(kLinkLocal)) { LOG(VB_GENERAL, LOG_DEBUG, QString("Adding link-local '%1' to address list.") .arg(PRETTYIP_(ip))); naList_4.append(*qnai); } else LOG(VB_GENERAL, LOG_DEBUG, QString("Skipping " "non-private address during IPv4 autoselection: %1") .arg(PRETTYIP_(ip))); } else LOG(VB_GENERAL, LOG_DEBUG, QString("Skipping address: %1") .arg(PRETTYIP_(ip))); #if !defined(QT_NO_IPV6) } else { if (ip.isInSubnet(kLinkLocal6)) { // set scope id for link local address ip.setScopeId(qni->name()); qnai->setIp(ip); } if (naList_6.contains(*qnai)) // already defined, skip continue; else if ((!config_v6.isNull()) && (ip == config_v6)) { // IPv6 address is defined, add it LOG(VB_GENERAL, LOG_DEBUG, QString("Adding BackendServerIP6 to address list.")); naList_6.append(*qnai); v6IsSet = true; } else if (ip == QHostAddress::LocalHostIPv6) { // always listen on LocalHost LOG(VB_GENERAL, LOG_DEBUG, QString("Adding IPv6 loopback to address list.")); naList_6.append(*qnai); if (!v6IsSet && (config_v6 == ip)) v6IsSet = true; } else if (ip.isInSubnet(kLinkLocal6) && allowLinkLocal) { // optionally listen on linklocal // the next clause will enable it anyway if no IP address // has been set LOG(VB_GENERAL, LOG_DEBUG, QString("Adding link-local '%1' to address list.") .arg(ip.toString())); naList_6.append(*qnai); } else if (config_v6.isNull()) { if (ip.isInSubnet(kLinkLocal6)) LOG(VB_GENERAL, LOG_DEBUG, QString("Adding link-local '%1' to address list.") .arg(PRETTYIP_(ip))); else LOG(VB_GENERAL, LOG_DEBUG, QString("Adding '%1' to address list.") .arg(PRETTYIP_(ip))); naList_6.append(*qnai); } else LOG(VB_GENERAL, LOG_DEBUG, QString("Skipping address: %1") .arg(PRETTYIP_(ip))); } #endif } } if (!v4IsSet && (config_v4 != QHostAddress::LocalHost) && !naList_4.isEmpty()) { LOG(VB_GENERAL, LOG_CRIT, LOC + QString("Host is configured to listen " "on %1, but address is not used on any local network " "interfaces.").arg(config_v4.toString())); } #if !defined(QT_NO_IPV6) if (!v6IsSet && (config_v6 != QHostAddress::LocalHostIPv6) && !naList_6.isEmpty()) { LOG(VB_GENERAL, LOG_CRIT, LOC + QString("Host is configured to listen " "on %1, but address is not used on any local network " "interfaces.").arg(PRETTYIP_(config_v6))); } #endif // NOTE: there is no warning for the case where both defined addresses // are localhost, and neither are found. however this would also // mean there is no configured network at all, and should be // sufficiently rare a case as to not worry about it. }
void ServerPool::SelectDefaultListen(bool force) { if (!force) { QReadLocker rlock(&naLock); if (!naList_4.isEmpty() || !naList_6.isEmpty()) // lists are already populated, do nothing return; } QWriteLocker wlock(&naLock); naList_4.clear(); naList_6.clear(); // populate stored IPv4 and IPv6 addresses // if address is not defined, QHostAddress will be invalid and Null QHostAddress config_v4(gCoreContext->GetSetting("BackendServerIP")); bool v4IsSet = config_v4.isNull() ? true : false; #if !defined(QT_NO_IPV6) QHostAddress config_v6(gCoreContext->GetSetting("BackendServerIP6")); bool v6IsSet = config_v6.isNull() ? true : false; #endif // loop through all available interfaces QList<QNetworkInterface> IFs = QNetworkInterface::allInterfaces(); QList<QNetworkInterface>::const_iterator qni; for (qni = IFs.begin(); qni != IFs.end(); ++qni) { QList<QNetworkAddressEntry> IPs = qni->addressEntries(); QList<QNetworkAddressEntry>::const_iterator qnai; for (qnai = IPs.begin(); qnai != IPs.end(); ++qnai) { QHostAddress ip = qnai->ip(); if (naList_4.contains(*qnai)) // already defined, skip continue; else if (!config_v4.isNull() && (ip == config_v4)) { // IPv4 address is defined, add it LOG(VB_GENERAL, LOG_DEBUG, QString("Adding BackendServerIP to address list.")); naList_4.append(*qnai); v4IsSet = true; } else if (ip == QHostAddress::LocalHost) { // always listen on LocalHost LOG(VB_GENERAL, LOG_DEBUG, QString("Adding IPv4 loopback to address list.")); naList_4.append(*qnai); if (!v4IsSet && (config_v4 == ip)) v4IsSet = true; } else if (config_v4.isNull() && (ip.protocol() == QAbstractSocket::IPv4Protocol)) { // IPv4 address is not defined, populate one // restrict autoconfiguration to RFC1918 private networks if (ip.isInSubnet(QHostAddress::parseSubnet("10.0.0.0/8")) || ip.isInSubnet(QHostAddress::parseSubnet("172.16.0.0/12")) || ip.isInSubnet(QHostAddress::parseSubnet("192.168.0.0/16"))) { LOG(VB_GENERAL, LOG_DEBUG, QString("Adding '%1' to address list.") .arg(ip.toString())); naList_4.append(*qnai); } else LOG(VB_GENERAL, LOG_DEBUG, QString("Skipping non-private " "address during IPv4 autoselection: %1") .arg(ip.toString())); } #if !defined(QT_NO_IPV6) else if (naList_6.contains(*qnai)) // already defined, skip continue; else if (!config_v6.isNull() && (ip == config_v6)) { // IPv6 address is defined, add it LOG(VB_GENERAL, LOG_DEBUG, QString("Adding BackendServerIP6 to address list.")); naList_6.append(*qnai); v6IsSet = true; } else if (ip == QHostAddress::LocalHostIPv6) { // always listen on LocalHost LOG(VB_GENERAL, LOG_DEBUG, QString("Adding IPv6 loopback to address list.")); naList_6.append(*qnai); if (!v6IsSet && (config_v6 == ip)) v6IsSet = true; } else if (config_v6.isNull() && (ip.protocol() == QAbstractSocket::IPv6Protocol)) { // IPv6 address is not defined, populate one // put in additional block filtering here? if (!ip.isInSubnet(QHostAddress::parseSubnet("fe80::/10"))) { LOG(VB_GENERAL, LOG_DEBUG, QString("Adding '%1' to address list.") .arg(PRETTYIP_(ip))); naList_6.append(*qnai); } else LOG(VB_GENERAL, LOG_DEBUG, QString("Skipping link-local " "address during IPv6 autoselection: %1") .arg(PRETTYIP_(ip))); } #endif else LOG(VB_GENERAL, LOG_DEBUG, QString("Skipping address: %1") .arg(PRETTYIP_(ip))); } } if (!v4IsSet && (config_v4 != QHostAddress::LocalHost) && !naList_4.isEmpty()) { LOG(VB_GENERAL, LOG_CRIT, LOC + QString("Host is configured to listen " "on %1, but address is not used on any local network " "interfaces.").arg(config_v4.toString())); } #if !defined(QT_NO_IPV6) if (!v6IsSet && (config_v6 != QHostAddress::LocalHostIPv6) && !naList_6.isEmpty()) { LOG(VB_GENERAL, LOG_CRIT, LOC + QString("Host is configured to listen " "on %1, but address is not used on any local network " "interfaces.").arg(PRETTYIP_(config_v6))); } #endif // NOTE: there is no warning for the case where both defined addresses // are localhost, and neither are found. however this would also // mean there is no configured network at all, and should be // sufficiently rare a case as to not worry about it. }