From 4204c1e0cf4698f6f7999f95932576687819101b Mon Sep 17 00:00:00 2001 From: Andriy Pylypenko Date: Thu, 12 Sep 2019 17:46:38 +0300 Subject: [PATCH 1/2] Add support for RFC3264. --- sippy/CCEvents.py | 38 +++++++++++++++++++++++++++++++++----- sippy/Rtp_proxy_session.py | 24 ++++++++++++------------ sippy/SdpSession.py | 38 ++++++++++++++++++++++++++++++++++++++ sippy/b2bua_radius.py | 15 ++++++++++++++- 4 files changed, 97 insertions(+), 18 deletions(-) create mode 100644 sippy/SdpSession.py diff --git a/sippy/CCEvents.py b/sippy/CCEvents.py index b03f6caff..6febadfa5 100644 --- a/sippy/CCEvents.py +++ b/sippy/CCEvents.py @@ -48,6 +48,9 @@ def __init__(self, data = None, rtime = None, origin = None): def getData(self): return self.data + def getBody(self): + return None + def getCopy(self): cself = self.__class__(self.data, self.rtime, self.origin) if self.reason != None: @@ -73,9 +76,18 @@ def getCopy(self): def onUacSetupComplete(self, uac): pass + def getBody(self): + if self.data != None: + return self.data[4] + return None + class CCEventRing(CCEventGeneric): name = 'CCEventRing' - pass + + def getBody(self): + if self.data != None: + return self.data[2] + return None class CCEventPreConnect(CCEventGeneric): name = 'CCEventPreConnect' @@ -83,7 +95,11 @@ class CCEventPreConnect(CCEventGeneric): class CCEventConnect(CCEventGeneric): name = 'CCEventConnect' - pass + + def getBody(self): + if self.data != None: + return self.data[2] + return None class CCEventUpdate(CCEventGeneric): name = 'CCEventUpdate' @@ -94,13 +110,20 @@ def getCopy(self): cself.max_forwards = self.max_forwards return cself + def getBody(self): + return self.data + class CCEventInfo(CCEventGeneric): name = 'CCEventInfo' - pass + + def getBody(self): + return self.data class CCEventDisconnect(CCEventGeneric): name = 'CCEventDisconnect' - pass + + def getBody(self): + return None from sippy.SipHeader import SipHeader from sippy.SipWarning import SipWarning @@ -119,6 +142,11 @@ def getCopy(self): def setWarning(self, eistr): self.warning = SipHeader(body = SipWarning(text = eistr)) + def getBody(self): + return None + class CCEventRedirect(CCEventGeneric): name = 'CCEventRedirect' - pass + + def getBody(self): + return None diff --git a/sippy/Rtp_proxy_session.py b/sippy/Rtp_proxy_session.py index ec3603db1..22f12ddf3 100644 --- a/sippy/Rtp_proxy_session.py +++ b/sippy/Rtp_proxy_session.py @@ -54,13 +54,8 @@ class _rtpps_side(object): codecs = None raddress = None laddress = None - origin = None - oh_remote = None repacketize = None - def __init__(self): - self.origin = SdpOrigin() - def update(self, rtpps, remote_ip, remote_port, result_callback, options = '', index = 0, \ atype = 'IP4', *callback_parameters): command = 'U' @@ -219,15 +214,20 @@ def _sdp_change_finish(self, cb_args, rtpps, sdp_body, sect, sects, result_callb fidx = sect.a_headers.index(a_header) + 1 sect.a_headers.insert(fidx, 'ptime:%d' % self.repacketize) if len([x for x in sects if x.needs_update]) == 0: - if self.oh_remote != None: - if self.oh_remote.session_id != sdp_body.content.o_header.session_id: - self.origin = SdpOrigin() - elif self.oh_remote.version != sdp_body.content.o_header.version: - self.origin.version += 1 - self.oh_remote = sdp_body.content.o_header.getCopy() - sdp_body.content.o_header = self.origin.getCopy() if rtpps.insert_nortpp: sdp_body.content += 'a=nortpproxy:yes\r\n' + sdp_body.content += 'a=nortpproxy:yes\r\n' + # RFC4566 + # ******* + # For privacy reasons, it is sometimes desirable to obfuscate the + # username and IP address of the session originator. If this is a + # concern, an arbitrary and private MAY be + # chosen to populate the "o=" field, provided that these are selected + # in a manner that does not affect the global uniqueness of the field. + # ******* + sdp_body.content.o_header.address = '192.0.2.1' # 192.0.2.0/24 (TEST-NET-1) + sdp_body.content.o_header.network_type = 'IN' + sdp_body.content.o_header.address_type = 'IP4' sdp_body.needs_update = False result_callback(sdp_body) diff --git a/sippy/SdpSession.py b/sippy/SdpSession.py new file mode 100644 index 000000000..2898d3120 --- /dev/null +++ b/sippy/SdpSession.py @@ -0,0 +1,38 @@ +# Copyright (c) 2003-2005 Maxim Sobolev. All rights reserved. +# Copyright (c) 2006-2019 Sippy Software, Inc. All rights reserved. +# +# Warning: This computer program is protected by copyright law and +# international treaties. Unauthorized reproduction or distribution of this +# program, or any portion of it, may result in severe civil and criminal +# penalties, and will be prosecuted under the maximum extent possible under +# law. + +from SdpOrigin import SdpOrigin + +class SdpSession: + last_origin = None + origin = None + + def __init__(self, origin = None): + if origin != None: + self.origin = origin + else: + self.origin = SdpOrigin() + + def fixup_version(self, event): + body = event.getBody() + if body == None: + return # no SDP so there is nothing to do + try: + body.parse() + except: + # not an SDP + return + new_origin = body.content.o_header.getCopy() + if self.last_origin != None: + if self.last_origin.session_id != new_origin.session_id or \ + self.last_origin.version != new_origin.version: + self.origin.version += 1 + self.last_origin = new_origin + body.content.o_header = self.origin.getCopy() + body.needs_update = False diff --git a/sippy/b2bua_radius.py b/sippy/b2bua_radius.py index 286acc821..06c69c607 100755 --- a/sippy/b2bua_radius.py +++ b/sippy/b2bua_radius.py @@ -57,6 +57,8 @@ from sippy.StatefulProxy import StatefulProxy from sippy.misc import daemonize from sippy.B2BRoute import B2BRoute +from sippy.SdpOrigin import SdpOrigin +from sippy.SdpSession import SdpSession import gc, getopt, os from re import sub @@ -102,6 +104,17 @@ class CCStateDead(object): class CCStateDisconnecting(object): sname = 'Disconnecting' +class RFC3264UA(UA): + def __init__(self, *args, **kwargs): + origin = SdpOrigin() + origin.address = '192.0.2.1' # 192.0.2.0/24 (TEST-NET-1) + self.sdp_session = SdpSession(origin) + UA.__init__(self, *args, **kwargs) + + def recvEvent(self, event): + self.sdp_session.fixup_version(event) + return UA.recvEvent(self, event) + class CallController(object): id = 1 uaA = None @@ -127,7 +140,7 @@ def __init__(self, remote_ip, source, global_config, pass_headers): self.id = CallController.id CallController.id += 1 self.global_config = global_config - self.uaA = UA(self.global_config, event_cb = self.recvEvent, conn_cbs = (self.aConn,), disc_cbs = (self.aDisc,), \ + self.uaA = RFC3264UA(self.global_config, event_cb = self.recvEvent, conn_cbs = (self.aConn,), disc_cbs = (self.aDisc,), \ fail_cbs = (self.aDisc,), dead_cbs = (self.aDead,)) self.uaA.kaInterval = self.global_config['keepalive_ans'] self.uaA.local_ua = self.global_config['_uaname'] From 87b18b50f30b08098e033e98b2ecf532ab8985e8 Mon Sep 17 00:00:00 2001 From: Andriy Pylypenko Date: Sat, 11 Jan 2020 10:53:11 +0200 Subject: [PATCH 2/2] Add missed CCEventPreconnect::getBody() method. --- sippy/CCEvents.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sippy/CCEvents.py b/sippy/CCEvents.py index 6febadfa5..8e7a674d1 100644 --- a/sippy/CCEvents.py +++ b/sippy/CCEvents.py @@ -91,7 +91,11 @@ def getBody(self): class CCEventPreConnect(CCEventGeneric): name = 'CCEventPreConnect' - pass + + def getBody(self): + if self.data != None: + return self.data[2] + return None class CCEventConnect(CCEventGeneric): name = 'CCEventConnect'