summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h')
-rw-r--r--Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h121
1 files changed, 69 insertions, 52 deletions
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h
index 1bec5f7..cc95d64 100644
--- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h
@@ -1,62 +1,79 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2019 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h>
-#include <Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h>
+#include <mutex>
+
+#include <boost/numeric/conversion/cast.hpp>
+
#include <Swiften/Base/ByteArray.h>
#include <Swiften/EventLoop/EventLoop.h>
-#include <boost/numeric/conversion/cast.hpp>
+#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h>
+#include <Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h>
namespace Swift {
- class BonjourQuerier;
-
- class BonjourRegisterQuery : public DNSSDRegisterQuery, public BonjourQuery {
- public:
- BonjourRegisterQuery(const std::string& name, int port, const ByteArray& txtRecord, boost::shared_ptr<BonjourQuerier> querier, EventLoop* eventLoop) : BonjourQuery(querier, eventLoop) {
- DNSServiceErrorType result = DNSServiceRegister(
- &sdRef, 0, 0, name.c_str(), "_presence._tcp", NULL, NULL, boost::numeric_cast<unsigned short>(port),
- boost::numeric_cast<unsigned short>(txtRecord.size()), vecptr(txtRecord),
- &BonjourRegisterQuery::handleServiceRegisteredStatic, this);
- if (result != kDNSServiceErr_NoError) {
- sdRef = NULL;
- }
- }
-
- void registerService() {
- if (sdRef) {
- run();
- }
- else {
- eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this());
- }
- }
-
- void unregisterService() {
- finish();
- }
-
- void updateServiceInfo(const ByteArray& txtRecord) {
- boost::lock_guard<boost::mutex> lock(sdRefMutex);
- DNSServiceUpdateRecord(sdRef, NULL, 0, boost::numeric_cast<unsigned short>(txtRecord.size()), vecptr(txtRecord), 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) {
- eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this());
- }
- else {
- eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>(DNSSDServiceID(name, domain, regtype, 0))), shared_from_this());
- }
- }
- };
+ class BonjourQuerier;
+
+ class BonjourRegisterQuery : public DNSSDRegisterQuery, public BonjourQuery {
+ public:
+ BonjourRegisterQuery(const std::string& name, unsigned short port, const ByteArray& txtRecord, std::shared_ptr<BonjourQuerier> querier, EventLoop* eventLoop) : BonjourQuery(querier, eventLoop) {
+ unsigned short recordSize = 0;
+ try {
+ recordSize = boost::numeric_cast<unsigned short>(txtRecord.size());
+ }
+ catch (const boost::numeric::bad_numeric_cast&) {
+ SWIFT_LOG(warning) << "Bonjour TXT record is too long (" << txtRecord.size() << " bytes), not registring service";
+ return;
+ }
+ DNSServiceErrorType result = DNSServiceRegister(
+ &sdRef, 0, 0, name.c_str(), "_presence._tcp", nullptr, nullptr, port,
+ recordSize, vecptr(txtRecord),
+ &BonjourRegisterQuery::handleServiceRegisteredStatic, this);
+ if (result != kDNSServiceErr_NoError) {
+ SWIFT_LOG(warning) << "Failed to register Bonjour service";
+ sdRef = nullptr;
+ }
+ }
+
+ void registerService() {
+ if (sdRef) {
+ run();
+ }
+ else {
+ eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this());
+ }
+ }
+
+ void unregisterService() {
+ finish();
+ }
+
+ void updateServiceInfo(const ByteArray& txtRecord) {
+ std::lock_guard<std::mutex> lock(sdRefMutex);
+ try {
+ DNSServiceUpdateRecord(sdRef, nullptr, 0, boost::numeric_cast<unsigned short>(txtRecord.size()), vecptr(txtRecord), 0);
+ }
+ catch (const boost::numeric::bad_numeric_cast&) {
+ SWIFT_LOG(warning) << "Bonjour TXT record is too long (" << txtRecord.size() << " bytes), not updating service record";
+ }
+ }
+
+ 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) {
+ eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this());
+ }
+ else {
+ eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>(DNSSDServiceID(name, domain, regtype, 0))), shared_from_this());
+ }
+ }
+ };
}