[svn-commits] twilson: testsuite/asterisk/trunk r2819 - in /asterisk/trunk: configs/ config...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Dec 1 13:47:08 CST 2011


Author: twilson
Date: Thu Dec  1 13:47:01 2011
New Revision: 2819

URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=2819
Log:
Add test to verify when username leaked due to nat settings

Review: https://reviewboard.asterisk.org/r/1590/

Added:
    asterisk/trunk/configs/http.conf   (with props)
    asterisk/trunk/lib/python/asterisk/syncami.py   (with props)
    asterisk/trunk/lib/python/qm.py   (with props)
    asterisk/trunk/tests/channels/SIP/nat_supertest/
    asterisk/trunk/tests/channels/SIP/nat_supertest/configs/
    asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/
    asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/extensions.conf   (with props)
    asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/sip.conf   (with props)
    asterisk/trunk/tests/channels/SIP/nat_supertest/run-test   (with props)
    asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/
    asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/inject.csv   (with props)
    asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/register.xml   (with props)
    asterisk/trunk/tests/channels/SIP/nat_supertest/test-config.yaml   (with props)
Modified:
    asterisk/trunk/configs/branch-1.4/manager.conf
    asterisk/trunk/configs/manager.conf
    asterisk/trunk/tests/channels/SIP/tests.yaml

Modified: asterisk/trunk/configs/branch-1.4/manager.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/configs/branch-1.4/manager.conf?view=diff&rev=2819&r1=2818&r2=2819
==============================================================================
--- asterisk/trunk/configs/branch-1.4/manager.conf (original)
+++ asterisk/trunk/configs/branch-1.4/manager.conf Thu Dec  1 13:47:01 2011
@@ -1,7 +1,8 @@
 [general]
 #include "manager.general.conf.inc"
 
-enabled = no
+enabled = yes
+webenabled = yes
 port = 5038
 bindaddr = 127.0.0.1
 

Added: asterisk/trunk/configs/http.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/configs/http.conf?view=auto&rev=2819
==============================================================================
--- asterisk/trunk/configs/http.conf (added)
+++ asterisk/trunk/configs/http.conf Thu Dec  1 13:47:01 2011
@@ -1,0 +1,5 @@
+[general]
+enabled=yes
+bindaddr=127.0.0.1
+bindport=8088
+prefix=

Propchange: asterisk/trunk/configs/http.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/configs/http.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/configs/http.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: asterisk/trunk/configs/manager.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/configs/manager.conf?view=diff&rev=2819&r1=2818&r2=2819
==============================================================================
--- asterisk/trunk/configs/manager.conf (original)
+++ asterisk/trunk/configs/manager.conf Thu Dec  1 13:47:01 2011
@@ -1,5 +1,6 @@
 [general]
 enabled = yes
+webenabled = yes
 port = 5038
 bindaddr = 127.0.0.1
 

Added: asterisk/trunk/lib/python/asterisk/syncami.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/lib/python/asterisk/syncami.py?view=auto&rev=2819
==============================================================================
--- asterisk/trunk/lib/python/asterisk/syncami.py (added)
+++ asterisk/trunk/lib/python/asterisk/syncami.py Thu Dec  1 13:47:01 2011
@@ -1,0 +1,67 @@
+from urllib import urlencode
+from email.parser import HeaderParser
+try:
+    from httplib import *
+except:
+    from http.client import *
+
+
+class InvalidAMIResponse(Exception):
+    def __init__(self, response):
+        self.response = response
+
+    def __str__(self):
+        return repr(self.response)
+
+
+class SyncAMI(object):
+    """ A class for synchronously handling AMI actions and responses over HTTP
+    It currently only raises an error on non-200 responses from the server. It
+    would be a good idea to offer built-in checking of the Response header for
+    non-success results, but this behavior differs between different versions
+    of Asterisk, so for now we just return the response and can check the
+    the Response header outside of the library. A login is attempted during
+    construction."""
+
+    def __init__(self, location="127.0.0.1:8088", path="/rawman", username="user", secret="mysecret"):
+        self.location = location
+        self.path = path
+        self.cookie = None
+        try:
+            self.con = HTTPConnection(location)
+            self.login(username, secret)
+        except:
+            raise
+
+    def login(self, username, secret):
+        return self.send({'action': 'login', 'username': username, 'secret': secret})
+
+    def logoff(self):
+        return self.send({'action': 'logoff'})
+
+    def send(self, args):
+        """ Send an AMI request "action" given a dict of header values
+        Returns an email.message.Message which we could wrap with our
+        own AMIMessage class if we were feeling industrious. You can get
+        access the  headers via:
+            ami = SyncAMI()
+            res = ami.send({'action': 'ping'})
+            res.items() => [("header", "value"), ...]
+            res.get("header") => "value"
+            res.get_all("header") => ["value", ...]"""
+
+        headers = {}
+        params = "?" + urlencode(args)
+        if self.cookie is not None:
+            headers['Cookie'] = self.cookie
+        self.con.request("GET", self.path + params, headers=headers)
+        res = self.con.getresponse()
+        if res.status != 200:
+            raise InvalidAMIResponse(res)
+        self.cookie = res.getheader('set-cookie', None)
+        data = res.read()
+        p = HeaderParser()
+
+        return p.parsestr(data)
+
+

Propchange: asterisk/trunk/lib/python/asterisk/syncami.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/lib/python/asterisk/syncami.py
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/lib/python/asterisk/syncami.py
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/lib/python/qm.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/lib/python/qm.py?view=auto&rev=2819
==============================================================================
--- asterisk/trunk/lib/python/qm.py (added)
+++ asterisk/trunk/lib/python/qm.py Thu Dec  1 13:47:01 2011
@@ -1,0 +1,270 @@
+#!/usr/bin/env python
+
+"""
+This class implements the Quine-McCluskey algorithm for minimization of boolean
+functions.
+
+Based on code from Robert Dick <dickrp at eecs.umich.edu> and Pat Maupin
+<pmaupin at gmail.com>. Most of the original code was re-written for performance
+reasons.
+
+NOTE: The author stated that this code was in the Public Domain
+
+>>> qm = QM(['A','B'])
+
+>>> qm.get_function(qm.solve([],[])[1])
+'0'
+>>> qm.get_function(qm.solve([1,3],[0,2])[1])
+'1'
+>>> qm.get_function(qm.solve([0,1,2,3],[])[1])
+'1'
+>>> qm.get_function(qm.solve([3],[])[1])
+'(A AND B)'
+>>> qm.get_function(qm.solve([0],[])[1])
+'((NOT A) AND (NOT B))'
+>>> qm.get_function(qm.solve([1,3],[])[1])
+'A'
+>>> qm.get_function(qm.solve([1],[3])[1])
+'A'
+>>> qm.get_function(qm.solve([2,3],[])[1])
+'B'
+>>> qm.get_function(qm.solve([0,2],[])[1])
+'(NOT A)'
+>>> qm.get_function(qm.solve([0,1],[])[1])
+'(NOT B)'
+>>> qm.get_function(qm.solve([1,2,3],[])[1])
+'(A OR B)'
+>>> qm.get_function(qm.solve([0,1,2],[])[1])
+'((NOT B) OR (NOT A))'
+"""
+
+class QM:
+  def __init__(self, variables):
+    """
+    Initialize the Quine-McCluskey solver.
+
+    variables: a list of strings that are the names of the variables used in
+    the boolean functions
+    """
+
+    self.variables = variables
+    self.numvars = len(variables)
+
+  def solve(self, ones, dc):
+    """
+    Executes the Quine-McCluskey algorithm and returns its results.
+
+    ones: a list of indices for the minterms for which the function evaluates
+    to 1
+    dc: a list of indices for the minterms for which we do not care about the
+    function evaluation
+
+    returns: a tuple a,b; a is the complexity of the result and b is a list of
+    minterms which is the minified boolean function expressed as a sum of
+    products
+    """
+
+    # Handle special case for functions that always evaluate to True or False.
+    if len(ones) == 0:
+      return 0,'0'
+    if len(ones) + len(dc) == 1<<self.numvars:
+      return 0,'1'
+
+    primes = self.compute_primes(ones + dc)
+    return self.unate_cover(list(primes), ones)
+
+  def compute_primes(self, cubes):
+    """
+    Find all prime implicants of the function.
+
+    cubes: a list of indices for the minterms for which the function evaluates
+    to 1 or don't-care.
+    """
+
+    sigma = []
+    for i in xrange(self.numvars+1):
+      sigma.append(set())
+    for i in cubes:
+      sigma[bitcount(i)].add((i,0))
+
+    primes = set()
+    while sigma:
+      nsigma = []
+      redundant = set()
+      for c1, c2 in zip(sigma[:-1], sigma[1:]):
+        nc = set()
+        for a in c1:
+          for b in c2:
+            m = merge(a, b)
+            if m != None:
+              nc.add(m)
+              redundant |= set([a, b])
+        nsigma.append(nc)
+      primes |= set(c for cubes in sigma for c in cubes) - redundant
+      sigma = nsigma
+    return primes
+
+  def unate_cover(self, primes, ones):
+    """
+    Use the prime implicants to find the essential prime implicants of the
+    function, as well as other prime implicants that are necessary to cover
+    the function. This method uses the Petrick's method, which is a technique
+    for determining all minimum sum-of-products solutions from a prime implicant
+    chart.
+
+    primes: the prime implicants that we want to minimize.
+    ones: a list of indices for the minterms for which we want the function to
+    evaluate to 1.
+    """
+
+    chart = []
+    for one in ones:
+      column = []
+      for i in xrange(len(primes)):
+        if (one & (~primes[i][1])) == primes[i][0]:
+          column.append(i)
+      chart.append(column)
+
+    covers = []
+    if len(chart) > 0:
+      covers = [set([i]) for i in chart[0]]
+    for i in xrange(1,len(chart)):
+      new_covers = []
+      for cover in covers:
+        for prime_index in chart[i]:
+          x = set(cover)
+          x.add(prime_index)
+          append = True
+          for j in xrange(len(new_covers)-1,-1,-1):
+            if x <= new_covers[j]:
+              del new_covers[j]
+            elif x > new_covers[j]:
+              append = False
+          if append:
+            new_covers.append(x)
+      covers = new_covers
+
+    min_complexity = 99999999
+    for cover in covers:
+      primes_in_cover = [primes[prime_index] for prime_index in cover]
+      complexity = self.calculate_complexity(primes_in_cover)
+      if complexity < min_complexity:
+        min_complexity = complexity
+        result = primes_in_cover
+
+    return min_complexity,result
+
+  def calculate_complexity(self, minterms):
+    """
+    Calculate the complexity of the given function. The complexity is calculated
+    based on the following rules:
+      A NOT gate adds 1 to the complexity.
+      A n-input AND or OR gate adds n to the complexity.
+
+    minterms: a list of minterms that form the function
+
+    returns: an integer that is the complexity of the function
+
+    >>> qm = QM(['A','B','C'])
+
+    >>> qm.calculate_complexity([(1,6)])
+    0
+    >>> qm.calculate_complexity([(0,6)])
+    1
+    >>> qm.calculate_complexity([(3,4)])
+    2
+    >>> qm.calculate_complexity([(7,0)])
+    3
+    >>> qm.calculate_complexity([(1,6),(2,5),(4,3)])
+    3
+    >>> qm.calculate_complexity([(0,6),(2,5),(4,3)])
+    4
+    >>> qm.calculate_complexity([(0,6),(0,5),(4,3)])
+    5
+    >>> qm.calculate_complexity([(0,6),(0,5),(0,3)])
+    6
+    >>> qm.calculate_complexity([(3,4),(7,0),(5,2)])
+    10
+    >>> qm.calculate_complexity([(1,4),(7,0),(5,2)])
+    11
+    >>> qm.calculate_complexity([(2,4),(7,0),(5,2)])
+    11
+    >>> qm.calculate_complexity([(0,4),(7,0),(5,2)])
+    12
+    >>> qm.calculate_complexity([(0,4),(0,0),(5,2)])
+    15
+    >>> qm.calculate_complexity([(0,4),(0,0),(0,2)])
+    17
+    """
+
+    complexity = len(minterms)
+    if complexity == 1:
+      complexity = 0
+    mask = (1<<self.numvars)-1
+    for minterm in minterms:
+      masked = ~minterm[1] & mask
+      term_complexity = bitcount(masked)
+      if term_complexity == 1:
+        term_complexity = 0
+      complexity += term_complexity
+      complexity += bitcount(~minterm[0] & masked)
+
+    return complexity
+
+  def get_function(self, minterms):
+    """
+    Return in human readable form a sum of products function.
+
+    minterms: a list of minterms that form the function
+
+    returns: a string that represents the function using operators AND, OR and
+    NOT.
+    """
+
+    if isinstance(minterms,str):
+      return minterms
+
+    def parentheses(glue, array):
+      if len(array) > 1:
+        return ''.join(['(',glue.join(array),')'])
+      else:
+        return glue.join(array)
+
+    or_terms = []
+    for minterm in minterms:
+      and_terms = []
+      for j in xrange(len(self.variables)):
+        if minterm[0] & 1<<j:
+          and_terms.append(self.variables[j])
+        elif not minterm[1] & 1<<j:
+          and_terms.append('(NOT %s)' % self.variables[j])
+      or_terms.append(parentheses(' AND ', and_terms))
+    return parentheses(' OR ', or_terms)
+
+def bitcount(i):
+  """ Count set bits of the input. """
+
+  res = 0
+  while i > 0:
+    res += i&1
+    i>>=1
+  return res
+
+def is_power_of_two_or_zero(x):
+  """
+  Determine if an input is zero or a power of two. Alternative, determine if an
+  input has at most 1 bit set.
+  """
+
+  return (x & (~x + 1)) == x
+
+def merge(i, j):
+  """ Combine two minterms. """
+
+  if i[1] != j[1]:
+    return None
+  y = i[0] ^ j[0]
+  if not is_power_of_two_or_zero(y):
+    return None
+  return (i[0] & j[0],i[1]|y)
+

Propchange: asterisk/trunk/lib/python/qm.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/lib/python/qm.py
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/lib/python/qm.py
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/extensions.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/extensions.conf?view=auto&rev=2819
==============================================================================
--- asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/extensions.conf (added)
+++ asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/extensions.conf Thu Dec  1 13:47:01 2011
@@ -1,0 +1,6 @@
+[general]
+static=yes
+writeprotect=no
+clearglobalvars=no
+
+[default]

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/sip.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/sip.conf?view=auto&rev=2819
==============================================================================
--- asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/sip.conf (added)
+++ asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/sip.conf Thu Dec  1 13:47:01 2011
@@ -1,0 +1,10 @@
+[general]
+allowguest=no
+alwaysauthreject=yes
+nat=yes;general
+
+[existing]
+type=friend
+host=dynamic
+secret=1234
+nat=yes;specific

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/sip.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/sip.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/configs/ast1/sip.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/channels/SIP/nat_supertest/run-test
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/channels/SIP/nat_supertest/run-test?view=auto&rev=2819
==============================================================================
--- asterisk/trunk/tests/channels/SIP/nat_supertest/run-test (added)
+++ asterisk/trunk/tests/channels/SIP/nat_supertest/run-test Thu Dec  1 13:47:01 2011
@@ -1,0 +1,163 @@
+#!/usr/bin/env python
+'''
+Copyright (C) 2011, Digium, Inc.
+Terry Wilson <twilson at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+'''
+
+import sys
+import os
+import logging
+
+sys.path.append("lib/python")
+
+from asterisk.TestCase import TestCase
+from asterisk.sipp import SIPpScenario
+from asterisk.syncami import SyncAMI, InvalidAMIResponse
+from twisted.internet import reactor
+from qm import QM
+
+TEST_DIR = os.path.dirname(os.path.realpath(__file__))
+logger = logging.getLogger(__name__)
+INJECT_FILE = TEST_DIR + "/sipp/inject.csv"
+
+expected_failures = {
+    'branch-1.4': [4, 6, 8, 10],
+    'branch-1.6.2': [4, 6, 8, 10],
+    'branch-1.8': [4, 8],
+    'branch-10': [4, 8],
+    'trunk': [4, 8]
+}
+
+nat_modes = {
+    'branch-1.4': {False: 'no', True: 'route'},
+    'branch-1.6.2': {False: 'no', True: 'route'},
+    'branch-1.8': {False: 'no', True: 'force_rport'},
+    'branch-10': {False: 'no', True: 'force_rport'},
+    'trunk': {False: 'no', True: 'force_rport'},
+}
+
+def compute_value(val):
+    """ Take an iterable of booleans (MSB-first) and return their integer value
+    For example:
+        compute_value((False, False)) => 0
+        compute_value((False, True)) => 1
+        compute_value((True, False)) => 2
+        compute_value((True, True)) => 3"""
+    return sum(map(lambda (n, x) : ((2 ** n) * int(x)), enumerate(reversed(val))))
+
+
+class SIPNatTest(TestCase):
+    def __init__(self):
+        super(SIPNatTest, self).__init__()
+        self.passed = False
+        self.create_asterisk()
+        self.failures = []
+
+    def run(self):
+        super(SIPNatTest, self).run()
+        self.create_ami_factory()
+
+    def get_nat_value(self, route):
+        return nat_modes[self.ast[0].ast_version.branch][route]
+
+    def update_config(self, general_nat, peer_nat):
+        global_nat = self.get_nat_value(general_nat)
+        spec_nat = self.get_nat_value(peer_nat)
+        message = {
+            'Action': 'UpdateConfig',
+            'SrcFilename': 'sip.conf',
+            'DstFilename': 'sip.conf',
+            'Action-000000': 'Update',
+            'Var-000000': 'nat'
+        }
+
+        try:
+            message['Value-000000'] = global_nat
+            message['Cat-000000'] = 'general'
+            self.syncami.send(message)
+
+            message['Value-000000'] = spec_nat
+            message['Cat-000000'] = 'existing'
+            message['Reload'] = 'chan_sip.so'
+            self.syncami.send(message)
+        except InvalidAMIResponse as err:
+            logger.warn("Inavlid Response: %s\n" % (err,))
+            reactor.stop()
+
+    def update_inject_file(self, rport_specified, port_matches_via):
+        inject_str = '%d;%s\n' % ((5062,5061)[port_matches_via], ('ignored', 'rport')[rport_specified])
+
+        try:
+            os.remove(INJECT_FILE)
+        except:
+            pass
+        f = open(INJECT_FILE, 'w+')
+        f.writelines(["SEQUENTIAL\n", inject_str])
+        f.close()
+
+    def run_combos(self):
+        scenario_def = {'scenario': 'register.xml', '-p': '5061', '-recv_timeout': '1000', '-inf': INJECT_FILE}
+        for general_nat in [False, True]:
+            for peer_nat in [False, True]:
+                self.update_config(general_nat, peer_nat)
+                for rport_specified in [False, True]:
+                    for port_matches_via in [False, True]:
+                        existing_result = None
+                        nonexisting_result = None
+                        self.update_inject_file(rport_specified, port_matches_via)
+                        for peer_name in ["existing", "nonexisting"]:
+                            scenario_def['-s'] = peer_name
+                            scenario = SIPpScenario(TEST_DIR, scenario_def)
+                            scenario.run()
+                            if peer_name == "existing":
+                                existing_result = scenario.waitAndEvaluate()
+                            else:
+                                nonexisting_result = scenario.waitAndEvaluate()
+                            self.reset_timeout()
+                        if nonexisting_result != existing_result:
+                            values = [general_nat, peer_nat, rport_specified, port_matches_via]
+                            logger.debug("Failed global_nat=%s peer_nat=%s rport_sepcified=%s port_matches_via=%s" % (self.get_nat_value(general_nat),self. get_nat_value(peer_nat), rport_specified, port_matches_via))
+                            self.failures.append(compute_value(values))
+
+        # order of variables is least significant first!
+        qm = QM(["port_matches_via", "rport_specified", "peer_nat", "general_nat"])
+        logger.debug("Failures: %s" % (self.failures,))
+        try:
+            if self.failures == expected_failures[self.ast[0].ast_version.branch]:
+                self.passed = True
+                logger.info(qm.get_function(qm.solve(self.failures, [])[1]))
+            else:
+                logger.warn(qm.get_function(qm.solve(self.failures, [])[1]))
+        except KeyError:
+            log.error("We don't know the expected failures for branch: %s\n" % (self.ast[0].ast_version.branch,))
+            self.passed = True
+
+        reactor.stop()
+
+    def ami_connect(self, ami):
+        logger.debug("Connected to AMI")
+        # Use synchronous calls to AMI over HTTP to make life simpler
+        self.syncami = SyncAMI()
+        self.run_combos()
+
+
+def main():
+    test = SIPNatTest()
+    test.start_asterisk()
+    reactor.run()
+    test.stop_asterisk()
+
+    if test.passed:
+        return 0
+
+    return 1
+
+
+if __name__ == "__main__":
+    sys.exit(main())
+
+
+# vim:sw=4:ts=4:expandtab:textwidth=79

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/run-test
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/run-test
------------------------------------------------------------------------------
    svn:executable = *

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/run-test
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/run-test
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/inject.csv
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/inject.csv?view=auto&rev=2819
==============================================================================
--- asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/inject.csv (added)
+++ asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/inject.csv Thu Dec  1 13:47:01 2011
@@ -1,0 +1,2 @@
+SEQUENTIAL
+5061;rport

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/inject.csv
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/inject.csv
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/inject.csv
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/register.xml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/register.xml?view=auto&rev=2819
==============================================================================
--- asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/register.xml (added)
+++ asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/register.xml Thu Dec  1 13:47:01 2011
@@ -1,0 +1,32 @@
+<?xml version="1.0" encoding="ISO-8859-2" ?>
+
+<!--  Use with CSV file struct like: 5061,;rport;
+-->
+
+<scenario name="register_client">
+  <send>
+    <![CDATA[
+
+      REGISTER sip:[remote_ip] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[field0 line=0];branch=[branch];[field1 line=0]
+      From: <sip:[service]@[local_ip]>;tag=[call_number]
+      To: <sip:[service]@[local_ip]>
+      Call-ID: [call_id]
+      CSeq: [cseq] REGISTER
+      Contact: sip:[service]@[local_ip]:[local_port]
+      Max-Forwards: 10
+      Expires: 120
+      User-Agent: SIPp
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <!-- asterisk -->
+  <recv response="100" optional="true">
+  </recv>
+
+  <recv response="401">
+  </recv>
+
+</scenario>

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/register.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/register.xml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/sipp/register.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/channels/SIP/nat_supertest/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/channels/SIP/nat_supertest/test-config.yaml?view=auto&rev=2819
==============================================================================
--- asterisk/trunk/tests/channels/SIP/nat_supertest/test-config.yaml (added)
+++ asterisk/trunk/tests/channels/SIP/nat_supertest/test-config.yaml Thu Dec  1 13:47:01 2011
@@ -1,0 +1,9 @@
+testinfo:
+    summary:    'Test SIP realtime peer matching'
+    description: |
+        'Make sure that realtime peers are matched properly'
+properties:
+    minversion: '1.4'
+    dependencies:
+        - python : 'twisted'
+        - python : 'starpy'

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/test-config.yaml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/test-config.yaml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/channels/SIP/nat_supertest/test-config.yaml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: asterisk/trunk/tests/channels/SIP/tests.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/channels/SIP/tests.yaml?view=diff&rev=2819&r1=2818&r2=2819
==============================================================================
--- asterisk/trunk/tests/channels/SIP/tests.yaml (original)
+++ asterisk/trunk/tests/channels/SIP/tests.yaml Thu Dec  1 13:47:01 2011
@@ -27,3 +27,4 @@
     - test: 'realtime_sipregs'
     - test: 'realtime_nosipregs'
     - test: 'codec_negotiation'
+    - test: 'nat_supertest'




More information about the svn-commits mailing list