Exemplo n.º 1
0
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.
}
Exemplo n.º 2
0
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.
}