diff options
Diffstat (limited to 'Swiften/LinkLocal')
10 files changed, 127 insertions, 68 deletions
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h index c049ed2..63f34db 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -50,12 +50,17 @@ namespace Swift { } else { //std::cout << "Discovered service: name:" << name << " domain:" << domain << " type: " << type << std::endl; - DNSSDServiceID service(name, domain, type, boost::numeric_cast<int>(interfaceIndex)); - if (flags & kDNSServiceFlagsAdd) { - eventLoop->postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); + try { + DNSSDServiceID service(name, domain, type, boost::numeric_cast<int>(interfaceIndex)); + if (flags & kDNSServiceFlagsAdd) { + eventLoop->postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); + } + else { + eventLoop->postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this()); + } } - else { - eventLoop->postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this()); + catch (...) { + eventLoop->postEvent(boost::bind(boost::ref(onError)), shared_from_this()); } } } diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h index dbf3f0e..61f000e 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -23,11 +23,16 @@ namespace Swift { class BonjourResolveHostnameQuery : public DNSSDResolveHostnameQuery, public BonjourQuery { public: BonjourResolveHostnameQuery(const std::string& hostname, int interfaceIndex, std::shared_ptr<BonjourQuerier> querier, EventLoop* eventLoop) : BonjourQuery(querier, eventLoop) { - DNSServiceErrorType result = DNSServiceGetAddrInfo( - &sdRef, 0, boost::numeric_cast<unsigned int>(interfaceIndex), kDNSServiceProtocol_IPv4, - hostname.c_str(), - &BonjourResolveHostnameQuery::handleHostnameResolvedStatic, this); - if (result != kDNSServiceErr_NoError) { + try { + DNSServiceErrorType result = DNSServiceGetAddrInfo( + &sdRef, 0, boost::numeric_cast<unsigned int>(interfaceIndex), kDNSServiceProtocol_IPv4, + hostname.c_str(), + &BonjourResolveHostnameQuery::handleHostnameResolvedStatic, this); + if (result != kDNSServiceErr_NoError) { + sdRef = nullptr; + } + } + catch (...) { sdRef = nullptr; } } diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h index 7a5555e..4baf87b 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -20,12 +20,17 @@ namespace Swift { class BonjourResolveServiceQuery : public DNSSDResolveServiceQuery, public BonjourQuery { public: BonjourResolveServiceQuery(const DNSSDServiceID& service, std::shared_ptr<BonjourQuerier> querier, EventLoop* eventLoop) : BonjourQuery(querier, eventLoop) { - DNSServiceErrorType result = DNSServiceResolve( - &sdRef, 0, boost::numeric_cast<unsigned int>(service.getNetworkInterfaceID()), - service.getName().c_str(), service.getType().c_str(), - service.getDomain().c_str(), - &BonjourResolveServiceQuery::handleServiceResolvedStatic, this); - if (result != kDNSServiceErr_NoError) { + try { + DNSServiceErrorType result = DNSServiceResolve( + &sdRef, 0, boost::numeric_cast<unsigned int>(service.getNetworkInterfaceID()), + service.getName().c_str(), service.getType().c_str(), + service.getDomain().c_str(), + &BonjourResolveServiceQuery::handleServiceResolvedStatic, this); + if (result != kDNSServiceErr_NoError) { + sdRef = nullptr; + } + } + catch (...) { sdRef = nullptr; } } diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index b3328cd..0498384 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -67,15 +67,27 @@ bool LinkLocalServiceBrowser::isRegistered() const { void LinkLocalServiceBrowser::registerService(const std::string& name, unsigned short port, const LinkLocalServiceInfo& info) { assert(!registerQuery); - registerQuery = querier->createRegisterQuery(name, port, info.toTXTRecord()); - registerQuery->onRegisterFinished.connect( - boost::bind(&LinkLocalServiceBrowser::handleRegisterFinished, this, _1)); - registerQuery->registerService(); + if (auto txtRecord = info.toTXTRecord()) { + registerQuery = querier->createRegisterQuery(name, port, *txtRecord); + registerQuery->onRegisterFinished.connect( + boost::bind(&LinkLocalServiceBrowser::handleRegisterFinished, this, _1)); + registerQuery->registerService(); + } + else { + haveError = true; + stop(); + } } void LinkLocalServiceBrowser::updateService(const LinkLocalServiceInfo& info) { assert(registerQuery); - registerQuery->updateServiceInfo(info.toTXTRecord()); + if (auto txtRecord = info.toTXTRecord()) { + registerQuery->updateServiceInfo(*txtRecord); + } + else { + haveError = true; + stop(); + } } void LinkLocalServiceBrowser::unregisterService() { diff --git a/Swiften/LinkLocal/LinkLocalServiceInfo.cpp b/Swiften/LinkLocal/LinkLocalServiceInfo.cpp index 102b7f3..914fab4 100644 --- a/Swiften/LinkLocal/LinkLocalServiceInfo.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceInfo.cpp @@ -11,40 +11,47 @@ #include <Swiften/Base/Algorithm.h> #include <Swiften/Base/Concat.h> +#include <Swiften/Base/Log.h> namespace Swift { -ByteArray LinkLocalServiceInfo::toTXTRecord() const { - ByteArray result(getEncoded("txtvers=1")); - if (!firstName.empty()) { - append(result, getEncoded("1st=" + firstName)); - } - if (!lastName.empty()) { - append(result, getEncoded("last=" + lastName)); - } - if (!email.empty()) { - append(result, getEncoded("email=" + email)); - } - if (jid.isValid()) { - append(result, getEncoded("jid=" + jid.toString())); - } - if (!message.empty()) { - append(result, getEncoded("msg=" + message)); - } - if (!nick.empty()) { - append(result, getEncoded("nick=" + nick)); - } - if (port) { - append(result, getEncoded("port.p2pj=" + std::string(std::to_string(*port)))); - } +boost::optional<ByteArray> LinkLocalServiceInfo::toTXTRecord() const { + try { + ByteArray result(getEncoded("txtvers=1")); + if (!firstName.empty()) { + append(result, getEncoded("1st=" + firstName)); + } + if (!lastName.empty()) { + append(result, getEncoded("last=" + lastName)); + } + if (!email.empty()) { + append(result, getEncoded("email=" + email)); + } + if (jid.isValid()) { + append(result, getEncoded("jid=" + jid.toString())); + } + if (!message.empty()) { + append(result, getEncoded("msg=" + message)); + } + if (!nick.empty()) { + append(result, getEncoded("nick=" + nick)); + } + if (port) { + append(result, getEncoded("port.p2pj=" + std::string(std::to_string(*port)))); + } - switch (status) { - case Available: append(result, getEncoded("status=avail")); break; - case Away: append(result, getEncoded("status=away")); break; - case DND: append(result, getEncoded("status=dnd")); break; - } + switch (status) { + case Available: append(result, getEncoded("status=avail")); break; + case Away: append(result, getEncoded("status=away")); break; + case DND: append(result, getEncoded("status=dnd")); break; + } - return result; + return result; + } + catch (const std::exception& e) { + SWIFT_LOG(warning) << "Failed to create TXT record for link local service info: " << e.what() << std::endl; + return boost::none; + } } ByteArray LinkLocalServiceInfo::getEncoded(const std::string& s) { diff --git a/Swiften/LinkLocal/LinkLocalServiceInfo.h b/Swiften/LinkLocal/LinkLocalServiceInfo.h index eb65706..adfd062 100644 --- a/Swiften/LinkLocal/LinkLocalServiceInfo.h +++ b/Swiften/LinkLocal/LinkLocalServiceInfo.h @@ -46,7 +46,7 @@ namespace Swift { boost::optional<unsigned short> getPort() const { return port; } void setPort(unsigned short p) { port = p; } - ByteArray toTXTRecord() const; + boost::optional<ByteArray> toTXTRecord() const; static LinkLocalServiceInfo createFromTXTRecord(const ByteArray& record); diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp index ab1ee0c..59cf996 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp @@ -115,11 +115,13 @@ class LinkLocalConnectorTest : public CppUnit::TestFixture { private: std::shared_ptr<LinkLocalConnector> createConnector(const std::string& hostname, unsigned short port) { + auto txtRecord = LinkLocalServiceInfo().toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); LinkLocalService service( DNSSDServiceID("myname", "local."), DNSSDResolveServiceQuery::Result( "myname._presence._tcp.local", hostname, port, - LinkLocalServiceInfo().toTXTRecord())); + *txtRecord)); std::shared_ptr<LinkLocalConnector> result( new LinkLocalConnector(service, querier, connection)); result->onConnectFinished.connect( diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index a80d748..3491634 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -47,10 +47,12 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { eventLoop = new DummyEventLoop(); querier = std::make_shared<FakeDNSSDQuerier>("wonderland.lit", eventLoop); aliceServiceID = new DNSSDServiceID("alice", "wonderland.lit"); - aliceServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.wonderland.lit", "xmpp.wonderland.lit", 1234, LinkLocalServiceInfo().toTXTRecord()); + auto txtRecord = LinkLocalServiceInfo().toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); + aliceServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.wonderland.lit", "xmpp.wonderland.lit", 1234, *txtRecord); testServiceID = new DNSSDServiceID("foo", "bar.local"); - testServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.bar.local", "xmpp.bar.local", 1234, LinkLocalServiceInfo().toTXTRecord()); - testServiceInfo2 = new DNSSDResolveServiceQuery::Result("_presence.tcp.bar.local", "xmpp.foo.local", 2345, LinkLocalServiceInfo().toTXTRecord()); + testServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.bar.local", "xmpp.bar.local", 1234, *txtRecord); + testServiceInfo2 = new DNSSDResolveServiceQuery::Result("_presence.tcp.bar.local", "xmpp.foo.local", 2345, *txtRecord); errorStopReceived = false; normalStopReceived = false; } @@ -292,7 +294,9 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { testling->registerService("foo@bar", 1234, info); eventLoop->processEvents(); - CPPUNIT_ASSERT(querier->isServiceRegistered("foo@bar", 1234, info.toTXTRecord())); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); + CPPUNIT_ASSERT(querier->isServiceRegistered("foo@bar", 1234, *txtRecord)); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(registeredServices.size())); CPPUNIT_ASSERT(registeredServices[0] == DNSSDServiceID("foo@bar", "wonderland.lit")); testling->stop(); @@ -311,7 +315,9 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(!testling->isRunning()); CPPUNIT_ASSERT(testling->hasError()); CPPUNIT_ASSERT(errorStopReceived); - CPPUNIT_ASSERT(!querier->isServiceRegistered("foo@bar", 1234, info.toTXTRecord())); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); + CPPUNIT_ASSERT(!querier->isServiceRegistered("foo@bar", 1234, *txtRecord)); } void testRegisterService_Reregister() { @@ -329,7 +335,9 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { testling->registerService("bar@baz", 3456, info); eventLoop->processEvents(); - CPPUNIT_ASSERT(querier->isServiceRegistered("bar@baz", 3456, info.toTXTRecord())); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); + CPPUNIT_ASSERT(querier->isServiceRegistered("bar@baz", 3456, *txtRecord)); testling->stop(); } @@ -346,7 +354,9 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { info.setFirstName("Bar"); testling->updateService(info); - CPPUNIT_ASSERT(querier->isServiceRegistered("foo@bar", 1234, info.toTXTRecord())); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); + CPPUNIT_ASSERT(querier->isServiceRegistered("foo@bar", 1234, *txtRecord)); testling->stop(); } diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp index 0a94a98..35cb1b4 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -29,7 +29,9 @@ class LinkLocalServiceInfoTest : public CppUnit::TestFixture { info.setLastName("Tron\xc3\xe7on"); info.setStatus(LinkLocalServiceInfo::Away); - CPPUNIT_ASSERT_EQUAL(createByteArray("\x09txtvers=1\x09" + std::string("1st=Remko\x0dlast=Tron\xc3\xe7on\x0bstatus=away")), info.toTXTRecord()); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x09txtvers=1\x09" + std::string("1st=Remko\x0dlast=Tron\xc3\xe7on\x0bstatus=away")), *txtRecord); } void testCreateFromTXTRecord() { @@ -57,7 +59,9 @@ class LinkLocalServiceInfoTest : public CppUnit::TestFixture { info.setStatus(LinkLocalServiceInfo::DND); info.setPort(1234); - LinkLocalServiceInfo info2 = LinkLocalServiceInfo::createFromTXTRecord(info.toTXTRecord()); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); + LinkLocalServiceInfo info2 = LinkLocalServiceInfo::createFromTXTRecord(*txtRecord); CPPUNIT_ASSERT_EQUAL(info.getFirstName(), info2.getFirstName()); CPPUNIT_ASSERT_EQUAL(info.getLastName(), info2.getLastName()); CPPUNIT_ASSERT_EQUAL(info.getEMail(), info2.getEMail()); @@ -67,6 +71,13 @@ class LinkLocalServiceInfoTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(info.getStatus() == info2.getStatus()); CPPUNIT_ASSERT(info.getPort() == info2.getPort()); } + + void testToTXTRecordWithInvalidParameter() { + LinkLocalServiceInfo info; + info.setFirstName(std::string(256, 'x')); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(!txtRecord); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(LinkLocalServiceInfoTest); diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp index 206d824..cb5f40a 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -58,10 +58,12 @@ class LinkLocalServiceTest : public CppUnit::TestFixture { info.setFirstName(firstName); info.setLastName(lastName); info.setNick(nickName); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); return LinkLocalService(service, DNSSDResolveServiceQuery::Result( name + "._presence._tcp.local", "rabbithole.local", 1234, - info.toTXTRecord())); + *txtRecord)); } }; |