2019-01-11 16:48:30 +01:00
|
|
|
// Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
|
2015-11-30 21:26:25 +01:00
|
|
|
//
|
2015-12-15 21:37:34 +01:00
|
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
2015-11-30 21:26:25 +01:00
|
|
|
|
|
|
|
#ifndef MYSQL_HOST_DATA_SOURCE_H
|
|
|
|
#define MYSQL_HOST_DATA_SOURCE_H
|
|
|
|
|
2018-08-28 11:56:19 +02:00
|
|
|
#include <database/db_exceptions.h>
|
2015-11-30 21:26:25 +01:00
|
|
|
#include <dhcpsrv/base_host_data_source.h>
|
2018-08-29 15:40:02 +02:00
|
|
|
#include <mysql/mysql_connection.h>
|
2015-11-30 21:26:25 +01:00
|
|
|
|
2017-08-18 10:27:29 +03:00
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include <utility>
|
|
|
|
#include <string>
|
|
|
|
|
2015-11-30 21:26:25 +01:00
|
|
|
namespace isc {
|
|
|
|
namespace dhcp {
|
|
|
|
|
2016-03-02 17:59:54 +01:00
|
|
|
/// Forward declaration to the implementation of the @ref MySqlHostDataSource.
|
|
|
|
class MySqlHostDataSourceImpl;
|
2015-11-30 21:26:25 +01:00
|
|
|
|
|
|
|
/// @brief MySQL Host Data Source
|
|
|
|
///
|
2016-03-02 17:59:54 +01:00
|
|
|
/// This class implements the @ref isc::dhcp::BaseHostDataSource interface to
|
|
|
|
/// the MySQL database. Use of this backend presupposes that a MySQL database
|
|
|
|
/// is available and that the Kea schema has been created within it.
|
2015-11-30 21:26:25 +01:00
|
|
|
class MySqlHostDataSource: public BaseHostDataSource {
|
|
|
|
public:
|
|
|
|
|
|
|
|
/// @brief Constructor
|
|
|
|
///
|
|
|
|
/// Uses the following keywords in the parameters passed to it to
|
|
|
|
/// connect to the database:
|
|
|
|
/// - name - Name of the database to which to connect (mandatory)
|
|
|
|
/// - host - Host to which to connect (optional, defaults to "localhost")
|
|
|
|
/// - user - Username under which to connect (optional)
|
|
|
|
/// - password - Password for "user" on the database (optional)
|
|
|
|
///
|
|
|
|
/// If the database is successfully opened, the version number in the
|
|
|
|
/// schema_version table will be checked against hard-coded value in
|
|
|
|
/// the implementation file.
|
|
|
|
///
|
|
|
|
/// Finally, all the SQL commands are pre-compiled.
|
|
|
|
///
|
|
|
|
/// @param parameters A data structure relating keywords and values
|
|
|
|
/// concerned with the database.
|
|
|
|
///
|
|
|
|
/// @throw isc::dhcp::NoDatabaseName Mandatory database name not given
|
2018-08-28 13:09:25 +02:00
|
|
|
/// @throw isc::db::DbOpenError Error opening the database or the
|
2018-05-31 11:51:19 -04:00
|
|
|
/// schema version is invalid.
|
2018-08-28 13:09:25 +02:00
|
|
|
/// @throw isc::db::DbOperationError An operation on the open database has
|
2015-11-30 21:26:25 +01:00
|
|
|
/// failed.
|
2018-08-28 13:09:25 +02:00
|
|
|
MySqlHostDataSource(const db::DatabaseConnection::ParameterMap& parameters);
|
2015-11-30 21:26:25 +01:00
|
|
|
|
2016-03-02 17:59:54 +01:00
|
|
|
/// @brief Virtual destructor.
|
|
|
|
///
|
|
|
|
/// Releases prepared MySQL statements used by the backend.
|
2015-11-30 21:26:25 +01:00
|
|
|
virtual ~MySqlHostDataSource();
|
|
|
|
|
2018-02-13 18:28:40 +02:00
|
|
|
/// @brief Adds a new host to the collection.
|
|
|
|
///
|
|
|
|
/// The implementations of this method should guard against duplicate
|
|
|
|
/// reservations for the same host, where possible. For example, when the
|
|
|
|
/// reservation for the same HW address and subnet id is added twice, the
|
|
|
|
/// addHost method should throw an DuplicateEntry exception. Note, that
|
|
|
|
/// usually it is impossible to guard against adding duplicated host, where
|
|
|
|
/// one instance is identified by HW address, another one by DUID.
|
|
|
|
///
|
|
|
|
/// @param host Pointer to the new @c Host object being added.
|
|
|
|
virtual void add(const HostPtr& host);
|
|
|
|
|
|
|
|
/// @brief Attempts to delete a host by (subnet-id, address)
|
|
|
|
///
|
|
|
|
/// This method supports both v4 and v6.
|
|
|
|
///
|
|
|
|
/// @param subnet_id subnet identifier.
|
|
|
|
/// @param addr specified address.
|
|
|
|
/// @return true if deletion was successful, false if the host was not there.
|
|
|
|
/// @throw various exceptions in case of errors
|
|
|
|
virtual bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr);
|
|
|
|
|
|
|
|
/// @brief Attempts to delete a host by (subnet4-id, identifier type, identifier)
|
|
|
|
///
|
|
|
|
/// This method supports v4 hosts only.
|
|
|
|
///
|
|
|
|
/// @param subnet_id subnet identifier.
|
|
|
|
/// @param identifier_type Identifier type.
|
|
|
|
/// @param identifier_begin Pointer to a beginning of a buffer containing
|
|
|
|
/// an identifier.
|
|
|
|
/// @param identifier_len Identifier length.
|
|
|
|
///
|
|
|
|
/// @return true if deletion was successful, false if the host was not there.
|
|
|
|
/// @throw various exceptions in case of errors
|
|
|
|
virtual bool del4(const SubnetID& subnet_id,
|
|
|
|
const Host::IdentifierType& identifier_type,
|
|
|
|
const uint8_t* identifier_begin, const size_t identifier_len);
|
|
|
|
|
|
|
|
/// @brief Attempts to delete a host by (subnet6-id, identifier type, identifier)
|
|
|
|
///
|
|
|
|
/// This method supports v6 hosts only.
|
|
|
|
///
|
|
|
|
/// @param subnet_id subnet identifier.
|
|
|
|
/// @param identifier_type Identifier type.
|
|
|
|
/// @param identifier_begin Pointer to a beginning of a buffer containing
|
|
|
|
/// an identifier.
|
|
|
|
/// @param identifier_len Identifier length.
|
|
|
|
///
|
|
|
|
/// @return true if deletion was successful, false if the host was not there.
|
|
|
|
/// @throw various exceptions in case of errors
|
|
|
|
virtual bool del6(const SubnetID& subnet_id,
|
|
|
|
const Host::IdentifierType& identifier_type,
|
|
|
|
const uint8_t* identifier_begin, const size_t identifier_len);
|
|
|
|
|
2016-03-10 14:13:07 +01:00
|
|
|
/// @brief Return all hosts connected to any subnet for which reservations
|
|
|
|
/// have been made using a specified identifier.
|
|
|
|
///
|
|
|
|
/// This method returns all @c Host objects which represent reservations
|
|
|
|
/// for a specified identifier. This method may return multiple hosts
|
|
|
|
/// because a particular client may have reservations in multiple subnets.
|
|
|
|
///
|
2016-06-01 17:35:44 +02:00
|
|
|
/// @param identifier_type Identifier type.
|
2016-12-14 16:57:44 +02:00
|
|
|
/// @param identifier_begin Pointer to a beginning of a buffer containing
|
2016-03-10 14:13:07 +01:00
|
|
|
/// an identifier.
|
|
|
|
/// @param identifier_len Identifier length.
|
|
|
|
///
|
|
|
|
/// @return Collection of const @c Host objects.
|
|
|
|
virtual ConstHostCollection
|
|
|
|
getAll(const Host::IdentifierType& identifier_type,
|
|
|
|
const uint8_t* identifier_begin, const size_t identifier_len) const;
|
|
|
|
|
2019-01-11 16:48:30 +01:00
|
|
|
/// @brief Return all hosts in a DHCPv4 subnet.
|
|
|
|
///
|
|
|
|
/// This method returns all @ref Host objects which represent reservations
|
|
|
|
/// in a specified subnet.
|
|
|
|
///
|
|
|
|
/// @param subnet_id subnet identifier to filter by
|
|
|
|
///
|
|
|
|
/// @return Collection of const @ref Host objects.
|
|
|
|
virtual ConstHostCollection
|
2019-01-13 11:40:20 +01:00
|
|
|
getAll4(const SubnetID& subnet_id) const;
|
2019-01-11 16:48:30 +01:00
|
|
|
|
|
|
|
/// @brief Return all hosts in a DHCPv6 subnet.
|
|
|
|
///
|
|
|
|
/// This method returns all @ref Host objects which represent reservations
|
|
|
|
/// in a specified subnet.
|
|
|
|
///
|
|
|
|
/// @param subnet_id subnet identifier to filter by
|
|
|
|
///
|
|
|
|
/// @return Collection of const @ref Host objects.
|
|
|
|
virtual ConstHostCollection
|
2019-01-13 11:40:20 +01:00
|
|
|
getAll6(const SubnetID& subnet_id) const;
|
2019-01-11 16:48:30 +01:00
|
|
|
|
2019-09-29 09:28:13 +02:00
|
|
|
/// @brief Return all hosts with a hostname.
|
|
|
|
///
|
|
|
|
/// This method returns all @c Host objects which represent reservations
|
|
|
|
/// using a specified hostname.
|
|
|
|
///
|
|
|
|
/// @param hostname The lower case hostname.
|
|
|
|
///
|
|
|
|
/// @return Collection of const @c Host objects.
|
|
|
|
virtual ConstHostCollection
|
|
|
|
getAllbyHostname(const std::string& hostname) const;
|
|
|
|
|
|
|
|
/// @brief Return all hosts with a hostname in a DHCPv4 subnet.
|
|
|
|
///
|
|
|
|
/// This method returns all @c Host objects which represent reservations
|
|
|
|
/// using a specified hostname in a specified subnet.
|
|
|
|
///
|
|
|
|
/// @param hostname The lower case hostname.
|
|
|
|
/// @param subnet_id Subnet identifier.
|
|
|
|
///
|
|
|
|
/// @return Collection of const @c Host objects.
|
|
|
|
virtual ConstHostCollection
|
|
|
|
getAllbyHostname4(const std::string& hostname, const SubnetID& subnet_id) const;
|
|
|
|
|
|
|
|
/// @brief Return all hosts with a hostname in a DHCPv6 subnet.
|
|
|
|
///
|
|
|
|
/// This method returns all @c Host objects which represent reservations
|
|
|
|
/// using a specified hostname in a specified subnet.
|
|
|
|
///
|
|
|
|
/// @param hostname The lower case hostname.
|
|
|
|
/// @param subnet_id Subnet identifier.
|
|
|
|
///
|
|
|
|
/// @return Collection of const @c Host objects.
|
|
|
|
virtual ConstHostCollection
|
|
|
|
getAllbyHostname6(const std::string& hostname, const SubnetID& subnet_id) const;
|
|
|
|
|
2019-01-13 17:11:57 +01:00
|
|
|
/// @brief Returns range of hosts in a DHCPv4 subnet.
|
|
|
|
///
|
|
|
|
/// This method returns a page of @c Host objects which represent
|
|
|
|
/// reservations in a specified subnet.
|
|
|
|
///
|
|
|
|
/// @param subnet_id Subnet identifier.
|
|
|
|
/// @param source_index Index of the source (unused).
|
|
|
|
/// @param lower_host_id Host identifier used as lower bound for the
|
|
|
|
/// returned range.
|
|
|
|
/// @param page_size maximum size of the page returned.
|
|
|
|
///
|
|
|
|
/// @return Collection of const @c Host objects (may be empty).
|
|
|
|
virtual ConstHostCollection
|
|
|
|
getPage4(const SubnetID& subnet_id,
|
|
|
|
size_t& source_index,
|
|
|
|
uint64_t lower_host_id,
|
|
|
|
const HostPageSize& page_size) const;
|
|
|
|
|
|
|
|
/// @brief Returns range of hosts in a DHCPv6 subnet.
|
|
|
|
///
|
|
|
|
/// This method returns a page of @c Host objects which represent
|
|
|
|
/// reservations in a specified subnet.
|
|
|
|
///
|
|
|
|
/// @param subnet_id Subnet identifier.
|
|
|
|
/// @param source_index Index of the source (unused).
|
|
|
|
/// @param lower_host_id Host identifier used as lower bound for the
|
|
|
|
/// returned range.
|
|
|
|
/// @param page_size maximum size of the page returned.
|
|
|
|
///
|
|
|
|
/// @return Collection of const @c Host objects (may be empty).
|
|
|
|
virtual ConstHostCollection
|
|
|
|
getPage6(const SubnetID& subnet_id,
|
|
|
|
size_t& source_index,
|
|
|
|
uint64_t lower_host_id,
|
|
|
|
const HostPageSize& page_size) const;
|
|
|
|
|
2015-11-30 21:26:25 +01:00
|
|
|
/// @brief Returns a collection of hosts using the specified IPv4 address.
|
|
|
|
///
|
|
|
|
/// This method may return multiple @c Host objects if they are connected
|
|
|
|
/// to different subnets.
|
|
|
|
///
|
|
|
|
/// @param address IPv4 address for which the @c Host object is searched.
|
|
|
|
///
|
|
|
|
/// @return Collection of const @c Host objects.
|
|
|
|
virtual ConstHostCollection
|
|
|
|
getAll4(const asiolink::IOAddress& address) const;
|
|
|
|
|
2016-03-10 14:13:07 +01:00
|
|
|
/// @brief Returns a host connected to the IPv4 subnet.
|
|
|
|
///
|
|
|
|
/// @param subnet_id Subnet identifier.
|
|
|
|
/// @param identifier_type Identifier type.
|
2016-12-14 16:57:44 +02:00
|
|
|
/// @param identifier_begin Pointer to a beginning of a buffer containing
|
2016-03-10 14:13:07 +01:00
|
|
|
/// an identifier.
|
|
|
|
/// @param identifier_len Identifier length.
|
|
|
|
///
|
|
|
|
/// @return Const @c Host object for which reservation has been made using
|
|
|
|
/// the specified identifier.
|
|
|
|
virtual ConstHostPtr
|
|
|
|
get4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
|
|
|
|
const uint8_t* identifier_begin, const size_t identifier_len) const;
|
|
|
|
|
2015-11-30 21:26:25 +01:00
|
|
|
/// @brief Returns a host connected to the IPv4 subnet and having
|
|
|
|
/// a reservation for a specified IPv4 address.
|
|
|
|
///
|
|
|
|
/// One of the use cases for this method is to detect collisions between
|
|
|
|
/// dynamically allocated addresses and reserved addresses. When the new
|
|
|
|
/// address is assigned to a client, the allocation mechanism should check
|
|
|
|
/// if this address is not reserved for some other host and do not allocate
|
|
|
|
/// this address if reservation is present.
|
|
|
|
///
|
|
|
|
/// Implementations of this method should guard against invalid addresses,
|
|
|
|
/// such as IPv6 address.
|
|
|
|
///
|
|
|
|
/// @param subnet_id Subnet identifier.
|
|
|
|
/// @param address reserved IPv4 address.
|
|
|
|
///
|
|
|
|
/// @return Const @c Host object using a specified IPv4 address.
|
|
|
|
virtual ConstHostPtr
|
|
|
|
get4(const SubnetID& subnet_id, const asiolink::IOAddress& address) const;
|
|
|
|
|
2016-03-10 14:13:07 +01:00
|
|
|
/// @brief Returns a host connected to the IPv6 subnet.
|
|
|
|
///
|
|
|
|
/// @param subnet_id Subnet identifier.
|
|
|
|
/// @param identifier_type Identifier type.
|
2016-12-14 16:57:44 +02:00
|
|
|
/// @param identifier_begin Pointer to a beginning of a buffer containing
|
2016-03-10 14:13:07 +01:00
|
|
|
/// an identifier.
|
|
|
|
/// @param identifier_len Identifier length.
|
|
|
|
///
|
|
|
|
/// @return Const @c Host object for which reservation has been made using
|
|
|
|
/// the specified identifier.
|
|
|
|
virtual ConstHostPtr
|
|
|
|
get6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
|
|
|
|
const uint8_t* identifier_begin, const size_t identifier_len) const;
|
|
|
|
|
2015-11-30 21:26:25 +01:00
|
|
|
/// @brief Returns a host using the specified IPv6 prefix.
|
|
|
|
///
|
|
|
|
/// @param prefix IPv6 prefix for which the @c Host object is searched.
|
|
|
|
/// @param prefix_len IPv6 prefix length.
|
|
|
|
///
|
2018-05-24 16:51:07 +02:00
|
|
|
/// @return Const @c Host object using a specified IPv6 prefix.
|
2015-11-30 21:26:25 +01:00
|
|
|
virtual ConstHostPtr
|
|
|
|
get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len) const;
|
|
|
|
|
2016-09-20 09:29:06 +02:00
|
|
|
/// @brief Returns a host connected to the IPv6 subnet and having
|
|
|
|
/// a reservation for a specified IPv6 address or prefix.
|
|
|
|
///
|
|
|
|
/// @param subnet_id Subnet identifier.
|
|
|
|
/// @param address reserved IPv6 address/prefix.
|
|
|
|
///
|
|
|
|
/// @return Const @c Host object using a specified IPv6 address/prefix.
|
|
|
|
virtual ConstHostPtr
|
|
|
|
get6(const SubnetID& subnet_id, const asiolink::IOAddress& address) const;
|
|
|
|
|
2015-11-30 21:26:25 +01:00
|
|
|
/// @brief Return backend type
|
|
|
|
///
|
|
|
|
/// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
|
|
|
|
///
|
|
|
|
/// @return Type of the backend.
|
|
|
|
virtual std::string getType() const {
|
|
|
|
return (std::string("mysql"));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// @brief Returns backend name.
|
|
|
|
///
|
2016-03-02 17:59:54 +01:00
|
|
|
/// Each backend have specific name.
|
2015-11-30 21:26:25 +01:00
|
|
|
///
|
2016-03-02 17:59:54 +01:00
|
|
|
/// @return "mysql".
|
2015-11-30 21:26:25 +01:00
|
|
|
virtual std::string getName() const;
|
|
|
|
|
|
|
|
/// @brief Returns description of the backend.
|
|
|
|
///
|
|
|
|
/// This description may be multiline text that describes the backend.
|
|
|
|
///
|
|
|
|
/// @return Description of the backend.
|
|
|
|
virtual std::string getDescription() const;
|
|
|
|
|
|
|
|
/// @brief Returns backend version.
|
|
|
|
///
|
|
|
|
/// @return Version number stored in the database, as a pair of unsigned
|
|
|
|
/// integers. "first" is the major version number, "second" the
|
|
|
|
/// minor number.
|
|
|
|
///
|
2018-08-28 13:09:25 +02:00
|
|
|
/// @throw isc::db::DbOperationError An operation on the open database
|
2015-11-30 21:26:25 +01:00
|
|
|
/// has failed.
|
|
|
|
virtual std::pair<uint32_t, uint32_t> getVersion() const;
|
|
|
|
|
|
|
|
/// @brief Commit Transactions
|
|
|
|
///
|
2016-03-02 17:59:54 +01:00
|
|
|
/// Commits all pending database operations.
|
2015-11-30 21:26:25 +01:00
|
|
|
virtual void commit();
|
|
|
|
|
|
|
|
/// @brief Rollback Transactions
|
|
|
|
///
|
2016-03-02 17:59:54 +01:00
|
|
|
/// Rolls back all pending database operations.
|
2015-11-30 21:26:25 +01:00
|
|
|
virtual void rollback();
|
|
|
|
|
|
|
|
private:
|
2016-03-02 17:59:54 +01:00
|
|
|
/// @brief Pointer to the implementation of the @ref MySqlHostDataSource.
|
2016-07-28 21:08:43 +02:00
|
|
|
MySqlHostDataSourceImpl* impl_;
|
2015-11-30 21:26:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // MYSQL_HOST_DATA_SOURCE_H
|