diff options
author | Edwin Mons <edwin.mons@isode.com> | 2018-11-13 10:54:58 (GMT) |
---|---|---|
committer | Edwin Mons <edwin.mons@isode.com> | 2018-11-14 13:40:05 (GMT) |
commit | 5d7fc97148125584a44a39a4beee1e71d9518385 (patch) | |
tree | 9f630e8a9f69bdbd701c1b3c082bacf2b769938d | |
parent | c0615a472f8d23ce449fd59bbb1cdf7071082a43 (diff) | |
download | swift-5d7fc97148125584a44a39a4beee1e71d9518385.zip swift-5d7fc97148125584a44a39a4beee1e71d9518385.tar.bz2 |
Address LinkLocal issues
Generation of TXT records might fail if any of the fields is too long,
so the result is now an optional (pending Expected). Callsites have been
updated to deal with this.
Three potentially uncaught exceptions in the Bonjour implementation have
been addressed.
Test-Information:
Unit tests pass on macOS 10.14 and Debian 9
Change-Id: Iec02c4606a18eee855362fd3c3d15614a9e72547
-rw-r--r-- | Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp | 10 | ||||
-rw-r--r-- | Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h | 17 | ||||
-rw-r--r-- | Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h | 17 | ||||
-rw-r--r-- | Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h | 19 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalServiceBrowser.cpp | 22 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalServiceInfo.cpp | 65 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalServiceInfo.h | 2 | ||||
-rw-r--r-- | Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp | 4 | ||||
-rw-r--r-- | Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp | 26 | ||||
-rw-r--r-- | Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp | 17 | ||||
-rw-r--r-- | Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp | 6 | ||||
-rw-r--r-- | Swiften/QA/DNSSDTest/DNSSDTest.cpp | 8 | ||||
-rw-r--r-- | Swiften/QA/DNSSDTest/SConscript | 2 |
13 files changed, 140 insertions, 75 deletions
diff --git a/Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp b/Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp index c8e7700..b1a51c9 100644 --- a/Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp +++ b/Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp @@ -1,3 +1,3 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. @@ -227,3 +227,5 @@ class LinkLocalPresenceManagerTest : public CppUnit::TestFixture { info.setNick(nickName); - querier->setServiceInfo(service, DNSSDResolveServiceQuery::Result(name + "._presence._tcp.local", "rabbithole.local", 1234, info.toTXTRecord())); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); + querier->setServiceInfo(service, DNSSDResolveServiceQuery::Result(name + "._presence._tcp.local", "rabbithole.local", 1234, *txtRecord)); querier->addService(service); @@ -243,3 +245,5 @@ class LinkLocalPresenceManagerTest : public CppUnit::TestFixture { info.setMessage(message); - querier->setServiceInfo(service, DNSSDResolveServiceQuery::Result(name + "._presence._tcp.local", "rabbithole.local", 1234, info.toTXTRecord())); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); + querier->setServiceInfo(service, DNSSDResolveServiceQuery::Result(name + "._presence._tcp.local", "rabbithole.local", 1234, *txtRecord)); eventLoop->processEvents(); 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,3 +1,3 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. @@ -52,8 +52,13 @@ namespace Swift { //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,3 +1,3 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. @@ -25,7 +25,12 @@ namespace Swift { 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,3 +1,3 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. @@ -22,8 +22,13 @@ namespace Swift { 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 @@ -69,6 +69,12 @@ void LinkLocalServiceBrowser::registerService(const std::string& name, unsigned 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(); + } } @@ -77,3 +83,9 @@ void LinkLocalServiceBrowser::updateService(const LinkLocalServiceInfo& info) { assert(registerQuery); - registerQuery->updateServiceInfo(info.toTXTRecord()); + if (auto txtRecord = info.toTXTRecord()) { + registerQuery->updateServiceInfo(*txtRecord); + } + else { + haveError = true; + stop(); + } } 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 @@ -13,2 +13,3 @@ #include <Swiften/Base/Concat.h> +#include <Swiften/Base/Log.h> @@ -16,33 +17,39 @@ 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; + } } 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 @@ -48,3 +48,3 @@ namespace Swift { - ByteArray toTXTRecord() const; + boost::optional<ByteArray> toTXTRecord() const; 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 @@ -117,2 +117,4 @@ class LinkLocalConnectorTest : public CppUnit::TestFixture { std::shared_ptr<LinkLocalConnector> createConnector(const std::string& hostname, unsigned short port) { + auto txtRecord = LinkLocalServiceInfo().toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); LinkLocalService service( @@ -121,3 +123,3 @@ class LinkLocalConnectorTest : public CppUnit::TestFixture { "myname._presence._tcp.local", hostname, port, - LinkLocalServiceInfo().toTXTRecord())); + *txtRecord)); std::shared_ptr<LinkLocalConnector> result( 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,3 +1,3 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. @@ -49,6 +49,8 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { 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; @@ -294,3 +296,5 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { - 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())); @@ -313,3 +317,5 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { 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)); } @@ -331,3 +337,5 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { - CPPUNIT_ASSERT(querier->isServiceRegistered("bar@baz", 3456, info.toTXTRecord())); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); + CPPUNIT_ASSERT(querier->isServiceRegistered("bar@baz", 3456, *txtRecord)); @@ -348,3 +356,5 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { - CPPUNIT_ASSERT(querier->isServiceRegistered("foo@bar", 1234, info.toTXTRecord())); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); + CPPUNIT_ASSERT(querier->isServiceRegistered("foo@bar", 1234, *txtRecord)); 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,3 +1,3 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. @@ -31,3 +31,5 @@ class LinkLocalServiceInfoTest : public CppUnit::TestFixture { - 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); } @@ -59,3 +61,5 @@ class LinkLocalServiceInfoTest : public CppUnit::TestFixture { - 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()); @@ -69,2 +73,9 @@ class LinkLocalServiceInfoTest : public CppUnit::TestFixture { } + + void testToTXTRecordWithInvalidParameter() { + LinkLocalServiceInfo info; + info.setFirstName(std::string(256, 'x')); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(!txtRecord); + } }; 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,3 +1,3 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. @@ -60,2 +60,4 @@ class LinkLocalServiceTest : public CppUnit::TestFixture { info.setNick(nickName); + auto txtRecord = info.toTXTRecord(); + CPPUNIT_ASSERT(txtRecord); return LinkLocalService(service, @@ -63,3 +65,3 @@ class LinkLocalServiceTest : public CppUnit::TestFixture { name + "._presence._tcp.local", "rabbithole.local", 1234, - info.toTXTRecord())); + *txtRecord)); } diff --git a/Swiften/QA/DNSSDTest/DNSSDTest.cpp b/Swiften/QA/DNSSDTest/DNSSDTest.cpp index ae2fafd..5a78d2f 100644 --- a/Swiften/QA/DNSSDTest/DNSSDTest.cpp +++ b/Swiften/QA/DNSSDTest/DNSSDTest.cpp @@ -1,3 +1,3 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. @@ -37,3 +37,3 @@ class DNSSDTest : public CppUnit::TestFixture { eventLoop = new DummyEventLoop(); - querier = std::make_shared<DNSSDQuerier>(); + querier = std::make_shared<DNSSDQuerierType>(eventLoop); querier->start(); @@ -57,3 +57,3 @@ class DNSSDTest : public CppUnit::TestFixture { LinkLocalServiceInfo info; - std::shared_ptr<DNSSDRegisterQuery> registerQuery = querier->createRegisterQuery("DNSSDTest", 1234, info.toTXTRecord()); + std::shared_ptr<DNSSDRegisterQuery> registerQuery = querier->createRegisterQuery("DNSSDTest", 1234, *info.toTXTRecord()); registerQuery->onRegisterFinished.connect(boost::bind(&DNSSDTest::handleRegisterFinished, this, _1)); @@ -139,3 +139,3 @@ class DNSSDTest : public CppUnit::TestFixture { DummyEventLoop* eventLoop; - std::shared_ptr<DNSSDQuerier> querier; + std::shared_ptr<DNSSDQuerierType> querier; std::vector<DNSSDServiceID> added; diff --git a/Swiften/QA/DNSSDTest/SConscript b/Swiften/QA/DNSSDTest/SConscript index 275a314..d9c9b04 100644 --- a/Swiften/QA/DNSSDTest/SConscript +++ b/Swiften/QA/DNSSDTest/SConscript @@ -9,2 +9,3 @@ if env["TEST"] : myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) + myenv.MergeFlags(myenv["GOOGLETEST_FLAGS"]) myenv.MergeFlags(myenv["BOOST_FLAGS"]) @@ -16,2 +17,3 @@ if env["TEST"] : myenv.MergeFlags(myenv["AVAHI_FLAGS"]) + myenv.MergeFlags(myenv["PLATFORM_FLAGS"]) |