[OpenSER-Users] mediaproxy server NEW FEATURE!!!

Gonzalo J. Sambucaro gonzalo.sambucaro at mslc.com.ar
Fri Feb 29 14:25:23 CET 2008


Raju,
     Thanks for testing it, now I am working in making it more secure.

Regards,

Gonzalo.

> Gonzalo,
>
> Thanks!! It works very well esp. we have few clients
> behind DSL which is unstable and the connectivity is
> remarkably improved.
>
> Good contribution to mediaproxy.
>
> regards,
>
> Raju
> --- "Gonzalo J. Sambucaro"
> <gonzalo.sambucaro at mslc.com.ar> wrote:
>
>> Raju,
>>      please replase the file rtphandler.py.
>>
>> Regards,
>> Gonzalo.
>>
>> > Hi Gonzalo,
>> >
>> > Can you please let me know how I can try out this
>> > addition. I am currently using Mediaproxy 1.9.1
>> along
>> > with openser-tls-1.1.1.
>> >
>> >
>> > Please do let me know where I can get this patch.
>> >
>> > regards,
>> >
>> > Raju
>> > --- "Gonzalo J. Sambucaro"
>> > <gonzalo.sambucaro at mslc.com.ar> wrote:
>> >
>> >> Andreas,
>> >>         our local ISP´s are disconnecting DSL
>> lines
>> >> more ofthen but it
>> >> renews the IP almost instantaneously.
>> >>
>> >> Regards,
>> >> Gonzalo.
>> >>
>> >> > Hello,
>> >> > nice feature, i know the problem, because our
>> >> local ISP´s are
>> >> > disconnecting  DSL lines every 8 hours.
>> >> > But the DSL line needs nearly 8 seconds, to be
>> up
>> >> and running again(PPP
>> >> > dialup), if i can´t hear my
>> >> > partner for a few seconds i will disconnect the
>> >> line and redial, my
>> >> > opinion.
>> >> >
>> >> > Same in mobile environments, when the handover
>> >> doesn´t work, saying
>> >> > "hello? - hello?" -> hangup ->
>> >> > redial.
>> >> >
>> >> > But i´m willing to try, leave me a note, where
>> i
>> >> can download your
>> >> > version.
>> >> >
>> >> > regards,
>> >> > Andreas M.
>> >> >
>> >> >
>> >> >
>> >> > Gonzalo J. Sambucaro schrieb:
>> >> >> Folks,
>> >> >>       I developed a new feature in the Media
>> >> Proxy project of
>> >> >> AG-Proyect.
>> >> >> With this new feature the Media Proxy Server
>> is
>> >> now able to manage the
>> >> >> problem of the NAT IP change in an established
>> >> call. It is
>> >> >> currently in production and working without
>> any
>> >> problem.
>> >> >>
>> >> >> Somebody wants to test it?
>> >> >>
>> >> >> I would like to know what to do to make this
>> >> feature available to
>> >> >> everybody. Does anybody know?
>> >> >>
>> >> >> Regards,
>> >> >>
>> >> >> ------------------------------
>> >> >>
>> >> >> Details:
>> >> >> -------
>> >> >>       Supose that there is an established rtp
>> >> connection between two
>> >> >> endpoints and the media proxy is in the middle
>> >> doing the relay of
>> >> >> the rtp streams, let´s say
>> >> >>
>> >> >> (MP = mediaproxy)
>> >> >>
>> >> >> EP A <--------->[NAT with IP1]<-----------> MP
>> >> <--------------------> EP
>> >> >> B
>> >> >>
>> >> >> EP A sends rtp to MP_IP:MP_PORT  passing
>> through
>> >> the NAT box.
>> >> >> EP B sends rtp to MP_IP:MP_PORT  without
>> passing
>> >> through a NAT box.
>> >> >>
>> >> >> The MP know that the caller =
>> NAT_IP1:NAT_PORT1,
>> >> and the called =
>> >> >> EP_B_IP:EP_B_PORT
>> >> >>
>> >> >> Now, supose that the NAT box change their
>> PUBLIC
>> >> IP from IP1 to IP2, so
>> >> >> this escenary
>> >> >>
>> >> >> EP A <------->[NAT with IP1]<---------> MP
>> >> <-------------> EP B
>> >> >>
>> >> >> will change to this
>> >> >>
>> >> >> EP A <------->[NAT with IP2]<---------> MP
>> >> <--------------> EP B
>> >> >>
>> >> >> so the MP should detect that change of IPs and
>> >> continue relaying the rtp
>> >> >> streams but now to IP2:PORT2 instead of
>> >> IP1:PORT1.
>> >> >>
>> >> >> Well, that was the situation y have
>> experienced.
>> >> >>
>> >> >> To fix this, I developed this solution,
>> changing
>> >> rtphandler.py file:
>> >> >>
>> >> >> 1) When the first rtp packet of a source
>> arrives,
>> >> save the SSRC field in
>> >> >> the MP.
>> >> >>  - Save the SSRC of the caller.
>> >> >>  - Save the SSRC of the called.
>> >> >>
>> >> >> 2) If arrives a rtp packet with unknown source
>> IP
>> >> but with the same SSRC
>> >> >> field of some of the two streams, updates the
>> >> binding (with the new IP
>> >> >> detected) between the caller and the MP or
>> >> between the called and the MP
>> >> >> according to the field SSRC previously saved.
>> >> >>
>> >> >> Note: SSRC (RFC 3550 RTP),  (from the rfc:
>> "The
>> >> SSRC identifier carried
>> >> >> in
>> >> >> the RTP header and in various fields of RTCP
>> >> packets is a random 32-bit
>> >> >> number that is required to be globally unique
>> >> within an RTP session ")
>> >> >>
>> >> >> --------------------------------
>> >> >>
>> >> >
>> >> > --
>> >> > g,
>> >> > Andreas M.
>> >> >
>> >> > _______________________________________________
>> >> > Users mailing list
>> >> > Users at lists.openser.org
>> >> >
>> >>
>> >
>>
> http://lists.openser.org/cgi-bin/mailman/listinfo/users
>> >> >
>> >>
>> >>
>> >> --
>> >> Gonzalo J. Sambucaro
>> >> Ingeniería de Software
>> >> Tel: +54-341-4230504
>> >> MSLC
>> >> gonzalo.sambucaro at mslc.com.ar
>> >> www.mslc.com.ar
>> >> Ocampo y Esmeralda - Vivero de Empresas de Base
>> >> Tecnológica
>> >> Ciudad Universitaria Rosario UNR, CCT CONICET
>> >> Rosario - Santa Fé - Argentina
>> >>
>> >>
>> >> _______________________________________________
>> >> Users mailing list
>> >> Users at lists.openser.org
>> >>
>> >
>>
> http://lists.openser.org/cgi-bin/mailman/listinfo/users
>> >>
>> >
>> >
>>
>>
>> --
>> Gonzalo J. Sambucaro
>>
> === message truncated ===>
>> '''
>> Handle media stream relaying and provide control
>> ports to receive and
>> process requests from SER (SIP Express Router) or
>> the proxydispatcher.
>>
>> Copyright 2003-2005 Dan Pascu
>> '''
>>
>> import asyncore
>> import socket
>> import sys, os, grp, errno, traceback, atexit
>> import time
>> import struct
>> import re
>> import weakref
>>
>> from utilities import *
>> from datatypes import *
>> from version import release
>> from request import Request, InvalidRequestError
>> from configuration import readSettings,
>> ConfigSection, Boolean, dumpSection
>>
>>
>> class ProxyConfig(ConfigSection):
>>     _dataTypes = {'socket':     ControlSocket,
>>                   'proxyIP':    IPAddress,
>>                   'portRange':  PortRange,
>>                   'TOS':        HexNumber,
>>                   'listen':     NetworkAddress,
>>                   'allow':      NetworkRangeList}
>>     socket      = '/var/run/mediaproxy.sock'
>>     group       = 'openser'
>>     proxyIP     = thisHostIP ## defined in utilities
>>     portRange   = (60000, 65000)
>>     TOS         = 0xb8
>>     listen      = None
>>     allow       = None
>>     idleTimeout = 60
>>     holdTimeout = 60*60
>>     forceClose  = 0
>>
>>
>> ## We use this to overwrite some of the settings
>> above on a local basis if needed
>> readSettings('MediaProxy', ProxyConfig)
>> #dumpSection(ProxyConfig)
>>
>> if ProxyConfig.allow and NetworkRange('Any') not in
>> ProxyConfig.allow:
>>     ## Always add ourselves to the accept list
>>     myself = NetworkRange('127.0.0.1')
>>     if myself not in ProxyConfig.allow:
>>         ProxyConfig.allow.append(myself)
>>
>> maxDataSize = 8*1024
>>
>> try:
>>     from accounting import accounting, StopRecord,
>> StopRecordSerializer, QueuedItemProcessingThread
>> except ImportError:
>>     warning("accounting is enabled but the
>> accounting module is missing. accounting is not
>> available!")
>>     accounting = Null()
>>     dispatcher = Null()
>>     class StopRecord(object):
>>         def __new__(typ, *args, **kwargs):
>>             return None
>> else:
>>     class
>> DispatcherNotifyThread(QueuedItemProcessingThread):
>>         '''
>>         Notify the proxydispatcher of calls that did
>> timeout and provide
>>         the dispatcher with the accounting
>> information for them.
>>         '''
>>         def __init__(self):
>>
>> QueuedItemProcessingThread.__init__(self,
>> name='DispatcherNotify',
>> file='.dispatcher-notify.dat')
>>
>>         def process(self, record):
>>             address = record['dispatcher']
>>             expires = record['expires']
>>             del record['dispatcher'],
>> record['expires']
>>
>>             msg = 'timeout %s %s\n' % (record['id'],
>> StopRecordSerializer().dump(record))
>>
>>             s = socket.socket(socket.AF_INET,
>> socket.SOCK_STREAM)
>>             try:
>>                 s.settimeout(5)
>>             except AttributeError:
>>                 pass
>>             try:
>>                 start = time.time()
>>                 try:
>>                     s.connect(address)
>>                     s.send(msg)
>>                     result =
>> s.recv(maxDataSize).strip()
>>                 except (socket.error,
>> socket.gaierror, socket.herror, socket.timeout),
>> why:
>>                     try:               motive =
>> why[1]
>>                     except IndexError: motive = why
>>                     now = time.time()
>>                     if now < expires:
>>                         warning("couldn't notify
>> dispatcher at %s (%s). will retry later." %
>> (address[0], motive))
>>                         record['dispatcher'] =
>> address
>>                         record['expires'] = expires
>>                         # eventually use a different
>> queue only for failures
>>                         delay = 1
>>                         duration = now - start
>>                         if duration < delay:
>>
>> time.sleep(delay-duration)
>>                         self.put(record) ## put back
>> in the queue and process later
>>                     else:
>>                         error("couldn't notify
>> dispatcher at %s (%s). giving up." % (address[0],
>> motive))
>>                         # eventually log the record
>> to syslog or a file
>>                     return
>>                 if result.lower() == 'ok':
>>                     info("notified dispatcher at %s
>> about expired session %s" % (address[0],
>> record['id']))
>>                 elif result.lower() == 'not found':
>>                     info("session %s already closed
>> by the dispatcher at %s" % (record['id'],
>> address[0]))
>>                 else:
>>                     error("failed to notify
>> dispatcher at %s (returned `%s')." % (address[0],
>> result))
>>                     # eventually log the record to
>> syslog or a file
>>             finally:
>>                 s.close()
>>
>>         def notify(self, session):
>>             if not session.dispatcher:
>>                 return ## no dispatcher to notify.
>>             record = StopRecord(session)
>>             record['dispatcher'] =
>> session.dispatcher
>>             record['expires'] = time.time() + 3600
>> ## try for an hour
>>             self.put(record)
>>
>>     dispatcher = DispatcherNotifyThread()
>>     dispatcher.start()
>>
>> ## Internal state of mediaproxy (DON'T TOUCH!!!)
>>
>> ## A few shortcuts, for faster access
>> proxyIP = ProxyConfig.proxyIP
>> minPort = ProxyConfig.portRange[0]
>> maxPort = ProxyConfig.portRange[1]
>> crtPort = minPort
>>
>> Sessions = {}
>>
>> ## For computing traffic through mediaproxy
>> byteBucket = [0, 0, 0]
>> Traffic    = [0, 0, 0]
>>
>> ## Non public networks. This includes RFC1918
>> networks, localnet (127.0.0.0/8),
>> ## broadcast networks (224.0.0.0/4) and 0.0.0.0/8
>> nonPublicNetworks = [
>>     {'name': '0.0.0.0',     'value': 0x00000000L,
>> 'mask': 0xff000000L},
>>     {'name': '10.0.0.0',    'value': 0x0a000000L,
>> 'mask': 0xff000000L},
>>     {'name': '127.0.0.0',   'value': 0x7f000000L,
>> 'mask': 0xff000000L},
>>     {'name': '172.16.0.0',  'value': 0xac100000L,
>> 'mask': 0xfff00000L},
>>     {'name': '192.168.0.0', 'value': 0xc0a80000L,
>> 'mask': 0xffff0000L},
>>     {'name': '224.0.0.0',   'value': 0xe0000000L,
>> 'mask': 0xf0000000L}
>> ]
>>
>> rtpPayloads = {
>>
> === message truncated ===
>
>


-- 
Gonzalo J. Sambucaro
Ingeniería de Software
Tel: +54-341-4230504
MSLC
gonzalo.sambucaro at mslc.com.ar
www.mslc.com.ar
Ocampo y Esmeralda - Vivero de Empresas de Base Tecnológica
Ciudad Universitaria Rosario UNR, CCT CONICET
Rosario - Santa Fé - Argentina





More information about the Users mailing list