From 42c6e7aae454d6dd43ae6ef3c2c7b0d80e2b1390 Mon Sep 17 00:00:00 2001
From: Boris Grozev <boris@jitsi.org>
Date: Thu, 15 Jan 2015 11:51:54 +0200
Subject: [PATCH] Uses the RTP version field to differentiate between RTP and
 other (ZRTP, DTLS) packets. Guards against possible problems caused by RTP
 header extensions added in the beginning of the transformer chain.

---
 src/org/jitsi/impl/neomedia/RawPacket.java          | 13 +++++++++++--
 .../impl/neomedia/transform/AbsSendTimeEngine.java  |  3 +++
 .../impl/neomedia/transform/REDTransformEngine.java |  5 ++---
 .../transform/csrc/CsrcTransformEngine.java         |  7 +++----
 .../transform/csrc/SsrcTransformEngine.java         |  2 +-
 .../impl/neomedia/transform/dtmf/DtmfRawPacket.java |  5 ++++-
 .../transform/dtmf/DtmfTransformEngine.java         |  5 ++++-
 .../impl/neomedia/transform/fec/FECReceiver.java    |  2 +-
 .../impl/neomedia/transform/fec/FECSender.java      |  3 ++-
 .../transform/pt/PayloadTypeTransformEngine.java    |  5 ++++-
 10 files changed, 35 insertions(+), 15 deletions(-)

diff --git a/src/org/jitsi/impl/neomedia/RawPacket.java b/src/org/jitsi/impl/neomedia/RawPacket.java
index 5d4a65ce..7d220b89 100644
--- a/src/org/jitsi/impl/neomedia/RawPacket.java
+++ b/src/org/jitsi/impl/neomedia/RawPacket.java
@@ -88,10 +88,10 @@ public RawPacket(byte[] buffer, int offset, int length)
     }
 
     /**
-     * Adds the <tt>extBuff</tt> buffer to as an extension of this packet
+     * Adds the <tt>extBuff</tt> buffer as an extension of this packet
      * according the rules specified in RFC 5285. Note that this method does
      * not replace extensions so if you add the same buffer twice it would be
-     * added as to separate extensions.
+     * added as a separate extension.
      *
      * @param extBuff the buffer that we'd like to add as an extension in this
      * packet.
@@ -580,6 +580,15 @@ public int getOffset()
         return this.offset;
     }
 
+    /**
+     * Gets the value of the "version" field of an RTP packet.
+     * @return the value of the RTP "version" field.
+     */
+    public int getVersion()
+    {
+        return (buffer[offset] & 0xC0) >> 6;
+    }
+
     /**
      * Get RTP padding size from a RTP packet
      *
diff --git a/src/org/jitsi/impl/neomedia/transform/AbsSendTimeEngine.java b/src/org/jitsi/impl/neomedia/transform/AbsSendTimeEngine.java
index 1f5e0248..b43e4ca1 100644
--- a/src/org/jitsi/impl/neomedia/transform/AbsSendTimeEngine.java
+++ b/src/org/jitsi/impl/neomedia/transform/AbsSendTimeEngine.java
@@ -6,6 +6,7 @@
  */
 package org.jitsi.impl.neomedia.transform;
 
+import net.sf.fmj.media.rtp.*;
 import org.jitsi.impl.neomedia.*;
 
 /**
@@ -38,6 +39,8 @@ public class AbsSendTimeEngine
     public RawPacket transform(RawPacket pkt)
     {
         if (extensionID != -1
+              && pkt != null
+              && pkt.getVersion() == RTPHeader.VERSION
               && pkt.getExtensionBit())
         {
             replaceAbsSendTime(pkt);
diff --git a/src/org/jitsi/impl/neomedia/transform/REDTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/REDTransformEngine.java
index b260d0ce..354b7663 100644
--- a/src/org/jitsi/impl/neomedia/transform/REDTransformEngine.java
+++ b/src/org/jitsi/impl/neomedia/transform/REDTransformEngine.java
@@ -6,6 +6,7 @@
  */
 package org.jitsi.impl.neomedia.transform;
 
+import net.sf.fmj.media.rtp.*;
 import org.jitsi.impl.neomedia.*;
 import org.jitsi.util.*;
 
@@ -145,9 +146,7 @@ public RawPacket[] transform(RawPacket[] pkts)
 
         for (RawPacket pkt : pkts)
         {
-            // we don't touch packets with PT=0, because they might be ZRTP
-            // packets. Do we need any other filters -- PT, SSRC?
-            if (pkt != null && pkt.getPayloadType() != 0)
+            if (pkt != null && pkt.getVersion() == RTPHeader.VERSION)
             {
                 byte[] buf = pkt.getBuffer();
                 int len = pkt.getLength();
diff --git a/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java
index ebf2ead1..7246a49a 100644
--- a/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java
+++ b/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java
@@ -8,6 +8,7 @@
 
 import java.util.*;
 
+import net.sf.fmj.media.rtp.*;
 import org.jitsi.impl.neomedia.*;
 import org.jitsi.impl.neomedia.transform.*;
 import org.jitsi.service.neomedia.*;
@@ -268,10 +269,8 @@ public void setCsrcAudioLevelExtensionID(byte extID, MediaDirection dir)
     @Override
     public synchronized RawPacket transform(RawPacket pkt)
     {
-        // if somebody has modified the packet and added an extension
-        // don't process it. As ZRTP creates special RTP packets carrying no
-        // RTP data and those packets are used only by ZRTP we don't use them.
-        if(pkt.getExtensionBit())
+        // Only transform RTP packets (and not ZRTP/DTLS, etc)
+        if (pkt == null || pkt.getVersion() != RTPHeader.VERSION)
             return pkt;
 
         long[] csrcList = mediaStream.getLocalContributingSourceIDs();
diff --git a/src/org/jitsi/impl/neomedia/transform/csrc/SsrcTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/csrc/SsrcTransformEngine.java
index ad14e0c7..f14ffbac 100644
--- a/src/org/jitsi/impl/neomedia/transform/csrc/SsrcTransformEngine.java
+++ b/src/org/jitsi/impl/neomedia/transform/csrc/SsrcTransformEngine.java
@@ -221,7 +221,7 @@ public RawPacket reverseTransform(RawPacket pkt)
         if ((ssrcAudioLevelExtID > 0)
                 && ssrcAudioLevelDirection.allowsReceiving()
                 && !pkt.isInvalid()
-                && (RTPHeader.VERSION == ((pkt.readByte(0) & 0xC0) >>> 6)))
+                && RTPHeader.VERSION == pkt.getVersion())
         {
             byte level = pkt.extractSsrcAudioLevel(ssrcAudioLevelExtID);
 
diff --git a/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfRawPacket.java b/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfRawPacket.java
index de5f36b1..796731bd 100644
--- a/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfRawPacket.java
+++ b/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfRawPacket.java
@@ -108,12 +108,15 @@ public void init(int     code,
                 " Marker = " + marker + " End = " + end);
         }
 
-        // Set the payload type and the marker
+        // Set the marker
         setMarker(marker);
 
         // set the Timestamp
         setTimestamp(timestamp);
 
+        // Clear any RTP header extensions
+        removeExtension();
+
          // Create the RTP data
         setDtmfPayload(code, end, duration, volume);
     }
diff --git a/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfTransformEngine.java
index daf5ef96..93ff442b 100644
--- a/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfTransformEngine.java
+++ b/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfTransformEngine.java
@@ -10,6 +10,7 @@
 
 import javax.media.*;
 
+import net.sf.fmj.media.rtp.*;
 import org.jitsi.impl.neomedia.*;
 import org.jitsi.impl.neomedia.transform.*;
 import org.jitsi.service.neomedia.*;
@@ -272,7 +273,9 @@ public RawPacket reverseTransform(RawPacket pkt)
      */
     public RawPacket transform(RawPacket pkt)
     {
-        if(currentTone.isEmpty())
+        if (currentTone.isEmpty()
+                || pkt == null
+                || pkt.getVersion() != RTPHeader.VERSION)
         {
             return pkt;
         }
diff --git a/src/org/jitsi/impl/neomedia/transform/fec/FECReceiver.java b/src/org/jitsi/impl/neomedia/transform/fec/FECReceiver.java
index 27eade9e..725fd32d 100644
--- a/src/org/jitsi/impl/neomedia/transform/fec/FECReceiver.java
+++ b/src/org/jitsi/impl/neomedia/transform/fec/FECReceiver.java
@@ -539,7 +539,7 @@ private RawPacket recover()
             }
 
             // set the version to 2
-            recoveredBuf[0] &= 0x3f; //set version to 2
+            recoveredBuf[0] &= 0x3f;
             recoveredBuf[0] |= 0x80;
             // the RTP header is now set, except for SSRC and seq. which are not
             // recoverable in this way and will be set later
diff --git a/src/org/jitsi/impl/neomedia/transform/fec/FECSender.java b/src/org/jitsi/impl/neomedia/transform/fec/FECSender.java
index 49e73f8c..b8cbd2c3 100644
--- a/src/org/jitsi/impl/neomedia/transform/fec/FECSender.java
+++ b/src/org/jitsi/impl/neomedia/transform/fec/FECSender.java
@@ -6,6 +6,7 @@
  */
 package org.jitsi.impl.neomedia.transform.fec;
 
+import net.sf.fmj.media.rtp.*;
 import org.jitsi.impl.neomedia.*;
 import org.jitsi.impl.neomedia.transform.*;
 import org.jitsi.util.Logger;
@@ -90,7 +91,7 @@ public synchronized RawPacket[] transform(RawPacket[] pkts)
         RawPacket pkt = null;
         for (RawPacket p : pkts)
         {
-            if (p != null && p.getPayloadType() != 0) //might be ZRTP
+            if (p != null && p.getVersion() == RTPHeader.VERSION)
             {
                 pkt = p;
                 break;
diff --git a/src/org/jitsi/impl/neomedia/transform/pt/PayloadTypeTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/pt/PayloadTypeTransformEngine.java
index c0555fc8..805b5dbf 100644
--- a/src/org/jitsi/impl/neomedia/transform/pt/PayloadTypeTransformEngine.java
+++ b/src/org/jitsi/impl/neomedia/transform/pt/PayloadTypeTransformEngine.java
@@ -6,6 +6,7 @@
  */
 package org.jitsi.impl.neomedia.transform.pt;
 
+import net.sf.fmj.media.rtp.*;
 import org.jitsi.impl.neomedia.*;
 import org.jitsi.impl.neomedia.transform.*;
 
@@ -53,7 +54,9 @@ public class PayloadTypeTransformEngine
      */
     public RawPacket transform(RawPacket pkt)
     {
-        if(mappingOverridesCopy == null || mappingOverridesCopy.isEmpty())
+        if (mappingOverridesCopy == null
+                || mappingOverridesCopy.isEmpty()
+                || pkt.getVersion() != RTPHeader.VERSION)
             return pkt;
 
         Byte newPT = mappingOverridesCopy.get(pkt.getPayloadType());
-- 
GitLab