summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Maudsley <richard.maudsley@isode.com>2014-07-17 09:46:50 (GMT)
committerSwift Review <review@swift.im>2014-08-10 11:08:27 (GMT)
commit8ec22a9c5591584fd1725ed028d714c51b7509d3 (patch)
tree3687e7023696c9e790a24fd54b7d04f14ac58ab2 /Swiften/Network/Connector.cpp
parent5e9e715e49a5ddb6ce9c76ec61e7ecfd6eacdb58 (diff)
downloadswift-contrib-8ec22a9c5591584fd1725ed028d714c51b7509d3.zip
swift-contrib-8ec22a9c5591584fd1725ed028d714c51b7509d3.tar.bz2
Fix invalid characters being allowed in JID domains
Test-Information: Prepare valid and invalid JIDs and make sure that isValid() is reported correctly. Added unit tests. Change-Id: Ic4d86f8b6ea9defc517ada2f8e3cc54979237cf4
Diffstat (limited to 'Swiften/Network/Connector.cpp')
-rw-r--r--Swiften/Network/Connector.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp
index da2490f..1db1eac 100644
--- a/Swiften/Network/Connector.cpp
+++ b/Swiften/Network/Connector.cpp
@@ -1,186 +1,186 @@
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swiften/Network/Connector.h>
#include <boost/bind.hpp>
#include <iostream>
#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/Network/DomainNameResolver.h>
#include <Swiften/Network/DomainNameAddressQuery.h>
#include <Swiften/Network/TimerFactory.h>
#include <Swiften/Base/Log.h>
namespace Swift {
Connector::Connector(const std::string& hostname, int port, const boost::optional<std::string>& serviceLookupPrefix, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) : hostname(hostname), port(port), serviceLookupPrefix(serviceLookupPrefix), resolver(resolver), connectionFactory(connectionFactory), timerFactory(timerFactory), timeoutMilliseconds(0), queriedAllServices(true), foundSomeDNS(false) {
}
void Connector::setTimeoutMilliseconds(int milliseconds) {
timeoutMilliseconds = milliseconds;
}
void Connector::start() {
SWIFT_LOG(debug) << "Starting connector for " << hostname << std::endl;
//std::cout << "Connector::start()" << std::endl;
assert(!currentConnection);
assert(!serviceQuery);
assert(!timer);
queriedAllServices = false;
if (timeoutMilliseconds > 0) {
timer = timerFactory->createTimer(timeoutMilliseconds);
timer->onTick.connect(boost::bind(&Connector::handleTimeout, shared_from_this()));
}
if (serviceLookupPrefix) {
- serviceQuery = resolver->createServiceQuery((*serviceLookupPrefix) + hostname);
+ serviceQuery = resolver->createServiceQuery(*serviceLookupPrefix, hostname);
serviceQuery->onResult.connect(boost::bind(&Connector::handleServiceQueryResult, shared_from_this(), _1));
serviceQuery->run();
}
else {
queryAddress(hostname);
}
}
void Connector::stop() {
finish(boost::shared_ptr<Connection>());
}
void Connector::queryAddress(const std::string& hostname) {
assert(!addressQuery);
addressQuery = resolver->createAddressQuery(hostname);
addressQuery->onResult.connect(boost::bind(&Connector::handleAddressQueryResult, shared_from_this(), _1, _2));
addressQuery->run();
}
void Connector::handleServiceQueryResult(const std::vector<DomainNameServiceQuery::Result>& result) {
SWIFT_LOG(debug) << result.size() << " SRV result(s)" << std::endl;
serviceQueryResults = std::deque<DomainNameServiceQuery::Result>(result.begin(), result.end());
serviceQuery.reset();
if (!serviceQueryResults.empty()) {
foundSomeDNS = true;
}
tryNextServiceOrFallback();
}
void Connector::tryNextServiceOrFallback() {
if (queriedAllServices) {
SWIFT_LOG(debug) << "Queried all services" << std::endl;
finish(boost::shared_ptr<Connection>());
}
else if (serviceQueryResults.empty()) {
SWIFT_LOG(debug) << "Falling back on A resolution" << std::endl;
// Fall back on simple address resolving
queriedAllServices = true;
queryAddress(hostname);
}
else {
SWIFT_LOG(debug) << "Querying next address" << std::endl;
queryAddress(serviceQueryResults.front().hostname);
}
}
void Connector::handleAddressQueryResult(const std::vector<HostAddress>& addresses, boost::optional<DomainNameResolveError> error) {
SWIFT_LOG(debug) << addresses.size() << " addresses" << std::endl;
addressQuery.reset();
if (error || addresses.empty()) {
if (!serviceQueryResults.empty()) {
serviceQueryResults.pop_front();
}
tryNextServiceOrFallback();
}
else {
foundSomeDNS = true;
addressQueryResults = std::deque<HostAddress>(addresses.begin(), addresses.end());
tryNextAddress();
}
}
void Connector::tryNextAddress() {
if (addressQueryResults.empty()) {
SWIFT_LOG(debug) << "Done trying addresses. Moving on." << std::endl;
// Done trying all addresses. Move on to the next host.
if (!serviceQueryResults.empty()) {
serviceQueryResults.pop_front();
}
tryNextServiceOrFallback();
}
else {
SWIFT_LOG(debug) << "Trying next address" << std::endl;
HostAddress address = addressQueryResults.front();
addressQueryResults.pop_front();
int connectPort = (port == -1 ? 5222 : port);
if (!serviceQueryResults.empty()) {
connectPort = serviceQueryResults.front().port;
}
tryConnect(HostAddressPort(address, connectPort));
}
}
void Connector::tryConnect(const HostAddressPort& target) {
assert(!currentConnection);
SWIFT_LOG(debug) << "Trying to connect to " << target.getAddress().toString() << ":" << target.getPort() << std::endl;
currentConnection = connectionFactory->createConnection();
currentConnection->onConnectFinished.connect(boost::bind(&Connector::handleConnectionConnectFinished, shared_from_this(), _1));
currentConnection->connect(target);
if (timer) {
timer->start();
}
}
void Connector::handleConnectionConnectFinished(bool error) {
SWIFT_LOG(debug) << "ConnectFinished: " << (error ? "error" : "success") << std::endl;
if (timer) {
timer->stop();
timer.reset();
}
currentConnection->onConnectFinished.disconnect(boost::bind(&Connector::handleConnectionConnectFinished, shared_from_this(), _1));
if (error) {
currentConnection.reset();
if (!addressQueryResults.empty()) {
tryNextAddress();
}
else {
if (!serviceQueryResults.empty()) {
serviceQueryResults.pop_front();
}
tryNextServiceOrFallback();
}
}
else {
finish(currentConnection);
}
}
void Connector::finish(boost::shared_ptr<Connection> connection) {
if (timer) {
timer->stop();
timer->onTick.disconnect(boost::bind(&Connector::handleTimeout, shared_from_this()));
timer.reset();
}
if (serviceQuery) {
serviceQuery->onResult.disconnect(boost::bind(&Connector::handleServiceQueryResult, shared_from_this(), _1));
serviceQuery.reset();
}
if (addressQuery) {
addressQuery->onResult.disconnect(boost::bind(&Connector::handleAddressQueryResult, shared_from_this(), _1, _2));
addressQuery.reset();
}
if (currentConnection) {
currentConnection->onConnectFinished.disconnect(boost::bind(&Connector::handleConnectionConnectFinished, shared_from_this(), _1));
currentConnection.reset();
}
onConnectFinished(connection, (connection || foundSomeDNS) ? boost::shared_ptr<Error>() : boost::make_shared<DomainNameResolveError>());
}
void Connector::handleTimeout() {
SWIFT_LOG(debug) << "Timeout" << std::endl;
handleConnectionConnectFinished(true);
}
}