def rtpp_reply_l(self, rval, sdata): #print 'rtpp_reply', sdata if rval == 'E71': print 'bingo 2' Timeout(self.issue_command_l, 2 * random(), 1, sdata) return if rval == None or rval.startswith('E'): print ('rtpp_reply_l: error: %s, original command: %s' % \ (str(rval), sdata.command_l)) reactor.stop() return if random() > 0.5: # let 50% of the sessions timeout, disconnect the rest after # 8.5-58.5 seconds explicitly tout = 8.5 + (50.0 * random()) if random() > 0.5: Timeout(self.issue_command_d, tout, 1, sdata.command_d_b1) else: Timeout(self.issue_command_d, tout, 1, sdata.command_d_b2) self.rcodes.append(rval) self.rremain -= 1 if self.rremain == 0: reactor.stop() self.issue_command()
def __init__(self, name, global_config, address, cmd_out_address): self.call_id_map = [] self.call_id_map_old = [] self.name = name self.global_config = global_config self.asess_filtered = rc_filter(0.9) self.cmd_out_address = cmd_out_address if cmd_out_address != None: bind_address = (cmd_out_address, 0) else: bind_address = None Rtp_proxy_client.__init__(self, global_config, address, bind_address = bind_address) self.timer = Timeout(self.call_id_map_aging, 600, -1)
def __init__(self, global_config): self.global_config = global_config self.ccmap = [] self.el = Timeout(self.GClector, 60, -1) Signal(SIGHUP, self.discAll, SIGHUP) Signal(SIGUSR2, self.toggleDebug, SIGUSR2) Signal(SIGPROF, self.safeRestart, SIGPROF)
def __init__(self, name, global_config, *args, **kwargs): self.call_id_map = [] self.call_id_map_old = [] self.name = name self.global_config = global_config Rtp_proxy_client.__init__(self, global_config, *args, **kwargs) self.timer = Timeout(self.call_id_map_aging, 600, -1)
def __init__(self, global_config, bodys, portrange, test_timeout): global_config['_sip_tm'] = SipTransactionManager( global_config, self.recvRequest) Timeout(self.timeout, test_timeout, 1) self.bodys = bodys self.global_config = global_config self.portrange = portrange
def placeOriginate(self, oroute): cId, cGUID, cli, cld, body, auth, caller_name = self.eTry.getData() cld = oroute.cld self.huntstop_scodes = oroute.params.get('huntstop_scodes', ()) if self.global_config.has_key('static_tr_out'): cld = re_replace(self.global_config['static_tr_out'], cld) if oroute.hostport == 'sip-ua': host = self.source[0] nh_address, same_af = self.source, True else: host = oroute.hostonly nh_address, same_af = oroute.getNHAddr(self.source) if not oroute.forward_on_fail and self.global_config['acct_enable']: self.acctO = RadiusAccounting(self.global_config, 'originate', \ send_start = self.global_config['start_acct_enable'], lperiod = \ self.global_config.getdefault('alive_acct_int', None)) self.acctO.ms_precision = self.global_config.getdefault( 'precise_acct', False) self.acctO.setParams(oroute.params.get('bill-to', self.username), oroute.params.get('bill-cli', oroute.cli), \ oroute.params.get('bill-cld', cld), self.cGUID, self.cId, host) else: self.acctO = None self.acctA.credit_time = oroute.credit_time conn_handlers = [self.oConn] disc_handlers = [] if not oroute.forward_on_fail and self.global_config['acct_enable']: disc_handlers.append(self.acctO.disc) self.uaO = UA(self.global_config, self.recvEvent, oroute.user, oroute.passw, nh_address, oroute.credit_time, tuple(conn_handlers), \ tuple(disc_handlers), tuple(disc_handlers), dead_cbs = (self.oDead,), expire_time = oroute.expires, \ no_progress_time = oroute.no_progress_expires, extra_headers = oroute.extra_headers) self.uaO.local_ua = self.global_config['_uaname'] if self.source != oroute.params.get('outbound_proxy', None): self.uaO.outbound_proxy = oroute.params.get('outbound_proxy', None) if self.rtp_proxy_session != None and oroute.params.get('rtpp', True): self.uaO.on_local_sdp_change = self.rtp_proxy_session.on_caller_sdp_change self.uaO.on_remote_sdp_change = self.rtp_proxy_session.on_callee_sdp_change self.rtp_proxy_session.caller.raddress = nh_address if body != None: body = body.getCopy() self.proxied = True self.uaO.kaInterval = self.global_config['keepalive_orig'] if oroute.params.has_key('group_timeout'): timeout, skipto = oroute.params['group_timeout'] Timeout(self.group_expires, timeout, 1, skipto) if self.global_config.getdefault('hide_call_id', False): cId = SipCallId( md5(str(cId)).hexdigest() + ('-b2b_%d' % oroute.rnum)) else: cId += '-b2b_%d' % oroute.rnum event = CCEventTry((cId, cGUID, oroute.cli, cld, body, auth, \ oroute.params.get('caller_name', self.caller_name))) if self.eTry.max_forwards != None: event.max_forwards = self.eTry.max_forwards - 1 if event.max_forwards <= 0: self.uaA.recvEvent(CCEventFail((483, 'Too Many Hops'))) self.state = CCStateDead return event.reason = self.eTry.reason self.uaO.recvEvent(event)
def connect(self, ua): #if random() > 0.3: # ua.recvEvent(CCEventFail((666, 'Random Failure'))) # return event = CCEventConnect((200, 'OK', self.body), origin='switch') Timeout(self.disconnect, self.disconnect_ival, 1, ua) ua.recvEvent(event) self.connect_done = True
def rtpp_reply_u(self, rval, sdata): #print 'rtpp_reply' if rval == 'E72': print 'bingo 1' Timeout(self.issue_command, 3 * random()) return if rval == None or rval.startswith('E'): print ('rtpp_reply_u: error: %s, original command: %s' % \ (str(rval), sdata.command_u)) reactor.stop() return self.rcodes.append(rval) if random() < 0.1: Timeout(self.issue_command_d, 10 * random(), 1, sdata.command_d_c) self.issue_command() else: self.issue_command_l(sdata)
def __init__(self, global_config, name, address = '/var/run/rtpproxy.sock', dry_run = False): self.active = [] self.pending = [] self.l1rcache = {} self.l2rcache = {} if len(address) == 2: if not dry_run: uopts = Udp_server_opts(address, self.up_command_udp) self.ccm = Udp_server(global_config, uopts) else: sown = global_config.get('_rtpc_sockowner', None) if not dry_run: self.ccm = Cli_server_local(self.up_command, address, sown) self.ccm.protocol.expect_lf = False self.global_config = global_config self.name = name self.address = address self.commands_inflight = [] self.cache_purge_el = Timeout(self.rCachePurge, 10, -1)
def rtpp_reply_u(self, rval, sdata): #print 'rtpp_reply' if rval == 'E72': print 'bingo 1' Timeout(self.issue_command, 3 * random()) return if rval == None or rval.startswith('E'): print('error: %s' % str(rval)) reactor.stop() return self.rcodes.append(rval) self.issue_command_l(sdata)
def __init__(self, global_config, body, portrange, tests, test_timeout): global_config['_sip_tm'] = SipTransactionManager( global_config, self.recvRequest) for subtest_class in ALL_TESTS * 2: if subtest_class.cli not in tests: continue sdp_body = body.getCopy() fillhostport(sdp_body, portrange, subtest_class.atype) subtest = subtest_class(global_config, sdp_body, self.subtest_done, portrange) self.nsubtests_running += 1 self.rval = self.nsubtests_running Timeout(self.timeout, test_timeout, 1)
def answer(self, global_config, body, req, sip_t): in_body = req.getBody() in_body.parse() if not checkhostport(in_body, self.portrange, self.atype): self.nerrs += 1 raise ValueError('Bob(%s): hostport validation has failed' % str(self.__class__)) # New dialog uaA = UA(global_config, self.recvEvent, disc_cbs = (self.disconnected,), \ fail_cbs = (self.disconnected,), dead_cbs = (self.alldone,)) uaA.godead_timeout = 10 uaA.compact_sip = self.compact_sip Timeout(self.ring, self.ring_ival, 1, uaA) self.body = body return uaA.recvRequest(req, sip_t)
def rtpp_reply_l(self, rval, sdata): #print 'rtpp_reply' if rval == 'E71': print 'bingo 2' Timeout(self.issue_command_l, 2 * random(), 1, sdata) return if rval == None or rval.startswith('E'): print('error: %s' % str(rval)) reactor.stop() return self.rcodes.append(rval) self.rremain -= 1 if self.rremain == 0: reactor.stop() self.issue_command()
class Rtp_cluster_member(Rtp_proxy_client): name = None status = 'ACTIVE' capacity = 4000 weight = 100 wan_address = None lan_address = None call_id_map = None call_id_map_old = None on_state_change = None on_active_update = None timer = None global_config = None asess_filtered = None cmd_out_address = None def __init__(self, name, global_config, address, cmd_out_address): self.call_id_map = [] self.call_id_map_old = [] self.name = name self.global_config = global_config self.asess_filtered = rc_filter(0.9) self.cmd_out_address = cmd_out_address if cmd_out_address != None: bind_address = (cmd_out_address, 0) else: bind_address = None Rtp_proxy_client.__init__(self, global_config, address, bind_address = bind_address) self.timer = Timeout(self.call_id_map_aging, 600, -1) def reconnect(self, address): if self.cmd_out_address != None: bind_address = (self.cmd_out_address, 0) else: bind_address = None Rtp_proxy_client.reconnect(self, address, bind_address = bind_address) def isYours(self, call_id): if call_id in self.call_id_map: self.call_id_map.remove(call_id) self.call_id_map.insert(0, call_id) return True if call_id not in self.call_id_map_old: return False self.call_id_map_old.remove(call_id) self.call_id_map.insert(0, call_id) return True def bind_session(self, call_id, cmd_type): if cmd_type != 'D': self.call_id_map.insert(0, call_id) else: self.call_id_map_old.insert(0, call_id) def unbind_session(self, call_id): self.call_id_map.remove(call_id) self.call_id_map_old.insert(0, call_id) def go_online(self): #print 'go_online', self if not self.online: self.global_config['_sip_logger'].write('RTPproxy "%s" has changed ' \ 'status from offline to online' % self.name) if self.on_state_change != None: self.on_state_change(self, True) Rtp_proxy_client.go_online(self) def go_offline(self): #print 'go_offline', self if self.online: self.global_config['_sip_logger'].write('RTPproxy "%s" has changed ' \ 'status from online to offline' % self.name) if self.on_state_change != None: self.on_state_change(self, False) Rtp_proxy_client.go_offline(self) def update_active(self, active_sessions, *more_args): self.asess_filtered.apply(active_sessions) if self.active_sessions != active_sessions and self.on_active_update != None: self.on_active_update(self, active_sessions) Rtp_proxy_client.update_active(self, active_sessions, *more_args) def call_id_map_aging(self): if self.shutdown: self.timer.cancel() return if len(self.call_id_map) < 1000: # Do not age if there are less than 1000 calls in the list self.call_id_map_old = [] return self.call_id_map_old = self.call_id_map[len(self.call_id_map) / 2:] del self.call_id_map[len(self.call_id_map) / 2:] def get_caputil(self): return (self.asess_filtered.get() / self.capacity)
def placeOriginate(self, args): cId, cGUID, cli, cld, body, auth, caller_name = self.eTry.getData() rnum, host, cld, credit_time, expires, no_progress_expires, forward_on_fail, user, passw, cli, \ parameters = args self.huntstop_scodes = parameters.get('huntstop_scodes', ()) if self.global_config.has_key('static_tr_out'): cld = re_replace(self.global_config['static_tr_out'], cld) if host == 'sip-ua': host = self.source[0] port = self.source[1] else: if host.startswith('['): # IPv6 host = host.split(']', 1) port = host[1].split(':', 1) host = host[0] + ']' if len(port) > 1: port = int(port[1]) else: port = SipConf.default_port else: # IPv4 host = host.split(':', 1) if len(host) > 1: port = int(host[1]) else: port = SipConf.default_port host = host[0] if not forward_on_fail and self.global_config['acct_enable']: self.acctO = RadiusAccounting(self.global_config, 'originate', \ send_start = self.global_config['start_acct_enable'], lperiod = \ self.global_config.getdefault('alive_acct_int', None)) self.acctO.ms_precision = self.global_config.getdefault('precise_acct', False) self.acctO.setParams(parameters.get('bill-to', self.username), parameters.get('bill-cli', cli), \ parameters.get('bill-cld', cld), self.cGUID, self.cId, host) else: self.acctO = None self.acctA.credit_time = credit_time conn_handlers = [self.oConn] disc_handlers = [] if not forward_on_fail and self.global_config['acct_enable']: disc_handlers.append(self.acctO.disc) self.uaO = UA(self.global_config, self.recvEvent, user, passw, (host, port), credit_time, tuple(conn_handlers), \ tuple(disc_handlers), tuple(disc_handlers), dead_cbs = (self.oDead,), expire_time = expires, \ no_progress_time = no_progress_expires, extra_headers = parameters.get('extra_headers', None)) if self.source != parameters.get('outbound_proxy', None): self.uaO.outbound_proxy = parameters.get('outbound_proxy', None) if self.rtp_proxy_session != None and parameters.get('rtpp', True): self.uaO.on_local_sdp_change = self.rtp_proxy_session.on_caller_sdp_change self.uaO.on_remote_sdp_change = self.rtp_proxy_session.on_callee_sdp_change self.rtp_proxy_session.caller_raddress = (host, port) if body != None: body = body.getCopy() body.content += 'a=nortpproxy:yes\r\n' self.proxied = True self.uaO.kaInterval = self.global_config['keepalive_orig'] if parameters.has_key('group_timeout'): timeout, skipto = parameters['group_timeout'] Timeout(self.group_expires, timeout, 1, skipto) if self.global_config.getdefault('hide_call_id', False): cId = SipCallId(md5(str(cId)).hexdigest() + ('-b2b_%d' % rnum)) else: cId += '-b2b_%d' % rnum event = CCEventTry((cId, cGUID, cli, cld, body, auth, \ parameters.get('caller_name', self.caller_name))) event.reason = self.eTry.reason self.uaO.recvEvent(event)
def connected(self, ua, rtime, origin): Timeout(self.disconnect, self.disconnect_ival, 1, ua) self.connect_done = True
class Rtp_cluster_member(Rtp_proxy_client): name = None status = 'ACTIVE' capacity = 4000 weight = 100 wan_address = None lan_address = None call_id_map = None call_id_map_old = None on_state_change = None on_active_update = None timer = None global_config = None asess_filtered = None cmd_out_address = None stats_cache = None def __init__(self, name, global_config, address, cmd_out_address): self.call_id_map = [] self.call_id_map_old = [] self.name = name self.global_config = global_config self.asess_filtered = rc_filter(0.9) self.cmd_out_address = cmd_out_address self.stats_cache = {} if cmd_out_address != None: bind_address = (cmd_out_address, 0) else: bind_address = None Rtp_proxy_client.__init__(self, global_config, address, bind_address=bind_address) self.timer = Timeout(self.call_id_map_aging, 600, -1) def reconnect(self, address): if self.cmd_out_address != None: bind_address = (self.cmd_out_address, 0) else: bind_address = None Rtp_proxy_client.reconnect(self, address, bind_address=bind_address) def isYours(self, call_id): if call_id in self.call_id_map: self.call_id_map.remove(call_id) self.call_id_map.insert(0, call_id) return True if call_id not in self.call_id_map_old: return False self.call_id_map_old.remove(call_id) self.call_id_map.insert(0, call_id) return True def bind_session(self, call_id, cmd_type): if cmd_type != 'D': self.call_id_map.insert(0, call_id) else: self.call_id_map_old.insert(0, call_id) def unbind_session(self, call_id): self.call_id_map.remove(call_id) self.call_id_map_old.insert(0, call_id) def go_online(self): #print 'go_online', self if not self.online: self.global_config['_sip_logger'].write('RTPproxy "%s" has changed ' \ 'status from offline to online' % self.name) if self.on_state_change != None: self.on_state_change(self, True) Rtp_proxy_client.go_online(self) def go_offline(self): #print 'go_offline', self if self.online: self.global_config['_sip_logger'].write('RTPproxy "%s" has changed ' \ 'status from online to offline' % self.name) self.stats_cache = {} if self.on_state_change != None: self.on_state_change(self, False) Rtp_proxy_client.go_offline(self) def update_active(self, active_sessions, *more_args): self.asess_filtered.apply(active_sessions) if self.active_sessions != active_sessions and self.on_active_update != None: self.on_active_update(self, active_sessions) Rtp_proxy_client.update_active(self, active_sessions, *more_args) def call_id_map_aging(self): if self.shut_down: self.timer.cancel() return if len(self.call_id_map) < 1000: # Do not age if there are less than 1000 calls in the list self.call_id_map_old = [] return self.call_id_map_old = self.call_id_map[len(self.call_id_map) / 2:] del self.call_id_map[len(self.call_id_map) / 2:] def get_caputil(self): return (self.asess_filtered.get() / self.capacity)
def ring(self, ua): event = CCEventRing((180, 'Ringing', None), origin='switch') Timeout(self.connect, self.answer_ival, 1, ua) ua.recvEvent(event) self.ring_done = True
def __init__(self, name, *args, **kwargs): self.call_id_map = [] self.call_id_map_old = [] self.name = name Rtp_proxy_client.__init__(self, *args, **kwargs) self.timer = Timeout(self.call_id_map_aging, 600, -1)
continue if o == '-S': sippy_path = a.strip() continue if o == '-o': fname = a.strip() if fname == '-': file_out = sys.stdout else: file_out = file(fname, 'w') if o == '-t': timeout = float(a.strip()) continue if sippy_path != None: sys.path.insert(0, sippy_path) from sippy.Cli_server_local import Cli_server_local from sippy.Cli_server_tcp import Cli_server_tcp from sippy.Timeout import Timeout ch = cli_handler(file_out) if stype == 'unix': cs = Cli_server_local(ch.command_received, spath) else: cs = Cli_server_tcp(ch.command_received, spath) if timeout != None: Timeout(ch.done, timeout) reactor.run(installSignalHandlers=1) sys.exit(ch.rval)
class Rtp_cluster_member(Rtp_proxy_client): name = None status = "ACTIVE" capacity = 4000 weight = 100 wan_address = None call_id_map = None call_id_map_old = None on_state_change = None on_active_update = None timer = None def __init__(self, name, *args, **kwargs): self.call_id_map = [] self.call_id_map_old = [] self.name = name Rtp_proxy_client.__init__(self, *args, **kwargs) self.timer = Timeout(self.call_id_map_aging, 600, -1) def isYours(self, call_id): if call_id in self.call_id_map: self.call_id_map.remove(call_id) self.call_id_map.insert(0, call_id) return True if call_id not in self.call_id_map_old: return False self.call_id_map_old.remove(call_id) self.call_id_map.insert(0, call_id) return True def bind_session(self, call_id, cmd_type): if cmd_type != "D": self.call_id_map.insert(0, call_id) else: self.call_id_map_old.insert(0, call_id) def unbind_session(self, call_id): self.call_id_map.remove(call_id) self.call_id_map_old.insert(0, call_id) def go_online(self): # print 'go_online', self if not self.online and self.on_state_change != None: self.on_state_change(self, True) Rtp_proxy_client.go_online(self) def go_offline(self): # print 'go_offline', self if self.online and self.on_state_change != None: self.on_state_change(self, False) Rtp_proxy_client.go_offline(self) def update_active(self, active_sessions): if self.active_sessions != active_sessions and self.on_active_update != None: self.on_active_update(self, active_sessions) Rtp_proxy_client.update_active(self, active_sessions) def call_id_map_aging(self): if self.shutdown: self.timer.cancel() return if len(self.call_id_map) < 1000: # Do not age if there are less than 1000 calls in the list self.call_id_map_old = [] return self.call_id_map_old = self.call_id_map[len(self.call_id_map) / 2 :] del self.call_id_map[len(self.call_id_map) / 2 :]
class Rtp_cluster_member(Rtp_proxy_client): name = None status = 'ACTIVE' capacity = 4000 weight = 100 wan_address = None call_id_map = None call_id_map_old = None on_state_change = None on_active_update = None timer = None def __init__(self, name, *args, **kwargs): self.call_id_map = [] self.call_id_map_old = [] self.name = name Rtp_proxy_client.__init__(self, *args, **kwargs) self.timer = Timeout(self.call_id_map_aging, 600, -1) def isYours(self, call_id): if call_id in self.call_id_map: self.call_id_map.remove(call_id) self.call_id_map.insert(0, call_id) return True if call_id not in self.call_id_map_old: return False self.call_id_map_old.remove(call_id) self.call_id_map.insert(0, call_id) return True def bind_session(self, call_id, cmd_type): if cmd_type != 'D': self.call_id_map.insert(0, call_id) else: self.call_id_map_old.insert(0, call_id) def unbind_session(self, call_id): self.call_id_map.remove(call_id) self.call_id_map_old.insert(0, call_id) def go_online(self): #print 'go_online', self if not self.online and self.on_state_change != None: self.on_state_change(self, True) Rtp_proxy_client.go_online(self) def go_offline(self): #print 'go_offline', self if self.online and self.on_state_change != None: self.on_state_change(self, False) Rtp_proxy_client.go_offline(self) def update_active(self, active_sessions): if self.active_sessions != active_sessions and self.on_active_update != None: self.on_active_update(self, active_sessions) Rtp_proxy_client.update_active(self, active_sessions) def call_id_map_aging(self): if self.shutdown: self.timer.cancel() return if len(self.call_id_map) < 1000: # Do not age if there are less than 1000 calls in the list self.call_id_map_old = [] return self.call_id_map_old = self.call_id_map[len(self.call_id_map) / 2:] del self.call_id_map[len(self.call_id_map) / 2:]
class Rtp_cluster(object): global_config = None address = None name = None active = None pending = None ccm = None commands_inflight = None l1rcache = None l2rcache = None cache_purge_el = None def __init__(self, global_config, name, address = '/var/run/rtpproxy.sock', dry_run = False): self.active = [] self.pending = [] self.l1rcache = {} self.l2rcache = {} if len(address) == 2: if not dry_run: uopts = Udp_server_opts(address, self.up_command_udp) self.ccm = Udp_server(global_config, uopts) else: sown = global_config.get('_rtpc_sockowner', None) if not dry_run: self.ccm = Cli_server_local(self.up_command, address, sown) self.ccm.protocol.expect_lf = False self.global_config = global_config self.name = name self.address = address self.commands_inflight = [] self.cache_purge_el = Timeout(self.rCachePurge, 10, -1) def add_member(self, member): member.on_state_change = self.rtpp_status_change if member.online: self.active.append(member) else: self.pending.append(member) def up_command_udp(self, data, address, server, rtime): dataparts = data.split(None, 1) if len(dataparts) == 1: return cookie, cmd = dataparts if cookie in self.commands_inflight: return cresp = self.l1rcache.get(cookie, self.l2rcache.get(cookie, None)) if cresp != None: response = '%s %s' % (cookie, cresp) server.send_to(response, address) print('Rtp_cluster.up_command_udp(): sending cached response "%s" to %s' % \ (response[:-1], address)) return self.commands_inflight.append(cookie) clim = UdpCLIM(address, cookie, server) return self.up_command(clim, cmd) def up_command(self, clim, orig_cmd): #print 'up_command', orig_cmd cmd = Rtp_proxy_cmd(orig_cmd) #print cmd if len(self.active) == 0: self.down_command('E999', clim, cmd, None) return if cmd.type in ('U', 'L', 'D', 'P', 'S', 'R', 'C', 'Q'): #print 'up', cmd.call_id, str(cmd) for rtpp in self.active: if rtpp.isYours(cmd.call_id): break else: rtpp = None if cmd.type == 'U' and cmd.ul_opts.to_tag == None: new_session = True else: new_session = False if rtpp == None and not new_session: # Existing session, also check if it exists on any of the offline # members and try to relay it there, it makes no sense to broadcast # the call to every other node in that case for rtpp in self.pending: if rtpp.isYours(cmd.call_id): break else: rtpp = None if rtpp != None and cmd.type == 'D': rtpp.unbind_session(cmd.call_id) if rtpp == None and new_session: # New session rtpp = self.pick_proxy(cmd.call_id) rtpp.bind_session(cmd.call_id, cmd.type) elif rtpp == None: # Existing session we know nothing about if cmd.type == 'U': # Do a forced lookup orig_cmd = 'L%s' % cmd.ul_opts.getstr(cmd.call_id, swaptags = True) active = [x for x in self.active if x.online] br = Broadcaster(len(active), clim, cmd) for rtpp in active: if cmd.type in ('U', 'L') and rtpp.lan_address != None: out_cmd = Rtp_proxy_cmd(orig_cmd) out_cmd.ul_opts.local_ip = rtpp.lan_address out_cmd = str(out_cmd) else: out_cmd = orig_cmd rtpp.send_command(out_cmd, self.merge_results, br, rtpp) return elif cmd.type == 'I' and cmd.command_opts == 'b': active = [x for x in self.active if x.online] sessions_created = active_sessions = active_streams = preceived = ptransmitted = 0 for rtpp in active: if rtpp.active_sessions == None: # There might be some time between "online" and heartbeat reply, # when stats are still empty, or when proxy goes from offline # to online, skip it continue sessions_created += rtpp.sessions_created active_sessions += rtpp.active_sessions active_streams += rtpp.active_streams preceived += rtpp.preceived ptransmitted += rtpp.ptransmitted reply = 'sessions created: %d\nactive sessions: %d\nactive streams: %d\npackets received: %d\npackets transmitted: %d' % \ (sessions_created, active_sessions, active_streams, preceived, ptransmitted) self.down_command(reply, clim, cmd, None) return elif cmd.type == 'G': active = [x for x in self.active if x.online] br = Broadcaster(len(active), clim, cmd) br.sobj = Rtpp_stats(cmd.args.split()) if cmd.command_opts != None and cmd.command_opts.lower() == 'v': cmd.command_opts = None br.sobj.verbose = True cmd.nretr = 0 for rtpp in active: rtpp.send_command(cmd, self.merge_stats_results, br, rtpp) return else: rtpp = self.active[0] #print 'up', cmd #print 'rtpp.send_command' if cmd.type in ('U', 'L') and rtpp.lan_address != None: out_cmd = Rtp_proxy_cmd(orig_cmd) out_cmd.ul_opts.local_ip = rtpp.lan_address out_cmd = str(out_cmd) else: out_cmd = orig_cmd rtpp.send_command(out_cmd, self.down_command, clim, cmd, rtpp) def down_command(self, result, clim, cmd, rtpp): if isinstance(clim, UdpCLIM) and clim.cookie in self.commands_inflight: self.commands_inflight.remove(clim.cookie) #print 'down', result if result == None: result = 'E999' elif cmd.type in ('U', 'L') and not result[0].upper() == 'E' and \ rtpp.wan_address != None: #print 'down', cmd.ul_opts.destination_ip, rtpp.wan_address req_dip = cmd.ul_opts.destination_ip req_lip = cmd.ul_opts.local_ip if req_dip != None and not is_dst_local(req_dip) and \ req_lip != rtpp.lan_address: result_parts = result.strip().split() result = '%s %s' % (result_parts[0], rtpp.wan_address) elif req_lip == None: result_parts = result.strip().split() result = '%s %s' % (result_parts[0], rtpp.wan_address) # result = '%s %s' % (result_parts[0], '192.168.1.22') #print 'down clim.send', result response = result + '\n' clim.send(response) if isinstance(clim, UdpCLIM): self.l1rcache[clim.cookie] = response clim.close() def merge_results(self, result, br, rtpp): if result == None: result = 'E999' if br != None and not result[0].upper() == 'E' and not \ (br.cmd.type in ('U', 'L') and result == '0'): br.results.append(result) br.bcount -= 1 if br.bcount > 0: # More results to come return if len(br.results) == 1: rtpp.bind_session(br.cmd.call_id, br.cmd.type) self.down_command(br.results[0], br.clim, br.cmd, rtpp) else: # No results or more than one proxy returns positive # XXX: more than one result can probably be handled if br.cmd.type in ('U', 'L'): self.down_command('0', br.clim, br.cmd, rtpp) else: self.down_command('E999', br.clim, br.cmd, rtpp) def merge_stats_results(self, result, br, rtpp): #print 'merge_stats_results, result', result if result == None: result = rtpp.stats_cache.get(br.sobj.all_names, 'E999') print 'merge_stats_results: getting from the cache %s' % result elif result[0].upper() != 'E': rtpp.stats_cache[br.sobj.all_names] = result if br != None and not result[0].upper() == 'E': try: br.sobj.parseAndAdd(result) br.ecount -= 1 except: pass br.bcount -= 1 if br.bcount > 0: # More results to come return #print 'merge_stats_results, br.sobj', br.sobj if br.ecount == br.nparts: rval = 'E999' else: rval = str(br.sobj) self.down_command(rval, br.clim, br.cmd, rtpp) def pick_proxy(self, call_id): active = [(rtpp, rtpp.weight * (1 - rtpp.get_caputil())) \ for rtpp in self.active if rtpp.status == 'ACTIVE' and rtpp.online] available = [(rtpp, weight) for rtpp, weight in active if weight > 0] if len(available) > 0: # Normal case, there are some proxies that are loaded below their capacities total_weight = sum([x[1] for x in available]) thr_weight = (random() * total_weight) % total_weight #print total_weight, thr_weight for rtpp, weight in available: thr_weight -= weight if thr_weight < 0: break #print 'pick_proxyNG: picked up %s for the call %s (normal)' % (rtpp.name, call_id) return rtpp elif len(active) > 0: max_rtpp, max_weight = active[0] for rtpp, weight in active[1:]: if weight > max_weight: max_rtpp, max_weight = rtpp, weight #print 'pick_proxyNG: picked up %s for the call %s (overload)' % (max_rtpp.name, call_id) return max_rtpp print 'pick_proxyNG: OUCH, no proxies to pickup from for the call %s' % (call_id,) return None def rtpp_status_change(self, rtpp, online): #print 'rtpp_status_change', self, rtpp, online if online and rtpp in self.pending: self.pending.remove(rtpp) self.active.append(rtpp) if not online and rtpp in self.active: self.active.remove(rtpp) self.pending.append(rtpp) def bring_down(self, rtpp): if rtpp in self.active: if rtpp.active_sessions in (0, None): self.active.remove(rtpp) return rtpp.status = 'DRAINING' rtpp.on_active_update = self.rtpp_active_change return self.pending.remove(rtpp) def rtpp_active_change(self, rtpp, active_sessions): if rtpp.status == 'DRAINING' and active_sessions == 0: if rtpp in self.pending: self.pending.remove(rtpp) else: self.active.remove(rtpp) rtpp.shutdown() def rtpp_by_name(self, name): idx = 0 for rtpp in self.active + self.pending: if rtpp.name == name: return (rtpp, idx) idx += 1 return (None, None) def shutdown(self): for rtpp in self.active + self.pending: rtpp.shutdown() if self.ccm != None: self.ccm.shutdown() if self.cache_purge_el != None: self.cache_purge_el.cancel() self.active = None self.pending = None self.ccm = None self.cache_purge_el = None def all_members(self): return tuple(self.active + self.pending) def rCachePurge(self): self.l2rcache = self.l1rcache self.l1rcache = {}
def ring(self, ua): event = CCEventRing((183, 'Session Progress', self.body), \ origin = 'switch') Timeout(self.connect, self.answer_ival, 1, ua) ua.recvEvent(event) self.ring_done = True