From 4c1ee37ea722d27bfbc553bf68adccbcc0be5bb7 Mon Sep 17 00:00:00 2001 From: vanitasvitae Date: Wed, 21 Jun 2017 15:28:32 +0200 Subject: [PATCH] Reuse S5B methods --- .../OutgoingJingleFileOffer.java | 7 +- .../socks5/Socks5BytestreamManager.java | 4 +- .../smackx/jingle/JingleManager.java | 6 + .../jingle/JingleTransportMethodManager.java | 9 ++ .../JingleTransportInitiationCallback.java | 3 +- .../transports/JingleTransportManager.java | 17 ++- .../jingle_ibb/JingleIBBTransportManager.java | 109 ++++++++++++++++ .../jingle_s5b/JingleS5BTransportManager.java | 116 ++++++++++++++++++ 8 files changed, 265 insertions(+), 6 deletions(-) create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_ibb/JingleIBBTransportManager.java create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/JingleS5BTransportManager.java diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/OutgoingJingleFileOffer.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/OutgoingJingleFileOffer.java index 514b1b47c..f7184d145 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/OutgoingJingleFileOffer.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/OutgoingJingleFileOffer.java @@ -92,12 +92,17 @@ public class OutgoingJingleFileOffer extends JingleFileTransferSession { // Legal else { state = State.active; - transportManager.initiateOutgoingSession(transport, new JingleTransportInitiationCallback() { + transportManager.initiateOutgoingSession(getResponder(), transport, new JingleTransportInitiationCallback() { @Override public void onSessionInitiated(final BytestreamSession session) { sendingThread = new SendingThread(session, source); sendingThread.run(); } + + @Override + public void onException(Exception e) { + LOGGER.log(Level.SEVERE, "Cannot create outgoing Bytestream session: ", e); + } }); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java index 38c0a6261..247e4de7e 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java @@ -538,7 +538,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream * @throws NotConnectedException * @throws InterruptedException */ - private List determineProxies() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + public List determineProxies() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { XMPPConnection connection = connection(); ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection); @@ -634,7 +634,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream * @return the stream host information of the local SOCKS5 proxy or null if local SOCKS5 proxy * is not running */ - private List getLocalStreamHost() { + public List getLocalStreamHost() { XMPPConnection connection = connection(); // get local proxy singleton Socks5Proxy socks5Server = Socks5Proxy.getSocks5Proxy(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleManager.java index 347ae7ff4..5962e8233 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleManager.java @@ -32,6 +32,8 @@ import org.jivesoftware.smackx.jingle.element.Jingle; import org.jivesoftware.smackx.jingle.element.JingleAction; import org.jivesoftware.smackx.jingle.element.JingleContent; import org.jivesoftware.smackx.jingle.element.JingleContentDescription; +import org.jivesoftware.smackx.jingle.transports.jingle_ibb.JingleIBBTransportManager; +import org.jivesoftware.smackx.jingle.transports.jingle_s5b.JingleS5BTransportManager; import org.jxmpp.jid.FullJid; @@ -95,6 +97,10 @@ public final class JingleManager extends Manager { return jutil.createErrorUnknownSession(jingle); } }); + //Register transports. + JingleTransportMethodManager transportMethodManager = JingleTransportMethodManager.getInstanceFor(connection); + transportMethodManager.registerTransportManager(JingleIBBTransportManager.getInstanceFor(connection)); + transportMethodManager.registerTransportManager(JingleS5BTransportManager.getInstanceFor(connection)); } public JingleHandler registerDescriptionHandler(String namespace, JingleHandler handler) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleTransportMethodManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleTransportMethodManager.java index 72dc03279..dea71d6ab 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleTransportMethodManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleTransportMethodManager.java @@ -35,6 +35,15 @@ import org.jivesoftware.smackx.jingle.transports.jingle_s5b.elements.JingleS5BTr public final class JingleTransportMethodManager extends Manager { private static final WeakHashMap INSTANCES = new WeakHashMap<>(); + + static { + ClassLoader classLoader = JingleTransportMethodManager.class.getClassLoader(); + String[] knownTransports = new String[] { + "org.jivesoftware.smackx.jingle.transports.jingle_s5b.JingleS5BTransportManager", + "org.jivesoftware.smackx.jingle.transports.jingle_ibb.JingleIBBTransportManager" + }; + //TODO: Load dynamically. + } private final HashMap> transportManagers = new HashMap<>(); private static final String[] transportPreference = new String[] { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportInitiationCallback.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportInitiationCallback.java index 3db3f91ea..79932c1e0 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportInitiationCallback.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportInitiationCallback.java @@ -19,11 +19,12 @@ package org.jivesoftware.smackx.jingle.transports; import org.jivesoftware.smackx.bytestreams.BytestreamSession; /** - * Created by vanitas on 20.06.17. + * Callback for bytestream session creation of TransportManagers. */ public interface JingleTransportInitiationCallback { void onSessionInitiated(BytestreamSession bytestreamSession); + void onException(Exception e); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java index 108e39a4c..371a0bc9d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java @@ -16,23 +16,36 @@ */ package org.jivesoftware.smackx.jingle.transports; +import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smackx.jingle.element.Jingle; import org.jivesoftware.smackx.jingle.element.JingleContentTransport; +import org.jxmpp.jid.FullJid; + /** * Manager for a JingleTransport method. * @param JingleContentTransport. */ public abstract class JingleTransportManager { + private final XMPPConnection connection; + + public JingleTransportManager(XMPPConnection connection) { + this.connection = connection; + } + + public XMPPConnection getConnection() { + return connection; + } + public abstract String getNamespace(); public abstract D createTransport(); public abstract D createTransport(Jingle request); - public abstract void initiateOutgoingSession(JingleContentTransport transport, JingleTransportInitiationCallback callback); + public abstract void initiateOutgoingSession(FullJid remote, JingleContentTransport transport, JingleTransportInitiationCallback callback); - public abstract void initiateIncomingSession(JingleContentTransport transport, JingleTransportInitiationCallback callback); + public abstract void initiateIncomingSession(FullJid remote, JingleContentTransport transport, JingleTransportInitiationCallback callback); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_ibb/JingleIBBTransportManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_ibb/JingleIBBTransportManager.java new file mode 100644 index 000000000..a3cc7d66c --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_ibb/JingleIBBTransportManager.java @@ -0,0 +1,109 @@ +/** + * + * Copyright 2017 Paul Schaub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.jingle.transports.jingle_ibb; + +import java.util.WeakHashMap; + +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smackx.bytestreams.BytestreamListener; +import org.jivesoftware.smackx.bytestreams.BytestreamRequest; +import org.jivesoftware.smackx.bytestreams.BytestreamSession; +import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager; +import org.jivesoftware.smackx.jingle.element.Jingle; +import org.jivesoftware.smackx.jingle.element.JingleContentTransport; +import org.jivesoftware.smackx.jingle.transports.JingleTransportInitiationCallback; +import org.jivesoftware.smackx.jingle.transports.JingleTransportManager; +import org.jivesoftware.smackx.jingle.transports.jingle_ibb.element.JingleIBBTransport; + +import org.jxmpp.jid.FullJid; + +/** + * Manager for Jingle InBandBytestream transports (XEP-0261). + */ +public final class JingleIBBTransportManager extends JingleTransportManager { + + private static final WeakHashMap INSTANCES = new WeakHashMap<>(); + + private JingleIBBTransportManager(XMPPConnection connection) { + super(connection); + } + + public static JingleIBBTransportManager getInstanceFor(XMPPConnection connection) { + JingleIBBTransportManager manager = INSTANCES.get(connection); + if (manager == null) { + manager = new JingleIBBTransportManager(connection); + INSTANCES.put(connection, manager); + } + return manager; + } + + @Override + public String getNamespace() { + return JingleIBBTransport.NAMESPACE_V1; + } + + @Override + public JingleIBBTransport createTransport() { + return new JingleIBBTransport(); + } + + @Override + public JingleIBBTransport createTransport(Jingle request) { + JingleIBBTransport rTransport = (JingleIBBTransport) request.getContents().get(0).getJingleTransport(); + return new JingleIBBTransport(rTransport.getBlockSize(), rTransport.getSessionId()); + } + + @Override + public void initiateOutgoingSession(FullJid remote, JingleContentTransport transport, JingleTransportInitiationCallback callback) { + JingleIBBTransport ibbTransport = (JingleIBBTransport) transport; + BytestreamSession session; + + try { + session = InBandBytestreamManager.getByteStreamManager(getConnection()) + .establishSession(remote, ibbTransport.getSessionId()); + callback.onSessionInitiated(session); + } catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { + callback.onException(e); + } + } + + @Override + public void initiateIncomingSession(final FullJid remote, final JingleContentTransport transport, final JingleTransportInitiationCallback callback) { + final JingleIBBTransport ibbTransport = (JingleIBBTransport) transport; + + InBandBytestreamManager.getByteStreamManager(getConnection()).addIncomingBytestreamListener(new BytestreamListener() { + @Override + public void incomingBytestreamRequest(BytestreamRequest request) { + if (request.getFrom().asFullJidIfPossible().equals(remote) + && request.getSessionID().equals(ibbTransport.getSessionId())) { + + BytestreamSession session; + + try { + session = request.accept(); + } catch (InterruptedException | SmackException | XMPPException.XMPPErrorException e) { + callback.onException(e); + return; + } + callback.onSessionInitiated(session); + } + } + }); + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/JingleS5BTransportManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/JingleS5BTransportManager.java new file mode 100644 index 000000000..8f48965f7 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/JingleS5BTransportManager.java @@ -0,0 +1,116 @@ +/** + * + * Copyright 2017 Paul Schaub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.jingle.transports.jingle_s5b; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.WeakHashMap; + +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager; +import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; +import org.jivesoftware.smackx.jingle.element.Jingle; +import org.jivesoftware.smackx.jingle.element.JingleContentTransport; +import org.jivesoftware.smackx.jingle.transports.JingleTransportInitiationCallback; +import org.jivesoftware.smackx.jingle.transports.JingleTransportManager; +import org.jivesoftware.smackx.jingle.transports.jingle_s5b.elements.JingleS5BTransport; + +import org.jxmpp.jid.FullJid; +import org.jxmpp.jid.Jid; + +/** + * Manager for Jingle SOCKS5 Bytestream transports (XEP-0261). + */ +public final class JingleS5BTransportManager extends JingleTransportManager { + + private static final WeakHashMap INSTANCES = new WeakHashMap<>(); + + private JingleS5BTransportManager(XMPPConnection connection) { + super(connection); + } + + public static JingleS5BTransportManager getInstanceFor(XMPPConnection connection) { + JingleS5BTransportManager manager = INSTANCES.get(connection); + if (manager == null) { + manager = new JingleS5BTransportManager(connection); + INSTANCES.put(connection, manager); + } + return manager; + } + + @Override + public String getNamespace() { + return JingleS5BTransport.NAMESPACE_V1; + } + + @Override + public JingleS5BTransport createTransport() { + return null; + } + + @Override + public JingleS5BTransport createTransport(Jingle request) { + return null; + } + + @Override + public void initiateOutgoingSession(FullJid remote, JingleContentTransport transport, JingleTransportInitiationCallback callback) { + + } + + @Override + public void initiateIncomingSession(FullJid remote, JingleContentTransport transport, JingleTransportInitiationCallback callback) { + + } + + public List getAvailableStreamHosts() throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { + Socks5BytestreamManager s5m = Socks5BytestreamManager.getBytestreamManager(getConnection()); + List proxies = s5m.determineProxies(); + return determineStreamHostInfo(proxies); + } + + public List getLocalStreamHosts() { + return Socks5BytestreamManager.getBytestreamManager(getConnection()) + .getLocalStreamHost(); + } + + public List determineStreamHostInfo(List proxies) { + XMPPConnection connection = getConnection(); + List streamHosts = new ArrayList<>(); + + Iterator iterator = proxies.iterator(); + while (iterator.hasNext()) { + Jid proxy = iterator.next(); + Bytestream request = new Bytestream(); + request.setType(IQ.Type.get); + request.setTo(proxy); + try { + Bytestream response = connection.createStanzaCollectorAndSend(request).nextResultOrThrow(); + streamHosts.addAll(response.getStreamHosts()); + } + catch (Exception e) { + iterator.remove(); + } + } + + return streamHosts; + } +}