From 415b109524ca7d198e1cd2d10e072fa1acd29ff9 Mon Sep 17 00:00:00 2001
From: Ingo Bauersachs <ingo@jitsi.org>
Date: Thu, 3 Jan 2013 22:35:10 +0000
Subject: [PATCH] Avoid recreation of SRTP context for every packet

---
 .../transform/sdes/SDesControlImpl.java       |  3 +-
 .../transform/sdes/SDesTransformEngine.java   | 66 ++++++++++--------
 .../srtp/AsymmetricSRTPTransformer.java       | 69 -------------------
 .../transform/srtp/SRTCPTransformer.java      | 40 +++++------
 ...ormEngine.java => SRTPContextFactory.java} | 37 ++--------
 .../transform/srtp/SRTPTransformer.java       | 40 +++++------
 .../transform/zrtp/ZRTPTransformEngine.java   | 24 +++----
 7 files changed, 97 insertions(+), 182 deletions(-)
 delete mode 100644 src/org/jitsi/impl/neomedia/transform/srtp/AsymmetricSRTPTransformer.java
 rename src/org/jitsi/impl/neomedia/transform/srtp/{SRTPTransformEngine.java => SRTPContextFactory.java} (71%)

diff --git a/src/org/jitsi/impl/neomedia/transform/sdes/SDesControlImpl.java b/src/org/jitsi/impl/neomedia/transform/sdes/SDesControlImpl.java
index 28355df1..d1a5db19 100644
--- a/src/org/jitsi/impl/neomedia/transform/sdes/SDesControlImpl.java
+++ b/src/org/jitsi/impl/neomedia/transform/sdes/SDesControlImpl.java
@@ -151,7 +151,8 @@ public TransformEngine getTransformEngine()
     {
         if(engine == null)
         {
-            engine = new SDesTransformEngine(this);
+            engine = new SDesTransformEngine(selectedInAttribute,
+                    selectedOutAttribute);
         }
         return engine;
     }
diff --git a/src/org/jitsi/impl/neomedia/transform/sdes/SDesTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/sdes/SDesTransformEngine.java
index 38953263..1f5dacb4 100644
--- a/src/org/jitsi/impl/neomedia/transform/sdes/SDesTransformEngine.java
+++ b/src/org/jitsi/impl/neomedia/transform/sdes/SDesTransformEngine.java
@@ -6,31 +6,48 @@
  */
 package org.jitsi.impl.neomedia.transform.sdes;
 
+import org.jitsi.impl.neomedia.transform.*;
 import org.jitsi.impl.neomedia.transform.srtp.*;
 
 import ch.imvs.sdes4j.srtp.*;
 
 /**
- * PacketTransformer for SDES based SRTP encryption.
+ * TransformEngine for SDES based SRTP encryption.
  * 
  * @author Ingo Bauersachs
  */
 public class SDesTransformEngine
-    extends AsymmetricSRTPTransformer
+    implements TransformEngine
 {
+    private SRTPTransformer srtpTransformer;
+    private SRTCPTransformer srtcpTransformer;
+
     /**
      * Creates a new instance of this class.
-     * @param sDesControl The control that supplies the key material.
+     * @param inAttribute Key material for the incoming stream.
+     * @param outAttribute Key material for the outgoing stream.
      */
-    public SDesTransformEngine(SDesControlImpl sDesControl)
+    public SDesTransformEngine(SrtpCryptoAttribute inAttribute,
+            SrtpCryptoAttribute outAttribute)
     {
-        super(
-            getTransformEngine(sDesControl.getOutAttribute()),
-            getTransformEngine(sDesControl.getInAttribute())
-        );
+        SRTPContextFactory forwardCtx = getTransformEngine(outAttribute);
+        SRTPContextFactory reverseCtx = getTransformEngine(inAttribute);
+        srtpTransformer = new SRTPTransformer(forwardCtx, reverseCtx);
+        srtcpTransformer = new SRTCPTransformer(forwardCtx, reverseCtx);
     }
 
-    private static SRTPTransformEngine getTransformEngine(
+    public void close()
+    {
+        if (srtpTransformer != null)
+            srtpTransformer.close();
+        if (srtcpTransformer != null)
+            srtcpTransformer.close();
+
+        srtpTransformer = null;
+        srtcpTransformer = null;
+    }
+
+    private static SRTPContextFactory getTransformEngine(
         SrtpCryptoAttribute attribute)
     {
         if (attribute.getSessionParams() != null
@@ -41,7 +58,7 @@ private static SRTPTransformEngine getTransformEngine(
         }
 
         SrtpCryptoSuite cs = attribute.getCryptoSuite();
-        return new SRTPTransformEngine(
+        return new SRTPContextFactory(
             getKey(attribute),
             getSalt(attribute),
             new SRTPPolicy(
@@ -59,25 +76,6 @@ private static SRTPTransformEngine getTransformEngine(
         );
     }
 
-//    /**
-//     * Get the key derivation parameter or the default from the SDES attribute.
-//     * @param attribute The negotiated SDES attribute for the stream.
-//     * @return The KDR parameter or 0 if not present.
-//     */
-//    private static long getKdr(SrtpCryptoAttribute attribute)
-//    {
-//        if (attribute.getSessionParams() != null)
-//        {
-//            for (SrtpSessionParam param : attribute.getSessionParams())
-//            {
-//                if (param instanceof KdrSessionParam)
-//                    return ((KdrSessionParam) param)
-//                        .getKeyDerivationRateExpanded();
-//            }
-//        }
-//        return 0;
-//    }
-
     private static byte[] getKey(SrtpCryptoAttribute attribute)
     {
         int length = attribute.getCryptoSuite().getEncKeyLength() / 8;
@@ -120,4 +118,14 @@ private static int getHashAlgorithm(SrtpCryptoSuite cs)
                 throw new IllegalArgumentException("Unsupported hash");
         }
     }
+
+    public PacketTransformer getRTPTransformer()
+    {
+        return srtpTransformer;
+    }
+
+    public PacketTransformer getRTCPTransformer()
+    {
+        return srtcpTransformer;
+    }
 }
diff --git a/src/org/jitsi/impl/neomedia/transform/srtp/AsymmetricSRTPTransformer.java b/src/org/jitsi/impl/neomedia/transform/srtp/AsymmetricSRTPTransformer.java
deleted file mode 100644
index 0e40c5d0..00000000
--- a/src/org/jitsi/impl/neomedia/transform/srtp/AsymmetricSRTPTransformer.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jitsi.impl.neomedia.transform.srtp;
-
-import org.jitsi.impl.neomedia.transform.*;
-
-/**
- * SRTP/SRTCP TransformEngine that uses different keys for forward and reverse
- * transformations.
- * 
- * @author Ingo Bauersachs
- */
-public class AsymmetricSRTPTransformer
-    implements TransformEngine
-{
-    private SRTPTransformEngine forwardEngine;
-    private SRTPTransformEngine reverseEngine;
-
-    public AsymmetricSRTPTransformer(SRTPTransformEngine forwardEngine,
-        SRTPTransformEngine reverseEngine)
-    {
-        this.forwardEngine = forwardEngine;
-        this.reverseEngine = reverseEngine;
-    }
-
-    /**
-     * Close the transformer engine.
-     * 
-     * The close functions closes all stored default crypto contexts. This 
-     * deletes key data and forces a cleanup of the crypto contexts.
-     */
-    public void close()
-    {
-        if (forwardEngine != null)
-            forwardEngine.close();
-        if (reverseEngine != null)
-            reverseEngine.close();
-
-        forwardEngine = null;
-        reverseEngine = null;
-    }
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.jitsi.impl.neomedia.transform.srtp.SRTPTransformEngine
-     * #getRTCPTransformer()
-     */
-    public PacketTransformer getRTCPTransformer()
-    {
-        return new SRTCPTransformer(forwardEngine, reverseEngine);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.jitsi.impl.neomedia.transform.srtp.SRTPTransformEngine
-     * #getRTPTransformer()
-     */
-    public PacketTransformer getRTPTransformer()
-    {
-        return new SRTPTransformer(forwardEngine, reverseEngine);
-    }
-}
diff --git a/src/org/jitsi/impl/neomedia/transform/srtp/SRTCPTransformer.java b/src/org/jitsi/impl/neomedia/transform/srtp/SRTCPTransformer.java
index 20d16d59..2b519bb2 100644
--- a/src/org/jitsi/impl/neomedia/transform/srtp/SRTCPTransformer.java
+++ b/src/org/jitsi/impl/neomedia/transform/srtp/SRTCPTransformer.java
@@ -21,8 +21,8 @@
 public class SRTCPTransformer
     implements PacketTransformer
 {
-    private final SRTPTransformEngine forwardEngine;
-    private final SRTPTransformEngine reverseEngine;
+    private final SRTPContextFactory forwardFactory;
+    private final SRTPContextFactory reverseFactory;
 
     /**
      * All the known SSRC's corresponding SRTCPCryptoContexts
@@ -32,28 +32,28 @@ public class SRTCPTransformer
     /**
      * Constructs a SRTCPTransformer object.
      * 
-     * @param engine The associated SRTPTransformEngine object for both
+     * @param factory The associated context factory for both
      *            transform directions.
      */
-    public SRTCPTransformer(SRTPTransformEngine engine)
+    public SRTCPTransformer(SRTPContextFactory factory)
     {
-        this(engine, engine);
+        this(factory, factory);
     }
 
     /**
      * Constructs a SRTCPTransformer object.
      * 
-     * @param forwardEngine The associated SRTPTransformEngine object for
-     *            forward transformations.
-     * @param reverseEngine The associated SRTPTransformEngine object for
-     *            reverse transformations.
+     * @param forwardFactory The associated context factory for forward
+     *            transformations.
+     * @param reverseFactory The associated context factory for reverse
+     *            transformations.
      */
     public SRTCPTransformer(
-            SRTPTransformEngine forwardEngine,
-            SRTPTransformEngine reverseEngine)
+            SRTPContextFactory forwardFactory,
+            SRTPContextFactory reverseFactory)
     {
-        this.forwardEngine = forwardEngine;
-        this.reverseEngine = reverseEngine;
+        this.forwardFactory = forwardFactory;
+        this.reverseFactory = reverseFactory;
         this.contexts = new Hashtable<Long, SRTCPCryptoContext>();
     }
 
@@ -66,9 +66,9 @@ public void close()
     {
         synchronized (contexts)
         {
-            forwardEngine.close();
-            if (reverseEngine != forwardEngine)
-                reverseEngine.close();
+            forwardFactory.close();
+            if (reverseFactory != forwardFactory)
+                reverseFactory.close();
 
             Iterator<Map.Entry<Long, SRTCPCryptoContext>> iter
                 = contexts.entrySet().iterator();
@@ -87,7 +87,7 @@ public void close()
 
     private SRTCPCryptoContext getContext(
             RawPacket pkt,
-            SRTPTransformEngine engine)
+            SRTPContextFactory engine)
     {
         long ssrc = pkt.getRTCPSSRC();
         SRTCPCryptoContext context = null;
@@ -118,7 +118,7 @@ private SRTCPCryptoContext getContext(
      */
     public RawPacket reverseTransform(RawPacket pkt)
     {
-        SRTCPCryptoContext context = getContext(pkt, reverseEngine);
+        SRTCPCryptoContext context = getContext(pkt, reverseFactory);
 
         return
             ((context != null) && context.reverseTransformPacket(pkt))
@@ -134,7 +134,7 @@ public RawPacket reverseTransform(RawPacket pkt)
      */
     public RawPacket transform(RawPacket pkt)
     {
-        SRTCPCryptoContext context = getContext(pkt, forwardEngine);
+        SRTCPCryptoContext context = getContext(pkt, forwardFactory);
 
         if(context != null)
         {
@@ -143,7 +143,7 @@ public RawPacket transform(RawPacket pkt)
         }
         else
         {
-            // The packet can not be encrypted. Thus, does not send it.
+            // The packet can not be encrypted. Thus, do not send it.
             return null;
         }
     }
diff --git a/src/org/jitsi/impl/neomedia/transform/srtp/SRTPTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/srtp/SRTPContextFactory.java
similarity index 71%
rename from src/org/jitsi/impl/neomedia/transform/srtp/SRTPTransformEngine.java
rename to src/org/jitsi/impl/neomedia/transform/srtp/SRTPContextFactory.java
index 7608d79c..bc49086f 100644
--- a/src/org/jitsi/impl/neomedia/transform/srtp/SRTPTransformEngine.java
+++ b/src/org/jitsi/impl/neomedia/transform/srtp/SRTPContextFactory.java
@@ -6,19 +6,14 @@
  */
 package org.jitsi.impl.neomedia.transform.srtp;
 
-import org.jitsi.impl.neomedia.transform.*;
-
 /**
- * SRTPTransformEngine class implements TransformEngine interface.
- * It stores important information / objects regarding SRTP processing.
- * Through SRTPTransformEngine, we can get the needed PacketTransformer, which
- * will be used by abstract TransformConnector classes.
- *
+ * The <tt>SRTPContextFactory</tt> creates the initial crypto contexts for RTP
+ * and RTCP encryption using the supplied key material.
+ * 
  * @author Bing SU (nova.su@gmail.com)
- *
+ * 
  */
-public class SRTPTransformEngine
-    implements TransformEngine
+public class SRTPContextFactory
 {
     /**
      * The default SRTPCryptoContext, which will be used to derivate other
@@ -41,7 +36,7 @@ public class SRTPTransformEngine
      * @param srtpPolicy SRTP policy
      * @param srtcpPolicy SRTCP policy
      */
-    public SRTPTransformEngine(byte[] masterKey, byte[] masterSalt,
+    public SRTPContextFactory(byte[] masterKey, byte[] masterSalt,
                                SRTPPolicy srtpPolicy, SRTPPolicy srtcpPolicy)
     {
 
@@ -72,26 +67,6 @@ public void close()
         defaultContextControl = null;
     }
 
-    /**
-     * Gets the <tt>PacketTransformer</tt> for RTCP packets.
-     *
-     * @return the <tt>PacketTransformer</tt> for RTCP packets
-     */
-    public PacketTransformer getRTCPTransformer()
-    {
-        return new SRTCPTransformer(this);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.jitsi.impl.media.transform.
-     * TransformEngine#getRTPTransformer()
-     */
-    public PacketTransformer getRTPTransformer()
-    {
-        return new SRTPTransformer(this);
-    }
-
     /**
      * Get the default SRTPCryptoContext
      *
diff --git a/src/org/jitsi/impl/neomedia/transform/srtp/SRTPTransformer.java b/src/org/jitsi/impl/neomedia/transform/srtp/SRTPTransformer.java
index 5d9aa209..fcbfd30f 100644
--- a/src/org/jitsi/impl/neomedia/transform/srtp/SRTPTransformer.java
+++ b/src/org/jitsi/impl/neomedia/transform/srtp/SRTPTransformer.java
@@ -44,8 +44,8 @@
 public class SRTPTransformer
     implements PacketTransformer
 {
-    private final SRTPTransformEngine forwardEngine;
-    private final SRTPTransformEngine reverseEngine;
+    private final SRTPContextFactory forwardFactory;
+    private final SRTPContextFactory reverseFactory;
 
     /**
      * All the known SSRC's corresponding SRTPCryptoContexts
@@ -55,28 +55,28 @@ public class SRTPTransformer
     /**
      * Initializes a new <tt>SRTPTransformer</tt> instance.
      * 
-     * @param engine the <tt>SRTPTransformEngine</tt> to be used by the new
-     * instance for both directions
+     * @param factory the context factory to be used by the new
+     * instance for both directions.
      */
-    public SRTPTransformer(SRTPTransformEngine engine)
+    public SRTPTransformer(SRTPContextFactory factory)
     {
-        this(engine, engine);
+        this(factory, factory);
     }
 
     /**
      * Constructs a SRTPTransformer object.
      * 
-     * @param forwardEngine The associated SRTPTransformEngine object for
-     *            forward transformations.
-     * @param reverseEngine The associated SRTPTransformEngine object for
-     *            reverse transformations.
+     * @param forwardFactory The associated context factory for forward
+     *            transformations.
+     * @param reverseFactory The associated context factory for reverse
+     *            transformations.
      */
     public SRTPTransformer(
-            SRTPTransformEngine forwardEngine,
-            SRTPTransformEngine reverseEngine)
+            SRTPContextFactory forwardFactory,
+            SRTPContextFactory reverseFactory)
     {
-        this.forwardEngine = forwardEngine;
-        this.reverseEngine = reverseEngine;
+        this.forwardFactory = forwardFactory;
+        this.reverseFactory = reverseFactory;
         this.contexts = new Hashtable<Long, SRTPCryptoContext>();
     }
 
@@ -89,9 +89,9 @@ public void close()
     {
         synchronized (contexts)
         {
-            forwardEngine.close();
-            if (reverseEngine != forwardEngine)
-                reverseEngine.close();
+            forwardFactory.close();
+            if (reverseFactory != forwardFactory)
+                reverseFactory.close();
 
             Iterator<Map.Entry<Long, SRTPCryptoContext>> iter
                 = contexts.entrySet().iterator();
@@ -110,7 +110,7 @@ public void close()
 
     private SRTPCryptoContext getContext(
             long ssrc,
-            SRTPTransformEngine engine,
+            SRTPContextFactory engine,
             int deriveSrtpKeysIndex)
     {
         SRTPCryptoContext context;
@@ -148,7 +148,7 @@ public RawPacket reverseTransform(RawPacket pkt)
             return null;
 
         SRTPCryptoContext context
-            = getContext(pkt.getSSRC(), reverseEngine, pkt.getSequenceNumber());
+            = getContext(pkt.getSSRC(), reverseFactory, pkt.getSequenceNumber());
 
         return
             ((context != null) && context.reverseTransformPacket(pkt))
@@ -164,7 +164,7 @@ public RawPacket reverseTransform(RawPacket pkt)
      */
     public RawPacket transform(RawPacket pkt)
     {
-        SRTPCryptoContext context = getContext(pkt.getSSRC(), forwardEngine, 0);
+        SRTPCryptoContext context = getContext(pkt.getSSRC(), forwardFactory, 0);
 
         context.transformPacket(pkt);
         return pkt;
diff --git a/src/org/jitsi/impl/neomedia/transform/zrtp/ZRTPTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/zrtp/ZRTPTransformEngine.java
index 40afcf53..89699901 100644
--- a/src/org/jitsi/impl/neomedia/transform/zrtp/ZRTPTransformEngine.java
+++ b/src/org/jitsi/impl/neomedia/transform/zrtp/ZRTPTransformEngine.java
@@ -856,12 +856,12 @@ public boolean srtpSecretsReady(
                         secrets.getInitSaltLen() / 8    // salt length
                 );
 
-                SRTPTransformEngine engine = new SRTPTransformEngine(secrets
+                SRTPContextFactory engine = new SRTPContextFactory(secrets
                         .getKeyInitiator(), secrets.getSaltInitiator(),
                         srtpPolicy, srtpPolicy);
 
-                srtpOutTransformer = engine.getRTPTransformer();
-                getRTCPTransformer().setSrtcpOut(engine.getRTCPTransformer());
+                srtpOutTransformer = new SRTPTransformer(engine);
+                getRTCPTransformer().setSrtcpOut(new SRTCPTransformer(engine));
             }
             else
             {
@@ -872,11 +872,11 @@ public boolean srtpSecretsReady(
                         secrets.getRespSaltLen() / 8    // salt length
                 );
 
-                SRTPTransformEngine engine = new SRTPTransformEngine(secrets
+                SRTPContextFactory engine = new SRTPContextFactory(secrets
                         .getKeyResponder(), secrets.getSaltResponder(),
                         srtpPolicy, srtpPolicy);
-                srtpOutTransformer = engine.getRTPTransformer();
-                getRTCPTransformer().setSrtcpOut(engine.getRTCPTransformer());
+                srtpOutTransformer = new SRTPTransformer(engine);
+                getRTCPTransformer().setSrtcpOut(new SRTCPTransformer(engine));
             }
         }
 
@@ -894,11 +894,11 @@ public boolean srtpSecretsReady(
                         secrets.getRespSaltLen() / 8    // salt length
                 );
 
-                SRTPTransformEngine engine = new SRTPTransformEngine(secrets
+                SRTPContextFactory engine = new SRTPContextFactory(secrets
                         .getKeyResponder(), secrets.getSaltResponder(),
                         srtpPolicy, srtpPolicy);
-                srtpInTransformer = engine.getRTPTransformer();
-                getRTCPTransformer().setSrtcpIn(engine.getRTCPTransformer());
+                srtpInTransformer = new SRTPTransformer(engine);
+                getRTCPTransformer().setSrtcpIn(new SRTCPTransformer(engine));
                 this.muted = false;
             }
             else
@@ -910,11 +910,11 @@ public boolean srtpSecretsReady(
                         secrets.getInitSaltLen() / 8    // salt length
                 );
 
-                SRTPTransformEngine engine = new SRTPTransformEngine(secrets
+                SRTPContextFactory engine = new SRTPContextFactory(secrets
                         .getKeyInitiator(), secrets.getSaltInitiator(),
                         srtpPolicy, srtpPolicy);
-                srtpInTransformer = engine.getRTPTransformer();
-                getRTCPTransformer().setSrtcpIn(engine.getRTCPTransformer());
+                srtpInTransformer = new SRTPTransformer(engine);
+                getRTCPTransformer().setSrtcpIn(new SRTCPTransformer(engine));
                 this.muted = false;
             }
         }
-- 
GitLab