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

View File

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