diff options
author | Tobias Markmann <tm@ayena.de> | 2015-01-11 15:40:09 (GMT) |
---|---|---|
committer | Swift Review <review@swift.im> | 2015-02-11 09:36:03 (GMT) |
commit | f176050a50fb846bbad3fb49d6b2f7a2c81e3589 (patch) | |
tree | bd93b8b540cb3818cc0d47d44b9dd8751dd17dd5 | |
parent | 71e34ffa7144441bc5a7fce15728f506daffc756 (diff) | |
download | swift-f176050a50fb846bbad3fb49d6b2f7a2c81e3589.zip swift-f176050a50fb846bbad3fb49d6b2f7a2c81e3589.tar.bz2 |
Wait for responder to terminate the the file transfer session after data
verification.
Test-Information:
Tested with FileTransferTest (coming with future commit) and inspected
the logs.
Change-Id: Idd2739e15ab944e8486065cb2a3bc559ce9053d1
5 files changed, 38 insertions, 5 deletions
diff --git a/Swiften/FileTransfer/FileTransferManagerImpl.cpp b/Swiften/FileTransfer/FileTransferManagerImpl.cpp index ab4cb5c..ab08c45 100644 --- a/Swiften/FileTransfer/FileTransferManagerImpl.cpp +++ b/Swiften/FileTransfer/FileTransferManagerImpl.cpp @@ -73,12 +73,13 @@ FileTransferManagerImpl::FileTransferManagerImpl( crypto, iqRouter); outgoingFTManager = new OutgoingFileTransferManager( jingleSessionManager, iqRouter, transporterFactory, + timerFactory, crypto); incomingFTManager = new IncomingFileTransferManager( jingleSessionManager, iqRouter, transporterFactory, timerFactory, diff --git a/Swiften/FileTransfer/OutgoingFileTransferManager.cpp b/Swiften/FileTransfer/OutgoingFileTransferManager.cpp index 5d0555f..0ed2395 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-2014 Isode Limited. + * Copyright (c) 2013-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/FileTransfer/OutgoingFileTransferManager.h> @@ -22,18 +22,20 @@ #include <Swiften/Base/IDGenerator.h> namespace Swift { OutgoingFileTransferManager::OutgoingFileTransferManager( JingleSessionManager* jingleSessionManager, - IQRouter* router, + IQRouter* router, FileTransferTransporterFactory* transporterFactory, + TimerFactory* timerFactory, CryptoProvider* crypto) : jingleSessionManager(jingleSessionManager), iqRouter(router), transporterFactory(transporterFactory), + timerFactory(timerFactory), crypto(crypto) { idGenerator = new IDGenerator(); } OutgoingFileTransferManager::~OutgoingFileTransferManager() { delete idGenerator; @@ -50,12 +52,13 @@ boost::shared_ptr<OutgoingFileTransfer> OutgoingFileTransferManager::createOutgo jingleSessionManager->registerOutgoingSession(from, jingleSession); return boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer( recipient, jingleSession, readBytestream, transporterFactory, + timerFactory, idGenerator, fileInfo, config, crypto)); } diff --git a/Swiften/FileTransfer/OutgoingFileTransferManager.h b/Swiften/FileTransfer/OutgoingFileTransferManager.h index fd7380b..f97bc9b 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-2014 Isode Limited. + * Copyright (c) 2013-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once @@ -22,19 +22,21 @@ namespace Swift { class JID; class IDGenerator; class ReadBytestream; class JingleFileTransferFileInfo; class CryptoProvider; class FileTransferOptions; + class TimerFactory; class OutgoingFileTransferManager { public: OutgoingFileTransferManager( JingleSessionManager* jingleSessionManager, IQRouter* router, FileTransferTransporterFactory* transporterFactory, + TimerFactory* timerFactory, CryptoProvider* crypto); ~OutgoingFileTransferManager(); boost::shared_ptr<OutgoingFileTransfer> createOutgoingFileTransfer( const JID& from, const JID& to, @@ -43,10 +45,11 @@ namespace Swift { const FileTransferOptions&); private: JingleSessionManager* jingleSessionManager; IQRouter* iqRouter; FileTransferTransporterFactory* transporterFactory; + TimerFactory* timerFactory; IDGenerator* idGenerator; CryptoProvider* crypto; }; } diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp index 4183af7..07e927e 100644 --- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp @@ -33,24 +33,26 @@ #include <Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h> #include <Swiften/FileTransfer/FileTransferTransporter.h> #include <Swiften/FileTransfer/FileTransferTransporterFactory.h> #include <Swiften/FileTransfer/ReadBytestream.h> #include <Swiften/FileTransfer/TransportSession.h> #include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Network/TimerFactory.h> #include <Swiften/Base/Log.h> using namespace Swift; static const int DEFAULT_BLOCK_SIZE = 4096; OutgoingJingleFileTransfer::OutgoingJingleFileTransfer( const JID& toJID, JingleSession::ref session, boost::shared_ptr<ReadBytestream> stream, FileTransferTransporterFactory* transporterFactory, + TimerFactory* timerFactory, IDGenerator* idGenerator, const JingleFileTransferFileInfo& fileInfo, const FileTransferOptions& options, CryptoProvider* crypto) : JingleFileTransfer(session, toJID, transporterFactory), idGenerator(idGenerator), @@ -64,12 +66,15 @@ OutgoingJingleFileTransfer::OutgoingJingleFileTransfer( setFileInfo(fileInfo.getName(), fileInfo.getSize()); // calculate both, MD5 and SHA-1 since we don't know which one the other side supports hashCalculator = new IncrementalBytestreamHashCalculator(true, true, crypto); stream->onRead.connect( boost::bind(&IncrementalBytestreamHashCalculator::feedData, hashCalculator, _1)); + + waitForRemoteTermination = timerFactory->createTimer(5000); + waitForRemoteTermination->onTick.connect(boost::bind(&OutgoingJingleFileTransfer::handleWaitForRemoteTerminationTimeout, this)); } OutgoingJingleFileTransfer::~OutgoingJingleFileTransfer() { stream->onRead.disconnect( boost::bind(&IncrementalBytestreamHashCalculator::feedData, hashCalculator, _1)); delete hashCalculator; @@ -196,13 +201,16 @@ void OutgoingJingleFileTransfer::handleTransferFinished(boost::optional<FileTran if (error) { terminate(JinglePayload::Reason::ConnectivityError); } else { sendSessionInfoHash(); - terminate(JinglePayload::Reason::Success); + + // wait for other party to terminate session after they have verified the hash + setState(WaitForTermination); + waitForRemoteTermination->start(); } } void OutgoingJingleFileTransfer::startTransferring(boost::shared_ptr<TransportSession> transportSession) { SWIFT_LOG(debug) << std::endl; @@ -238,12 +246,13 @@ FileTransfer::State::Type OutgoingJingleFileTransfer::getExternalState(State sta case TryingCandidates: return FileTransfer::State::Negotiating; case WaitingForPeerProxyActivate: return FileTransfer::State::Negotiating; case WaitingForLocalProxyActivate: return FileTransfer::State::Negotiating; case WaitingForCandidateAcknowledge: return FileTransfer::State::Negotiating; case FallbackRequested: return FileTransfer::State::Negotiating; case Transferring: return FileTransfer::State::Transferring; + case WaitForTermination: return FileTransfer::State::Transferring; case Finished: return FileTransfer::State::Finished; } assert(false); return FileTransfer::State::Initial; } @@ -262,12 +271,14 @@ void OutgoingJingleFileTransfer::stopAll() { assert(transportSession); processedBytesConnection.disconnect(); transferFinishedConnection.disconnect(); transportSession->stop(); transportSession.reset(); break; + case WaitForTermination: + break; case Finished: SWIFT_LOG(warning) << "Already finished" << std::endl; break; } if (state != Initial) { delete transporter; } } @@ -340,6 +351,13 @@ boost::shared_ptr<TransportSession> OutgoingJingleFileTransfer::createLocalCandi } boost::shared_ptr<TransportSession> OutgoingJingleFileTransfer::createRemoteCandidateSession() { return transporter->createRemoteCandidateSession(stream); } +void OutgoingJingleFileTransfer::handleWaitForRemoteTerminationTimeout() { + assert(state == WaitForTermination); + SWIFT_LOG(warning) << "Other party did not terminate session. Terminate it now." << std::endl; + waitForRemoteTermination->stop(); + terminate(JinglePayload::Reason::MediaError); +} + diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.h b/Swiften/FileTransfer/OutgoingJingleFileTransfer.h index f022b9f..52960d5 100644 --- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.h +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.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-2014 Isode Limited. + * Copyright (c) 2013-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once @@ -19,29 +19,32 @@ #include <Swiften/Base/Override.h> #include <Swiften/Jingle/JingleContentID.h> #include <Swiften/Elements/JingleFileTransferFileInfo.h> #include <Swiften/FileTransfer/OutgoingFileTransfer.h> #include <Swiften/FileTransfer/JingleFileTransfer.h> #include <Swiften/FileTransfer/FileTransferOptions.h> +#include <Swiften/Network/Timer.h> namespace Swift { class ReadBytestream; class IDGenerator; class IncrementalBytestreamHashCalculator; class CryptoProvider; class FileTransferTransporter; class FileTransferTransporterFactory; class TransportSession; + class TimerFactory; class SWIFTEN_API OutgoingJingleFileTransfer : public OutgoingFileTransfer, public JingleFileTransfer { public: OutgoingJingleFileTransfer( const JID& to, boost::shared_ptr<JingleSession>, boost::shared_ptr<ReadBytestream>, FileTransferTransporterFactory*, + TimerFactory*, IDGenerator*, const JingleFileTransferFileInfo&, const FileTransferOptions&, CryptoProvider*); virtual ~OutgoingJingleFileTransfer(); @@ -56,12 +59,13 @@ namespace Swift { TryingCandidates, WaitingForPeerProxyActivate, WaitingForLocalProxyActivate, WaitingForCandidateAcknowledge, FallbackRequested, Transferring, + WaitForTermination, Finished }; virtual void handleSessionAcceptReceived(const JingleContentID&, boost::shared_ptr<JingleDescription>, boost::shared_ptr<JingleTransportPayload>) SWIFTEN_OVERRIDE; virtual void handleSessionTerminateReceived(boost::optional<JinglePayload::Reason> reason) SWIFTEN_OVERRIDE; virtual void handleTransportAcceptReceived(const JingleContentID&, boost::shared_ptr<JingleTransportPayload>) SWIFTEN_OVERRIDE; @@ -87,12 +91,14 @@ namespace Swift { virtual bool isWaitingForPeerProxyActivate() const SWIFTEN_OVERRIDE; virtual bool isWaitingForLocalProxyActivate() const SWIFTEN_OVERRIDE; virtual bool isTryingCandidates() const SWIFTEN_OVERRIDE; virtual boost::shared_ptr<TransportSession> createLocalCandidateSession() SWIFTEN_OVERRIDE; virtual boost::shared_ptr<TransportSession> createRemoteCandidateSession() SWIFTEN_OVERRIDE; + void handleWaitForRemoteTerminationTimeout(); + void stopAll(); void setState(State state); void setFinishedState(FileTransfer::State::Type, const boost::optional<FileTransferError>& error); static FileTransfer::State::Type getExternalState(State state); @@ -103,11 +109,13 @@ namespace Swift { FileTransferOptions options; JingleContentID contentID; IncrementalBytestreamHashCalculator* hashCalculator; State state; bool candidateAcknowledged; + Timer::ref waitForRemoteTermination; + boost::bsignals::connection processedBytesConnection; boost::bsignals::connection transferFinishedConnection; }; } |