2
* Copyright (C) 2009 Barracuda Networks, Inc.
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.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHANY 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.
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
21
#include "stunbinding.h"
23
#include <QHostAddress>
24
#include "stunmessage.h"
25
#include "stuntypes.h"
26
#include "stuntransaction.h"
30
class StunBinding::Private : public QObject
36
StunTransactionPool *pool;
37
StunTransaction *trans;
38
QHostAddress stunAddr;
43
bool use_extPriority, use_extIceControlling, use_extIceControlled;
46
quint64 extIceControlling, extIceControlled;
47
QString stuser, stpass;
50
Private(StunBinding *_q) :
55
use_extPriority(false),
56
use_extIceControlling(false),
57
use_extIceControlled(false),
58
extUseCandidate(false),
68
void start(const QHostAddress &_addr = QHostAddress(), int _port = -1)
75
trans = new StunTransaction(this);
76
connect(trans, SIGNAL(createMessage(const QByteArray &)), SLOT(trans_createMessage(const QByteArray &)));
77
connect(trans, SIGNAL(finished(const XMPP::StunMessage &)), SLOT(trans_finished(const XMPP::StunMessage &)));
78
connect(trans, SIGNAL(error(XMPP::StunTransaction::Error)), SLOT(trans_error(XMPP::StunTransaction::Error)));
82
trans->setShortTermUsername(stuser);
83
trans->setShortTermPassword(stpass);
86
trans->setFingerprintRequired(fpRequired);
88
trans->start(pool, stunAddr, stunPort);
92
void trans_createMessage(const QByteArray &transactionId)
95
message.setMethod(StunTypes::Binding);
96
message.setId((const quint8 *)transactionId.data());
98
QList<StunMessage::Attribute> list;
102
StunMessage::Attribute a;
103
a.type = StunTypes::PRIORITY;
104
a.value = StunTypes::createPriority(extPriority);
110
StunMessage::Attribute a;
111
a.type = StunTypes::USE_CANDIDATE;
115
if(use_extIceControlling)
117
StunMessage::Attribute a;
118
a.type = StunTypes::ICE_CONTROLLING;
119
a.value = StunTypes::createIceControlling(extIceControlling);
123
if(use_extIceControlled)
125
StunMessage::Attribute a;
126
a.type = StunTypes::ICE_CONTROLLED;
127
a.value = StunTypes::createIceControlled(extIceControlled);
131
message.setAttributes(list);
133
trans->setMessage(message);
136
void trans_finished(const XMPP::StunMessage &response)
144
if(response.mclass() == StunMessage::ErrorResponse)
146
if(!StunTypes::parseErrorCode(response.attribute(StunTypes::ERROR_CODE), &code, &reason))
148
errorString = "Unable to parse ERROR-CODE in error response.";
149
emit q->error(StunBinding::ErrorProtocol);
158
errorString = reason;
159
if(code == StunTypes::RoleConflict)
160
emit q->error(StunBinding::ErrorConflict);
162
emit q->error(StunBinding::ErrorRejected);
170
val = response.attribute(StunTypes::XOR_MAPPED_ADDRESS);
173
if(!StunTypes::parseXorMappedAddress(val, response.magic(), response.id(), &saddr, &sport))
175
errorString = "Unable to parse XOR-MAPPED-ADDRESS response.";
176
emit q->error(StunBinding::ErrorProtocol);
182
val = response.attribute(StunTypes::MAPPED_ADDRESS);
185
if(!StunTypes::parseMappedAddress(val, &saddr, &sport))
187
errorString = "Unable to parse MAPPED-ADDRESS response.";
188
emit q->error(StunBinding::ErrorProtocol);
194
errorString = "Response does not contain XOR-MAPPED-ADDRESS or MAPPED-ADDRESS.";
195
emit q->error(StunBinding::ErrorProtocol);
205
void trans_error(XMPP::StunTransaction::Error e)
210
if(e == StunTransaction::ErrorTimeout)
212
errorString = "Request timed out.";
213
emit q->error(StunBinding::ErrorTimeout);
217
errorString = "Generic transaction error.";
218
emit q->error(StunBinding::ErrorGeneric);
223
StunBinding::StunBinding(StunTransactionPool *pool) :
226
d = new Private(this);
230
StunBinding::~StunBinding()
235
void StunBinding::setPriority(quint32 i)
237
d->use_extPriority = true;
241
void StunBinding::setUseCandidate(bool enabled)
243
d->extUseCandidate = enabled;
246
void StunBinding::setIceControlling(quint64 i)
248
d->use_extIceControlling = true;
249
d->extIceControlling = i;
252
void StunBinding::setIceControlled(quint64 i)
254
d->use_extIceControlled = true;
255
d->extIceControlled = i;
258
void StunBinding::setShortTermUsername(const QString &username)
260
d->stuser = username;
263
void StunBinding::setShortTermPassword(const QString &password)
265
d->stpass = password;
268
void StunBinding::setFingerprintRequired(bool enabled)
270
d->fpRequired = enabled;
273
void StunBinding::start()
278
void StunBinding::start(const QHostAddress &addr, int port)
280
d->start(addr, port);
283
QHostAddress StunBinding::reflexiveAddress() const
288
int StunBinding::reflexivePort() const
293
QString StunBinding::errorString() const
295
return d->errorString;
300
#include "stunbinding.moc"