diff options
| -rw-r--r-- | Nim/main.cpp | 166 | ||||
| -rw-r--r-- | Swiften/LinkLocal/AppleDNSSDService.cpp | 116 | ||||
| -rw-r--r-- | Swiften/LinkLocal/AppleDNSSDService.h | 26 | ||||
| -rw-r--r-- | Swiften/LinkLocal/DNSSDService.cpp | 8 | ||||
| -rw-r--r-- | Swiften/LinkLocal/DNSSDService.h | 27 | ||||
| -rw-r--r-- | Swiften/LinkLocal/LinkLocalRoster.cpp | 21 | ||||
| -rw-r--r-- | Swiften/LinkLocal/LinkLocalRoster.h | 19 | ||||
| -rw-r--r-- | Swiften/LinkLocal/Makefile.inc | 9 | ||||
| -rw-r--r-- | Swiften/Makefile.inc | 1 | 
9 files changed, 323 insertions, 70 deletions
| diff --git a/Nim/main.cpp b/Nim/main.cpp index 52755ae..2709bb1 100644 --- a/Nim/main.cpp +++ b/Nim/main.cpp @@ -1,85 +1,111 @@ -#include <dns_sd.h> -#include <iostream> -#include <sys/socket.h> +#include <string> +#include <boost/bind.hpp> +#include <boost/shared_ptr.hpp> -#include "Swiften/Network/HostAddress.h" +#include "Swiften/Elements/IQ.h" +#include "Swiften/Elements/RosterPayload.h" +#include "Swiften/Elements/VCard.h" +#include "Swiften/Server/UserRegistry.h" +#include "Swiften/JID/JID.h" +#include "Swiften/Base/String.h" +#include "Swiften/Server/UserRegistry.h" +#include "Swiften/Base/IDGenerator.h" +#include "Swiften/EventLoop/MainEventLoop.h" +#include "Swiften/EventLoop/SimpleEventLoop.h" +#include "Swiften/EventLoop/EventOwner.h" +#include "Swiften/Elements/Stanza.h" +#include "Swiften/LinkLocal/LinkLocalRoster.h" +#include "Swiften/LinkLocal/DNSSDService.h" +#include "Swiften/LinkLocal/AppleDNSSDService.h" +#include "Swiften/Network/ConnectionServer.h" +#include "Swiften/Network/BoostConnection.h" +#include "Swiften/Network/BoostIOServiceThread.h" +#include "Swiften/Network/BoostConnectionServer.h" +#include "Swiften/Server/ServerFromClientSession.h" +#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" +#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"  using namespace Swift; -void handleServiceRegistered(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context ) { -	std::cerr << "Service registered " << name << " " << regtype << " " << domain << std::endl; -} - -void handleServiceDiscovered(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context ) { -	std::cerr << "Service discovered " << interfaceIndex << " " << serviceName << " " << regtype << " " << replyDomain << " " << flags << std::endl; -} - -void handleServiceResolved( DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context ) { -	std::cerr << "Service resolved " << fullname << " " << hosttarget << " " << port << " " << txtLen << " " << /*std::string((const char*) txtRecord, txtLen) <<*/ std::endl; -} -void handleAddressInfoReceived ( DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context ) { -	std::cerr << "Address received " << HostAddress((const unsigned char*) address->sa_data, 4).toString() << std::endl; -}  +class DummyUserRegistry : public UserRegistry { +	public: +		DummyUserRegistry() { +		} -int main(int argc, char* argv[]) { -	fd_set fdSet; -	DNSServiceErrorType result; +		virtual bool isValidUserPassword(const JID&, const String&) const { +			return true; +		} +}; -	DNSServiceRef registerSDRef; -	result = DNSServiceRegister(®isterSDRef, 0, 0, "eemi", "_presence._tcp", NULL, NULL, 5269, 0, NULL, handleServiceRegistered, NULL); -	if (result != kDNSServiceErr_NoError) { -		std::cerr << "Error 1" << std::endl; -	} -	int registerSocket = DNSServiceRefSockFD(registerSDRef); -	FD_ZERO(&fdSet); -	FD_SET(registerSocket, &fdSet); -	select(registerSocket+1, &fdSet, &fdSet, &fdSet, 0); -	DNSServiceProcessResult(registerSDRef); +class Server { +	public: +		Server() { +			serverFromClientConnectionServer_ = boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer(5224, &boostIOServiceThread_.getIOService())); +			serverFromClientConnectionServer_->onNewConnection.connect(boost::bind(&Server::handleNewConnection, this, _1)); +			serverFromClientConnectionServer_->start(); -	DNSServiceRef browseSDRef; -	result = DNSServiceBrowse(&browseSDRef, 0, 0, "_presence._tcp", 0, handleServiceDiscovered , 0); -	if (result != kDNSServiceErr_NoError) { -		std::cerr << "Error 2" << std::endl; -	} -	int browseSocket = DNSServiceRefSockFD(browseSDRef); -	//while(true) { -		FD_ZERO(&fdSet); -		FD_SET(browseSocket, &fdSet); -		select(browseSocket+1, &fdSet, &fdSet, &fdSet, 0); -		DNSServiceProcessResult(browseSDRef); -	//} +			dnsSDService_ = boost::shared_ptr<AppleDNSSDService>(new AppleDNSSDService()); +			linkLocalRoster_ = boost::shared_ptr<LinkLocalRoster>(new LinkLocalRoster(dnsSDService_)); +			dnsSDService_->start(); +			// dnsSDService_->publish +		} +	private: +		void handleNewConnection(boost::shared_ptr<Connection> c) { +			ServerFromClientSession* session = new ServerFromClientSession(idGenerator_.generateID(), c, &payloadParserFactories_, &payloadSerializers_, &userRegistry_); +			serverFromClientSessions_.push_back(session); +			session->onStanzaReceived.connect(boost::bind(&Server::handleStanzaReceived, this, _1, session)); +			session->onSessionFinished.connect(boost::bind(&Server::handleSessionFinished, this, session)); +		} -	DNSServiceRef resolveSDRef; -	result = DNSServiceResolve(&resolveSDRef, 0, 6, "Remko@Micro", "_presence._tcp.", "local.", handleServiceResolved , 0); -	if (result != kDNSServiceErr_NoError) { -		std::cerr << "Error 3" << std::endl; -	} -	int resolveSocket = DNSServiceRefSockFD(resolveSDRef); -	//while(true) { -		FD_ZERO(&fdSet); -		FD_SET(resolveSocket, &fdSet); -		select(resolveSocket+1, &fdSet, &fdSet, &fdSet, 0); -		DNSServiceProcessResult(resolveSDRef); -	//} +		void handleSessionFinished(ServerFromClientSession* session) { +			serverFromClientSessions_.erase(std::remove(serverFromClientSessions_.begin(), serverFromClientSessions_.end(), session), serverFromClientSessions_.end()); +			delete session; +		} +		void handleStanzaReceived(boost::shared_ptr<Stanza> stanza, ServerFromClientSession* session) { +			stanza->setFrom(session->getJID()); +			if (!stanza->getTo().isValid()) { +				stanza->setTo(JID(session->getDomain())); +			} +			if (!stanza->getTo().isValid() || stanza->getTo() == session->getDomain() || stanza->getTo() == session->getJID().toBare()) { +				if (boost::shared_ptr<IQ> iq = boost::dynamic_pointer_cast<IQ>(stanza)) { +					if (iq->getPayload<RosterPayload>()) { +						session->sendStanza(IQ::createResult(iq->getFrom(), iq->getID(), boost::shared_ptr<RosterPayload>(new RosterPayload()))); +					} +					if (iq->getPayload<VCard>()) { +						if (iq->getType() == IQ::Get) { +							boost::shared_ptr<VCard> vcard(new VCard()); +							vcard->setNickname(iq->getFrom().getNode()); +							session->sendStanza(IQ::createResult(iq->getFrom(), iq->getID(), vcard)); +						} +						else { +							session->sendStanza(IQ::createError(iq->getFrom(), iq->getID(), Error::Forbidden, Error::Cancel)); +						} +					} +					else { +						session->sendStanza(IQ::createError(iq->getFrom(), iq->getID(), Error::FeatureNotImplemented, Error::Cancel)); +					} +				} +			} +		} -	DNSServiceRef addressSDRef; -	result = DNSServiceGetAddrInfo(&addressSDRef, 0, 6, kDNSServiceProtocol_IPv4, "Micro.local.", handleAddressInfoReceived, 0); -	if (result != kDNSServiceErr_NoError) { -		std::cerr << "Error 4" << std::endl; -	} -	int addressSocket = DNSServiceRefSockFD(addressSDRef); -	//while(true) { -	std::cout << "GetAddrInfo2" << std::endl; -		FD_ZERO(&fdSet); -		FD_SET(addressSocket, &fdSet); -		select(addressSocket+1, &fdSet, &fdSet, &fdSet, 0); -		DNSServiceProcessResult(addressSDRef); -	//} +	private: +		IDGenerator idGenerator_; +		BoostIOServiceThread boostIOServiceThread_; +		DummyUserRegistry userRegistry_; +		boost::shared_ptr<AppleDNSSDService> dnsSDService_; +		boost::shared_ptr<LinkLocalRoster> linkLocalRoster_; +		boost::shared_ptr<BoostConnectionServer> serverFromClientConnectionServer_; +		std::vector<ServerFromClientSession*> serverFromClientSessions_; +		FullPayloadParserFactoryCollection payloadParserFactories_; +		FullPayloadSerializerCollection payloadSerializers_; +}; -	// DNSServiceRefDeallocate -	 +int main() { +	SimpleEventLoop eventLoop; +	Server server; +	eventLoop.run();  	return 0;  } diff --git a/Swiften/LinkLocal/AppleDNSSDService.cpp b/Swiften/LinkLocal/AppleDNSSDService.cpp new file mode 100644 index 0000000..b68b09e --- /dev/null +++ b/Swiften/LinkLocal/AppleDNSSDService.cpp @@ -0,0 +1,116 @@ +#include "Swiften/LinkLocal/AppleDNSSDService.h" + +#include <dns_sd.h> +#include <iostream> +#include <sys/socket.h> + +namespace Swift { + +namespace { +	void handleServiceRegistered(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context ) { +		std::cerr << "Service registered " << name << " " << regtype << " " << domain << std::endl; +	} + +	void handleServiceDiscovered(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context ) { +		std::cerr << "Service discovered " << interfaceIndex << " " << serviceName << " " << regtype << " " << replyDomain << " " << flags << std::endl; +	} + +	void handleServiceResolved( DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context ) { +		std::cerr << "Service resolved " << fullname << " " << hosttarget << " " << port << " " << txtLen << " " << /*std::string((const char*) txtRecord, txtLen) <<*/ std::endl; +	} + +	void handleAddressInfoReceived ( DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context ) { +		std::cerr << "Address received " << HostAddress((const unsigned char*) address->sa_data, 4).toString() << std::endl; +	}  +} + + +AppleDNSSDService::AppleDNSSDService() : thread(0), stopRequested(false) { +} + +AppleDNSSDService::~AppleDNSSDService() { +	stop(); +} + +void AppleDNSSDService::publishService(const std::map<String,String>) { +} + +void AppleDNSSDService::start() { +	assert(!thread); +	thread = new boost::thread(boost::bind(&AppleDNSSDService::doStart, shared_from_this())); +} + +void AppleDNSSDService::stop() { +	if (thread) { +		stopRequested = true; +		thread->join(); +		delete thread; +		stopRequested = false; +	} +} + +void AppleDNSSDService::doStart() { +	while (!stopRequested) { + +		fd_set fdSet; +		DNSServiceErrorType result; + +		DNSServiceRef registerSDRef; +		result = DNSServiceRegister(®isterSDRef, 0, 0, "eemi", "_presence._tcp", NULL, NULL, 5269, 0, NULL, handleServiceRegistered, NULL); +		if (result != kDNSServiceErr_NoError) { +			std::cerr << "Error 1" << std::endl; +		} +		int registerSocket = DNSServiceRefSockFD(registerSDRef); +		FD_ZERO(&fdSet); +		FD_SET(registerSocket, &fdSet); +		select(registerSocket+1, &fdSet, &fdSet, &fdSet, 0); +		DNSServiceProcessResult(registerSDRef); + +		DNSServiceRef browseSDRef; +		result = DNSServiceBrowse(&browseSDRef, 0, 0, "_presence._tcp", 0, handleServiceDiscovered , 0); +		if (result != kDNSServiceErr_NoError) { +			std::cerr << "Error 2" << std::endl; +		} +		int browseSocket = DNSServiceRefSockFD(browseSDRef); +		//while(true) { +			FD_ZERO(&fdSet); +			FD_SET(browseSocket, &fdSet); +			select(browseSocket+1, &fdSet, &fdSet, &fdSet, 0); +			DNSServiceProcessResult(browseSDRef); +		//} + + +		DNSServiceRef resolveSDRef; +		result = DNSServiceResolve(&resolveSDRef, 0, 6, "Remko@Micro", "_presence._tcp.", "local.", handleServiceResolved , 0); +		if (result != kDNSServiceErr_NoError) { +			std::cerr << "Error 3" << std::endl; +		} +		int resolveSocket = DNSServiceRefSockFD(resolveSDRef); +		//while(true) { +			FD_ZERO(&fdSet); +			FD_SET(resolveSocket, &fdSet); +			select(resolveSocket+1, &fdSet, &fdSet, &fdSet, 0); +			DNSServiceProcessResult(resolveSDRef); +		//} + + +		DNSServiceRef addressSDRef; +		result = DNSServiceGetAddrInfo(&addressSDRef, 0, 6, kDNSServiceProtocol_IPv4, "Micro.local.", handleAddressInfoReceived, 0); +		if (result != kDNSServiceErr_NoError) { +			std::cerr << "Error 4" << std::endl; +		} +		int addressSocket = DNSServiceRefSockFD(addressSDRef); +		//while(true) { +		std::cout << "GetAddrInfo2" << std::endl; +			FD_ZERO(&fdSet); +			FD_SET(addressSocket, &fdSet); +			select(addressSocket+1, &fdSet, &fdSet, &fdSet, 0); +			DNSServiceProcessResult(addressSDRef); +		//} + +		// DNSServiceRefDeallocate + +	} +} + +} diff --git a/Swiften/LinkLocal/AppleDNSSDService.h b/Swiften/LinkLocal/AppleDNSSDService.h new file mode 100644 index 0000000..e6bedf7 --- /dev/null +++ b/Swiften/LinkLocal/AppleDNSSDService.h @@ -0,0 +1,26 @@ +#pragma once + +#include <boost/enable_shared_from_this.hpp> +#include <boost/thread.hpp> + +#include "Swiften/LinkLocal/DNSSDService.h" +#include "Swiften/EventLoop/EventOwner.h" + +namespace Swift { +	class AppleDNSSDService : public DNSSDService, public EventOwner, public boost::enable_shared_from_this<AppleDNSSDService> { +		public: +			AppleDNSSDService(); +			~AppleDNSSDService(); + +			virtual void publishService(const std::map<String,String> properties); +			virtual void start(); +			virtual void stop(); + +		private: +			void doStart(); + +		private: +			boost::thread* thread; +			bool stopRequested; +	}; +} diff --git a/Swiften/LinkLocal/DNSSDService.cpp b/Swiften/LinkLocal/DNSSDService.cpp new file mode 100644 index 0000000..9545981 --- /dev/null +++ b/Swiften/LinkLocal/DNSSDService.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSDService.h" + +namespace Swift { + +DNSSDService::~DNSSDService() { +} + +} diff --git a/Swiften/LinkLocal/DNSSDService.h b/Swiften/LinkLocal/DNSSDService.h new file mode 100644 index 0000000..0899ffd --- /dev/null +++ b/Swiften/LinkLocal/DNSSDService.h @@ -0,0 +1,27 @@ +#pragma once + +#include <boost/signal.hpp> +#include <map> + +#include "Swiften/Base/String.h" + +namespace Swift { +	class DNSSDService { +		public: +			struct DiscoveredService { +				String name; +				String type; +				String domain; +				int networkInterface; +			}; + +			virtual ~DNSSDService(); + +			virtual void publishService(const std::map<String,String> properties) = 0; +			virtual void start() = 0; + +			boost::signal<void (const DiscoveredService&)> onServiceAdded; +			boost::signal<void (const DiscoveredService&)> onServiceRemoved; +			boost::signal<void ()> onServiceRegistered; +	}; +} diff --git a/Swiften/LinkLocal/LinkLocalRoster.cpp b/Swiften/LinkLocal/LinkLocalRoster.cpp new file mode 100644 index 0000000..6773d51 --- /dev/null +++ b/Swiften/LinkLocal/LinkLocalRoster.cpp @@ -0,0 +1,21 @@ +#include <boost/bind.hpp> +#include <iostream> + +#include "Swiften/LinkLocal/LinkLocalRoster.h" + +namespace Swift { + +LinkLocalRoster::LinkLocalRoster(boost::shared_ptr<DNSSDService> service) : dnsSDService(service) { +	service->onServiceAdded.connect(boost::bind(&LinkLocalRoster::handleServiceAdded, this, _1)); +	service->onServiceRemoved.connect(boost::bind(&LinkLocalRoster::handleServiceRemoved, this, _1)); +} + +void LinkLocalRoster::handleServiceAdded(const DNSSDService::DiscoveredService& service) { +	std::cout << "Service added " << service.name << " " << service.type << " " << service.domain << std::endl; +} + +void LinkLocalRoster::handleServiceRemoved(const DNSSDService::DiscoveredService& service) { +	std::cout << "Service removed " << service.name << " " << service.type << " " << service.domain << std::endl; +} + +} diff --git a/Swiften/LinkLocal/LinkLocalRoster.h b/Swiften/LinkLocal/LinkLocalRoster.h new file mode 100644 index 0000000..625bf8b --- /dev/null +++ b/Swiften/LinkLocal/LinkLocalRoster.h @@ -0,0 +1,19 @@ +#pragma once + +#include <boost/shared_ptr.hpp> + +#include "Swiften/LinkLocal/DNSSDService.h" + +namespace Swift { +	class LinkLocalRoster { +		public: +			LinkLocalRoster(boost::shared_ptr<DNSSDService> service); + +		private: +			void handleServiceAdded(const DNSSDService::DiscoveredService&); +			void handleServiceRemoved(const DNSSDService::DiscoveredService&); + +		private: +			boost::shared_ptr<DNSSDService> dnsSDService; +	}; +} diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc new file mode 100644 index 0000000..54315da --- /dev/null +++ b/Swiften/LinkLocal/Makefile.inc @@ -0,0 +1,9 @@ +SWIFTEN_SOURCES += \ +	Swiften/LinkLocal/DNSSDService.cpp \ +	Swiften/LinkLocal/LinkLocalRoster.cpp + + +ifeq ($(MACOSX),1) +SWIFTEN_SOURCES += \ +	Swiften/LinkLocal/AppleDNSSDService.cpp +endif diff --git a/Swiften/Makefile.inc b/Swiften/Makefile.inc index 6e47259..6fa2df8 100644 --- a/Swiften/Makefile.inc +++ b/Swiften/Makefile.inc @@ -22,6 +22,7 @@ include Swiften/Notifier/Makefile.inc  include Swiften/History/Makefile.inc  include Swiften/Avatars/Makefile.inc  include Swiften/Server/Makefile.inc +include Swiften/LinkLocal/Makefile.inc  CPPFLAGS += $(SQLITE_CPPFLAGS) | 
 Swift
 Swift