aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Schneppe <christian.schneppe@pix-art.de>2019-12-09 20:00:47 +0100
committerChristian Schneppe <christian.schneppe@pix-art.de>2019-12-09 20:09:09 +0100
commit0c9d00068940c32f97ab32e7d149cf8516c5b58e (patch)
treecade8e44e6daf1fb98073f92162ff88f6033ea09
parent20b0c52e352a225cf288939b2fcdad5a2c92ae5a (diff)
jingle ibb: wait to receive ibb
previously we signalled succesfull file reception after receiving enough bytes on ibb; however that causes us to race with the session-info file hash. now the recipient will wait for <close/> and the sender will make sure to send the session-info before sending close.
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java20
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnectionManager.java12
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/jingle/JingleInBandTransport.java (renamed from src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java)57
3 files changed, 53 insertions, 36 deletions
diff --git a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java
index 7925c9b60..2d9abc562 100644
--- a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java
+++ b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java
@@ -97,7 +97,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];
@@ -692,7 +696,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);
@@ -752,7 +756,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);
@@ -961,7 +965,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");
@@ -1012,7 +1016,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));
@@ -1033,7 +1037,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);
@@ -1051,7 +1055,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);
@@ -1075,7 +1079,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/de/pixart/messenger/xmpp/jingle/JingleConnectionManager.java b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnectionManager.java
index 8faf5fbc1..fa57fbac7 100644
--- a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnectionManager.java
+++ b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnectionManager.java
@@ -49,6 +49,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
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");
@@ -150,17 +151,16 @@ public class JingleConnectionManager extends AbstractConnectionManager {
if (connection.getAccount() == account
&& connection.hasTransportId(sid)) {
JingleTransport transport = connection.getTransport();
- if (transport instanceof JingleInbandTransport) {
- JingleInbandTransport inbandTransport = (JingleInbandTransport) transport;
+ 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");
}
+ Log.d(Config.LOGTAG, "unable to deliver ibb packet: " + packet.toString());
+ account.getXmppConnection().sendIqPacket(packet.generateResponse(IqPacket.TYPE.ERROR), null);
}
public void cancelInTransmission() {
@@ -170,4 +170,4 @@ public class JingleConnectionManager extends AbstractConnectionManager {
}
}
}
-}
+} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleInBandTransport.java
index 744a72548..5de666402 100644
--- a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java
+++ b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleInBandTransport.java
@@ -20,20 +20,20 @@ import de.pixart.messenger.xmpp.OnIqPacketReceived;
import de.pixart.messenger.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,15 +60,16 @@ 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;
}
private void sendClose() {
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": sending ibb close");
IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
iq.setTo(this.counterpart);
Element close = iq.addChild("close", "http://jabber.org/protocol/ibb");
@@ -107,10 +108,7 @@ public class JingleInbandTransport extends JingleTransport {
return;
}
this.remainingSize = this.fileSize = file.getExpectedSize();
- } catch (final NoSuchAlgorithmException e) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + " " + e.getMessage());
- callback.onFileTransferAborted();
- } catch (final IOException e) {
+ } catch (final NoSuchAlgorithmException | IOException e) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + " " + e.getMessage());
callback.onFileTransferAborted();
}
@@ -180,9 +178,9 @@ public class JingleInbandTransport extends JingleTransport {
this.seq++;
connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100));
if (this.remainingSize <= 0) {
- sendClose();
file.setSha1Sum(digest.digest());
this.onFileTransmissionStatusChanged.onFileTransmitted(file);
+ sendClose();
fileInputStream.close();
}
} catch (IOException e) {
@@ -202,11 +200,7 @@ public class JingleInbandTransport extends JingleTransport {
this.fileOutputStream.write(buffer);
this.digest.update(buffer);
if (this.remainingSize <= 0) {
- file.setSha1Sum(digest.digest());
- fileOutputStream.flush();
- fileOutputStream.close();
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": receive next block nothing remaining");
- this.onFileTransmissionStatusChanged.onFileTransmitted(file);
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received last block. waiting for close");
} else {
connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100));
}
@@ -217,7 +211,20 @@ public class JingleInbandTransport extends JingleTransport {
}
}
- public void deliverPayload(IqPacket packet, Element payload) {
+ private void done() {
+ try {
+ file.setSha1Sum(digest.digest());
+ fileOutputStream.flush();
+ fileOutputStream.close();
+ this.onFileTransmissionStatusChanged.onFileTransmitted(file);
+ } catch (Exception e) {
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": " + e.getMessage());
+ FileBackend.close(fileOutputStream);
+ this.onFileTransmissionStatusChanged.onFileTransferAborted();
+ }
+ }
+
+ void deliverPayload(IqPacket packet, Element payload) {
if (payload.getName().equals("open")) {
if (!established) {
established = true;
@@ -237,10 +244,16 @@ public class JingleInbandTransport extends JingleTransport {
this.connected = false;
this.account.getXmppConnection().sendIqPacket(
packet.generateResponse(IqPacket.TYPE.RESULT), null);
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received ibb close");
+ if (this.remainingSize <= 0) {
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received ibb close. done");
+ done();
+ } else {
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received ibb close with " + this.remainingSize + " remaining");
+ FileBackend.close(fileOutputStream);
+ this.onFileTransmissionStatusChanged.onFileTransferAborted();
+ }
} else {
- Log.d(Config.LOGTAG, payload.toString());
- // TODO some sort of exception
+ this.account.getXmppConnection().sendIqPacket(packet.generateResponse(IqPacket.TYPE.ERROR), null);
}
}
} \ No newline at end of file