aboutsummaryrefslogtreecommitdiff
path: root/src/client/QXmppOutgoingClient.cpp
diff options
context:
space:
mode:
authorMartin Koller <kollix@aon.at>2017-12-16 10:16:33 +0100
committerJeremy Lainé <jeremy.laine@m4x.org>2018-09-08 09:55:46 +0200
commitaeada5e5175c947d8fbc25d71c03725f3e55620b (patch)
treea1747ce55f1b07b20c04bacca131f80b6fc8a5c1 /src/client/QXmppOutgoingClient.cpp
parent0ef60d1a4e8f75b0a5658df1a880caef92b98f20 (diff)
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
Diffstat (limited to 'src/client/QXmppOutgoingClient.cpp')
-rw-r--r--src/client/QXmppOutgoingClient.cpp28
1 files changed, 23 insertions, 5 deletions
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<QSslError> &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