def testRaetPreSharedKeysPromiscous(tdir): alphaSigner = SimpleSigner() betaSigner = SimpleSigner() logger.debug("Alpha's verkey {}".format(alphaSigner.naclSigner.verhex)) logger.debug("Beta's verkey {}".format(betaSigner.naclSigner.verhex)) alpha = RoadStack(name='alpha', ha=genHa(), sigkey=alphaSigner.naclSigner.keyhex, auto=AutoMode.always, basedirpath=tdir) beta = RoadStack(name='beta', ha=genHa(), sigkey=betaSigner.naclSigner.keyhex, main=True, auto=AutoMode.always, basedirpath=tdir) try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha, verkey=betaSigner.naclSigner.verhex) alpha.addRemote(betaRemote) alpha.allow(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def __init__(self, *args, **kwargs): checkPortAvailable(kwargs['ha']) basedirpath = kwargs.get('basedirpath') keep = RoadKeep(basedirpath=basedirpath, stackname=kwargs['name'], auto=kwargs.get('auto'), baseroledirpath=basedirpath) # type: RoadKeep kwargs['keep'] = keep localRoleData = keep.loadLocalRoleData() sighex = kwargs.pop('sighex', None) or localRoleData['sighex'] if not sighex: (sighex, _), (prihex, _) = getEd25519AndCurve25519Keys() else: prihex = ed25519SkToCurve25519(sighex, toHex=True) kwargs['sigkey'] = sighex kwargs['prikey'] = prihex self.msgHandler = kwargs.pop('msgHandler', None) # type: Callable # if no timeout is set then message will never timeout self.messageTimeout = kwargs.pop('messageTimeout', 0) self.raetStack = RoadStack(*args, **kwargs) if self.ha[1] != kwargs['ha'].port: error("the stack port number has changed, likely due to " "information in the keep. {} passed {}, actual {}".format( kwargs['name'], kwargs['ha'].port, self.ha[1])) self._created = time.perf_counter() self.coro = None self._conns = set() # type: Set[str]
def testPromiscuousConnection(tdir, keysAndNames): # Simulating node to client connection alphaSighex, alphaPrikey, alphaVerhex, alphaPubkey, alphaName, betaSighex, \ betaPrikey, betaVerhex, betaPubkey, betaName = keysAndNames alpha = RoadStack(name=alphaName, ha=genHa(), sigkey=alphaSighex, prikey=hexlify(alphaPrikey), auto=AutoMode.always, basedirpath=tdir) beta = RoadStack(name=betaName, ha=genHa(), main=True, sigkey=betaSighex, prikey=hexlify(betaPrikey), auto=AutoMode.always, basedirpath=tdir) try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.join(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def testRaetPreSharedKeysNonPromiscous(tdir): alphaSigner = SimpleSigner() betaSigner = SimpleSigner() alphaPrivateer = Privateer() betaPrivateer = Privateer() logger.debug("Alpha's verkey {}".format(alphaSigner.verkey)) logger.debug("Beta's verkey {}".format(betaSigner.verkey)) alpha = RoadStack(name='alpha', ha=genHa(), sigkey=alphaSigner.naclSigner.keyhex, prikey=alphaPrivateer.keyhex, auto=AutoMode.never, basedirpath=tdir) beta = RoadStack(name='beta', ha=genHa(), sigkey=betaSigner.naclSigner.keyhex, prikey=betaPrivateer.keyhex, main=True, auto=AutoMode.never, basedirpath=tdir) alpha.keep.dumpRemoteRoleData({ "acceptance": Acceptance.accepted.value, "verhex": betaSigner.verkey, "pubhex": betaPrivateer.pubhex }, "beta") beta.keep.dumpRemoteRoleData({ "acceptance": Acceptance.accepted.value, "verhex": alphaSigner.verkey, "pubhex": alphaPrivateer.pubhex }, "alpha") try: betaRemote = raet.road.estating.RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.allow(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def postinitio(self): ''' Setup stack instance ''' sigkey = self.local.data.sigkey prikey = self.local.data.prikey name = self.local.data.name dirpath = os.path.abspath( os.path.join(self.opts.value['cachedir'], 'raet')) auto = self.local.data.auto main = self.local.data.main ha = (self.opts.value['interface'], self.opts.value['raet_port']) eid = self.local.data.eid local = LocalEstate(eid=eid, name=name, ha=ha, sigkey=sigkey, prikey=prikey) txMsgs = self.txmsgs.value rxMsgs = self.rxmsgs.value safe = salting.SaltSafe(opts=self.opts.value) self.stack.value = RoadStack(local=local, store=self.store, name=name, auto=auto, main=main, dirpath=dirpath, safe=safe, txMsgs=txMsgs, rxMsgs=rxMsgs) self.stack.value.Bk = raeting.bodyKinds.msgpack
def action(self): ''' enter action should only run once to setup road stack. moved from postinitio so can do clean up before stack is initialized do salt raet road stack setup at enter ''' kind = self.opts.value['__role'] # application kind if kind not in daemons.APPL_KINDS: emsg = ("Invalid application kind = '{0}'.".format(kind)) log.error(emsg + '\n') raise ValueError(emsg) role = self.opts.value.get('id', '') if not role: emsg = ("Missing role required to setup RoadStack.") log.error(emsg + "\n") raise ValueError(emsg) name = "{0}_{1}".format(role, kind) sigkey = self.local.data.sigkey prikey = self.local.data.prikey main = self.opts.value.get('raet_main', self.local.data.main) mutable = self.opts.value.get('raet_mutable', self.local.data.mutable) always = self.opts.value.get('open_mode', False) mutable = mutable or always # open_made when True takes precedence uid = self.local.data.uid ha = (self.opts.value['interface'], self.opts.value['raet_port']) basedirpath = os.path.abspath( os.path.join(self.opts.value['cachedir'], 'raet')) txMsgs = self.txmsgs.value rxMsgs = self.rxmsgs.value keep = salting.SaltKeep(opts=self.opts.value, basedirpath=basedirpath, stackname=name) self.stack.value = RoadStack(store=self.store, keep=keep, name=name, uid=uid, ha=ha, role=role, sigkey=sigkey, prikey=prikey, main=main, kind=daemons.APPL_KINDS[kind], mutable=mutable, txMsgs=txMsgs, rxMsgs=rxMsgs, period=3.0, offset=0.5) if self.opts.value.get('raet_clear_remotes'): for remote in self.stack.value.remotes.values(): self.stack.value.removeRemote(remote, clear=True) self.stack.puid = self.stack.value.Uid # reset puid
def action(self): self.stats_req.value = deque() minionStack = self.road_stack.value # Create Master Stack self.store.stamp = 0.0 masterStack = RoadStack(store=self.store, name='master', ha=('', raeting.RAET_PORT), role='master', main=True, cleanremote=True, period=3.0, offset=0.5) self.event_stack.value = masterStack minionRemoteMaster = RemoteEstate(stack=minionStack, fuid=0, sid=0, ha=masterStack.local.ha) minionStack.addRemote(minionRemoteMaster) # Make life easier masterStack.keep.auto = raeting.AutoMode.always.value minionStack.keep.auto = raeting.AutoMode.always.value minionStack.join(minionRemoteMaster.uid) serviceRoads([minionStack, masterStack]) minionStack.allow(minionRemoteMaster.uid) serviceRoads([minionStack, masterStack])
def testRaetPreSharedKeysPromiscous(tdir): alphaSigner = NaclSigner() betaSigner = NaclSigner() logger.debug("Alpha's verkey {}".format(alphaSigner.verhex)) logger.debug("Beta's verkey {}".format(betaSigner.verhex)) alpha = RoadStack(name='alpha', ha=genHa(), sigkey=alphaSigner.keyhex, auto=AutoMode.always, basedirpath=tdir) beta = RoadStack(name='beta', ha=genHa(), sigkey=betaSigner.keyhex, main=True, auto=AutoMode.always, basedirpath=tdir) try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha, verkey=betaSigner.verhex) alpha.addRemote(betaRemote) alpha.allow(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def testNonPromiscousConnectionWithOneKey(tdir, keysAndNames): # Simulating node to node connection alphaSighex, alphaPrikey, alphaVerhex, alphaPubkey, alphaName, betaSighex,\ betaPrikey, betaVerhex, betaPubkey, betaName = keysAndNames alpha = RoadStack(name=alphaName, ha=genHa(), sigkey=alphaSighex, prikey=hexlify(alphaPrikey), auto=AutoMode.never, basedirpath=tdir) beta = RoadStack(name=betaName, ha=genHa(), sigkey=betaSighex, prikey=hexlify(betaPrikey), main=True, auto=AutoMode.never, basedirpath=tdir) alpha.keep.dumpRemoteRoleData({ "acceptance": Acceptance.accepted.value, "verhex": betaVerhex, "pubhex": hexlify(betaPubkey) }, betaName) beta.keep.dumpRemoteRoleData({ "acceptance": Acceptance.accepted.value, "verhex": alphaVerhex, "pubhex": hexlify(alphaPubkey) }, alphaName) try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.allow(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def setupAlpha(ha): nonlocal alpha alpha = RoadStack(name='alpha', ha=ha, sigkey=alphaSigner.keyhex, prikey=alphaPrivateer.keyhex, auto=AutoMode.never, basedirpath=tdir) alpha.keep.dumpRemoteRoleData({ "acceptance": Acceptance.accepted.value, "verhex": betaSigner.verhex, "pubhex": betaPrivateer.pubhex }, "beta")
def testPromiscuousConnection(tdir): alpha = RoadStack(name='alpha', ha=genHa(), auto=AutoMode.always, basedirpath=tdir) beta = RoadStack(name='beta', ha=genHa(), main=True, auto=AutoMode.always, basedirpath=tdir) try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.join(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def testRaetPreSharedKeysNonPromiscous(tdir): alphaSigner = SimpleSigner() betaSigner = SimpleSigner() alphaPrivateer = Privateer() betaPrivateer = Privateer() logger.debug("Alpha's verkey {}".format(alphaSigner.naclSigner.verhex)) logger.debug("Beta's verkey {}".format(betaSigner.naclSigner.verhex)) alpha = RoadStack(name='alpha', ha=genHa(), sigkey=alphaSigner.naclSigner.keyhex, prikey=alphaPrivateer.keyhex, auto=AutoMode.never, basedirpath=tdir) beta = RoadStack(name='beta', ha=genHa(), sigkey=betaSigner.naclSigner.keyhex, prikey=betaPrivateer.keyhex, main=True, auto=AutoMode.never, basedirpath=tdir) alpha.keep.dumpRemoteRoleData( { "acceptance": Acceptance.accepted.value, "verhex": betaSigner.naclSigner.verhex, "pubhex": betaPrivateer.pubhex }, "beta") beta.keep.dumpRemoteRoleData( { "acceptance": Acceptance.accepted.value, "verhex": alphaSigner.naclSigner.verhex, "pubhex": alphaPrivateer.pubhex }, "alpha") try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.allow(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def action(self): ''' enter action should only run once to setup road stack. moved from postinitio so can do clean up before stack is initialized do salt raet road stack setup at enter ''' role = self.opts.value.get('id', self.local.data.role) kind = self.opts.value['__role'] # application kind sigkey = self.local.data.sigkey prikey = self.local.data.prikey #name = self.opts.value.get('id', self.local.data.name) #name = LocalEstate.nameGuid(prefix='road') # name is guid #name = 'stack_' + role name = role main = self.opts.value.get('raet_main', self.local.data.main) mutable = self.opts.value.get('raet_mutable', self.local.data.mutable) always = self.opts.value.get('open_mode', False) mutable = mutable or always # open_made when True takes precedence uid = self.local.data.uid ha = (self.opts.value['interface'], self.opts.value['raet_port']) basedirpath = os.path.abspath( os.path.join(self.opts.value['cachedir'], 'raet')) txMsgs = self.txmsgs.value rxMsgs = self.rxmsgs.value keep = salting.SaltKeep(opts=self.opts.value, basedirpath=basedirpath, stackname=name) self.stack.value = RoadStack(store=self.store, keep=keep, name=name, uid=uid, ha=ha, role=role, sigkey=sigkey, prikey=prikey, main=main, mutable=mutable, txMsgs=txMsgs, rxMsgs=rxMsgs, period=3.0, offset=0.5)
def testNonPromiscousConnectionWithOneKey(tdir, keysAndNames): # Simulating node to node connection alphaSighex, alphaPrikey, alphaVerhex, alphaPubkey, alphaName, betaSighex,\ betaPrikey, betaVerhex, betaPubkey, betaName = keysAndNames alpha = RoadStack(name=alphaName, ha=genHa(), sigkey=alphaSighex, prikey=hexlify(alphaPrikey), auto=AutoMode.never, basedirpath=tdir) beta = RoadStack(name=betaName, ha=genHa(), sigkey=betaSighex, prikey=hexlify(betaPrikey), main=True, auto=AutoMode.never, basedirpath=tdir) alpha.keep.dumpRemoteRoleData( { "acceptance": Acceptance.accepted.value, "verhex": betaVerhex, "pubhex": hexlify(betaPubkey) }, betaName) beta.keep.dumpRemoteRoleData( { "acceptance": Acceptance.accepted.value, "verhex": alphaVerhex, "pubhex": hexlify(alphaPubkey) }, alphaName) try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.allow(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def action(self): ''' enter action should only run once to setup road stack. moved from postinitio so can do clean up before stack is initialized do salt raet road stack setup at enter ''' name = self.opts.value.get('id', self.local.data.name) sigkey = self.local.data.sigkey prikey = self.local.data.prikey auto = self.local.data.auto main = self.local.data.main eid = self.local.data.eid ha = (self.opts.value['interface'], self.opts.value['raet_port']) basedirpath = os.path.abspath( os.path.join(self.opts.value['cachedir'], 'raet')) local = LocalEstate(eid=eid, name=name, main=main, ha=ha, sigkey=sigkey, prikey=prikey) txMsgs = self.txmsgs.value rxMsgs = self.rxmsgs.value keep = salting.SaltKeep(opts=self.opts.value, basedirpath=basedirpath, stackname=name, auto=auto) self.stack.value = RoadStack(local=local, store=self.store, name=name, main=main, keep=keep, txMsgs=txMsgs, rxMsgs=rxMsgs, period=3.0, offset=0.5)
def testConnectionWithHaChanged(tdir): console = getConsole() console.reinit(verbosity=console.Wordage.verbose) alphaSigner = SimpleSigner() betaSigner = SimpleSigner() alphaPrivateer = Privateer() betaPrivateer = Privateer() logger.debug("Alpha's verkey {}".format(alphaSigner.naclSigner.verhex)) logger.debug("Beta's verkey {}".format(betaSigner.naclSigner.verhex)) alpha = None def setupAlpha(ha): nonlocal alpha alpha = RoadStack(name='alpha', ha=ha, sigkey=alphaSigner.naclSigner.keyhex, prikey=alphaPrivateer.keyhex, auto=AutoMode.never, basedirpath=tdir) alpha.keep.dumpRemoteRoleData( { "acceptance": Acceptance.accepted.value, "verhex": betaSigner.naclSigner.verhex, "pubhex": betaPrivateer.pubhex }, "beta") oldHa = genHa() setupAlpha(oldHa) beta = RoadStack(name='beta', ha=genHa(), sigkey=betaSigner.naclSigner.keyhex, prikey=betaPrivateer.keyhex, main=True, auto=AutoMode.never, basedirpath=tdir, mutable=True) beta.keep.dumpRemoteRoleData( { "acceptance": Acceptance.accepted.value, "verhex": alphaSigner.naclSigner.verhex, "pubhex": alphaPrivateer.pubhex }, "alpha") try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.join(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) logger.debug("beta knows alpha as {}".format( getRemote(beta, "alpha").ha)) cleanup(alpha) newHa = genHa() logger.debug("alpha changing ha to {}".format(newHa)) setupAlpha(newHa) betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.join(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) logger.debug("beta knows alpha as {}".format( getRemote(beta, "alpha").ha)) finally: cleanup(alpha, beta)
class RStack(NetworkInterface): def __init__(self, *args, **kwargs): checkPortAvailable(kwargs['ha']) basedirpath = kwargs.get('basedirpath') authMode = kwargs.pop('auth_mode', None) kwargs['auto'] = self._getAuto(authMode) keep = RoadKeep(basedirpath=basedirpath, stackname=kwargs['name'], auto=kwargs.get('auto'), baseroledirpath=basedirpath) # type: RoadKeep kwargs['keep'] = keep localRoleData = keep.loadLocalRoleData() sighex = kwargs.pop('sighex', None) or localRoleData['sighex'] if not sighex: (sighex, _), (prihex, _) = getEd25519AndCurve25519Keys() else: prihex = ed25519SkToCurve25519(sighex, toHex=True) kwargs['sigkey'] = sighex kwargs['prikey'] = prihex self.msgHandler = kwargs.pop('msgHandler', None) # type: Callable # if no timeout is set then message will never timeout self.messageTimeout = kwargs.pop('messageTimeout', 0) self.raetStack = RoadStack(*args, **kwargs) if self.ha[1] != kwargs['ha'].port: error("the stack port number has changed, likely due to " "information in the keep. {} passed {}, actual {}".format( kwargs['name'], kwargs['ha'].port, self.ha[1])) self._created = time.perf_counter() self.coro = None self._conns = set() # type: Set[str] def _getAuto(self, authMode): if authMode == AuthMode.ALLOW_ANY.value: return AutoMode.always if authMode == AuthMode.RESTRICTED.value: return AutoMode.never return None def __repr__(self): return self.name @property def name(self): return self.raetStack.name @property def remotes(self): return self.raetStack.remotes @property def created(self): return self._created @property def rxMsgs(self): return self.raetStack.rxMsgs @staticmethod def isRemoteConnected(r) -> bool: """ A node is considered to be connected if it is joined, allowed and alived. :param r: the remote to check """ return r.joined and r.allowed and r.alived @staticmethod def initLocalKeys(name, baseDir, sigseed, override=False): """ Initialize RAET local keep. Write local role data to file. :param name: name of the node :param baseDir: base directory :param pkseed: seed to generate public and private key pair :param sigseed: seed to generate signing and verification key pair :param override: overwrite the local role.json file if already exists :return: tuple(public key, verification key) """ rolePath = os.path.join(baseDir, name, "role", "local", "role.json") if os.path.isfile(rolePath): if not override: raise FileExistsError( "Keys exists for local role {}".format(name)) if sigseed and not isinstance(sigseed, bytes): sigseed = sigseed.encode() signer = Signer(sigseed) keep = RoadKeep(stackname=name, baseroledirpath=baseDir) sigkey, verkey = signer.keyhex, signer.verhex prikey, pubkey = ed25519SkToCurve25519(sigkey, toHex=True), \ ed25519PkToCurve25519(verkey, toHex=True) data = OrderedDict([("role", name), ("prihex", prikey), ("sighex", sigkey)]) keep.dumpLocalRoleData(data) return pubkey.decode(), verkey.decode() @staticmethod def initRemoteKeys(name, remoteName, baseDir, verkey, override=False): """ Initialize RAET remote keep :param name: name of the node :param remoteName: name of the remote to store keys for :param baseDir: base directory :param pubkey: public key of the remote :param verkey: private key of the remote :param override: overwrite the role.remoteName.json file if it already exists. """ rolePath = os.path.join(baseDir, name, "role", "remote", "role.{}.json".format(remoteName)) if os.path.isfile(rolePath): if not override: raise FileExistsError( "Keys exists for remote role {}".format(remoteName)) keep = RoadKeep(stackname=name, baseroledirpath=baseDir) data = OrderedDict([('role', remoteName), ('acceptance', 1), ('pubhex', ed25519PkToCurve25519(verkey, toHex=True)), ('verhex', verkey)]) keep.dumpRemoteRoleData(data, role=remoteName) def onHostAddressChanged(self): logger.debug( "{} clearing local data in keep as host address changed".format( self.name)) self.raetStack.keep.clearLocalData() @staticmethod def areKeysSetup(name, baseDir): """ Check that the local RAET keep has the values of role, sighex and prihex populated for the given node :param name: the name of the node to check the keys for :param baseDir: base directory of Plenum :return: whether the keys are setup """ localRoleData = getLocalKeep(name=name, baseDir=baseDir) for key in ['role', 'sighex', 'prihex']: if localRoleData.get(key) is None: return False return True @staticmethod def learnKeysFromOthers(baseDir, name, others): pass @staticmethod def getHaFromLocal(name, basedirpath): localEstate = getLocalEstateData(name, basedirpath) if localEstate: return localEstate.get("ha") def tellKeysToOthers(self, others): pass def getRemote(self, name: str = None, ha: HA = None): """ Find the remote by name or ha. :param name: the name of the remote to find :param ha: host address pair the remote to find :raises: RemoteNotFound """ return self.findInRemotesByHA(ha) if ha else \ self.findInRemotesByName(name) def connect(self, name=None, remoteId=None, ha=None, verKeyRaw=None, publicKeyRaw=None): """ Connect to the node specified by name. :param name: name of the node to connect to :type name: str or (HA, tuple) :return: the uid of the remote estate, or None if a connect is not attempted """ # if not self.isKeySharing: # logger.debug("{} skipping join with {} because not key sharing". # format(self, name)) # return None if not remoteId and not ha: raise ValueError( 'Either Host Address or Remote ID must be provided to connect to a node in Raet stack' ) if remoteId: remote = self.remotes[remoteId] return self._doConnectRemote(remote, name) else: return self._doConnectByHA(ha, name) def _doConnectByHA(self, ha, name=None): remote = RemoteEstate(stack=self.raetStack, ha=ha) self.raetStack.addRemote(remote) return self._doConnectRemote(remote, name) def _doConnectRemote(self, remote, name=None): # updates the store time so the join timer is accurate self.updateStamp() self.raetStack.join(uid=remote.uid, cascade=True, timeout=30) logger.info("{} looking for {} at {}:{}".format( self, name or remote.name, *remote.ha), extra={ "cli": "PLAIN", "tags": ["node-looking"] }) return remote.uid def removeRemote(self, r): self.raetStack.removeRemote(r) def transmit(self, msg, uid, timeout=None): self.raetStack.transmit(msg, uid, timeout=timeout) @property def ha(self): return self.raetStack.ha def start(self): if not self.opened: self.open() logger.info("stack {} starting at {} in {} mode".format( self, self.ha, self.raetStack.keep.auto), extra={"cli": False}) # self.coro = self._raetcoro() self.coro = self._raetcoro def stop(self): if self.opened: self.close() self.coro = None logger.info("stack {} stopped".format(self.name), extra={"cli": False}) async def service(self, limit=None) -> int: """ Service `limit` number of received messages in this stack. :param limit: the maximum number of messages to be processed. If None, processes all of the messages in rxMsgs. :return: the number of messages processed. """ pracLimit = limit if limit else sys.maxsize if self.coro: # x = next(self.coro) x = await self.coro() if x > 0: for x in range(pracLimit): try: self.msgHandler(self.raetStack.rxMsgs.popleft()) except IndexError: break return x else: logger.debug("{} is stopped".format(self)) return 0 # def _raetcoro(self): # """ # Generator to service all messages. # Yields the length of rxMsgs queue of this stack. # """ # while True: # try: # self._serviceStack(self.age) # l = len(self.rxMsgs) # except Exception as ex: # if isinstance(ex, OSError) and \ # len(ex.args) > 0 and \ # ex.args[0] == 22: # logger.error("Error servicing stack {}: {}. This could be " # "due to binding to an internal network " # "and trying to route to an external one.". # format(self.name, ex), extra={'cli': 'WARNING'}) # else: # logger.error("Error servicing stack {}: {} {}". # format(self.name, ex, ex.args), # extra={'cli': 'WARNING'}) # # l = 0 # yield l async def _raetcoro(self): try: await self._serviceStack(self.age) l = len(self.raetStack.rxMsgs) except Exception as ex: if isinstance(ex, OSError) and \ len(ex.args) > 0 and \ ex.args[0] == 22: logger.error("Error servicing stack {}: {}. This could be " "due to binding to an internal network " "and trying to route to an external one.".format( self.name, ex), extra={'cli': 'WARNING'}) else: logger.error("Error servicing stack {}: {} {}".format( self.name, ex, ex.args), extra={'cli': 'WARNING'}) l = 0 return l async def _serviceStack(self, age): """ Update stacks clock and service all tx and rx messages. :param age: update timestamp of this RoadStack to this value """ self.updateStamp(age) self.raetStack.serviceAll() def updateStamp(self, age=None): """ Change the timestamp of this stack's test store. :param age: the timestamp will be set to this value """ self.raetStack.store.changeStamp(age if age else self.age) @property def opened(self): return self.raetStack.server.opened def open(self): """ Open the UDP socket of this stack's server. """ self.raetStack.server.open() # close the UDP socket def close(self): """ Close the UDP socket of this stack's server. """ self.raetStack.server.close() # close the UDP socket @property def isKeySharing(self): return self.raetStack.keep.auto != AutoMode.never @property def verhex(self): return self.raetStack.local.signer.verhex @property def keyhex(self): return self.raetStack.local.signer.keyhex @property def pubhex(self): return self.raetStack.local.priver.pubhex @property def prihex(self): return self.raetStack.local.priver.keyhex def send(self, msg: Any, remoteName: str, ha=None): """ Transmit the specified message to the remote specified by `remoteName`. :param msg: a message :param remoteName: the name of the remote """ rid = self.getRemote(remoteName, ha).uid # Setting timeout to never expire self.raetStack.transmit(msg, rid, timeout=self.messageTimeout)