summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Network')
-rw-r--r--Swiften/Network/DomainNameAddressQuery.h2
-rw-r--r--Swiften/Network/DomainNameServiceQuery.h3
-rw-r--r--Swiften/Network/PlatformDomainNameAddressQuery.cpp56
-rw-r--r--Swiften/Network/PlatformDomainNameAddressQuery.h38
-rw-r--r--Swiften/Network/PlatformDomainNameQuery.h31
-rw-r--r--Swiften/Network/PlatformDomainNameResolver.cpp105
-rw-r--r--Swiften/Network/PlatformDomainNameResolver.h26
-rw-r--r--Swiften/Network/PlatformDomainNameServiceQuery.cpp20
-rw-r--r--Swiften/Network/PlatformDomainNameServiceQuery.h11
-rw-r--r--Swiften/Network/SConscript1
10 files changed, 199 insertions, 94 deletions
diff --git a/Swiften/Network/DomainNameAddressQuery.h b/Swiften/Network/DomainNameAddressQuery.h
index 390916f..5bac350 100644
--- a/Swiften/Network/DomainNameAddressQuery.h
+++ b/Swiften/Network/DomainNameAddressQuery.h
@@ -16,6 +16,8 @@
namespace Swift {
class DomainNameAddressQuery {
public:
+ typedef boost::shared_ptr<DomainNameAddressQuery> ref;
+
virtual ~DomainNameAddressQuery();
virtual void run() = 0;
diff --git a/Swiften/Network/DomainNameServiceQuery.h b/Swiften/Network/DomainNameServiceQuery.h
index 3ba3a00..fb44e82 100644
--- a/Swiften/Network/DomainNameServiceQuery.h
+++ b/Swiften/Network/DomainNameServiceQuery.h
@@ -9,6 +9,7 @@
#include "Swiften/Base/boost_bsignals.h"
#include <boost/optional.hpp>
#include <vector>
+#include <boost/shared_ptr.hpp>
#include "Swiften/Base/String.h"
#include "Swiften/Network/DomainNameResolveError.h"
@@ -16,6 +17,8 @@
namespace Swift {
class DomainNameServiceQuery {
public:
+ typedef boost::shared_ptr<DomainNameServiceQuery> ref;
+
struct Result {
Result(const String& hostname = "", int port = -1, int priority = -1, int weight = -1) : hostname(hostname), port(port), priority(priority), weight(weight) {}
String hostname;
diff --git a/Swiften/Network/PlatformDomainNameAddressQuery.cpp b/Swiften/Network/PlatformDomainNameAddressQuery.cpp
new file mode 100644
index 0000000..2a8574d
--- /dev/null
+++ b/Swiften/Network/PlatformDomainNameAddressQuery.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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/PlatformDomainNameAddressQuery.h>
+
+#include <Swiften/Network/PlatformDomainNameResolver.h>
+#include <Swiften/EventLoop/EventLoop.h>
+
+namespace Swift {
+
+PlatformDomainNameAddressQuery::PlatformDomainNameAddressQuery(const String& host, EventLoop* eventLoop, PlatformDomainNameResolver* resolver) : PlatformDomainNameQuery(resolver), hostname(host), eventLoop(eventLoop) {
+}
+
+void PlatformDomainNameAddressQuery::run() {
+ getResolver()->addQueryToQueue(shared_from_this());
+}
+
+void PlatformDomainNameAddressQuery::runBlocking() {
+ //std::cout << "PlatformDomainNameResolver::doRun()" << std::endl;
+ boost::asio::ip::tcp::resolver resolver(ioService);
+ boost::asio::ip::tcp::resolver::query query(hostname.getUTF8String(), "5222");
+ try {
+ //std::cout << "PlatformDomainNameResolver::doRun(): Resolving" << std::endl;
+ boost::asio::ip::tcp::resolver::iterator endpointIterator = resolver.resolve(query);
+ //std::cout << "PlatformDomainNameResolver::doRun(): Resolved" << std::endl;
+ if (endpointIterator == boost::asio::ip::tcp::resolver::iterator()) {
+ //std::cout << "PlatformDomainNameResolver::doRun(): Error 1" << std::endl;
+ emitError();
+ }
+ else {
+ std::vector<HostAddress> results;
+ for ( ; endpointIterator != boost::asio::ip::tcp::resolver::iterator(); ++endpointIterator) {
+ boost::asio::ip::address address = (*endpointIterator).endpoint().address();
+ results.push_back(address.is_v4() ? HostAddress(&address.to_v4().to_bytes()[0], 4) : HostAddress(&address.to_v6().to_bytes()[0], 16));
+ }
+
+ //std::cout << "PlatformDomainNameResolver::doRun(): Success" << std::endl;
+ eventLoop->postEvent(
+ boost::bind(boost::ref(onResult), results, boost::optional<DomainNameResolveError>()),
+ shared_from_this());
+ }
+ }
+ catch (...) {
+ //std::cout << "PlatformDomainNameResolver::doRun(): Error 2" << std::endl;
+ emitError();
+ }
+}
+
+void PlatformDomainNameAddressQuery::emitError() {
+ eventLoop->postEvent(boost::bind(boost::ref(onResult), std::vector<HostAddress>(), boost::optional<DomainNameResolveError>(DomainNameResolveError())), shared_from_this());
+}
+
+}
diff --git a/Swiften/Network/PlatformDomainNameAddressQuery.h b/Swiften/Network/PlatformDomainNameAddressQuery.h
new file mode 100644
index 0000000..0153688
--- /dev/null
+++ b/Swiften/Network/PlatformDomainNameAddressQuery.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/asio.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include <Swiften/Network/DomainNameAddressQuery.h>
+#include <Swiften/Network/PlatformDomainNameQuery.h>
+#include <Swiften/EventLoop/EventOwner.h>
+#include <Swiften/Base/String.h>
+
+namespace Swift {
+ class PlatformDomainNameResolver;
+ class EventLoop;
+
+ class PlatformDomainNameAddressQuery : public DomainNameAddressQuery, public PlatformDomainNameQuery, public boost::enable_shared_from_this<PlatformDomainNameAddressQuery>, public EventOwner {
+ public:
+ PlatformDomainNameAddressQuery(const String& host, EventLoop* eventLoop, PlatformDomainNameResolver*);
+
+ void run();
+
+ private:
+ void runBlocking();
+ void emitError();
+
+ private:
+ boost::asio::io_service ioService;
+ String hostname;
+ EventLoop* eventLoop;
+ };
+}
+
+
diff --git a/Swiften/Network/PlatformDomainNameQuery.h b/Swiften/Network/PlatformDomainNameQuery.h
new file mode 100644
index 0000000..bbfb1d1
--- /dev/null
+++ b/Swiften/Network/PlatformDomainNameQuery.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+ class PlatformDomainNameResolver;
+
+ class PlatformDomainNameQuery {
+ public:
+ typedef boost::shared_ptr<PlatformDomainNameQuery> ref;
+
+ PlatformDomainNameQuery(PlatformDomainNameResolver* resolver) : resolver(resolver) {}
+ virtual ~PlatformDomainNameQuery() {}
+
+ virtual void runBlocking() = 0;
+
+ protected:
+ PlatformDomainNameResolver* getResolver() {
+ return resolver;
+ }
+
+ private:
+ PlatformDomainNameResolver* resolver;
+ };
+}
diff --git a/Swiften/Network/PlatformDomainNameResolver.cpp b/Swiften/Network/PlatformDomainNameResolver.cpp
index 3f72466..6a61337 100644
--- a/Swiften/Network/PlatformDomainNameResolver.cpp
+++ b/Swiften/Network/PlatformDomainNameResolver.cpp
@@ -11,10 +11,8 @@
#include <string>
#include <vector>
-#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
-#include <boost/enable_shared_from_this.hpp>
#include <algorithm>
#include "Swiften/Base/String.h"
@@ -23,84 +21,55 @@
#include "Swiften/EventLoop/EventLoop.h"
#include "Swiften/Network/HostAddressPort.h"
#include "Swiften/Network/DomainNameAddressQuery.h"
+#include <Swiften/Network/PlatformDomainNameAddressQuery.h>
using namespace Swift;
-namespace {
- struct AddressQuery : public DomainNameAddressQuery, public boost::enable_shared_from_this<AddressQuery>, public EventOwner {
- AddressQuery(const String& host, EventLoop* eventLoop) : hostname(host), eventLoop(eventLoop), thread(NULL), safeToJoin(false) {}
-
- ~AddressQuery() {
- if (safeToJoin) {
- thread->join();
- }
- else {
- // FIXME: UGLYYYYY
- }
- delete thread;
- }
-
- void run() {
- safeToJoin = false;
- thread = new boost::thread(boost::bind(&AddressQuery::doRun, shared_from_this()));
- }
-
- void doRun() {
- //std::cout << "PlatformDomainNameResolver::doRun()" << std::endl;
- boost::asio::ip::tcp::resolver resolver(ioService);
- boost::asio::ip::tcp::resolver::query query(hostname.getUTF8String(), "5222");
- try {
- //std::cout << "PlatformDomainNameResolver::doRun(): Resolving" << std::endl;
- boost::asio::ip::tcp::resolver::iterator endpointIterator = resolver.resolve(query);
- //std::cout << "PlatformDomainNameResolver::doRun(): Resolved" << std::endl;
- if (endpointIterator == boost::asio::ip::tcp::resolver::iterator()) {
- //std::cout << "PlatformDomainNameResolver::doRun(): Error 1" << std::endl;
- emitError();
- }
- else {
- std::vector<HostAddress> results;
- for ( ; endpointIterator != boost::asio::ip::tcp::resolver::iterator(); ++endpointIterator) {
- boost::asio::ip::address address = (*endpointIterator).endpoint().address();
- results.push_back(address.is_v4() ? HostAddress(&address.to_v4().to_bytes()[0], 4) : HostAddress(&address.to_v6().to_bytes()[0], 16));
- }
-
- //std::cout << "PlatformDomainNameResolver::doRun(): Success" << std::endl;
- eventLoop->postEvent(
- boost::bind(boost::ref(onResult), results, boost::optional<DomainNameResolveError>()),
- shared_from_this());
- }
- }
- catch (...) {
- //std::cout << "PlatformDomainNameResolver::doRun(): Error 2" << std::endl;
- emitError();
- }
- safeToJoin = true;
- }
-
- void emitError() {
- eventLoop->postEvent(boost::bind(boost::ref(onResult), std::vector<HostAddress>(), boost::optional<DomainNameResolveError>(DomainNameResolveError())), shared_from_this());
- }
-
- boost::asio::io_service ioService;
- String hostname;
- EventLoop* eventLoop;
- boost::thread* thread;
- bool safeToJoin;
- };
+namespace Swift {
+PlatformDomainNameResolver::PlatformDomainNameResolver(EventLoop* eventLoop) : eventLoop(eventLoop), stopRequested(false) {
+ thread = new boost::thread(boost::bind(&PlatformDomainNameResolver::run, this));
}
-namespace Swift {
-
-PlatformDomainNameResolver::PlatformDomainNameResolver(EventLoop* eventLoop) : eventLoop(eventLoop) {
+PlatformDomainNameResolver::~PlatformDomainNameResolver() {
+ stopRequested = true;
+ addQueryToQueue(boost::shared_ptr<PlatformDomainNameQuery>());
+ thread->join();
}
boost::shared_ptr<DomainNameServiceQuery> PlatformDomainNameResolver::createServiceQuery(const String& name) {
- return boost::shared_ptr<DomainNameServiceQuery>(new PlatformDomainNameServiceQuery(IDNA::getEncoded(name), eventLoop));
+ return boost::shared_ptr<DomainNameServiceQuery>(new PlatformDomainNameServiceQuery(IDNA::getEncoded(name), eventLoop, this));
}
boost::shared_ptr<DomainNameAddressQuery> PlatformDomainNameResolver::createAddressQuery(const String& name) {
- return boost::shared_ptr<DomainNameAddressQuery>(new AddressQuery(IDNA::getEncoded(name), eventLoop));
+ return boost::shared_ptr<DomainNameAddressQuery>(new PlatformDomainNameAddressQuery(IDNA::getEncoded(name), eventLoop, this));
+}
+
+void PlatformDomainNameResolver::run() {
+ while (!stopRequested) {
+ PlatformDomainNameQuery::ref query;
+ {
+ boost::unique_lock<boost::mutex> lock(queueMutex);
+ while (queue.empty()) {
+ queueNonEmpty.wait(lock);
+ }
+ query = queue.front();
+ queue.pop_front();
+ }
+ // Check whether we don't have a non-null query (used to stop the
+ // resolver)
+ if (query) {
+ query->runBlocking();
+ }
+ }
+}
+
+void PlatformDomainNameResolver::addQueryToQueue(PlatformDomainNameQuery::ref query) {
+ {
+ boost::lock_guard<boost::mutex> lock(queueMutex);
+ queue.push_back(query);
+ }
+ queueNonEmpty.notify_one();
}
}
diff --git a/Swiften/Network/PlatformDomainNameResolver.h b/Swiften/Network/PlatformDomainNameResolver.h
index 46c209b..249f2e3 100644
--- a/Swiften/Network/PlatformDomainNameResolver.h
+++ b/Swiften/Network/PlatformDomainNameResolver.h
@@ -6,7 +6,15 @@
#pragma once
-#include "Swiften/Network/DomainNameResolver.h"
+#include <deque>
+#include <boost/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+#include <Swiften/Network/DomainNameResolver.h>
+#include <Swiften/Network/PlatformDomainNameQuery.h>
+#include <Swiften/Network/DomainNameServiceQuery.h>
+#include <Swiften/Network/DomainNameAddressQuery.h>
namespace Swift {
class String;
@@ -15,11 +23,23 @@ namespace Swift {
class PlatformDomainNameResolver : public DomainNameResolver {
public:
PlatformDomainNameResolver(EventLoop* eventLoop);
+ ~PlatformDomainNameResolver();
+
+ virtual DomainNameServiceQuery::ref createServiceQuery(const String& name);
+ virtual DomainNameAddressQuery::ref createAddressQuery(const String& name);
- virtual boost::shared_ptr<DomainNameServiceQuery> createServiceQuery(const String& name);
- virtual boost::shared_ptr<DomainNameAddressQuery> createAddressQuery(const String& name);
+ private:
+ void run();
+ void addQueryToQueue(PlatformDomainNameQuery::ref);
private:
+ friend class PlatformDomainNameServiceQuery;
+ friend class PlatformDomainNameAddressQuery;
EventLoop* eventLoop;
+ bool stopRequested;
+ boost::thread* thread;
+ std::deque<PlatformDomainNameQuery::ref> queue;
+ boost::mutex queueMutex;
+ boost::condition_variable queueNonEmpty;
};
}
diff --git a/Swiften/Network/PlatformDomainNameServiceQuery.cpp b/Swiften/Network/PlatformDomainNameServiceQuery.cpp
index 7ab6e7a..bdbb664 100644
--- a/Swiften/Network/PlatformDomainNameServiceQuery.cpp
+++ b/Swiften/Network/PlatformDomainNameServiceQuery.cpp
@@ -28,30 +28,20 @@
#include "Swiften/EventLoop/EventLoop.h"
#include "Swiften/Base/foreach.h"
#include <Swiften/Base/Log.h>
+#include <Swiften/Network/PlatformDomainNameResolver.h>
using namespace Swift;
namespace Swift {
-PlatformDomainNameServiceQuery::PlatformDomainNameServiceQuery(const String& service, EventLoop* eventLoop) : eventLoop(eventLoop), thread(NULL), service(service), safeToJoin(true) {
-}
-
-PlatformDomainNameServiceQuery::~PlatformDomainNameServiceQuery() {
- if (safeToJoin) {
- thread->join();
- }
- else {
- // FIXME: UGLYYYYY
- }
- delete thread;
+PlatformDomainNameServiceQuery::PlatformDomainNameServiceQuery(const String& service, EventLoop* eventLoop, PlatformDomainNameResolver* resolver) : PlatformDomainNameQuery(resolver), eventLoop(eventLoop), service(service) {
}
void PlatformDomainNameServiceQuery::run() {
- safeToJoin = false;
- thread = new boost::thread(boost::bind(&PlatformDomainNameServiceQuery::doRun, shared_from_this()));
+ getResolver()->addQueryToQueue(shared_from_this());
}
-void PlatformDomainNameServiceQuery::doRun() {
+void PlatformDomainNameServiceQuery::runBlocking() {
SWIFT_LOG(debug) << "Querying " << service << std::endl;
std::vector<DomainNameServiceQuery::Result> records;
@@ -166,14 +156,12 @@ void PlatformDomainNameServiceQuery::doRun() {
}
#endif
- safeToJoin = true;
std::sort(records.begin(), records.end(), ResultPriorityComparator());
//std::cout << "Sending out " << records.size() << " SRV results " << std::endl;
eventLoop->postEvent(boost::bind(boost::ref(onResult), records));
}
void PlatformDomainNameServiceQuery::emitError() {
- safeToJoin = true;
eventLoop->postEvent(boost::bind(boost::ref(onResult), std::vector<DomainNameServiceQuery::Result>()), shared_from_this());
}
diff --git a/Swiften/Network/PlatformDomainNameServiceQuery.h b/Swiften/Network/PlatformDomainNameServiceQuery.h
index 9808196..c9dbd65 100644
--- a/Swiften/Network/PlatformDomainNameServiceQuery.h
+++ b/Swiften/Network/PlatformDomainNameServiceQuery.h
@@ -6,31 +6,28 @@
#pragma once
-#include <boost/thread.hpp>
#include <boost/enable_shared_from_this.hpp>
#include "Swiften/Network/DomainNameServiceQuery.h"
#include "Swiften/EventLoop/EventOwner.h"
#include "Swiften/Base/String.h"
+#include <Swiften/Network/PlatformDomainNameQuery.h>
namespace Swift {
class EventLoop;
- class PlatformDomainNameServiceQuery : public DomainNameServiceQuery, public boost::enable_shared_from_this<PlatformDomainNameServiceQuery>, public EventOwner {
+ class PlatformDomainNameServiceQuery : public DomainNameServiceQuery, public PlatformDomainNameQuery, public boost::enable_shared_from_this<PlatformDomainNameServiceQuery>, public EventOwner {
public:
- PlatformDomainNameServiceQuery(const String& service, EventLoop* eventLoop);
- ~PlatformDomainNameServiceQuery();
+ PlatformDomainNameServiceQuery(const String& service, EventLoop* eventLoop, PlatformDomainNameResolver* resolver);
virtual void run();
private:
- void doRun();
+ void runBlocking();
void emitError();
private:
EventLoop* eventLoop;
- boost::thread* thread;
String service;
- bool safeToJoin;
};
}
diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript
index f193407..2e376af 100644
--- a/Swiften/Network/SConscript
+++ b/Swiften/Network/SConscript
@@ -21,6 +21,7 @@ sourceList = [
"DomainNameServiceQuery.cpp",
"PlatformDomainNameResolver.cpp",
"PlatformDomainNameServiceQuery.cpp",
+ "PlatformDomainNameAddressQuery.cpp",
"StaticDomainNameResolver.cpp",
"HostAddress.cpp",
"NetworkFactories.cpp",