From 9281a35fb912657f98ff0918ed683b2ef6071b45 Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Sun, 11 Jan 2015 13:39:50 +0100
Subject: Restrict generated candidates and selected candidates to those
 allowed by supplied FileTransferOptions.

Test-Information:

Automatically tested all FileTransferOption combinations and verified
it generates only allowed candidates.

Change-Id: I0b3ce983a3f230a4c2c3940f5d928fd74d6012b6

diff --git a/Swiften/FileTransfer/DefaultFileTransferTransporter.cpp b/Swiften/FileTransfer/DefaultFileTransferTransporter.cpp
index 1a77685..2c54d88 100644
--- a/Swiften/FileTransfer/DefaultFileTransferTransporter.cpp
+++ b/Swiften/FileTransfer/DefaultFileTransferTransporter.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014 Isode Limited.
+ * Copyright (c) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -138,7 +138,8 @@ DefaultFileTransferTransporter::DefaultFileTransferTransporter(
 		ConnectionFactory* connectionFactory, 
 		TimerFactory* timerFactory, 
 		CryptoProvider* crypto,
-		IQRouter* router) : 
+		IQRouter* router,
+		const FileTransferOptions& options) :
 			initiator(initiator),
 			responder(responder),
 			role(role),
@@ -151,13 +152,15 @@ DefaultFileTransferTransporter::DefaultFileTransferTransporter(
 			s5bServerManager,
 			s5bProxy,
 			role == Initiator ? initiator : responder,
-			idGenerator);
+			idGenerator,
+			options);
 	localCandidateGenerator->onLocalTransportCandidatesGenerated.connect(
 		boost::bind(&DefaultFileTransferTransporter::handleLocalCandidatesGenerated, this, _1));
 
 	remoteCandidateSelector = new RemoteJingleTransportCandidateSelector(
 			connectionFactory,
-			timerFactory);
+			timerFactory,
+			options);
 	remoteCandidateSelector->onCandidateSelectFinished.connect(
 		boost::bind(&DefaultFileTransferTransporter::handleRemoteCandidateSelectFinished, this, _1, _2));
 }
diff --git a/Swiften/FileTransfer/DefaultFileTransferTransporter.h b/Swiften/FileTransfer/DefaultFileTransferTransporter.h
index 1ceb79f..f5a4b9d 100644
--- a/Swiften/FileTransfer/DefaultFileTransferTransporter.h
+++ b/Swiften/FileTransfer/DefaultFileTransferTransporter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -25,6 +25,7 @@ namespace Swift {
 	class ConnectionFactory;
 	class TimerFactory;
 	class CryptoProvider;
+	class FileTransferOptions;
 
 	class SWIFTEN_API DefaultFileTransferTransporter : public FileTransferTransporter {
 		public:
@@ -44,7 +45,8 @@ namespace Swift {
 				ConnectionFactory*, 
 				TimerFactory*, 
 				CryptoProvider*,
-				IQRouter*);
+				IQRouter*,
+				const FileTransferOptions&);
 			virtual ~DefaultFileTransferTransporter();
 
 			
diff --git a/Swiften/FileTransfer/DefaultFileTransferTransporterFactory.cpp b/Swiften/FileTransfer/DefaultFileTransferTransporterFactory.cpp
index 02de40c..ffa0a12 100644
--- a/Swiften/FileTransfer/DefaultFileTransferTransporterFactory.cpp
+++ b/Swiften/FileTransfer/DefaultFileTransferTransporterFactory.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -34,7 +34,7 @@ DefaultFileTransferTransporterFactory::~DefaultFileTransferTransporterFactory()
 }
 
 FileTransferTransporter* DefaultFileTransferTransporterFactory::createInitiatorTransporter(
-		const JID& initiator, const JID& responder) {
+		const JID& initiator, const JID& responder, const FileTransferOptions& options) {
 	DefaultFileTransferTransporter* transporter = new DefaultFileTransferTransporter(
 		initiator, 
 		responder,
@@ -46,17 +46,18 @@ FileTransferTransporter* DefaultFileTransferTransporterFactory::createInitiatorT
 		connectionFactory,
 		timerFactory,
 		cryptoProvider,
-		iqRouter);
+		iqRouter,
+		options);
 	transporter->initialize();
 	return transporter;
 }
 
 FileTransferTransporter* DefaultFileTransferTransporterFactory::createResponderTransporter(
-		const JID& initiator, const JID& responder, const std::string& s5bSessionID) {
+		const JID& initiator, const JID& responder, const std::string& s5bSessionID, const FileTransferOptions& options) {
 	DefaultFileTransferTransporter* transporter = new DefaultFileTransferTransporter(
 		initiator, 
 		responder,
-		DefaultFileTransferTransporter::Initiator,
+		DefaultFileTransferTransporter::Responder,
 		s5bRegistry,
 		s5bServerManager,
 		s5bProxiesManager,
@@ -64,7 +65,8 @@ FileTransferTransporter* DefaultFileTransferTransporterFactory::createResponderT
 		connectionFactory,
 		timerFactory,
 		cryptoProvider,
-		iqRouter);
+		iqRouter,
+		options);
 	transporter->initialize(s5bSessionID);
 	return transporter;
 }
diff --git a/Swiften/FileTransfer/DefaultFileTransferTransporterFactory.h b/Swiften/FileTransfer/DefaultFileTransferTransporterFactory.h
index c1cf09b..93cf262 100644
--- a/Swiften/FileTransfer/DefaultFileTransferTransporterFactory.h
+++ b/Swiften/FileTransfer/DefaultFileTransferTransporterFactory.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -34,9 +34,9 @@ namespace Swift {
 			virtual ~DefaultFileTransferTransporterFactory();
 
 			virtual FileTransferTransporter* createInitiatorTransporter(
-					const JID& initiator, const JID& responder) SWIFTEN_OVERRIDE;
+					const JID& initiator, const JID& responder, const FileTransferOptions&) SWIFTEN_OVERRIDE;
 			virtual FileTransferTransporter* createResponderTransporter(
-					const JID& initiator, const JID& responder, const std::string& s5bSessionID) SWIFTEN_OVERRIDE;
+					const JID& initiator, const JID& responder, const std::string& s5bSessionID, const FileTransferOptions&) SWIFTEN_OVERRIDE;
 
 		private:
 			SOCKS5BytestreamRegistry* s5bRegistry; 
diff --git a/Swiften/FileTransfer/FileTransferTransporterFactory.h b/Swiften/FileTransfer/FileTransferTransporterFactory.h
index 8b213b4..a1af4af 100644
--- a/Swiften/FileTransfer/FileTransferTransporterFactory.h
+++ b/Swiften/FileTransfer/FileTransferTransporterFactory.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -13,6 +13,7 @@
 namespace Swift {
 	class JID;
 	class FileTransferTransporter;
+	class FileTransferOptions;
 
 	class SWIFTEN_API FileTransferTransporterFactory {
 		public:
@@ -20,10 +21,12 @@ namespace Swift {
 
 			virtual FileTransferTransporter* createInitiatorTransporter(
 					const JID& initiator, 
-					const JID& responder) = 0;
+					const JID& responder,
+					const FileTransferOptions& options) = 0;
 			virtual FileTransferTransporter* createResponderTransporter(
 					const JID& initiator, 
 					const JID& responder, 
-					const std::string& s5bSessionID) = 0;
+					const std::string& s5bSessionID,
+					const FileTransferOptions& options) = 0;
 	};
 }
diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp
index 720eefd..daecf92 100644
--- a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp
+++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014 Isode Limited.
+ * Copyright (c) 2011-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -79,7 +79,7 @@ void IncomingJingleFileTransfer::accept(
 	if (JingleS5BTransportPayload::ref s5bTransport = initialContent->getTransport<JingleS5BTransportPayload>()) {
 		SWIFT_LOG(debug) << "Got S5B transport as initial payload." << std::endl;
 		setTransporter(transporterFactory->createResponderTransporter(
-				getInitiator(), getResponder(), s5bTransport->getSessionID()));
+				getInitiator(), getResponder(), s5bTransport->getSessionID(), options));
 		transporter->addRemoteCandidates(s5bTransport->getCandidates());
 		setState(GeneratingInitialLocalCandidates);
 		transporter->startGeneratingLocalCandidates();
@@ -87,7 +87,7 @@ void IncomingJingleFileTransfer::accept(
 	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()));
+				getInitiator(), getResponder(), ibbTransport->getSessionID(), options));
 
 		startTransferring(transporter->createIBBReceiveSession(
 			ibbTransport->getSessionID(),
diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp
index 20f5189..c684a90 100644
--- a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp
+++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp
@@ -5,7 +5,7 @@
  */
 
 /*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -33,11 +33,13 @@ LocalJingleTransportCandidateGenerator::LocalJingleTransportCandidateGenerator(
 		SOCKS5BytestreamServerManager* s5bServerManager,
 		SOCKS5BytestreamProxiesManager* s5bProxy, 
 		const JID& ownJID,
-		IDGenerator* idGenerator) : 
+		IDGenerator* idGenerator,
+		const FileTransferOptions& options) :
 			s5bServerManager(s5bServerManager),
 			s5bProxy(s5bProxy), 
 			ownJID(ownJID),
-			idGenerator(idGenerator) {
+			idGenerator(idGenerator),
+			options_(options) {
 }
 
 LocalJingleTransportCandidateGenerator::~LocalJingleTransportCandidateGenerator() {
@@ -49,7 +51,6 @@ void LocalJingleTransportCandidateGenerator::start() {
 	s5bServerInitializeRequest = s5bServerManager->createInitializeRequest();
 	s5bServerInitializeRequest->onFinished.connect(
 			boost::bind(&LocalJingleTransportCandidateGenerator::handleS5BServerInitialized, this, _1));
-
 	s5bServerInitializeRequest->start();
 }
 
@@ -58,11 +59,36 @@ void LocalJingleTransportCandidateGenerator::stop() {
 		s5bServerInitializeRequest->stop();
 		s5bServerInitializeRequest.reset();
 	}
+
+	s5bServerManager->stop();
 }
 
 void LocalJingleTransportCandidateGenerator::handleS5BServerInitialized(bool success) {
-	std::vector<JingleS5BTransportPayload::Candidate> candidates;
 	if (success) {
+		if (options_.isProxiedAllowed()) {
+			if (s5bProxy->getOrDiscoverS5BProxies()) {
+				emitOnLocalTransportCandidatesGenerated();
+			} else {
+				s5bProxy->onDiscoveredProxiesChanged.connect(boost::bind(&LocalJingleTransportCandidateGenerator::handleDiscoveredProxiesChanged, this));
+			}
+		}
+		else {
+			emitOnLocalTransportCandidatesGenerated();
+		}
+	}
+	else {
+		SWIFT_LOG(warning) << "Unable to start SOCKS5 server" << std::endl;
+	}
+
+	s5bServerInitializeRequest->stop();
+	s5bServerInitializeRequest.reset();
+
+}
+
+void LocalJingleTransportCandidateGenerator::emitOnLocalTransportCandidatesGenerated() {
+	std::vector<JingleS5BTransportPayload::Candidate> candidates;
+
+	if (options_.isDirectAllowed()) {
 		// get direct candidates
 		std::vector<HostAddressPort> directCandidates = s5bServerManager->getHostAddressPorts();
 		foreach(HostAddressPort addressPort, directCandidates) {
@@ -74,7 +100,9 @@ void LocalJingleTransportCandidateGenerator::handleS5BServerInitialized(bool suc
 			candidate.cid = idGenerator->generateID();
 			candidates.push_back(candidate);
 		}
+	}
 
+	if (options_.isAssistedAllowed()) {
 		// get assissted candidates
 		std::vector<HostAddressPort> assisstedCandidates = s5bServerManager->getAssistedHostAddressPorts();
 		foreach(HostAddressPort addressPort, assisstedCandidates) {
@@ -87,16 +115,31 @@ void LocalJingleTransportCandidateGenerator::handleS5BServerInitialized(bool suc
 			candidates.push_back(candidate);
 		}
 	}
-	else {
-		SWIFT_LOG(warning) << "Unable to start SOCKS5 server" << std::endl;
-	}
 
-	s5bServerInitializeRequest->stop();
-	s5bServerInitializeRequest.reset();
+	if (options_.isProxiedAllowed()) {
+		foreach(S5BProxyRequest::ref proxy, s5bProxy->getOrDiscoverS5BProxies().get()) {
+			if (proxy->getStreamHost()) { // FIXME: Added this test, because there were cases where this wasn't initialized. Investigate this. (Remko)
+				JingleS5BTransportPayload::Candidate candidate;
+				candidate.type = JingleS5BTransportPayload::Candidate::ProxyType;
+				candidate.jid = (*proxy->getStreamHost()).jid;
+				HostAddress address = (*proxy->getStreamHost()).host;
+				assert(address.isValid());
+				candidate.hostPort = HostAddressPort(address, (*proxy->getStreamHost()).port);
+				candidate.priority = 65536 * 10 + LOCAL_PREFERENCE;
+				candidate.cid = idGenerator->generateID();
+				candidates.push_back(candidate);
+			}
+		}
+	}
 
 	onLocalTransportCandidatesGenerated(candidates);
 }
 
+void LocalJingleTransportCandidateGenerator::handleDiscoveredProxiesChanged() {
+	s5bProxy->onDiscoveredProxiesChanged.disconnect(boost::bind(&LocalJingleTransportCandidateGenerator::handleDiscoveredProxiesChanged, this));
+	emitOnLocalTransportCandidatesGenerated();
+}
+
 /*void LocalJingleTransportCandidateGenerator::handleS5BProxiesDiscovered() {
 	foreach(S5BProxyRequest::ref proxy, s5bProxiesDiscoverRequest->getS5BProxies()) {
 		if (proxy->getStreamHost()) { // FIXME: Added this test, because there were cases where this wasn't initialized. Investigate this. (Remko)
diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h
index 0b831be..ed2b4f0 100644
--- a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h
+++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h
@@ -5,7 +5,7 @@
  */
 
 /*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -19,6 +19,8 @@
 #include <Swiften/Base/Override.h>
 #include <Swiften/JID/JID.h>
 #include <Swiften/Elements/JingleS5BTransportPayload.h>
+#include <Swiften/FileTransfer/FileTransferOptions.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h>
 
 namespace Swift {
 	class SOCKS5BytestreamServerManager;
@@ -32,7 +34,8 @@ namespace Swift {
 					SOCKS5BytestreamServerManager* s5bServerManager,
 					SOCKS5BytestreamProxiesManager* s5bProxy, 
 					const JID& ownJID,
-					IDGenerator* idGenerator);
+					IDGenerator* idGenerator,
+					const FileTransferOptions& options);
 			virtual ~LocalJingleTransportCandidateGenerator();
 
 			virtual void start();
@@ -42,7 +45,10 @@ namespace Swift {
 
 		private:
 			void handleS5BServerInitialized(bool success);
+			void handleDiscoveredProxiesChanged();
+
 			void checkS5BCandidatesReady();
+			void emitOnLocalTransportCandidatesGenerated();
 
 		private:
 			SOCKS5BytestreamServerManager* s5bServerManager;
@@ -50,5 +56,6 @@ namespace Swift {
 			JID ownJID;
 			IDGenerator* idGenerator;
 			boost::shared_ptr<SOCKS5BytestreamServerInitializeRequest> s5bServerInitializeRequest;
+			FileTransferOptions options_;
 	};
 }
diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp
index 369af8f..4183af7 100644
--- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp
+++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp
@@ -5,7 +5,7 @@
  */
 
 /*
- * Copyright (C) 2013-2014 Isode Limited.
+ * Copyright (C) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -79,7 +79,7 @@ void OutgoingJingleFileTransfer::start() {
 	SWIFT_LOG(debug) << std::endl;
 	if (state != Initial) { SWIFT_LOG(warning) << "Incorrect state" << std::endl; return; }
 
-	setTransporter(transporterFactory->createInitiatorTransporter(getInitiator(), getResponder()));
+	setTransporter(transporterFactory->createInitiatorTransporter(getInitiator(), getResponder(), options));
 	setState(GeneratingInitialLocalCandidates);
 	transporter->startGeneratingLocalCandidates();
 }
diff --git a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.cpp b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.cpp
index 1f563e3..05a0f0e 100644
--- a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.cpp
+++ b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.cpp
@@ -5,7 +5,7 @@
  */
 
 /*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -26,9 +26,11 @@ using namespace Swift;
 
 RemoteJingleTransportCandidateSelector::RemoteJingleTransportCandidateSelector(
 		ConnectionFactory* connectionFactory, 
-		TimerFactory* timerFactory) :
+		TimerFactory* timerFactory,
+		const FileTransferOptions& options) :
 			connectionFactory(connectionFactory), 
-			timerFactory(timerFactory) {
+			timerFactory(timerFactory),
+			options(options) {
 }
 
 RemoteJingleTransportCandidateSelector::~RemoteJingleTransportCandidateSelector() {
@@ -62,9 +64,9 @@ void RemoteJingleTransportCandidateSelector::tryNextCandidate() {
 		lastCandidate = candidates.top();
 		candidates.pop();
 		SWIFT_LOG(debug) << "Trying candidate " << lastCandidate.cid << std::endl;
-		if (lastCandidate.type == JingleS5BTransportPayload::Candidate::DirectType 
-				|| lastCandidate.type == JingleS5BTransportPayload::Candidate::AssistedType 
-				|| lastCandidate.type == JingleS5BTransportPayload::Candidate::ProxyType ) {
+		if ((lastCandidate.type == JingleS5BTransportPayload::Candidate::DirectType && options.isDirectAllowed()) ||
+			(lastCandidate.type == JingleS5BTransportPayload::Candidate::AssistedType && options.isAssistedAllowed()) ||
+			(lastCandidate.type == JingleS5BTransportPayload::Candidate::ProxyType && options.isProxiedAllowed())) {
 			boost::shared_ptr<Connection> connection = connectionFactory->createConnection();
 			s5bSession = boost::make_shared<SOCKS5BytestreamClientSession>(
 					connection, lastCandidate.hostPort, socks5DstAddr, timerFactory);
diff --git a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h
index 442fa6a..342655c 100644
--- a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h
+++ b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h
@@ -5,7 +5,7 @@
  */
 
 /*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -23,6 +23,7 @@
 #include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h>
 #include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h>
 #include <Swiften/Elements/JingleS5BTransportPayload.h>
+#include <Swiften/FileTransfer/FileTransferOptions.h>
 
 
 namespace Swift {
@@ -31,7 +32,7 @@ namespace Swift {
 
 	class RemoteJingleTransportCandidateSelector {
 		public:
-			RemoteJingleTransportCandidateSelector(ConnectionFactory*, TimerFactory*);
+			RemoteJingleTransportCandidateSelector(ConnectionFactory*, TimerFactory*, const FileTransferOptions&);
 			virtual ~RemoteJingleTransportCandidateSelector();
 
 			virtual void addCandidates(const std::vector<JingleS5BTransportPayload::Candidate>&);
@@ -57,5 +58,6 @@ namespace Swift {
 			boost::bsignals::connection sessionReadyConnection;
 			JingleS5BTransportPayload::Candidate lastCandidate;
 			std::string socks5DstAddr;
+			FileTransferOptions options;
 		};
 }
diff --git a/Swiften/Jingle/JingleSessionImpl.cpp b/Swiften/Jingle/JingleSessionImpl.cpp
index 8299fac..a5273d6 100644
--- a/Swiften/Jingle/JingleSessionImpl.cpp
+++ b/Swiften/Jingle/JingleSessionImpl.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -151,8 +151,17 @@ std::string JingleSessionImpl::sendTransportInfo(const JingleContentID& id, Jing
 	return sendSetRequest(payload);
 }
 
-void JingleSessionImpl::sendTransportReject(const JingleContentID& /* id */, JingleTransportPayload::ref /* transPayload */) {
-	SWIFT_LOG(debug) << "NOT IMPLEMENTED YET!!!!" << std::endl;
+void JingleSessionImpl::sendTransportReject(const JingleContentID& id, JingleTransportPayload::ref transPayload) {
+	JinglePayload::ref payload = createPayload();
+
+	JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>();
+	content->setCreator(id.getCreator());
+	content->setName(id.getName());
+	content->addTransport(transPayload);
+	payload->setAction(JinglePayload::TransportReject);
+	payload->addPayload(content);
+
+	sendSetRequest(payload);
 }
 
 void JingleSessionImpl::sendTransportReplace(const JingleContentID& id, JingleTransportPayload::ref transPayload) {
-- 
cgit v0.10.2-6-g49f6