From 0f77a684b42f25052eb1cfa688721e321526a90d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sat, 25 Jul 2009 11:37:42 +0200
Subject: Created DNSSD submodule for LinkLocal.


diff --git a/Swiften/LinkLocal/BonjourBrowseQuery.h b/Swiften/LinkLocal/BonjourBrowseQuery.h
deleted file mode 100644
index 6db108d..0000000
--- a/Swiften/LinkLocal/BonjourBrowseQuery.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-#include "Swiften/LinkLocal/BonjourQuery.h"
-#include "Swiften/LinkLocal/DNSSDBrowseQuery.h"
-#include "Swiften/EventLoop/MainEventLoop.h"
-
-namespace Swift {
-	class BonjourQuerier;
-
-	class BonjourBrowseQuery : public DNSSDBrowseQuery, public BonjourQuery {
-		public:	
-			BonjourBrowseQuery(boost::shared_ptr<BonjourQuerier> q) : BonjourQuery(q) {
-				DNSServiceErrorType result = DNSServiceBrowse(
-						&sdRef, 0, 0, "_presence._tcp", 0, 
-						&BonjourBrowseQuery::handleServiceDiscoveredStatic, this);
-				if (result != kDNSServiceErr_NoError) {
-					std::cout << "Error" << std::endl;
-					// TODO
-				}
-			}
-
-			void startBrowsing() {
-				assert(sdRef);
-				run();
-			}
-
-			void stopBrowsing() {
-				finish();
-			}
-
-		private:
-			static void handleServiceDiscoveredStatic(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain, void *context) {
-				static_cast<BonjourBrowseQuery*>(context)->handleServiceDiscovered(flags, interfaceIndex, errorCode, name, type, domain);
-			}
-
-			void handleServiceDiscovered(DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain) {
-				if (errorCode != kDNSServiceErr_NoError) {
-					return;
-				}
-				else {
-					LinkLocalServiceID service(name, type, domain, interfaceIndex);
-					if (flags & kDNSServiceFlagsAdd) {
-						MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this());
-					}
-					else {
-						MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this());
-					}
-				}
-			}
-	};
-}
diff --git a/Swiften/LinkLocal/BonjourQuerier.cpp b/Swiften/LinkLocal/BonjourQuerier.cpp
deleted file mode 100644
index 42ba12a..0000000
--- a/Swiften/LinkLocal/BonjourQuerier.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-#include "Swiften/LinkLocal/BonjourQuerier.h"
-
-#include <unistd.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-
-#include "Swiften/LinkLocal/BonjourBrowseQuery.h"
-#include "Swiften/LinkLocal/BonjourRegisterQuery.h"
-#include "Swiften/LinkLocal/BonjourResolveServiceQuery.h"
-#include "Swiften/LinkLocal/BonjourResolveHostnameQuery.h"
-#include "Swiften/Base/foreach.h"
-
-namespace Swift {
-
-BonjourQuerier::BonjourQuerier() : stopRequested(false), thread(0) {
-	int fds[2];
-	int result = pipe(fds);
-	assert(result == 0);
-	interruptSelectReadSocket = fds[0];
-	fcntl(interruptSelectReadSocket, F_SETFL, fcntl(interruptSelectReadSocket, F_GETFL)|O_NONBLOCK);
-	interruptSelectWriteSocket = fds[1];
-}
-
-BonjourQuerier::~BonjourQuerier() {
-	stop();
-}
-
-boost::shared_ptr<DNSSDBrowseQuery> BonjourQuerier::createBrowseQuery() {
-	return boost::shared_ptr<DNSSDBrowseQuery>(new BonjourBrowseQuery(shared_from_this()));
-}
-
-boost::shared_ptr<DNSSDRegisterQuery> BonjourQuerier::createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info) {
-	return boost::shared_ptr<DNSSDRegisterQuery>(new BonjourRegisterQuery(name, port, info, shared_from_this()));
-}
-
-boost::shared_ptr<DNSSDResolveServiceQuery> BonjourQuerier::createResolveServiceQuery(const LinkLocalServiceID& service) {
-	return boost::shared_ptr<DNSSDResolveServiceQuery>(new BonjourResolveServiceQuery(service, shared_from_this()));
-}
-
-boost::shared_ptr<DNSSDResolveHostnameQuery> BonjourQuerier::createResolveHostnameQuery(const String& hostname, int interfaceIndex) {
-	return boost::shared_ptr<DNSSDResolveHostnameQuery>(new BonjourResolveHostnameQuery(hostname, interfaceIndex, shared_from_this()));
-}
-
-void BonjourQuerier::addRunningQuery(boost::shared_ptr<BonjourQuery> query) {
-	{
-		boost::lock_guard<boost::mutex> lock(runningQueriesMutex);
-		runningQueries.push_back(query);
-	}
-	runningQueriesAvailableEvent.notify_one();
-	interruptSelect();
-}
-
-void BonjourQuerier::removeRunningQuery(boost::shared_ptr<BonjourQuery> query) {
-	{
-		boost::lock_guard<boost::mutex> lock(runningQueriesMutex);
-		runningQueries.erase(std::remove(
-			runningQueries.begin(), runningQueries.end(), query), runningQueries.end());
-	}
-}
-
-void BonjourQuerier::interruptSelect() {
-	char c = 0;
-	write(interruptSelectWriteSocket, &c, 1);
-}
-
-void BonjourQuerier::start() {
-	stop();
-	thread = new boost::thread(boost::bind(&BonjourQuerier::run, shared_from_this()));
-}
-
-void BonjourQuerier::stop() {
-	if (thread) {
-		stopRequested = true;
-		runningQueries.clear(); // TODO: Is this the right thing to do?
-		runningQueriesAvailableEvent.notify_one();
-		interruptSelect();
-		thread->join();
-		delete thread;
-		stopRequested = false;
-	}
-}
-
-void BonjourQuerier::run() {
-	while (!stopRequested) {
-		fd_set fdSet;
-		int maxSocket;
-		{
-			boost::unique_lock<boost::mutex> lock(runningQueriesMutex);
-			if (runningQueries.empty()) {
-				runningQueriesAvailableEvent.wait(lock);
-				if (runningQueries.empty()) {
-					continue;
-				}
-			}
-
-			// Run all running queries
-			FD_ZERO(&fdSet);
-			maxSocket = interruptSelectReadSocket;
-			FD_SET(interruptSelectReadSocket, &fdSet);
-
-			foreach(const boost::shared_ptr<BonjourQuery>& query, runningQueries) {
-				int socketID = query->getSocketID();
-				maxSocket = std::max(maxSocket, socketID);
-				FD_SET(socketID, &fdSet);
-			}
-		}
-
-		if (select(maxSocket+1, &fdSet, NULL, NULL, 0) <= 0) {
-			continue;
-		}
-
-		if (FD_ISSET(interruptSelectReadSocket, &fdSet)) {
-			char dummy;
-			while (read(interruptSelectReadSocket, &dummy, 1) > 0) {}
-		}
-
-		{
-			boost::lock_guard<boost::mutex> lock(runningQueriesMutex);
-			foreach(boost::shared_ptr<BonjourQuery> query, runningQueries) {
-				if (FD_ISSET(query->getSocketID(), &fdSet)) {
-					query->processResult();
-				}
-			}
-		}
-	}
-}
-
-}
diff --git a/Swiften/LinkLocal/BonjourQuerier.h b/Swiften/LinkLocal/BonjourQuerier.h
deleted file mode 100644
index 324e79e..0000000
--- a/Swiften/LinkLocal/BonjourQuerier.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-
-#include <boost/shared_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
-#include <list>
-#include <boost/thread.hpp>
-#include <boost/thread/mutex.hpp>
-
-#include "Swiften/LinkLocal/DNSSDQuerier.h"
-#include "Swiften/LinkLocal/BonjourQuery.h"
-
-namespace Swift {
-	class LinkLocalServiceInfo;
-
-	class BonjourQuerier : 
-			public DNSSDQuerier, 
-			public boost::enable_shared_from_this<BonjourQuerier> {
-		public:
-			BonjourQuerier();
-			~BonjourQuerier();
-
-			boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery();
-			boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery(
-					const String& name, int port, const LinkLocalServiceInfo& info);
-			boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery(
-					const LinkLocalServiceID&);
-			boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery(
-					const String& hostname, int interfaceIndex);
-
-			void start();
-			void stop();
-
-		private:
-			friend class BonjourQuery;
-
-			void addRunningQuery(boost::shared_ptr<BonjourQuery>);
-			void removeRunningQuery(boost::shared_ptr<BonjourQuery>);
-			void interruptSelect();
-			void run();
-
-		private:
-			bool stopRequested;
-			boost::thread* thread;
-			boost::mutex runningQueriesMutex;
-			std::list< boost::shared_ptr<BonjourQuery> > runningQueries;
-			int interruptSelectReadSocket;
-			int interruptSelectWriteSocket;
-			boost::condition_variable runningQueriesAvailableEvent;
-	};
-}
diff --git a/Swiften/LinkLocal/BonjourQuery.cpp b/Swiften/LinkLocal/BonjourQuery.cpp
deleted file mode 100644
index a9c13fb..0000000
--- a/Swiften/LinkLocal/BonjourQuery.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "Swiften/LinkLocal/BonjourQuery.h"
-#include "Swiften/LinkLocal/BonjourQuerier.h"
-
-namespace Swift {
-
-BonjourQuery::BonjourQuery(boost::shared_ptr<BonjourQuerier> q) : querier(q), sdRef(0) {
-}
-
-BonjourQuery::~BonjourQuery() {
-	DNSServiceRefDeallocate(sdRef);
-}
-
-void BonjourQuery::processResult() {
-	boost::lock_guard<boost::mutex> lock(sdRefMutex);
-	DNSServiceProcessResult(sdRef);
-}
-
-int BonjourQuery::getSocketID() const {
-	boost::lock_guard<boost::mutex> lock(sdRefMutex);
-	return DNSServiceRefSockFD(sdRef);
-}
-
-void BonjourQuery::run() {
-	querier->addRunningQuery(shared_from_this());
-}
-
-void BonjourQuery::finish() {
-	querier->removeRunningQuery(shared_from_this());
-}
-
-}
diff --git a/Swiften/LinkLocal/BonjourQuery.h b/Swiften/LinkLocal/BonjourQuery.h
deleted file mode 100644
index bdb91a4..0000000
--- a/Swiften/LinkLocal/BonjourQuery.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <dns_sd.h>
-#include <boost/shared_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
-#include <boost/thread/mutex.hpp>
-
-#include "Swiften/EventLoop/EventOwner.h"
-
-namespace Swift {
-	class BonjourQuerier;
-
-	class BonjourQuery : 
-			public EventOwner,
-			public boost::enable_shared_from_this<BonjourQuery> {
-		public:
-			BonjourQuery(boost::shared_ptr<BonjourQuerier>);
-			virtual ~BonjourQuery();
-			
-			void processResult();
-			int getSocketID() const;
-
-		protected:
-			void run();
-			void finish();
-		
-		protected:
-			boost::shared_ptr<BonjourQuerier> querier;
-			mutable boost::mutex sdRefMutex;
-			DNSServiceRef sdRef;
-	};
-}
diff --git a/Swiften/LinkLocal/BonjourRegisterQuery.h b/Swiften/LinkLocal/BonjourRegisterQuery.h
deleted file mode 100644
index c34ba02..0000000
--- a/Swiften/LinkLocal/BonjourRegisterQuery.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-
-#include "Swiften/LinkLocal/BonjourQuery.h"
-#include "Swiften/LinkLocal/DNSSDRegisterQuery.h"
-#include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
-#include "Swiften/Base/ByteArray.h"
-#include "Swiften/EventLoop/MainEventLoop.h"
-
-namespace Swift {
-	class BonjourQuerier;
-
-	class BonjourRegisterQuery : public DNSSDRegisterQuery, public BonjourQuery {
-		public:	
-			BonjourRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) {
-				ByteArray txtRecord = info.toTXTRecord();
-				DNSServiceErrorType result = DNSServiceRegister(
-						&sdRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, 
-						txtRecord.getSize(), txtRecord.getData(), 
-						&BonjourRegisterQuery::handleServiceRegisteredStatic, this);
-				if (result != kDNSServiceErr_NoError) {
-					// TODO
-					std::cerr << "Error creating service registration" << std::endl;
-				}
-			}
-
-			void registerService() {
-				run();
-			}
-
-			void updateServiceInfo(const LinkLocalServiceInfo& info) {
-				boost::lock_guard<boost::mutex> lock(sdRefMutex);
-				ByteArray txtRecord = info.toTXTRecord();
-				DNSServiceUpdateRecord(sdRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0);
-			}
-
-		private:
-			static void handleServiceRegisteredStatic(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) {
-				static_cast<BonjourRegisterQuery*>(context)->handleServiceRegistered(errorCode, name, regtype, domain);
-			}
-
-			void handleServiceRegistered(DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain) {
-				if (errorCode != kDNSServiceErr_NoError) {
-					MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>()), shared_from_this());
-				}
-				else {
-					MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0))), shared_from_this());
-				}
-			}
-	};
-}
diff --git a/Swiften/LinkLocal/BonjourResolveHostnameQuery.h b/Swiften/LinkLocal/BonjourResolveHostnameQuery.h
deleted file mode 100644
index 771fc84..0000000
--- a/Swiften/LinkLocal/BonjourResolveHostnameQuery.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#pragma once
-
-#include "Swiften/Base/String.h"
-#include "Swiften/LinkLocal/BonjourQuery.h"
-#include "Swiften/LinkLocal/DNSSDResolveHostnameQuery.h"
-#include "Swiften/EventLoop/MainEventLoop.h"
-#include "Swiften/Network/HostAddress.h"
-
-#include <netinet/in.h>
-
-namespace Swift {
-	class BonjourQuerier;
-
-	class BonjourResolveHostnameQuery : public DNSSDResolveHostnameQuery, public BonjourQuery {
-		public:	
-			BonjourResolveHostnameQuery(const String& hostname, int interfaceIndex, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) {
-				DNSServiceErrorType result = DNSServiceGetAddrInfo(
-						&sdRef, 0, interfaceIndex, kDNSServiceProtocol_IPv4, 
-						hostname.getUTF8Data(), 
-						&BonjourResolveHostnameQuery::handleHostnameResolvedStatic, this);
-				if (result != kDNSServiceErr_NoError) {
-					MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>()), shared_from_this());
-				}
-			}
-
-			//void DNSSDResolveHostnameQuery::run() {
-			void run() {
-				BonjourQuery::run();
-			}
-
-		private:
-			static void handleHostnameResolvedStatic(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char*, const struct sockaddr *address, uint32_t, void *context) {
-				static_cast<BonjourResolveHostnameQuery*>(context)->handleHostnameResolved(errorCode, address);
-			} 
-
-			void handleHostnameResolved(DNSServiceErrorType errorCode, const struct sockaddr *rawAddress) {
-				if (errorCode) {
-					MainEventLoop::postEvent(
-								boost::bind(boost::ref(onHostnameResolved), 
-								boost::optional<HostAddress>()), 
-							shared_from_this());
-				}
-				else {
-					assert(rawAddress->sa_family == AF_INET);
-					const sockaddr_in* sa = reinterpret_cast<const sockaddr_in*>(rawAddress);
-					uint32_t address = ntohl(sa->sin_addr.s_addr);
-					MainEventLoop::postEvent(boost::bind(
-								boost::ref(onHostnameResolved), 
-								HostAddress(reinterpret_cast<unsigned char*>(&address), 4)), 
-							shared_from_this());
-				}
-			}
-	};
-}
diff --git a/Swiften/LinkLocal/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/BonjourResolveServiceQuery.h
deleted file mode 100644
index e4f02ee..0000000
--- a/Swiften/LinkLocal/BonjourResolveServiceQuery.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-#include "Swiften/LinkLocal/BonjourQuery.h"
-#include "Swiften/LinkLocal/DNSSDResolveServiceQuery.h"
-#include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
-#include "Swiften/Base/ByteArray.h"
-#include "Swiften/EventLoop/MainEventLoop.h"
-
-namespace Swift {
-	class BonjourQuerier;
-
-	class BonjourResolveServiceQuery : public DNSSDResolveServiceQuery, public BonjourQuery {
-		public:	
-			BonjourResolveServiceQuery(const LinkLocalServiceID& service, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) {
-				DNSServiceErrorType result = DNSServiceResolve(
-						&sdRef, 0, service.getNetworkInterfaceID(), 
-						service.getName().getUTF8Data(), service.getType().getUTF8Data(), 
-						service.getDomain().getUTF8Data(), 
-						&BonjourResolveServiceQuery::handleServiceResolvedStatic, this);
-				if (result != kDNSServiceErr_NoError) {
-					MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this());
-				}
-			}
-
-			void start() {
-				run();
-			}
-
-			void stop() {
-				finish();
-			}
-
-		private:
-			static void handleServiceResolvedStatic(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context) {
-				static_cast<BonjourResolveServiceQuery*>(context)->handleServiceResolved(errorCode, fullname, hosttarget, port, txtLen, txtRecord);
-			}
-
-			void handleServiceResolved(DNSServiceErrorType errorCode, const char* fullName, const char* host, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord) {
-				if (errorCode != kDNSServiceErr_NoError) {
-					MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this());
-				}
-				else {
-					MainEventLoop::postEvent(
-							boost::bind(
-								boost::ref(onServiceResolved), 
-								Result(String(fullName), String(host), port, 
-									LinkLocalServiceInfo::createFromTXTRecord(
-										ByteArray(reinterpret_cast<const char*>(txtRecord), txtLen)))), 
-							shared_from_this());
-				}
-			}
-	};
-}
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h
new file mode 100644
index 0000000..edff064
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h"
+#include "Swiften/EventLoop/MainEventLoop.h"
+
+namespace Swift {
+	class BonjourQuerier;
+
+	class BonjourBrowseQuery : public DNSSDBrowseQuery, public BonjourQuery {
+		public:	
+			BonjourBrowseQuery(boost::shared_ptr<BonjourQuerier> q) : BonjourQuery(q) {
+				DNSServiceErrorType result = DNSServiceBrowse(
+						&sdRef, 0, 0, "_presence._tcp", 0, 
+						&BonjourBrowseQuery::handleServiceDiscoveredStatic, this);
+				if (result != kDNSServiceErr_NoError) {
+					std::cout << "Error" << std::endl;
+					// TODO
+				}
+			}
+
+			void startBrowsing() {
+				assert(sdRef);
+				run();
+			}
+
+			void stopBrowsing() {
+				finish();
+			}
+
+		private:
+			static void handleServiceDiscoveredStatic(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain, void *context) {
+				static_cast<BonjourBrowseQuery*>(context)->handleServiceDiscovered(flags, interfaceIndex, errorCode, name, type, domain);
+			}
+
+			void handleServiceDiscovered(DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain) {
+				if (errorCode != kDNSServiceErr_NoError) {
+					return;
+				}
+				else {
+					LinkLocalServiceID service(name, type, domain, interfaceIndex);
+					if (flags & kDNSServiceFlagsAdd) {
+						MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this());
+					}
+					else {
+						MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this());
+					}
+				}
+			}
+	};
+}
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp
new file mode 100644
index 0000000..064e3c5
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp
@@ -0,0 +1,128 @@
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h"
+
+#include <unistd.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h"
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h"
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h"
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h"
+#include "Swiften/Base/foreach.h"
+
+namespace Swift {
+
+BonjourQuerier::BonjourQuerier() : stopRequested(false), thread(0) {
+	int fds[2];
+	int result = pipe(fds);
+	assert(result == 0);
+	interruptSelectReadSocket = fds[0];
+	fcntl(interruptSelectReadSocket, F_SETFL, fcntl(interruptSelectReadSocket, F_GETFL)|O_NONBLOCK);
+	interruptSelectWriteSocket = fds[1];
+}
+
+BonjourQuerier::~BonjourQuerier() {
+	stop();
+}
+
+boost::shared_ptr<DNSSDBrowseQuery> BonjourQuerier::createBrowseQuery() {
+	return boost::shared_ptr<DNSSDBrowseQuery>(new BonjourBrowseQuery(shared_from_this()));
+}
+
+boost::shared_ptr<DNSSDRegisterQuery> BonjourQuerier::createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info) {
+	return boost::shared_ptr<DNSSDRegisterQuery>(new BonjourRegisterQuery(name, port, info, shared_from_this()));
+}
+
+boost::shared_ptr<DNSSDResolveServiceQuery> BonjourQuerier::createResolveServiceQuery(const LinkLocalServiceID& service) {
+	return boost::shared_ptr<DNSSDResolveServiceQuery>(new BonjourResolveServiceQuery(service, shared_from_this()));
+}
+
+boost::shared_ptr<DNSSDResolveHostnameQuery> BonjourQuerier::createResolveHostnameQuery(const String& hostname, int interfaceIndex) {
+	return boost::shared_ptr<DNSSDResolveHostnameQuery>(new BonjourResolveHostnameQuery(hostname, interfaceIndex, shared_from_this()));
+}
+
+void BonjourQuerier::addRunningQuery(boost::shared_ptr<BonjourQuery> query) {
+	{
+		boost::lock_guard<boost::mutex> lock(runningQueriesMutex);
+		runningQueries.push_back(query);
+	}
+	runningQueriesAvailableEvent.notify_one();
+	interruptSelect();
+}
+
+void BonjourQuerier::removeRunningQuery(boost::shared_ptr<BonjourQuery> query) {
+	{
+		boost::lock_guard<boost::mutex> lock(runningQueriesMutex);
+		runningQueries.erase(std::remove(
+			runningQueries.begin(), runningQueries.end(), query), runningQueries.end());
+	}
+}
+
+void BonjourQuerier::interruptSelect() {
+	char c = 0;
+	write(interruptSelectWriteSocket, &c, 1);
+}
+
+void BonjourQuerier::start() {
+	stop();
+	thread = new boost::thread(boost::bind(&BonjourQuerier::run, shared_from_this()));
+}
+
+void BonjourQuerier::stop() {
+	if (thread) {
+		stopRequested = true;
+		runningQueries.clear(); // TODO: Is this the right thing to do?
+		runningQueriesAvailableEvent.notify_one();
+		interruptSelect();
+		thread->join();
+		delete thread;
+		stopRequested = false;
+	}
+}
+
+void BonjourQuerier::run() {
+	while (!stopRequested) {
+		fd_set fdSet;
+		int maxSocket;
+		{
+			boost::unique_lock<boost::mutex> lock(runningQueriesMutex);
+			if (runningQueries.empty()) {
+				runningQueriesAvailableEvent.wait(lock);
+				if (runningQueries.empty()) {
+					continue;
+				}
+			}
+
+			// Run all running queries
+			FD_ZERO(&fdSet);
+			maxSocket = interruptSelectReadSocket;
+			FD_SET(interruptSelectReadSocket, &fdSet);
+
+			foreach(const boost::shared_ptr<BonjourQuery>& query, runningQueries) {
+				int socketID = query->getSocketID();
+				maxSocket = std::max(maxSocket, socketID);
+				FD_SET(socketID, &fdSet);
+			}
+		}
+
+		if (select(maxSocket+1, &fdSet, NULL, NULL, 0) <= 0) {
+			continue;
+		}
+
+		if (FD_ISSET(interruptSelectReadSocket, &fdSet)) {
+			char dummy;
+			while (read(interruptSelectReadSocket, &dummy, 1) > 0) {}
+		}
+
+		{
+			boost::lock_guard<boost::mutex> lock(runningQueriesMutex);
+			foreach(boost::shared_ptr<BonjourQuery> query, runningQueries) {
+				if (FD_ISSET(query->getSocketID(), &fdSet)) {
+					query->processResult();
+				}
+			}
+		}
+	}
+}
+
+}
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h
new file mode 100644
index 0000000..79f9a81
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <list>
+#include <boost/thread.hpp>
+#include <boost/thread/mutex.hpp>
+
+#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h"
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h"
+
+namespace Swift {
+	class LinkLocalServiceInfo;
+
+	class BonjourQuerier : 
+			public DNSSDQuerier, 
+			public boost::enable_shared_from_this<BonjourQuerier> {
+		public:
+			BonjourQuerier();
+			~BonjourQuerier();
+
+			boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery();
+			boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery(
+					const String& name, int port, const LinkLocalServiceInfo& info);
+			boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery(
+					const LinkLocalServiceID&);
+			boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery(
+					const String& hostname, int interfaceIndex);
+
+			void start();
+			void stop();
+
+		private:
+			friend class BonjourQuery;
+
+			void addRunningQuery(boost::shared_ptr<BonjourQuery>);
+			void removeRunningQuery(boost::shared_ptr<BonjourQuery>);
+			void interruptSelect();
+			void run();
+
+		private:
+			bool stopRequested;
+			boost::thread* thread;
+			boost::mutex runningQueriesMutex;
+			std::list< boost::shared_ptr<BonjourQuery> > runningQueries;
+			int interruptSelectReadSocket;
+			int interruptSelectWriteSocket;
+			boost::condition_variable runningQueriesAvailableEvent;
+	};
+}
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp
new file mode 100644
index 0000000..c1c481b
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp
@@ -0,0 +1,31 @@
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h"
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h"
+
+namespace Swift {
+
+BonjourQuery::BonjourQuery(boost::shared_ptr<BonjourQuerier> q) : querier(q), sdRef(0) {
+}
+
+BonjourQuery::~BonjourQuery() {
+	DNSServiceRefDeallocate(sdRef);
+}
+
+void BonjourQuery::processResult() {
+	boost::lock_guard<boost::mutex> lock(sdRefMutex);
+	DNSServiceProcessResult(sdRef);
+}
+
+int BonjourQuery::getSocketID() const {
+	boost::lock_guard<boost::mutex> lock(sdRefMutex);
+	return DNSServiceRefSockFD(sdRef);
+}
+
+void BonjourQuery::run() {
+	querier->addRunningQuery(shared_from_this());
+}
+
+void BonjourQuery::finish() {
+	querier->removeRunningQuery(shared_from_this());
+}
+
+}
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h
new file mode 100644
index 0000000..bdb91a4
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <dns_sd.h>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/thread/mutex.hpp>
+
+#include "Swiften/EventLoop/EventOwner.h"
+
+namespace Swift {
+	class BonjourQuerier;
+
+	class BonjourQuery : 
+			public EventOwner,
+			public boost::enable_shared_from_this<BonjourQuery> {
+		public:
+			BonjourQuery(boost::shared_ptr<BonjourQuerier>);
+			virtual ~BonjourQuery();
+			
+			void processResult();
+			int getSocketID() const;
+
+		protected:
+			void run();
+			void finish();
+		
+		protected:
+			boost::shared_ptr<BonjourQuerier> querier;
+			mutable boost::mutex sdRefMutex;
+			DNSServiceRef sdRef;
+	};
+}
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h
new file mode 100644
index 0000000..31e86fc
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h"
+#include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
+#include "Swiften/Base/ByteArray.h"
+#include "Swiften/EventLoop/MainEventLoop.h"
+
+namespace Swift {
+	class BonjourQuerier;
+
+	class BonjourRegisterQuery : public DNSSDRegisterQuery, public BonjourQuery {
+		public:	
+			BonjourRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) {
+				ByteArray txtRecord = info.toTXTRecord();
+				DNSServiceErrorType result = DNSServiceRegister(
+						&sdRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, 
+						txtRecord.getSize(), txtRecord.getData(), 
+						&BonjourRegisterQuery::handleServiceRegisteredStatic, this);
+				if (result != kDNSServiceErr_NoError) {
+					// TODO
+					std::cerr << "Error creating service registration" << std::endl;
+				}
+			}
+
+			void registerService() {
+				run();
+			}
+
+			void updateServiceInfo(const LinkLocalServiceInfo& info) {
+				boost::lock_guard<boost::mutex> lock(sdRefMutex);
+				ByteArray txtRecord = info.toTXTRecord();
+				DNSServiceUpdateRecord(sdRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0);
+			}
+
+		private:
+			static void handleServiceRegisteredStatic(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) {
+				static_cast<BonjourRegisterQuery*>(context)->handleServiceRegistered(errorCode, name, regtype, domain);
+			}
+
+			void handleServiceRegistered(DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain) {
+				if (errorCode != kDNSServiceErr_NoError) {
+					MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>()), shared_from_this());
+				}
+				else {
+					MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0))), shared_from_this());
+				}
+			}
+	};
+}
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h
new file mode 100644
index 0000000..58c6588
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include "Swiften/Base/String.h"
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h"
+#include "Swiften/EventLoop/MainEventLoop.h"
+#include "Swiften/Network/HostAddress.h"
+
+#include <netinet/in.h>
+
+namespace Swift {
+	class BonjourQuerier;
+
+	class BonjourResolveHostnameQuery : public DNSSDResolveHostnameQuery, public BonjourQuery {
+		public:	
+			BonjourResolveHostnameQuery(const String& hostname, int interfaceIndex, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) {
+				DNSServiceErrorType result = DNSServiceGetAddrInfo(
+						&sdRef, 0, interfaceIndex, kDNSServiceProtocol_IPv4, 
+						hostname.getUTF8Data(), 
+						&BonjourResolveHostnameQuery::handleHostnameResolvedStatic, this);
+				if (result != kDNSServiceErr_NoError) {
+					MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>()), shared_from_this());
+				}
+			}
+
+			//void DNSSDResolveHostnameQuery::run() {
+			void run() {
+				BonjourQuery::run();
+			}
+
+		private:
+			static void handleHostnameResolvedStatic(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char*, const struct sockaddr *address, uint32_t, void *context) {
+				static_cast<BonjourResolveHostnameQuery*>(context)->handleHostnameResolved(errorCode, address);
+			} 
+
+			void handleHostnameResolved(DNSServiceErrorType errorCode, const struct sockaddr *rawAddress) {
+				if (errorCode) {
+					MainEventLoop::postEvent(
+								boost::bind(boost::ref(onHostnameResolved), 
+								boost::optional<HostAddress>()), 
+							shared_from_this());
+				}
+				else {
+					assert(rawAddress->sa_family == AF_INET);
+					const sockaddr_in* sa = reinterpret_cast<const sockaddr_in*>(rawAddress);
+					uint32_t address = ntohl(sa->sin_addr.s_addr);
+					MainEventLoop::postEvent(boost::bind(
+								boost::ref(onHostnameResolved), 
+								HostAddress(reinterpret_cast<unsigned char*>(&address), 4)), 
+							shared_from_this());
+				}
+			}
+	};
+}
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h
new file mode 100644
index 0000000..1afdf5a
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h
@@ -0,0 +1,53 @@
+#pragma once
+
+#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h"
+#include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
+#include "Swiften/Base/ByteArray.h"
+#include "Swiften/EventLoop/MainEventLoop.h"
+
+namespace Swift {
+	class BonjourQuerier;
+
+	class BonjourResolveServiceQuery : public DNSSDResolveServiceQuery, public BonjourQuery {
+		public:	
+			BonjourResolveServiceQuery(const LinkLocalServiceID& service, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) {
+				DNSServiceErrorType result = DNSServiceResolve(
+						&sdRef, 0, service.getNetworkInterfaceID(), 
+						service.getName().getUTF8Data(), service.getType().getUTF8Data(), 
+						service.getDomain().getUTF8Data(), 
+						&BonjourResolveServiceQuery::handleServiceResolvedStatic, this);
+				if (result != kDNSServiceErr_NoError) {
+					MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this());
+				}
+			}
+
+			void start() {
+				run();
+			}
+
+			void stop() {
+				finish();
+			}
+
+		private:
+			static void handleServiceResolvedStatic(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context) {
+				static_cast<BonjourResolveServiceQuery*>(context)->handleServiceResolved(errorCode, fullname, hosttarget, port, txtLen, txtRecord);
+			}
+
+			void handleServiceResolved(DNSServiceErrorType errorCode, const char* fullName, const char* host, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord) {
+				if (errorCode != kDNSServiceErr_NoError) {
+					MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this());
+				}
+				else {
+					MainEventLoop::postEvent(
+							boost::bind(
+								boost::ref(onServiceResolved), 
+								Result(String(fullName), String(host), port, 
+									LinkLocalServiceInfo::createFromTXTRecord(
+										ByteArray(reinterpret_cast<const char*>(txtRecord), txtLen)))), 
+							shared_from_this());
+				}
+			}
+	};
+}
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/Makefile.inc b/Swiften/LinkLocal/DNSSD/Bonjour/Makefile.inc
new file mode 100644
index 0000000..efa329d
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/Makefile.inc
@@ -0,0 +1,3 @@
+SWIFTEN_SOURCES += \
+	Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp \
+	Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp
new file mode 100644
index 0000000..1dbff2c
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h"
+
+namespace Swift {
+
+DNSSDBrowseQuery::~DNSSDBrowseQuery() {
+}
+
+}
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h
new file mode 100644
index 0000000..e548ca5
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <boost/signal.hpp>
+
+#include "Swiften/LinkLocal/LinkLocalServiceID.h"
+
+namespace Swift {
+	class DNSSDBrowseQuery {
+		public:
+			virtual ~DNSSDBrowseQuery();
+
+			virtual void startBrowsing() = 0;
+			virtual void stopBrowsing() = 0;
+
+			boost::signal<void (const LinkLocalServiceID&)> onServiceAdded;
+			boost::signal<void (const LinkLocalServiceID&)> onServiceRemoved;
+	};
+}
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp
new file mode 100644
index 0000000..cc8d6ef
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h"
+
+namespace Swift {
+
+DNSSDQuerier::~DNSSDQuerier() {
+}
+
+}
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h
new file mode 100644
index 0000000..528a6ea
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+	class String;
+	class LinkLocalServiceInfo;
+	class LinkLocalServiceID;
+	class DNSSDBrowseQuery;
+	class DNSSDRegisterQuery;
+	class DNSSDResolveServiceQuery;
+	class DNSSDResolveHostnameQuery;
+
+	class DNSSDQuerier {
+		public:
+			virtual ~DNSSDQuerier();
+
+			virtual boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery() = 0;
+			virtual boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery(
+					const String& name, int port, const LinkLocalServiceInfo& info) = 0;
+			virtual boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery(
+					const LinkLocalServiceID&) = 0;
+			virtual boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery(
+					const String& hostname, int interfaceIndex) = 0;
+	};
+}
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp
new file mode 100644
index 0000000..bbb8692
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h"
+
+namespace Swift {
+
+DNSSDRegisterQuery::~DNSSDRegisterQuery() {
+}
+
+}
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h
new file mode 100644
index 0000000..252fbf0
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <boost/signal.hpp>
+#include <boost/optional.hpp>
+
+#include "Swiften/LinkLocal/LinkLocalServiceID.h"
+
+namespace Swift {
+	class LinkLocalServiceInfo;
+
+	class DNSSDRegisterQuery {
+		public:
+			virtual ~DNSSDRegisterQuery();
+
+			virtual void registerService() = 0;
+			virtual void updateServiceInfo(const LinkLocalServiceInfo& info) = 0;
+
+			boost::signal<void (boost::optional<LinkLocalServiceID>)> onRegisterFinished;
+	};
+}
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp
new file mode 100644
index 0000000..e247e39
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h"
+
+namespace Swift {
+
+DNSSDResolveHostnameQuery::~DNSSDResolveHostnameQuery() {
+}
+
+}
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h
new file mode 100644
index 0000000..a2e218c
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <boost/signal.hpp>
+#include <boost/optional.hpp>
+
+#include "Swiften/Network/HostAddress.h"
+
+namespace Swift {
+	class DNSSDResolveHostnameQuery {
+		public:
+			virtual ~DNSSDResolveHostnameQuery();
+
+			virtual void run() = 0;
+
+			boost::signal<void (const boost::optional<HostAddress>&)> onHostnameResolved;
+	};
+}
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp
new file mode 100644
index 0000000..67a5d66
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h"
+
+namespace Swift {
+
+DNSSDResolveServiceQuery::~DNSSDResolveServiceQuery() {
+}
+
+}
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h
new file mode 100644
index 0000000..d8b5cf1
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <boost/signal.hpp>
+#include <boost/optional.hpp>
+
+#include "Swiften/LinkLocal/LinkLocalServiceID.h"
+#include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
+
+namespace Swift {
+	class DNSSDResolveServiceQuery {
+		public:
+			struct Result {
+				Result(const String& fullName, const String& host, int port, 
+						const LinkLocalServiceInfo& info) : 
+							fullName(fullName), host(host), port(port), info(info) {}
+				String fullName;
+				String host;
+				int port;
+				LinkLocalServiceInfo info;
+			};
+
+			virtual ~DNSSDResolveServiceQuery();
+
+			virtual void start() = 0;
+			virtual void stop() = 0;
+
+			boost::signal<void (const boost::optional<Result>&)> onServiceResolved;
+	};
+}
diff --git a/Swiften/LinkLocal/DNSSD/Makefile.inc b/Swiften/LinkLocal/DNSSD/Makefile.inc
new file mode 100644
index 0000000..81beee0
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Makefile.inc
@@ -0,0 +1,12 @@
+SWIFTEN_SOURCES += \
+	Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp \
+	Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp \
+	Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp \
+	Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp \
+	Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp
+
+ifeq ($(HAVE_BONJOUR),yes)
+include Swiften/LinkLocal/DNSSD/Bonjour/Makefile.inc
+endif
+ifeq ($(HAVE_AVAHI),yes)
+endif
diff --git a/Swiften/LinkLocal/DNSSDBrowseQuery.cpp b/Swiften/LinkLocal/DNSSDBrowseQuery.cpp
deleted file mode 100644
index 4924247..0000000
--- a/Swiften/LinkLocal/DNSSDBrowseQuery.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "Swiften/LinkLocal/DNSSDBrowseQuery.h"
-
-namespace Swift {
-
-DNSSDBrowseQuery::~DNSSDBrowseQuery() {
-}
-
-}
diff --git a/Swiften/LinkLocal/DNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSDBrowseQuery.h
deleted file mode 100644
index e548ca5..0000000
--- a/Swiften/LinkLocal/DNSSDBrowseQuery.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include <boost/signal.hpp>
-
-#include "Swiften/LinkLocal/LinkLocalServiceID.h"
-
-namespace Swift {
-	class DNSSDBrowseQuery {
-		public:
-			virtual ~DNSSDBrowseQuery();
-
-			virtual void startBrowsing() = 0;
-			virtual void stopBrowsing() = 0;
-
-			boost::signal<void (const LinkLocalServiceID&)> onServiceAdded;
-			boost::signal<void (const LinkLocalServiceID&)> onServiceRemoved;
-	};
-}
diff --git a/Swiften/LinkLocal/DNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSDQuerier.cpp
deleted file mode 100644
index be87a3c..0000000
--- a/Swiften/LinkLocal/DNSSDQuerier.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "Swiften/LinkLocal/DNSSDQuerier.h"
-
-namespace Swift {
-
-DNSSDQuerier::~DNSSDQuerier() {
-}
-
-}
diff --git a/Swiften/LinkLocal/DNSSDQuerier.h b/Swiften/LinkLocal/DNSSDQuerier.h
deleted file mode 100644
index 528a6ea..0000000
--- a/Swiften/LinkLocal/DNSSDQuerier.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include <boost/shared_ptr.hpp>
-
-namespace Swift {
-	class String;
-	class LinkLocalServiceInfo;
-	class LinkLocalServiceID;
-	class DNSSDBrowseQuery;
-	class DNSSDRegisterQuery;
-	class DNSSDResolveServiceQuery;
-	class DNSSDResolveHostnameQuery;
-
-	class DNSSDQuerier {
-		public:
-			virtual ~DNSSDQuerier();
-
-			virtual boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery() = 0;
-			virtual boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery(
-					const String& name, int port, const LinkLocalServiceInfo& info) = 0;
-			virtual boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery(
-					const LinkLocalServiceID&) = 0;
-			virtual boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery(
-					const String& hostname, int interfaceIndex) = 0;
-	};
-}
diff --git a/Swiften/LinkLocal/DNSSDRegisterQuery.cpp b/Swiften/LinkLocal/DNSSDRegisterQuery.cpp
deleted file mode 100644
index fe00b02..0000000
--- a/Swiften/LinkLocal/DNSSDRegisterQuery.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "Swiften/LinkLocal/DNSSDRegisterQuery.h"
-
-namespace Swift {
-
-DNSSDRegisterQuery::~DNSSDRegisterQuery() {
-}
-
-}
diff --git a/Swiften/LinkLocal/DNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSDRegisterQuery.h
deleted file mode 100644
index 252fbf0..0000000
--- a/Swiften/LinkLocal/DNSSDRegisterQuery.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include <boost/signal.hpp>
-#include <boost/optional.hpp>
-
-#include "Swiften/LinkLocal/LinkLocalServiceID.h"
-
-namespace Swift {
-	class LinkLocalServiceInfo;
-
-	class DNSSDRegisterQuery {
-		public:
-			virtual ~DNSSDRegisterQuery();
-
-			virtual void registerService() = 0;
-			virtual void updateServiceInfo(const LinkLocalServiceInfo& info) = 0;
-
-			boost::signal<void (boost::optional<LinkLocalServiceID>)> onRegisterFinished;
-	};
-}
diff --git a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp
deleted file mode 100644
index f7c88bd..0000000
--- a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "Swiften/LinkLocal/DNSSDResolveHostnameQuery.h"
-
-namespace Swift {
-
-DNSSDResolveHostnameQuery::~DNSSDResolveHostnameQuery() {
-}
-
-}
diff --git a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h
deleted file mode 100644
index a2e218c..0000000
--- a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include <boost/signal.hpp>
-#include <boost/optional.hpp>
-
-#include "Swiften/Network/HostAddress.h"
-
-namespace Swift {
-	class DNSSDResolveHostnameQuery {
-		public:
-			virtual ~DNSSDResolveHostnameQuery();
-
-			virtual void run() = 0;
-
-			boost::signal<void (const boost::optional<HostAddress>&)> onHostnameResolved;
-	};
-}
diff --git a/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp b/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp
deleted file mode 100644
index 83a9ccd..0000000
--- a/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "Swiften/LinkLocal/DNSSDResolveServiceQuery.h"
-
-namespace Swift {
-
-DNSSDResolveServiceQuery::~DNSSDResolveServiceQuery() {
-}
-
-}
diff --git a/Swiften/LinkLocal/DNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSDResolveServiceQuery.h
deleted file mode 100644
index d8b5cf1..0000000
--- a/Swiften/LinkLocal/DNSSDResolveServiceQuery.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include <boost/signal.hpp>
-#include <boost/optional.hpp>
-
-#include "Swiften/LinkLocal/LinkLocalServiceID.h"
-#include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
-
-namespace Swift {
-	class DNSSDResolveServiceQuery {
-		public:
-			struct Result {
-				Result(const String& fullName, const String& host, int port, 
-						const LinkLocalServiceInfo& info) : 
-							fullName(fullName), host(host), port(port), info(info) {}
-				String fullName;
-				String host;
-				int port;
-				LinkLocalServiceInfo info;
-			};
-
-			virtual ~DNSSDResolveServiceQuery();
-
-			virtual void start() = 0;
-			virtual void stop() = 0;
-
-			boost::signal<void (const boost::optional<Result>&)> onServiceResolved;
-	};
-}
diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc
index 9522cbb..86a25fd 100644
--- a/Swiften/LinkLocal/Makefile.inc
+++ b/Swiften/LinkLocal/Makefile.inc
@@ -1,12 +1,7 @@
 SWIFTEN_SOURCES += \
-	Swiften/LinkLocal/DNSSDQuerier.cpp \
-	Swiften/LinkLocal/DNSSDBrowseQuery.cpp \
-	Swiften/LinkLocal/DNSSDRegisterQuery.cpp \
-	Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp \
-	Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp \
 	Swiften/LinkLocal/DNSSDServiceFactory.cpp \
-	Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \
 	Swiften/LinkLocal/DNSSDService.cpp \
+	Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \
 	Swiften/LinkLocal/LinkLocalRoster.cpp \
 	Swiften/LinkLocal/LinkLocalServiceID.cpp \
 	Swiften/LinkLocal/LinkLocalServiceInfo.cpp \
@@ -17,8 +12,6 @@ SWIFTEN_SOURCES += \
 
 ifeq ($(HAVE_BONJOUR),yes)
 SWIFTEN_SOURCES += \
-	Swiften/LinkLocal/BonjourQuery.cpp \
-	Swiften/LinkLocal/BonjourQuerier.cpp \
 	Swiften/LinkLocal/AppleDNSSDService.cpp
 endif
 ifeq ($(HAVE_AVAHI),yes)
@@ -26,4 +19,5 @@ SWIFTEN_SOURCES += \
 	Swiften/LinkLocal/AvahiDNSSDService.cpp
 endif
 
+include Swiften/LinkLocal/DNSSD/Makefile.inc
 include Swiften/LinkLocal/UnitTest/Makefile.inc
-- 
cgit v0.10.2-6-g49f6