@@ -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);
@@ -23,151 +23,151 @@ import eu.siacs.conversations.xmpp.stanzas.IqPacket;
import rocks.xmpp.addr.Jid;
public class JingleConnectionManager extends AbstractConnectionManager {
- private List<JingleConnection> connections = new CopyOnWriteArrayList<>();
-
- private HashMap<Jid, JingleCandidate> primaryCandidates = new HashMap<>();
-
- @SuppressLint("TrulyRandom")
- private SecureRandom random = new SecureRandom();
-
- 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 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 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() {
-
- @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()));
- }
- }
-
- 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 cancelInTransmission() {
- for (JingleConnection connection : this.connections) {
- if (connection.getJingleStatus() == JingleConnection.JINGLE_STATUS_TRANSMITTING) {
- connection.abort("connectivity-error");
- }
- }
- }
+ private List<JingleConnection> connections = new CopyOnWriteArrayList<>();
+
+ private HashMap<Jid, JingleCandidate> primaryCandidates = new HashMap<>();
+
+ @SuppressLint("TrulyRandom")
+ private SecureRandom random = new SecureRandom();
+
+ 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;
+ }
+ }
+ 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(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 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);
+ }
+
+ } else {
+ listener.onPrimaryCandidateFound(true,
+ this.primaryCandidates.get(account.getJid().asBareJid()));
+ }
+ }
+
+ 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, "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");
+ }
+ }
+ }
}
@@ -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;