~ubuntu-branches/ubuntu/saucy/kopete/saucy-proposed

« back to all changes in this revision

Viewing changes to protocols/jabber/libiris/src/irisnet/corelib/addressresolver.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-06-21 02:22:39 UTC
  • Revision ID: package-import@ubuntu.com-20130621022239-63l3zc8p0nf26pt6
Tags: upstream-4.10.80
ImportĀ upstreamĀ versionĀ 4.10.80

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010  Barracuda Networks, Inc.
 
3
 *
 
4
 * This library is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU Lesser General Public
 
6
 * License as published by the Free Software Foundation; either
 
7
 * version 2.1 of the License, or (at your option) any later version.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * Lesser General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Lesser General Public
 
15
 * License along with this library; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
17
 *
 
18
 */
 
19
 
 
20
#include "addressresolver.h"
 
21
 
 
22
#include "objectsession.h"
 
23
#include "netnames.h"
 
24
 
 
25
namespace XMPP {
 
26
 
 
27
class AddressResolver::Private : public QObject
 
28
{
 
29
        Q_OBJECT
 
30
 
 
31
public:
 
32
        enum State
 
33
        {
 
34
                AddressWait,
 
35
                AddressFirstCome
 
36
        };
 
37
 
 
38
        AddressResolver *q;
 
39
        ObjectSession sess;
 
40
        State state;
 
41
        NameResolver req6;
 
42
        NameResolver req4;
 
43
        bool done6;
 
44
        bool done4;
 
45
        QList<QHostAddress> addrs6;
 
46
        QList<QHostAddress> addrs4;
 
47
        QTimer *opTimer;
 
48
 
 
49
        Private(AddressResolver *_q) :
 
50
                QObject(_q),
 
51
                q(_q),
 
52
                sess(this),
 
53
                req6(this),
 
54
                req4(this)
 
55
        {
 
56
                connect(&req6, SIGNAL(resultsReady(const QList<XMPP::NameRecord> &)), SLOT(req6_resultsReady(const QList<XMPP::NameRecord> &)));
 
57
                connect(&req6, SIGNAL(error(XMPP::NameResolver::Error)), SLOT(req6_error(XMPP::NameResolver::Error)));
 
58
 
 
59
                connect(&req4, SIGNAL(resultsReady(const QList<XMPP::NameRecord> &)), SLOT(req4_resultsReady(const QList<XMPP::NameRecord> &)));
 
60
                connect(&req4, SIGNAL(error(XMPP::NameResolver::Error)), SLOT(req4_error(XMPP::NameResolver::Error)));
 
61
 
 
62
                opTimer = new QTimer(this);
 
63
                connect(opTimer, SIGNAL(timeout()), SLOT(op_timeout()));
 
64
                opTimer->setSingleShot(true);
 
65
        }
 
66
 
 
67
        ~Private()
 
68
        {
 
69
                opTimer->disconnect(this);
 
70
                opTimer->setParent(0);
 
71
                opTimer->deleteLater();
 
72
        }
 
73
 
 
74
        void start(const QByteArray &hostName)
 
75
        {
 
76
                state = AddressWait;
 
77
 
 
78
                // was an IP address used as input?
 
79
                QHostAddress addr;
 
80
                if(addr.setAddress(QString::fromLatin1(hostName)))
 
81
                {
 
82
                        // use this as the result, no need to perform dns query
 
83
                        done6 = true;
 
84
                        done4 = true;
 
85
                        if(addr.protocol() == QAbstractSocket::IPv6Protocol)
 
86
                                addrs6 += addr;
 
87
                        else
 
88
                                addrs4 += addr;
 
89
 
 
90
                        sess.defer(this, "ipAddress_input");
 
91
                        return;
 
92
                }
 
93
 
 
94
                done6 = false;
 
95
                done4 = false;
 
96
 
 
97
                // wait at least 5 seconds for one of AAAA or A, to be
 
98
                //   consistent with netnames_jdns' dns-sd resolves
 
99
                opTimer->start(5000);
 
100
 
 
101
                req6.start(hostName, NameRecord::Aaaa);
 
102
                req4.start(hostName, NameRecord::A);
 
103
        }
 
104
 
 
105
        void stop()
 
106
        {
 
107
                cleanup();
 
108
        }
 
109
 
 
110
private:
 
111
        void cleanup()
 
112
        {
 
113
                sess.reset();
 
114
 
 
115
                req6.stop();
 
116
                req4.stop();
 
117
                opTimer->stop();
 
118
 
 
119
                addrs6.clear();
 
120
                addrs4.clear();
 
121
        }
 
122
 
 
123
        bool tryDone()
 
124
        {
 
125
                if((done6 && done4) || (state == AddressFirstCome && (done6 || done4)))
 
126
                {
 
127
                        QList<QHostAddress> results = addrs6 + addrs4;
 
128
                        cleanup();
 
129
 
 
130
                        if(!results.isEmpty())
 
131
                                emit q->resultsReady(results);
 
132
                        else
 
133
                                emit q->error(ErrorGeneric);
 
134
 
 
135
                        return true;
 
136
                }
 
137
 
 
138
                return false;
 
139
        }
 
140
 
 
141
private slots:
 
142
        void req6_resultsReady(const QList<XMPP::NameRecord> &results)
 
143
        {
 
144
                foreach(const NameRecord &rec, results)
 
145
                        addrs6 += rec.address();
 
146
 
 
147
                done6 = true;
 
148
                tryDone();
 
149
        }
 
150
 
 
151
        void req6_error(XMPP::NameResolver::Error e)
 
152
        {
 
153
                Q_UNUSED(e);
 
154
 
 
155
                done6 = true;
 
156
                tryDone();
 
157
        }
 
158
 
 
159
        void req4_resultsReady(const QList<XMPP::NameRecord> &results)
 
160
        {
 
161
                foreach(const NameRecord &rec, results)
 
162
                        addrs4 += rec.address();
 
163
 
 
164
                done4 = true;
 
165
                tryDone();
 
166
        }
 
167
 
 
168
        void req4_error(XMPP::NameResolver::Error e)
 
169
        {
 
170
                Q_UNUSED(e);
 
171
 
 
172
                done4 = true;
 
173
                tryDone();
 
174
        }
 
175
 
 
176
        void op_timeout()
 
177
        {
 
178
                state = AddressFirstCome;
 
179
 
 
180
                if(done6 || done4)
 
181
                        tryDone();
 
182
        }
 
183
 
 
184
        void ipAddress_input()
 
185
        {
 
186
                tryDone();
 
187
        }
 
188
};
 
189
 
 
190
AddressResolver::AddressResolver(QObject *parent) :
 
191
        QObject(parent)
 
192
{
 
193
        d = new Private(this);
 
194
}
 
195
 
 
196
AddressResolver::~AddressResolver()
 
197
{
 
198
        delete d;
 
199
}
 
200
 
 
201
void AddressResolver::start(const QByteArray &hostName)
 
202
{
 
203
        d->start(hostName);
 
204
}
 
205
 
 
206
void AddressResolver::stop()
 
207
{
 
208
        d->stop();
 
209
}
 
210
 
 
211
}
 
212
 
 
213
#include "addressresolver.moc"