mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-27 14:32:06 +01:00
Progess
This commit is contained in:
parent
ad32393b61
commit
09548855dd
6 changed files with 164 additions and 12 deletions
|
@ -37,7 +37,7 @@ public class Socks5BytestreamSession implements BytestreamSession {
|
||||||
/* flag to indicate if this session is a direct or mediated connection */
|
/* flag to indicate if this session is a direct or mediated connection */
|
||||||
private final boolean isDirect;
|
private final boolean isDirect;
|
||||||
|
|
||||||
protected Socks5BytestreamSession(Socket socket, boolean isDirect) {
|
public Socks5BytestreamSession(Socket socket, boolean isDirect) {
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
this.isDirect = isDirect;
|
this.isDirect = isDirect;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ import org.jxmpp.jid.Jid;
|
||||||
*
|
*
|
||||||
* @author Henning Staib
|
* @author Henning Staib
|
||||||
*/
|
*/
|
||||||
class Socks5ClientForInitiator extends Socks5Client {
|
public class Socks5ClientForInitiator extends Socks5Client {
|
||||||
|
|
||||||
/* the XMPP connection used to communicate with the SOCKS5 proxy */
|
/* the XMPP connection used to communicate with the SOCKS5 proxy */
|
||||||
private WeakReference<XMPPConnection> connection;
|
private WeakReference<XMPPConnection> connection;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.jivesoftware.smackx.jingle.transports;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by vanitas on 25.06.17.
|
||||||
|
*/
|
||||||
|
public abstract class JingleTransportInitiationException extends Exception {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
|
||||||
|
public static class ProxyError extends JingleTransportInitiationException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CandidateError extends JingleTransportInitiationException {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,7 +45,6 @@ public abstract class JingleTransportManager<D extends JingleContentTransport> i
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void connected(XMPPConnection connection) {
|
public void connected(XMPPConnection connection) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
|
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.bytestreams.socks5.packet.Bytestream;
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
import org.jivesoftware.smackx.jingle.JingleSession;
|
||||||
import org.jivesoftware.smackx.jingle.element.Jingle;
|
import org.jivesoftware.smackx.jingle.element.Jingle;
|
||||||
|
@ -129,6 +130,10 @@ public final class JingleS5BTransportManager extends JingleTransportManager<Jing
|
||||||
@Override
|
@Override
|
||||||
public void authenticated(XMPPConnection connection, boolean resumed) {
|
public void authenticated(XMPPConnection connection, boolean resumed) {
|
||||||
if (!resumed) try {
|
if (!resumed) try {
|
||||||
|
Socks5Proxy socks5Proxy = Socks5Proxy.getSocks5Proxy();
|
||||||
|
if (!socks5Proxy.isRunning()) {
|
||||||
|
socks5Proxy.start();
|
||||||
|
}
|
||||||
localStreamHosts = queryLocalStreamHosts();
|
localStreamHosts = queryLocalStreamHosts();
|
||||||
availableStreamHosts = queryAvailableStreamHosts();
|
availableStreamHosts = queryAvailableStreamHosts();
|
||||||
} catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
|
} catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
|
||||||
|
@ -171,4 +176,5 @@ public final class JingleS5BTransportManager extends JingleTransportManager<Jing
|
||||||
|
|
||||||
return jingle;
|
return jingle;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,10 @@ import java.util.logging.Logger;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
||||||
|
import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession;
|
||||||
import org.jivesoftware.smackx.bytestreams.socks5.Socks5Client;
|
import org.jivesoftware.smackx.bytestreams.socks5.Socks5Client;
|
||||||
|
import org.jivesoftware.smackx.bytestreams.socks5.Socks5ClientForInitiator;
|
||||||
import org.jivesoftware.smackx.bytestreams.socks5.Socks5Utils;
|
import org.jivesoftware.smackx.bytestreams.socks5.Socks5Utils;
|
||||||
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
|
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
|
||||||
import org.jivesoftware.smackx.jingle.JingleManager;
|
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||||
|
@ -36,10 +39,12 @@ import org.jivesoftware.smackx.jingle.element.Jingle;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContent;
|
import org.jivesoftware.smackx.jingle.element.JingleContent;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentTransportCandidate;
|
import org.jivesoftware.smackx.jingle.element.JingleContentTransportCandidate;
|
||||||
import org.jivesoftware.smackx.jingle.transports.JingleTransportInitiationCallback;
|
import org.jivesoftware.smackx.jingle.transports.JingleTransportInitiationCallback;
|
||||||
|
import org.jivesoftware.smackx.jingle.transports.JingleTransportInitiationException;
|
||||||
import org.jivesoftware.smackx.jingle.transports.JingleTransportManager;
|
import org.jivesoftware.smackx.jingle.transports.JingleTransportManager;
|
||||||
import org.jivesoftware.smackx.jingle.transports.JingleTransportSession;
|
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.elements.JingleS5BTransport;
|
||||||
import org.jivesoftware.smackx.jingle.transports.jingle_s5b.elements.JingleS5BTransportCandidate;
|
import org.jivesoftware.smackx.jingle.transports.jingle_s5b.elements.JingleS5BTransportCandidate;
|
||||||
|
import org.jivesoftware.smackx.jingle.transports.jingle_s5b.elements.JingleS5BTransportInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LOL.
|
* LOL.
|
||||||
|
@ -49,7 +54,11 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
|
||||||
private final JingleS5BTransportManager transportManager;
|
private final JingleS5BTransportManager transportManager;
|
||||||
|
|
||||||
private Socket connectedSocket;
|
private Socket connectedSocket;
|
||||||
private JingleS5BTransportCandidate usedCandidate;
|
private JingleS5BTransportCandidate localUsedCandidate;
|
||||||
|
private JingleS5BTransportCandidate remoteUsedCandidate;
|
||||||
|
private JingleTransportInitiationCallback callback;
|
||||||
|
private boolean remoteError = false;
|
||||||
|
private boolean localError = false;
|
||||||
|
|
||||||
public JingleS5BTransportSession(JingleSession jingleSession) {
|
public JingleS5BTransportSession(JingleSession jingleSession) {
|
||||||
super(jingleSession);
|
super(jingleSession);
|
||||||
|
@ -66,6 +75,11 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
|
||||||
}
|
}
|
||||||
|
|
||||||
private JingleS5BTransport createTransport(String sid, Bytestream.Mode mode) {
|
private JingleS5BTransport createTransport(String sid, Bytestream.Mode mode) {
|
||||||
|
JingleSession jSession = jingleSession.get();
|
||||||
|
if (jSession == null) {
|
||||||
|
throw new NullPointerException("Lost reference to JingleSession.");
|
||||||
|
}
|
||||||
|
|
||||||
JingleS5BTransport.Builder builder = JingleS5BTransport.getBuilder();
|
JingleS5BTransport.Builder builder = JingleS5BTransport.getBuilder();
|
||||||
|
|
||||||
for (Bytestream.StreamHost host : transportManager.getLocalStreamHosts()) {
|
for (Bytestream.StreamHost host : transportManager.getLocalStreamHosts()) {
|
||||||
|
@ -77,7 +91,8 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
|
||||||
|
|
||||||
try {
|
try {
|
||||||
availableStreamHosts = transportManager.getAvailableStreamHosts();
|
availableStreamHosts = transportManager.getAvailableStreamHosts();
|
||||||
} catch (XMPPException.XMPPErrorException | SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException e) {
|
} catch (XMPPException.XMPPErrorException | SmackException.NoResponseException | InterruptedException |
|
||||||
|
SmackException.NotConnectedException e) {
|
||||||
LOGGER.log(Level.WARNING, "Could not get available StreamHosts: " + e, e);
|
LOGGER.log(Level.WARNING, "Could not get available StreamHosts: " + e, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,12 +104,23 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
|
||||||
|
|
||||||
builder.setStreamId(sid);
|
builder.setStreamId(sid);
|
||||||
builder.setMode(mode);
|
builder.setMode(mode);
|
||||||
builder.setDestinationAddress(Socks5Utils.createDigest(sid, jingleSession.get().getLocal(), jingleSession.get().getRemote()));
|
builder.setDestinationAddress(Socks5Utils.createDigest(sid, jSession.getLocal(), jSession.getRemote()));
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initiateOutgoingSession(JingleTransportInitiationCallback callback) {
|
public void initiateOutgoingSession(JingleTransportInitiationCallback callback) {
|
||||||
|
this.callback = callback;
|
||||||
|
initiateSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initiateIncomingSession(JingleTransportInitiationCallback callback) {
|
||||||
|
this.callback = callback;
|
||||||
|
initiateSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initiateSession() {
|
||||||
JingleSession jSession = jingleSession.get();
|
JingleSession jSession = jingleSession.get();
|
||||||
if (jSession == null) {
|
if (jSession == null) {
|
||||||
throw new NullPointerException("Lost reference to jingleSession.");
|
throw new NullPointerException("Lost reference to jingleSession.");
|
||||||
|
@ -127,17 +153,17 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
|
||||||
|
|
||||||
if (socket != null) {
|
if (socket != null) {
|
||||||
connectedSocket = socket;
|
connectedSocket = socket;
|
||||||
usedCandidate = workedForUs;
|
localUsedCandidate = workedForUs;
|
||||||
|
|
||||||
response = transportManager.createCandidateUsed(jSession.getRemote(),
|
response = transportManager.createCandidateUsed(jSession.getRemote(),
|
||||||
jSession.getSessionId(), content.getSenders(), content.getCreator(),
|
jSession.getSessionId(), content.getSenders(), content.getCreator(),
|
||||||
content.getName(), receivedTransport.getStreamId(), usedCandidate.getCandidateId());
|
content.getName(), receivedTransport.getStreamId(), localUsedCandidate.getCandidateId());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
localError = true;
|
||||||
response = transportManager.createCandidateError(jSession.getRemote(),
|
response = transportManager.createCandidateError(jSession.getRemote(),
|
||||||
jSession.getSessionId(), content.getSenders(), content.getCreator(),
|
jSession.getSessionId(), content.getSenders(), content.getCreator(),
|
||||||
content.getName(), receivedTransport.getStreamId());
|
content.getName(), receivedTransport.getStreamId());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -145,12 +171,90 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
|
||||||
} catch (SmackException.NotConnectedException | InterruptedException e) {
|
} catch (SmackException.NotConnectedException | InterruptedException e) {
|
||||||
LOGGER.log(Level.WARNING, "Could not send candidate-used.", e);
|
LOGGER.log(Level.WARNING, "Could not send candidate-used.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closeIfBothSidesFailed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private boolean closeIfBothSidesFailed() {
|
||||||
public void initiateIncomingSession(JingleTransportInitiationCallback callback) {
|
JingleSession jSession = jingleSession.get();
|
||||||
|
if (jSession != null) {
|
||||||
|
if (localError && remoteError) {
|
||||||
|
callback.onException(new JingleTransportInitiationException.CandidateError());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private JingleS5BTransportCandidate determineUsedCandidate() {
|
||||||
|
if (localUsedCandidate == null && remoteUsedCandidate == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remoteUsedCandidate == null) {
|
||||||
|
return localUsedCandidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localUsedCandidate == null) {
|
||||||
|
return remoteUsedCandidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localUsedCandidate.getPriority() > remoteUsedCandidate.getPriority()) {
|
||||||
|
return localUsedCandidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localUsedCandidate.getPriority() < remoteUsedCandidate.getPriority()) {
|
||||||
|
return remoteUsedCandidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return jingleSession.get().isInitiator() ? localUsedCandidate : remoteUsedCandidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ handleCandidateUsed(Jingle candidateUsed) {
|
||||||
|
JingleS5BTransportInfo info = (JingleS5BTransportInfo) candidateUsed.getContents().get(0)
|
||||||
|
.getJingleTransport().getInfos().get(0);
|
||||||
|
|
||||||
|
String candidateId = ((JingleS5BTransportInfo.CandidateUsed) info).getCandidateId();
|
||||||
|
|
||||||
|
for (JingleContentTransportCandidate c : localTransport.getCandidates()) {
|
||||||
|
JingleS5BTransportCandidate candidate = (JingleS5BTransportCandidate) c;
|
||||||
|
if (candidate.getCandidateId().equals(candidateId)) {
|
||||||
|
remoteUsedCandidate = candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remoteUsedCandidate == null) {
|
||||||
|
callback.onException(new Exception("Unknown candidate"));
|
||||||
|
return IQ.createResultIQ(candidateUsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localUsedCandidate != null) {
|
||||||
|
JingleS5BTransportCandidate used = determineUsedCandidate();
|
||||||
|
|
||||||
|
// Our candidate is nominated.
|
||||||
|
if (used == remoteUsedCandidate) {
|
||||||
|
|
||||||
|
if (used.getType() == JingleS5BTransportCandidate.Type.proxy) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
callback.onSessionInitiated();
|
||||||
|
}
|
||||||
|
// Remotes candidate is nominated.
|
||||||
|
else {
|
||||||
|
if (connectedSocket != null) {
|
||||||
|
callback.onSessionInitiated(new Socks5BytestreamSession(connectedSocket,
|
||||||
|
used.getJid().asBareJid().equals(jingleSession.get().getRemote().asBareJid())));
|
||||||
|
} else {
|
||||||
|
throw new AssertionError("Connected socket is null.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IQ.createResultIQ(candidateUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -160,7 +264,33 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IQ handleTransportInfo(Jingle transportInfo) {
|
public IQ handleTransportInfo(Jingle transportInfo) {
|
||||||
return null;
|
JingleS5BTransport transport = (JingleS5BTransport) transportInfo.getContents().get(0).getJingleTransport();
|
||||||
|
JingleS5BTransportInfo info = (JingleS5BTransportInfo) transport.getInfos().get(0);
|
||||||
|
if (info != null) {
|
||||||
|
switch (info.getElementName()) {
|
||||||
|
|
||||||
|
case JingleS5BTransportInfo.CandidateUsed.ELEMENT:
|
||||||
|
return handleCandidateUsed(transportInfo);
|
||||||
|
|
||||||
|
case JingleS5BTransportInfo.CandidateActivated.ELEMENT:
|
||||||
|
|
||||||
|
case JingleS5BTransportInfo.CandidateError.ELEMENT:
|
||||||
|
remoteError = true;
|
||||||
|
|
||||||
|
closeIfBothSidesFailed();
|
||||||
|
|
||||||
|
if (localUsedCandidate.getType() != JingleS5BTransportCandidate.Type.proxy) {
|
||||||
|
//TODO: Connect
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JingleS5BTransportInfo.ProxyError.ELEMENT:
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue