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 8851dc590..2596f9960 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -95,7 +95,11 @@ public class JingleConnection implements Transferable { private OnIqPacketReceived responseListener = (account, packet) -> { if (packet.getType() != IqPacket.TYPE.RESULT) { - fail(IqParser.extractErrorMessage(packet)); + if (mJingleStatus != JINGLE_STATUS_FAILED && mJingleStatus != JINGLE_STATUS_FINISHED) { + fail(IqParser.extractErrorMessage(packet)); + } else { + Log.d(Config.LOGTAG,"ignoring late delivery of jingle packet to jingle session with status="+mJingleStatus+": "+packet.toString()); + } } }; private byte[] expectedHash = new byte[0]; @@ -674,7 +678,7 @@ public class JingleConnection implements Transferable { } private void sendAcceptIbb() { - this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize); + this.transport = new JingleInBandTransport(this, this.transportId, this.ibbBlockSize); final JinglePacket packet = bootstrapPacket("session-accept"); final Content content = new Content(contentCreator, contentName); content.setFileOffer(fileOffer, ftVersion); @@ -734,7 +738,7 @@ public class JingleConnection implements Transferable { } } respondToIq(packet, true); - this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize); + this.transport = new JingleInBandTransport(this, this.transportId, this.ibbBlockSize); this.transport.connect(onIbbTransportConnected); } else { respondToIq(packet, false); @@ -943,7 +947,7 @@ public class JingleConnection implements Transferable { } } this.transportId = packet.getJingleContent().getTransportId(); - this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize); + this.transport = new JingleInBandTransport(this, this.transportId, this.ibbBlockSize); final JinglePacket answer = bootstrapPacket("transport-accept"); @@ -994,7 +998,7 @@ public class JingleConnection implements Transferable { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to parse block size in transport-accept"); } } - this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize); + this.transport = new JingleInBandTransport(this, this.transportId, this.ibbBlockSize); if (sid == null || !sid.equals(this.transportId)) { Log.w(Config.LOGTAG, String.format("%s: sid in transport-accept (%s) did not match our sid (%s) ", account.getJid().asBareJid(), sid, transportId)); @@ -1015,7 +1019,7 @@ public class JingleConnection implements Transferable { this.mJingleStatus = JINGLE_STATUS_FINISHED; this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_RECEIVED); this.disconnectSocks5Connections(); - if (this.transport instanceof JingleInbandTransport) { + if (this.transport instanceof JingleInBandTransport) { this.transport.disconnect(); } this.message.setTransferable(null); @@ -1033,7 +1037,7 @@ public class JingleConnection implements Transferable { void abort(final String reason) { this.disconnectSocks5Connections(); - if (this.transport instanceof JingleInbandTransport) { + if (this.transport instanceof JingleInBandTransport) { this.transport.disconnect(); } sendSessionTerminate(reason); @@ -1057,7 +1061,7 @@ public class JingleConnection implements Transferable { private void fail(String errorMessage) { this.mJingleStatus = JINGLE_STATUS_FAILED; this.disconnectSocks5Connections(); - if (this.transport instanceof JingleInbandTransport) { + if (this.transport instanceof JingleInBandTransport) { this.transport.disconnect(); } FileBackend.close(mFileInputStream); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index f354c25af..60d6ebfe2 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -23,151 +23,151 @@ import eu.siacs.conversations.xmpp.stanzas.IqPacket; import rocks.xmpp.addr.Jid; public class JingleConnectionManager extends AbstractConnectionManager { - private List connections = new CopyOnWriteArrayList<>(); + private List connections = new CopyOnWriteArrayList<>(); - private HashMap primaryCandidates = new HashMap<>(); + private HashMap primaryCandidates = new HashMap<>(); - @SuppressLint("TrulyRandom") - private SecureRandom random = new SecureRandom(); + @SuppressLint("TrulyRandom") + private SecureRandom random = new SecureRandom(); - public JingleConnectionManager(XmppConnectionService service) { - super(service); - } + public JingleConnectionManager(XmppConnectionService service) { + super(service); + } - public void deliverPacket(Account account, JinglePacket packet) { - if (packet.isAction("session-initiate")) { - JingleConnection connection = new JingleConnection(this); - connection.init(account, packet); - connections.add(connection); - } else { - for (JingleConnection connection : connections) { - if (connection.getAccount() == account - && connection.getSessionId().equals( - packet.getSessionId()) - && connection.getCounterPart().equals(packet.getFrom())) { - connection.deliverPacket(packet); - return; - } - } - IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR); - Element error = response.addChild("error"); - error.setAttribute("type", "cancel"); - error.addChild("item-not-found", - "urn:ietf:params:xml:ns:xmpp-stanzas"); - error.addChild("unknown-session", "urn:xmpp:jingle:errors:1"); - account.getXmppConnection().sendIqPacket(response, null); - } - } + public void deliverPacket(Account account, JinglePacket packet) { + if (packet.isAction("session-initiate")) { + JingleConnection connection = new JingleConnection(this); + connection.init(account, packet); + connections.add(connection); + } else { + for (JingleConnection connection : connections) { + if (connection.getAccount() == account + && connection.getSessionId().equals( + packet.getSessionId()) + && connection.getCounterPart().equals(packet.getFrom())) { + connection.deliverPacket(packet); + return; + } + } + Log.d(Config.LOGTAG, "unable to route jingle packet: " + packet); + IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR); + Element error = response.addChild("error"); + error.setAttribute("type", "cancel"); + error.addChild("item-not-found", + "urn:ietf:params:xml:ns:xmpp-stanzas"); + error.addChild("unknown-session", "urn:xmpp:jingle:errors:1"); + account.getXmppConnection().sendIqPacket(response, null); + } + } - public JingleConnection createNewConnection(Message message) { - Transferable old = message.getTransferable(); - if (old != null) { - old.cancel(); - } - JingleConnection connection = new JingleConnection(this); - mXmppConnectionService.markMessage(message,Message.STATUS_WAITING); - connection.init(message); - this.connections.add(connection); - return connection; - } + public JingleConnection createNewConnection(Message message) { + Transferable old = message.getTransferable(); + if (old != null) { + old.cancel(); + } + JingleConnection connection = new JingleConnection(this); + mXmppConnectionService.markMessage(message, Message.STATUS_WAITING); + connection.init(message); + this.connections.add(connection); + return connection; + } - public JingleConnection createNewConnection(final JinglePacket packet) { - JingleConnection connection = new JingleConnection(this); - this.connections.add(connection); - return connection; - } + public JingleConnection createNewConnection(final JinglePacket packet) { + JingleConnection connection = new JingleConnection(this); + this.connections.add(connection); + return connection; + } - public void finishConnection(JingleConnection connection) { - this.connections.remove(connection); - } + public void finishConnection(JingleConnection connection) { + this.connections.remove(connection); + } - public void getPrimaryCandidate(final Account account, final boolean initiator, final OnPrimaryCandidateFound listener) { - if (Config.DISABLE_PROXY_LOOKUP) { - listener.onPrimaryCandidateFound(false, null); - return; - } - if (!this.primaryCandidates.containsKey(account.getJid().asBareJid())) { - final Jid proxy = account.getXmppConnection().findDiscoItemByFeature(Namespace.BYTE_STREAMS); - if (proxy != null) { - IqPacket iq = new IqPacket(IqPacket.TYPE.GET); - iq.setTo(proxy); - iq.query(Namespace.BYTE_STREAMS); - account.getXmppConnection().sendIqPacket(iq,new OnIqPacketReceived() { + public void getPrimaryCandidate(final Account account, final boolean initiator, final OnPrimaryCandidateFound listener) { + if (Config.DISABLE_PROXY_LOOKUP) { + listener.onPrimaryCandidateFound(false, null); + return; + } + if (!this.primaryCandidates.containsKey(account.getJid().asBareJid())) { + final Jid proxy = account.getXmppConnection().findDiscoItemByFeature(Namespace.BYTE_STREAMS); + if (proxy != null) { + IqPacket iq = new IqPacket(IqPacket.TYPE.GET); + iq.setTo(proxy); + iq.query(Namespace.BYTE_STREAMS); + account.getXmppConnection().sendIqPacket(iq, new OnIqPacketReceived() { - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - Element streamhost = packet.query().findChild("streamhost", Namespace.BYTE_STREAMS); - final String host = streamhost == null ? null : streamhost.getAttribute("host"); - final String port = streamhost == null ? null : streamhost.getAttribute("port"); - if (host != null && port != null) { - try { - JingleCandidate candidate = new JingleCandidate(nextRandomId(), true); - candidate.setHost(host); - candidate.setPort(Integer.parseInt(port)); - candidate.setType(JingleCandidate.TYPE_PROXY); - candidate.setJid(proxy); - candidate.setPriority(655360 + (initiator ? 30 : 0)); - primaryCandidates.put(account.getJid().asBareJid(),candidate); - listener.onPrimaryCandidateFound(true,candidate); - } catch (final NumberFormatException e) { - listener.onPrimaryCandidateFound(false,null); - return; - } - } else { - listener.onPrimaryCandidateFound(false,null); - } - } - }); - } else { - listener.onPrimaryCandidateFound(false, null); - } + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + Element streamhost = packet.query().findChild("streamhost", Namespace.BYTE_STREAMS); + final String host = streamhost == null ? null : streamhost.getAttribute("host"); + final String port = streamhost == null ? null : streamhost.getAttribute("port"); + if (host != null && port != null) { + try { + JingleCandidate candidate = new JingleCandidate(nextRandomId(), true); + candidate.setHost(host); + candidate.setPort(Integer.parseInt(port)); + candidate.setType(JingleCandidate.TYPE_PROXY); + candidate.setJid(proxy); + candidate.setPriority(655360 + (initiator ? 30 : 0)); + primaryCandidates.put(account.getJid().asBareJid(), candidate); + listener.onPrimaryCandidateFound(true, candidate); + } catch (final NumberFormatException e) { + listener.onPrimaryCandidateFound(false, null); + return; + } + } else { + listener.onPrimaryCandidateFound(false, null); + } + } + }); + } else { + listener.onPrimaryCandidateFound(false, null); + } - } else { - listener.onPrimaryCandidateFound(true, - this.primaryCandidates.get(account.getJid().asBareJid())); - } - } + } else { + listener.onPrimaryCandidateFound(true, + this.primaryCandidates.get(account.getJid().asBareJid())); + } + } - public String nextRandomId() { - return new BigInteger(50, random).toString(32); - } + public String nextRandomId() { + return new BigInteger(50, random).toString(32); + } - public void deliverIbbPacket(Account account, IqPacket packet) { - String sid = null; - Element payload = null; - if (packet.hasChild("open", "http://jabber.org/protocol/ibb")) { - payload = packet.findChild("open", "http://jabber.org/protocol/ibb"); - sid = payload.getAttribute("sid"); - } else if (packet.hasChild("data", "http://jabber.org/protocol/ibb")) { - payload = packet.findChild("data", "http://jabber.org/protocol/ibb"); - sid = payload.getAttribute("sid"); - } else if (packet.hasChild("close","http://jabber.org/protocol/ibb")) { - payload = packet.findChild("close", "http://jabber.org/protocol/ibb"); - sid = payload.getAttribute("sid"); - } - if (sid != null) { - for (JingleConnection connection : connections) { - if (connection.getAccount() == account - && connection.hasTransportId(sid)) { - JingleTransport transport = connection.getTransport(); - if (transport instanceof JingleInbandTransport) { - JingleInbandTransport inbandTransport = (JingleInbandTransport) transport; - inbandTransport.deliverPayload(packet, payload); - return; - } - } - } - Log.d(Config.LOGTAG,"couldn't deliver payload: " + payload.toString()); - } else { - Log.d(Config.LOGTAG, "no sid found in incoming ibb packet"); - } - } + public void deliverIbbPacket(Account account, IqPacket packet) { + String sid = null; + Element payload = null; + if (packet.hasChild("open", "http://jabber.org/protocol/ibb")) { + payload = packet.findChild("open", "http://jabber.org/protocol/ibb"); + sid = payload.getAttribute("sid"); + } else if (packet.hasChild("data", "http://jabber.org/protocol/ibb")) { + payload = packet.findChild("data", "http://jabber.org/protocol/ibb"); + sid = payload.getAttribute("sid"); + } else if (packet.hasChild("close", "http://jabber.org/protocol/ibb")) { + payload = packet.findChild("close", "http://jabber.org/protocol/ibb"); + sid = payload.getAttribute("sid"); + } + if (sid != null) { + for (JingleConnection connection : connections) { + if (connection.getAccount() == account + && connection.hasTransportId(sid)) { + JingleTransport transport = connection.getTransport(); + if (transport instanceof JingleInBandTransport) { + JingleInBandTransport inbandTransport = (JingleInBandTransport) transport; + inbandTransport.deliverPayload(packet, payload); + return; + } + } + } + } + Log.d(Config.LOGTAG, "unable to deliver ibb packet: " + packet.toString()); + account.getXmppConnection().sendIqPacket(packet.generateResponse(IqPacket.TYPE.ERROR), null); + } - public void cancelInTransmission() { - for (JingleConnection connection : this.connections) { - if (connection.getJingleStatus() == JingleConnection.JINGLE_STATUS_TRANSMITTING) { - connection.abort("connectivity-error"); - } - } - } + public void cancelInTransmission() { + for (JingleConnection connection : this.connections) { + if (connection.getJingleStatus() == JingleConnection.JINGLE_STATUS_TRANSMITTING) { + connection.abort("connectivity-error"); + } + } + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInBandTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInBandTransport.java index 64a9ff846..4182da08c 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInBandTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInBandTransport.java @@ -20,20 +20,20 @@ import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.stanzas.IqPacket; import rocks.xmpp.addr.Jid; -public class JingleInbandTransport extends JingleTransport { +public class JingleInBandTransport extends JingleTransport { - private Account account; - private Jid counterpart; - private int blockSize; + private final Account account; + private final Jid counterpart; + private final int blockSize; private int seq = 0; - private String sessionId; + private final String sessionId; private boolean established = false; private boolean connected = true; private DownloadableFile file; - private JingleConnection connection; + private final JingleConnection connection; private InputStream fileInputStream = null; private InputStream innerInputStream = null; @@ -60,11 +60,11 @@ public class JingleInbandTransport extends JingleTransport { } }; - public JingleInbandTransport(final JingleConnection connection, final String sid, final int blocksize) { + JingleInBandTransport(final JingleConnection connection, final String sid, final int blockSize) { this.connection = connection; this.account = connection.getAccount(); this.counterpart = connection.getCounterPart(); - this.blockSize = blocksize; + this.blockSize = blockSize; this.sessionId = sid; } @@ -224,7 +224,7 @@ public class JingleInbandTransport extends JingleTransport { } } - public void deliverPayload(IqPacket packet, Element payload) { + void deliverPayload(IqPacket packet, Element payload) { if (payload.getName().equals("open")) { if (!established) { established = true;