Beispiel #1
0
    def search_exact(self, _prefix, head=None):
        if self.head is None:
            return None

        prefix = RadixPrefix(_prefix)
        if head is None:
            head = self.head

        node = head
        addr = prefix.addr
        bitlen = prefix.bitlen

        while node.bitlen < bitlen:
            if self._addr_test(addr, node.bitlen):
                node = node.right
            else:
                node = node.left

            if node is None:
                return None

        if node.bitlen > bitlen:
            return None

        if self._prefix_match(node.prefix, prefix, bitlen):
            return node

        return None
Beispiel #2
0
    def search_best(self, _prefix, head=None):
        if self.head is None:
            return None

        prefix = RadixPrefix(_prefix)
        if head is None:
            head = self.head

        node = head
        addr = prefix.addr
        bitlen = prefix.bitlen

        stack = []
        while node.bitlen < bitlen:
            stack.append(node)
            if self._addr_test(addr, node.bitlen):
                node = node.right
            else:
                node = node.left

            if node is None:
                break

        if node is not None:
            stack.append(node)

        if len(stack) <= 0:
            return None

        for node in stack[::-1]:
            if (self._prefix_match(node.prefix, prefix,
                                   node.bitlen)) and node.bitlen <= bitlen:
                return node
        return None
Beispiel #3
0
 def set_attr(self, attr):
     self.prefix = RadixPrefix(attr["prefix"])
     self.bitlen = self.prefix.bitlen
     self.probed = attr["probed"]
     self.respond = attr["respond"]
     self.aggregated = attr["aggregated"]
     self.free = False
Beispiel #4
0
    def _common_prefix(self, node1, node2):
        '''
        Generate common prefix of node1 and node2.

        Args:
            node1 (RadixNode)
            node2 (RadixNode)

        Returns:
            RadixPrefix: common prefix of node1 and node2
        '''
        addr1 = node1.prefix.addr
        addr2 = node2.prefix.addr
        common_addr = bytearray(16)
        prefixmask = [0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe]

        # differ_bit: addr1とaddr2の一致するビット長
        differ_bit = 0
        i = 0
        while i * 8 < 128:
            r = addr1[i] ^ addr2[i]
            if r == 0:
                differ_bit = (i + 1) * 8
                common_addr[i] = addr1[i]
                i += 1
                continue

            for j in range(8):
                if r & (0x80 >> j):
                    common_addr[i] = addr1[i] & prefixmask[j & 7]
                    break
            differ_bit = i * 8 + j
            break

        return RadixPrefix(packed=common_addr, masklen=differ_bit)
Beispiel #5
0
 def __init__(self, prefix="::/0", maxnode=64, repair_path=None):
     super(AggradixTree, self).__init__()
     if repair_path is None:
         head = AggradixNode(node_id=0)
         head.set(RadixPrefix(prefix))
         self.head = head
         self.maxnode = maxnode - 1
         self.free_nodes = self.maxnode
         self.packet_count = 0
         self.nodes = pylru.lrucache(self.maxnode)
         self.active_leaf_cache = self.nodes.head.prev
         self._lru_init()
     else:
         self._repair(repair_path)
Beispiel #6
0
    def add_count(self, src_addr, dst_addr, respond=False):
        if self.free_nodes < 2:
            self.aggregate()

        dst_prefix = RadixPrefix(f'{dst_addr}/128')
        node = self.add(dst_prefix)
        self.nodes[node.node_id] = node

        # プローブを受けた回数を加算
        init_or_add(node.probed, src_addr, 1)

        # 応答を返した回数を加算
        if respond:
            if dst_addr not in node.respond.keys():
                node.respond[dst_addr] = {}
            if src_addr not in node.respond[dst_addr].keys():
                node.respond[dst_addr][src_addr] = 0
            node.respond[dst_addr][src_addr] += 1
Beispiel #7
0
    def search_covered(self, _prefix, head=None):
        if self.head is None:
            return None

        prefix = RadixPrefix(_prefix)
        if head is None:
            head = self.head

        # headのプレフィクス長が検索するプレフィクスのプレフィクス長より長い場合
        # 同じか短くなるまで木を上に探索
        while prefix.bitlen > head.prefix.bitlen:
            if head.parent is None:
                break
            head = head.parent

        results = []
        node = head
        addr = prefix.addr
        bitlen = prefix.bitlen

        while node.bitlen < bitlen:
            if self._addr_test(addr, node.bitlen):
                node = node.right
            else:
                node = node.left

            if node is None:
                return results

        stack = [node]
        while stack:
            node = stack.pop()
            if self._prefix_match(node.prefix, prefix, prefix.bitlen):
                results.append(node)
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)

        return results
Beispiel #8
0
 def search_worst(self, _prefix):
     return super().search_worst(RadixPrefix(_prefix))