diff options
6 files changed, 78 insertions, 27 deletions
diff --git a/src/com/isode/stroke/filetransfer/DummyFileTransferTransporterFactory.java b/src/com/isode/stroke/filetransfer/DummyFileTransferTransporterFactory.java index 10b630d..1904944 100644 --- a/src/com/isode/stroke/filetransfer/DummyFileTransferTransporterFactory.java +++ b/src/com/isode/stroke/filetransfer/DummyFileTransferTransporterFactory.java @@ -1,8 +1,8 @@ /* - * Copyright (c) 2015 Isode Limited. + * Copyright (c) 2015-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ /* * Copyright (c) 2015 Tarun Gupta. * Licensed under the simplified BSD license. @@ -48,27 +48,34 @@ class DummyFileTransferTransporter extends FileTransferTransporter { SOCKS5BytestreamProxiesManager s5bProxy, IDGenerator idGenerator, ConnectionFactory connectionFactory, TimerFactory timer, CryptoProvider cryptoProvider, IQRouter iqRouter, - final FileTransferOptions option) { + final FileTransferOptions ftOptions) { initiator_ = initiator; responder_ = responder; role_ = role; s5bRegistry_ = s5bRegistry; crypto_ = cryptoProvider; iqRouter_ = iqRouter; + ftOptions_ = new FileTransferOptions(ftOptions); } public void initialize() { s5bSessionID_ = s5bRegistry_.generateSessionID(); } public void startGeneratingLocalCandidates() { Vector<JingleS5BTransportPayload.Candidate> candidates = new Vector<JingleS5BTransportPayload.Candidate>(); + if (ftOptions_.isDirectAllowed()) { + JingleS5BTransportPayload.Candidate candidate = new JingleS5BTransportPayload.Candidate(); + candidate.cid = "123"; + candidate.priority = 1235; + candidates.add(candidate); + } onLocalCandidatesGenerated.emit(s5bSessionID_, candidates, getSOCKS5DstAddr()); } public void stopGeneratingLocalCandidates() { } @@ -144,12 +151,13 @@ class DummyFileTransferTransporter extends FileTransferTransporter { private JID responder_; private Role role_; private SOCKS5BytestreamRegistry s5bRegistry_; private CryptoProvider crypto_; private String s5bSessionID_; private IQRouter iqRouter_; + private final FileTransferOptions ftOptions_; }; public class DummyFileTransferTransporterFactory implements FileTransferTransporterFactory { public DummyFileTransferTransporterFactory( SOCKS5BytestreamRegistry s5bRegistry, diff --git a/src/com/isode/stroke/filetransfer/IncomingFileTransferManager.java b/src/com/isode/stroke/filetransfer/IncomingFileTransferManager.java index 7166d67..06ed3ab 100644 --- a/src/com/isode/stroke/filetransfer/IncomingFileTransferManager.java +++ b/src/com/isode/stroke/filetransfer/IncomingFileTransferManager.java @@ -1,8 +1,8 @@ /* - * Copyright (c) 2010-2015 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ /* * Copyright (c) 2015 Tarun Gupta. * Licensed under the simplified BSD license. @@ -12,21 +12,23 @@ package com.isode.stroke.filetransfer; import com.isode.stroke.signals.Signal1; import com.isode.stroke.jingle.IncomingJingleSessionHandler; import com.isode.stroke.jingle.JingleSessionManager; import com.isode.stroke.jingle.JingleSession; +import com.isode.stroke.elements.JingleIBBTransportPayload; import com.isode.stroke.elements.JinglePayload; import com.isode.stroke.elements.JingleContentPayload; import com.isode.stroke.elements.JingleFileTransferDescription; import com.isode.stroke.elements.JingleS5BTransportPayload; import com.isode.stroke.jingle.Jingle; import com.isode.stroke.network.TimerFactory; import com.isode.stroke.crypto.CryptoProvider; import com.isode.stroke.queries.IQRouter; import com.isode.stroke.jid.JID; + import java.util.logging.Logger; import java.util.Vector; public class IncomingFileTransferManager implements IncomingJingleSessionHandler { private JingleSessionManager jingleSessionManager; @@ -52,13 +54,14 @@ public class IncomingFileTransferManager implements IncomingJingleSessionHandler public boolean handleIncomingJingleSession( JingleSession session, final Vector<JingleContentPayload> contents, final JID recipient) { if (Jingle.getContentWithDescription(contents, new JingleFileTransferDescription()) != null) { JingleContentPayload content = Jingle.getContentWithDescription(contents, new JingleFileTransferDescription()); - if (content.getTransport(new JingleS5BTransportPayload()) != null) { + if ( (content.getTransport(new JingleS5BTransportPayload()) != null) + || (content.getTransport(new JingleIBBTransportPayload()) != null) ) { JingleFileTransferDescription description = content.getDescription(new JingleFileTransferDescription()); if (description != null) { IncomingJingleFileTransfer transfer = new IncomingJingleFileTransfer( recipient, session, content, transporterFactory, timerFactory, crypto); onIncomingFileTransfer.emit(transfer); } diff --git a/src/com/isode/stroke/filetransfer/IncomingJingleFileTransfer.java b/src/com/isode/stroke/filetransfer/IncomingJingleFileTransfer.java index 1c67014..f6aa01f 100644 --- a/src/com/isode/stroke/filetransfer/IncomingJingleFileTransfer.java +++ b/src/com/isode/stroke/filetransfer/IncomingJingleFileTransfer.java @@ -168,32 +168,33 @@ public class IncomingJingleFileTransfer extends JingleFileTransfer implements In @Override public void call(ByteArray b) { handleWriteStreamDataReceived(b); } }); - if (initialContent.getTransport(new JingleS5BTransportPayload()) != null) { - JingleS5BTransportPayload s5bTransport = initialContent.getTransport(new JingleS5BTransportPayload()); + JingleS5BTransportPayload s5bTransport = initialContent.getTransport(new JingleS5BTransportPayload()); + JingleIBBTransportPayload ibbTransport = initialContent.getTransport(new JingleIBBTransportPayload()); + if (s5bTransport != null) { logger_.fine("Got S5B transport as initial payload.\n"); setTransporter(transporterFactory.createResponderTransporter(getInitiator(), getResponder(), s5bTransport.getSessionID(), options)); transporter.addRemoteCandidates(s5bTransport.getCandidates(), s5bTransport.getDstAddr()); setInternalState(State.GeneratingInitialLocalCandidates); transporter.startGeneratingLocalCandidates(); } - else if(initialContent.getTransport(new JingleIBBTransportPayload()) != null) { - JingleIBBTransportPayload ibbTransport = initialContent.getTransport(new JingleIBBTransportPayload()); + else if(ibbTransport != null && options.isInBandAllowed()) { logger_.fine("Got IBB transport as initial payload.\n"); setTransporter(transporterFactory.createResponderTransporter(getInitiator(), getResponder(), ibbTransport.getSessionID(), options)); startTransferring(transporter.createIBBReceiveSession(ibbTransport.getSessionID(), (int)description.getFileInfo().getSize(), stream)); session.sendAccept(getContentID(), initialContent.getDescriptions().get(0), ibbTransport); } else { - // Can't happen, because the transfer would have been rejected automatically - assert(false); + // This might happen on incoming transfer which only list transport methods we are not allowed to use due to file-transfer options. + session.sendTerminate(JinglePayload.Reason.Type.UnsupportedTransports); + setFinishedState(FileTransfer.State.Type.Failed, new FileTransferError(FileTransferError.Type.PeerError)); } } /** * IncomingFileTransferMethod. */ diff --git a/src/com/isode/stroke/filetransfer/OutgoingJingleFileTransfer.java b/src/com/isode/stroke/filetransfer/OutgoingJingleFileTransfer.java index aa38022..e2117b6 100644 --- a/src/com/isode/stroke/filetransfer/OutgoingJingleFileTransfer.java +++ b/src/com/isode/stroke/filetransfer/OutgoingJingleFileTransfer.java @@ -176,16 +176,25 @@ public class OutgoingJingleFileTransfer extends JingleFileTransfer implements Ou public void start() { logger_.fine("\n"); if (!State.Initial.equals(internalState)) { logger_.warning("Incorrect state\n"); return; } - - setTransporter(transporterFactory.createInitiatorTransporter(getInitiator(), getResponder(), options)); - setInternalState(State.GeneratingInitialLocalCandidates); - transporter.startGeneratingLocalCandidates(); + + if (!options.isInBandAllowed() && !options.isDirectAllowed() + && !options.isAssistedAllowed() && !options.isProxiedAllowed()) { + // Started outgoing file transfer while not supporting transport methods. + setFinishedState(FileTransfer.State.Type.Failed, + new FileTransferError(FileTransferError.Type.UnknownError)); + } + else { + setTransporter(transporterFactory.createInitiatorTransporter(getInitiator(), getResponder(), options)); + setInternalState(State.GeneratingInitialLocalCandidates); + transporter.startGeneratingLocalCandidates(); + } + } /** * JingleFileTransferMethod. */ @Override @@ -214,12 +223,19 @@ public class OutgoingJingleFileTransfer extends JingleFileTransfer implements Ou if (transportPayload instanceof JingleS5BTransportPayload) { JingleS5BTransportPayload s5bPayload = (JingleS5BTransportPayload)transportPayload; transporter.addRemoteCandidates(s5bPayload.getCandidates(), s5bPayload.getDstAddr()); setInternalState(State.TryingCandidates); transporter.startTryingRemoteCandidates(); } + else if (transportPayload instanceof JingleIBBTransportPayload) { + JingleIBBTransportPayload ibbPayload = (JingleIBBTransportPayload) transportPayload; + int blockSize = ibbPayload.getBlockSize() != null ? + ibbPayload.getBlockSize().intValue() : DEFAULT_BLOCK_SIZE; + startTransferring(transporter.createIBBSendSession(ibbPayload.getSessionID(), + blockSize, stream)); + } else { logger_.fine("Unknown transport payload. Falling back.\n"); fallback(); } } @@ -307,20 +323,31 @@ public class OutgoingJingleFileTransfer extends JingleFileTransfer implements Ou JingleFileTransferDescription description = new JingleFileTransferDescription(); fileInfo.addHash(new HashElement("sha-1", new ByteArray())); fileInfo.addHash(new HashElement("md5", new ByteArray())); description.setFileInfo(fileInfo); - JingleS5BTransportPayload transport = new JingleS5BTransportPayload(); - transport.setSessionID(s5bSessionID); - transport.setMode(JingleS5BTransportPayload.Mode.TCPMode); - transport.setDstAddr(dstAddr); - for(JingleS5BTransportPayload.Candidate candidate : candidates) { - transport.addCandidate(candidate); - logger_.fine("\t" + "S5B candidate: " + candidate.hostPort.toString() + "\n"); - } + JingleTransportPayload transport = null; + if (candidates.isEmpty()) { + logger_.fine("no S5B candidate generated. Send IBB transport candidate.\n"); + JingleIBBTransportPayload ibbTransport = new JingleIBBTransportPayload(); + ibbTransport.setBlockSize(DEFAULT_BLOCK_SIZE); + ibbTransport.setSessionID(idGenerator.generateID()); + transport = ibbTransport; + } + else { + JingleS5BTransportPayload s5bTransport = new JingleS5BTransportPayload(); + s5bTransport.setSessionID(s5bSessionID); + s5bTransport.setMode(JingleS5BTransportPayload.Mode.TCPMode); + s5bTransport.setDstAddr(dstAddr); + for (JingleS5BTransportPayload.Candidate candidate : candidates) { + s5bTransport.addCandidate(candidate); + logger_.fine("\tS5B candidate: "+candidate.hostPort +"\n"); + } + transport = s5bTransport; + } setInternalState(State.WaitingForAccept); session.sendInitiate(contentID, description, transport); } public void handleTransportInfoAcknowledged(final String id) { if (id.equals(candidateSelectRequestID)) { diff --git a/src/com/isode/stroke/filetransfer/SOCKS5BytestreamServerManager.java b/src/com/isode/stroke/filetransfer/SOCKS5BytestreamServerManager.java index 590ee60..0d1f0a9 100644 --- a/src/com/isode/stroke/filetransfer/SOCKS5BytestreamServerManager.java +++ b/src/com/isode/stroke/filetransfer/SOCKS5BytestreamServerManager.java @@ -123,12 +123,16 @@ public class SOCKS5BytestreamServerManager { getPublicIPRequest = null; } if (forwardPortRequest != null) { forwardPortRequest.stop(); forwardPortRequest = null; } + if (unforwardPortRequest != null) { + unforwardPortRequest.stop(); + unforwardPortRequest = null; + } if (server != null) { server.stop(); server = null; } if (connectionServer != null) { connectionServer.stop(); diff --git a/test/com/isode/stroke/filetransfer/OutgoingJingleFileTransferTest.java b/test/com/isode/stroke/filetransfer/OutgoingJingleFileTransferTest.java index 4532efb..f8b76b8 100644 --- a/test/com/isode/stroke/filetransfer/OutgoingJingleFileTransferTest.java +++ b/test/com/isode/stroke/filetransfer/OutgoingJingleFileTransferTest.java @@ -95,26 +95,31 @@ public class OutgoingJingleFileTransferTest { if (call.description instanceof JingleFileTransferDescription) { description = (JingleFileTransferDescription) call.description; } assertNotNull(description); assertEquals(1048576,description.getFileInfo().getSize()); - JingleS5BTransportPayload transport = null; - if (call.payload instanceof JingleS5BTransportPayload) { - transport = (JingleS5BTransportPayload) call.payload; + JingleIBBTransportPayload transport = null; + if (call.payload instanceof JingleIBBTransportPayload) { + transport = (JingleIBBTransportPayload) call.payload; + } + else { + System.out.println(call.payload.getClass().getName()); } assertNotNull(transport); } @Test public void test_FallbackToIBBAfterFailingS5b() { - OutgoingJingleFileTransfer transfer = createTestling(); + OutgoingJingleFileTransfer transfer = + createTestling(new FileTransferOptions().withAssistedAllowed(true).withDirectAllowed(true).withProxiedAllowed(true)); transfer.start(); FakeJingleSession.InitiateCall call = getCall(FakeJingleSession.InitiateCall.class,0); + assertTrue(call.payload instanceof JingleS5BTransportPayload); fakeJingleSession.handleSessionAcceptReceived(call.id, call.description, call.payload); // Send candidate failure JingleS5BTransportPayload candiateFailurePayload = new JingleS5BTransportPayload(); candiateFailurePayload.setCandidateError(true); candiateFailurePayload.setSessionID(call.payload.getSessionID()); @@ -208,19 +213,22 @@ public class OutgoingJingleFileTransferTest { private boolean finishedCalled = false; private Type errorType = Type.UnknownError; private State state = null; } private OutgoingJingleFileTransfer createTestling() { + return createTestling(new FileTransferOptions().withAssistedAllowed(false).withDirectAllowed(false).withProxiedAllowed(false)); + } + + private OutgoingJingleFileTransfer createTestling(FileTransferOptions options) { JID to = new JID("test@foo.com/bla"); JingleFileTransferFileInfo fileInfo = new JingleFileTransferFileInfo(); fileInfo.setDescription("some file"); fileInfo.setName("test.bin"); fileInfo.addHash(new HashElement("sha-1", new ByteArray())); fileInfo.setSize(1024 * 1024); - FileTransferOptions options = (new FileTransferOptions()).withAssistedAllowed(false).withDirectAllowed(false).withProxiedAllowed(false); return new OutgoingJingleFileTransfer(to, fakeJingleSession, stream, ftTransporterFactory, timeFactory, idGen, fileInfo, options, crypto); } private IQ createIBBRequest(IBB ibb,JID from,String id) { IQ request = IQ.createRequest(IQ.Type.Set, new JID("foo@bar.com/baz"), id, ibb); |
Swift