summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2012-03-03 11:56:45 (GMT)
committerKevin Smith <git@kismith.co.uk>2012-03-04 16:01:01 (GMT)
commit4b6694377e3a0308009bdf90be0a4e0de463b215 (patch)
tree86b860395d040c38774dfa4400979f9687dff8ae /Swiften/Client
parentfde71bd59b1412ae475c06f2d4100ce088e86af6 (diff)
downloadswift-contrib-4b6694377e3a0308009bdf90be0a4e0de463b215.zip
swift-contrib-4b6694377e3a0308009bdf90be0a4e0de463b215.tar.bz2
Pass along errors about DNS resolution.
Diffstat (limited to 'Swiften/Client')
-rw-r--r--Swiften/Client/CoreClient.cpp15
-rw-r--r--Swiften/Client/CoreClient.h2
2 files changed, 11 insertions, 6 deletions
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index e2a8e5a..f7e3b21 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -12,18 +12,19 @@
#include <Swiften/Base/IDGenerator.h>
#include <Swiften/Base/Log.h>
#include <Swiften/Base/foreach.h>
#include <Swiften/Base/Algorithm.h>
#include <Swiften/Client/ClientSession.h>
#include <Swiften/TLS/CertificateVerificationError.h>
#include <Swiften/Network/ChainedConnector.h>
#include <Swiften/Network/NetworkFactories.h>
#include <Swiften/Network/ProxyProvider.h>
+#include <Swiften/Network/DomainNameResolveError.h>
#include <Swiften/TLS/PKCS12Certificate.h>
#include <Swiften/Session/BasicSessionStream.h>
#include <Swiften/Session/BOSHSessionStream.h>
#include <Swiften/Queries/IQRouter.h>
#include <Swiften/Client/ClientSessionStanzaChannel.h>
#include <Swiften/Network/SOCKS5ProxiedConnectionFactory.h>
#include <Swiften/Network/HTTPConnectProxiedConnectionFactory.h>
namespace Swift {
@@ -57,29 +58,29 @@ void CoreClient::connect(const ClientOptions& o) {
}
void CoreClient::connect(const std::string& host) {
forceReset();
SWIFT_LOG(debug) << "Connecting to host " << host << std::endl;
disconnectRequested_ = false;
assert(!connector_);
assert(proxyConnectionFactories.empty());
- if(networkFactories->getProxyProvider()->getSOCKS5Proxy().isValid()) {
+ if (networkFactories->getProxyProvider()->getSOCKS5Proxy().isValid()) {
proxyConnectionFactories.push_back(new SOCKS5ProxiedConnectionFactory(networkFactories->getConnectionFactory(), networkFactories->getProxyProvider()->getSOCKS5Proxy()));
}
if(networkFactories->getProxyProvider()->getHTTPConnectProxy().isValid()) {
proxyConnectionFactories.push_back(new HTTPConnectProxiedConnectionFactory(networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory(), networkFactories->getEventLoop(), networkFactories->getProxyProvider()->getHTTPConnectProxy().getAddress().toString(), networkFactories->getProxyProvider()->getHTTPConnectProxy().getPort()));
}
std::vector<ConnectionFactory*> connectionFactories(proxyConnectionFactories);
if (options.boshURL.empty()) {
connectionFactories.push_back(networkFactories->getConnectionFactory());
connector_ = boost::make_shared<ChainedConnector>(host, networkFactories->getDomainNameResolver(), connectionFactories, networkFactories->getTimerFactory());
- connector_->onConnectFinished.connect(boost::bind(&CoreClient::handleConnectorFinished, this, _1));
+ connector_->onConnectFinished.connect(boost::bind(&CoreClient::handleConnectorFinished, this, _1, _2));
connector_->setTimeoutMilliseconds(60*1000);
connector_->start();
}
else {
/* Autodiscovery of which proxy works is largely ok with a TCP session, because this is a one-off. With BOSH
* it would be quite painful given that potentially every stanza could be sent on a new connection.
*/
//sessionStream_ = boost::make_shared<BOSHSessionStream>(boost::make_shared<BOSHConnectionFactory>(options.boshURL, networkFactories->getConnectionFactory(), networkFactories->getXMLParserFactory(), networkFactories->getTLSContextFactory()), getPayloadParserFactories(), getPayloadSerializers(), networkFactories->getTLSContextFactory(), networkFactories->getTimerFactory(), networkFactories->getXMLParserFactory(), networkFactories->getEventLoop(), host, options.boshHTTPConnectProxyURL, options.boshHTTPConnectProxyAuthID, options.boshHTTPConnectProxyAuthPassword);
sessionStream_ = boost::shared_ptr<BOSHSessionStream>(new BOSHSessionStream(
@@ -123,25 +124,29 @@ void CoreClient::bindSessionToStream() {
stanzaChannel_->setSession(session_);
session_->onFinished.connect(boost::bind(&CoreClient::handleSessionFinished, this, _1));
session_->onNeedCredentials.connect(boost::bind(&CoreClient::handleNeedCredentials, this));
session_->start();
}
/**
* Only called for TCP sessions. BOSH is handled inside the BOSHSessionStream.
*/
-void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connection) {
+void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connection, boost::shared_ptr<Error> error) {
resetConnector();
if (!connection) {
if (options.forgetPassword) {
purgePassword();
}
- onDisconnected(disconnectRequested_ ? boost::optional<ClientError>() : boost::optional<ClientError>(ClientError::ConnectionError));
+ boost::optional<ClientError> clientError;
+ if (!disconnectRequested_) {
+ clientError = boost::dynamic_pointer_cast<DomainNameResolveError>(error) ? boost::optional<ClientError>(ClientError::DomainNameResolveError) : boost::optional<ClientError>(ClientError::ConnectionError);
+ }
+ onDisconnected(clientError);
}
else {
assert(!connection_);
connection_ = connection;
assert(!sessionStream_);
sessionStream_ = boost::make_shared<BasicSessionStream>(ClientStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), networkFactories->getTLSContextFactory(), networkFactories->getTimerFactory(), networkFactories->getXMLParserFactory());
if (certificate_ && !certificate_->isNull()) {
sessionStream_->setTLSCertificate(certificate_);
@@ -350,19 +355,19 @@ const JID& CoreClient::getJID() const {
return jid_;
}
}
void CoreClient::purgePassword() {
safeClear(password_);
}
void CoreClient::resetConnector() {
- connector_->onConnectFinished.disconnect(boost::bind(&CoreClient::handleConnectorFinished, this, _1));
+ connector_->onConnectFinished.disconnect(boost::bind(&CoreClient::handleConnectorFinished, this, _1, _2));
connector_.reset();
foreach(ConnectionFactory* f, proxyConnectionFactories) {
delete f;
}
proxyConnectionFactories.clear();
}
void CoreClient::resetSession() {
session_->onFinished.disconnect(boost::bind(&CoreClient::handleSessionFinished, this, _1));
diff --git a/Swiften/Client/CoreClient.h b/Swiften/Client/CoreClient.h
index c9a6f30..cafc634 100644
--- a/Swiften/Client/CoreClient.h
+++ b/Swiften/Client/CoreClient.h
@@ -197,19 +197,19 @@ namespace Swift {
return networkFactories;
}
/**
* Called before onConnected signal is emmitted.
*/
virtual void handleConnected() {};
private:
- void handleConnectorFinished(boost::shared_ptr<Connection>);
+ void handleConnectorFinished(boost::shared_ptr<Connection>, boost::shared_ptr<Error> error);
void handleStanzaChannelAvailableChanged(bool available);
void handleSessionFinished(boost::shared_ptr<Error>);
void handleNeedCredentials();
void handleDataRead(const SafeByteArray&);
void handleDataWritten(const SafeByteArray&);
void handlePresenceReceived(boost::shared_ptr<Presence>);
void handleMessageReceived(boost::shared_ptr<Message>);
void handleStanzaAcked(boost::shared_ptr<Stanza>);
void purgePassword();