diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Content.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Content.java index e0b341e8d..ab060984e 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Content.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Content.java @@ -22,7 +22,7 @@ import org.jivesoftware.smackx.jingle3.element.JingleContentTransportElement; */ public class Content { - private Session session; + private Session parent; private JingleContentElement.Creator creator; private String name; private String disposition; @@ -117,28 +117,49 @@ public class Content { 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; } + public void setDescription(Description description) { + if (this.description != description) { + this.description = description; + description.setParent(this); + } + } + public Transport getTransport() { return transport; } public void setTransport(Transport transport) { - this.transport = transport; - } - - public void setSession(Session session) { - if (this.session != session) { - this.session = session; + if (this.transport != transport) { + this.transport = transport; + transport.setParent(this); } } - public Security getSecurity() { + public Security getSecurity() { return security; } + public void setSecurity(Security security) { + if (this.security != security) { + this.security = security; + security.setParent(this); + } + } + public static String randomName() { return "cont-" + StringUtils.randomString(16); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Description.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Description.java index d3d5a678b..1c04b967c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Description.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Description.java @@ -7,5 +7,17 @@ import org.jivesoftware.smackx.jingle3.element.JingleContentDescriptionElement; */ public abstract class Description { + private Content parent; + public abstract D getElement(); + + public void setParent(Content parent) { + if (this.parent != parent) { + this.parent = parent; + } + } + + public Content getParent() { + return parent; + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Security.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Security.java index 719bdc0d7..2917a9409 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Security.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Security.java @@ -9,7 +9,19 @@ import org.jivesoftware.smackx.jingle3.element.JingleContentSecurityInfoElement; */ public abstract class Security { + private Content parent; + public abstract D getElement(); public abstract JingleElement handleSecurityInfo(JingleContentSecurityInfoElement element); + + public void setParent(Content parent) { + if (this.parent != parent) { + this.parent = parent; + } + } + + public Content getParent() { + return parent; + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Session.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Session.java index 3d85bb986..c676c2ad1 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Session.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Session.java @@ -57,7 +57,7 @@ public class Session { void addContent(Content content) { contents.put(content.getName(), content); - content.setSession(this); + content.setParent(this); } void addContent(JingleContentElement content) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Transport.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Transport.java index e24d68300..678d63db2 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Transport.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/Transport.java @@ -1,5 +1,8 @@ package org.jivesoftware.smackx.jingle3.internal; +import java.util.ArrayList; +import java.util.List; + import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smackx.jingle3.element.JingleContentTransportElement; import org.jivesoftware.smackx.jingle3.element.JingleContentTransportInfoElement; @@ -12,8 +15,45 @@ import org.jxmpp.jid.FullJid; */ public abstract class Transport { + private Content parent; + private final ArrayList> candidates = new ArrayList<>(); + + private Transport peersProposal; + private boolean isPeersProposal; + 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> getCandidates() { + return candidates; + } + public abstract String getNamespace(); public abstract void establishIncomingBytestreamSession(FullJid peer, @@ -26,7 +66,24 @@ public abstract class Transport { BytestreamSessionEstablishedListener listener, 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 void setParent(Content parent) { + if (this.parent != parent) { + this.parent = parent; + } + } + + public Content getParent() { + return parent; + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/TransportCandidate.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/TransportCandidate.java new file mode 100644 index 000000000..77b586705 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/internal/TransportCandidate.java @@ -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 { + + 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(); +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_ibb/JingleIBBTransport.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_ibb/JingleIBBTransport.java index f1676d4f5..76794c294 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_ibb/JingleIBBTransport.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_ibb/JingleIBBTransport.java @@ -10,6 +10,7 @@ import org.jivesoftware.smackx.bytestreams.BytestreamSession; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager; import org.jivesoftware.smackx.jingle3.element.JingleContentTransportInfoElement; 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.jingle_ibb.element.JingleIBBTransportElement; @@ -26,8 +27,6 @@ public class JingleIBBTransport extends Transport { private final String streamId; private final Short blockSize; - private JingleIBBTransport peersProposal; - public JingleIBBTransport(String streamId, Short blockSize) { this.streamId = streamId; this.blockSize = blockSize; @@ -82,12 +81,13 @@ public class JingleIBBTransport extends Transport { } @Override - public void setPeersProposal(Transport peersProposal) { - this.peersProposal = (JingleIBBTransport) peersProposal; + public void addCandidate(TransportCandidate candidate) { + // Sorry, we don't want any candidates. } @Override public void handleTransportInfo(JingleContentTransportInfoElement info) { // Nothing to do. + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransport.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransport.java index 1db7f5428..2d844cfc1 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransport.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransport.java @@ -1,13 +1,14 @@ package org.jivesoftware.smackx.jingle3.transport.jingle_s5b; import java.util.Collections; -import java.util.HashMap; import java.util.List; import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smackx.bytestreams.socks5.Socks5Proxy; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.jingle3.element.JingleContentTransportInfoElement; 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.jingle_s5b.elements.JingleS5BTransportCandidateElement; import org.jivesoftware.smackx.jingle3.transport.jingle_s5b.elements.JingleS5BTransportElement; @@ -27,11 +28,8 @@ public class JingleS5BTransport extends Transport { private String dstAddr; private Bytestream.Mode mode; - private HashMap candidates = new HashMap<>(); - private String peerDstAddr; - private Bytestream.Mode peerMode; - private HashMap peerCandidates; + private JingleS5BTransport peersProposal; private JingleS5BTransportCandidate ourChoice, theirChoice; private JingleS5BTransportCandidate nominee; @@ -41,9 +39,9 @@ public class JingleS5BTransport extends Transport { this.dstAddr = dstAddr; this.mode = mode; - for (JingleS5BTransportCandidate c : (candidates != null ? + for (TransportCandidate c : (candidates != null ? candidates : Collections.emptySet())) { - this.candidates.put(c.getCandidateId(), c); + addCandidate(c); } } @@ -54,14 +52,21 @@ public class JingleS5BTransport extends Transport { .setDestinationAddress(dstAddr) .setMode(mode); - for (JingleS5BTransportCandidate candidate : candidates.values()) { - builder.addTransportCandidate( - (JingleS5BTransportCandidateElement) candidate.getElement()); + for (TransportCandidate candidate : getCandidates()) { + builder.addTransportCandidate((JingleS5BTransportCandidateElement) candidate.getElement()); } return builder.build(); } + public String getDstAddr() { + return dstAddr; + } + + public Bytestream.Mode getMode() { + return mode; + } + @Override public String getNamespace() { return NAMESPACE; @@ -69,7 +74,7 @@ public class JingleS5BTransport extends Transport { @Override public void establishIncomingBytestreamSession(FullJid peer, String transportSessionId, BytestreamSessionEstablishedListener listener, XMPPConnection connection) { - + Socks5Proxy.getSocks5Proxy().addTransfer(dstAddr); } @Override @@ -77,14 +82,6 @@ public class JingleS5BTransport extends Transport { } - @Override - public void setPeersProposal(Transport peersProposal) { - JingleS5BTransport transport = (JingleS5BTransport) peersProposal; - peerCandidates = transport.candidates; - peerDstAddr = transport.dstAddr; - peerMode = transport.mode; - } - @Override public void handleTransportInfo(JingleContentTransportInfoElement info) { switch (info.getElementName()) { @@ -112,7 +109,6 @@ public class JingleS5BTransport extends Transport { private void handleCandidateUsed(JingleS5BTransportInfoElement info) { String candidateId = ((JingleS5BTransportInfoElement.CandidateUsed) info).getCandidateId(); - theirChoice = candidates.get(candidateId); if (theirChoice == null) { /* diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransportAdapter.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransportAdapter.java index 5bd763c15..365892554 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransportAdapter.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransportAdapter.java @@ -1,7 +1,12 @@ package org.jivesoftware.smackx.jingle3.transport.jingle_s5b; +import java.util.ArrayList; + 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.transport.jingle_s5b.elements.JingleS5BTransportCandidateElement; +import org.jivesoftware.smackx.jingle3.transport.jingle_s5b.elements.JingleS5BTransportElement; /** * Created by vanitas on 19.07.17. @@ -10,7 +15,14 @@ public class JingleS5BTransportAdapter implements JingleTransportAdapter 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 diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransportCandidate.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransportCandidate.java index 29e09688a..739753514 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransportCandidate.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle3/transport/jingle_s5b/JingleS5BTransportCandidate.java @@ -1,27 +1,42 @@ 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.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; /** * Created by vanitas on 19.07.17. */ -public class JingleS5BTransportCandidate { +public class JingleS5BTransportCandidate extends TransportCandidate { private final String candidateId; private final Bytestream.StreamHost streamHost; - private final int priority; private final JingleS5BTransportCandidateElement.Type type; + private Socket socket; + public JingleS5BTransportCandidate(String candidateId, Bytestream.StreamHost streamHost, int priority, JingleS5BTransportCandidateElement.Type type) { this.candidateId = candidateId; this.streamHost = streamHost; - this.priority = priority; 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() { @@ -32,15 +47,30 @@ public class JingleS5BTransportCandidate { return streamHost; } - public int getPriority() { - return priority; - } - public JingleS5BTransportCandidateElement.Type getType() { return type; } - public JingleContentTransportCandidateElement getElement() { - return new JingleS5BTransportCandidateElement(candidateId, streamHost.getAddress(), streamHost.getJID(), streamHost.getPort(), priority, type); + public JingleS5BTransportCandidateElement getElement() { + 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; } }