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@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@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:
- 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.
- 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@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@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@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 ===