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 c0ddfd96a..ce726a2f0 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -150,6 +150,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web private Set proposedMedia; private RtpContentMap initiatorRtpContentMap; private RtpContentMap responderRtpContentMap; + private IceUdpTransportInfo.Setup peerDtlsSetup; private final Stopwatch sessionDuration = Stopwatch.createUnstarted(); private final Queue stateHistory = new LinkedList<>(); private ScheduledFuture ringingTimeoutFuture; @@ -332,11 +333,18 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } private IceUdpTransportInfo.Setup getPeerDtlsSetup() { - final IceUdpTransportInfo.Setup responderSetup = this.responderRtpContentMap.getDtlsSetup(); - if (responderSetup == null || responderSetup == IceUdpTransportInfo.Setup.ACTPASS) { - throw new IllegalStateException("Invalid DTLS setup value in responder content map"); + final IceUdpTransportInfo.Setup peerSetup = this.peerDtlsSetup; + if (peerSetup == null || peerSetup == IceUdpTransportInfo.Setup.ACTPASS) { + throw new IllegalStateException("Invalid peer setup"); } - return isInitiator() ? responderSetup : responderSetup.flip(); + return peerSetup; + } + + private void storePeerDtlsSetup(final IceUdpTransportInfo.Setup setup) { + if (setup == null || setup == IceUdpTransportInfo.Setup.ACTPASS) { + throw new IllegalArgumentException("Trying to store invalid peer dtls setup"); + } + this.peerDtlsSetup = setup; } private boolean applyIceRestart(final JinglePacket jinglePacket, final RtpContentMap restartContentMap, final boolean isOffer) throws ExecutionException, InterruptedException { @@ -352,11 +360,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web webRTCWrapper.rollbackLocalDescription().get(); } webRTCWrapper.setRemoteDescription(sdp).get(); - if (isInitiator()) { - this.responderRtpContentMap = restartContentMap; - } else { - this.initiatorRtpContentMap = restartContentMap; - } + setRemoteContentMap(restartContentMap); if (isOffer) { webRTCWrapper.setIsReadyToReceiveIceCandidates(false); final SessionDescription localSessionDescription = setLocalSessionDescription(); @@ -364,6 +368,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web //We need to respond OK before sending any candidates respondOk(jinglePacket); webRTCWrapper.setIsReadyToReceiveIceCandidates(true); + } else { + storePeerDtlsSetup(restartContentMap.getDtlsSetup()); } return true; } @@ -569,6 +575,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web private void receiveSessionAccept(final RtpContentMap contentMap) { this.responderRtpContentMap = contentMap; + this.storePeerDtlsSetup(contentMap.getDtlsSetup()); final SessionDescription sessionDescription; try { sessionDescription = SessionDescription.of(contentMap); @@ -663,6 +670,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web final SessionDescription sessionDescription = SessionDescription.parse(webRTCSessionDescription.description); final RtpContentMap respondingRtpContentMap = RtpContentMap.of(sessionDescription); this.responderRtpContentMap = respondingRtpContentMap; + storePeerDtlsSetup(respondingRtpContentMap.getDtlsSetup().flip()); webRTCWrapper.setIsReadyToReceiveIceCandidates(true); final ListenableFuture outgoingContentMapFuture = prepareOutgoingContentMap(respondingRtpContentMap); Futures.addCallback(outgoingContentMapFuture, @@ -1520,6 +1528,14 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } } + private void setRemoteContentMap(final RtpContentMap rtpContentMap) { + if (isInitiator()) { + this.responderRtpContentMap = rtpContentMap; + } else { + this.initiatorRtpContentMap = rtpContentMap; + } + } + private SessionDescription setLocalSessionDescription() throws ExecutionException, InterruptedException { final org.webrtc.SessionDescription sessionDescription = this.webRTCWrapper.setLocalDescription().get(); return SessionDescription.parse(sessionDescription.description); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/RtpContentMap.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/RtpContentMap.java index 5366460ec..091bf7c10 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/RtpContentMap.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/RtpContentMap.java @@ -155,7 +155,11 @@ public class RtpContentMap { contents.values(), dt->dt.transport.getFingerprint().getSetup() )); - return setups.size() == 1 ? Iterables.getFirst(setups, null) : null; + final IceUdpTransportInfo.Setup setup = Iterables.getFirst(setups, null); + if (setups.size() == 1 && setup != null) { + return setup; + } + throw new IllegalStateException("Content map doesn't have distinct DTLS setup"); } public boolean emptyCandidates() {