class Stack: def __init__(self, product_name="nuswit diameter", ip4_address="127.0.0.1"): self.auth_apps = dict() self.acct_apps = dict() self.peer_listeners = list() self.dictionaries = dict() self.manager = PeerManager(self) self.product_name = product_name self.ip4_address = ip4_address self.vendor_id = 0 self.supported_vendors = list() self.firmware_revision = 1 self.watchdog_seconds = None self.hbh = 0 self.ete = 0 self.queued_messages = [] self.identity = None self.realm = None def nextHbH(self): self.hbh += 1 return self.hbh def nextEtE(self): self.ete += 1 return self.ete def createRequest(self, application, code, auth=False, acct=False, vendor_id=None): _log.debug("Creating Diameter message with command code %d", code) ret = DiameterMessage() ret.request_flag = True ret.eTe = self.nextEtE() ret.hBh = self.nextHbH() ret.application_id = application ret.command_code = code self.addOriginHostRealm(ret) if vendor_id: app_container = DiameterAVP() app_container.setCode(260) app_container.setMandatory(True) tmp = DiameterAVP() tmp.setCode(266) tmp.setMandatory(True) tmp.setInteger32(vendor_id) app_container.addAVP(tmp) else: app_container = ret if auth: tmp = DiameterAVP() tmp.setCode(258) tmp.setMandatory(True) tmp.setInteger32(application) app_container.addAVP(tmp) elif acct: tmp = DiameterAVP() tmp.setCode(258) tmp.setMandatory(True) tmp.setInteger32(application) app_container.addAVP(tmp) if app_container != ret: ret.addAVP(app_container) return ret def createAnswer(self, req, ret_code=None): ret = DiameterMessage() ret.request_flag = False ret.proxiable_flag = req.proxiable_flag ret.eTe = req.eTe ret.hBh = req.hBh ret.application_id = req.application_id ret.command_code = req.command_code if ret_code: tmp = DiameterAVP() tmp.setCode(268) tmp.setMandatory(True) tmp.setInteger32(ret_code) ret.addAVP(tmp) self.addOriginHostRealm(ret) return ret def addOriginHostRealm(self, msg): origin_host = DiameterAVP() origin_host.setCode(264) origin_host.setMandatory(True) origin_host.setOctetString(self.identity) msg.addAVP(origin_host) origin_realm = DiameterAVP() origin_realm.setCode(296) origin_realm.setMandatory(True) origin_realm.setOctetString(self.realm) msg.addAVP(origin_realm) def loadDictionary(self, dict_name, dict_file): self.dictionaries[dict_name] = dictionary.DiameterDictionary(dict_file) def getDictionary(self, dict_name): return self.dictionaries[dict_name] def addSupportedVendor(self, vendor): self.supported_vendors.append(vendor) def registerAuthApplication(self, app, vendor, code): self.auth_apps[(vendor,code)] = app def registerAcctApplication(self, app, vendor, code): self.acct_apps[(vendor,code)] = app def registerPeerListener(self, pl): self.peer_listeners.append(pl) def registerPeerIO(self, pio): self.manager.registerPeerIO(pio) def clientV4Add(self, host, port): return self.manager.clientV4Add(host, port) def serverV4Add(self, host, port): return self.manager.serverV4Add(host, port) def serverV4Accept(self, base_peer, host, port): return self.manager.serverV4Accept(base_peer, host, port) def sendByPeer(self, peer, message, retransmission=True): if message.request_flag and retransmission: self.queued_messages.append((peer,message)) self.manager.send(peer, message) def registerPeer(self, peer, identity, realm, apps): r = self.manager.registerPeer(peer, identity, realm, apps) _log.info("Registering peer %s with identity %s for realm %s with apps %s", peer, identity, realm, apps) if r == True: _log.info("Successfully registered %s", peer) for p in self.peer_listeners: if peer.peer_type == PeerStateMachine.PEER_CLIENT: p.connected(peer) else: p.added(peer) return True else: #error, duplicated peer or something like that _log.error("Failed to register %s", peer) return False def removePeer(self, peer): self.manager.removerPeer(peer) for p in self.peer_listeners: if peer.peer_type == PeerStateMachine.PEER_SERVER: p.removed(peer) def handleIncomingMessage(self, peer, message): _log.debug("Handling incoming Diameter message from peer %s", peer) # first check for a vendor-specific application id vendorid = 0 rapp_container = message.findFirstAVP(260) if rapp_container != None: rvendorid = rapp_container.findFirstAVP(266) if rvendorid != None: vendorid = rvendorid.getInteger32() else: rapp_container = message # look for auth/application ids rapp = rapp_container.findFirstAVP(258) if rapp == None: rapp = rapp_container.findFirstAVP(259) if rapp != None: rvalue = rapp.getInteger32() else: rvalue = message.application_id if self.auth_apps.has_key((vendorid,rvalue)): app = self.auth_apps[(vendorid,rvalue)] elif self.acct_apps.has_key((vendorid,rvalue)): app = self.acct_apps[(vendorid,rvalue)] else: _log.error("Peer %s: Application (%d,%d) not found" % (peer, vendorid, rvalue)) if message.request_flag: answ = self.createAnswer(message) answ.error_flag = True self.sendByPeer(peer, answ) return if message.request_flag: app.onRequest(peer, message) else: #remove from retransmission queue self.queued_messages[:] = [x for x in self.queued_messages if not x[1].hBh == message.hBh] app.onAnswer(peer, message) def tick(self): """Check retransmissions""" self.queued_messages[:] = [x for x in self.queued_messages if self.dispatch_messages(*x)] #tick all applications ( required so tick is called only once ) apps = list(set(self.auth_apps.values()).union(set(self.acct_apps.values()))) for app in apps: app.onTick() def dispatch_messages(self, peer, msg): now = int(time.time()) #3 seconds, 3 retries ( one per sec ) if msg.last_try < now - 1: if msg.retries < 3: _log.debug("Sending message to peer %s, attempt number %d", peer, msg.retries) self.manager.send(peer,msg) return True else: _log.error("Failed to send message to peer %s, after %d retries", peer, msg.retries) return False
class Stack: def __init__(self, product_name="nuswit diameter", ip4_address="127.0.0.1"): self.auth_apps = dict() self.acct_apps = dict() self.peer_listeners = list() self.dictionaries = dict() self.manager = PeerManager(self) self.product_name = product_name self.ip4_address = ip4_address self.vendor_id = 0 self.supported_vendors = list() self.firmware_revision = 1 self.watchdog_seconds = None self.hbh = 0 self.ete = 0 self.queued_messages = [] self.identity = None self.realm = None def nextHbH(self): self.hbh += 1 return self.hbh def nextEtE(self): self.ete += 1 return self.ete def createRequest(self, application, code, auth=False, acct=False, vendor_id=None): _log.debug("Creating Diameter message with command code %d", code) ret = DiameterMessage() ret.request_flag = True ret.eTe = self.nextEtE() ret.hBh = self.nextHbH() ret.application_id = application ret.command_code = code self.addOriginHostRealm(ret) if vendor_id: app_container = DiameterAVP() app_container.setCode(260) app_container.setMandatory(True) tmp = DiameterAVP() tmp.setCode(266) tmp.setMandatory(True) tmp.setInteger32(vendor_id) app_container.addAVP(tmp) else: app_container = ret if auth: tmp = DiameterAVP() tmp.setCode(258) tmp.setMandatory(True) tmp.setInteger32(application) app_container.addAVP(tmp) elif acct: tmp = DiameterAVP() tmp.setCode(258) tmp.setMandatory(True) tmp.setInteger32(application) app_container.addAVP(tmp) if app_container != ret: ret.addAVP(app_container) return ret def createAnswer(self, req, ret_code=None): ret = DiameterMessage() ret.request_flag = False ret.proxiable_flag = req.proxiable_flag ret.eTe = req.eTe ret.hBh = req.hBh ret.application_id = req.application_id ret.command_code = req.command_code if ret_code: tmp = DiameterAVP() tmp.setCode(268) tmp.setMandatory(True) tmp.setInteger32(ret_code) ret.addAVP(tmp) self.addOriginHostRealm(ret) return ret def addOriginHostRealm(self, msg): origin_host = DiameterAVP() origin_host.setCode(264) origin_host.setMandatory(True) origin_host.setOctetString(self.identity) msg.addAVP(origin_host) origin_realm = DiameterAVP() origin_realm.setCode(296) origin_realm.setMandatory(True) origin_realm.setOctetString(self.realm) msg.addAVP(origin_realm) def loadDictionary(self, dict_name, dict_file): self.dictionaries[dict_name] = dictionary.DiameterDictionary(dict_file) def getDictionary(self, dict_name): return self.dictionaries[dict_name] def addSupportedVendor(self, vendor): self.supported_vendors.append(vendor) def registerAuthApplication(self, app, vendor, code): self.auth_apps[(vendor,code)] = app def registerAcctApplication(self, app, vendor, code): self.acct_apps[(vendor,code)] = app def registerPeerListener(self, pl): self.peer_listeners.append(pl) def registerPeerIO(self, pio): self.manager.registerPeerIO(pio) def clientV4Add(self, host, port): return self.manager.clientV4Add(host, port) def serverV4Add(self, host, port): return self.manager.serverV4Add(host, port) def serverV4Accept(self, base_peer, host, port): return self.manager.serverV4Accept(base_peer, host, port) def sendByPeer(self, peer, message, retransmission=True): if message.request_flag and retransmission: self.queued_messages.append((peer,message)) self.manager.send(peer, message) def registerPeer(self, peer, identity, realm, apps): r = self.manager.registerPeer(peer, identity, realm, apps) _log.info("Registering peer %s with identity %s for realm %s with apps %s", peer, identity, realm, apps) if r == True: _log.info("Successfully registered %s", peer) for p in self.peer_listeners: if peer.peer_type == PeerStateMachine.PEER_CLIENT: p.connected(peer) else: p.added(peer) return True else: #error, duplicated peer or something like that _log.error("Failed to register %s", peer) return False def handleIncomingMessage(self, peer, message): _log.debug("Handling incoming Diameter message from peer %s", peer) # first check for a vendor-specific application id vendorid = 0 rapp_container = message.findFirstAVP(260) if rapp_container != None: rvendorid = rapp_container.findFirstAVP(266) if rvendorid != None: vendorid = rvendorid.getInteger32() else: rapp_container = message # look for auth/application ids rapp = rapp_container.findFirstAVP(258) if rapp == None: rapp = rapp_container.findFirstAVP(259) if rapp != None: rvalue = rapp.getInteger32() else: rvalue = message.application_id if self.auth_apps.has_key((vendorid,rvalue)): app = self.auth_apps[(vendorid,rvalue)] elif self.acct_apps.has_key((vendorid,rvalue)): app = self.acct_apps[(vendorid,rvalue)] else: _log.error("Peer %s: Application (%d,%d) not found" % (peer, vendorid, rvalue)) if message.request_flag: answ = self.createAnswer(message) answ.error_flag = True self.sendByPeer(peer, answ) return if message.request_flag: app.onRequest(peer, message) else: #remove from retransmission queue self.queued_messages[:] = [x for x in self.queued_messages if not x[1].hBh == message.hBh] app.onAnswer(peer, message) def tick(self): """Check retransmissions""" self.queued_messages[:] = [x for x in self.queued_messages if self.dispatch_messages(*x)] #tick all applications ( required so tick is called only once ) apps = list(set(self.auth_apps.values()).union(set(self.acct_apps.values()))) for app in apps: app.onTick() def dispatch_messages(self, peer, msg): now = int(time.time()) #3 seconds, 3 retries ( one per sec ) if msg.last_try < now - 1: if msg.retries < 3: _log.debug("Sending message to peer %s, attempt number %d", peer, msg.retries) self.manager.send(peer,msg) return True else: _log.error("Failed to send message to peer %s, after %d retries", peer, msg.retries) return False
class Stack: def __init__(self): self.applications = dict() self.peer_listeners = list() self.dictionaries = dict() self.manager = PeerManager(self) self.product_name = "nuswit diameter" self.ip4_address = "127.0.0.1" self.vendor_id = 0 self.firmware_revision = 1 self.watchdog_seconds = None self.hbh = 0 self.ete = 0 self.queued_messages = [] self.identity = None self.realm = None def nextHbH(self): self.hbh += 1 return self.hbh def nextEtE(self): self.ete += 1 return self.ete def createRequest(self, application, code, auth=False, acct=False): ret = DiameterMessage() ret.request_flag = True ret.eTe = self.nextEtE() ret.hBh = self.nextHbH() ret.application_id = application ret.command_code = code origin_host = DiameterAVP() origin_host.setCode(264) origin_host.setMandatory(True) origin_host.setOctetString(self.identity) ret.addAVP(origin_host) origin_realm = DiameterAVP() origin_realm.setCode(296) origin_realm.setMandatory(True) origin_realm.setOctetString(self.realm) ret.addAVP(origin_realm) if auth: tmp = DiameterAVP() tmp.setCode(258) tmp.setMandatory(True) tmp.setInteger32(application) ret.addAVP(tmp) elif acct: tmp = DiameterAVP() tmp.setCode(258) tmp.setMandatory(True) tmp.setInteger32(application) ret.addAVP(tmp) return ret def loadDictionary(self, dict_name, dict_file): self.dictionaries[dict_name] = dictionary.DiameterDictionary(dict_file) def getDictionary(self, dict_name): return self.dictionaries[dict_name] def registerApplication(self, app, vendor, code): self.applications[(vendor,code)] = app def registerPeerListener(self, pl): self.peer_listeners.append(pl) def registerPeerIO(self, pio): self.manager.registerPeerIO(pio) def clientV4Add(self, host, port): return self.manager.clientV4Add(host, port) def serverV4Add(self, host, port): return self.manager.serverV4Add(host, port) def serverV4Accept(self, base_peer, host, port): return self.manager.serverV4Accept(base_peer, host, port) def sendByPeer(self, peer, message, retransmission=True): if message.request_flag and retransmission: self.queued_messages.append((peer,message)) self.manager.send(peer, message) def registerPeer(self, peer, identity, realm, apps): r = self.manager.registerPeer(peer, identity, realm, apps) if r == True: for p in self.peer_listeners: if peer.peer_type == PeerStateMachine.PEER_CLIENT: p.connected(peer) else: p.added(peer) return True else: #error, duplicated peer or something like that return False def handleIncomingMessage(self, peer, message): # look for auth/application ids rapp = message.findFirstAVP(258) if rapp == None: rapp = message.findFirstAVP(259) if rapp != None: rvalue = rapp.getInteger32() else: rvalue = message.application_id try: app = self.applications[(0,rvalue)] except: print("Application %d not found" % app) if message.request_flag: answ = message.createAnswer() answ.error_flag = True self.sendByPeer(peer, answ) return if message.request_flag: app.onRequest(peer, message) else: #remove from retransmission queue self.queued_messages[:] = [x for x in self.queued_messages if not x[1].hBh == message.hBh] app.onAnswer(peer, message) def tick(self): """Check retransmissions""" self.queued_messages[:] = [x for x in self.queued_messages if self.dispatch_messages(*x)] #tick all applications ( required so tick is called only once ) apps = list(set(self.applications.values())) for app in apps: app.onTick() def dispatch_messages(self, peer, msg): now = int(time.time()) print(repr(msg)) print(repr(peer)) #3 seconds, 3 retries ( one per sec ) if msg.last_try < now - 1: if msg.retries < 3: print("Retrying...") self.manager.send(peer,msg) return True else: return False
class Stack: def __init__(self): self.applications = dict() self.peer_listeners = list() self.dictionaries = dict() self.manager = PeerManager(self) self.product_name = "nuswit diameter" self.ip4_address = "127.0.0.1" self.vendor_id = 0 self.firmware_revision = 1 self.watchdog_seconds = None self.hbh = 0 self.ete = 0 self.queued_messages = [] self.identity = None self.realm = None def nextHbH(self): self.hbh += 1 return self.hbh def nextEtE(self): self.ete += 1 return self.ete def createRequest(self, application, code, auth=False, acct=False): ret = DiameterMessage() ret.request_flag = True ret.eTe = self.nextEtE() ret.hBh = self.nextHbH() ret.application_id = application ret.command_code = code origin_host = DiameterAVP() origin_host.setCode(264) origin_host.setMandatory(True) origin_host.setOctetString(self.identity) ret.addAVP(origin_host) origin_realm = DiameterAVP() origin_realm.setCode(296) origin_realm.setMandatory(True) origin_realm.setOctetString(self.realm) ret.addAVP(origin_realm) if auth: tmp = DiameterAVP() tmp.setCode(258) tmp.setMandatory(True) tmp.setInteger32(application) ret.addAVP(tmp) elif acct: tmp = DiameterAVP() tmp.setCode(258) tmp.setMandatory(True) tmp.setInteger32(application) ret.addAVP(tmp) return ret def loadDictionary(self, dict_name, dict_file): self.dictionaries[dict_name] = dictionary.DiameterDictionary(dict_file) def getDictionary(self, dict_name): return self.dictionaries[dict_name] def registerApplication(self, app, vendor, code): self.applications[(vendor, code)] = app def registerPeerListener(self, pl): self.peer_listeners.append(pl) def registerPeerIO(self, pio): self.manager.registerPeerIO(pio) def clientV4Add(self, host, port): return self.manager.clientV4Add(host, port) def serverV4Add(self, host, port): return self.manager.serverV4Add(host, port) def serverV4Accept(self, base_peer, host, port): return self.manager.serverV4Accept(base_peer, host, port) def sendByPeer(self, peer, message, retransmission=True): if message.request_flag and retransmission: self.queued_messages.append((peer, message)) self.manager.send(peer, message) def registerPeer(self, peer, identity, realm, apps): r = self.manager.registerPeer(peer, identity, realm, apps) if r == True: for p in self.peer_listeners: if peer.peer_type == PeerStateMachine.PEER_CLIENT: p.connected(peer) else: p.added(peer) return True else: #error, duplicated peer or something like that return False def handleIncomingMessage(self, peer, message): # look for auth/application ids rapp = message.findFirstAVP(258) if rapp == None: rapp = message.findFirstAVP(259) if rapp != None: rvalue = rapp.getInteger32() else: rvalue = message.application_id try: app = self.applications[(0, rvalue)] except: print("Application %d not found" % app) if message.request_flag: answ = message.createAnswer() answ.error_flag = True self.sendByPeer(peer, answ) return if message.request_flag: app.onRequest(peer, message) else: #remove from retransmission queue self.queued_messages[:] = [ x for x in self.queued_messages if not x[1].hBh == message.hBh ] app.onAnswer(peer, message) def tick(self): """Check retransmissions""" self.queued_messages[:] = [ x for x in self.queued_messages if self.dispatch_messages(*x) ] #tick all applications ( required so tick is called only once ) apps = list(set(self.applications.values())) for app in apps: app.onTick() def dispatch_messages(self, peer, msg): now = int(time.time()) print(repr(msg)) print(repr(peer)) #3 seconds, 3 retries ( one per sec ) if msg.last_try < now - 1: if msg.retries < 3: print("Retrying...") self.manager.send(peer, msg) return True else: return False