3#include <QtCore/QtEndian>
4#include <QtNetwork/QHostAddress>
5#include <QtNetwork/QHostInfo>
6#include <QtNetwork/QSslConfiguration>
7#include <QtNetwork/QSslSocket>
8#include <QtNetwork/QUdpSocket>
26 _socket =
new QUdpSocket(
this);
29 if (data.size() > kMaxDatagramSize) {
30 emit
errorOccurred(tr(
"UDP payload too large (%1 bytes), dropped").arg(data.size()));
34 QHostAddress addr(_host);
37 const QHostInfo info = QHostInfo::fromName(_host);
38 if (info.error() != QHostInfo::NoError || info.addresses().isEmpty()) {
39 emit
errorOccurred(tr(
"DNS resolution failed for '%1': %2").arg(_host, info.errorString()));
42 addr = info.addresses().first();
44 const qint64 written = _socket->writeDatagram(data, addr, _port);
56 _socket->deleteLater();
86 if (!_socket || !_connected) {
91 frame.reserve(4 + data.size());
92 const quint32 len = qToBigEndian(
static_cast<quint32
>(data.size()));
93 frame.append(
reinterpret_cast<const char *
>(&len), 4);
96 const qint64 written = _socket->write(frame);
107 _socket->disconnect(
this);
108 _socket->disconnectFromHost();
109 _socket->deleteLater();
120 if (_socket && _socket->state() != QAbstractSocket::UnconnectedState) {
127 _socket->connectToHostEncrypted(_host, _port);
129 _socket->connectToHost(_host, _port);
133void TcpTransport::_createSocket()
136 _socket->deleteLater();
140 _socket =
new QSslSocket(
this);
143 QSslConfiguration config = QSslConfiguration::defaultConfiguration();
144 if (!_caCertificates.isEmpty()) {
145 config.setCaCertificates(_caCertificates);
147 if (!_clientCert.isNull()) {
148 config.setLocalCertificate(_clientCert);
149 config.setPrivateKey(_clientKey);
151 if (!_tlsVerifyPeer) {
152 config.setPeerVerifyMode(QSslSocket::VerifyNone);
154 _socket->setSslConfiguration(config);
155 connect(_socket, &QSslSocket::sslErrors,
this, &TcpTransport::_onSslErrors);
158 connect(_socket, &QAbstractSocket::connected,
this, &TcpTransport::_onConnected);
159 connect(_socket, &QAbstractSocket::disconnected,
this, &TcpTransport::_onDisconnected);
160 connect(_socket, &QAbstractSocket::errorOccurred,
this, &TcpTransport::_onError);
163void TcpTransport::_onConnected()
169void TcpTransport::_onDisconnected()
175void TcpTransport::_onError(QAbstractSocket::SocketError)
182void TcpTransport::_onSslErrors(
const QList<QSslError> &errors)
184 QStringList messages;
185 for (
const auto &err : errors) {
186 messages.append(err.errorString());
188 emit
errorOccurred(QStringLiteral(
"TLS: ") + messages.join(QStringLiteral(
"; ")));
190 if (!_tlsVerifyPeer && _socket) {
192 QList<QSslError> certErrors;
193 for (
const auto &err : errors) {
194 switch (err.error()) {
195 case QSslError::SelfSignedCertificate:
196 case QSslError::SelfSignedCertificateInChain:
197 case QSslError::CertificateUntrusted:
198 case QSslError::CertificateNotYetValid:
199 case QSslError::CertificateExpired:
200 case QSslError::HostNameMismatch:
201 case QSslError::UnableToGetLocalIssuerCertificate:
202 case QSslError::UnableToVerifyFirstCertificate:
203 certErrors.append(err);
209 if (!certErrors.isEmpty()) {
210 _socket->ignoreSslErrors(certErrors);
void errorOccurred(const QString &message)
bool send(const QByteArray &data) override
void setTlsCaCertificates(const QList< QSslCertificate > &certs)
void setTlsEnabled(bool enabled)
void setTlsVerifyPeer(bool verify)
void setTlsClientCertificate(const QSslCertificate &cert, const QSslKey &key)
TcpTransport(QObject *parent=nullptr)
void setTarget(const QString &host, quint16 port)
bool send(const QByteArray &data) override
UdpTransport(QObject *parent=nullptr)
void setTarget(const QString &host, quint16 port)