Esempio n. 1
0
    def update_assign(self, transaction):
        """
        Updates the state for an Assign transaction

        :param transaction: <dict> An assign transaction
        """
        prefix = transaction['input'][0]
        as_source = transaction['input'][1]
        asn_list = transaction['input'][2]
        ld = transaction['input'][4]
        tt = transaction['input'][5]
        last_assign = transaction['txid']

        found = 0
        for asn in asn_list:
            for i in range(len(state[prefix])):
                if asn in state[prefix][i]:
                    found = 1
                    break
            if found == 0:
                state[prefix].append((asn, ld, tt, last_assign))

        for i in range(len(state[prefix])):
            if as_source == state[prefix][i][0]:
                state[prefix].pop(i)
                break  # the as_source has been removed from the state dict.

        # also reject the previous topo for this prefix and start a new one.
        topo_mutex.acquire()
        topo = AS_topo[prefix]
        self.clear_topology(topo, prefix, as_source)

        for AS in asn_list:
            topo.add_edge(AS, prefix)
        topo_mutex.release()
Esempio n. 2
0
    def verify_origin(self):
        """
        Verifies the origin of this transaction, based on the topo of this prefix.

        :return: <Bool> True if the origin is verified. False otherwise.
        """
        topo_mutex.acquire()
        topo = AS_topo[self.prefix]
        topo_mutex.release()

        if len(self.as_source_list) == 0 or not self.check_network():
            return False

        if self.as_source_list[0] == '0' and len(self.as_source_list) == 1:
            return topo.has_edge(self.as_source, self.prefix)

        elif self.as_source_list[0] == '0' and len(self.as_source_list) > 1:
            direct = topo.has_edge(self.as_source, self.prefix)
            src_l = self.as_source_list[1:]
            src_l.append(self.prefix)
            successors = list(topo.successors(self.as_source))
            src_l.sort()
            successors.sort()
            return direct and src_l == successors

        else:
            src_l = self.as_source_list
            successors = list(topo.successors(self.as_source))
            src_l.sort()
            successors.sort()
            return src_l == successors
Esempio n. 3
0
def return_topos():
    """
    Returns all the topologies of all the prefixes.
    """
    topos = {}
    topo_mutex.acquire()
    for prefix in AS_topo.keys():
        topos[prefix] = list(AS_topo[prefix].edges)
    topo_mutex.release()
    return jsonify(topos), 200
Esempio n. 4
0
    def update_revoke(self, transaction):
        """
        Updates the state for a Revoke transaction

        :param transaction: <dict> A revoke transaction
        """
        as_source = transaction['input'][0]
        assign_tran_id = transaction['input'][1]
        ld = transaction['output'][0][2]
        tt = transaction['output'][0][-1]
        assign_tran = self.find_by_txid(assign_tran_id)

        if assign_tran is not None:
            tran = assign_tran['trans']
            prefix = tran['input'][0]
            as_dest_list = tran['input'][2]
            last_assign = tran['input'][-1]

            for asn in as_dest_list:
                for i in range(len(state[prefix])):
                    if asn == state[prefix][i][0]:
                        state[prefix].pop(i)  # remove the others
                        break  # found it!
            found = 0
            for i in range(len(state[prefix])):
                if as_source in state[prefix][i]:
                    state[prefix].pop(i)
                    state[prefix].append((as_source, ld, tt, last_assign))  # ?
                    found = 1
                    break
            if found == 0:
                state[prefix].append(
                    (as_source, ld, tt,
                     last_assign))  # the one that did the revocation

            # also restore the topology of this prefix.
            topo_mutex.acquire()
            topo = AS_topo[prefix]

            for AS in as_dest_list:
                self.clear_topology(
                    topo, prefix,
                    AS)  # remove the ASes that no longer own the prefix.

            topo.add_edge(
                as_source, prefix
            )  # add the AS that did the revocation and now owns the prefix.
            topo_mutex.release()
Esempio n. 5
0
    def update_bgp_announce(self, transaction):
        """
        Updates the topology of a prefix given in an Announce transaction.

        :param transaction: <dict> A BGP Announce transaction
        """
        prefix = transaction['input'][0]
        sub_paths = transaction['output']
        topo_mutex.acquire()
        topo = AS_topo[prefix]

        for path in sub_paths:
            if path[1] == '0':
                topo.add_edges_from([(path[2], prefix), (path[3], path[2])
                                     ])  # don't add the 0 node in the graph
            else:
                topo.add_edges_from([(path[2], path[1]), (path[3], path[2])])
        topo_mutex.release()
Esempio n. 6
0
    def check_loops(self):
        """
        Checks if this transaction introduces loops in the topology of this prefix.

        :return: <bool> True if there are loops. False otherwise.
        """
        topo_mutex.acquire()
        old_topo = AS_topo[self.prefix]
        new_topo = copy.deepcopy(old_topo)

        self.find_new_topo(new_topo)
        try:
            nx.find_cycle(new_topo, source=self.as_source, orientation='original')
            topo_mutex.release()
            return True
        except nx.NetworkXNoCycle:
            topo_mutex.release()
            return False
Esempio n. 7
0
    def verify_path(self):
        """
        Checks if there is at least one path from the Withdrawing AS to the prefix.

        :return: <Bool> True if there's at least one path, False otherwise.
        """
        topo_mutex.acquire()
        topo = AS_topo[self.prefix]
        # paths from as_source to prefix.
        try:
            paths = nx.all_simple_paths(topo, self.as_source, self.prefix)
            topo_mutex.release()
        except nx.NodeNotFound:
            print("Error: Node not in graph")
            topo_mutex.release()
            return False

        if len(list(paths)) == 0:
            # no paths found.
            return False
        else:
            return True
Esempio n. 8
0
def graph_visualization():
    """
    Creates an image of the graph of the prefix requested.
    """
    values = request.get_json()
    required = ['prefix']
    if not all(k in values for k in required):
        return 'Missing Values', 400

    prefix = values['prefix']
    topo_mutex.acquire()
    try:
        graph = AS_topo[prefix]
        graph.nodes[prefix].update(style='filled', fillcolor='lightblue')
        A = to_agraph(graph)
        A.layout('dot')
        prefix = prefix.replace('/', '+')
        A.draw('graph_for_' + prefix + '.png')
        topo_mutex.release()
    except KeyError:
        topo_mutex.release()
        return 'The prefix does not exists', 400
    return 'Check your folder for a pic of the graph', 200
Esempio n. 9
0
    def update_bgp_withdraw(self, transaction):
        """
        Updates the topology of a prefix after a Withdraw transaction.

        :param transaction: <dict> A BGP Withdraw transaction.
        """
        redundant_nodes = set()
        prefix = transaction['input'][0]
        as_source = transaction['input'][1]
        topo_mutex.acquire()
        topo = AS_topo[prefix]
        # remove the edges between the withdrawing node and its predecessors.
        pred_edges = []
        for pred in topo.predecessors(as_source):
            pred_edges.append((pred, as_source))
        topo.remove_edges_from(pred_edges)
        # find all the other nodes that cannot reach the prefix.
        for node in topo.nodes:
            paths = nx.all_simple_paths(topo, node, prefix)
            if len(list(paths)) == 0 and node != prefix:
                redundant_nodes.add(
                    node)  # these nodes cannot reach the prefix.
        topo.remove_nodes_from(redundant_nodes)
        topo_mutex.release()