<p>Jenkins2 <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/6364">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, approved
  Jenkins2: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">tests/rtp/strict_rtp: Add test for strict RTP support.<br><br>This adds a test that sets up a call between two Asterisk<br>instances with strict RTP enabled and symmetric RTP enabled.<br>Once media has started flowing a flood of minimal RTP packets<br>are sent to each instance. If any traffic is received on the<br>port that the RTP packets were sent from the test fails as<br>strict RTP protection did not discard the packets.<br><br>ASTERISK-27013<br><br>Change-Id: Id24462bed062424295d32618658d94ef4209a934<br>---<br>A tests/rtp/strict_rtp/configs/ast1/extensions.conf<br>A tests/rtp/strict_rtp/configs/ast1/pjsip.conf<br>A tests/rtp/strict_rtp/configs/ast1/rtp.conf<br>A tests/rtp/strict_rtp/configs/ast2/extensions.conf<br>A tests/rtp/strict_rtp/configs/ast2/pjsip.conf<br>A tests/rtp/strict_rtp/configs/ast2/rtp.conf<br>A tests/rtp/strict_rtp/strict_rtp.py<br>A tests/rtp/strict_rtp/test-config.yaml<br>A tests/rtp/tests.yaml<br>M tests/tests.yaml<br>10 files changed, 224 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/tests/rtp/strict_rtp/configs/ast1/extensions.conf b/tests/rtp/strict_rtp/configs/ast1/extensions.conf<br>new file mode 100644<br>index 0000000..eabe04d<br>--- /dev/null<br>+++ b/tests/rtp/strict_rtp/configs/ast1/extensions.conf<br>@@ -0,0 +1,15 @@<br>+<br>+[default]<br>+<br>+; -- Audio Source --<br>+<br>+exten => playback,1,NoOp()<br>+ same => n,Answer()<br>+ same => n,Playback(tt-monkeys)<br>+ same => n,Hangup()<br>+<br>+; -- Sender --<br>+<br>+exten => 1000,1,NoOp()<br>+ same => n,Dial(PJSIP/ast2)<br>+ same => n,Hangup()<br>diff --git a/tests/rtp/strict_rtp/configs/ast1/pjsip.conf b/tests/rtp/strict_rtp/configs/ast1/pjsip.conf<br>new file mode 100644<br>index 0000000..c633496<br>--- /dev/null<br>+++ b/tests/rtp/strict_rtp/configs/ast1/pjsip.conf<br>@@ -0,0 +1,19 @@<br>+[global]<br>+debug=yes<br>+<br>+[local-transport-udp]<br>+type=transport<br>+bind=127.0.0.1:5060<br>+protocol=udp<br>+<br>+[ast2]<br>+type=aor<br>+contact=sip:ast2@127.0.0.2:5060<br>+<br>+[ast2]<br>+type=endpoint<br>+aors=ast2<br>+context=default<br>+allow=!all,ulaw,alaw<br>+direct_media=no<br>+rtp_symmetric=yes<br>diff --git a/tests/rtp/strict_rtp/configs/ast1/rtp.conf b/tests/rtp/strict_rtp/configs/ast1/rtp.conf<br>new file mode 100644<br>index 0000000..25f04dd<br>--- /dev/null<br>+++ b/tests/rtp/strict_rtp/configs/ast1/rtp.conf<br>@@ -0,0 +1,4 @@<br>+[general]<br>+rtpstart=10000<br>+rtpend=10002<br>+strictrtp=yes<br>diff --git a/tests/rtp/strict_rtp/configs/ast2/extensions.conf b/tests/rtp/strict_rtp/configs/ast2/extensions.conf<br>new file mode 100644<br>index 0000000..4848420<br>--- /dev/null<br>+++ b/tests/rtp/strict_rtp/configs/ast2/extensions.conf<br>@@ -0,0 +1,9 @@<br>+<br>+[default]<br>+<br>+; -- Receiver --<br>+<br>+exten => ast2,1,NoOp()<br>+ same => n,Answer()<br>+ same => n,Echo()<br>+<br>diff --git a/tests/rtp/strict_rtp/configs/ast2/pjsip.conf b/tests/rtp/strict_rtp/configs/ast2/pjsip.conf<br>new file mode 100644<br>index 0000000..4db6013<br>--- /dev/null<br>+++ b/tests/rtp/strict_rtp/configs/ast2/pjsip.conf<br>@@ -0,0 +1,24 @@<br>+[global]<br>+debug=yes<br>+<br>+[local-transport-udp]<br>+type=transport<br>+bind=127.0.0.2:5060<br>+protocol=udp<br>+<br>+[ast1]<br>+type=identify<br>+endpoint=ast1<br>+match=127.0.0.1<br>+<br>+[ast1]<br>+type=aor<br>+contact=sip:ast1@127.0.0.1:5060<br>+<br>+[ast1]<br>+type=endpoint<br>+aors=ast1<br>+context=default<br>+allow=!all,ulaw,alaw<br>+direct_media=no<br>+rtp_symmetric=yes<br>diff --git a/tests/rtp/strict_rtp/configs/ast2/rtp.conf b/tests/rtp/strict_rtp/configs/ast2/rtp.conf<br>new file mode 100644<br>index 0000000..cb64420<br>--- /dev/null<br>+++ b/tests/rtp/strict_rtp/configs/ast2/rtp.conf<br>@@ -0,0 +1,4 @@<br>+[general]<br>+rtpstart=10100<br>+rtpend=10102<br>+strictrtp=yes<br>diff --git a/tests/rtp/strict_rtp/strict_rtp.py b/tests/rtp/strict_rtp/strict_rtp.py<br>new file mode 100644<br>index 0000000..a782152<br>--- /dev/null<br>+++ b/tests/rtp/strict_rtp/strict_rtp.py<br>@@ -0,0 +1,96 @@<br>+"""Strict RTP verification<br>+<br>+This module sends a flood of RTP packets to a target and considers the<br>+test failed if we receive any traffic back.<br>+<br>+Copyright (C) 2017, Digium, Inc.<br>+Joshua Colp <jcolp@digium.com><br>+<br>+This program is free software, distributed under the terms of<br>+the GNU General Public License Version 2.<br>+"""<br>+<br>+import logging<br>+from datetime import datetime<br>+<br>+from twisted.internet.protocol import DatagramProtocol<br>+from twisted.internet import reactor<br>+<br>+LOGGER = logging.getLogger(__name__)<br>+<br>+<br>+class StrictRtpTester(object):<br>+    """A pluggable module for verifying the strict RTP functionality"""<br>+<br>+    class NoAnswerProtocol(DatagramProtocol):<br>+        """The twisted NoAnswerProtocol that fails the test if any packets are received<br>+        """<br>+<br>+        def __init__(self, test_object):<br>+            """Constructor<br>+<br>+            Keyword Arguments:<br>+            test_object Our one and only test object<br>+            """<br>+            self.test_object = test_object<br>+<br>+        def datagramReceived(self, data, (host, port)):<br>+            """Callback for when a datagram is received<br>+<br>+            Keyword Arguments:<br>+            data         The actual packet<br>+            (host, port) Tuple of source host and port<br>+            """<br>+            LOGGER.debug('Packet received from {0}:{1}\n{2}'.format(<br>+                host, port, data))<br>+<br>+            self.test_object.set_passed(False)<br>+<br>+    def __init__(self, module_config, test_object):<br>+        """Constructor<br>+<br>+        Keyword Arguments:<br>+        module_config The configuration for this pluggable module<br>+        test_object   The one and only test object<br>+        """<br>+<br>+        self.packet_count = 8<br>+<br>+        # Use the AMI callback to know for sure we are fully booted<br>+        self.test_object = test_object<br>+        test_object.register_ami_observer(self.ami_connect_cb)<br>+<br>+    def ami_connect_cb(self, ami):<br>+        """Callback called when AMI connects<br>+<br>+        Keyword Arguments:<br>+        ami The AMI manager object for our Asterisk instance<br>+        """<br>+        ami.registerEvent('RTCPReceived', self.rtcp_received_handler)<br>+<br>+    def rtcp_received_handler(self, ami, event):<br>+        """RTCPReceived callback<br>+<br>+        Keyword Arguments:<br>+        ami   The AMI protocol instance<br>+        event The Newchannel event<br>+        """<br>+        if event['sentpackets'] != '250':<br>+            return<br>+<br>+        self.test_object.set_passed(True)<br>+        protocol = StrictRtpTester.NoAnswerProtocol(self.test_object)<br>+        reactor.listenUDP(0, protocol)<br>+<br>+        # Determine the target of the packets from the RTCPReceived event<br>+        (host, port) = event["to"].split(":")<br>+<br>+        # Construct a minimal RTP header by setting the version to 2<br>+        header = bytearray(12)<br>+        header[0] = (2 << 6) & 0xC0<br>+<br>+        for packet in range(self.packet_count):<br>+            # Set the sequence number to the packet number<br>+            header[2] = (packet & 0xFF00) >> 8<br>+            header[3] = (packet & 0xFF)<br>+            protocol.transport.write(header, (host, int(port) - 1))<br>diff --git a/tests/rtp/strict_rtp/test-config.yaml b/tests/rtp/strict_rtp/test-config.yaml<br>new file mode 100644<br>index 0000000..e5d3c88<br>--- /dev/null<br>+++ b/tests/rtp/strict_rtp/test-config.yaml<br>@@ -0,0 +1,49 @@<br>+testinfo:<br>+    summary: 'Verify the strict RTP functionality of the RTP stack'<br>+    description: |<br>+        This test verifies that during a call with strict RTP and symmetric RTP<br>+        enabled that the act of sending multiple RTP packets at the same time<br>+        does not cause media to be taken away from the existing target. The test<br>+        listens for RTCP events which indicate media is flowing. The target RTP<br>+        address information is extracted from these and multiple basic RTP packets<br>+        sent. If any UDP traffic is received on the port that the packets were<br>+        sent from the test fails. If no packets are received the test passes.<br>+<br>+test-modules:<br>+    add-test-to-search-path: True<br>+    test-object:<br>+        config-section: test-object-config<br>+        typename: 'test_case.TestCaseModule'<br>+    modules:<br>+        -<br>+            typename: 'pluggable_modules.Originator'<br>+            config-section: originator-config<br>+        -<br>+            config-section: 'hangup-monitor'<br>+            typename: 'pluggable_modules.HangupMonitor'<br>+        -<br>+            typename: 'strict_rtp.StrictRtpTester'<br>+            config-section: dummy-config<br>+<br>+test-object-config:<br>+    asterisk-instances: 2<br>+    connect-ami: True<br>+<br>+hangup-monitor:<br>+    ids: '0'<br>+<br>+originator-config:<br>+    channel: 'Local/1000@default'<br>+    exten: 'playback'<br>+    context: 'default'<br>+    priority: 1<br>+    async: True<br>+    trigger: 'ami_connect'<br>+    async: True<br>+<br>+dummy-config:<br>+<br>+properties:<br>+    minversion: '13.16.1'<br>+    dependencies:<br>+        - asterisk : 'chan_pjsip'<br>diff --git a/tests/rtp/tests.yaml b/tests/rtp/tests.yaml<br>new file mode 100644<br>index 0000000..4a5db65<br>--- /dev/null<br>+++ b/tests/rtp/tests.yaml<br>@@ -0,0 +1,3 @@<br>+# Enter tests here in the order they should be considered for execution:<br>+tests:<br>+    - test: 'strict_rtp'<br>diff --git a/tests/tests.yaml b/tests/tests.yaml<br>index e3a0b07..9d7ef0f 100644<br>--- a/tests/tests.yaml<br>+++ b/tests/tests.yaml<br>@@ -37,3 +37,4 @@<br>     - dir: 'sorcery'<br>     - test: 'remote-test'<br>     - dir: 'codecs'<br>+    - dir: 'rtp'<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/6364">change 6364</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/6364"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: testsuite </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Id24462bed062424295d32618658d94ef4209a934 </div>
<div style="display:none"> Gerrit-Change-Number: 6364 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>