JingleS5BTransportManager.java
- /**
- *
- * 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 java.util.logging.Level;
- import java.util.logging.Logger;
- 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.Socks5Proxy;
- import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
- import org.jivesoftware.smackx.jingle.JingleSession;
- 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.provider.JingleContentProviderManager;
- import org.jivesoftware.smackx.jingle.transports.JingleTransportManager;
- import org.jivesoftware.smackx.jingle.transports.JingleTransportSession;
- import org.jivesoftware.smackx.jingle.transports.jingle_s5b.elements.JingleS5BTransport;
- import org.jivesoftware.smackx.jingle.transports.jingle_s5b.provider.JingleS5BTransportProvider;
- import org.jxmpp.jid.FullJid;
- import org.jxmpp.jid.Jid;
- /**
- * Manager for Jingle SOCKS5 Bytestream transports (XEP-0261).
- */
- public final class JingleS5BTransportManager extends JingleTransportManager<JingleS5BTransport> {
- private static final Logger LOGGER = Logger.getLogger(JingleS5BTransportManager.class.getName());
- private static final WeakHashMap<XMPPConnection, JingleS5BTransportManager> INSTANCES = new WeakHashMap<>();
- private List<Bytestream.StreamHost> localStreamHosts = null;
- private List<Bytestream.StreamHost> availableStreamHosts = null;
- private static boolean useLocalCandidates = true;
- private static boolean useExternalCandidates = true;
- private JingleS5BTransportManager(XMPPConnection connection) {
- super(connection);
- JingleContentProviderManager.addJingleContentTransportProvider(getNamespace(), new JingleS5BTransportProvider());
- }
- public static synchronized 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 JingleTransportSession<JingleS5BTransport> transportSession(JingleSession jingleSession) {
- return new JingleS5BTransportSession(jingleSession);
- }
- private List<Bytestream.StreamHost> queryAvailableStreamHosts() throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
- Socks5BytestreamManager s5m = Socks5BytestreamManager.getBytestreamManager(getConnection());
- List<Jid> proxies = s5m.determineProxies();
- return determineStreamHostInfo(proxies);
- }
- private List<Bytestream.StreamHost> queryLocalStreamHosts() {
- return Socks5BytestreamManager.getBytestreamManager(getConnection())
- .getLocalStreamHost();
- }
- public List<Bytestream.StreamHost> getAvailableStreamHosts() throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
- if (availableStreamHosts == null) {
- availableStreamHosts = queryAvailableStreamHosts();
- }
- return availableStreamHosts;
- }
- public List<Bytestream.StreamHost> getLocalStreamHosts() {
- if (localStreamHosts == null) {
- localStreamHosts = queryLocalStreamHosts();
- }
- return localStreamHosts;
- }
- public List<Bytestream.StreamHost> determineStreamHostInfo(List<Jid> proxies) {
- XMPPConnection connection = getConnection();
- List<Bytestream.StreamHost> streamHosts = new ArrayList<>();
- Iterator<Jid> 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.sendIqRequestAndWaitForResponse(request);
- streamHosts.addAll(response.getStreamHosts());
- }
- catch (Exception e) {
- iterator.remove();
- }
- }
- return streamHosts;
- }
- @Override
- public void authenticated(XMPPConnection connection, boolean resumed) {
- if (!resumed) try {
- Socks5Proxy socks5Proxy = Socks5Proxy.getSocks5Proxy();
- if (!socks5Proxy.isRunning()) {
- socks5Proxy.start();
- }
- localStreamHosts = queryLocalStreamHosts();
- availableStreamHosts = queryAvailableStreamHosts();
- } catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
- LOGGER.log(Level.WARNING, "Could not query available StreamHosts: " + e, e);
- }
- }
- public Jingle createCandidateUsed(FullJid recipient, FullJid initiator, String sessionId, JingleContent.Senders contentSenders,
- JingleContent.Creator contentCreator, String contentName, String streamId,
- String candidateId) {
- Jingle.Builder jb = Jingle.builder(connection());
- jb.setSessionId(sessionId).setInitiator(initiator).setAction(JingleAction.transport_info);
- JingleContent.Builder cb = JingleContent.getBuilder();
- cb.setName(contentName).setCreator(contentCreator).setSenders(contentSenders);
- JingleS5BTransport.Builder tb = JingleS5BTransport.getBuilder();
- tb.setCandidateUsed(candidateId).setStreamId(streamId);
- Jingle jingle = jb.addJingleContent(cb.setTransport(tb.build()).build()).build();
- jingle.setFrom(getConnection().getUser().asFullJidOrThrow());
- jingle.setTo(recipient);
- return jingle;
- }
- public Jingle createCandidateError(FullJid remote, FullJid initiator, String sessionId, JingleContent.Senders senders, JingleContent.Creator creator, String name, String streamId) {
- Jingle.Builder jb = Jingle.builder(connection());
- jb.setSessionId(sessionId).setInitiator(initiator).setAction(JingleAction.transport_info);
- JingleContent.Builder cb = JingleContent.getBuilder();
- cb.setName(name).setCreator(creator).setSenders(senders);
- JingleS5BTransport.Builder tb = JingleS5BTransport.getBuilder();
- tb.setCandidateError().setStreamId(streamId);
- Jingle jingle = jb.addJingleContent(cb.setTransport(tb.build()).build()).build();
- jingle.setFrom(getConnection().getUser().asFullJidOrThrow());
- jingle.setTo(remote);
- return jingle;
- }
- public Jingle createProxyError(FullJid remote, FullJid initiator, String sessionId,
- JingleContent.Senders senders, JingleContent.Creator creator,
- String name, String streamId) {
- Jingle.Builder jb = Jingle.builder(connection());
- jb.setSessionId(sessionId).setAction(JingleAction.transport_info).setInitiator(initiator);
- JingleContent.Builder cb = JingleContent.getBuilder();
- cb.setSenders(senders).setCreator(creator).setName(name);
- JingleS5BTransport.Builder tb = JingleS5BTransport.getBuilder();
- tb.setStreamId(sessionId).setProxyError().setStreamId(streamId);
- Jingle jingle = jb.addJingleContent(cb.setTransport(tb.build()).build()).build();
- jingle.setTo(remote);
- jingle.setFrom(getConnection().getUser().asFullJidOrThrow());
- return jingle;
- }
- public Jingle createCandidateActivated(FullJid remote, FullJid initiator, String sessionId,
- JingleContent.Senders senders, JingleContent.Creator creator,
- String name, String streamId, String candidateId) {
- Jingle.Builder jb = Jingle.builder(connection());
- jb.setInitiator(initiator).setSessionId(sessionId).setAction(JingleAction.transport_info);
- JingleContent.Builder cb = JingleContent.getBuilder();
- cb.setName(name).setCreator(creator).setSenders(senders);
- JingleS5BTransport.Builder tb = JingleS5BTransport.getBuilder();
- tb.setStreamId(streamId).setCandidateActivated(candidateId);
- Jingle jingle = jb.addJingleContent(cb.setTransport(tb.build()).build()).build();
- jingle.setFrom(getConnection().getUser().asFullJidOrThrow());
- jingle.setTo(remote);
- return jingle;
- }
- public static void setUseLocalCandidates(boolean localCandidates) {
- JingleS5BTransportManager.useLocalCandidates = localCandidates;
- }
- public static void setUseExternalCandidates(boolean externalCandidates) {
- JingleS5BTransportManager.useExternalCandidates = externalCandidates;
- }
- public static boolean isUseLocalCandidates() {
- return useLocalCandidates;
- }
- public static boolean isUseExternalCandidates() {
- return useExternalCandidates;
- }
- }