diff options
author | Tobias Markmann <tm@ayena.de> | 2016-02-11 14:50:37 (GMT) |
---|---|---|
committer | Kevin Smith <kevin.smith@isode.com> | 2016-02-15 13:05:18 (GMT) |
commit | 75703db2de5bbfb6622286600362016edb42dfb0 (patch) | |
tree | 2520ed777286c6b732e756387ca88d49b9c1814e /Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp | |
parent | ca226e7bb019308db4bfc818d7e04422d9d28106 (diff) | |
download | swift-75703db2de5bbfb6622286600362016edb42dfb0.zip swift-75703db2de5bbfb6622286600362016edb42dfb0.tar.bz2 |
Support early IBB use in Jingle File Transfer
Previously Jingle File Transfer in Swiften only used IBB
transport as fallback mechanism. With this patch Swiften will
use IBB transport candidates directly in the first
session-initate/session-accept message if the other party
only supports IBB.
Fixed a ASAN reported heap-use-after-free in
SOCKS5BytestreamServerManager.cpp while testing.
Test-Information:
./scons test=system passed without error.
Testing all sender/receiver file-transfer option configurations
with FileTransferTest resulting in expected behavior.
Successfully transferring a file between two Swift instances.
Change-Id: Ia0ffeaa1fd54fc0da23db75344c9e94f9d03a774
Diffstat (limited to 'Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp')
-rw-r--r-- | Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp index f3fe42e..fee26d5 100644 --- a/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp +++ b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp @@ -1,38 +1,38 @@ /* * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2013-2015 Isode Limited. + * Copyright (c) 2013-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <iostream> #include <boost/bind.hpp> #include <boost/optional.hpp> #include <boost/smart_ptr/make_shared.hpp> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <Swiften/Base/ByteArray.h> #include <Swiften/Base/IDGenerator.h> #include <Swiften/Base/Override.h> #include <Swiften/Client/DummyStanzaChannel.h> #include <Swiften/Crypto/CryptoProvider.h> #include <Swiften/Crypto/PlatformCryptoProvider.h> #include <Swiften/Elements/IBB.h> #include <Swiften/Elements/JingleFileTransferDescription.h> #include <Swiften/Elements/JingleIBBTransportPayload.h> #include <Swiften/Elements/JingleS5BTransportPayload.h> #include <Swiften/EventLoop/DummyEventLoop.h> #include <Swiften/FileTransfer/ByteArrayReadBytestream.h> #include <Swiften/FileTransfer/DefaultFileTransferTransporterFactory.h> #include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h> #include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h> #include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h> #include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> @@ -54,76 +54,76 @@ using namespace Swift; class OutgoingJingleFileTransferTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(OutgoingJingleFileTransferTest); CPPUNIT_TEST(test_SendSessionInitiateOnStart); CPPUNIT_TEST(test_FallbackToIBBAfterFailingS5B); CPPUNIT_TEST(test_ReceiveSessionTerminateAfterSessionInitiate); CPPUNIT_TEST(test_DeclineEmitsFinishedStateCanceled); CPPUNIT_TEST_SUITE_END(); class FTStatusHelper { public: FTStatusHelper() : finishedCalled(false), error(FileTransferError::UnknownError) { } void handleFileTransferFinished(boost::optional<FileTransferError> error) { finishedCalled = true; if (error.is_initialized()) this->error = error.get().getType(); } void handleFileTransferStatusChanged(FileTransfer::State fileTransferSTate) { state = fileTransferSTate; } public: bool finishedCalled; FileTransferError::Type error; boost::optional<FileTransfer::State> state; }; public: - boost::shared_ptr<OutgoingJingleFileTransfer> createTestling() { + boost::shared_ptr<OutgoingJingleFileTransfer> createTestling(const FileTransferOptions& options = FileTransferOptions().withAssistedAllowed(false).withDirectAllowed(false).withProxiedAllowed(false)) { JID to("test@foo.com/bla"); JingleFileTransferFileInfo fileInfo; fileInfo.setDescription("some file"); fileInfo.setName("test.bin"); fileInfo.addHash(HashElement("sha-1", ByteArray())); fileInfo.setSize(1024 * 1024); return boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer( to, boost::shared_ptr<JingleSession>(fakeJingleSession), stream, ftTransportFactory, timerFactory, idGen, fileInfo, - FileTransferOptions().withAssistedAllowed(false).withDirectAllowed(false).withProxiedAllowed(false), + options, crypto.get())); } IQ::ref createIBBRequest(IBB::ref ibb, const JID& from, const std::string& id) { IQ::ref request = IQ::createRequest(IQ::Set, JID("foo@bar.com/baz"), id, ibb); request->setFrom(from); return request; } void setUp() { crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); fakeJingleSession = new FakeJingleSession("foo@bar.com/baz", "mysession"); jingleContentPayload = boost::make_shared<JingleContentPayload>(); stanzaChannel = new DummyStanzaChannel(); iqRouter = new IQRouter(stanzaChannel); eventLoop = new DummyEventLoop(); timerFactory = new DummyTimerFactory(); connectionFactory = new DummyConnectionFactory(eventLoop); serverConnectionFactory = new DummyConnectionServerFactory(eventLoop); s5bRegistry = new SOCKS5BytestreamRegistry(); networkEnvironment = new PlatformNetworkEnvironment(); natTraverser = new PlatformNATTraversalWorker(eventLoop); bytestreamServerManager = new SOCKS5BytestreamServerManager(s5bRegistry, serverConnectionFactory, networkEnvironment, natTraverser); data.clear(); for (int n=0; n < 1024 * 1024; ++n) { data.push_back(34); } stream = boost::make_shared<ByteArrayReadBytestream>(data); @@ -132,70 +132,71 @@ public: s5bProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory, resolver, iqRouter, "bar.com"); ftTransportFactory = new DummyFileTransferTransporterFactory(s5bRegistry, bytestreamServerManager, s5bProxy, idGen, connectionFactory, timerFactory, crypto.get(), iqRouter); } void tearDown() { delete ftTransportFactory; delete s5bProxy; delete idGen; delete bytestreamServerManager; delete natTraverser; delete networkEnvironment; delete s5bRegistry; delete serverConnectionFactory; delete connectionFactory; delete timerFactory; delete eventLoop; delete iqRouter; delete stanzaChannel; } void test_SendSessionInitiateOnStart() { boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(); transfer->start(); FakeJingleSession::InitiateCall call = getCall<FakeJingleSession::InitiateCall>(0); JingleFileTransferDescription::ref description = boost::dynamic_pointer_cast<JingleFileTransferDescription>(call.description); CPPUNIT_ASSERT(description); CPPUNIT_ASSERT(static_cast<size_t>(1048576) == description->getFileInfo().getSize()); - JingleS5BTransportPayload::ref transport = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(call.payload); + JingleIBBTransportPayload::ref transport = boost::dynamic_pointer_cast<JingleIBBTransportPayload>(call.payload); CPPUNIT_ASSERT(transport); } void test_FallbackToIBBAfterFailingS5B() { - boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(); + boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(FileTransferOptions().withAssistedAllowed(true).withDirectAllowed(true).withProxiedAllowed(true)); transfer->start(); FakeJingleSession::InitiateCall call = getCall<FakeJingleSession::InitiateCall>(0); + CPPUNIT_ASSERT(boost::dynamic_pointer_cast<JingleS5BTransportPayload>(call.payload)); fakeJingleSession->handleSessionAcceptReceived(call.id, call.description, call.payload); // send candidate failure JingleS5BTransportPayload::ref candidateFailurePayload = boost::make_shared<JingleS5BTransportPayload>(); candidateFailurePayload->setCandidateError(true); candidateFailurePayload->setSessionID(call.payload->getSessionID()); fakeJingleSession->handleTransportInfoReceived(call.id, candidateFailurePayload); // no S5B candidates -> fallback to IBB // call at position 1 is the candidate our candidate error FakeJingleSession::ReplaceTransportCall replaceCall = getCall<FakeJingleSession::ReplaceTransportCall>(2); // accept transport replace fakeJingleSession->handleTransportAcceptReceived(replaceCall.id, replaceCall.payload); IQ::ref iqOpenStanza = stanzaChannel->getStanzaAtIndex<IQ>(0); CPPUNIT_ASSERT(iqOpenStanza); IBB::ref ibbOpen = iqOpenStanza->getPayload<IBB>(); CPPUNIT_ASSERT(ibbOpen); CPPUNIT_ASSERT_EQUAL(IBB::Open, ibbOpen->getAction()); } void test_ReceiveSessionTerminateAfterSessionInitiate() { boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(); transfer->start(); getCall<FakeJingleSession::InitiateCall>(0); FTStatusHelper helper; helper.finishedCalled = false; |