summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2018-08-06 12:05:26 +0200
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2018-08-09 03:52:13 +0000
commit5b8d5c7493259544f853eb2732cca2829c0f67ca (patch)
treeba8a06551d7241869f8255d8a3a7cdf33cc87721
parent4c089601d7982bb45080d57b3399ed0653f69dd1 (diff)
Document DTLS examples
Task-number: QTBUG-68070 Change-Id: I2b08322049005b02f1ed680bee21992ade16813a Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
-rw-r--r--examples/network/doc/images/secureudpclient-example.pngbin0 -> 23211 bytes
-rw-r--r--examples/network/doc/images/secureudpserver-example.pngbin0 -> 38412 bytes
-rw-r--r--examples/network/doc/src/secureudpclient.qdoc93
-rw-r--r--examples/network/doc/src/secureudpserver.qdoc101
-rw-r--r--examples/network/secureudpclient/addressdialog.h2
-rw-r--r--examples/network/secureudpclient/association.cpp35
-rw-r--r--examples/network/secureudpclient/association.h6
-rw-r--r--examples/network/secureudpclient/mainwindow.cpp4
-rw-r--r--examples/network/secureudpclient/mainwindow.h2
-rw-r--r--examples/network/secureudpserver/mainwindow.cpp2
-rw-r--r--examples/network/secureudpserver/mainwindow.h3
-rw-r--r--examples/network/secureudpserver/server.cpp28
-rw-r--r--examples/network/secureudpserver/server.h6
13 files changed, 255 insertions, 27 deletions
diff --git a/examples/network/doc/images/secureudpclient-example.png b/examples/network/doc/images/secureudpclient-example.png
new file mode 100644
index 0000000000..a566aa4ce5
--- /dev/null
+++ b/examples/network/doc/images/secureudpclient-example.png
Binary files differ
diff --git a/examples/network/doc/images/secureudpserver-example.png b/examples/network/doc/images/secureudpserver-example.png
new file mode 100644
index 0000000000..a117b02834
--- /dev/null
+++ b/examples/network/doc/images/secureudpserver-example.png
Binary files differ
diff --git a/examples/network/doc/src/secureudpclient.qdoc b/examples/network/doc/src/secureudpclient.qdoc
index 587689ac47..dc8538cf85 100644
--- a/examples/network/doc/src/secureudpclient.qdoc
+++ b/examples/network/doc/src/secureudpclient.qdoc
@@ -29,9 +29,96 @@
\example secureudpclient
\title DTLS client
\ingroup examples-network
- \brief Demonstrates how to implement a simple DTLS client
+ \brief This example demonstrates how to implement client-side DTLS connections.
- This example uses QUdpSocket, QDtlsClientVerifier, and QDtls to securely
- communicate over the User Datagram Protocol with DTLS servers.
+ \image secureudpclient-example.png Screenshot of the DTLS client example.
+
+ \note The DTLS client example is intended to be run alongside the \l{secureudpserver}{DTLS server} example.
+
+ The example DTLS client can establish several DTLS connections to one
+ or many DTLS servers. A client-side DTLS connection is implemented by the
+ DtlsAssociation class. This class uses QUdpSocket to read and write datagrams
+ and QDtls for encryption:
+
+ \snippet secureudpclient/association.h 0
+
+ The constructor sets the minimal TLS configuration for the new DTLS connection,
+ and sets the address and the port of the server:
+
+ \dots
+ \snippet secureudpclient/association.cpp 1
+ \dots
+
+ The QDtls::handshakeTimeout() signal is connected to the handleTimeout() slot
+ to deal with packet loss and retransmission during the handshake phase:
+
+ \dots
+ \snippet secureudpclient/association.cpp 2
+ \dots
+
+ To ensure we receive only the datagrams from the server, we connect our UDP socket to the server:
+
+ \dots
+ \snippet secureudpclient/association.cpp 3
+ \dots
+
+ The QUdpSocket::readyRead() signal is connected to the readyRead() slot:
+
+ \dots
+ \snippet secureudpclient/association.cpp 13
+ \dots
+
+ When a secure connection to a server is established, a DtlsAssociation object
+ will be sending short ping messages to the server, using a timer:
+
+ \snippet secureudpclient/association.cpp 4
+
+ startHandshake() starts a handshake with the server:
+
+ \snippet secureudpclient/association.cpp 5
+
+ The readyRead() slot reads a datagram sent by the server:
+
+ \snippet secureudpclient/association.cpp 6
+
+ If the handshake was already completed, this datagram is decrypted:
+
+ \snippet secureudpclient/association.cpp 7
+
+ otherwise, we try to continue the handshake:
+
+ \snippet secureudpclient/association.cpp 8
+
+ When the handshake has completed, we send our first ping message:
+
+ \snippet secureudpclient/association.cpp 9
+
+ The pskRequired() slot provides the Pre-Shared Key (PSK) needed during the handshake
+ phase:
+
+ \snippet secureudpclient/association.cpp 14
+
+ \note For the sake of brevity, the definition of pskRequired() is oversimplified.
+ The documentation for the QSslPreSharedKeyAuthenticator class explains in detail
+ how this slot can be properly implemented.
+
+ pingTimeout() sends an encrypted message to the server:
+
+ \snippet secureudpclient/association.cpp 10
+
+ During the handshake phase the client must handle possible timeouts, which
+ can happen due to packet loss. The handshakeTimeout() slot retransmits
+ the handshake messages:
+
+ \snippet secureudpclient/association.cpp 11
+
+ Before a client connection is destroyed, its DTLS connection must be shut down:
+
+ \snippet secureudpclient/association.cpp 12
+
+ Error messages, informational messages, and decrypted responses from servers
+ are displayed by the UI:
+
+ \snippet secureudpclient/mainwindow.cpp 0
*/
diff --git a/examples/network/doc/src/secureudpserver.qdoc b/examples/network/doc/src/secureudpserver.qdoc
index a00d65773b..0857f7065f 100644
--- a/examples/network/doc/src/secureudpserver.qdoc
+++ b/examples/network/doc/src/secureudpserver.qdoc
@@ -29,8 +29,103 @@
\example secureudpserver
\title DTLS server
\ingroup examples-network
- \brief Demonstrates how to implement a simple DTLS server
+ \brief This examples demonstrates how to implement a simple DTLS server.
- This example uses QUdpSocket, QDtlsClientVerifier, and QDtls to securely respond
- to DTLS client requests over the User Datagram Protocol.
+ \image secureudpserver-example.png Screenshot of the DTLS server example.
+
+ \note The DTLS server example is intended to be run alongside the \l{secureudpclient}{DTLS client} example.
+
+ The server is implemented by the DtlsServer class. It uses QUdpSocket,
+ QDtlsClientVerifier, and QDtls to test each client's reachability, complete a handshake,
+ and read and write encrypted messages.
+
+ \snippet secureudpserver/server.h 0
+
+ The constructor connects the QUdpSocket::readyRead() signal to its
+ readyRead() slot and sets the minimal needed TLS configuration:
+
+ \snippet secureudpserver/server.cpp 1
+
+ \note The server is not using a certificate and is relying on Pre-Shared
+ Key (PSK) handshake.
+
+ listen() binds QUdpSocket:
+
+ \snippet secureudpserver/server.cpp 2
+
+ The readyRead() slot processes incoming datagrams:
+
+ \dots
+ \snippet secureudpserver/server.cpp 3
+ \dots
+
+ After extracting an address and a port number, the server first tests
+ if it's a datagram from an already known peer:
+
+ \dots
+ \snippet secureudpserver/server.cpp 4
+ \dots
+
+ If it is a new, unknown address and port, the datagram is processed as a
+ potential ClientHello message, sent by a DTLS client:
+
+ \dots
+ \snippet secureudpserver/server.cpp 5
+ \dots
+
+ If it's a known DTLS client, the server either decrypts the datagram:
+
+ \dots
+ \snippet secureudpserver/server.cpp 6
+ \dots
+
+ or continues a handshake with this peer:
+
+ \dots
+ \snippet secureudpserver/server.cpp 7
+ \dots
+
+ handleNewConnection() verifies it's a reachable DTLS client, or sends a
+ HelloVerifyRequest:
+
+ \snippet secureudpserver/server.cpp 8
+ \dots
+
+ If the new client was verified to be a reachable DTLS client, the server creates
+ and configures a new QDtls object, and starts a server-side handshake:
+
+ \dots
+ \snippet secureudpserver/server.cpp 9
+ \dots
+
+ doHandshake() progresses through the handshake phase:
+
+ \snippet secureudpserver/server.cpp 11
+
+ During the handshake phase, the QDtls::pskRequired() signal is emitted and
+ the pskRequired() slot provides the preshared key:
+
+ \snippet secureudpserver/server.cpp 13
+
+ \note For the sake of brevity, the definition of pskRequired() is oversimplified.
+ The documentation for the QSslPreSharedKeyAuthenticator class explains in detail
+ how this slot can be properly implemented.
+
+ After the handshake is completed for the network peer, an encrypted DTLS
+ connection is considered to be established and the server decrypts subsequent
+ datagrams, sent by the peer, by calling decryptDatagram(). The server also
+ sends an encrypted response to the peer:
+
+ \snippet secureudpserver/server.cpp 12
+
+ The server closes its DTLS connections by calling QDtls::shutdown():
+
+ \snippet secureudpserver/server.cpp 14
+
+ During its operation, the server reports errors, informational messages, and
+ decrypted datagrams, by emitting signals errorMessage(), warningMessage(),
+ infoMessage(), and datagramReceived(). These messages are logged by the server's
+ UI:
+
+ \snippet secureudpserver/mainwindow.cpp 0
*/
diff --git a/examples/network/secureudpclient/addressdialog.h b/examples/network/secureudpclient/addressdialog.h
index 7c5e2e03e8..43792faa4b 100644
--- a/examples/network/secureudpclient/addressdialog.h
+++ b/examples/network/secureudpclient/addressdialog.h
@@ -69,7 +69,6 @@ class AddressDialog : public QDialog
Q_OBJECT
public:
-
explicit AddressDialog(QWidget *parent = nullptr);
~AddressDialog();
@@ -77,7 +76,6 @@ public:
quint16 remotePort() const;
private:
-
void setupHostSelector();
void setupPortSelector();
diff --git a/examples/network/secureudpclient/association.cpp b/examples/network/secureudpclient/association.cpp
index 6b510909f1..c950260078 100644
--- a/examples/network/secureudpclient/association.cpp
+++ b/examples/network/secureudpclient/association.cpp
@@ -57,27 +57,38 @@ DtlsAssociation::DtlsAssociation(const QHostAddress &address, quint16 port,
: name(connectionName),
crypto(QSslSocket::SslClientMode)
{
+ //! [1]
auto configuration = QSslConfiguration::defaultDtlsConfiguration();
configuration.setPeerVerifyMode(QSslSocket::VerifyNone);
crypto.setPeer(address, port);
crypto.setDtlsConfiguration(configuration);
+ //! [1]
+ //! [2]
connect(&crypto, &QDtls::handshakeTimeout, this, &DtlsAssociation::handshakeTimeout);
+ //! [2]
connect(&crypto, &QDtls::pskRequired, this, &DtlsAssociation::pskRequired);
-
+ //! [3]
socket.connectToHost(address.toString(), port);
+ //! [3]
+ //! [13]
connect(&socket, &QUdpSocket::readyRead, this, &DtlsAssociation::readyRead);
-
+ //! [13]
+ //! [4]
pingTimer.setInterval(5000);
connect(&pingTimer, &QTimer::timeout, this, &DtlsAssociation::pingTimeout);
+ //! [4]
}
+//! [12]
DtlsAssociation::~DtlsAssociation()
{
if (crypto.isConnectionEncrypted())
crypto.shutdown(&socket);
}
+//! [12]
+//! [5]
void DtlsAssociation::startHandshake()
{
if (socket.state() != QAbstractSocket::ConnectedState) {
@@ -86,11 +97,12 @@ void DtlsAssociation::startHandshake()
return;
}
- if (!crypto.doHandshake(&socket, {}))
+ if (!crypto.doHandshake(&socket))
emit errorMessage(tr("%1: failed to start a handshake - %2").arg(name, crypto.dtlsErrorString()));
else
emit infoMessage(tr("%1: starting a handshake").arg(name));
}
+//! [5]
void DtlsAssociation::udpSocketConnected()
{
@@ -100,7 +112,8 @@ void DtlsAssociation::udpSocketConnected()
void DtlsAssociation::readyRead()
{
- QByteArray dgram(socket.pendingDatagramSize(), '\0');
+ //! [6]
+ QByteArray dgram(socket.pendingDatagramSize(), Qt::Uninitialized);
const qint64 bytesRead = socket.readDatagram(dgram.data(), dgram.size());
if (bytesRead <= 0) {
emit warningMessage(tr("%1: spurious read notification?").arg(name));
@@ -108,6 +121,8 @@ void DtlsAssociation::readyRead()
}
dgram.resize(bytesRead);
+ //! [6]
+ //! [7]
if (crypto.isConnectionEncrypted()) {
const QByteArray plainText = crypto.decryptDatagram(&socket, dgram);
if (plainText.size()) {
@@ -124,27 +139,36 @@ void DtlsAssociation::readyRead()
emit warningMessage(tr("%1: zero-length datagram received?").arg(name));
} else {
+ //! [7]
+ //! [8]
if (!crypto.doHandshake(&socket, dgram)) {
emit errorMessage(tr("%1: handshake error - %2").arg(name, crypto.dtlsErrorString()));
return;
}
+ //! [8]
+
+ //! [9]
if (crypto.isConnectionEncrypted()) {
emit infoMessage(tr("%1: encrypted connection established!").arg(name));
pingTimer.start();
pingTimeout();
} else {
+ //! [9]
emit infoMessage(tr("%1: continuing with handshake ...").arg(name));
}
}
}
+//! [11]
void DtlsAssociation::handshakeTimeout()
{
emit warningMessage(tr("%1: handshake timeout, trying to re-transmit").arg(name));
if (!crypto.handleTimeout(&socket))
emit errorMessage(tr("%1: failed to re-transmit - %2").arg(name, crypto.dtlsErrorString()));
}
+//! [11]
+//! [14]
void DtlsAssociation::pskRequired(QSslPreSharedKeyAuthenticator *auth)
{
Q_ASSERT(auth);
@@ -153,7 +177,9 @@ void DtlsAssociation::pskRequired(QSslPreSharedKeyAuthenticator *auth)
auth->setIdentity(name.toLatin1());
auth->setPreSharedKey(QByteArrayLiteral("\x1a\x2b\x3c\x4d\x5e\x6f"));
}
+//! [14]
+//! [10]
void DtlsAssociation::pingTimeout()
{
static const QString message = QStringLiteral("I am %1, please, accept our ping %2");
@@ -166,5 +192,6 @@ void DtlsAssociation::pingTimeout()
++ping;
}
+//! [10]
QT_END_NAMESPACE
diff --git a/examples/network/secureudpclient/association.h b/examples/network/secureudpclient/association.h
index 157882f23d..be89ce695e 100644
--- a/examples/network/secureudpclient/association.h
+++ b/examples/network/secureudpclient/association.h
@@ -55,19 +55,18 @@
QT_BEGIN_NAMESPACE
+//! [0]
class DtlsAssociation : public QObject
{
Q_OBJECT
public:
-
DtlsAssociation(const QHostAddress &address, quint16 port,
const QString &connectionName);
~DtlsAssociation();
void startHandshake();
signals:
-
void errorMessage(const QString &message);
void warningMessage(const QString &message);
void infoMessage(const QString &message);
@@ -75,7 +74,6 @@ signals:
const QByteArray &plainText);
private slots:
-
void udpSocketConnected();
void readyRead();
void handshakeTimeout();
@@ -83,7 +81,6 @@ private slots:
void pingTimeout();
private:
-
QString name;
QUdpSocket socket;
QDtls crypto;
@@ -93,6 +90,7 @@ private:
Q_DISABLE_COPY(DtlsAssociation)
};
+//! [0]
QT_END_NAMESPACE
diff --git a/examples/network/secureudpclient/mainwindow.cpp b/examples/network/secureudpclient/mainwindow.cpp
index 07c614cf3a..2fbf757c81 100644
--- a/examples/network/secureudpclient/mainwindow.cpp
+++ b/examples/network/secureudpclient/mainwindow.cpp
@@ -72,6 +72,8 @@ MainWindow::~MainWindow()
delete ui;
}
+//! [0]
+
const QString colorizer(QStringLiteral("<font color=\"%1\">%2</font><br>"));
void MainWindow::addErrorMessage(const QString &message)
@@ -102,6 +104,8 @@ void MainWindow::addServerResponse(const QString &clientInfo, const QByteArray &
ui->serverMessages->insertHtml(colorizer.arg(messageColor, html));
}
+//! [0]
+
void MainWindow::on_connectButton_clicked()
{
if (lookupId != -1) {
diff --git a/examples/network/secureudpclient/mainwindow.h b/examples/network/secureudpclient/mainwindow.h
index b231b44627..0d443fd376 100644
--- a/examples/network/secureudpclient/mainwindow.h
+++ b/examples/network/secureudpclient/mainwindow.h
@@ -76,7 +76,6 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
-
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
@@ -94,7 +93,6 @@ private slots:
void lookupFinished(const QHostInfo &hostInfo);
private:
-
void updateUi();
void startNewConnection(const QHostAddress &address);
diff --git a/examples/network/secureudpserver/mainwindow.cpp b/examples/network/secureudpserver/mainwindow.cpp
index d751ec931d..ef1974c311 100644
--- a/examples/network/secureudpserver/mainwindow.cpp
+++ b/examples/network/secureudpserver/mainwindow.cpp
@@ -104,6 +104,7 @@ void MainWindow::updateUi()
: ui->startButton->setText(tr("Start listening"));
}
+//! [0]
const QString colorizer(QStringLiteral("<font color=\"%1\">%2</font><br>"));
void MainWindow::addErrorMessage(const QString &message)
@@ -134,3 +135,4 @@ void MainWindow::addClientMessage(const QString &peerInfo, const QByteArray &dat
QString::fromUtf8(plainText));
ui->messages->insertHtml(colorizer.arg(messageColor, html));
}
+//! [0]
diff --git a/examples/network/secureudpserver/mainwindow.h b/examples/network/secureudpserver/mainwindow.h
index 0c914f5021..b39d984d50 100644
--- a/examples/network/secureudpserver/mainwindow.h
+++ b/examples/network/secureudpserver/mainwindow.h
@@ -69,12 +69,10 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
-
MainWindow();
~MainWindow();
private slots:
-
void addErrorMessage(const QString &message);
void addWarningMessage(const QString &message);
void addInfoMessage(const QString &message);
@@ -85,7 +83,6 @@ private slots:
void on_quitButton_clicked();
private:
-
void updateUi();
Ui::MainWindow *ui = nullptr;
diff --git a/examples/network/secureudpserver/server.cpp b/examples/network/secureudpserver/server.cpp
index 763024e4f4..6870123163 100644
--- a/examples/network/secureudpserver/server.cpp
+++ b/examples/network/secureudpserver/server.cpp
@@ -87,6 +87,7 @@ QString connection_info(QSharedPointer<QDtls> connection)
} // unnamed namespace
+//! [1]
DtlsServer::DtlsServer()
{
connect(&serverSocket, &QAbstractSocket::readyRead, this, &DtlsServer::readyRead);
@@ -94,12 +95,14 @@ DtlsServer::DtlsServer()
serverConfiguration.setPreSharedKeyIdentityHint("Qt DTLS example server");
serverConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
}
+//! [1]
DtlsServer::~DtlsServer()
{
shutdown();
}
+//! [2]
bool DtlsServer::listen(const QHostAddress &address, quint16 port)
{
if (address != serverSocket.localAddress() || port != serverSocket.localPort()) {
@@ -113,6 +116,7 @@ bool DtlsServer::listen(const QHostAddress &address, quint16 port)
return listening;
}
+//! [2]
bool DtlsServer::isListening() const
{
@@ -126,6 +130,7 @@ void DtlsServer::close()
void DtlsServer::readyRead()
{
+ //! [3]
const qint64 bytesToRead = serverSocket.pendingDatagramSize();
if (bytesToRead <= 0) {
emit warningMessage(tr("A spurious read notification"));
@@ -143,7 +148,8 @@ void DtlsServer::readyRead()
}
dgram.resize(bytesRead);
-
+ //! [3]
+ //! [4]
if (peerAddress.isNull() || !peerPort) {
emit warningMessage(tr("Failed to extract peer info (address, port)"));
return;
@@ -154,20 +160,28 @@ void DtlsServer::readyRead()
return connection->peerAddress() == peerAddress
&& connection->peerPort() == peerPort;
});
+ //! [4]
+ //! [5]
if (client == knownClients.end())
return handleNewConnection(peerAddress, peerPort, dgram);
+ //! [5]
+ //! [6]
if ((*client)->isConnectionEncrypted()) {
decryptDatagram(*client, dgram);
if ((*client)->dtlsError() == QDtlsError::RemoteClosedConnectionError)
knownClients.erase(client);
return;
}
+ //! [6]
+ //! [7]
doHandshake(*client, dgram);
+ //! [7]
}
+//! [13]
void DtlsServer::pskRequired(QSslPreSharedKeyAuthenticator *auth)
{
Q_ASSERT(auth);
@@ -176,7 +190,9 @@ void DtlsServer::pskRequired(QSslPreSharedKeyAuthenticator *auth)
.arg(QString::fromLatin1(auth->identity())));
auth->setPreSharedKey(QByteArrayLiteral("\x1a\x2b\x3c\x4d\x5e\x6f"));
}
+//! [13]
+//! [8]
void DtlsServer::handleNewConnection(const QHostAddress &peerAddress,
quint16 peerPort, const QByteArray &clientHello)
{
@@ -186,7 +202,8 @@ void DtlsServer::handleNewConnection(const QHostAddress &peerAddress,
const QString peerInfo = peer_info(peerAddress, peerPort);
if (cookieSender.verifyClient(&serverSocket, clientHello, peerAddress, peerPort)) {
emit infoMessage(peerInfo + tr(": verified, starting a handshake"));
-
+ //! [8]
+ //! [9]
DtlsConnection newConnection(new QDtls(QSslSocket::SslServerMode));
newConnection->setDtlsConfiguration(serverConfiguration);
newConnection->setPeer(peerAddress, peerPort);
@@ -194,6 +211,7 @@ void DtlsServer::handleNewConnection(const QHostAddress &peerAddress,
this, &DtlsServer::pskRequired);
knownClients.push_back(newConnection);
doHandshake(newConnection, clientHello);
+ //! [9]
} else if (cookieSender.dtlsError() != QDtlsError::NoError) {
emit errorMessage(tr("DTLS error: ") + cookieSender.dtlsErrorString());
} else {
@@ -201,6 +219,7 @@ void DtlsServer::handleNewConnection(const QHostAddress &peerAddress,
}
}
+//! [11]
void DtlsServer::doHandshake(DtlsConnection newConnection, const QByteArray &clientHello)
{
const bool result = newConnection->doHandshake(&serverSocket, clientHello);
@@ -223,7 +242,9 @@ void DtlsServer::doHandshake(DtlsConnection newConnection, const QByteArray &cli
Q_UNREACHABLE();
}
}
+//! [11]
+//! [12]
void DtlsServer::decryptDatagram(DtlsConnection connection, const QByteArray &clientMessage)
{
Q_ASSERT(connection->isConnectionEncrypted());
@@ -239,7 +260,9 @@ void DtlsServer::decryptDatagram(DtlsConnection connection, const QByteArray &cl
emit errorMessage(peerInfo + ": " + connection->dtlsErrorString());
}
}
+//! [12]
+//! [14]
void DtlsServer::shutdown()
{
for (DtlsConnection &connection : knownClients)
@@ -248,5 +271,6 @@ void DtlsServer::shutdown()
knownClients.clear();
serverSocket.close();
}
+//! [14]
QT_END_NAMESPACE
diff --git a/examples/network/secureudpserver/server.h b/examples/network/secureudpserver/server.h
index 33444f7407..b720368e7b 100644
--- a/examples/network/secureudpserver/server.h
+++ b/examples/network/secureudpserver/server.h
@@ -57,12 +57,12 @@
QT_BEGIN_NAMESPACE
+//! [0]
class DtlsServer : public QObject
{
Q_OBJECT
public:
-
DtlsServer();
~DtlsServer();
@@ -71,7 +71,6 @@ public:
void close();
signals:
-
void errorMessage(const QString &message);
void warningMessage(const QString &message);
void infoMessage(const QString &message);
@@ -80,12 +79,10 @@ signals:
const QByteArray &plainText);
private slots:
-
void readyRead();
void pskRequired(QSslPreSharedKeyAuthenticator *auth);
private:
-
void handleNewConnection(const QHostAddress &peerAddress, quint16 peerPort,
const QByteArray &clientHello);
@@ -103,6 +100,7 @@ private:
Q_DISABLE_COPY(DtlsServer)
};
+//! [0]
QT_END_NAMESPACE