require dtls and ensure procceds get tracked
This commit is contained in:
		
							parent
							
								
									0661c1bd37
								
							
						
					
					
						commit
						6884e427ef
					
				| 
						 | 
				
			
			@ -238,7 +238,7 @@ public class MessageGenerator extends AbstractGenerator {
 | 
			
		|||
		final MessagePacket packet = new MessagePacket();
 | 
			
		||||
        packet.setType(MessagePacket.TYPE_CHAT); //we want to carbon copy those
 | 
			
		||||
		packet.setTo(proposal.with);
 | 
			
		||||
		packet.setId(JingleRtpConnection.JINGLE_MESSAGE_ID_PREFIX+proposal.sessionId);
 | 
			
		||||
		packet.setId(JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX +proposal.sessionId);
 | 
			
		||||
		final Element propose = packet.addChild("propose", Namespace.JINGLE_MESSAGE);
 | 
			
		||||
		propose.setAttribute("id", proposal.sessionId);
 | 
			
		||||
		propose.addChild("description", Namespace.JINGLE_APPS_RTP);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -306,12 +306,17 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
 | 
			
		|||
            final Jid from = packet.getFrom();
 | 
			
		||||
            final String id = packet.getId();
 | 
			
		||||
            if (from != null && id != null) {
 | 
			
		||||
                if (id.startsWith(JingleRtpConnection.JINGLE_MESSAGE_ID_PREFIX)) {
 | 
			
		||||
                    final String sessionId = id.substring(JingleRtpConnection.JINGLE_MESSAGE_ID_PREFIX.length());
 | 
			
		||||
                if (id.startsWith(JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX)) {
 | 
			
		||||
                    final String sessionId = id.substring(JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX.length());
 | 
			
		||||
                    mXmppConnectionService.getJingleConnectionManager()
 | 
			
		||||
                            .updateProposedSessionDiscovered(account, from, sessionId, JingleConnectionManager.DeviceDiscoveryState.FAILED);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                if (id.startsWith(JingleRtpConnection.JINGLE_MESSAGE_PROCEED_ID_PREFIX)) {
 | 
			
		||||
                    final String sessionId = id.substring(JingleRtpConnection.JINGLE_MESSAGE_PROCEED_ID_PREFIX.length());
 | 
			
		||||
                    mXmppConnectionService.getJingleConnectionManager().failProceed(account, from, sessionId);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                mXmppConnectionService.markMessage(account,
 | 
			
		||||
                        from.asBareJid(),
 | 
			
		||||
                        id,
 | 
			
		||||
| 
						 | 
				
			
			@ -845,8 +850,8 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
 | 
			
		|||
                    query.removePendingReceiptRequest(new ReceiptRequest(packet.getTo(), id));
 | 
			
		||||
                }
 | 
			
		||||
            } else if (id != null) {
 | 
			
		||||
                if (id.startsWith(JingleRtpConnection.JINGLE_MESSAGE_ID_PREFIX)) {
 | 
			
		||||
                    final String sessionId = id.substring(JingleRtpConnection.JINGLE_MESSAGE_ID_PREFIX.length());
 | 
			
		||||
                if (id.startsWith(JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX)) {
 | 
			
		||||
                    final String sessionId = id.substring(JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX.length());
 | 
			
		||||
                    mXmppConnectionService.getJingleConnectionManager()
 | 
			
		||||
                            .updateProposedSessionDiscovered(account, from, sessionId, JingleConnectionManager.DeviceDiscoveryState.DISCOVERED);
 | 
			
		||||
                } else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,8 @@ import rocks.xmpp.addr.Jid;
 | 
			
		|||
 | 
			
		||||
public abstract class AbstractJingleConnection {
 | 
			
		||||
 | 
			
		||||
    public static final String JINGLE_MESSAGE_ID_PREFIX = "jm-propose-";
 | 
			
		||||
    public static final String JINGLE_MESSAGE_PROPOSE_ID_PREFIX = "jm-propose-";
 | 
			
		||||
    public static final String JINGLE_MESSAGE_PROCEED_ID_PREFIX = "jm-proceed-";
 | 
			
		||||
 | 
			
		||||
    protected final JingleConnectionManager jingleConnectionManager;
 | 
			
		||||
    protected final XmppConnectionService xmppConnectionService;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -354,6 +354,14 @@ public class JingleConnectionManager extends AbstractConnectionManager {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void failProceed(Account account, final Jid with, String sessionId) {
 | 
			
		||||
        final AbstractJingleConnection.Id id = AbstractJingleConnection.Id.of(account, with, sessionId);
 | 
			
		||||
        final AbstractJingleConnection existingJingleConnection = connections.get(id);
 | 
			
		||||
        if (existingJingleConnection instanceof JingleRtpConnection) {
 | 
			
		||||
            ((JingleRtpConnection) existingJingleConnection).deliverFailedProceed();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class RtpSessionProposal {
 | 
			
		||||
        private final Account account;
 | 
			
		||||
        public final Jid with;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
 | 
			
		|||
    private RtpContentMap responderRtpContentMap;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public JingleRtpConnection(JingleConnectionManager jingleConnectionManager, Id id, Jid initiator) {
 | 
			
		||||
    JingleRtpConnection(JingleConnectionManager jingleConnectionManager, Id id, Jid initiator) {
 | 
			
		||||
        super(jingleConnectionManager, id, initiator);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -186,8 +186,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
 | 
			
		|||
        try {
 | 
			
		||||
            contentMap = RtpContentMap.of(jinglePacket);
 | 
			
		||||
            contentMap.requireContentDescriptions();
 | 
			
		||||
            //TODO requireTransportWithDtls();
 | 
			
		||||
        } catch (IllegalArgumentException | IllegalStateException | NullPointerException e) {
 | 
			
		||||
            contentMap.requireDTLSFingerprint();
 | 
			
		||||
        } catch (final IllegalArgumentException | IllegalStateException | NullPointerException e) {
 | 
			
		||||
            respondOk(jinglePacket);
 | 
			
		||||
            sendSessionTerminate(Reason.FAILED_APPLICATION);
 | 
			
		||||
            Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": improperly formatted contents", e);
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +226,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
 | 
			
		|||
        try {
 | 
			
		||||
            contentMap = RtpContentMap.of(jinglePacket);
 | 
			
		||||
            contentMap.requireContentDescriptions();
 | 
			
		||||
            //TODO requireTransportWithDtls();
 | 
			
		||||
            contentMap.requireDTLSFingerprint();
 | 
			
		||||
        } catch (IllegalArgumentException | IllegalStateException | NullPointerException e) {
 | 
			
		||||
            respondOk(jinglePacket);
 | 
			
		||||
            Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": improperly formatted contents in session-accept", e);
 | 
			
		||||
| 
						 | 
				
			
			@ -351,6 +351,15 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void deliverFailedProceed() {
 | 
			
		||||
        Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": receive message error for proceed message");
 | 
			
		||||
        if (transition(State.TERMINATED_CONNECTIVITY_ERROR)) {
 | 
			
		||||
            webRTCWrapper.close();
 | 
			
		||||
            Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": transitioned into connectivity error");
 | 
			
		||||
            this.jingleConnectionManager.finishConnection(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void receiveAccept(Jid from, Element message) {
 | 
			
		||||
        final boolean originatedFromMyself = from.asBareJid().equals(id.account.getJid().asBareJid());
 | 
			
		||||
        if (originatedFromMyself) {
 | 
			
		||||
| 
						 | 
				
			
			@ -533,7 +542,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    private void terminateWithOutOfOrder(final JinglePacket jinglePacket) {
 | 
			
		||||
        Log.d(Config.LOGTAG,id.account.getJid().asBareJid()+": terminating session with out-of-order");
 | 
			
		||||
        Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": terminating session with out-of-order");
 | 
			
		||||
        webRTCWrapper.close();
 | 
			
		||||
        transitionOrThrow(State.TERMINATED_APPLICATION_FAILURE);
 | 
			
		||||
        respondWithOutOfOrder(jinglePacket);
 | 
			
		||||
| 
						 | 
				
			
			@ -681,6 +690,9 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
 | 
			
		|||
 | 
			
		||||
    private void sendJingleMessage(final String action, final Jid to) {
 | 
			
		||||
        final MessagePacket messagePacket = new MessagePacket();
 | 
			
		||||
        if ("proceed".equals(action)) {
 | 
			
		||||
            messagePacket.setId(JINGLE_MESSAGE_PROCEED_ID_PREFIX + id.sessionId);
 | 
			
		||||
        }
 | 
			
		||||
        messagePacket.setType(MessagePacket.TYPE_CHAT); //we want to carbon copy those
 | 
			
		||||
        messagePacket.setTo(to);
 | 
			
		||||
        messagePacket.addChild(action, Namespace.JINGLE_MESSAGE).setAttribute("id", id.sessionId);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import android.util.Log;
 | 
			
		|||
 | 
			
		||||
import com.google.common.base.Function;
 | 
			
		||||
import com.google.common.base.Preconditions;
 | 
			
		||||
import com.google.common.base.Strings;
 | 
			
		||||
import com.google.common.collect.ImmutableMap;
 | 
			
		||||
import com.google.common.collect.Iterables;
 | 
			
		||||
import com.google.common.collect.Maps;
 | 
			
		||||
| 
						 | 
				
			
			@ -51,13 +52,26 @@ public class RtpContentMap {
 | 
			
		|||
        if (this.contents.size() == 0) {
 | 
			
		||||
            throw new IllegalStateException("No contents available");
 | 
			
		||||
        }
 | 
			
		||||
        for(Map.Entry<String,DescriptionTransport> entry : this.contents.entrySet()) {
 | 
			
		||||
        for (Map.Entry<String, DescriptionTransport> entry : this.contents.entrySet()) {
 | 
			
		||||
            if (entry.getValue().description == null) {
 | 
			
		||||
                throw new IllegalStateException(String.format("%s is lacking content description", entry.getKey()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void requireDTLSFingerprint() {
 | 
			
		||||
        if (this.contents.size() == 0) {
 | 
			
		||||
            throw new IllegalStateException("No contents available");
 | 
			
		||||
        }
 | 
			
		||||
        for (Map.Entry<String, DescriptionTransport> entry : this.contents.entrySet()) {
 | 
			
		||||
            final IceUdpTransportInfo transport = entry.getValue().transport;
 | 
			
		||||
            final IceUdpTransportInfo.Fingerprint fingerprint = transport.getFingerprint();
 | 
			
		||||
            if (fingerprint == null || Strings.isNullOrEmpty(fingerprint.getContent()) || Strings.isNullOrEmpty(fingerprint.getHash())) {
 | 
			
		||||
                throw new SecurityException(String.format("Use of DTLS-SRTP (XEP-0320) is required for content %s", entry.getKey()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public JinglePacket toJinglePacket(final JinglePacket.Action action, final String sessionId) {
 | 
			
		||||
        final JinglePacket jinglePacket = new JinglePacket(action, sessionId);
 | 
			
		||||
        if (this.group != null) {
 | 
			
		||||
| 
						 | 
				
			
			@ -75,14 +89,14 @@ public class RtpContentMap {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    public RtpContentMap transportInfo(final String contentName, final IceUdpTransportInfo.Candidate candidate) {
 | 
			
		||||
        final RtpContentMap.DescriptionTransport descriptionTransport =  contents.get(contentName);
 | 
			
		||||
        final RtpContentMap.DescriptionTransport descriptionTransport = contents.get(contentName);
 | 
			
		||||
        final IceUdpTransportInfo transportInfo = descriptionTransport == null ? null : descriptionTransport.transport;
 | 
			
		||||
        if (transportInfo == null) {
 | 
			
		||||
            throw new IllegalArgumentException("Unable to find transport info for content name "+contentName);
 | 
			
		||||
            throw new IllegalArgumentException("Unable to find transport info for content name " + contentName);
 | 
			
		||||
        }
 | 
			
		||||
        final IceUdpTransportInfo newTransportInfo = transportInfo.cloneWrapper();
 | 
			
		||||
        newTransportInfo.addChild(candidate);
 | 
			
		||||
        return new RtpContentMap(null, ImmutableMap.of(contentName, new DescriptionTransport(null,newTransportInfo)));
 | 
			
		||||
        return new RtpContentMap(null, ImmutableMap.of(contentName, new DescriptionTransport(null, newTransportInfo)));
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue