def get_neighbors(self): """ : return: Nested dictionary with intra and inter isd neighbor dictionaries """ intra_dict = {} inter_dict = {} border_routers = self.topology["BorderRouters"] for br in border_routers: if_id = self.get_neighbor_IA_interface(br)['interface'] n_IA = ISD_AS(self.get_neighbor_IA_interface(br)['IA']) n_isd = n_IA.isd_str() n_as = n_IA.as_file_fmt() if n_isd == self.ISD: intra_isd_neighbor = \ {'n_as': n_as, 'br-ip': border_routers[br]["Interfaces"][if_id]["PublicOverlay"]["Addr"], 'br-port': border_routers[br]["Interfaces"][if_id]["PublicOverlay"]["OverlayPort"], 'remote-ip': border_routers[br]["Interfaces"][if_id]["RemoteOverlay"]["Addr"], 'remote-port': border_routers[br]["Interfaces"][if_id]["RemoteOverlay"]["OverlayPort"]} intra_dict[if_id] = intra_isd_neighbor else: inter_isd_neighbor = \ {'n_isd': n_isd, 'n_as': n_as, 'br-ip': border_routers[br]["Interfaces"][if_id]["PublicOverlay"]["Addr"], 'br-port': border_routers[br]["Interfaces"][if_id]["PublicOverlay"]["OverlayPort"], 'remote-ip': border_routers[br]["Interfaces"][if_id]["RemoteOverlay"]["Addr"], 'remote-port': border_routers[br]["Interfaces"][if_id]["PublicOverlay"]["OverlayPort"]} inter_dict[if_id] = inter_isd_neighbor return {'intra': intra_dict, 'inter': inter_dict}
def fill_router_info(self, router_dict): """ Update the router information in the database. (i.e., BorderRouter and BorderRouterAddress.) :param dict router_dict: topo_dict['BorderRouters'] """ for name, router in router_dict.items(): br_obj, _ = BorderRouter.objects.update_or_create(name=name, ad=self) router_addr = router['InternalAddrs']['IPv4'] addr_info = router_addr['PublicOverlay'] internal_public_obj, _ = BorderRouterAddress.objects.update_or_create( addr=addr_info['Addr'], l4port=addr_info['OverlayPort'], addr_type='IPv4', is_public=True, router=br_obj, ad=self ) addr_info = router_addr.get('BindOverlay', None) if addr_info: internal_bound_obj, _ = BorderRouterAddress.objects.update_or_create( addr=addr_info['Addr'], l4port=addr_info['OverlayPort'], addr_type='IPv4', is_public=False, router=br_obj, ad=self ) else: internal_bound_obj = None # TODO: we need to update the model: BorderRouterAddress should have also CtrlAddr, both should # have public + bind address. BorderRouterInterface should not have an index # But I don't find where we read this data for anything ! for if_id, intf in router["Interfaces"].items(): isd_as = ISD_AS(intf["ISD_AS"]) br_addr_obj = internal_public_obj br_inft_obj, _ = BorderRouterInterface.objects.update_or_create( addr=intf['PublicOverlay']['Addr'], l4port=intf['PublicOverlay']['OverlayPort'], remote_addr=intf['RemoteOverlay']['Addr'], remote_l4port=intf['RemoteOverlay']['OverlayPort'], internal_addr_idx=0, interface_id=if_id, bandwidth=intf['Bandwidth'], mtu=intf['MTU'], neighbor_isd_id=isd_as[0], neighbor_as_id=isd_as[1], neighbor_as_id_str=isd_as.as_str(), neighbor_type=intf["LinkTo"], router_addr=br_addr_obj, ad=self, bind_addr=intf['BindOverlay']['Addr'] if 'BindOverlay' in intf.keys() else None, bind_l4port=intf['BindOverlay']['OverlayPort'] if 'BindOverlay' in intf.keys() else None, )
def draw_node_without_attributes(self, AS, core, graph, location_labels, labels): """ Adds a node without any attributes to the graph. : param: self, string AS: AS ID, boolean core: inidicates if the AS is core graphviz graph: graph to which we add the AS dict labels: Dictionary containing labels for ISDs and ASes """ ia = ISD_AS("%s-%s" % (self.ISD, AS)) node_id = ia.file_fmt() node_name = ia.__str__() if core: node_name += " (core)" if location_labels and ia.__str__() in labels['AS']: node_name += '\n' + labels['AS'][ia.__str__()] graph.node(node_id, node_name, _attributes={'shape': 'box'})
def __init__(self, AS, AS_number, ISD): # ex: info_dict[br] = ip address of br # ex: reverse_info_dict[1.3.3.3] = ['zk', 'bs'] self.info_dict = {} self.rev_info_dict = {} self.AS = AS self.AS_n = AS_number self.ISD = ISD self.IA = ISD_AS.from_values(self.ISD, self.AS_n) self.gather_non_br_info() self.gather_intra_br_info() self.gather_inter_br_info() self.info_string = self.assemble_string
def _mk_if_info(self, if_id): """ Small helper method to make it easier to deal with ingress/egress interface being 0 while building ASMarkings. """ d = {"remote_ia": ISD_AS.from_values(0, 0), "remote_if": 0, "mtu": 0} if not if_id: return d br = self.ifid2br[if_id] d["remote_ia"] = br.interfaces[if_id].isd_as d["remote_if"] = br.interfaces[if_id].to_if_id d["mtu"] = br.interfaces[if_id].mtu return d
def test_one_timestep(self): # Check that the revocation proof is verifiable across T and T+1. # Setup isd_as = ISD_AS("1-11") if_ids = [23, 35, 120] initial_seed = b"qwerty" inst = ConnectedHashTree(isd_as, if_ids, initial_seed) root = inst.get_root() # Call next_tree = inst.get_next_tree(isd_as, if_ids, b"new!!seed") inst.update(next_tree) # Tests proof = inst.get_proof(35) # if_id = 35. ntools.eq_(ConnectedHashTree.verify(proof, root), True)
def _generate_toplevel_prom_config(local_gen_path): """ Generates the top level prometheus config file. :param str local_gen_path: The gen path of scion-web. """ job_dict = defaultdict(list) all_ases = AD.objects.all() for as_obj in all_ases: ia = ISD_AS.from_values(as_obj.isd_id, as_obj.as_id) for ele_type, target_file in PrometheusGenerator.TARGET_FILES.items(): targets_path = os.path.join( get_elem_dir(local_gen_path, ia, ""), PrometheusGenerator.PROM_DIR, target_file) job_dict[PrometheusGenerator.JOB_NAMES[ele_type]].append(targets_path) _write_prometheus_config_file(local_gen_path, job_dict)
def _send_trc_request(self, isd, ver, as_): isd_as = ISD_AS.from_values(isd, as_) trc_req = TRCRequest.from_values(isd_as, ver, cache_only=True) path_meta = self._get_path_via_api(isd_as) if path_meta: meta = self._build_meta(isd_as, host=SVCType.CS_A, path=path_meta.fwd_path()) self.send_meta(trc_req, meta) logging.info("TRC request sent to %s via [%s]: %s", meta, path_meta.short_desc(), trc_req.short_desc()) else: logging.warning("TRC request not sent for %s: no path found.", trc_req.short_desc())
def __init__(self, if_id, interface_dict, name=None): """ :pacam int if_id: interface id :param dict interface_dict: contains information about the interface. """ self.if_id = int(if_id) self.isd_as = ISD_AS(interface_dict['ISD_AS']) self.link_type = interface_dict['LinkTo'].lower() self.bandwidth = interface_dict['Bandwidth'] self.mtu = interface_dict['MTU'] self.overlay = interface_dict.get('Overlay') self.to_if_id = 0 # Filled in later by IFID packets self.remote = self._parse_addrs(interface_dict.get('RemoteOverlay')) super().__init__(self._new_addrs(interface_dict), name)
def _get_my_asid(): """ Load ISDAS information running on the local machine :returns: a list of ISD_AS objects """ isdas_list = [] for directory in os.listdir(GEN_PATH): if 'ISD' in directory: for folder in os.listdir(os.path.join(GEN_PATH, directory)): if 'AS' in folder: isdas = ISD_AS.from_values(int(directory[3:]), int(folder[2:])) isdas_list.append(isdas) return isdas_list
def draw_edges_from_current(self, current_neighbors, graph, node_labels): """ Adds edges for all ASes in current_neighbors :param: self, array of ASes: list of ASes whose edges we draw, graphviz graph: graph to which we add the edges, boolean edge_labels: boolean indicating if we add labels to the edges """ next_neighbors = [] for AS in current_neighbors: self.ASes_done.append(AS) ia = ISD_AS.from_values(self.ISD, AS) id = ia.__str__() for interface in self.AS_list[AS]["intra_n"]: neighbor = self.AS_list[AS]["intra_n"][interface]["n_as"] # check if neighbor exists (referenced in interface but AS folder does not exist) if neighbor not in self.AS_list: continue # check if interface connects to an AS we already handled if neighbor not in self.ASes_done: n_ia = ISD_AS.from_values(self.ISD, neighbor) n_id = n_ia.__str__() if node_labels: color = self.get_color() remote = self.get_remote_interface(neighbor, self.AS_list[AS]["intra_n"][interface]["br-ip"], \ self.AS_list[AS]["intra_n"][interface]["br-port"]) headlabel = '<<font color="' + color + '">' + str(remote[0]) + ": " + str(remote[1]) + '</font>>' taillabel = '<<font color="' + color + '">' + str(interface) + ": " + \ str(self.AS_list[AS]["intra_n"][interface]["br-port"]) + '</font>>' graph.edge(id, n_id, color=color, _attributes={'headlabel': headlabel, 'taillabel': taillabel}) else: graph.edge(id, n_id) if neighbor not in current_neighbors: if neighbor not in next_neighbors: next_neighbors.append(neighbor) return next_neighbors
def addr_c2py(caddr): """ Helper function to convert C_SCIONAddr to SCIONAddr :param caddr: C_SCIONAddr to convert :type caddr: C_SCIONAddr :returns: Converted object :rtype: SCIONAddr """ isd_as = ISD_AS(caddr.isd_as.to_bytes(4, 'big')) if caddr.host.addr_type == 0: return None htype = haddr_get_type(caddr.host.addr_type) haddr = haddr_parse(caddr.host.addr_type, bytes(caddr.host.addr)[:htype.LEN]) return SCIONAddr.from_values(isd_as, haddr)
def add_to_topology(request): """ Adds the router information which comes with a connection reply into the topology of the AS. :param HttpRequest request: Django HTTP request. """ con_reply = json.loads(request.body.decode('utf-8')) # find the corresponding connection request from DB try: con_req = ConnectionRequest.objects.get(id=con_reply['RequestId']) except ConnectionRequest.DoesNotExist: logger.error("Connection request for reply with ID %s not found", con_reply['RequestId']) return HttpResponseNotFound( "Connection request for reply %s not found" % con_reply['RequestId']) # find the corresponding router ip = con_req.router_public_ip port = con_req.router_public_port try: router_intf = BorderRouterInterface.objects.get(addr=ip, l4port=port) router_addr = router_intf.router_addr router = router_addr.router except BorderRouterAddress.DoesNotExist: logger.error("Router for connection reply with ID %s not found.", con_reply['RequestId']) return HttpResponseNotFound("Router for connection reply with ID %s " "not found." % con_reply['RequestId']) isd_id, as_id = ISD_AS(con_reply['RequestIA']) try: req_ia = AD.objects.get(isd_id=isd_id, as_id=as_id) except AD.DoesNotExist: logger.error("AS %s was not found." % con_reply['RequestIA']) return HttpResponseNotFound("AS %s was not found" % con_reply['RequestIA']) topo = req_ia.original_topology interface = topo['BorderRouters'][router.name]['Interfaces'][str( router_intf.interface_id)] interface['Remote']['Addr'] = con_reply['IP'] if "UDP" in con_reply['OverlayType']: interface['Remote']['L4Port'] = con_reply['Port'] # TODO(ercanucan): verify the other parameters of the request as well? req_ia.save() # write the updated topology file create_local_gen(con_reply['RequestIA'], topo) # save the data into DB req_ia.fill_from_topology(topo, clear=True) return HttpResponse("Successfully added to topology of %s" % router.name)
def __init__(self, if_id, interface_dict, name=None): """ :pacam int if_id: interface id :param dict interface_dict: contains information about the interface. """ self.if_id = int(if_id) self.addr_idx = interface_dict['InternalAddrIdx'] self.isd_as = ISD_AS(interface_dict['ISD_AS']) self.link_type = interface_dict['LinkType'] self.bandwidth = interface_dict['Bandwidth'] self.mtu = interface_dict['MTU'] self.overlay = interface_dict['Overlay'] self.to_if_id = 0 # Filled in later by IFID packets self.remote = self._parse_addrs(interface_dict['Remote']) super().__init__(interface_dict['Public'], interface_dict.get('Bind'), name)
def _generate_toplevel_prom_config(local_gen_path): """ Generates the top level prometheus config file. :param str local_gen_path: The gen path of scion-web. """ job_dict = defaultdict(list) all_ases = AD.objects.all() for as_obj in all_ases: ia = ISD_AS.from_values(as_obj.isd_id, as_obj.as_id) for ele_type, target_file in PrometheusGenerator.TARGET_FILES.items(): targets_path = os.path.join(get_elem_dir(local_gen_path, ia, ""), PrometheusGenerator.PROM_DIR, target_file) job_dict[PrometheusGenerator.JOB_NAMES[ele_type]].append( targets_path) _write_prometheus_config_file(local_gen_path, job_dict)
def draw_node_without_attributes(self, AS, core, graph, location_labels, labels): """ Adds a node without any attributes to the graph. :param: self, string AS: AS ID, boolean core: inidicates if the AS is core graphviz graph: graph to which we add the AS dict labels: Dictionary containing labels for ISDs and ASes """ ia = ISD_AS.from_values(self.ISD, AS) node_id = ia.__str__() node_name = self.AS_list[AS]["name"] node_name = ia.__str__() + node_name if core: node_name += " (core)" if location_labels and ia.__str__() in labels['AS']: node_name += '\n' + labels['AS'][ia.__str__()] graph.node(node_id, node_name, _attributes={'shape': 'box'})
def test(self): # Setup isd_as = ISD_AS("1-11") if_ids = [23, 35, 120] initial_seed = b"qwerty" inst = ConnectedHashTree(isd_as, if_ids, initial_seed) root1_before_update = inst._ht1._nodes[0] root2_before_update = inst._ht2._nodes[0] # Call new_tree = inst.get_next_tree(isd_as, if_ids, b"new!!seed") inst.update(new_tree) # Tests root0_after_update = inst._ht0_root root1_after_update = inst._ht1._nodes[0] ntools.eq_(root1_before_update, root0_after_update) ntools.eq_(root2_before_update, root1_after_update)
def draw_node_with_attributes(self, AS, core, graph): """ Adds a node with attributes to the graph. :param: self, string AS: AS ID, boolean core: inidicates if the AS is core graphviz graph: graph to which we add the AS """ ia = ISD_AS.from_values(self.ISD, AS) node_id = ia.__str__() node_name = self.AS_list[AS]["name"] node_name = ia.__str__() + node_name if core: node_name = node_name + " (core)" node_name = node_name + "\n" node_attributes = self.NodeAttributes(self.AS_list[AS], AS, self.ISD) node_name = node_name + node_attributes.assemble_string() graph.node(node_id, node_name, _attributes={'shape': 'box'})
def get_neighbor_IA_interface(self, br): """ : param: br: Border router string : return: A dictionary with the neighbor IA and interface of the border router connected to that IA """ interface = "" neighbor_IA = "" # extract neighbor IA for this border router brs = self.topology["BorderRouters"] for item in brs[br]["Interfaces"]: neighbor_IA = ISD_AS( brs[br]["Interfaces"][item]["ISD_AS"]).file_fmt() interface = item break return {'IA': neighbor_IA, 'interface': interface}
def _parse(self, raw: bytes) -> None: try: decoded = raw.decode("utf-8") except UnicodeDecodeError as e: raise SCIONParseError(e) from None groups = self.FMT_RE.findall(decoded) if not groups: raise SCIONParseError("Input does not match pattern. Decoded: %s" % decoded) from None try: self.ia = ISD_AS(groups[0][0]) except SCIONParseError as e: raise SCIONParseError("Unable to parse IA. Decoded: %s error: %s" % (decoded, e)) from None self.chain_ver = int(groups[0][1]) self.trc_ver = int(groups[0][2])
def handle_join_reply(reply, web_req, jr_id): logger.info("resp = %s", reply.json()) join_reply = reply.json() new_as = ISD_AS(join_reply['assigned_isdas']) # TODO(ercanucan): create the ISD in DB if it's not yet in DB AD.objects.update_or_create(as_id=int(new_as[1]), isd=ISD.objects.get(id=int(new_as[0])), is_core_ad=False, is_open=False, certificate=join_reply['certificate'], trc=join_reply['trc']) messages.success(web_req, 'Created new AS with ID %s.' % new_as) # change join request status to APPROVED JoinRequest.objects.filter(request_id=jr_id).update(status=REQ_APPROVED)
def _remove_child_interfaces(topo): """ Remove all Interfaces to CHILD user-ASes and the corresponding Border Routers from the topology config :param topo: The topology dict from which Interfaces and BRs will be removed """ brs = topo['BorderRouters'] for brname in list(brs.keys()): # list() because we del() br = brs[brname] for ifnum in list(br['Interfaces'].keys()): iface = br['Interfaces'][ifnum] ia = ISD_AS(iface['ISD_AS']) if not asid_is_infrastructure( ia[1]) and iface['LinkTo'] == 'CHILD': del br['Interfaces'][ifnum] if not br['Interfaces']: # no interfaces left -> remove BR del brs[brname]
def _parse(self, raw): """ Parse payload to extract hop informations. """ hops_no = raw[0] data = Raw(raw, self.NAME, self.MIN_LEN + hops_no * self.HOP_LEN, min_=True) super()._parse(data) # Drop hops no and padding from the first row. data.pop(self.MIN_LEN) for _ in range(hops_no): isd_as = ISD_AS(data.pop(ISD_AS.LEN)) # 4 bytes if_id, timestamp = struct.unpack( "!HH", data.pop(self.HOP_LEN - ISD_AS.LEN)) self.append_hop(isd_as, if_id, timestamp)
def _get_path_via_api(self): """ Test local API. """ data = self._try_sciond_api() path_len = data.pop(1) * 8 self.path = SCIONPath(data.pop(path_len)) haddr_type = haddr_get_type(data.pop(1)) data.pop(haddr_type.LEN) # first hop, unused here data.pop(2) # port number, unused here self.path.mtu = struct.unpack("!H", data.pop(2))[0] ifcount = data.pop(1) self.iflist = [] for i in range(ifcount): isd_as = ISD_AS(data.pop(ISD_AS.LEN)) ifid = struct.unpack("!H", data.pop(2))[0] self.iflist.append((isd_as, ifid))
def __init__(self, interface_dict, name=None): """ :param dict interface_dict: contains information about the interface. """ super().__init__(interface_dict['Addr'], name) self.if_id = interface_dict['IFID'] self.isd_as = ISD_AS(interface_dict['ISD_AS']) self.link_type = interface_dict['LinkType'] self.to_udp_port = interface_dict['ToUdpPort'] self.udp_port = interface_dict['UdpPort'] self.bandwidth = interface_dict['Bandwidth'] self.mtu = interface_dict['MTU'] to_addr = interface_dict['ToAddr'] self.to_addr = None if to_addr: self.to_addr = haddr_parse_interface(to_addr) self.to_if_id = 0 # Filled in later by IFID packets
def test_two_timesteps(self): # Check that the revocation proof is "NOT" verifiable across T and T+2. # Setup isd_as = ISD_AS("1-11") if_ids = [23, 35, 120] initial_seed = b"qwerty" inst = ConnectedHashTree(isd_as, if_ids, initial_seed, HashType.SHA256) root = inst.get_root() # Call new_tree = inst.get_next_tree(isd_as, if_ids, b"newseed.@1", HashType.SHA256) inst.update(new_tree) new_tree = inst.get_next_tree(isd_as, if_ids, b"newseed.@2", HashType.SHA256) inst.update(new_tree) # Tests proof = inst.get_proof(35) # if_id = 35. ntools.eq_(ConnectedHashTree.verify(proof, root), False)
def __init__(self, connection, address, conn_id, scion_mode, kbase, source_isd_as, target_isd_as): """ Create a ConnectionHandler class to handle the incoming HTTP(S) request. :param connection: Socket object that belong to the incoming connection :type connection: socket :param address: Address of the connecting party. :type address: host, port """ self.scion_mode = scion_mode self.socket_kbase = kbase isd_as = ISD_AS(target_isd_as) host = HostAddrIPv4(self.target_proxy[0]) self.scion_target_proxy = SCIONAddr.from_values(isd_as, host) self.scion_target_port = self.target_proxy[1] self.isd_as = source_isd_as super().__init__(connection, address, conn_id)
def p_segment(s, seg, idx, name, color, rev): ''' Add segment to html list ''' list_add_head(s, idx, name, color) indent_open(s) list_add(s, "Creation: %s" % iso_timestamp(seg.p.timestamp)) list_add(s, "Expiration: %s" % iso_timestamp(seg.p.expTime)) list_add(s, "Hops: %i" % (len(seg.p.interfaces) / 2)) # enumerate path interfaces if rev: interfaces = reversed(seg.p.interfaces) else: interfaces = seg.p.interfaces for interface in interfaces: isd_as = ISD_AS(interface.isdas) link = interface.ifID list_add(s, "%s (%s)" % (str(isd_as), link)) indent_close(s)
def _check_trc_reqs(self): """ Checks if TRC requests timeout and resends requests if so. """ with self.req_trcs_lock: now = time.time() for (isd, ver), (req_time, meta) in self.requested_trcs.items(): if now - req_time >= self.TRC_CC_REQ_TIMEOUT: trc_req = TRCRequest.from_values(ISD_AS.from_values( isd, 0), ver, cache_only=True) logging.info("Re-Requesting TRC from %s: %s", meta, trc_req.short_desc()) self.send_meta(trc_req, meta) self.requested_trcs[(isd, ver)] = (time.time(), meta) if self._labels: PENDING_TRC_REQS_TOTAL.labels(**self._labels).set( len(self.requested_trcs))
def _update_credentials(path, max_as_number): """ Main routine to update with relevant ISD with new credentials. :param path: Location of the ISD folder, containing new credentials. :type path: string :param isd_id: ISD the AS belongs to. :type isd_id: string """ for (dirpath, dirnames, filenames) in os.walk(path): for dirname in dirnames: if dirname.startswith('AS'): token = dirpath.split('/') isd_id = token[len(token) - 1][3:] as_id = re.search('AS(.*)', dirname).group(1) if int(as_id[-2:].replace("_", ""), 16) > max_as_number: continue isd_as = ISD_AS("%s-%s" % (isd_id, as_id)) cred_obj = _load_credentials(os.path.join(dirpath, dirname), isd_as) _create_update_as(cred_obj, isd_as)
def _get_new_br_obj(new_neighbor, topo): """ Initiating border router objects to create new border router entity :param ISD_AS my_asid: current AS number :param bool is_vpn: is this a vpn-based setup :param dict tp: current AS topology :returns: new border router id, border router port, interface id, internal address, interface address, mtu and bandwidth """ br_id = [] if_id = [] br_n = "" br_port = [] for br_name, br in topo['BorderRouters'].items(): br_id.append(int(br_name.split('-')[2])) br_n = br_name.split('-')[0] + "-" + br_name.split('-')[1] br_port.append(br['InternalAddrs'][0]['Public'][0]['L4Port']) for ifid, intf in br['Interfaces'].items(): if_id.append(int(ifid)) new_br_id = '%s-%s' % (br_n, new_neighbor["BRID"]) new_if_id = new_neighbor["BRID"] external_port = new_neighbor["RemotePort"] neighbor_addr = new_neighbor["NeighborIP"] ext_addr = get_credentials()["IP"] if new_neighbor["Linktype"] == CHILD: linktype = "CHILD" elif new_neighbor["Linktype"] == PARENT: linktype = "PARENT" else: linktype = "CORE" internal_port = new_neighbor["LocalPort"] int_addr = ni.ifaddresses(INTERFACE)[ni.AF_INET][0]['addr'] ia = ISD_AS.from_values(new_neighbor["NeighborISD"], new_neighbor["NeighborAS"]) ia = ia.__str__() new_br_port = _get_lowest_empty_id(br_port) return new_br_id, new_br_port, new_if_id, external_port, neighbor_addr, ext_addr, linktype, internal_port, int_addr, ia
def test(self, hash_func_for_type, _): # Setup isd_as = ISD_AS("1-11") if_ids = [1, 2, 3] hashes = [ b"s10", b"10s10", b"s20", b"20s20", b"s30", b"30s30", b"0", b"30s300", b"10s1020s20", b"10s1020s2030s300" ] hash_func = create_mock_full(side_effect=hashes) hash_func_for_type.return_value = hash_func inst = HashTree(isd_as, if_ids, b"s", 1, HashType.SHA256) inst._depth = 2 # Call inst.create_tree(if_ids) # Tests expected = [ b"10s1020s2030s300", b"10s1020s20", b"30s300", b"10s10", b"20s20", b"30s30", b"0" ] ntools.eq_(inst._nodes, expected)
def parse_dict(self, path_policy): """ Parses the policies from the dictionary. :param dict path_policy: path policy. """ self.best_set_size = path_policy['BestSetSize'] self.candidates_set_size = path_policy['CandidatesSetSize'] self.history_limit = path_policy['HistoryLimit'] self.update_after_number = path_policy['UpdateAfterNumber'] self.update_after_time = path_policy['UpdateAfterTime'] unwanted_ases = path_policy['UnwantedASes'].split(',') for unwanted in unwanted_ases: self.unwanted_ases.append(ISD_AS(unwanted)) property_ranges = path_policy['PropertyRanges'] for key in property_ranges: property_range = property_ranges[key].split('-') property_range = int(property_range[0]), int(property_range[1]) self.property_ranges[key] = property_range self.property_weights = path_policy['PropertyWeights']
def _remove_child_interfaces(topo): """ Remove all Interfaces to CHILD user-ASes and the corresponding Border Routers from the topology config :param topo: The topology dict from which Interfaces and BRs will be removed """ brs = topo['BorderRouters'] for brname in list(brs.keys()): # list() because we del() br = brs[brname] # count references to internal addrs: internalAddrIdxCounter = collections.Counter( iface['InternalAddrIdx'] for iface in br['Interfaces'].values()) for ifnum in list(br['Interfaces'].keys()): iface = br['Interfaces'][ifnum] ia = ISD_AS(iface['ISD_AS']) internalAddrIdx = iface['InternalAddrIdx'] # if the link is to a child and that child is a user AS if not asid_is_infrastructure( ia[1]) and iface['LinkTo'] == 'CHILD': internalAddrIdxCounter[internalAddrIdx] -= 1 del br['Interfaces'][ifnum] if not br['Interfaces']: # no interfaces left -> remove BR del brs[brname] else: # remove unreferenced internal addrs: idxsToRemove = (idx for idx, count in internalAddrIdxCounter.items() if count is 0) for i in sorted(idxsToRemove, reverse=True): del br['InternalAddrs'][i] # patch remaining internal adddress indexes: idxRemap = {} idxOffset = 0 for idx, count in internalAddrIdxCounter.items(): if count == 0: idxOffset += 1 else: idxRemap[idx] = idx - idxOffset for iface in br['Interfaces'].values(): iface['InternalAddrIdx'] = idxRemap[iface['InternalAddrIdx']]