diff options
author | Daniel Gultsch <daniel@gultsch.de> | 2016-06-29 17:16:34 +0200 |
---|---|---|
committer | Christian Schneppe <christian@pix-art.de> | 2016-06-30 16:53:43 +0200 |
commit | 845bb3f7363893cd8539dbbcbb75c2215ea9b3ea (patch) | |
tree | f36dc58c01cca83af1c9393bbc3009df3c8bebf6 /src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java | |
parent | 01eb94ef997c22f9de46894d06be8ee8a87beb66 (diff) |
support jingle ft:4 to be compatible with swift
Conversations and Gajim both have an implementation bug that sends the jingle session id instead of the transport id (compare XEP-260 2.2). This commit has a work around for this that remains buggy when using ft:3. If gajim is ever to fix this we will be incompatbile. gajim should implement ft:4 instead. (gajim to gajim is broken as well)
Diffstat (limited to '')
-rw-r--r-- | src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index a2ddaa4ae..1001cfe45 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -23,6 +23,7 @@ import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.persistance.FileBackend; @@ -48,6 +49,8 @@ public class JingleConnection implements Transferable { protected static final int JINGLE_STATUS_TRANSMITTING = 5; protected static final int JINGLE_STATUS_FAILED = 99; + private Content.Version ftVersion = Content.Version.FT_3; + private int ibbBlockSize = 8192; private int mJingleStatus = -1; @@ -241,12 +244,14 @@ public class JingleConnection implements Transferable { this.contentCreator = "initiator"; this.contentName = this.mJingleConnectionManager.nextRandomId(); this.message = message; + this.account = message.getConversation().getAccount(); + upgradeNamespace(); this.message.setTransferable(this); this.mStatus = Transferable.STATUS_UPLOADING; - this.account = message.getConversation().getAccount(); this.initiator = this.account.getJid(); this.responder = this.message.getCounterpart(); this.sessionId = this.mJingleConnectionManager.nextRandomId(); + this.transportId = this.mJingleConnectionManager.nextRandomId(); if (this.candidates.size() > 0) { this.sendInitRequest(); } else { @@ -290,6 +295,20 @@ public class JingleConnection implements Transferable { } + private void upgradeNamespace() { + Jid jid = this.message.getCounterpart(); + String resource = jid != null ?jid.getResourcepart() : null; + if (resource != null) { + Presence presence = this.account.getRoster().getContact(jid).getPresences().getPresences().get(resource); + if (presence != null) { + List<String> features = presence.getServiceDiscoveryResult().getFeatures(); + if (features.contains(Content.Version.FT_4.getNamespace())) { + this.ftVersion = Content.Version.FT_4; + } + } + } + } + public void init(Account account, JinglePacket packet) { this.mJingleStatus = JINGLE_STATUS_INITIATED; Conversation conversation = this.mXmppConnectionService @@ -310,7 +329,13 @@ public class JingleConnection implements Transferable { this.contentName = content.getAttribute("name"); this.transportId = content.getTransportId(); this.mergeCandidates(JingleCandidate.parse(content.socks5transport().getChildren())); - this.fileOffer = packet.getJingleContent().getFileOffer(); + this.ftVersion = content.getVersion(); + if (ftVersion == null) { + this.sendCancel(); + this.fail(); + return; + } + this.fileOffer = content.getFileOffer(this.ftVersion); mXmppConnectionService.sendIqPacket(account,packet.generateResponse(IqPacket.TYPE.RESULT),null); @@ -435,24 +460,23 @@ public class JingleConnection implements Transferable { this.file.setKeyAndIv(conversation.getSymmetricKey()); pair = AbstractConnectionManager.createInputStream(this.file, false); this.file.setExpectedSize(pair.second); - content.setFileOffer(this.file, true); + content.setFileOffer(this.file, true, this.ftVersion); } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { this.file.setKey(mXmppAxolotlMessage.getInnerKey()); this.file.setIv(mXmppAxolotlMessage.getIV()); pair = AbstractConnectionManager.createInputStream(this.file, true); this.file.setExpectedSize(pair.second); - content.setFileOffer(this.file, false).addChild(mXmppAxolotlMessage.toElement()); + content.setFileOffer(this.file, false, this.ftVersion).addChild(mXmppAxolotlMessage.toElement()); } else { pair = AbstractConnectionManager.createInputStream(this.file, false); this.file.setExpectedSize(pair.second); - content.setFileOffer(this.file, false); + content.setFileOffer(this.file, false, this.ftVersion); } } catch (FileNotFoundException e) { cancel(); return; } this.mFileInputStream = pair.first; - this.transportId = this.mJingleConnectionManager.nextRandomId(); content.setTransportId(this.transportId); content.socks5transport().setChildren(getCandidatesAsElements()); packet.setContent(content); @@ -492,7 +516,7 @@ public class JingleConnection implements Transferable { public void onPrimaryCandidateFound(boolean success, final JingleCandidate candidate) { final JinglePacket packet = bootstrapPacket("session-accept"); final Content content = new Content(contentCreator,contentName); - content.setFileOffer(fileOffer); + content.setFileOffer(fileOffer, ftVersion); content.setTransportId(transportId); if (success && candidate != null && !equalCandidateExists(candidate)) { final JingleSocks5Transport socksConnection = new JingleSocks5Transport( @@ -630,13 +654,20 @@ public class JingleConnection implements Transferable { this.mJingleStatus = JINGLE_STATUS_TRANSMITTING; if (connection.needsActivation()) { if (connection.getCandidate().isOurs()) { + final String sid; + if (ftVersion == Content.Version.FT_3) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": use session ID instead of transport ID to activate proxy"); + sid = getSessionId(); + } else { + sid = getTransportId(); + } Log.d(Config.LOGTAG, "candidate " + connection.getCandidate().getCid() + " was our proxy. going to activate"); IqPacket activation = new IqPacket(IqPacket.TYPE.SET); activation.setTo(connection.getCandidate().getJid()); activation.query("http://jabber.org/protocol/bytestreams") - .setAttribute("sid", this.getSessionId()); + .setAttribute("sid", sid); activation.query().addChild("activate") .setContent(this.getCounterPart().toString()); mXmppConnectionService.sendIqPacket(account,activation, @@ -979,6 +1010,14 @@ public class JingleConnection implements Transferable { mXmppConnectionService.updateConversationUi(); } + public String getTransportId() { + return this.transportId; + } + + public Content.Version getFtVersion() { + return this.ftVersion; + } + interface OnProxyActivated { public void success(); |