def __init__(self, ip: str, port: int, log_level=255, encoder: BasicEncoder = None, autoconfig: bool = False, interfaces=None): # create encoder and chunkifyer if encoder is None: self.encoder = SimpleStringEncoder(log_level=log_level) else: encoder.set_log_level(log_level) self.encoder = encoder self.chunkifyer = SimpleContentChunkifyer() # initialize layers synced_data_struct_factory = PiCNSyncDataStructFactory() synced_data_struct_factory.register("faceidtable", FaceIDDict) synced_data_struct_factory.create_manager() faceidtable = synced_data_struct_factory.manager.faceidtable() if interfaces is None: interfaces = [UDP4Interface(0)] else: interfaces = interfaces # create layers self.linklayer = BasicLinkLayer(interfaces, faceidtable, log_level=log_level) self.packetencodinglayer = BasicPacketEncodingLayer( self.encoder, log_level=log_level) self.chunklayer = BasicChunkLayer(self.chunkifyer, log_level=log_level) self.lstack: LayerStack = LayerStack( [self.chunklayer, self.packetencodinglayer, self.linklayer]) self.autoconfig = autoconfig if autoconfig: self.autoconfiglayer: AutoconfigClientLayer = AutoconfigClientLayer( self.linklayer) self.lstack.insert(self.autoconfiglayer, on_top_of=self.packetencodinglayer) # setup communication if port is None: self.fid = self.linklayer.faceidtable.get_or_create_faceid( AddressInfo(ip, 0)) else: self.fid = self.linklayer.faceidtable.get_or_create_faceid( AddressInfo((ip, port), 0)) # send packet self.lstack.start_all()
def test_insert_bottom(self): toplayer: LayerProcess = BasicPacketEncodingLayer() newlayer: LayerProcess = BasicPacketEncodingLayer() lstack: LayerStack = LayerStack([toplayer]) lstack.insert(newlayer, below_of=toplayer) self.assertEqual(2, len(lstack.layers)) self.assertEqual(toplayer, lstack.layers[0]) self.assertEqual(newlayer, lstack.layers[1]) self.assertEqual(toplayer.queue_to_lower, newlayer.queue_from_higher) self.assertEqual(toplayer.queue_from_lower, newlayer.queue_to_higher) self.assertEqual(lstack.queue_to_lower, newlayer.queue_to_lower) self.assertEqual(lstack.queue_from_lower, newlayer.queue_from_lower)
def __init__(self, ip: str, port: int, high_level_name: Name, log_level=255): """ :param ip: :param port: :param high_level_name: :param log_level: """ """ Create stack of layers for fetch tool (UDP only) :param ip: IP address of entry node to network :param port: Port address of entry node to network :param high_level_name: Name of high-level object to fetch :param log_level: Log level """ # create encoder self.encoder = NdnTlvEncoder() # create datastruct synced_data_struct_factory1 = PiCNSyncDataStructFactory() synced_data_struct_factory1.register("faceidtable", FaceIDDict) synced_data_struct_factory1.create_manager() faceidtable = synced_data_struct_factory1.manager.faceidtable() # create layers self.link_layer = BasicLinkLayer([UDP4Interface(0)], faceidtable, log_level=log_level) self.packet_encoding_layer = BasicPacketEncodingLayer( self.encoder, log_level=log_level) self.fetch_layer = FetchLayer(log_level) self.layer_stack: LayerStack = LayerStack( [self.fetch_layer, self.packet_encoding_layer, self.link_layer]) # setup face self.face_id = self.link_layer.faceidtable.get_or_create_faceid( AddressInfo((ip, port), 0)) # start all layers in the stack self.layer_stack.start_all() # trigger fetch self.fetch_layer.trigger_fetching(high_level_name, self.face_id)
def test_create_multiple(self): toplayer: LayerProcess = BasicPacketEncodingLayer() middlelayer: LayerProcess = BasicPacketEncodingLayer() bottomlayer: LayerProcess = BasicPacketEncodingLayer() lstack: LayerStack = LayerStack([toplayer, middlelayer, bottomlayer]) self.assertEqual(3, len(lstack.layers)) self.assertEqual(4, len(lstack.queues)) self.assertEqual(toplayer.queue_to_lower, middlelayer.queue_from_higher) self.assertEqual(toplayer.queue_from_lower, middlelayer.queue_to_higher) self.assertEqual(middlelayer.queue_to_lower, bottomlayer.queue_from_higher) self.assertEqual(middlelayer.queue_from_lower, bottomlayer.queue_to_higher) self.assertNotEqual(toplayer.queue_to_lower, bottomlayer.queue_from_higher) self.assertNotEqual(toplayer.queue_from_lower, bottomlayer.queue_to_higher)
def test_insert_between(self): toplayer: LayerProcess = BasicPacketEncodingLayer() bottomlayer: LayerProcess = BasicPacketEncodingLayer() newlayer: LayerProcess = BasicPacketEncodingLayer() lstack: LayerStack = LayerStack([toplayer, bottomlayer]) lstack.insert(newlayer, on_top_of=bottomlayer) self.assertEqual(3, len(lstack.layers)) self.assertEqual(toplayer, lstack.layers[0]) self.assertEqual(newlayer, lstack.layers[1]) self.assertEqual(bottomlayer, lstack.layers[2]) self.assertEqual(toplayer.queue_to_lower, newlayer.queue_from_higher) self.assertEqual(toplayer.queue_from_lower, newlayer.queue_to_higher) self.assertEqual(bottomlayer.queue_to_higher, newlayer.queue_from_lower) self.assertEqual(bottomlayer.queue_from_higher, newlayer.queue_to_lower) self.assertNotEqual(toplayer.queue_to_lower, bottomlayer.queue_from_higher) self.assertNotEqual(toplayer.queue_from_lower, bottomlayer.queue_to_higher)
def setUp(self): synced_data_struct_factory = PiCNSyncDataStructFactory() synced_data_struct_factory.register('cs', ContentStoreMemoryExact) synced_data_struct_factory.register('pit', PendingInterstTableMemoryExact) synced_data_struct_factory.register( 'fib', ForwardingInformationBaseMemoryPrefix) synced_data_struct_factory.register('faceidtable', FaceIDDict) synced_data_struct_factory.create_manager() # Set up forwarder cs = synced_data_struct_factory.manager.cs() pit = synced_data_struct_factory.manager.pit() fib = synced_data_struct_factory.manager.fib() prefixes = [(Name('/test/prefix/repos'), True)] # Auto-assign port forwarder_interface = UDP4Interface(0) forwarder_fidtable = synced_data_struct_factory.manager.faceidtable() forwarder_linklayer = BasicLinkLayer([forwarder_interface], forwarder_fidtable) forwarder_port = forwarder_interface.get_port() forwarder_encoder = NdnTlvEncoder() icnlayer = BasicICNLayer() icnlayer.cs = cs icnlayer.pit = pit icnlayer.fib = fib forwarder_autoconfiglayer = AutoconfigServerLayer( forwarder_linklayer, registration_prefixes=prefixes) forwarder_autoconfiglayer.fib = fib self.forwarder = LayerStack([ icnlayer, forwarder_autoconfiglayer, BasicPacketEncodingLayer(forwarder_encoder), forwarder_linklayer ]) # Set up repo repository = MockRepository(Name('/thisshouldbechanged')) repo_chunkifyer = SimpleContentChunkifyer() repo_chunklayer = BasicChunkLayer(repo_chunkifyer) repo_encoder = NdnTlvEncoder() # Auto-assign port repo_interface = UDP4Interface(0) repo_fidtable = synced_data_struct_factory.manager.faceidtable() repo_linklayer = BasicLinkLayer([repo_interface], repo_fidtable) repo_port = repo_interface.get_port() self.repo = LayerStack([ BasicRepositoryLayer(repository), repo_chunklayer, AutoconfigRepoLayer('testrepo', repo_linklayer, repository, '127.0.0.1', forwarder_port), BasicPacketEncodingLayer(repo_encoder), repo_linklayer ]) # Set up fetch client client_chunkifyer = SimpleContentChunkifyer() client_chunklayer = BasicChunkLayer(client_chunkifyer) client_encoder = NdnTlvEncoder() client_interface = UDP4Interface(0) client_fidtable = synced_data_struct_factory.manager.faceidtable() client_linklayer = BasicLinkLayer([client_interface], client_fidtable) self.client = LayerStack([ client_chunklayer, AutoconfigClientLayer(client_linklayer, bcport=forwarder_port), BasicPacketEncodingLayer(client_encoder), client_linklayer ])
class AutoConfigFullStackTestSimulation(object): def setUp(self): synced_data_struct_factory = PiCNSyncDataStructFactory() synced_data_struct_factory.register('cs', ContentStoreMemoryExact) synced_data_struct_factory.register('pit', PendingInterstTableMemoryExact) synced_data_struct_factory.register( 'fib', ForwardingInformationBaseMemoryPrefix) synced_data_struct_factory.register('faceidtable', FaceIDDict) synced_data_struct_factory.create_manager() # Set up forwarder cs = synced_data_struct_factory.manager.cs() pit = synced_data_struct_factory.manager.pit() fib = synced_data_struct_factory.manager.fib() prefixes = [(Name('/test/prefix/repos'), True)] # Auto-assign port forwarder_interface = UDP4Interface(0) forwarder_fidtable = synced_data_struct_factory.manager.faceidtable() forwarder_linklayer = BasicLinkLayer([forwarder_interface], forwarder_fidtable) forwarder_port = forwarder_interface.get_port() forwarder_encoder = NdnTlvEncoder() icnlayer = BasicICNLayer() icnlayer.cs = cs icnlayer.pit = pit icnlayer.fib = fib forwarder_autoconfiglayer = AutoconfigServerLayer( forwarder_linklayer, registration_prefixes=prefixes) forwarder_autoconfiglayer.fib = fib self.forwarder = LayerStack([ icnlayer, forwarder_autoconfiglayer, BasicPacketEncodingLayer(forwarder_encoder), forwarder_linklayer ]) # Set up repo repository = MockRepository(Name('/thisshouldbechanged')) repo_chunkifyer = SimpleContentChunkifyer() repo_chunklayer = BasicChunkLayer(repo_chunkifyer) repo_encoder = NdnTlvEncoder() # Auto-assign port repo_interface = UDP4Interface(0) repo_fidtable = synced_data_struct_factory.manager.faceidtable() repo_linklayer = BasicLinkLayer([repo_interface], repo_fidtable) repo_port = repo_interface.get_port() self.repo = LayerStack([ BasicRepositoryLayer(repository), repo_chunklayer, AutoconfigRepoLayer('testrepo', repo_linklayer, repository, '127.0.0.1', forwarder_port), BasicPacketEncodingLayer(repo_encoder), repo_linklayer ]) # Set up fetch client client_chunkifyer = SimpleContentChunkifyer() client_chunklayer = BasicChunkLayer(client_chunkifyer) client_encoder = NdnTlvEncoder() client_interface = UDP4Interface(0) client_fidtable = synced_data_struct_factory.manager.faceidtable() client_linklayer = BasicLinkLayer([client_interface], client_fidtable) self.client = LayerStack([ client_chunklayer, AutoconfigClientLayer(client_linklayer, bcport=forwarder_port), BasicPacketEncodingLayer(client_encoder), client_linklayer ]) def tearDown(self): self.forwarder.stop_all() self.repo.stop_all() self.client.stop_all() def run_simulation(self): self.forwarder.start_all() time.sleep(1.0) self.repo.start_all() time.sleep(1.0) self.client.start_all() time.sleep(5.0) # Send an interest with a fixed name, let autoconfig figure out where to get the data from name = Name('/test/prefix/repos/testrepo/testcontent') interest = Interest(name) self.client.queue_from_higher.put([None, interest]) try: data = self.client.queue_to_higher.get(timeout=20.0) except queue.Empty: self.fail() if isinstance( data[1], Content ) and data[1].name == name and data[1].content == "testcontent": print("Simulation successful") else: print("Error")
def __init__(self, port=9000, log_level=255, encoder: BasicEncoder = None, interfaces: List[BaseInterface] = None, executors: BaseNFNExecutor = None, ageing_interval: int = 3, use_thunks=False): # debug level logger = Logger("NFNForwarder", log_level) logger.info("Start PiCN NFN Forwarder on port " + str(port)) # packet encoder if encoder is None: self.encoder = SimpleStringEncoder(log_level=log_level) else: encoder.set_log_level(log_level) self.encoder = encoder # setup data structures synced_data_struct_factory = PiCNSyncDataStructFactory() synced_data_struct_factory.register("cs", ContentStoreMemoryExact) synced_data_struct_factory.register( "fib", ForwardingInformationBaseMemoryPrefix) synced_data_struct_factory.register("pit", PendingInterstTableMemoryExact) synced_data_struct_factory.register("faceidtable", FaceIDDict) synced_data_struct_factory.register("computation_table", NFNComputationList) synced_data_struct_factory.register("timeoutprevention_dict", TimeoutPreventionMessageDict) if use_thunks: synced_data_struct_factory.register("thunktable", ThunkList) synced_data_struct_factory.register("plantable", PlanTable) synced_data_struct_factory.create_manager() cs = synced_data_struct_factory.manager.cs() fib = synced_data_struct_factory.manager.fib() pit = synced_data_struct_factory.manager.pit() faceidtable = synced_data_struct_factory.manager.faceidtable() self.parser = DefaultNFNParser() if use_thunks: thunktable = synced_data_struct_factory.manager.thunktable() plantable = synced_data_struct_factory.manager.plantable( self.parser) #setup chunkifier self.chunkifier = SimpleContentChunkifyer() # default interface if interfaces is not None: self.interfaces = interfaces mgmt_port = port else: interfaces = [UDP4Interface(port)] mgmt_port = interfaces[0].get_port() # initialize layers self.linklayer = BasicLinkLayer(interfaces, faceidtable, log_level=log_level) self.packetencodinglayer = BasicPacketEncodingLayer( self.encoder, log_level=log_level) self.icnlayer = BasicICNLayer(log_level=log_level, ageing_interval=ageing_interval) self.chunklayer = BasicChunkLayer(self.chunkifier, log_level=log_level) # setup nfn self.icnlayer._interest_to_app = True if executors is None: self.executors = {"PYTHON": NFNPythonExecutor()} else: self.executors = executors self.r2cclient = TimeoutR2CHandler() comp_table = synced_data_struct_factory.manager.computation_table( self.r2cclient, self.parser) self.nfnlayer = BasicNFNLayer(cs, fib, pit, faceidtable, comp_table, self.executors, self.parser, self.r2cclient, log_level=log_level) if use_thunks: self.thunk_layer = BasicThunkLayer(cs, fib, pit, faceidtable, thunktable, plantable, self.parser, log_level=log_level) self.nfnlayer.optimizer = ThunkPlanExecutor( cs, fib, pit, faceidtable, plantable) timeoutprevention_dict = synced_data_struct_factory.manager.timeoutprevention_dict( ) self.timeoutpreventionlayer = BasicTimeoutPreventionLayer( timeoutprevention_dict, comp_table, pit=pit, log_level=log_level) if use_thunks: self.lstack: LayerStack = LayerStack([ self.nfnlayer, self.chunklayer, self.timeoutpreventionlayer, self.thunk_layer, self.icnlayer, self.packetencodinglayer, self.linklayer ]) else: self.lstack: LayerStack = LayerStack([ self.nfnlayer, self.chunklayer, self.timeoutpreventionlayer, self.icnlayer, self.packetencodinglayer, self.linklayer ]) self.icnlayer.cs = cs self.icnlayer.fib = fib self.icnlayer.pit = pit # mgmt self.mgmt = Mgmt(self.icnlayer.cs, self.icnlayer.fib, self.icnlayer.pit, self.linklayer, mgmt_port, self.stop_forwarder, log_level=log_level)
def test_create_empty(self): with self.assertRaises(ValueError): lstack: LayerStack = LayerStack([])
def test_create_single(self): layer: LayerProcess = LayerProcess() lstack: LayerStack = LayerStack([layer]) self.assertEqual(1, len(lstack.layers)) self.assertEqual(0, len(lstack.queues))
def measure_repo_hopping(run: int, routing_interval: float, hopping_interval: float, lease_time: float, edge_traverse: bool = False): testname = f'repo_hopping{"_edge_traverse" if edge_traverse else ""}' print( f'{testname} routing interval={routing_interval}, hopping interval={hopping_interval}, lease time=' + f'{lease_time}, run {run}') global repo, lock, running manager = multiprocessing.Manager() autoconfig_edgeprefix: List[Tuple[Name, bool]] = [(Name('/edge'), False)] nodes: Dict[int, ICNForwarder] = dict() ports: Dict[int, Tuple[str, int]] = dict() edgeports: List[int] = list() # Initialize core nodes for c in [00, 10, 20, 30]: nodes[c] = ICNForwarder(9000 + c, encoder=NdnTlvEncoder(), routing=True, peers=[]) ports[c] = nodes[c].linklayer.sock.getsockname() # Initialize edge nodes for e in [11, 12, 13, 21, 22, 23, 31, 32, 33]: nodes[e] = ICNForwarder(9000 + e, encoder=NdnTlvEncoder(), routing=True, peers=[], autoconfig=True) ports[e] = nodes[e].linklayer.sock.getsockname() edgeports.append(ports[e][1]) # Assign routing peers after the OS assigned UDP ports. Each node knows the nodes one layer "beneath" itself # in above graph as its routing peers. nodes[00].routinglayer._peers = [ports[10], ports[20], ports[30]] nodes[10].routinglayer._peers = [ports[11], ports[12], ports[13]] nodes[20].routinglayer._peers = [ports[21], ports[22], ports[23]] nodes[30].routinglayer._peers = [ports[31], ports[32], ports[33]] # Set up faces and static FIB of core00 node. fid00to10: int = nodes[00].linklayer.get_or_create_fid(ports[10], static=True) fid00to20: int = nodes[00].linklayer.get_or_create_fid(ports[20], static=True) fid00to30: int = nodes[00].linklayer.get_or_create_fid(ports[30], static=True) fib00: BaseForwardingInformationBase = nodes[00].data_structs['fib'] if edge_traverse: fib00.add_fib_entry(Name('/edge'), fid00to10, static=True) fib00.add_fib_entry(Name('/edge'), fid00to20, static=True) fib00.add_fib_entry(Name('/edge'), fid00to30, static=True) nodes[00].data_structs['fib'] = fib00 nodes[00].data_structs['rib'] = TreeRoutingInformationBase( manager, shortest_only=False) # Set up faces and static FIB of core10 node. fid10to11: int = nodes[10].linklayer.get_or_create_fid(ports[11], static=True) fid10to12: int = nodes[10].linklayer.get_or_create_fid(ports[12], static=True) fid10to13: int = nodes[10].linklayer.get_or_create_fid(ports[13], static=True) fib10: BaseForwardingInformationBase = nodes[10].data_structs['fib'] if edge_traverse: fib10.add_fib_entry(Name('/edge'), fid10to11, static=True) fib10.add_fib_entry(Name('/edge'), fid10to12, static=True) fib10.add_fib_entry(Name('/edge'), fid10to13, static=True) nodes[10].data_structs['fib'] = fib10 nodes[10].data_structs['rib'] = TreeRoutingInformationBase( manager, shortest_only=False) # Set up faces and static FIB of core20 node. fid20to21: int = nodes[20].linklayer.get_or_create_fid(ports[21], static=True) fid20to22: int = nodes[20].linklayer.get_or_create_fid(ports[22], static=True) fid20to23: int = nodes[20].linklayer.get_or_create_fid(ports[23], static=True) fib20: BaseForwardingInformationBase = nodes[20].data_structs['fib'] if edge_traverse: fib20.add_fib_entry(Name('/edge'), fid20to21, static=True) fib20.add_fib_entry(Name('/edge'), fid20to22, static=True) fib20.add_fib_entry(Name('/edge'), fid20to23, static=True) nodes[20].data_structs['fib'] = fib20 nodes[20].data_structs['rib'] = TreeRoutingInformationBase( manager, shortest_only=False) # Set up faces and static FIB of core30 node. fid30to31: int = nodes[30].linklayer.get_or_create_fid(ports[31], static=True) fid30to32: int = nodes[30].linklayer.get_or_create_fid(ports[32], static=True) fid30to33: int = nodes[30].linklayer.get_or_create_fid(ports[33], static=True) fib30: BaseForwardingInformationBase = nodes[30].data_structs['fib'] if edge_traverse: fib30.add_fib_entry(Name('/edge'), fid30to31, static=True) fib30.add_fib_entry(Name('/edge'), fid30to32, static=True) fib30.add_fib_entry(Name('/edge'), fid30to33, static=True) nodes[30].data_structs['fib'] = fib30 nodes[30].data_structs['rib'] = TreeRoutingInformationBase( manager, shortest_only=False) for node in [00, 10, 20, 30]: nodes[node].routinglayer._ageing_interval = routing_interval # Set up network edge autoconfig. for e in [11, 12, 13, 21, 22, 23, 31, 32, 33]: nodes[ e].autoconfiglayer._service_registration_prefixes = autoconfig_edgeprefix nodes[e].routinglayer._ageing_interval = routing_interval nodes[e].autoconfiglayer._service_registration_timeout = timedelta( seconds=lease_time) forwarders = list(nodes.values()) random.shuffle(forwarders) for n in forwarders: n.start_forwarder() sleep(0.05) imr = SimpleMemoryRepository(Name('/edge/hoppingrepo'), manager) n = 600 for i in range(n): imr.add_content(Name(f'/edge/hoppingrepo/{i}'), f'content {i}') def repo_hop(): global repo, edge_index, lock, running if repo is not None: repo.linklayer.sock.close() dumpster.append(repo) with lock: if not running: return repo = ICNDataRepository(None, Name('/hoppingrepo'), 0, encoder=NdnTlvEncoder(), autoconfig=True, autoconfig_routed=True) repo.repolayer._repository = imr edge_index = (edge_index + 1) % len(edgeports) repo.autoconfiglayer._broadcast_port = edgeports[edge_index] repo.start_repo() threading.Timer(hopping_interval, repo_hop).start() repo_hop() class DurationTaggingLayer(LayerProcess): def __init__(self): super().__init__('DurationTaggingLayer') self._names: Dict[Name, datetime] = dict() def data_from_lower(self, to_lower: multiprocessing.Queue, to_higher: multiprocessing.Queue, data): fid, packet = data if packet.name in self._names: to_higher.put([ fid, packet, (datetime.utcnow() - self._names[packet.name]).total_seconds() ]) del self._names[packet.name] else: to_higher.put([fid, packet, None]) def data_from_higher(self, to_lower: multiprocessing.Queue, to_higher: multiprocessing.Queue, data): fid, packet = data self._names[packet.name] = datetime.utcnow() to_lower.put(data) linklayer = UDP4LinkLayer(port=0) fetch_fid = linklayer.create_new_fid(ports[00], True) fetch = LayerStack([ DurationTaggingLayer(), BasicChunkLayer(), BasicPacketEncodingLayer(NdnTlvEncoder()), linklayer ]) end_time = datetime.utcnow() fetch.start_all() for i in range(n): fetch.queue_from_higher.put( [fetch_fid, Interest(Name(f'/edge/hoppingrepo/{i}'))]) end_time += timedelta(milliseconds=100) delay = (end_time - datetime.utcnow()).total_seconds() if delay > 0: sleep(delay) satisfied_interests: Dict[int, bool] = dict() satisfied_interests_outoforder: Dict[int, bool] = dict() maxreceived = -1 avgduration = 0 while not fetch.queue_to_higher.empty(): _, data, duration = fetch.queue_to_higher.get() if isinstance(data, Content) and data.content.startswith('content '): _, i = data.content.split(' ', 1) i = int(i) satisfied_interests_outoforder[i] = True avgduration += duration if i <= maxreceived: continue maxreceived = i satisfied_interests[i] = True success = len(satisfied_interests) success_outoforder = len(satisfied_interests_outoforder) os.makedirs('raw', exist_ok=True) filename = f'raw/{now}_{testname}.csv' with open(filename, 'a') as f: f.write( f'{routing_interval},{hopping_interval},{lease_time},{success / n},{success_outoforder / n},{avgduration / success if success > 0 else 0.0}\n' ) print(f'Wrote data to file {filename}') fetch.stop_all() for f in nodes.values(): f.stop_forwarder() if repo is not None: repo.stop_repo() for r in dumpster: r.stop_repo() with lock: running = False