class SipRegistrationAgent(object): global_config = None user = None passw = None rmsg = None dead = False atries = 0 source_address = None def __init__(self, global_config, aor, contact, user=None, passw=None, exp=180, rok_cb=None, rfail_cb=None, cb_arg=None, target=None): self.global_config = global_config self.user = user self.passw = passw self.rok_cb = rok_cb self.rfail_cb = rfail_cb self.cb_arg = cb_arg ruri = aor.getCopy() ruri.username = None aor.port = None tfaddr = SipAddress(url=aor) fr0m = SipFrom(address=tfaddr.getCopy()) fr0m.genTag() to = SipTo(address=tfaddr) contact = SipContact(address=SipAddress(url=contact)) contact.address.params['expires'] = '180' self.rmsg = SipRequest(method='REGISTER', ruri=ruri, fr0m=fr0m, contact=contact, to=to, target=target) def doregister(self): if self.dead: return self.global_config['_sip_tm'].newTransaction(self.rmsg, self.gotreply, \ laddress = self.source_address) self.rmsg.getHFBody('via').genBranch() self.rmsg.getHFBody('cseq').incCSeqNum() def stopregister(self): self.dead = True self.rmsg = None def gotreply(self, resp): if self.dead: return if resp.scode < 200: return if resp.scode >= 200 and resp.scode < 300 and resp.reason != 'Auth Failed': contact = None if resp.countHFs('contact') > 0: contact = resp.getHFBody('contact') if contact != None and 'expires' in contact.address.params: tout = int(contact.address.params['expires']) elif resp.countHFs('expires') > 0: tout = resp.getHFBody('expires').getNum() else: tout = 180 timer = Timeout(self.doregister, tout) if self.rok_cb != None: self.rok_cb(timer.etime.realt, contact, self.cb_arg) self.atries = 0 return if resp.scode == 401 and resp.countHFs('www-authenticate') != 0 and \ self.user != None and self.passw != None and self.atries < 3: challenge = resp.getHFBody('www-authenticate') auth = SipAuthorization(realm=challenge.getRealm(), nonce=challenge.getNonce(), method='REGISTER', uri=str(self.rmsg.ruri), username=self.user, password=self.passw) for authorization in self.rmsg.getHFs('authorization'): self.rmsg.removeHeader(authorization) self.rmsg.appendHeader(SipHeader(name='authorization', body=auth)) self.atries += 1 self.doregister() return if resp.scode == 407 and resp.countHFs('proxy-authenticate') != 0 and \ self.user != None and self.passw != None and self.atries < 3: challenge = resp.getHFBody('proxy-authenticate') auth = SipProxyAuthorization(realm=challenge.getRealm(), nonce=challenge.getNonce(), method='REGISTER', uri=str(self.rmsg.ruri), username=self.user, password=self.passw) for authorization in self.rmsg.getHFs('proxy-authorization'): self.rmsg.removeHeader(authorization) self.rmsg.appendHeader( SipHeader(name='proxy-authorization', body=auth)) self.atries += 1 self.doregister() return if self.rfail_cb != None: self.rfail_cb(resp.getSL(), self.cb_arg) Timeout(self.doregister, 60) self.atries = 0
def handleIncoming(self, data_in, address, server, rtime): if len(data_in) < 32: return data = data_in.decode() self.global_config['_sip_logger'].write( 'RECEIVED message from %s:%d:\n' % address, data, ltime=rtime.realt) checksum = md5(data_in).digest() retrans = self.l1rcache.get(checksum, None) if retrans == None: retrans = self.l2rcache.get(checksum, None) if retrans != None: if retrans.data == None: return self.transmitData(retrans.userv, retrans.data, retrans.address, \ lossemul = retrans.lossemul) return if data.startswith('SIP/2.0 '): try: resp = SipResponse(data) tid = resp.getTId(True, True) except Exception as exception: dump_exception('can\'t parse SIP response from %s:%d' % (address[0], address[1]), extra=data) self.l1rcache[checksum] = SipTMRetransmitO() return if resp.getSCode()[0] < 100 or resp.getSCode()[0] > 999: print( datetime.now(), 'invalid status code in SIP response from %s:%d:' % address) print(data) sys.stdout.flush() self.l1rcache[checksum] = SipTMRetransmitO() return resp.rtime = rtime if not tid in self.tclient: #print 'no transaction with tid of %s in progress' % str(tid) self.l1rcache[checksum] = SipTMRetransmitO() return t = self.tclient[tid] if self.nat_traversal and resp.countHFs( 'contact') > 0 and not check1918(t.address[0]): cbody = resp.getHFBody('contact') if not cbody.asterisk: curl = cbody.getUrl() if check1918(curl.host): curl.host, curl.port = address resp.setSource(address) self.incomingResponse(resp, t, checksum) else: try: req = SipRequest(data) tids = req.getTIds() except Exception as exception: if isinstance( exception, ESipParseException) and exception.sip_response != None: self.transmitMsg(server, exception.sip_response, address, checksum) dump_exception('can\'t parse SIP request from %s:%d' % (address[0], address[1]), extra=data) self.l1rcache[checksum] = SipTMRetransmitO() return req.rtime = rtime via0 = req.getHFBody('via') ahost, aport = via0.getAddr() rhost, rport = address if self.nat_traversal and rport != aport and check1918(ahost): req.nated = True if ahost != rhost: via0.params['received'] = rhost if 'rport' in via0.params or req.nated: via0.params['rport'] = str(rport) if self.nat_traversal and req.countHFs( 'contact') > 0 and req.countHFs('via') == 1: try: cbody = req.getHFBody('contact') except Exception as exception: dump_exception('can\'t parse SIP request from %s:%d: %s:' % (address[0], address[1]), extra=data) self.l1rcache[checksum] = SipTMRetransmitO() return if not cbody.asterisk: curl = cbody.getUrl() if check1918( curl.host ) or curl.port == 0 or curl.host == '255.255.255.255': curl.host, curl.port = address req.nated = True req.setSource(address) self.incomingRequest(req, checksum, tids, server)
class SipRegistrationAgent(object): global_config = None user = None passw = None rmsg = None dead = False atries = 0 source_address = None def __init__(self, global_config, aor, contact, user = None, passw = None, exp = 180, rok_cb = None, rfail_cb = None, cb_arg = None, target = None): self.global_config = global_config self.user = user self.passw = passw self.rok_cb = rok_cb self.rfail_cb = rfail_cb self.cb_arg = cb_arg ruri = aor.getCopy() ruri.username = None aor.port = None tfaddr = SipAddress(url = aor) fr0m = SipFrom(address = tfaddr.getCopy()) fr0m.genTag() to = SipTo(address = tfaddr) contact = SipContact(address = SipAddress(url = contact)) contact.address.params['expires'] = '180' self.rmsg = SipRequest(method = 'REGISTER', ruri = ruri, fr0m = fr0m, contact = contact, to = to, target = target) def doregister(self): if self.dead: return self.global_config['_sip_tm'].newTransaction(self.rmsg, self.gotreply, \ laddress = self.source_address) self.rmsg.getHFBody('via').genBranch() self.rmsg.getHFBody('cseq').incCSeqNum() def stopregister(self): self.dead = True self.rmsg = None def gotreply(self, resp): if self.dead: return if resp.scode < 200: return if resp.scode >= 200 and resp.scode < 300 and resp.reason != 'Auth Failed': contact = None if resp.countHFs('contact') > 0: contact = resp.getHFBody('contact') if contact != None and 'expires' in contact.address.params: tout = int(contact.address.params['expires']) elif resp.countHFs('expires') > 0: tout = resp.getHFBody('expires').getNum() else: tout = 180 timer = Timeout(self.doregister, tout) if self.rok_cb != None: self.rok_cb(timer.etime.realt, contact, self.cb_arg) self.atries = 0 return if resp.scode == 401 and resp.countHFs('www-authenticate') != 0 and \ self.user != None and self.passw != None and self.atries < 3: challenge = resp.getHFBody('www-authenticate') auth = SipAuthorization(realm = challenge.getRealm(), nonce = challenge.getNonce(), method = 'REGISTER', uri = str(self.rmsg.ruri), username = self.user, password = self.passw) for authorization in self.rmsg.getHFs('authorization'): self.rmsg.removeHeader(authorization) self.rmsg.appendHeader(SipHeader(name = 'authorization', body = auth)) self.atries += 1 self.doregister() return if resp.scode == 407 and resp.countHFs('proxy-authenticate') != 0 and \ self.user != None and self.passw != None and self.atries < 3: challenge = resp.getHFBody('proxy-authenticate') auth = SipProxyAuthorization(realm = challenge.getRealm(), nonce = challenge.getNonce(), method = 'REGISTER', uri = str(self.rmsg.ruri), username = self.user, password = self.passw) for authorization in self.rmsg.getHFs('proxy-authorization'): self.rmsg.removeHeader(authorization) self.rmsg.appendHeader(SipHeader(name = 'proxy-authorization', body = auth)) self.atries += 1 self.doregister() return if self.rfail_cb != None: self.rfail_cb(resp.getSL(), self.cb_arg) Timeout(self.doregister, 60) self.atries = 0
def handleIncoming(self, data_in, address, server, rtime): if len(data_in) < 32: return data = data_in.decode() self.global_config['_sip_logger'].write('RECEIVED message from %s:%d:\n' % address, data, ltime = rtime.realt) checksum = md5(data_in).digest() retrans = self.l1rcache.get(checksum, None) if retrans == None: retrans = self.l2rcache.get(checksum, None) if retrans != None: if retrans.data == None: return self.transmitData(retrans.userv, retrans.data, retrans.address, \ lossemul = retrans.lossemul) return if data.startswith('SIP/2.0 '): try: resp = SipResponse(data) tid = resp.getTId(True, True) except Exception as exception: dump_exception('can\'t parse SIP response from %s:%d' % (address[0], address[1]), extra = data) self.l1rcache[checksum] = SipTMRetransmitO() return if resp.getSCode()[0] < 100 or resp.getSCode()[0] > 999: print(datetime.now(), 'invalid status code in SIP response from %s:%d:' % address) print(data) sys.stdout.flush() self.l1rcache[checksum] = SipTMRetransmitO() return resp.rtime = rtime if not tid in self.tclient: #print 'no transaction with tid of %s in progress' % str(tid) self.l1rcache[checksum] = SipTMRetransmitO() return t = self.tclient[tid] if self.nat_traversal and resp.countHFs('contact') > 0 and not check1918(t.address[0]): cbody = resp.getHFBody('contact') if not cbody.asterisk: curl = cbody.getUrl() if check1918(curl.host): curl.host, curl.port = address resp.setSource(address) self.incomingResponse(resp, t, checksum) else: try: req = SipRequest(data) tids = req.getTIds() except Exception as exception: if isinstance(exception, ESipParseException) and exception.sip_response != None: self.transmitMsg(server, exception.sip_response, address, checksum) dump_exception('can\'t parse SIP request from %s:%d' % (address[0], address[1]), extra = data) self.l1rcache[checksum] = SipTMRetransmitO() return req.rtime = rtime via0 = req.getHFBody('via') ahost, aport = via0.getAddr() rhost, rport = address if self.nat_traversal and rport != aport and check1918(ahost): req.nated = True if ahost != rhost: via0.params['received'] = rhost if 'rport' in via0.params or req.nated: via0.params['rport'] = str(rport) if self.nat_traversal and req.countHFs('contact') > 0 and req.countHFs('via') == 1: try: cbody = req.getHFBody('contact') except Exception as exception: dump_exception('can\'t parse SIP request from %s:%d: %s:' % (address[0], address[1]), extra = data) self.l1rcache[checksum] = SipTMRetransmitO() return if not cbody.asterisk: curl = cbody.getUrl() if check1918(curl.host) or curl.port == 0 or curl.host == '255.255.255.255': curl.host, curl.port = address req.nated = True req.setSource(address) self.incomingRequest(req, checksum, tids, server)