SecureUDPServer example: use std::unique_ptr instead of QSharedPointer

The only reason the code used QSharedPointer is that it used QVector
to hold a collection of them, and QVector infamously cannot hold
move-only types such as std::unique_ptr.

Fix by using std::vector<std::unique_ptr> instead. Also, pass the
objeccts into non-sink functions by raw pointer instead of shared_ptr.

As a drive-by, replace clear-following-iterate by the for-exchanged
pattern.

Change-Id: I605fbb98af840c1b93eab9e65c07defd6e7b39e1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Marc Mutz 2019-05-15 11:15:22 +02:00
parent de82d239f8
commit c6a3507de2
2 changed files with 15 additions and 16 deletions

View File

@ -62,7 +62,7 @@ QString peer_info(const QHostAddress &address, quint16 port)
return info.arg(address.toString()).arg(port);
}
QString connection_info(QSharedPointer<QDtls> connection)
QString connection_info(QDtls *connection)
{
QString info(DtlsServer::tr("Session cipher: "));
info += connection->sessionCipher().name();
@ -157,7 +157,7 @@ void DtlsServer::readyRead()
}
const auto client = std::find_if(knownClients.begin(), knownClients.end(),
[&](const DtlsConnection &connection){
[&](const std::unique_ptr<QDtls> &connection){
return connection->peerAddress() == peerAddress
&& connection->peerPort() == peerPort;
});
@ -170,7 +170,7 @@ void DtlsServer::readyRead()
//! [6]
if ((*client)->isConnectionEncrypted()) {
decryptDatagram(*client, dgram);
decryptDatagram(client->get(), dgram);
if ((*client)->dtlsError() == QDtlsError::RemoteClosedConnectionError)
knownClients.erase(client);
return;
@ -178,7 +178,7 @@ void DtlsServer::readyRead()
//! [6]
//! [7]
doHandshake(*client, dgram);
doHandshake(client->get(), dgram);
//! [7]
}
@ -205,13 +205,13 @@ void DtlsServer::handleNewConnection(const QHostAddress &peerAddress,
emit infoMessage(peerInfo + tr(": verified, starting a handshake"));
//! [8]
//! [9]
DtlsConnection newConnection(new QDtls(QSslSocket::SslServerMode));
std::unique_ptr<QDtls> newConnection{new QDtls{QSslSocket::SslServerMode}};
newConnection->setDtlsConfiguration(serverConfiguration);
newConnection->setPeer(peerAddress, peerPort);
newConnection->connect(newConnection.data(), &QDtls::pskRequired,
newConnection->connect(newConnection.get(), &QDtls::pskRequired,
this, &DtlsServer::pskRequired);
knownClients.push_back(newConnection);
doHandshake(newConnection, clientHello);
knownClients.push_back(std::move(newConnection));
doHandshake(knownClients.back().get(), clientHello);
//! [9]
} else if (cookieSender.dtlsError() != QDtlsError::NoError) {
emit errorMessage(tr("DTLS error: ") + cookieSender.dtlsErrorString());
@ -221,7 +221,7 @@ void DtlsServer::handleNewConnection(const QHostAddress &peerAddress,
}
//! [11]
void DtlsServer::doHandshake(DtlsConnection newConnection, const QByteArray &clientHello)
void DtlsServer::doHandshake(QDtls *newConnection, const QByteArray &clientHello)
{
const bool result = newConnection->doHandshake(&serverSocket, clientHello);
if (!result) {
@ -246,7 +246,7 @@ void DtlsServer::doHandshake(DtlsConnection newConnection, const QByteArray &cli
//! [11]
//! [12]
void DtlsServer::decryptDatagram(DtlsConnection connection, const QByteArray &clientMessage)
void DtlsServer::decryptDatagram(QDtls *connection, const QByteArray &clientMessage)
{
Q_ASSERT(connection->isConnectionEncrypted());
@ -266,10 +266,9 @@ void DtlsServer::decryptDatagram(DtlsConnection connection, const QByteArray &cl
//! [14]
void DtlsServer::shutdown()
{
for (DtlsConnection &connection : knownClients)
for (const auto &connection : qExchange(knownClients, {}))
connection->shutdown(&serverSocket);
knownClients.clear();
serverSocket.close();
}
//! [14]

View File

@ -54,6 +54,7 @@
#include <QtNetwork>
#include <vector>
#include <memory>
QT_BEGIN_NAMESPACE
@ -86,9 +87,8 @@ private:
void handleNewConnection(const QHostAddress &peerAddress, quint16 peerPort,
const QByteArray &clientHello);
using DtlsConnection = QSharedPointer<QDtls>;
void doHandshake(DtlsConnection newConnection, const QByteArray &clientHello);
void decryptDatagram(DtlsConnection connection, const QByteArray &clientMessage);
void doHandshake(QDtls *newConnection, const QByteArray &clientHello);
void decryptDatagram(QDtls *connection, const QByteArray &clientMessage);
void shutdown();
bool listening = false;
@ -96,7 +96,7 @@ private:
QSslConfiguration serverConfiguration;
QDtlsClientVerifier cookieSender;
QVector<DtlsConnection> knownClients;
std::vector<std::unique_ptr<QDtls>> knownClients;
Q_DISABLE_COPY(DtlsServer)
};