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) |