From b33a2937fe4a3cae0017892ad7f5c27b8a6f976d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Sat, 25 Jul 2009 10:35:33 +0200 Subject: Implement more DNSSD queries. diff --git a/Slimber/CLI/main.cpp b/Slimber/CLI/main.cpp index 65af3bc..3a72ca1 100644 --- a/Slimber/CLI/main.cpp +++ b/Slimber/CLI/main.cpp @@ -22,8 +22,8 @@ int main() { querier->start(); boost::shared_ptr query = querier->createBrowseQuery(); query->startBrowsing(); - boost::shared_ptr query2 = querier->createPublishQuery("remko", 1234, LinkLocalServiceInfo()); - query2->publish(); + boost::shared_ptr query2 = querier->createRegisterQuery("remko", 1234, LinkLocalServiceInfo()); + query2->registerService(); /* boost::shared_ptr dnsSDService; diff --git a/Swiften/LinkLocal/BonjourQuerier.cpp b/Swiften/LinkLocal/BonjourQuerier.cpp index 7764f51..42ba12a 100644 --- a/Swiften/LinkLocal/BonjourQuerier.cpp +++ b/Swiften/LinkLocal/BonjourQuerier.cpp @@ -2,11 +2,12 @@ #include #include -#include #include #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 { @@ -32,6 +33,14 @@ boost::shared_ptr BonjourQuerier::createRegisterQuery(const return boost::shared_ptr(new BonjourRegisterQuery(name, port, info, shared_from_this())); } +boost::shared_ptr BonjourQuerier::createResolveServiceQuery(const LinkLocalServiceID& service) { + return boost::shared_ptr(new BonjourResolveServiceQuery(service, shared_from_this())); +} + +boost::shared_ptr BonjourQuerier::createResolveHostnameQuery(const String& hostname, int interfaceIndex) { + return boost::shared_ptr(new BonjourResolveHostnameQuery(hostname, interfaceIndex, shared_from_this())); +} + void BonjourQuerier::addRunningQuery(boost::shared_ptr query) { { boost::lock_guard lock(runningQueriesMutex); diff --git a/Swiften/LinkLocal/BonjourQuerier.h b/Swiften/LinkLocal/BonjourQuerier.h index a35483c..324e79e 100644 --- a/Swiften/LinkLocal/BonjourQuerier.h +++ b/Swiften/LinkLocal/BonjourQuerier.h @@ -6,20 +6,26 @@ #include #include -#include "Swiften/LinkLocal/DNSSDBrowseQuery.h" -#include "Swiften/LinkLocal/DNSSDRegisterQuery.h" +#include "Swiften/LinkLocal/DNSSDQuerier.h" #include "Swiften/LinkLocal/BonjourQuery.h" namespace Swift { class LinkLocalServiceInfo; - class BonjourQuerier : public boost::enable_shared_from_this { + class BonjourQuerier : + public DNSSDQuerier, + public boost::enable_shared_from_this { public: BonjourQuerier(); ~BonjourQuerier(); boost::shared_ptr createBrowseQuery(); - boost::shared_ptr createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info); + boost::shared_ptr createRegisterQuery( + const String& name, int port, const LinkLocalServiceInfo& info); + boost::shared_ptr createResolveServiceQuery( + const LinkLocalServiceID&); + boost::shared_ptr createResolveHostnameQuery( + const String& hostname, int interfaceIndex); void start(); void stop(); @@ -29,8 +35,6 @@ namespace Swift { void addRunningQuery(boost::shared_ptr); void removeRunningQuery(boost::shared_ptr); - - private: void interruptSelect(); void run(); diff --git a/Swiften/LinkLocal/BonjourResolveHostnameQuery.h b/Swiften/LinkLocal/BonjourResolveHostnameQuery.h new file mode 100644 index 0000000..771fc84 --- /dev/null +++ b/Swiften/LinkLocal/BonjourResolveHostnameQuery.h @@ -0,0 +1,54 @@ +#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 + +namespace Swift { + class BonjourQuerier; + + class BonjourResolveHostnameQuery : public DNSSDResolveHostnameQuery, public BonjourQuery { + public: + BonjourResolveHostnameQuery(const String& hostname, int interfaceIndex, boost::shared_ptr 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()), 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(context)->handleHostnameResolved(errorCode, address); + } + + void handleHostnameResolved(DNSServiceErrorType errorCode, const struct sockaddr *rawAddress) { + if (errorCode) { + MainEventLoop::postEvent( + boost::bind(boost::ref(onHostnameResolved), + boost::optional()), + shared_from_this()); + } + else { + assert(rawAddress->sa_family == AF_INET); + const sockaddr_in* sa = reinterpret_cast(rawAddress); + uint32_t address = ntohl(sa->sin_addr.s_addr); + MainEventLoop::postEvent(boost::bind( + boost::ref(onHostnameResolved), + HostAddress(reinterpret_cast(&address), 4)), + shared_from_this()); + } + } + }; +} diff --git a/Swiften/LinkLocal/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/BonjourResolveServiceQuery.h new file mode 100644 index 0000000..e4f02ee --- /dev/null +++ b/Swiften/LinkLocal/BonjourResolveServiceQuery.h @@ -0,0 +1,53 @@ +#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 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()), 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(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()), shared_from_this()); + } + else { + MainEventLoop::postEvent( + boost::bind( + boost::ref(onServiceResolved), + Result(String(fullName), String(host), port, + LinkLocalServiceInfo::createFromTXTRecord( + ByteArray(reinterpret_cast(txtRecord), txtLen)))), + shared_from_this()); + } + } + }; +} diff --git a/Swiften/LinkLocal/DNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSDQuerier.cpp new file mode 100644 index 0000000..be87a3c --- /dev/null +++ b/Swiften/LinkLocal/DNSSDQuerier.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSDQuerier.h" + +namespace Swift { + +DNSSDQuerier::~DNSSDQuerier() { +} + +} diff --git a/Swiften/LinkLocal/DNSSDQuerier.h b/Swiften/LinkLocal/DNSSDQuerier.h new file mode 100644 index 0000000..528a6ea --- /dev/null +++ b/Swiften/LinkLocal/DNSSDQuerier.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +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 createBrowseQuery() = 0; + virtual boost::shared_ptr createRegisterQuery( + const String& name, int port, const LinkLocalServiceInfo& info) = 0; + virtual boost::shared_ptr createResolveServiceQuery( + const LinkLocalServiceID&) = 0; + virtual boost::shared_ptr createResolveHostnameQuery( + const String& hostname, int interfaceIndex) = 0; + }; +} diff --git a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp new file mode 100644 index 0000000..f7c88bd --- /dev/null +++ b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSDResolveHostnameQuery.h" + +namespace Swift { + +DNSSDResolveHostnameQuery::~DNSSDResolveHostnameQuery() { +} + +} diff --git a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h new file mode 100644 index 0000000..a2e218c --- /dev/null +++ b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +#include "Swiften/Network/HostAddress.h" + +namespace Swift { + class DNSSDResolveHostnameQuery { + public: + virtual ~DNSSDResolveHostnameQuery(); + + virtual void run() = 0; + + boost::signal&)> onHostnameResolved; + }; +} diff --git a/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp b/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp new file mode 100644 index 0000000..83a9ccd --- /dev/null +++ b/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSDResolveServiceQuery.h" + +namespace Swift { + +DNSSDResolveServiceQuery::~DNSSDResolveServiceQuery() { +} + +} diff --git a/Swiften/LinkLocal/DNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSDResolveServiceQuery.h new file mode 100644 index 0000000..d8b5cf1 --- /dev/null +++ b/Swiften/LinkLocal/DNSSDResolveServiceQuery.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +#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&)> onServiceResolved; + }; +} diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index a3144ac..9522cbb 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,6 +1,9 @@ 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 \ -- cgit v0.10.2-6-g49f6