From 2f437ea845a0972437c151100d59be5b7242d0b5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 17 Apr 2020 10:56:27 +0200 Subject: [PATCH] ignore iq errors if session has already been terminated --- .../xmpp/jingle/JingleRtpConnection.java | 66 +++++++++++-------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 41445c77c..64da8bc35 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.Set; import eu.siacs.conversations.Config; +import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Conversational; import eu.siacs.conversations.entities.Message; @@ -238,7 +239,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web try { sdp = candidate.toSdpAttribute(ufrag); } catch (IllegalArgumentException e) { - Log.d(Config.LOGTAG,id.account.getJid().asBareJid()+": ignoring invalid ICE candidate "+e.getMessage()); + Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": ignoring invalid ICE candidate " + e.getMessage()); continue; } final String sdpMid = content.getKey(); @@ -658,35 +659,44 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web private void send(final JinglePacket jinglePacket) { jinglePacket.setTo(id.with); - xmppConnectionService.sendIqPacket(id.account, jinglePacket, (account, response) -> { - if (response.getType() == IqPacket.TYPE.ERROR) { - final String errorCondition = response.getErrorCondition(); - Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received IQ-error from " + response.getFrom() + " in RTP session. " + errorCondition); - this.webRTCWrapper.close(); - final State target; - if (Arrays.asList( - "service-unavailable", - "recipient-unavailable", - "remote-server-not-found", - "remote-server-timeout" - ).contains(errorCondition)) { - target = State.TERMINATED_CONNECTIVITY_ERROR; - } else { - target = State.TERMINATED_APPLICATION_FAILURE; - } - if (transition(target)) { - Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": terminated session with " + id.with); - } else { - Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": not transitioning because already at state=" + this.state); - } + xmppConnectionService.sendIqPacket(id.account, jinglePacket, this::handleIqResponse); + } - } else if (response.getType() == IqPacket.TYPE.TIMEOUT) { - this.webRTCWrapper.close(); - Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received IQ timeout in RTP session with " + id.with + ". terminating with connectivity error"); - transition(State.TERMINATED_CONNECTIVITY_ERROR); - this.jingleConnectionManager.finishConnection(this); + private synchronized void handleIqResponse(final Account account, final IqPacket response) { + if (response.getType() == IqPacket.TYPE.ERROR) { + final String errorCondition = response.getErrorCondition(); + Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received IQ-error from " + response.getFrom() + " in RTP session. " + errorCondition); + if (TERMINATED.contains(this.state)) { + Log.i(Config.LOGTAG, id.account.getJid().asBareJid() + ": ignoring error because session was already terminated"); + return; } - }); + this.webRTCWrapper.close(); + final State target; + if (Arrays.asList( + "service-unavailable", + "recipient-unavailable", + "remote-server-not-found", + "remote-server-timeout" + ).contains(errorCondition)) { + target = State.TERMINATED_CONNECTIVITY_ERROR; + } else { + target = State.TERMINATED_APPLICATION_FAILURE; + } + if (transition(target)) { + Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": terminated session with " + id.with); + } else { + Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": not transitioning because already at state=" + this.state); + } + } else if (response.getType() == IqPacket.TYPE.TIMEOUT) { + Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received IQ timeout in RTP session with " + id.with + ". terminating with connectivity error"); + if (TERMINATED.contains(this.state)) { + Log.i(Config.LOGTAG, id.account.getJid().asBareJid() + ": ignoring error because session was already terminated"); + return; + } + this.webRTCWrapper.close(); + transition(State.TERMINATED_CONNECTIVITY_ERROR); + this.jingleConnectionManager.finishConnection(this); + } } private void terminateWithOutOfOrder(final JinglePacket jinglePacket) {