2
* srvresolver.cpp - class to simplify SRV lookups
3
* Copyright (C) 2003 Justin Karneges
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
#include "srvresolver.h"
29
static void sortSRVList(QList<Q3Dns::Server> &list)
31
QList<Q3Dns::Server> tmp = list;
34
while(!tmp.isEmpty()) {
35
QList<Q3Dns::Server>::Iterator p = tmp.end();
36
for(QList<Q3Dns::Server>::Iterator it = tmp.begin(); it != tmp.end(); ++it) {
40
int a = (*it).priority;
41
int b = (*p).priority;
44
if(a < b || (a == b && j < k))
53
class SrvResolver::Private
58
XMPP::NameResolver nndns;
59
XMPP::NameRecord::Type nntype;
67
QHostAddress resultAddress;
72
QList<Q3Dns::Server> servers;
78
SrvResolver::SrvResolver(QObject *parent)
82
d->nndns_busy = false;
84
connect(&d->nndns, SIGNAL(resultsReady(const QList<XMPP::NameRecord> &)), SLOT(nndns_resultsReady(const QList<XMPP::NameRecord> &)));
85
connect(&d->nndns, SIGNAL(error(XMPP::NameResolver::Error)), SLOT(nndns_error(XMPP::NameResolver::Error)));
88
connect(&d->ndns, SIGNAL(resultsReady()), SLOT(ndns_done()));
90
connect(&d->t, SIGNAL(timeout()), SLOT(t_timeout()));
94
SrvResolver::~SrvResolver()
100
void SrvResolver::resolve(const QString &server, const QString &type, const QString &proto)
106
d->srv = QString("_") + type + "._" + proto + '.' + server;
107
d->t.setSingleShot(true);
109
d->nndns_busy = true;
110
d->nntype = XMPP::NameRecord::Srv;
111
d->nndns.start(d->srv.toLatin1(), d->nntype);
114
void SrvResolver::resolveSrvOnly(const QString &server, const QString &type, const QString &proto)
120
d->srv = QString("_") + type + "._" + proto + '.' + server;
121
d->t.setSingleShot(true);
123
d->nndns_busy = true;
124
d->nntype = XMPP::NameRecord::Srv;
125
d->nndns.start(d->srv.toLatin1(), d->nntype);
128
void SrvResolver::next()
130
if(d->servers.isEmpty())
136
void SrvResolver::stop()
142
d->nndns_busy = false;
148
d->resultAddress = QHostAddress();
155
bool SrvResolver::isBusy() const
158
if(d->nndns_busy || d->ndns.isBusy())
167
QList<Q3Dns::Server> SrvResolver::servers() const
172
bool SrvResolver::failed() const
177
QHostAddress SrvResolver::resultAddress() const
179
return d->resultAddress;
182
quint16 SrvResolver::resultPort() const
184
return d->resultPort;
187
void SrvResolver::tryNext()
190
d->ndns.resolve(d->servers.first().name);
192
d->nndns_busy = true;
193
d->nntype = d->aaaa ? XMPP::NameRecord::Aaaa : XMPP::NameRecord::A;
194
d->nndns.start(d->servers.first().name.toLatin1(), d->nntype);
198
void SrvResolver::nndns_resultsReady(const QList<XMPP::NameRecord> &results)
205
if(d->nntype == XMPP::NameRecord::Srv) {
206
// grab the server list and destroy the qdns object
207
QList<Q3Dns::Server> list;
208
for(int n = 0; n < results.count(); ++n)
210
list += Q3Dns::Server(QString::fromLatin1(results[n].name()), results[n].priority(), results[n].weight(), results[n].port());
213
d->nndns_busy = false;
233
// grab the address list and destroy the qdns object
234
QList<QHostAddress> list;
235
if(d->nntype == XMPP::NameRecord::A || d->nntype == XMPP::NameRecord::Aaaa)
237
for(int n = 0; n < results.count(); ++n)
239
list += results[n].address();
242
d->nndns_busy = false;
245
if(!list.isEmpty()) {
246
int port = d->servers.first().port;
247
d->servers.removeFirst();
250
d->resultAddress = list.first();
251
d->resultPort = port;
256
d->servers.removeFirst();
259
// failed? bail if last one
260
if(d->servers.isEmpty()) {
266
// otherwise try the next
272
void SrvResolver::nndns_error(XMPP::NameResolver::Error)
274
nndns_resultsReady(QList<XMPP::NameRecord>());
277
void SrvResolver::ndns_done()
280
QHostAddress r = d->ndns.result();
281
int port = d->servers.first().port;
282
d->servers.removeFirst();
285
d->resultAddress = d->ndns.result();
286
d->resultPort = port;
290
// failed? bail if last one
291
if(d->servers.isEmpty()) {
297
// otherwise try the next
303
void SrvResolver::t_timeout()