From 05b0e3650ec8fd3dde80306b4a992b872c5fdc99 Mon Sep 17 00:00:00 2001 From: vanitasvitae Date: Thu, 8 Jun 2017 00:48:23 +0200 Subject: [PATCH] Introduce JingleSocks5TransportInfo class --- .../JingleSocks5BytestreamTransport.java | 50 ++--- ...gleSocks5BytestreamTransportCandidate.java | 51 ----- .../JingleSocks5BytestreamTransportInfo.java | 177 ++++++++++++++++++ ...ngleSocks5BytestreamTransportProvider.java | 63 +++++-- .../JingleSocks5BytestreamTransportTest.java | 61 +++++- .../element/JingleContentTransport.java | 2 +- 6 files changed, 302 insertions(+), 102 deletions(-) create mode 100644 smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransportInfo.java diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransport.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransport.java index 48b54b9ac..44c856ecc 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransport.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransport.java @@ -8,6 +8,7 @@ import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.jingle.element.JingleContentTransport; import org.jivesoftware.smackx.jingle.element.JingleContentTransportCandidate; +import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfo; /** * Socks5Bytestream transport element. @@ -22,22 +23,11 @@ public class JingleSocks5BytestreamTransport extends JingleContentTransport { private final String dstAddr; private final Bytestream.Mode mode; - private final String candidateUsed; - private final String candidateActivated; - private final boolean candidateError; - private final boolean proxyError; - - protected JingleSocks5BytestreamTransport(List candidates, String streamId, String dstAddr, Bytestream.Mode mode, - String candidateUsed, String candidateActivated, boolean candidateError, boolean proxyError) { - super(candidates); + protected JingleSocks5BytestreamTransport(List candidates, List infos, String streamId, String dstAddr, Bytestream.Mode mode) { + super(candidates, infos); this.streamId = streamId; this.dstAddr = dstAddr; this.mode = mode; - - this.candidateUsed = candidateUsed; - this.candidateActivated = candidateActivated; - this.candidateError = candidateError; - this.proxyError = proxyError; } public String getStreamId() { @@ -49,7 +39,7 @@ public class JingleSocks5BytestreamTransport extends JingleContentTransport { } public Bytestream.Mode getMode() { - return mode; + return mode == null ? Bytestream.Mode.tcp : mode; } @Override @@ -59,8 +49,8 @@ public class JingleSocks5BytestreamTransport extends JingleContentTransport { @Override protected void addExtraAttributes(XmlStringBuilder xml) { - xml.attribute(ATTR_DSTADDR, dstAddr); - xml.attribute(ATTR_MODE, mode.toString()); + xml.optAttribute(ATTR_DSTADDR, dstAddr); + xml.optAttribute(ATTR_MODE, mode); xml.attribute(ATTR_SID, streamId); } @@ -69,16 +59,11 @@ public class JingleSocks5BytestreamTransport extends JingleContentTransport { } public static class Builder { - - private String candidateUsed; - private String candidateActivated; - private boolean proxyError; - private boolean candidateError; - private String streamId; private String dstAddr; - private Bytestream.Mode mode = Bytestream.Mode.tcp; + private Bytestream.Mode mode; private ArrayList candidates = new ArrayList<>(); + private ArrayList infos = new ArrayList<>(); public Builder setStreamId(String sid) { this.streamId = sid; @@ -100,29 +85,30 @@ public class JingleSocks5BytestreamTransport extends JingleContentTransport { return this; } - public Builder setCandidateUsed(String candidateId) { - this.candidateUsed = candidateId; + public Builder addTransportInfo(JingleContentTransportInfo info) { + this.infos.add(info); return this; } + public Builder setCandidateUsed(String candidateId) { + return addTransportInfo(JingleSocks5BytestreamTransportInfo.CandidateUsed(candidateId)); + } + public Builder setCandidateActivated(String candidateId) { - this.candidateActivated = candidateId; - return this; + return addTransportInfo(JingleSocks5BytestreamTransportInfo.CandidateActivated(candidateId)); } public Builder setCandidateError() { - this.candidateError = true; - return this; + return addTransportInfo(JingleSocks5BytestreamTransportInfo.CandidateError()); } public Builder setProxyError() { - this.proxyError = true; - return this; + return addTransportInfo(JingleSocks5BytestreamTransportInfo.ProxyError()); } public JingleSocks5BytestreamTransport build() { StringUtils.requireNotNullOrEmpty(streamId, "sid MUST be neither null, nor empty."); - return new JingleSocks5BytestreamTransport(candidates, streamId, dstAddr, mode, candidateUsed, candidateActivated, candidateError, proxyError); + return new JingleSocks5BytestreamTransport(candidates, infos, streamId, dstAddr, mode); } } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransportCandidate.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransportCandidate.java index 7af4ddf6c..b84ac38ad 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransportCandidate.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransportCandidate.java @@ -168,55 +168,4 @@ public class JingleSocks5BytestreamTransportCandidate extends JingleContentTrans return new JingleSocks5BytestreamTransportCandidate(cid, host, jid, port, priority, type); } } - - public static class CandidateUsed extends JingleContentTransportCandidate { - - public static final String ELEMENT = "candidate-used"; - public static final String ATTR_CID = "cid"; - - private final String candidateId; - - public CandidateUsed(String candidateId) { - this.candidateId = candidateId; - } - - @Override - public CharSequence toXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(this); - xml.attribute(ATTR_CID, candidateId); - xml.closeEmptyElement(); - return xml; - } - } - - public static class CandidateActivated extends JingleContentTransportCandidate { - - public static final String ELEMENT = "candidate-activated"; - public static final String ATTR_CID = "cid"; - - private final String candidateId; - - public CandidateActivated(String candidateId) { - this.candidateId = candidateId; - } - - @Override - public CharSequence toXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(this); - xml.attribute(ATTR_CID, candidateId); - xml.closeEmptyElement(); - return xml; - } - } - - public static class CandidateError extends JingleContentTransportCandidate { - public static final String ELEMENT = "candidate-error"; - - @Override - public CharSequence toXML() { - return new XmlStringBuilder(this).closeEmptyElement(); - } - } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransportInfo.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransportInfo.java new file mode 100644 index 000000000..e3c2e6080 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/elements/JingleSocks5BytestreamTransportInfo.java @@ -0,0 +1,177 @@ +package org.jivesoftware.smackx.jingle_s5b.elements; + +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfo; + +/** + * Class representing possible SOCKS5 TransportInfo elements. + */ +public abstract class JingleSocks5BytestreamTransportInfo extends JingleContentTransportInfo { + + private static CandidateError CEI; + private static ProxyError PEI; + + public static CandidateUsed CandidateUsed(String candidateId) { + return new CandidateUsed(candidateId); + } + + public static CandidateActivated CandidateActivated(String candidateId) { + return new CandidateActivated(candidateId); + } + + public static CandidateError CandidateError() { + if (CEI == null) { + CEI = new CandidateError(); + } + return CEI; + } + + public static ProxyError ProxyError() { + if (PEI == null) { + PEI = new ProxyError(); + } + return PEI; + } + + public static class CandidateActivated extends JingleSocks5BytestreamTransportInfo { + public static final String ELEMENT = "candidate-activated"; + public static final String ATTR_CID = "cid"; + + private final String candidateId; + + public CandidateActivated(String candidateId) { + this.candidateId = candidateId; + } + + public String getCandidateId() { + return candidateId; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public CharSequence toXML() { + XmlStringBuilder xml = new XmlStringBuilder(); + xml.halfOpenElement(this); + xml.attribute(ATTR_CID, candidateId); + xml.closeEmptyElement(); + return xml; + } + + @Override + public boolean equals(Object other) { + return other instanceof CandidateActivated && + ((CandidateActivated) other).getCandidateId().equals(candidateId); + } + + @Override + public int hashCode() { + return toXML().toString().hashCode(); + } + } + + public static class CandidateUsed extends JingleSocks5BytestreamTransportInfo { + public static final String ELEMENT = "candidate-used"; + public static final String ATTR_CID = "cid"; + + private final String candidateId; + + public CandidateUsed(String candidateId) { + this.candidateId = candidateId; + } + + public String getCandidateId() { + return candidateId; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public CharSequence toXML() { + XmlStringBuilder xml = new XmlStringBuilder(); + xml.halfOpenElement(this); + xml.attribute(ATTR_CID, candidateId); + xml.closeEmptyElement(); + return xml; + } + + @Override + public boolean equals(Object other) { + return other instanceof CandidateUsed && + ((CandidateUsed) other).getCandidateId().equals(candidateId); + } + + @Override + public int hashCode() { + return toXML().toString().hashCode(); + } + } + + public static class CandidateError extends JingleSocks5BytestreamTransportInfo { + public static final String ELEMENT = "candidate-error"; + + private CandidateError() { + + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public CharSequence toXML() { + XmlStringBuilder xml = new XmlStringBuilder(); + xml.halfOpenElement(this); + xml.closeEmptyElement(); + return xml; + } + + @Override + public boolean equals(Object other) { + return other instanceof CandidateError; + } + + @Override + public int hashCode() { + return toXML().toString().hashCode(); + } + } + + public static class ProxyError extends JingleSocks5BytestreamTransportInfo { + public static final String ELEMENT = "proxy-error"; + + private ProxyError() { + + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public CharSequence toXML() { + XmlStringBuilder xml = new XmlStringBuilder(); + xml.halfOpenElement(this); + xml.closeEmptyElement(); + return xml; + } + + @Override + public boolean equals(Object other) { + return other instanceof ProxyError; + } + + @Override + public int hashCode() { + return toXML().toString().hashCode(); + } + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/provider/JingleSocks5BytestreamTransportProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/provider/JingleSocks5BytestreamTransportProvider.java index 2890a489d..4575bbdc8 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/provider/JingleSocks5BytestreamTransportProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_s5b/provider/JingleSocks5BytestreamTransportProvider.java @@ -18,6 +18,7 @@ import org.jivesoftware.smackx.jingle.element.JingleContentTransport; import org.jivesoftware.smackx.jingle.provider.JingleContentTransportProvider; import org.jivesoftware.smackx.jingle_s5b.elements.JingleSocks5BytestreamTransport; import org.jivesoftware.smackx.jingle_s5b.elements.JingleSocks5BytestreamTransportCandidate; +import org.jivesoftware.smackx.jingle_s5b.elements.JingleSocks5BytestreamTransportInfo; import org.xmlpull.v1.XmlPullParser; /** @@ -28,7 +29,6 @@ public class JingleSocks5BytestreamTransportProvider extends JingleContentTransp private static final Logger LOGGER = Logger.getLogger(JingleSocks5BytestreamTransportProvider.class.getName()); @Override public JingleSocks5BytestreamTransport parse(XmlPullParser parser, int initialDepth) throws Exception { - String namespace = JingleSocks5BytestreamTransport.NAMESPACE_V1; JingleSocks5BytestreamTransport.Builder builder = JingleSocks5BytestreamTransport.getBuilder(); String streamId = parser.getAttributeValue(null, JingleSocks5BytestreamTransport.ATTR_SID); @@ -45,28 +45,57 @@ public class JingleSocks5BytestreamTransportProvider extends JingleContentTransp builder.setMode(mode.equals(udp.toString()) ? udp : tcp); } - JingleSocks5BytestreamTransportCandidate.Builder cb = null; + JingleSocks5BytestreamTransportCandidate.Builder cb; while (true) { int tag = parser.nextTag(); String name = parser.getName(); - if (tag == START_TAG && name.equals(JingleSocks5BytestreamTransportCandidate.ELEMENT)) { - LOGGER.log(Level.SEVERE, "Payload"); - cb = JingleSocks5BytestreamTransportCandidate.getBuilder(); - cb.setCandidateId(parser.getAttributeValue(null, ATTR_CID)); - cb.setHost(parser.getAttributeValue(null, ATTR_HOST)); - cb.setJid(parser.getAttributeValue(null, ATTR_JID)); - cb.setPriority(Integer.parseInt(parser.getAttributeValue(null, ATTR_PRIORITY))); + if (tag == START_TAG) { + switch (name) { - String portString = parser.getAttributeValue(null, ATTR_PORT); - if (portString != null) { - cb.setPort(Integer.parseInt(portString)); - } + case JingleSocks5BytestreamTransportCandidate.ELEMENT: + LOGGER.log(Level.SEVERE, "Payload"); + cb = JingleSocks5BytestreamTransportCandidate.getBuilder(); + cb.setCandidateId(parser.getAttributeValue(null, ATTR_CID)); + cb.setHost(parser.getAttributeValue(null, ATTR_HOST)); + cb.setJid(parser.getAttributeValue(null, ATTR_JID)); + cb.setPriority(Integer.parseInt(parser.getAttributeValue(null, ATTR_PRIORITY))); - String typeString = parser.getAttributeValue(null, ATTR_TYPE); - if (typeString != null) { - cb.setType(JingleSocks5BytestreamTransportCandidate.Type.fromString(typeString)); + String portString = parser.getAttributeValue(null, ATTR_PORT); + if (portString != null) { + cb.setPort(Integer.parseInt(portString)); + } + + String typeString = parser.getAttributeValue(null, ATTR_TYPE); + if (typeString != null) { + cb.setType(JingleSocks5BytestreamTransportCandidate.Type.fromString(typeString)); + } + builder.addTransportCandidate(cb.build()); + break; + + case JingleSocks5BytestreamTransportInfo.CandidateActivated.ELEMENT: + LOGGER.log(Level.INFO, "Candidate-Activated found"); + builder.addTransportInfo(JingleSocks5BytestreamTransportInfo.CandidateActivated( + parser.getAttributeValue(null, + JingleSocks5BytestreamTransportInfo.CandidateActivated.ATTR_CID))); + break; + + case JingleSocks5BytestreamTransportInfo.CandidateUsed.ELEMENT: + LOGGER.log(Level.INFO, "Candidate-Used found"); + builder.addTransportInfo(JingleSocks5BytestreamTransportInfo.CandidateUsed( + parser.getAttributeValue(null, + JingleSocks5BytestreamTransportInfo.CandidateUsed.ATTR_CID))); + break; + + case JingleSocks5BytestreamTransportInfo.CandidateError.ELEMENT: + LOGGER.log(Level.INFO, "Candidate-Error found"); + builder.addTransportInfo(JingleSocks5BytestreamTransportInfo.CandidateError()); + break; + + case JingleSocks5BytestreamTransportInfo.ProxyError.ELEMENT: + LOGGER.log(Level.INFO, "Proxy-Error found"); + builder.addTransportInfo(JingleSocks5BytestreamTransportInfo.ProxyError()); + break; } - builder.addTransportCandidate(cb.build()); } if (tag == END_TAG && name.equals(JingleContentTransport.ELEMENT)) { diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_s5b/JingleSocks5BytestreamTransportTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_s5b/JingleSocks5BytestreamTransportTest.java index 0bb8f20e2..6d919fd8c 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_s5b/JingleSocks5BytestreamTransportTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_s5b/JingleSocks5BytestreamTransportTest.java @@ -1,5 +1,6 @@ package org.jivesoftware.smackx.jingle_s5b; +import static junit.framework.TestCase.assertNull; import static org.junit.Assert.assertEquals; import org.jivesoftware.smack.test.util.SmackTestSuite; @@ -7,6 +8,7 @@ import org.jivesoftware.smack.test.util.TestUtils; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.jingle_s5b.elements.JingleSocks5BytestreamTransport; import org.jivesoftware.smackx.jingle_s5b.elements.JingleSocks5BytestreamTransportCandidate; +import org.jivesoftware.smackx.jingle_s5b.elements.JingleSocks5BytestreamTransportInfo; import org.jivesoftware.smackx.jingle_s5b.provider.JingleSocks5BytestreamTransportProvider; import org.junit.Test; import org.jxmpp.jid.impl.JidCreate; @@ -17,7 +19,7 @@ import org.jxmpp.jid.impl.JidCreate; public class JingleSocks5BytestreamTransportTest extends SmackTestSuite { @Test - public void providerTest() throws Exception { + public void candidatesProviderTest() throws Exception { String xml = "" + + "" + + ""; + JingleSocks5BytestreamTransport candidateErrorTransport = new JingleSocks5BytestreamTransportProvider() + .parse(TestUtils.getParser(candidateError)); + assertNull(candidateErrorTransport.getDestinationAddress()); + assertEquals(1, candidateErrorTransport.getInfos().size()); + assertEquals("vj3hs98y", candidateErrorTransport.getStreamId()); + assertEquals(JingleSocks5BytestreamTransportInfo.CandidateError(), + candidateErrorTransport.getInfos().get(0)); + assertEquals(candidateError, candidateErrorTransport.toXML().toString()); + + String proxyError = + "" + + "" + + ""; + JingleSocks5BytestreamTransport proxyErrorTransport = new JingleSocks5BytestreamTransportProvider() + .parse(TestUtils.getParser(proxyError)); + assertNull(proxyErrorTransport.getDestinationAddress()); + assertEquals(1, proxyErrorTransport.getInfos().size()); + assertEquals("vj3hs98y", proxyErrorTransport.getStreamId()); + assertEquals(JingleSocks5BytestreamTransportInfo.ProxyError(), + proxyErrorTransport.getInfos().get(0)); + assertEquals(proxyError, proxyErrorTransport.toXML().toString()); + + String candidateUsed = + "" + + "" + + ""; + JingleSocks5BytestreamTransport candidateUsedTransport = new JingleSocks5BytestreamTransportProvider() + .parse(TestUtils.getParser(candidateUsed)); + assertEquals(1, candidateUsedTransport.getInfos().size()); + assertEquals(JingleSocks5BytestreamTransportInfo.CandidateUsed("hr65dqyd"), + candidateUsedTransport.getInfos().get(0)); + assertEquals("hr65dqyd", + ((JingleSocks5BytestreamTransportInfo.CandidateUsed) + candidateUsedTransport.getInfos().get(0)).getCandidateId()); + assertEquals(candidateUsed, candidateUsedTransport.toXML().toString()); + + String candidateActivated = + "" + + "" + + ""; + JingleSocks5BytestreamTransport candidateActivatedTransport = new JingleSocks5BytestreamTransportProvider() + .parse(TestUtils.getParser(candidateActivated)); + assertEquals(1, candidateActivatedTransport.getInfos().size()); + assertEquals(JingleSocks5BytestreamTransportInfo.CandidateActivated("hr65dqyd"), + candidateActivatedTransport.getInfos().get(0)); + assertEquals("hr65dqyd", + ((JingleSocks5BytestreamTransportInfo.CandidateActivated) + candidateActivatedTransport.getInfos().get(0)).getCandidateId()); + assertEquals(candidateActivated, candidateActivatedTransport.toXML().toString()); + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentTransport.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentTransport.java index 5397ef964..49f6dc66a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentTransport.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentTransport.java @@ -74,7 +74,7 @@ public abstract class JingleContentTransport implements ExtensionElement { XmlStringBuilder xml = new XmlStringBuilder(this); addExtraAttributes(xml); - if (candidates.isEmpty()) { + if (candidates.isEmpty() && infos.isEmpty()) { xml.closeEmptyElement(); } else {