diff options
author | Tobias Markmann <tm@ayena.de> | 2014-12-17 15:21:30 (GMT) |
---|---|---|
committer | Swift Review <review@swift.im> | 2015-02-03 10:03:17 (GMT) |
commit | b5fc240f1cf4e340e04177a23cb8cf827b9ca16b (patch) | |
tree | 13d701e160af328553551974e55fea876d21eed8 /Swiften/FileTransfer | |
parent | d860805af76ec85e003bf3019407bbb7acd218c9 (diff) | |
download | swift-b5fc240f1cf4e340e04177a23cb8cf827b9ca16b.zip swift-b5fc240f1cf4e340e04177a23cb8cf827b9ca16b.tar.bz2 |
Update Jingle FT protocol to namespace verison urn:xmpp:jingle:apps:file-transfer:4.
Test-Information:
Adjusted unit tests and successfully build/run them on OS X 10.9.5.
Change-Id: I63789e3fb351999f719157b54fa9fcf95f40fb07
Diffstat (limited to 'Swiften/FileTransfer')
15 files changed, 167 insertions, 97 deletions
diff --git a/Swiften/FileTransfer/DefaultFileTransferTransporter.cpp b/Swiften/FileTransfer/DefaultFileTransferTransporter.cpp index 74492b1..1a77685 100644 --- a/Swiften/FileTransfer/DefaultFileTransferTransporter.cpp +++ b/Swiften/FileTransfer/DefaultFileTransferTransporter.cpp @@ -1,8 +1,8 @@ /* - * Copyright (c) 2013 Isode Limited. + * Copyright (c) 2013-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/FileTransfer/DefaultFileTransferTransporter.h> @@ -239,14 +239,16 @@ boost::shared_ptr<TransportSession> DefaultFileTransferTransporter::createIBBSen ibbSession->setBlockSize(blockSize); return boost::make_shared<IBBSendTransportSession>(ibbSession); } boost::shared_ptr<TransportSession> DefaultFileTransferTransporter::createIBBReceiveSession( const std::string& sessionID, unsigned long long size, boost::shared_ptr<WriteBytestream> stream) { - closeLocalSession(); - closeRemoteSession(); + if (s5bServerManager->getServer()) { + closeLocalSession(); + closeRemoteSession(); + } boost::shared_ptr<IBBReceiveSession> ibbSession = boost::make_shared<IBBReceiveSession>( sessionID, initiator, responder, size, stream, router); return boost::make_shared<IBBReceiveTransportSession>(ibbSession); } boost::shared_ptr<TransportSession> DefaultFileTransferTransporter::createRemoteCandidateSession( diff --git a/Swiften/FileTransfer/FileTransferManagerImpl.cpp b/Swiften/FileTransfer/FileTransferManagerImpl.cpp index f248b8a..fe8bfd6 100644 --- a/Swiften/FileTransfer/FileTransferManagerImpl.cpp +++ b/Swiften/FileTransfer/FileTransferManagerImpl.cpp @@ -2,13 +2,13 @@ * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2013 Isode Limited. + * Copyright (c) 2013-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/FileTransfer/FileTransferManagerImpl.h> @@ -18,13 +18,13 @@ #include <Swiften/Base/foreach.h> #include <Swiften/Base/Log.h> #include <Swiften/Base/Path.h> #include "Swiften/Disco/EntityCapsProvider.h" #include <Swiften/JID/JID.h> -#include <Swiften/Elements/StreamInitiationFileInfo.h> +#include <Swiften/Elements/JingleFileTransferFileInfo.h> #include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h> #include <Swiften/FileTransfer/OutgoingFileTransferManager.h> #include <Swiften/FileTransfer/IncomingFileTransferManager.h> #include <Swiften/FileTransfer/DefaultFileTransferTransporterFactory.h> #include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> #include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h> @@ -143,13 +143,13 @@ OutgoingFileTransfer::ref FileTransferManagerImpl::createOutgoingFileTransfer( const std::string& filename, const std::string& description, const boost::uintmax_t sizeInBytes, const boost::posix_time::ptime& lastModified, boost::shared_ptr<ReadBytestream> bytestream, const FileTransferOptions& config) { - StreamInitiationFileInfo fileInfo; + JingleFileTransferFileInfo fileInfo; fileInfo.setDate(lastModified); fileInfo.setSize(sizeInBytes); fileInfo.setName(filename); fileInfo.setDescription(description); JID receipient = to; diff --git a/Swiften/FileTransfer/FileTransferOptions.h b/Swiften/FileTransfer/FileTransferOptions.h index 3a0abcb..3d00d2b 100644 --- a/Swiften/FileTransfer/FileTransferOptions.h +++ b/Swiften/FileTransfer/FileTransferOptions.h @@ -1,21 +1,21 @@ /* - * Copyright (c) 2013 Isode Limited. + * Copyright (c) 2013-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <Swiften/Base/Override.h> #include <Swiften/Base/API.h> namespace Swift { class SWIFTEN_API FileTransferOptions { public: - FileTransferOptions() : allowInBand(false) { + FileTransferOptions() : allowInBand(true) { } SWIFTEN_DEFAULT_COPY_CONSTRUCTOR(FileTransferOptions) ~FileTransferOptions(); FileTransferOptions& withInBandAllowed(bool b) { allowInBand = b; diff --git a/Swiften/FileTransfer/FileTransferTransporter.h b/Swiften/FileTransfer/FileTransferTransporter.h index d149722..2116f0d 100644 --- a/Swiften/FileTransfer/FileTransferTransporter.h +++ b/Swiften/FileTransfer/FileTransferTransporter.h @@ -1,8 +1,8 @@ /* - * Copyright (c) 2013 Isode Limited. + * Copyright (c) 2013-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once @@ -17,12 +17,17 @@ namespace Swift { class TransportSession; class ErrorPayload; class ReadBytestream; class WriteBytestream; + /** + * @brief The FileTransferTransporter class is an abstract factory definition + * to generate SOCKS5 bytestream transports or IBB bytestreams for use in file + * transfers. + */ class SWIFTEN_API FileTransferTransporter { public: virtual ~FileTransferTransporter(); virtual void startGeneratingLocalCandidates() = 0; virtual void stopGeneratingLocalCandidates() = 0; diff --git a/Swiften/FileTransfer/IncomingFileTransfer.h b/Swiften/FileTransfer/IncomingFileTransfer.h index e0cb4ad..93ecf1a 100644 --- a/Swiften/FileTransfer/IncomingFileTransfer.h +++ b/Swiften/FileTransfer/IncomingFileTransfer.h @@ -1,8 +1,8 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once @@ -13,12 +13,16 @@ #include <Swiften/FileTransfer/FileTransferOptions.h> namespace Swift { class WriteBytestream; class JID; + /** + * @brief The IncomingFileTransfer abstract class is the general interface in Swiften + * for incoming file transfers. + */ class IncomingFileTransfer : public FileTransfer { public: typedef boost::shared_ptr<IncomingFileTransfer> ref; virtual ~IncomingFileTransfer(); diff --git a/Swiften/FileTransfer/IncomingFileTransferManager.cpp b/Swiften/FileTransfer/IncomingFileTransferManager.cpp index 05d6259..239c4a8 100644 --- a/Swiften/FileTransfer/IncomingFileTransferManager.cpp +++ b/Swiften/FileTransfer/IncomingFileTransferManager.cpp @@ -41,19 +41,19 @@ bool IncomingFileTransferManager::handleIncomingJingleSession( JingleSession::ref session, const std::vector<JingleContentPayload::ref>& contents, const JID& recipient) { if (JingleContentPayload::ref content = Jingle::getContentWithDescription<JingleFileTransferDescription>(contents)) { if (content->getTransport<JingleS5BTransportPayload>()) { JingleFileTransferDescription::ref description = content->getDescription<JingleFileTransferDescription>(); - if (description && description->getOffers().size() == 1) { + if (description) { IncomingJingleFileTransfer::ref transfer = boost::make_shared<IncomingJingleFileTransfer>( recipient, session, content, transporterFactory, timerFactory, crypto); onIncomingFileTransfer(transfer); } else { - SWIFT_LOG(warning) << "Received a file-transfer request with no description or more than one file."; + SWIFT_LOG(warning) << "Received a file-transfer request with no file description."; session->sendTerminate(JinglePayload::Reason::FailedApplication); } } else { session->sendTerminate(JinglePayload::Reason::UnsupportedTransports); } diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp index 66b2e53..720eefd 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp @@ -1,18 +1,21 @@ /* - * Copyright (c) 2011-2013 Isode Limited. + * Copyright (c) 2011-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/FileTransfer/IncomingJingleFileTransfer.h> +#include <set> + #include <boost/bind.hpp> #include <boost/smart_ptr/make_shared.hpp> #include <Swiften/Base/Log.h> +#include <Swiften/StringCodecs/Base64.h> #include <Swiften/Base/foreach.h> #include <Swiften/Jingle/JingleSession.h> #include <Swiften/Elements/JingleIBBTransportPayload.h> #include <Swiften/Elements/JingleS5BTransportPayload.h> #include <Swiften/Elements/JingleFileTransferHash.h> #include <Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h> @@ -40,17 +43,15 @@ IncomingJingleFileTransfer::IncomingJingleFileTransfer( crypto(crypto), state(Initial), receivedBytes(0), hashCalculator(NULL) { description = initialContent->getDescription<JingleFileTransferDescription>(); assert(description); - assert(description->getOffers().size() == 1); - StreamInitiationFileInfo fileInfo = description->getOffers().front(); + JingleFileTransferFileInfo fileInfo = description->getFileInfo(); setFileInfo(fileInfo.getName(), fileInfo.getSize()); - hash = fileInfo.getHash(); - hashAlgorithm = fileInfo.getAlgo(); + hashes = fileInfo.getHashes(); waitOnHashTimer = timerFactory->createTimer(5000); waitOnHashTimerTickedConnection = waitOnHashTimer->onTick.connect( boost::bind(&IncomingJingleFileTransfer::handleWaitOnHashTimerTicked, this)); } @@ -65,26 +66,39 @@ void IncomingJingleFileTransfer::accept( assert(!this->stream); this->stream = stream; this->options = options; assert(!hashCalculator); + hashCalculator = new IncrementalBytestreamHashCalculator( - hashAlgorithm == "md5" || hash.empty(), hashAlgorithm == "sha-1" || hash.empty(), crypto); + hashes.find("md5") != hashes.end(), hashes.find("sha-1") != hashes.end(), crypto); writeStreamDataReceivedConnection = stream->onWrite.connect( boost::bind(&IncomingJingleFileTransfer::handleWriteStreamDataReceived, this, _1)); if (JingleS5BTransportPayload::ref s5bTransport = initialContent->getTransport<JingleS5BTransportPayload>()) { - SWIFT_LOG(debug) << "Got S5B transport payload!" << std::endl; + SWIFT_LOG(debug) << "Got S5B transport as initial payload." << std::endl; setTransporter(transporterFactory->createResponderTransporter( getInitiator(), getResponder(), s5bTransport->getSessionID())); transporter->addRemoteCandidates(s5bTransport->getCandidates()); setState(GeneratingInitialLocalCandidates); transporter->startGeneratingLocalCandidates(); } + else if (JingleIBBTransportPayload::ref ibbTransport = initialContent->getTransport<JingleIBBTransportPayload>()) { + SWIFT_LOG(debug) << "Got IBB transport as initial payload." << std::endl; + setTransporter(transporterFactory->createResponderTransporter( + getInitiator(), getResponder(), ibbTransport->getSessionID())); + + startTransferring(transporter->createIBBReceiveSession( + ibbTransport->getSessionID(), + description->getFileInfo().getSize(), + stream)); + + session->sendAccept(getContentID(), initialContent->getDescriptions()[0], ibbTransport); + } else { // Can't happen, because the transfer would have been rejected automatically assert(false); } } @@ -118,19 +132,17 @@ void IncomingJingleFileTransfer::handleSessionInfoReceived(JinglePayload::ref ji SWIFT_LOG(debug) << std::endl; JingleFileTransferHash::ref transferHash = jinglePayload->getPayload<JingleFileTransferHash>(); if (transferHash) { SWIFT_LOG(debug) << "Received hash information." << std::endl; waitOnHashTimer->stop(); - if (transferHash->getHashes().find("sha-1") != transferHash->getHashes().end()) { - hashAlgorithm = "sha-1"; - hash = transferHash->getHashes().find("sha-1")->second; + if (transferHash->getFileInfo().getHashes().find("sha-1") != transferHash->getFileInfo().getHashes().end()) { + hashes["sha-1"] = transferHash->getFileInfo().getHash("sha-1").get(); } - else if (transferHash->getHashes().find("md5") != transferHash->getHashes().end()) { - hashAlgorithm = "md5"; - hash = transferHash->getHashes().find("md5")->second; + else if (transferHash->getFileInfo().getHashes().find("md5") != transferHash->getFileInfo().getHashes().end()) { + hashes["md5"] = transferHash->getFileInfo().getHash("md5").get(); } if (state == WaitingForHash) { checkHashAndTerminate(); } } else { @@ -169,13 +181,18 @@ void IncomingJingleFileTransfer::checkHashAndTerminate() { } } void IncomingJingleFileTransfer::checkIfAllDataReceived() { if (receivedBytes == getFileSizeInBytes()) { SWIFT_LOG(debug) << "All data received." << std::endl; - if (hash.empty()) { + bool hashInfoAvailable = true; + foreach(const JingleFileTransferFileInfo::HashElementMap::value_type& hashElement, hashes) { + hashInfoAvailable &= !hashElement.second.empty(); + } + + if (!hashInfoAvailable) { SWIFT_LOG(debug) << "No hash information yet. Waiting a while on hash info." << std::endl; setState(WaitingForHash); waitOnHashTimer->start(); } else { checkHashAndTerminate(); @@ -204,13 +221,13 @@ void IncomingJingleFileTransfer::handleTransportReplaceReceived( if (JingleIBBTransportPayload::ref ibbTransport = boost::dynamic_pointer_cast<JingleIBBTransportPayload>(transport)) { SWIFT_LOG(debug) << "transport replaced with IBB" << std::endl; startTransferring(transporter->createIBBReceiveSession( ibbTransport->getSessionID(), - description->getOffers()[0].getSize(), + description->getFileInfo().getSize(), stream)); session->sendTransportAccept(content, ibbTransport); } else { SWIFT_LOG(debug) << "Unknown replace transport" << std::endl; session->sendTransportReject(content, transport); @@ -219,23 +236,23 @@ void IncomingJingleFileTransfer::handleTransportReplaceReceived( JingleContentID IncomingJingleFileTransfer::getContentID() const { return JingleContentID(initialContent->getName(), initialContent->getCreator()); } bool IncomingJingleFileTransfer::verifyData() { - if (hashAlgorithm.empty() || hash.empty()) { + if (hashes.empty()) { SWIFT_LOG(debug) << "no verification possible, skipping" << std::endl; return true; } - if (hashAlgorithm == "sha-1") { - SWIFT_LOG(debug) << "Verify SHA-1 hash: " << (hash == hashCalculator->getSHA1String()) << std::endl; - return hash == hashCalculator->getSHA1String(); + if (hashes.find("sha-1") != hashes.end()) { + SWIFT_LOG(debug) << "Verify SHA-1 hash: " << (hashes["sha-1"] == hashCalculator->getSHA1Hash()) << std::endl; + return hashes["sha-1"] == hashCalculator->getSHA1Hash(); } - else if (hashAlgorithm == "md5") { - SWIFT_LOG(debug) << "Verify MD5 hash: " << (hash == hashCalculator->getMD5String()) << std::endl; - return hash == hashCalculator->getMD5String(); + else if (hashes.find("md5") != hashes.end()) { + SWIFT_LOG(debug) << "Verify MD5 hash: " << (hashes["md5"] == hashCalculator->getMD5Hash()) << std::endl; + return hashes["md5"] == hashCalculator->getMD5Hash(); } else { SWIFT_LOG(debug) << "Unknown hash, skipping" << std::endl; return true; } } diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.h b/Swiften/FileTransfer/IncomingJingleFileTransfer.h index 727d278..7fc22f4 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.h +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.h @@ -1,8 +1,8 @@ /* - * Copyright (c) 2010-2013 Isode Limited. + * Copyright (c) 2010-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once @@ -14,25 +14,34 @@ #include <Swiften/Base/Override.h> #include <Swiften/Jingle/JingleContentID.h> #include <Swiften/FileTransfer/IncomingFileTransfer.h> #include <Swiften/FileTransfer/JingleFileTransfer.h> #include <Swiften/Elements/JingleS5BTransportPayload.h> #include <Swiften/FileTransfer/FileTransferOptions.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { class JID; class JingleSession; class JingleContentPayload; class FileTransferTransporter; class FileTransferTransporterFactory; class TimerFactory; class Timer; class CryptoProvider; class IncrementalBytestreamHashCalculator; class JingleFileTransferDescription; + class HashElement; + /** + * @brief The IncomingJingleFileTransfer class contains the business logic for managing incoming + * Jingle file transfers. + * + * Calling IncomingJingleFileTransfer::accept will start to negotiate possible transfer + * methods and after a working method has been decided among peers the trasnfer is started. + */ class SWIFTEN_API IncomingJingleFileTransfer : public IncomingFileTransfer, public JingleFileTransfer { public: typedef boost::shared_ptr<IncomingJingleFileTransfer> ref; IncomingJingleFileTransfer( const JID& recipient, @@ -40,13 +49,13 @@ namespace Swift { boost::shared_ptr<JingleContentPayload> content, FileTransferTransporterFactory*, TimerFactory*, CryptoProvider*); ~IncomingJingleFileTransfer(); - virtual void accept(boost::shared_ptr<WriteBytestream>, const FileTransferOptions&) SWIFTEN_OVERRIDE; + virtual void accept(boost::shared_ptr<WriteBytestream>, const FileTransferOptions& = FileTransferOptions()) SWIFTEN_OVERRIDE; virtual void cancel() SWIFTEN_OVERRIDE; private: enum State { Initial, GeneratingInitialLocalCandidates, @@ -105,14 +114,13 @@ namespace Swift { State state; boost::shared_ptr<JingleFileTransferDescription> description; boost::shared_ptr<WriteBytestream> stream; boost::uintmax_t receivedBytes; IncrementalBytestreamHashCalculator* hashCalculator; boost::shared_ptr<Timer> waitOnHashTimer; - std::string hashAlgorithm; - std::string hash; + std::map<std::string, ByteArray> hashes; FileTransferOptions options; boost::bsignals::scoped_connection writeStreamDataReceivedConnection; boost::bsignals::scoped_connection waitOnHashTimerTickedConnection; boost::bsignals::connection transferFinishedConnection; }; diff --git a/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.cpp b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.cpp index e982fd0..7eb9560 100644 --- a/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.cpp +++ b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.cpp @@ -2,13 +2,13 @@ * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2013 Isode Limited. + * Copyright (c) 2013-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h> @@ -43,23 +43,33 @@ void IncrementalBytestreamHashCalculator::feedData(const SafeByteArray& data) { } if (sha1Hasher) { sha1Hasher->update(createByteArray(data.data(), data.size())); } }*/ -std::string IncrementalBytestreamHashCalculator::getSHA1String() { +ByteArray IncrementalBytestreamHashCalculator::getSHA1Hash() { assert(sha1Hasher); if (!sha1Hash) { - sha1Hash = Hexify::hexify(sha1Hasher->getHash()); + sha1Hash = sha1Hasher->getHash(); } return *sha1Hash; } -std::string IncrementalBytestreamHashCalculator::getMD5String() { +ByteArray IncrementalBytestreamHashCalculator::getMD5Hash() { assert(md5Hasher); if (!md5Hash) { - md5Hash = Hexify::hexify(md5Hasher->getHash()); + md5Hash = md5Hasher->getHash(); } return *md5Hash; } +std::string IncrementalBytestreamHashCalculator::getSHA1String() { + assert(sha1Hasher); + return Hexify::hexify(getSHA1Hash());; +} + +std::string IncrementalBytestreamHashCalculator::getMD5String() { + assert(md5Hasher); + return Hexify::hexify(getMD5Hash());; +} + } diff --git a/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h index bb6b441..bc4ebf9 100644 --- a/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h +++ b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h @@ -2,13 +2,13 @@ * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2013 Isode Limited. + * Copyright (c) 2013-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once @@ -27,17 +27,20 @@ namespace Swift { IncrementalBytestreamHashCalculator(bool doMD5, bool doSHA1, CryptoProvider* crypto); ~IncrementalBytestreamHashCalculator(); void feedData(const ByteArray& data); //void feedData(const SafeByteArray& data); + ByteArray getSHA1Hash(); + ByteArray getMD5Hash(); + std::string getSHA1String(); std::string getMD5String(); private: Hash* md5Hasher; Hash* sha1Hasher; - boost::optional<std::string> md5Hash; - boost::optional<std::string> sha1Hash; + boost::optional<ByteArray> md5Hash; + boost::optional<ByteArray> sha1Hash; }; } diff --git a/Swiften/FileTransfer/OutgoingFileTransferManager.cpp b/Swiften/FileTransfer/OutgoingFileTransferManager.cpp index 5ed4656..5d0555f 100644 --- a/Swiften/FileTransfer/OutgoingFileTransferManager.cpp +++ b/Swiften/FileTransfer/OutgoingFileTransferManager.cpp @@ -2,13 +2,13 @@ * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2013 Isode Limited. + * Copyright (c) 2013-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/FileTransfer/OutgoingFileTransferManager.h> @@ -40,13 +40,13 @@ OutgoingFileTransferManager::~OutgoingFileTransferManager() { } boost::shared_ptr<OutgoingFileTransfer> OutgoingFileTransferManager::createOutgoingFileTransfer( const JID& from, const JID& recipient, boost::shared_ptr<ReadBytestream> readBytestream, - const StreamInitiationFileInfo& fileInfo, + const JingleFileTransferFileInfo& fileInfo, const FileTransferOptions& config) { JingleSessionImpl::ref jingleSession = boost::make_shared<JingleSessionImpl>( from, recipient, idGenerator->generateID(), iqRouter); jingleSessionManager->registerOutgoingSession(from, jingleSession); return boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer( recipient, diff --git a/Swiften/FileTransfer/OutgoingFileTransferManager.h b/Swiften/FileTransfer/OutgoingFileTransferManager.h index 8dd4bbc..fd7380b 100644 --- a/Swiften/FileTransfer/OutgoingFileTransferManager.h +++ b/Swiften/FileTransfer/OutgoingFileTransferManager.h @@ -2,13 +2,13 @@ * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2013 Isode Limited. + * Copyright (c) 2013-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once @@ -19,13 +19,13 @@ namespace Swift { class IQRouter; class FileTransferTransporterFactory; class OutgoingFileTransfer; class JID; class IDGenerator; class ReadBytestream; - class StreamInitiationFileInfo; + class JingleFileTransferFileInfo; class CryptoProvider; class FileTransferOptions; class OutgoingFileTransferManager { public: OutgoingFileTransferManager( @@ -36,13 +36,13 @@ namespace Swift { ~OutgoingFileTransferManager(); boost::shared_ptr<OutgoingFileTransfer> createOutgoingFileTransfer( const JID& from, const JID& to, boost::shared_ptr<ReadBytestream>, - const StreamInitiationFileInfo&, + const JingleFileTransferFileInfo&, const FileTransferOptions&); private: JingleSessionManager* jingleSessionManager; IQRouter* iqRouter; FileTransferTransporterFactory* transporterFactory; diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp index 93214eb..369af8f 100644 --- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp @@ -2,13 +2,13 @@ * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (C) 2013 Isode Limited. + * Copyright (C) 2013-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ // TODO: // - We should handle incoming terminates after we have terminated, so the other @@ -46,13 +46,13 @@ static const int DEFAULT_BLOCK_SIZE = 4096; OutgoingJingleFileTransfer::OutgoingJingleFileTransfer( const JID& toJID, JingleSession::ref session, boost::shared_ptr<ReadBytestream> stream, FileTransferTransporterFactory* transporterFactory, IDGenerator* idGenerator, - const StreamInitiationFileInfo& fileInfo, + const JingleFileTransferFileInfo& fileInfo, const FileTransferOptions& options, CryptoProvider* crypto) : JingleFileTransfer(session, toJID, transporterFactory), idGenerator(idGenerator), stream(stream), fileInfo(fileInfo), @@ -146,26 +146,28 @@ void OutgoingJingleFileTransfer::handleTransportAcceptReceived(const JingleConte } void OutgoingJingleFileTransfer::sendSessionInfoHash() { SWIFT_LOG(debug) << std::endl; JingleFileTransferHash::ref hashElement = boost::make_shared<JingleFileTransferHash>(); - hashElement->setHash("sha-1", hashCalculator->getSHA1String()); - hashElement->setHash("md5", hashCalculator->getMD5String()); + hashElement->getFileInfo().addHash(HashElement("sha-1", hashCalculator->getSHA1Hash())); + hashElement->getFileInfo().addHash(HashElement("md5", hashCalculator->getMD5Hash())); session->sendInfo(hashElement); } void OutgoingJingleFileTransfer::handleLocalTransportCandidatesGenerated( const std::string& s5bSessionID, const std::vector<JingleS5BTransportPayload::Candidate>& candidates) { SWIFT_LOG(debug) << std::endl; if (state != GeneratingInitialLocalCandidates) { SWIFT_LOG(warning) << "Incorrect state" << std::endl; return; } fillCandidateMap(localCandidates, candidates); JingleFileTransferDescription::ref description = boost::make_shared<JingleFileTransferDescription>(); - description->addOffer(fileInfo); + fileInfo.addHash(HashElement("sha-1", ByteArray())); + fileInfo.addHash(HashElement("md5", ByteArray())); + description->setFileInfo(fileInfo); JingleS5BTransportPayload::ref transport = boost::make_shared<JingleS5BTransportPayload>(); transport->setSessionID(s5bSessionID); transport->setMode(JingleS5BTransportPayload::TCPMode); foreach(JingleS5BTransportPayload::Candidate candidate, candidates) { transport->addCandidate(candidate); diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.h b/Swiften/FileTransfer/OutgoingJingleFileTransfer.h index c21c50b..f022b9f 100644 --- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.h +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.h @@ -2,26 +2,26 @@ * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2013 Isode Limited. + * Copyright (c) 2013-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <boost/shared_ptr.hpp> #include <boost/optional/optional.hpp> #include <Swiften/Base/API.h> #include <Swiften/Base/Override.h> #include <Swiften/Jingle/JingleContentID.h> -#include <Swiften/Elements/StreamInitiationFileInfo.h> +#include <Swiften/Elements/JingleFileTransferFileInfo.h> #include <Swiften/FileTransfer/OutgoingFileTransfer.h> #include <Swiften/FileTransfer/JingleFileTransfer.h> #include <Swiften/FileTransfer/FileTransferOptions.h> namespace Swift { class ReadBytestream; @@ -37,13 +37,13 @@ namespace Swift { OutgoingJingleFileTransfer( const JID& to, boost::shared_ptr<JingleSession>, boost::shared_ptr<ReadBytestream>, FileTransferTransporterFactory*, IDGenerator*, - const StreamInitiationFileInfo&, + const JingleFileTransferFileInfo&, const FileTransferOptions&, CryptoProvider*); virtual ~OutgoingJingleFileTransfer(); virtual void start() SWIFTEN_OVERRIDE; virtual void cancel() SWIFTEN_OVERRIDE; @@ -96,13 +96,13 @@ namespace Swift { static FileTransfer::State::Type getExternalState(State state); private: IDGenerator* idGenerator; boost::shared_ptr<ReadBytestream> stream; - StreamInitiationFileInfo fileInfo; + JingleFileTransferFileInfo fileInfo; FileTransferOptions options; JingleContentID contentID; IncrementalBytestreamHashCalculator* hashCalculator; State state; bool candidateAcknowledged; diff --git a/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp index a296b33..207f590 100644 --- a/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp +++ b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp @@ -2,13 +2,13 @@ * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2013 Isode Limited. + * Copyright (c) 2013-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> @@ -19,79 +19,93 @@ #include <Swiften/Base/Override.h> #include <Swiften/Base/Log.h> #include <Swiften/Client/DummyStanzaChannel.h> #include <Swiften/Elements/IBB.h> #include <Swiften/Elements/JingleIBBTransportPayload.h> #include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Elements/JingleFileTransferDescription.h> +#include <Swiften/FileTransfer/DefaultFileTransferTransporterFactory.h> #include <Swiften/FileTransfer/ByteArrayWriteBytestream.h> #include <Swiften/FileTransfer/IncomingJingleFileTransfer.h> #include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/Network/PlatformNetworkEnvironment.h> #include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h> #include <Swiften/Jingle/FakeJingleSession.h> +#include <Swiften/Network/NATTraverser.h> #include <Swiften/Network/DummyTimerFactory.h> #include <Swiften/EventLoop/DummyEventLoop.h> #include <Swiften/Network/DummyConnectionFactory.h> +#include <Swiften/Network/DummyConnectionServerFactory.h> #include <Swiften/Network/PlatformNATTraversalWorker.h> #include <Swiften/Queries/IQRouter.h> #include <Swiften/Crypto/CryptoProvider.h> #include <Swiften/Crypto/PlatformCryptoProvider.h> #include <iostream> using namespace Swift; using namespace boost; class IncomingJingleFileTransferTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(IncomingJingleFileTransferTest); - //CPPUNIT_TEST(test_AcceptOnyIBBSendsSessionAccept); - //CPPUNIT_TEST(test_OnlyIBBTransferReceiveWorks); + CPPUNIT_TEST(test_AcceptOnyIBBSendsSessionAccept); + CPPUNIT_TEST(test_OnlyIBBTransferReceiveWorks); //CPPUNIT_TEST(test_AcceptFailingS5BFallsBackToIBB); CPPUNIT_TEST_SUITE_END(); public: - // shared_ptr<IncomingJingleFileTransfer> createTestling() { - // JID ourJID("our@jid.org/full"); - // return boost::shared_ptr<IncomingJingleFileTransfer>(new IncomingJingleFileTransfer(ourJID, shared_ptr<JingleSession>(session), jingleContentPayload, fakeRJTCSF.get(), fakeLJTCF.get(), iqRouter, bytestreamRegistry, bytestreamProxy, timerFactory, crypto.get())); - // } + shared_ptr<IncomingJingleFileTransfer> createTestling() { + JID ourJID("our@jid.org/full"); + return boost::make_shared<IncomingJingleFileTransfer>(ourJID, shared_ptr<JingleSession>(session), jingleContentPayload, ftTransporterFactory, timerFactory, 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; - // } + 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()); eventLoop = new DummyEventLoop(); session = boost::make_shared<FakeJingleSession>("foo@bar.com/baz", "mysession"); - // jingleContentPayload = make_shared<JingleContentPayload>(); + jingleContentPayload = make_shared<JingleContentPayload>(); // fakeRJTCSF = make_shared<FakeRemoteJingleTransportCandidateSelectorFactory>(); // fakeLJTCF = make_shared<FakeLocalJingleTransportCandidateGeneratorFactory>(); - // stanzaChannel = new DummyStanzaChannel(); - // iqRouter = new IQRouter(stanzaChannel); - // bytestreamRegistry = new SOCKS5BytestreamRegistry(); - // timerFactory = new DummyTimerFactory(); - // connectionFactory = new DummyConnectionFactory(eventLoop); - // bytestreamProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory); + stanzaChannel = new DummyStanzaChannel(); + connectionFactory = new DummyConnectionFactory(eventLoop); + serverConnectionFactory = new DummyConnectionServerFactory(eventLoop); + iqRouter = new IQRouter(stanzaChannel); + bytestreamRegistry = new SOCKS5BytestreamRegistry(); + networkEnvironment = new PlatformNetworkEnvironment(); + natTraverser = new PlatformNATTraversalWorker(eventLoop); + bytestreamServerManager = new SOCKS5BytestreamServerManager(bytestreamRegistry, serverConnectionFactory, networkEnvironment, natTraverser); + idGenerator = new SimpleIDGenerator(); + timerFactory = new DummyTimerFactory(); + bytestreamProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory); + ftTransporterFactory = new DefaultFileTransferTransporterFactory(bytestreamRegistry, bytestreamServerManager, bytestreamProxy, idGenerator, connectionFactory, timerFactory, crypto.get(), iqRouter); } void tearDown() { - // delete bytestreamProxy; - // delete connectionFactory; - // delete timerFactory; - // delete bytestreamRegistry; - // delete iqRouter; - // delete stanzaChannel; + delete ftTransporterFactory; + delete bytestreamServerManager; + delete bytestreamProxy; + delete connectionFactory; + delete timerFactory; + delete bytestreamRegistry; + delete iqRouter; + delete stanzaChannel; delete eventLoop; + Log::setLogLevel(Log::error); } // Tests whether IncomingJingleFileTransfer would accept a IBB only file transfer. -#if 0 void test_AcceptOnyIBBSendsSessionAccept() { //1. create your test incoming file transfer shared_ptr<JingleFileTransferDescription> desc = make_shared<JingleFileTransferDescription>(); - desc->addOffer(StreamInitiationFileInfo("foo.txt", "", 10)); + desc->setFileInfo(JingleFileTransferFileInfo("foo.txt", "", 10)); jingleContentPayload->addDescription(desc); JingleIBBTransportPayload::ref tpRef = make_shared<JingleIBBTransportPayload>(); tpRef->setSessionID("mysession"); jingleContentPayload->addTransport(tpRef); shared_ptr<IncomingJingleFileTransfer> fileTransfer = createTestling(); @@ -104,13 +118,13 @@ public: getCall<FakeJingleSession::AcceptCall>(0); } void test_OnlyIBBTransferReceiveWorks() { //1. create your test incoming file transfer shared_ptr<JingleFileTransferDescription> desc = make_shared<JingleFileTransferDescription>(); - desc->addOffer(StreamInitiationFileInfo("file.txt", "", 10)); + desc->setFileInfo(JingleFileTransferFileInfo("file.txt", "", 10)); jingleContentPayload->addDescription(desc); JingleIBBTransportPayload::ref tpRef = make_shared<JingleIBBTransportPayload>(); tpRef->setSessionID("mysession"); jingleContentPayload->addTransport(tpRef); shared_ptr<IncomingJingleFileTransfer> fileTransfer = createTestling(); @@ -136,41 +150,43 @@ public: shared_ptr<IncomingJingleFileTransfer> fileTransfer = createTestling(); //2. do 'accept' on a dummy writebytestream (you'll have to look if there already is one) shared_ptr<ByteArrayWriteBytestream> byteStream = make_shared<ByteArrayWriteBytestream>(); fileTransfer->accept(byteStream); + // candidates are gathered + // check whether accept has been called FakeJingleSession::AcceptCall acceptCall = getCall<FakeJingleSession::AcceptCall>(0); CPPUNIT_ASSERT_EQUAL(payLoad->getSessionID(), acceptCall.payload->getSessionID()); // check for candidate error FakeJingleSession::InfoTransportCall infoTransportCall = getCall<FakeJingleSession::InfoTransportCall>(1); JingleS5BTransportPayload::ref s5bPayload = dynamic_pointer_cast<JingleS5BTransportPayload>(infoTransportCall.payload); CPPUNIT_ASSERT(s5bPayload->hasCandidateError()); // indicate transport replace (Romeo) - session->onTransportReplaceReceived(getContentID(), addJingleIBBPayload()); + session->handleTransportReplaceReceived(getContentID(), addJingleIBBPayload()); FakeJingleSession::AcceptTransportCall acceptTransportCall = getCall<FakeJingleSession::AcceptTransportCall>(2); // send a bit of data stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); CPPUNIT_ASSERT(createByteArray("abc") == byteStream->getData()); } - +#if 0 void test_S5BTransferReceiveTest() { addFileTransferDescription(); JingleS5BTransportPayload::ref payLoad = addJingleS5BPayload(); } - +#endif private: void addFileTransferDescription() { shared_ptr<JingleFileTransferDescription> desc = make_shared<JingleFileTransferDescription>(); - desc->addOffer(StreamInitiationFileInfo("file.txt", "", 10)); + desc->setFileInfo(JingleFileTransferFileInfo("file.txt", "", 10)); jingleContentPayload->addDescription(desc); } shared_ptr<JingleS5BTransportPayload> addJingleS5BPayload() { JingleS5BTransportPayload::ref payLoad = make_shared<JingleS5BTransportPayload>(); payLoad->setSessionID("mysession"); @@ -193,26 +209,29 @@ private: size_t index = static_cast<size_t>(i); CPPUNIT_ASSERT(index < session->calledCommands.size()); T* cmd = boost::get<T>(&session->calledCommands[index]); CPPUNIT_ASSERT(cmd); return *cmd; } -#endif private: EventLoop* eventLoop; boost::shared_ptr<CryptoProvider> crypto; boost::shared_ptr<FakeJingleSession> session; -#if 0 shared_ptr<JingleContentPayload> jingleContentPayload; - shared_ptr<FakeRemoteJingleTransportCandidateSelectorFactory> fakeRJTCSF; - shared_ptr<FakeLocalJingleTransportCandidateGeneratorFactory> fakeLJTCF; +// shared_ptr<FakeRemoteJingleTransportCandidateSelectorFactory> fakeRJTCSF; +// shared_ptr<FakeLocalJingleTransportCandidateGeneratorFactory> fakeLJTCF; + FileTransferTransporterFactory* ftTransporterFactory; + SOCKS5BytestreamServerManager* bytestreamServerManager; DummyStanzaChannel* stanzaChannel; IQRouter* iqRouter; SOCKS5BytestreamRegistry* bytestreamRegistry; DummyConnectionFactory* connectionFactory; + DummyConnectionServerFactory* serverConnectionFactory; SOCKS5BytestreamProxiesManager* bytestreamProxy; DummyTimerFactory* timerFactory; -#endif + NetworkEnvironment* networkEnvironment; + NATTraverser* natTraverser; + IDGenerator* idGenerator; }; CPPUNIT_TEST_SUITE_REGISTRATION(IncomingJingleFileTransferTest); |