From aeada5e5175c947d8fbc25d71c03725f3e55620b Mon Sep 17 00:00:00 2001 From: Martin Koller Date: Sat, 16 Dec 2017 10:16:33 +0100 Subject: auto-connect to next DNS-SRV record server on connection failure automatically try next server from DNS SRV record when connection to first can not be established --- src/client/QXmppOutgoingClient.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'src/client/QXmppOutgoingClient.cpp') diff --git a/src/client/QXmppOutgoingClient.cpp b/src/client/QXmppOutgoingClient.cpp index b5c7052a..9d5043d0 100644 --- a/src/client/QXmppOutgoingClient.cpp +++ b/src/client/QXmppOutgoingClient.cpp @@ -60,6 +60,7 @@ class QXmppOutgoingClientPrivate public: QXmppOutgoingClientPrivate(QXmppOutgoingClient *q); void connectToHost(const QString &host, quint16 port); + void connectToNextDNSHost(); void sendNonSASLAuth(bool plaintext); void sendNonSASLAuthQuery(); @@ -74,6 +75,7 @@ public: // DNS QDnsLookup dns; + int nextSrvRecordIdx; // Stream QString streamId; @@ -113,7 +115,8 @@ private: }; QXmppOutgoingClientPrivate::QXmppOutgoingClientPrivate(QXmppOutgoingClient *qq) - : redirectPort(0) + : nextSrvRecordIdx(0) + , redirectPort(0) , bindModeAvailable(false) , sessionAvailable(false) , sessionStarted(false) @@ -156,6 +159,15 @@ void QXmppOutgoingClientPrivate::connectToHost(const QString &host, quint16 port } } +void QXmppOutgoingClientPrivate::connectToNextDNSHost() +{ + connectToHost( + dns.serviceRecords().at(nextSrvRecordIdx).target(), + dns.serviceRecords().at(nextSrvRecordIdx).port()); + + nextSrvRecordIdx++; +} + /// Constructs an outgoing client stream. /// /// \param parent @@ -245,6 +257,7 @@ void QXmppOutgoingClient::connectToHost() d->dns.setName("_xmpp-client._tcp." + domain); d->dns.setType(QDnsLookup::SRV); d->dns.lookup(); + d->nextSrvRecordIdx = 0; } void QXmppOutgoingClient::disconnectFromHost() @@ -258,9 +271,7 @@ void QXmppOutgoingClient::_q_dnsLookupFinished() if (d->dns.error() == QDnsLookup::NoError && !d->dns.serviceRecords().isEmpty()) { // take the first returned record - d->connectToHost( - d->dns.serviceRecords().first().target(), - d->dns.serviceRecords().first().port()); + d->connectToNextDNSHost(); } else { // as a fallback, use domain as the host name warning(QString("Lookup for domain %1 failed: %2") @@ -314,7 +325,14 @@ void QXmppOutgoingClient::socketSslErrors(const QList &errors) void QXmppOutgoingClient::socketError(QAbstractSocket::SocketError socketError) { Q_UNUSED(socketError); - emit error(QXmppClient::SocketError); + if ( !d->sessionStarted && + (d->dns.serviceRecords().count() > d->nextSrvRecordIdx) ) + { + // some network error occured during startup -> try next available SRV record server + d->connectToNextDNSHost(); + } + else + emit error(QXmppClient::SocketError); } /// \cond -- cgit v1.2.3