Esempio n. 1
0
bool QNativeSocketEnginePrivate::checkProxy(const QHostAddress &address)
{
    if (address.isLoopback())
        return true;

#if !defined(QT_NO_NETWORKPROXY)
    QObject *parent = q_func()->parent();
    QNetworkProxy proxy;
    if (QAbstractSocket *socket = qobject_cast<QAbstractSocket *>(parent)) {
        proxy = socket->proxy();
    } else if (QTcpServer *server = qobject_cast<QTcpServer *>(parent)) {
        proxy = server->proxy();
    } else {
        // no parent -> no proxy
        return true;
    }

    if (proxy.type() == QNetworkProxy::DefaultProxy)
        proxy = QNetworkProxy::applicationProxy();

    if (proxy.type() != QNetworkProxy::DefaultProxy &&
        proxy.type() != QNetworkProxy::NoProxy) {
        // QNativeSocketEngine doesn't do proxies
        setError(QAbstractSocket::UnsupportedSocketOperationError,
                 QNativeSocketEnginePrivate::InvalidProxyTypeString);
        return false;
    }
#endif

    return true;
}
Esempio n. 2
0
///\brief Returns true if the address is accessible from other devices.
bool TorcNetwork::IsExternal(const QHostAddress &Address, bool IncludeLinkLocal /* = false*/)
{
    if (Address.isNull() || Address.isLoopback())
        return false;

    if (Address.isInSubnet(Address.protocol() == QAbstractSocket::IPv4Protocol ? gIPv4LinkLocal : gIPv6LinkLocal))
        return IncludeLinkLocal;

    return true;
}
Esempio n. 3
0
void TcpServerDevice::broadcast(const QByteArray &data)
{
    const QHostAddress address = m_server->serverAddress();

    // broadcast announcement only if we are actually listinging to remote connections
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
    if (address.toString() == "127.0.0.1" || address.toString() == "::1")
#else
    if (address.isLoopback())
#endif
        return;

    m_broadcastSocket->writeDatagram(data.data(), data.size(), QHostAddress::Broadcast, Server::broadcastPort());
}
//I'm the existing device, a new device is kindly introducing itself.
//I will create a TcpSocket and try to connect. This can result in either connected() or connectError().
void LanLinkProvider::newUdpConnection() //udpBroadcastReceived
{
    while (mUdpSocket.hasPendingDatagrams()) {

        QByteArray datagram;
        datagram.resize(mUdpSocket.pendingDatagramSize());
        QHostAddress sender;

        mUdpSocket.readDatagram(datagram.data(), datagram.size(), &sender);

        if (sender.isLoopback() && !mTestMode)
            continue;

        NetworkPackage* receivedPackage = new NetworkPackage("");
        bool success = NetworkPackage::unserialize(datagram, receivedPackage);

        //qCDebug(KDECONNECT_CORE) << "udp connection from " << receivedPackage->;

        //qCDebug(KDECONNECT_CORE) << "Datagram " << datagram.data() ;

        if (!success || receivedPackage->type() != PACKAGE_TYPE_IDENTITY) {
            delete receivedPackage;
            continue;
        }

        if (receivedPackage->get<QString>("deviceId") == KdeConnectConfig::instance()->deviceId()) {
            //qCDebug(KDECONNECT_CORE) << "Ignoring my own broadcast";
            delete receivedPackage;
            continue;
        }

        int tcpPort = receivedPackage->get<int>("tcpPort", port);

        //qCDebug(KDECONNECT_CORE) << "Received Udp identity package from" << sender << " asking for a tcp connection on port " << tcpPort;

        QSslSocket* socket = new QSslSocket(this);
        receivedIdentityPackages[socket].np = receivedPackage;
        receivedIdentityPackages[socket].sender = sender;
        connect(socket, SIGNAL(connected()), this, SLOT(connected()));
        connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError()));
        socket->connectToHost(sender, tcpPort);
    }
}
static bool isBypassed(const QString &host, const QStringList &bypassList)
{
    if (host.isEmpty())
        return false;

    bool isSimple = !host.contains(QLatin1Char('.')) && !host.contains(QLatin1Char(':'));

    QHostAddress ipAddress;
    bool isIpAddress = ipAddress.setAddress(host);

    // always exclude loopback
    if (isIpAddress && ipAddress.isLoopback())
        return true;

    // does it match the list of exclusions?
    foreach (const QString &entry, bypassList) {
        if (entry == QLatin1String("<local>")) {
            if (isSimple)
                return true;
            if (isIpAddress) {
                //exclude all local subnets
                foreach (const QNetworkInterface &iface, QNetworkInterface::allInterfaces()) {
                    foreach (const QNetworkAddressEntry netaddr, iface.addressEntries()) {
                        if (ipAddress.isInSubnet(netaddr.ip(), netaddr.prefixLength())) {
                            return true;
                        }
                    }
                }
            }
        }
        if (isIpAddress && ipAddress.isInSubnet(QHostAddress::parseSubnet(entry))) {
            return true;        // excluded
        } else {
            // do wildcard matching
            QRegExp rx(entry, Qt::CaseInsensitive, QRegExp::Wildcard);
            if (rx.exactMatch(host))
                return true;
        }
    }
Esempio n. 6
0
/*! \brief Convert an IP address to a string literal.
 *
 * For an IPv4 address, this is a no-op. For IPv6 addresses, we need to remove the scope Id if present
 * and wrap the remainder in braces.
*/
QString TorcNetwork::IPAddressToLiteral(const QHostAddress &Address, int Port, bool UseLocalhost /* = true*/)
{
    QString result;

    if (UseLocalhost && Address.isLoopback())
    {
        result = QString("localhost");
    }
    else if (Address.protocol() == QAbstractSocket::IPv4Protocol)
    {
        result = Address.toString();
    }
    else
    {
        QHostAddress address(Address);
        address.setScopeId("");
        result = "[" + address.toString() +"]";
    }

    if (Port)
        result += ":" + QString::number(Port);

    return result;
}
Esempio n. 7
0
QUrl TcpServerDevice::externalAddress() const
{
    const QHostAddress address(m_server->serverAddress());
    QString myHost;

#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
    if (address == QHostAddress::LocalHost || address == QHostAddress::LocalHostIPv6) {
#else
    if (address.isLoopback()) {
#endif
        myHost = address.toString();
    } else {
        foreach (const QNetworkInterface &inter, QNetworkInterface::allInterfaces()) {
            if (!(inter.flags() & QNetworkInterface::IsUp)
                || !(inter.flags() & QNetworkInterface::IsRunning)
                || (inter.flags() & QNetworkInterface::IsLoopBack))
                continue;

            foreach (const QNetworkAddressEntry &addrEntry, inter.addressEntries()) {
                const QHostAddress addr = addrEntry.ip();

                // Return the ip according to the listening server protocol.
                if (addr.protocol() != m_server->serverAddress().protocol()
                    || !addr.scopeId().isEmpty())
                    continue;

                myHost = addr.toString();
                break;
            }
            if (!myHost.isEmpty())
                break;
        }
    }

    // if localhost is all we got, use that rather than nothing
    if (myHost.isEmpty()) {
        switch (m_server->serverAddress().protocol()) {
        case QAbstractSocket::IPv4Protocol:
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
        case QAbstractSocket::AnyIPProtocol:
#endif
            myHost = QHostAddress(QHostAddress::LocalHost).toString();
            break;
        case QAbstractSocket::IPv6Protocol:
            myHost = QHostAddress(QHostAddress::LocalHostIPv6).toString();
            break;
        case QAbstractSocket::UnknownNetworkLayerProtocol:
            Q_ASSERT_X(false, "TcpServerDevice::externalAddress", "unknown TCP protocol");
            break;
        }
    }

    QUrl url;
    url.setScheme(QStringLiteral("tcp"));
    url.setHost(myHost);
    url.setPort(m_server->serverPort());
    return url;
}

void TcpServerDevice::broadcast(const QByteArray &data)
{
    const QHostAddress address = m_server->serverAddress();

    // broadcast announcement only if we are actually listinging to remote connections
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
    if (address == QHostAddress::LocalHost || address == QHostAddress::LocalHostIPv6)
#else
    if (address.isLoopback())
#endif
        return;

    m_broadcastSocket->writeDatagram(data.data(),
                                     data.size(), QHostAddress::Broadcast, Server::broadcastPort());
}
Esempio n. 8
0
void Discover::acceptRecords (QList<Record> records, bool removeThem, QString senderScope, QString senderAddress, QString senderPort)
{
	// TODO
	
	// This function gets its own copy of records
	// This loop edits each item so it can be used after
	for (Record& record : records)
	{
		// Preprocess the record before considering it
		Record::decompressReserved(record);

		// Set the scope based on the address if included, otherwise scope of sender
		QHostAddress recordAddress;
		if (record.has("Address")) recordAddress.setAddress(record["Address"]);
		if (recordAddress.protocol()!=QAbstractSocket::IPv4Protocol) recordAddress = QHostAddress::Null;
		if (recordAddress==QHostAddress::Broadcast) recordAddress = QHostAddress::Null;
		if (recordAddress==QHostAddress::AnyIPv4) recordAddress = QHostAddress::Null;
		if (recordAddress.isNull())
		{
			record["Scope"] = senderScope;
		}
		else
		{
				 if (recordAddress.isLoopback())    record["Scope"] = "Loopback";
			else if (addressIsLocal(recordAddress)) record["Scope"] = "Local";
			else                                    record["Scope"] = "Global";
		}

		if (record["Address"].isEmpty()) record["Address"] = senderAddress; // Sender may override these
		if (record["Port"].isEmpty()) record["Port"] = senderPort; // Sender may override these
		// TODO Extract a custom expiration duration so each record can have its own


		if (removeThem)
		{
			// See if it's new
			if (foundRecords.contains(record))
			{
				logDebug(QString("Record Departed: %1").arg(record.toString()));
				foundRecords.remove(record);
				emit recordLost(record);
			}
		}
		else
		{
			// See if it's new
			if (not foundRecords.contains(record) and passesFilters(record))
			{
				logDebug(QString("Found Record: %1").arg(record.toString()));
				emit recordFound(record);
			}

			// Reset the timer
			foundRecords[record] = QDateTime::currentMSecsSinceEpoch() + 2500; // Set the expire time
		}

		expireTimer->start(0); // In case the next expiration time was changed
	}
	
	// Server: Forward global departures to other global peers
	if (mServerMode and removeThem and senderScope == "Global")
	{
		QByteArray datagram("DSDD");
		datagram += makeDatagram(records, false);
		
		for (Record& record : foundRecords.keys())
		if (record["Scope"] == "Global")
		{
			bool ok;
			globalSocket->writeDatagram(datagram, QHostAddress(record["Address"]), record["Port"].toUInt(&ok, 10));
		}
	}
}
Esempio n. 9
0
void Discover::readDatagrams ()
{
	QUdpSocket* socket = qobject_cast<QUdpSocket*>(QObject::sender());
	if (socket)
	while (socket->hasPendingDatagrams())
	{
		// Read it to a buffer
		QByteArray datagram;
		datagram.resize(socket->pendingDatagramSize());
		QHostAddress sender;
		quint16 senderPort;
		socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);

		// Check the prefix
		bool respond = false;
		bool removeThem = false;
		if (datagram.startsWith("DSDA")) respond = false; // Announcement, do not respond
		else if (datagram.startsWith("DSDR")) respond = true; // Request, do respond
		else if (datagram.startsWith("DSDD")) removeThem = true; // This is a departure, remove records following
		else
		{
			// This datagram isn't written for Discover, pass it on
			QList<Record> matchingRecords;
			for (Record record : foundRecords.keys())
			{
				if (record.has("Address") and record["Address"]==sender.toString())
				if (record.has("Port") and record["Port"]==QString::number(senderPort))
					matchingRecords.append(record);
			}
			emit gotDatagram(datagram, sender, senderPort, matchingRecords);
			continue;
		}
		datagram.remove(0, 4);

		// Determine the scope of the sender
		// See if it's this machine
		QString scope("Global");
		if (sender.isLoopback())
		{
			scope = "Loopback";
		}
		else if (sender.protocol() == QAbstractSocket::IPv4Protocol)
		{
			if (addressIsLocal(sender)) scope = "Local";
		}

		// Process the records locally
		acceptRecords(Record::listFromBytes(datagram), removeThem, scope, sender.toString(), QString::number(senderPort));

		// Normal: Respond to only Local requests with only owned Records
		if (respond and not mServerMode and (scope=="Local" or scope=="Loopback"))
		{
			globalSocket->writeDatagram(QByteArray("DSDA")+makeDatagram(ownedRecords, true), sender, senderPort);
		}
		// Server: Respond to only global requests with owned and found Records
		else if (respond and mServerMode and scope=="Global")
		{
			globalSocket->writeDatagram(QByteArray("DSDA")+makeDatagram(ownedRecords + foundRecords.keys(), false), sender, senderPort);
		}
	}
}