#!/usr/bin/env python3 # -*- coding: utf-8 -*- """This is some demo code showing how a BRWSKY proxy would find a registrar in an ANIMA network using GRASP. """ import grasp import threading import time ################################### # Utility routine for debugging: # Print obj_registry and flood cache ################################### def dump_some(): grasp.tprint("Objective registry contents:") for x in grasp._obj_registry: o= x.objective grasp.tprint(o.name,"ASA:",x.asa_id,"Listen:",x.listening,"Neg:",o.neg, "Synch:",o.synch,"Count:",o.loop_count,"Value:",o.value) grasp.tprint("Flood cache contents:") for x in grasp._flood_cache: grasp.tprint(x.objective.name,"count:",x.objective.loop_count,"value:", x.objective.value,"source",x.source.locator, x.source.protocol, x.source.port,"expiry",x.source.expire) ################################### # Main thread starts here ################################### grasp.tprint("Procksy is starting up") #grasp.test_mode = True # tell everybody it's a test time.sleep(1) # just to avoid mixed up print output #################################### # Register ASA/objectives #################################### _ok,_asa_nonce = grasp.register_asa("Procksy") if _ok: grasp.tprint("ASA Procksy registered OK") else: exit() # Construct the (empty) GRASP objective to find the registrar # It's only used for get_flood so doesn't need to be filled in est_obj = grasp.objective("AN_registrar") est_obj.synch = True # Construct the GRASP objective to announce the proxy proxy_obj = grasp.objective("AN_proxy") proxy_obj.synch = True #placeholder for now, more to be filled in _ok, _temp = grasp.register_obj(_asa_nonce,proxy_obj) if _ok: grasp.tprint("Objective", proxy_obj.name,"registered OK") else: exit() ################################### # Now find the registrar(s) and do stuff... ################################### while True: registrar = None _ok, _results = grasp.get_flood(_asa_nonce, est_obj) if _ok: grasp.tprint("Found",len(_results),"result(s)") for x in _results: # Extract the details distance = x.objective.value[0] - x.objective.loop_count priority = x.objective.value[1] weight = x.objective.value[2] methods = x.objective.value[3] # Print the result grasp.tprint(x.objective.name, "flooded from", x.source.locator, x.source.protocol, x.source.port,"expiry",x.source.expire, "distance", distance, "priority", priority, "weight", weight, "methods", methods) # use whatever logic you want to decide which result to use. # For the demo code, we just pick the last one: registrar = x else: grasp.tprint("get_flood failed", _results) if registrar: r_addr = registrar.source.locator r_port = registrar.source.port r_method = registrar.objective.value[3][0] # For demo, pick the first method grasp.tprint("Chose", r_addr, r_port, r_method) # Try to connect to the registrar # try: # (socket calls etc) # simulate a random failure with a divide-by-zero _= 1/grasp._prng.randint(0,3) except: # Socket failure, tag this registrar as expired. # (Since floods expire, eventually the bad registrar # will vanish anyway, but this call avoids the wait.) grasp.tprint("Communication failed, expiring that registrar") grasp.expire_flood(_asa_nonce, registrar) time.sleep(23) # wait chosen to avoid synchronicity with Reggie