Esempio n. 1
0
    def find_client_by_remote_id(self, query: LQQueryOption) -> List[int]:
        """
        Get the row ids of the clients we want to return.

        :param query: The query
        :return: A list of row ids
        """
        # Get the requested remote ID from the query
        remote_id_option = query.get_option_of_type(RemoteIdOption)
        if not remote_id_option:
            raise ReplyWithLeasequeryError(
                STATUS_MALFORMED_QUERY,
                "Remote-ID queries must contain a remote ID")

        remote_id_str = self.encode_remote_id(remote_id_option)

        if query.link_address.is_unspecified:
            cur = self.db.execute(
                "SELECT client_fk FROM relay_ids WHERE relay_id=?",
                (remote_id_str, ))

            return [row['client_fk'] for row in cur]
        else:
            cur = self.db.execute(
                "SELECT id FROM clients "
                "WHERE link_address=? AND id IN (SELECT client_fk FROM relay_ids WHERE relay_id=?)",
                (query.link_address.exploded, remote_id_str))

            return [row['id'] for row in cur]
Esempio n. 2
0
    def find_client_by_address(self, query: LQQueryOption) -> List[int]:
        """
        Get the row ids of the clients we want to return.

        :param query: The query
        :return: A list of row ids
        """
        # Get the requested address from the query
        address_option = query.get_option_of_type(IAAddressOption)
        if not address_option:
            raise ReplyWithLeasequeryError(
                STATUS_MALFORMED_QUERY,
                "Address queries must contain an address")

        address = address_option.address.exploded

        if query.link_address.is_unspecified:
            cur = self.db.execute(
                "SELECT client_fk FROM addresses WHERE address=?"
                " UNION "
                "SELECT client_fk FROM prefixes WHERE ? BETWEEN first_address AND last_address",
                (address, address))
            return [row['client_fk'] for row in cur]
        else:
            cur = self.db.execute(
                "SELECT id FROM clients WHERE link_address=? AND ("
                "id IN (SELECT client_fk FROM addresses WHERE address=?)"
                " OR "
                "id IN (SELECT client_fk FROM prefixes WHERE ? BETWEEN first_address AND last_address)"
                ")", (query.link_address.exploded, address, address))
            return [row['id'] for row in cur]
Esempio n. 3
0
    def find_client_by_client_id(self, query: LQQueryOption) -> List[int]:
        """
        Get the row ids of the clients we want to return.

        :param query: The query
        :return: A list of row ids
        """
        # Get the requested client ID from the query
        client_id_option = query.get_option_of_type(ClientIdOption)
        if not client_id_option:
            raise ReplyWithLeasequeryError(
                STATUS_MALFORMED_QUERY,
                "Client-ID queries must contain a client ID")

        client_id_str = self.encode_duid(client_id_option.duid)

        if query.link_address.is_unspecified:
            cur = self.db.execute("SELECT id FROM clients WHERE client_id=?",
                                  (client_id_str, ))
        else:
            cur = self.db.execute(
                "SELECT id FROM clients WHERE client_id=? AND link_address=?",
                (client_id_str, query.link_address.exploded))

        return [row['id'] for row in cur]
Esempio n. 4
0
    def find_leases(
        self, query: LQQueryOption
    ) -> Tuple[int, Iterable[Tuple[IPv6Address, ClientDataOption]]]:
        """
        Find all leases that match the given query.

        :param query: The query
        :return: The number of leases and an iterator over tuples of link-address and corresponding client data
        """
        # Run everything in one transaction
        with self.db:
            if query.query_type == QUERY_BY_ADDRESS:
                client_row_ids = self.find_client_by_address(query)
            elif query.query_type == QUERY_BY_CLIENT_ID:
                client_row_ids = self.find_client_by_client_id(query)
            elif query.query_type == QUERY_BY_RELAY_ID:
                client_row_ids = self.find_client_by_relay_id(query)
            elif query.query_type == QUERY_BY_LINK_ADDRESS:
                client_row_ids = self.find_client_by_link_address(query)
            elif query.query_type == QUERY_BY_REMOTE_ID:
                client_row_ids = self.find_client_by_remote_id(query)
            else:
                # We can't handle this query
                return -1, []

            if not client_row_ids:
                # None found
                return 0, []

            # Generate records for these client IDs
            oro = query.get_option_of_type(OptionRequestOption)
            requested_options = oro.requested_options if oro else []
            return len(client_row_ids), self.generate_client_data_options(
                client_row_ids, requested_options)