Progress on Transports

This commit is contained in:
vanitasvitae 2017-07-21 17:58:57 +02:00
parent f4a910cfa5
commit c448d07234
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
10 changed files with 218 additions and 46 deletions

View File

@ -22,7 +22,7 @@ import org.jivesoftware.smackx.jingle3.element.JingleContentTransportElement;
*/ */
public class Content { public class Content {
private Session session; private Session parent;
private JingleContentElement.Creator creator; private JingleContentElement.Creator creator;
private String name; private String name;
private String disposition; private String disposition;
@ -117,28 +117,49 @@ public class Content {
return senders; return senders;
} }
public Description getDescription() { public void setParent(Session session) {
if (this.parent != session) {
this.parent = session;
}
}
public Session getParent() {
return parent;
}
public Description<?> getDescription() {
return description; return description;
} }
public void setDescription(Description<?> description) {
if (this.description != description) {
this.description = description;
description.setParent(this);
}
}
public Transport<?> getTransport() { public Transport<?> getTransport() {
return transport; return transport;
} }
public void setTransport(Transport<?> transport) { public void setTransport(Transport<?> transport) {
this.transport = transport; if (this.transport != transport) {
} this.transport = transport;
transport.setParent(this);
public void setSession(Session session) {
if (this.session != session) {
this.session = session;
} }
} }
public Security getSecurity() { public Security<?> getSecurity() {
return security; return security;
} }
public void setSecurity(Security<?> security) {
if (this.security != security) {
this.security = security;
security.setParent(this);
}
}
public static String randomName() { public static String randomName() {
return "cont-" + StringUtils.randomString(16); return "cont-" + StringUtils.randomString(16);
} }

View File

@ -7,5 +7,17 @@ import org.jivesoftware.smackx.jingle3.element.JingleContentDescriptionElement;
*/ */
public abstract class Description<D extends JingleContentDescriptionElement> { public abstract class Description<D extends JingleContentDescriptionElement> {
private Content parent;
public abstract D getElement(); public abstract D getElement();
public void setParent(Content parent) {
if (this.parent != parent) {
this.parent = parent;
}
}
public Content getParent() {
return parent;
}
} }

View File

@ -9,7 +9,19 @@ import org.jivesoftware.smackx.jingle3.element.JingleContentSecurityInfoElement;
*/ */
public abstract class Security<D extends JingleContentSecurityElement> { public abstract class Security<D extends JingleContentSecurityElement> {
private Content parent;
public abstract D getElement(); public abstract D getElement();
public abstract JingleElement handleSecurityInfo(JingleContentSecurityInfoElement element); public abstract JingleElement handleSecurityInfo(JingleContentSecurityInfoElement element);
public void setParent(Content parent) {
if (this.parent != parent) {
this.parent = parent;
}
}
public Content getParent() {
return parent;
}
} }

View File

@ -57,7 +57,7 @@ public class Session {
void addContent(Content content) { void addContent(Content content) {
contents.put(content.getName(), content); contents.put(content.getName(), content);
content.setSession(this); content.setParent(this);
} }
void addContent(JingleContentElement content) void addContent(JingleContentElement content)

View File

@ -1,5 +1,8 @@
package org.jivesoftware.smackx.jingle3.internal; package org.jivesoftware.smackx.jingle3.internal;
import java.util.ArrayList;
import java.util.List;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smackx.jingle3.element.JingleContentTransportElement; import org.jivesoftware.smackx.jingle3.element.JingleContentTransportElement;
import org.jivesoftware.smackx.jingle3.element.JingleContentTransportInfoElement; import org.jivesoftware.smackx.jingle3.element.JingleContentTransportInfoElement;
@ -12,8 +15,45 @@ import org.jxmpp.jid.FullJid;
*/ */
public abstract class Transport<D extends JingleContentTransportElement> { public abstract class Transport<D extends JingleContentTransportElement> {
private Content parent;
private final ArrayList<TransportCandidate<?>> candidates = new ArrayList<>();
private Transport peersProposal;
private boolean isPeersProposal;
public abstract D getElement(); public abstract D getElement();
public void addCandidate(TransportCandidate<?> candidate) {
// Insert sorted by priority descending
// Empty list -> insert
if (candidates.isEmpty()) {
candidates.add(candidate);
candidate.setParent(this);
return;
}
// Find appropriate index
for (int i = 0; i < candidates.size(); i++) {
TransportCandidate<?> c = candidates.get(i);
// list already contains element -> return
if (c == candidate) {
return;
}
//Found the index
if (c.getPriority() <= candidate.getPriority()) {
candidates.add(i, candidate);
candidate.setParent(this);
}
}
}
public List<TransportCandidate<?>> getCandidates() {
return candidates;
}
public abstract String getNamespace(); public abstract String getNamespace();
public abstract void establishIncomingBytestreamSession(FullJid peer, public abstract void establishIncomingBytestreamSession(FullJid peer,
@ -26,7 +66,24 @@ public abstract class Transport<D extends JingleContentTransportElement> {
BytestreamSessionEstablishedListener listener, BytestreamSessionEstablishedListener listener,
XMPPConnection connection); XMPPConnection connection);
public abstract void setPeersProposal(Transport<?> peersProposal); public void setPeersProposal(Transport peersProposal) {
this.peersProposal = peersProposal;
peersProposal.isPeersProposal = true;
}
public boolean isPeersProposal() {
return isPeersProposal;
}
public abstract void handleTransportInfo(JingleContentTransportInfoElement info); public abstract void handleTransportInfo(JingleContentTransportInfoElement info);
public void setParent(Content parent) {
if (this.parent != parent) {
this.parent = parent;
}
}
public Content getParent() {
return parent;
}
} }

View File

@ -0,0 +1,32 @@
package org.jivesoftware.smackx.jingle3.internal;
import org.jivesoftware.smackx.jingle3.element.JingleContentTransportCandidateElement;
/**
* Created by vanitas on 21.07.17.
*/
public abstract class TransportCandidate<E extends JingleContentTransportCandidateElement> {
private Transport<?> parent;
private int priority;
public void setParent(Transport<?> transport) {
if (parent != transport) {
parent = transport;
}
}
public Transport<?> getParent() {
return parent;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public abstract E getElement();
}

View File

@ -10,6 +10,7 @@ import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
import org.jivesoftware.smackx.jingle3.element.JingleContentTransportInfoElement; import org.jivesoftware.smackx.jingle3.element.JingleContentTransportInfoElement;
import org.jivesoftware.smackx.jingle3.internal.Transport; import org.jivesoftware.smackx.jingle3.internal.Transport;
import org.jivesoftware.smackx.jingle3.internal.TransportCandidate;
import org.jivesoftware.smackx.jingle3.transport.BytestreamSessionEstablishedListener; import org.jivesoftware.smackx.jingle3.transport.BytestreamSessionEstablishedListener;
import org.jivesoftware.smackx.jingle3.transport.jingle_ibb.element.JingleIBBTransportElement; import org.jivesoftware.smackx.jingle3.transport.jingle_ibb.element.JingleIBBTransportElement;
@ -26,8 +27,6 @@ public class JingleIBBTransport extends Transport<JingleIBBTransportElement> {
private final String streamId; private final String streamId;
private final Short blockSize; private final Short blockSize;
private JingleIBBTransport peersProposal;
public JingleIBBTransport(String streamId, Short blockSize) { public JingleIBBTransport(String streamId, Short blockSize) {
this.streamId = streamId; this.streamId = streamId;
this.blockSize = blockSize; this.blockSize = blockSize;
@ -82,12 +81,13 @@ public class JingleIBBTransport extends Transport<JingleIBBTransportElement> {
} }
@Override @Override
public void setPeersProposal(Transport<?> peersProposal) { public void addCandidate(TransportCandidate<?> candidate) {
this.peersProposal = (JingleIBBTransport) peersProposal; // Sorry, we don't want any candidates.
} }
@Override @Override
public void handleTransportInfo(JingleContentTransportInfoElement info) { public void handleTransportInfo(JingleContentTransportInfoElement info) {
// Nothing to do. // Nothing to do.
} }
} }

View File

@ -1,13 +1,14 @@
package org.jivesoftware.smackx.jingle3.transport.jingle_s5b; package org.jivesoftware.smackx.jingle3.transport.jingle_s5b;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
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.jingle3.element.JingleContentTransportInfoElement; import org.jivesoftware.smackx.jingle3.element.JingleContentTransportInfoElement;
import org.jivesoftware.smackx.jingle3.internal.Transport; import org.jivesoftware.smackx.jingle3.internal.Transport;
import org.jivesoftware.smackx.jingle3.internal.TransportCandidate;
import org.jivesoftware.smackx.jingle3.transport.BytestreamSessionEstablishedListener; import org.jivesoftware.smackx.jingle3.transport.BytestreamSessionEstablishedListener;
import org.jivesoftware.smackx.jingle3.transport.jingle_s5b.elements.JingleS5BTransportCandidateElement; import org.jivesoftware.smackx.jingle3.transport.jingle_s5b.elements.JingleS5BTransportCandidateElement;
import org.jivesoftware.smackx.jingle3.transport.jingle_s5b.elements.JingleS5BTransportElement; import org.jivesoftware.smackx.jingle3.transport.jingle_s5b.elements.JingleS5BTransportElement;
@ -27,11 +28,8 @@ public class JingleS5BTransport extends Transport<JingleS5BTransportElement> {
private String dstAddr; private String dstAddr;
private Bytestream.Mode mode; private Bytestream.Mode mode;
private HashMap<String, JingleS5BTransportCandidate> candidates = new HashMap<>();
private String peerDstAddr; private JingleS5BTransport peersProposal;
private Bytestream.Mode peerMode;
private HashMap<String, JingleS5BTransportCandidate> peerCandidates;
private JingleS5BTransportCandidate ourChoice, theirChoice; private JingleS5BTransportCandidate ourChoice, theirChoice;
private JingleS5BTransportCandidate nominee; private JingleS5BTransportCandidate nominee;
@ -41,9 +39,9 @@ public class JingleS5BTransport extends Transport<JingleS5BTransportElement> {
this.dstAddr = dstAddr; this.dstAddr = dstAddr;
this.mode = mode; this.mode = mode;
for (JingleS5BTransportCandidate c : (candidates != null ? for (TransportCandidate<JingleS5BTransportCandidateElement> c : (candidates != null ?
candidates : Collections.<JingleS5BTransportCandidate>emptySet())) { candidates : Collections.<JingleS5BTransportCandidate>emptySet())) {
this.candidates.put(c.getCandidateId(), c); addCandidate(c);
} }
} }
@ -54,14 +52,21 @@ public class JingleS5BTransport extends Transport<JingleS5BTransportElement> {
.setDestinationAddress(dstAddr) .setDestinationAddress(dstAddr)
.setMode(mode); .setMode(mode);
for (JingleS5BTransportCandidate candidate : candidates.values()) { for (TransportCandidate candidate : getCandidates()) {
builder.addTransportCandidate( builder.addTransportCandidate((JingleS5BTransportCandidateElement) candidate.getElement());
(JingleS5BTransportCandidateElement) candidate.getElement());
} }
return builder.build(); return builder.build();
} }
public String getDstAddr() {
return dstAddr;
}
public Bytestream.Mode getMode() {
return mode;
}
@Override @Override
public String getNamespace() { public String getNamespace() {
return NAMESPACE; return NAMESPACE;
@ -69,7 +74,7 @@ public class JingleS5BTransport extends Transport<JingleS5BTransportElement> {
@Override @Override
public void establishIncomingBytestreamSession(FullJid peer, String transportSessionId, BytestreamSessionEstablishedListener listener, XMPPConnection connection) { public void establishIncomingBytestreamSession(FullJid peer, String transportSessionId, BytestreamSessionEstablishedListener listener, XMPPConnection connection) {
Socks5Proxy.getSocks5Proxy().addTransfer(dstAddr);
} }
@Override @Override
@ -77,14 +82,6 @@ public class JingleS5BTransport extends Transport<JingleS5BTransportElement> {
} }
@Override
public void setPeersProposal(Transport<?> peersProposal) {
JingleS5BTransport transport = (JingleS5BTransport) peersProposal;
peerCandidates = transport.candidates;
peerDstAddr = transport.dstAddr;
peerMode = transport.mode;
}
@Override @Override
public void handleTransportInfo(JingleContentTransportInfoElement info) { public void handleTransportInfo(JingleContentTransportInfoElement info) {
switch (info.getElementName()) { switch (info.getElementName()) {
@ -112,7 +109,6 @@ public class JingleS5BTransport extends Transport<JingleS5BTransportElement> {
private void handleCandidateUsed(JingleS5BTransportInfoElement info) { private void handleCandidateUsed(JingleS5BTransportInfoElement info) {
String candidateId = ((JingleS5BTransportInfoElement.CandidateUsed) info).getCandidateId(); String candidateId = ((JingleS5BTransportInfoElement.CandidateUsed) info).getCandidateId();
theirChoice = candidates.get(candidateId);
if (theirChoice == null) { if (theirChoice == null) {
/* /*

View File

@ -1,7 +1,12 @@
package org.jivesoftware.smackx.jingle3.transport.jingle_s5b; package org.jivesoftware.smackx.jingle3.transport.jingle_s5b;
import java.util.ArrayList;
import org.jivesoftware.smackx.jingle3.adapter.JingleTransportAdapter; import org.jivesoftware.smackx.jingle3.adapter.JingleTransportAdapter;
import org.jivesoftware.smackx.jingle3.element.JingleContentTransportCandidateElement;
import org.jivesoftware.smackx.jingle3.element.JingleContentTransportElement; import org.jivesoftware.smackx.jingle3.element.JingleContentTransportElement;
import org.jivesoftware.smackx.jingle3.transport.jingle_s5b.elements.JingleS5BTransportCandidateElement;
import org.jivesoftware.smackx.jingle3.transport.jingle_s5b.elements.JingleS5BTransportElement;
/** /**
* Created by vanitas on 19.07.17. * Created by vanitas on 19.07.17.
@ -10,7 +15,14 @@ public class JingleS5BTransportAdapter implements JingleTransportAdapter<JingleS
@Override @Override
public JingleS5BTransport transportFromElement(JingleContentTransportElement element) { public JingleS5BTransport transportFromElement(JingleContentTransportElement element) {
JingleS5BTransport transport = new JingleS5BTransport(); JingleS5BTransportElement s5b = (JingleS5BTransportElement) element;
ArrayList<JingleS5BTransportCandidate> candidates = new ArrayList<>();
for (JingleContentTransportCandidateElement e : element.getCandidates()) {
candidates.add(JingleS5BTransportCandidate.fromElement((JingleS5BTransportCandidateElement) e));
}
return new JingleS5BTransport(s5b.getSid(), s5b.getDestinationAddress(), s5b.getMode(), candidates);
} }
@Override @Override

View File

@ -1,27 +1,42 @@
package org.jivesoftware.smackx.jingle3.transport.jingle_s5b; package org.jivesoftware.smackx.jingle3.transport.jingle_s5b;
import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.TimeoutException;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.bytestreams.socks5.Socks5Client;
import org.jivesoftware.smackx.bytestreams.socks5.Socks5ClientForInitiator;
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
import org.jivesoftware.smackx.jingle3.element.JingleContentTransportCandidateElement; import org.jivesoftware.smackx.jingle3.internal.Session;
import org.jivesoftware.smackx.jingle3.internal.TransportCandidate;
import org.jivesoftware.smackx.jingle3.transport.jingle_s5b.elements.JingleS5BTransportCandidateElement; import org.jivesoftware.smackx.jingle3.transport.jingle_s5b.elements.JingleS5BTransportCandidateElement;
/** /**
* Created by vanitas on 19.07.17. * Created by vanitas on 19.07.17.
*/ */
public class JingleS5BTransportCandidate { public class JingleS5BTransportCandidate extends TransportCandidate<JingleS5BTransportCandidateElement> {
private final String candidateId; private final String candidateId;
private final Bytestream.StreamHost streamHost; private final Bytestream.StreamHost streamHost;
private final int priority;
private final JingleS5BTransportCandidateElement.Type type; private final JingleS5BTransportCandidateElement.Type type;
private Socket socket;
public JingleS5BTransportCandidate(String candidateId, public JingleS5BTransportCandidate(String candidateId,
Bytestream.StreamHost streamHost, Bytestream.StreamHost streamHost,
int priority, int priority,
JingleS5BTransportCandidateElement.Type type) { JingleS5BTransportCandidateElement.Type type) {
this.candidateId = candidateId; this.candidateId = candidateId;
this.streamHost = streamHost; this.streamHost = streamHost;
this.priority = priority;
this.type = type; this.type = type;
setPriority(priority);
}
public static JingleS5BTransportCandidate fromElement(JingleS5BTransportCandidateElement element) {
return new JingleS5BTransportCandidate(element.getCandidateId(), element.getStreamHost(), element.getPriority(), element.getType());
} }
public String getCandidateId() { public String getCandidateId() {
@ -32,15 +47,30 @@ public class JingleS5BTransportCandidate {
return streamHost; return streamHost;
} }
public int getPriority() {
return priority;
}
public JingleS5BTransportCandidateElement.Type getType() { public JingleS5BTransportCandidateElement.Type getType() {
return type; return type;
} }
public JingleContentTransportCandidateElement getElement() { public JingleS5BTransportCandidateElement getElement() {
return new JingleS5BTransportCandidateElement(candidateId, streamHost.getAddress(), streamHost.getJID(), streamHost.getPort(), priority, type); return new JingleS5BTransportCandidateElement(
getCandidateId(), getStreamHost().getAddress(),
getStreamHost().getJID(), getStreamHost().getPort(),
getPriority(), getType());
}
public Socket connect(int timeout) throws InterruptedException, TimeoutException, SmackException, XMPPException, IOException {
Socks5Client client;
if (getParent().isPeersProposal()) {
client = new Socks5Client(getStreamHost(), ((JingleS5BTransport) getParent()).getDstAddr());
}
else {
Session session = getParent().getParent().getParent();
client = new Socks5ClientForInitiator(getStreamHost(), ((JingleS5BTransport) getParent()).getDstAddr(),
session.getJingleManager().getConnection(), session.getSessionId(), session.getPeer());
}
this.socket = client.getSocket(timeout);
return socket;
} }
} }