~ubuntu-branches/ubuntu/quantal/psi/quantal

« back to all changes in this revision

Viewing changes to iris/src/xmpp/xmpp-core/connector.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2009-09-25 17:49:51 UTC
  • mfrom: (6.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090925174951-lvm7kdap82o8xhn3
Tags: 0.13-1
* Updated to upstream version 0.13
* Set Standards-Version to 3.8.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * connector.cpp - establish a connection to an XMPP server
 
3
 * Copyright (C) 2003  Justin Karneges
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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
 
18
 *
 
19
 */
 
20
 
 
21
/*
 
22
  TODO:
 
23
 
 
24
  - Test and analyze all possible branches
 
25
 
 
26
  XMPP::AdvancedConnector is "good for now."  The only real issue is that
 
27
  most of what it provides is just to work around the old Jabber/XMPP 0.9
 
28
  connection behavior.  When XMPP 1.0 has taken over the world, we can
 
29
  greatly simplify this class.  - Sep 3rd, 2003.
 
30
*/
 
31
 
 
32
#include "xmpp.h"
 
33
 
 
34
#include <qpointer.h>
 
35
#include <qca.h>
 
36
#include <QList>
 
37
#include <QUrl>
 
38
#include <QTimer>
 
39
#include "safedelete.h"
 
40
#include <libidn/idna.h>
 
41
 
 
42
#include "ndns.h"
 
43
 
 
44
#include "bsocket.h"
 
45
#include "httpconnect.h"
 
46
#include "httppoll.h"
 
47
#include "socks.h"
 
48
#include "srvresolver.h"
 
49
 
 
50
//#define XMPP_DEBUG
 
51
 
 
52
using namespace XMPP;
 
53
 
 
54
//----------------------------------------------------------------------------
 
55
// Connector
 
56
//----------------------------------------------------------------------------
 
57
Connector::Connector(QObject *parent)
 
58
:QObject(parent)
 
59
{
 
60
        setUseSSL(false);
 
61
        setPeerAddressNone();
 
62
}
 
63
 
 
64
Connector::~Connector()
 
65
{
 
66
}
 
67
 
 
68
bool Connector::useSSL() const
 
69
{
 
70
        return ssl;
 
71
}
 
72
 
 
73
bool Connector::havePeerAddress() const
 
74
{
 
75
        return haveaddr;
 
76
}
 
77
 
 
78
QHostAddress Connector::peerAddress() const
 
79
{
 
80
        return addr;
 
81
}
 
82
 
 
83
quint16 Connector::peerPort() const
 
84
{
 
85
        return port;
 
86
}
 
87
 
 
88
void Connector::setUseSSL(bool b)
 
89
{
 
90
        ssl = b;
 
91
}
 
92
 
 
93
void Connector::setPeerAddressNone()
 
94
{
 
95
        haveaddr = false;
 
96
        addr = QHostAddress();
 
97
        port = 0;
 
98
}
 
99
 
 
100
void Connector::setPeerAddress(const QHostAddress &_addr, quint16 _port)
 
101
{
 
102
        haveaddr = true;
 
103
        addr = _addr;
 
104
        port = _port;
 
105
}
 
106
 
 
107
QString Connector::host() const
 
108
{
 
109
        return QString();
 
110
}
 
111
 
 
112
 
 
113
//----------------------------------------------------------------------------
 
114
// AdvancedConnector::Proxy
 
115
//----------------------------------------------------------------------------
 
116
AdvancedConnector::Proxy::Proxy()
 
117
{
 
118
        t = None;
 
119
        v_poll = 30;
 
120
}
 
121
 
 
122
AdvancedConnector::Proxy::~Proxy()
 
123
{
 
124
}
 
125
 
 
126
int AdvancedConnector::Proxy::type() const
 
127
{
 
128
        return t;
 
129
}
 
130
 
 
131
QString AdvancedConnector::Proxy::host() const
 
132
{
 
133
        return v_host;
 
134
}
 
135
 
 
136
quint16 AdvancedConnector::Proxy::port() const
 
137
{
 
138
        return v_port;
 
139
}
 
140
 
 
141
QString AdvancedConnector::Proxy::url() const
 
142
{
 
143
        return v_url;
 
144
}
 
145
 
 
146
QString AdvancedConnector::Proxy::user() const
 
147
{
 
148
        return v_user;
 
149
}
 
150
 
 
151
QString AdvancedConnector::Proxy::pass() const
 
152
{
 
153
        return v_pass;
 
154
}
 
155
 
 
156
int AdvancedConnector::Proxy::pollInterval() const
 
157
{
 
158
        return v_poll;
 
159
}
 
160
 
 
161
void AdvancedConnector::Proxy::setHttpConnect(const QString &host, quint16 port)
 
162
{
 
163
        t = HttpConnect;
 
164
        v_host = host;
 
165
        v_port = port;
 
166
}
 
167
 
 
168
void AdvancedConnector::Proxy::setHttpPoll(const QString &host, quint16 port, const QString &url)
 
169
{
 
170
        t = HttpPoll;
 
171
        v_host = host;
 
172
        v_port = port;
 
173
        v_url = url;
 
174
}
 
175
 
 
176
void AdvancedConnector::Proxy::setSocks(const QString &host, quint16 port)
 
177
{
 
178
        t = Socks;
 
179
        v_host = host;
 
180
        v_port = port;
 
181
}
 
182
 
 
183
void AdvancedConnector::Proxy::setUserPass(const QString &user, const QString &pass)
 
184
{
 
185
        v_user = user;
 
186
        v_pass = pass;
 
187
}
 
188
 
 
189
void AdvancedConnector::Proxy::setPollInterval(int secs)
 
190
{
 
191
        v_poll = secs;
 
192
}
 
193
 
 
194
 
 
195
//----------------------------------------------------------------------------
 
196
// AdvancedConnector
 
197
//----------------------------------------------------------------------------
 
198
enum { Idle, Connecting, Connected };
 
199
class AdvancedConnector::Private
 
200
{
 
201
public:
 
202
        int mode;
 
203
        ByteStream *bs;
 
204
        NDns dns;
 
205
        SrvResolver srv;
 
206
 
 
207
        QString server;
 
208
        QStringList opt_hosts;
 
209
        int opt_port;
 
210
        bool opt_probe, opt_ssl;
 
211
        Proxy proxy;
 
212
 
 
213
        QStringList hostsToTry;
 
214
        QString host;
 
215
        int port;
 
216
        QList<Q3Dns::Server> servers;
 
217
        int errorCode;
 
218
        QString connectHost;
 
219
 
 
220
        bool multi, using_srv;
 
221
        bool will_be_ssl;
 
222
        int probe_mode;
 
223
 
 
224
        bool aaaa;
 
225
        SafeDelete sd;
 
226
 
 
227
        QTimer connectTimeout;
 
228
};
 
229
 
 
230
AdvancedConnector::AdvancedConnector(QObject *parent)
 
231
:Connector(parent)
 
232
{
 
233
        d = new Private;
 
234
        d->bs = 0;
 
235
        connect(&d->dns, SIGNAL(resultsReady()), SLOT(dns_done()));
 
236
        connect(&d->srv, SIGNAL(resultsReady()), SLOT(srv_done()));
 
237
        connect(&d->connectTimeout, SIGNAL(timeout()), SLOT(t_timeout()));
 
238
        d->connectTimeout.setSingleShot(true);
 
239
        d->opt_probe = false;
 
240
        d->opt_ssl = false;
 
241
        cleanup();
 
242
        d->errorCode = 0;
 
243
}
 
244
 
 
245
AdvancedConnector::~AdvancedConnector()
 
246
{
 
247
        cleanup();
 
248
        delete d;
 
249
}
 
250
 
 
251
void AdvancedConnector::cleanup()
 
252
{
 
253
        d->mode = Idle;
 
254
 
 
255
        // stop any dns
 
256
        if(d->dns.isBusy())
 
257
                d->dns.stop();
 
258
        if(d->srv.isBusy())
 
259
                d->srv.stop();
 
260
 
 
261
        // destroy the bytestream, if there is one
 
262
        delete d->bs;
 
263
        d->bs = 0;
 
264
 
 
265
        d->multi = false;
 
266
        d->using_srv = false;
 
267
        d->will_be_ssl = false;
 
268
        d->probe_mode = -1;
 
269
 
 
270
        setUseSSL(false);
 
271
        setPeerAddressNone();
 
272
}
 
273
 
 
274
void AdvancedConnector::setProxy(const Proxy &proxy)
 
275
{
 
276
        if(d->mode != Idle)
 
277
                return;
 
278
        d->proxy = proxy;
 
279
}
 
280
 
 
281
void AdvancedConnector::setOptHostPort(const QString &host, quint16 _port)
 
282
{
 
283
        if(d->mode != Idle)
 
284
                return;
 
285
        // empty host means disable explicit host support
 
286
        if(host.isEmpty()) {
 
287
                d->opt_hosts.clear();
 
288
                return;
 
289
        }
 
290
        d->opt_hosts = QStringList() << host;
 
291
        d->opt_port = _port;
 
292
}
 
293
 
 
294
void AdvancedConnector::setOptHostsPort(const QStringList &_hosts, quint16 _port)
 
295
{
 
296
        if(d->mode != Idle)
 
297
                return;
 
298
        d->opt_hosts = _hosts;
 
299
        d->opt_port = _port;
 
300
}
 
301
 
 
302
void AdvancedConnector::setOptProbe(bool b)
 
303
{
 
304
        if(d->mode != Idle)
 
305
                return;
 
306
        d->opt_probe = b;
 
307
}
 
308
 
 
309
void AdvancedConnector::setOptSSL(bool b)
 
310
{
 
311
        if(d->mode != Idle)
 
312
                return;
 
313
        d->opt_ssl = b;
 
314
}
 
315
 
 
316
void AdvancedConnector::connectToServer(const QString &server)
 
317
{
 
318
        if(d->mode != Idle)
 
319
                return;
 
320
        if(server.isEmpty())
 
321
                return;
 
322
 
 
323
        d->hostsToTry.clear();
 
324
        d->errorCode = 0;
 
325
        d->mode = Connecting;
 
326
        d->aaaa = true;
 
327
        d->connectHost.clear();
 
328
 
 
329
        // Encode the servername
 
330
        d->server = QUrl::toAce(server);
 
331
        //char* server_encoded;
 
332
        //if (!idna_to_ascii_8z(server.utf8().data(), &server_encoded, 0)) {
 
333
        //      d->server = QString(server_encoded);
 
334
        //      free(server_encoded);
 
335
        //}
 
336
        //else {
 
337
        //      d->server = server;
 
338
        //}
 
339
 
 
340
        if(d->proxy.type() == Proxy::HttpPoll) {
 
341
                // need SHA1 here
 
342
                //if(!QCA::isSupported(QCA::CAP_SHA1))
 
343
                //      QCA::insertProvider(createProviderHash());
 
344
 
 
345
                HttpPoll *s = new HttpPoll;
 
346
                d->bs = s;
 
347
                connect(s, SIGNAL(connected()), SLOT(bs_connected()));
 
348
                connect(s, SIGNAL(syncStarted()), SLOT(http_syncStarted()));
 
349
                connect(s, SIGNAL(syncFinished()), SLOT(http_syncFinished()));
 
350
                connect(s, SIGNAL(error(int)), SLOT(bs_error(int)));
 
351
                if(!d->proxy.user().isEmpty())
 
352
                        s->setAuth(d->proxy.user(), d->proxy.pass());
 
353
                s->setPollInterval(d->proxy.pollInterval());
 
354
 
 
355
                if(d->proxy.host().isEmpty())
 
356
                        s->connectToUrl(d->proxy.url());
 
357
                else
 
358
                        s->connectToHost(d->proxy.host(), d->proxy.port(), d->proxy.url());
 
359
        }
 
360
        else if (d->proxy.type() == Proxy::HttpConnect) {
 
361
                if(!d->opt_hosts.isEmpty()) {
 
362
                        d->hostsToTry = d->opt_hosts;
 
363
                        d->host = d->hostsToTry.takeFirst();
 
364
                        d->port = d->opt_port;
 
365
                }
 
366
                else {
 
367
                        d->host = server;
 
368
                        d->port = 5222;
 
369
                }
 
370
                do_connect();
 
371
        }
 
372
        else {
 
373
                if(!d->opt_hosts.isEmpty()) {
 
374
                        d->hostsToTry = d->opt_hosts;
 
375
                        d->host = d->hostsToTry.takeFirst();
 
376
                        d->port = d->opt_port;
 
377
                        do_resolve();
 
378
                }
 
379
                else {
 
380
                        d->multi = true;
 
381
 
 
382
                        QPointer<QObject> self = this;
 
383
                        srvLookup(d->server);
 
384
                        if(!self)
 
385
                                return;
 
386
 
 
387
                        d->srv.resolveSrvOnly(d->server, "xmpp-client", "tcp");
 
388
                }
 
389
        }
 
390
}
 
391
 
 
392
void AdvancedConnector::changePollInterval(int secs)
 
393
{
 
394
        if(d->bs && (d->bs->inherits("XMPP::HttpPoll") || d->bs->inherits("HttpPoll"))) {
 
395
                HttpPoll *s = static_cast<HttpPoll*>(d->bs);
 
396
                s->setPollInterval(secs);
 
397
        }
 
398
}
 
399
 
 
400
ByteStream *AdvancedConnector::stream() const
 
401
{
 
402
        if(d->mode == Connected)
 
403
                return d->bs;
 
404
        else
 
405
                return 0;
 
406
}
 
407
 
 
408
void AdvancedConnector::done()
 
409
{
 
410
        cleanup();
 
411
}
 
412
 
 
413
int AdvancedConnector::errorCode() const
 
414
{
 
415
        return d->errorCode;
 
416
}
 
417
 
 
418
void AdvancedConnector::do_resolve()
 
419
{
 
420
        d->dns.resolve(d->host);
 
421
}
 
422
 
 
423
void AdvancedConnector::dns_done()
 
424
{
 
425
        bool failed = false;
 
426
        QHostAddress addr;
 
427
 
 
428
        if(d->dns.result().isNull ())
 
429
                failed = true;
 
430
        else
 
431
                addr = QHostAddress(d->dns.result());
 
432
 
 
433
        if(failed) {
 
434
#ifdef XMPP_DEBUG
 
435
                printf("dns1\n");
 
436
#endif
 
437
                // using proxy?  then try the unresolved host through the proxy
 
438
                if(d->proxy.type() != Proxy::None) {
 
439
#ifdef XMPP_DEBUG
 
440
                        printf("dns1.1\n");
 
441
#endif
 
442
                        do_connect();
 
443
                }
 
444
                else if(d->using_srv) {
 
445
#ifdef XMPP_DEBUG
 
446
                        printf("dns1.2\n");
 
447
#endif
 
448
                        if(d->servers.isEmpty()) {
 
449
#ifdef XMPP_DEBUG
 
450
                                printf("dns1.2.1\n");
 
451
#endif
 
452
                                cleanup();
 
453
                                d->errorCode = ErrConnectionRefused;
 
454
                                error();
 
455
                        }
 
456
                        else {
 
457
#ifdef XMPP_DEBUG
 
458
                                printf("dns1.2.2\n");
 
459
#endif
 
460
                                tryNextSrv();
 
461
                                return;
 
462
                        }
 
463
                }
 
464
                else {
 
465
#ifdef XMPP_DEBUG
 
466
                        printf("dns1.3\n");
 
467
#endif
 
468
                        if(!d->hostsToTry.isEmpty())
 
469
                        {
 
470
                                d->aaaa = true;
 
471
                                d->host = d->hostsToTry.takeFirst();
 
472
                                do_resolve();
 
473
                                return;
 
474
                        }
 
475
 
 
476
                        cleanup();
 
477
                        d->errorCode = ErrHostNotFound;
 
478
                        error();
 
479
                }
 
480
        }
 
481
        else {
 
482
#ifdef XMPP_DEBUG
 
483
                printf("dns2\n");
 
484
#endif
 
485
                d->connectHost = d->host;
 
486
                d->host = addr.toString();
 
487
                do_connect();
 
488
        }
 
489
}
 
490
 
 
491
void AdvancedConnector::do_connect()
 
492
{
 
493
        // 5 seconds to connect
 
494
        d->connectTimeout.start(5000);
 
495
 
 
496
#ifdef XMPP_DEBUG
 
497
        printf("trying %s:%d\n", d->host.latin1(), d->port);
 
498
#endif
 
499
        int t = d->proxy.type();
 
500
        if(t == Proxy::None) {
 
501
#ifdef XMPP_DEBUG
 
502
                printf("do_connect1\n");
 
503
#endif
 
504
                BSocket *s = new BSocket;
 
505
                d->bs = s;
 
506
                connect(s, SIGNAL(connected()), SLOT(bs_connected()));
 
507
                connect(s, SIGNAL(error(int)), SLOT(bs_error(int)));
 
508
                s->connectToHost(d->host, d->port);
 
509
        }
 
510
        else if(t == Proxy::HttpConnect) {
 
511
#ifdef XMPP_DEBUG
 
512
                printf("do_connect2\n");
 
513
#endif
 
514
                HttpConnect *s = new HttpConnect;
 
515
                d->bs = s;
 
516
                connect(s, SIGNAL(connected()), SLOT(bs_connected()));
 
517
                connect(s, SIGNAL(error(int)), SLOT(bs_error(int)));
 
518
                if(!d->proxy.user().isEmpty())
 
519
                        s->setAuth(d->proxy.user(), d->proxy.pass());
 
520
                s->connectToHost(d->proxy.host(), d->proxy.port(), d->host, d->port);
 
521
        }
 
522
        else if(t == Proxy::Socks) {
 
523
#ifdef XMPP_DEBUG
 
524
                printf("do_connect3\n");
 
525
#endif
 
526
                SocksClient *s = new SocksClient;
 
527
                d->bs = s;
 
528
                connect(s, SIGNAL(connected()), SLOT(bs_connected()));
 
529
                connect(s, SIGNAL(error(int)), SLOT(bs_error(int)));
 
530
                if(!d->proxy.user().isEmpty())
 
531
                        s->setAuth(d->proxy.user(), d->proxy.pass());
 
532
                s->connectToHost(d->proxy.host(), d->proxy.port(), d->host, d->port);
 
533
        }
 
534
}
 
535
 
 
536
void AdvancedConnector::tryNextSrv()
 
537
{
 
538
#ifdef XMPP_DEBUG
 
539
        printf("trying next srv\n");
 
540
#endif
 
541
        Q_ASSERT(!d->servers.isEmpty());
 
542
        d->host = d->servers.first().name;
 
543
        d->port = d->servers.first().port;
 
544
        d->servers.takeFirst();
 
545
        do_resolve();
 
546
}
 
547
 
 
548
void AdvancedConnector::srv_done()
 
549
{
 
550
        QPointer<QObject> self = this;
 
551
#ifdef XMPP_DEBUG
 
552
        printf("srv_done1\n");
 
553
#endif
 
554
        d->servers = d->srv.servers();
 
555
        if(d->servers.isEmpty()) {
 
556
                srvResult(false);
 
557
                if(!self)
 
558
                        return;
 
559
 
 
560
#ifdef XMPP_DEBUG
 
561
                printf("srv_done1.1\n");
 
562
#endif
 
563
                // fall back to A record
 
564
                d->using_srv = false;
 
565
                d->host = d->server;
 
566
                if(d->opt_probe) {
 
567
#ifdef XMPP_DEBUG
 
568
                        printf("srv_done1.1.1\n");
 
569
#endif
 
570
                        d->probe_mode = 0;
 
571
                        d->port = 5223;
 
572
                        d->will_be_ssl = true;
 
573
                }
 
574
                else {
 
575
#ifdef XMPP_DEBUG
 
576
                        printf("srv_done1.1.2\n");
 
577
#endif
 
578
                        d->probe_mode = 1;
 
579
                        d->port = 5222;
 
580
                }
 
581
                do_resolve();
 
582
                return;
 
583
        }
 
584
 
 
585
        srvResult(true);
 
586
        if(!self)
 
587
                return;
 
588
 
 
589
        d->using_srv = true;
 
590
        tryNextSrv();
 
591
}
 
592
 
 
593
void AdvancedConnector::bs_connected()
 
594
{
 
595
        d->connectTimeout.stop();
 
596
 
 
597
        if(d->proxy.type() == Proxy::None) {
 
598
                QHostAddress h = (static_cast<BSocket*>(d->bs))->peerAddress();
 
599
                int p = (static_cast<BSocket*>(d->bs))->peerPort();
 
600
                setPeerAddress(h, p);
 
601
        }
 
602
 
 
603
        // only allow ssl override if proxy==poll or host:port
 
604
        if((d->proxy.type() == Proxy::HttpPoll || !d->opt_hosts.isEmpty()) && d->opt_ssl)
 
605
                setUseSSL(true);
 
606
        else if(d->will_be_ssl)
 
607
                setUseSSL(true);
 
608
 
 
609
        d->mode = Connected;
 
610
        connected();
 
611
}
 
612
 
 
613
void AdvancedConnector::bs_error(int x)
 
614
{
 
615
        if(d->mode == Connected) {
 
616
                d->errorCode = ErrStream;
 
617
                error();
 
618
                return;
 
619
        }
 
620
 
 
621
        bool proxyError = false;
 
622
        int err = ErrConnectionRefused;
 
623
        int t = d->proxy.type();
 
624
 
 
625
#ifdef XMPP_DEBUG
 
626
        printf("bse1\n");
 
627
#endif
 
628
 
 
629
        // figure out the error
 
630
        if(t == Proxy::None) {
 
631
                if(x == BSocket::ErrHostNotFound)
 
632
                        err = ErrHostNotFound;
 
633
                else
 
634
                        err = ErrConnectionRefused;
 
635
        }
 
636
        else if(t == Proxy::HttpConnect) {
 
637
                if(x == HttpConnect::ErrConnectionRefused)
 
638
                        err = ErrConnectionRefused;
 
639
                else if(x == HttpConnect::ErrHostNotFound)
 
640
                        err = ErrHostNotFound;
 
641
                else {
 
642
                        proxyError = true;
 
643
                        if(x == HttpConnect::ErrProxyAuth)
 
644
                                err = ErrProxyAuth;
 
645
                        else if(x == HttpConnect::ErrProxyNeg)
 
646
                                err = ErrProxyNeg;
 
647
                        else
 
648
                                err = ErrProxyConnect;
 
649
                }
 
650
        }
 
651
        else if(t == Proxy::HttpPoll) {
 
652
                if(x == HttpPoll::ErrConnectionRefused)
 
653
                        err = ErrConnectionRefused;
 
654
                else if(x == HttpPoll::ErrHostNotFound)
 
655
                        err = ErrHostNotFound;
 
656
                else {
 
657
                        proxyError = true;
 
658
                        if(x == HttpPoll::ErrProxyAuth)
 
659
                                err = ErrProxyAuth;
 
660
                        else if(x == HttpPoll::ErrProxyNeg)
 
661
                                err = ErrProxyNeg;
 
662
                        else
 
663
                                err = ErrProxyConnect;
 
664
                }
 
665
        }
 
666
        else if(t == Proxy::Socks) {
 
667
                if(x == SocksClient::ErrConnectionRefused)
 
668
                        err = ErrConnectionRefused;
 
669
                else if(x == SocksClient::ErrHostNotFound)
 
670
                        err = ErrHostNotFound;
 
671
                else {
 
672
                        proxyError = true;
 
673
                        if(x == SocksClient::ErrProxyAuth)
 
674
                                err = ErrProxyAuth;
 
675
                        else if(x == SocksClient::ErrProxyNeg)
 
676
                                err = ErrProxyNeg;
 
677
                        else
 
678
                                err = ErrProxyConnect;
 
679
                }
 
680
        }
 
681
 
 
682
        // try next host, if any
 
683
        if(!d->hostsToTry.isEmpty())
 
684
        {
 
685
                d->aaaa = true;
 
686
                d->host = d->hostsToTry.takeFirst();
 
687
                do_resolve();
 
688
                return;
 
689
        }
 
690
 
 
691
        // no-multi or proxy error means we quit
 
692
        if(!d->multi || proxyError) {
 
693
                cleanup();
 
694
                d->errorCode = err;
 
695
                error();
 
696
                return;
 
697
        }
 
698
 
 
699
        if(d->using_srv && !d->servers.isEmpty()) {
 
700
#ifdef XMPP_DEBUG
 
701
                printf("bse1.1\n");
 
702
#endif
 
703
                tryNextSrv();
 
704
        }
 
705
        else if(!d->using_srv && d->opt_probe && d->probe_mode == 0) {
 
706
#ifdef XMPP_DEBUG
 
707
                printf("bse1.2\n");
 
708
#endif
 
709
                d->probe_mode = 1;
 
710
                d->port = 5222;
 
711
                d->will_be_ssl = false;
 
712
                do_connect();
 
713
        }
 
714
        else {
 
715
#ifdef XMPP_DEBUG
 
716
                printf("bse1.3\n");
 
717
#endif
 
718
                cleanup();
 
719
                d->errorCode = ErrConnectionRefused;
 
720
                error();
 
721
        }
 
722
}
 
723
 
 
724
void AdvancedConnector::http_syncStarted()
 
725
{
 
726
        httpSyncStarted();
 
727
}
 
728
 
 
729
void AdvancedConnector::http_syncFinished()
 
730
{
 
731
        httpSyncFinished();
 
732
}
 
733
 
 
734
void AdvancedConnector::t_timeout()
 
735
{
 
736
        // skip to next host, if there is one
 
737
        if(!d->hostsToTry.isEmpty())
 
738
        {
 
739
                delete d->bs;
 
740
                d->bs = 0;
 
741
 
 
742
                d->aaaa = true;
 
743
                d->host = d->hostsToTry.takeFirst();
 
744
                do_resolve();
 
745
        }
 
746
}
 
747
 
 
748
QString AdvancedConnector::host() const
 
749
{
 
750
        return d->connectHost;
 
751
}