summaryrefslogtreecommitdiffstats
path: root/examples/network/network-chat/peermanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/network/network-chat/peermanager.cpp')
-rw-r--r--examples/network/network-chat/peermanager.cpp99
1 files changed, 29 insertions, 70 deletions
diff --git a/examples/network/network-chat/peermanager.cpp b/examples/network/network-chat/peermanager.cpp
index 2c9d182211..a70ed7da73 100644
--- a/examples/network/network-chat/peermanager.cpp
+++ b/examples/network/network-chat/peermanager.cpp
@@ -1,68 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtNetwork>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2018 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "client.h"
#include "connection.h"
#include "peermanager.h"
+#include <QNetworkInterface>
+#include <QUuid>
+
static const qint32 BroadcastInterval = 2000;
static const unsigned broadcastPort = 45000;
PeerManager::PeerManager(Client *client)
- : QObject(client)
+ : QObject(client), client(client)
{
- this->client = client;
-
static const char *envVariables[] = {
"USERNAME", "USER", "USERDOMAIN", "HOSTNAME", "DOMAINNAME"
};
@@ -76,8 +28,12 @@ PeerManager::PeerManager(Client *client)
if (username.isEmpty())
username = "unknown";
+ // We generate a unique per-process identifier so we can avoid multiple
+ // connections to/from the same remote peer as well as ignore our own
+ // broadcasts.
+ localUniqueId = QUuid::createUuid().toByteArray();
+
updateAddresses();
- serverPort = 0;
broadcastSocket.bind(QHostAddress::Any, broadcastPort, QUdpSocket::ShareAddress
| QUdpSocket::ReuseAddressHint);
@@ -99,6 +55,11 @@ QString PeerManager::userName() const
return username;
}
+QByteArray PeerManager::uniqueId() const
+{
+ return localUniqueId;
+}
+
void PeerManager::startBroadcasting()
{
broadcastTimer.start();
@@ -106,11 +67,7 @@ void PeerManager::startBroadcasting()
bool PeerManager::isLocalHostAddress(const QHostAddress &address) const
{
- for (const QHostAddress &localAddress : ipAddresses) {
- if (address.isEqual(localAddress))
- return true;
- }
- return false;
+ return ipAddresses.contains(address);
}
void PeerManager::sendBroadcastDatagram()
@@ -119,15 +76,14 @@ void PeerManager::sendBroadcastDatagram()
{
QCborStreamWriter writer(&datagram);
writer.startArray(2);
- writer.append(username);
+ writer.append(localUniqueId);
writer.append(serverPort);
writer.endArray();
}
bool validBroadcastAddresses = true;
- for (const QHostAddress &address : qAsConst(broadcastAddresses)) {
- if (broadcastSocket.writeDatagram(datagram, address,
- broadcastPort) == -1)
+ for (const QHostAddress &address : std::as_const(broadcastAddresses)) {
+ if (broadcastSocket.writeDatagram(datagram, address, broadcastPort) == -1)
validBroadcastAddresses = false;
}
@@ -147,6 +103,7 @@ void PeerManager::readBroadcastDatagram()
continue;
int senderServerPort;
+ QByteArray peerUniqueId;
{
// decode the datagram
QCborStreamReader reader(datagram);
@@ -156,10 +113,12 @@ void PeerManager::readBroadcastDatagram()
continue;
reader.enterContainer();
- if (reader.lastError() != QCborError::NoError || !reader.isString())
+ if (reader.lastError() != QCborError::NoError || !reader.isByteArray())
continue;
- while (reader.readString().status == QCborStreamReader::Ok) {
- // we don't actually need the username right now
+ auto r = reader.readByteArray();
+ while (r.status == QCborStreamReader::Ok) {
+ peerUniqueId = r.data;
+ r = reader.readByteArray();
}
if (reader.lastError() != QCborError::NoError || !reader.isUnsignedInteger())
@@ -167,10 +126,10 @@ void PeerManager::readBroadcastDatagram()
senderServerPort = reader.toInteger();
}
- if (isLocalHostAddress(senderIp) && senderServerPort == serverPort)
+ if (peerUniqueId == localUniqueId)
continue;
- if (!client->hasConnection(senderIp)) {
+ if (!client->hasConnection(peerUniqueId)) {
Connection *connection = new Connection(this);
emit newConnection(connection);
connection->connectToHost(senderIp, senderServerPort);