26#include <boost/algorithm/string/split.hpp>
27#include <boost/algorithm/string/classification.hpp>
28#include <boost/array.hpp>
29#include <boost/foreach.hpp>
30#include <boost/pointer_cast.hpp>
31#include <boost/static_assert.hpp>
34#include <mysqld_error.h>
84class MySqlHostExchange {
91 static const size_t HOST_ID_COL = 0;
92 static const size_t DHCP_IDENTIFIER_COL = 1;
93 static const size_t DHCP_IDENTIFIER_TYPE_COL = 2;
94 static const size_t DHCP4_SUBNET_ID_COL = 3;
95 static const size_t DHCP6_SUBNET_ID_COL = 4;
96 static const size_t IPV4_ADDRESS_COL = 5;
97 static const size_t HOSTNAME_COL = 6;
98 static const size_t DHCP4_CLIENT_CLASSES_COL = 7;
99 static const size_t DHCP6_CLIENT_CLASSES_COL = 8;
100 static const size_t USER_CONTEXT_COL = 9;
101 static const size_t DHCP4_NEXT_SERVER_COL = 10;
102 static const size_t DHCP4_SERVER_HOSTNAME_COL = 11;
103 static const size_t DHCP4_BOOT_FILE_NAME_COL = 12;
104 static const size_t AUTH_KEY_COL = 13;
107 static const size_t HOST_COLUMNS = 14;
117 MySqlHostExchange(
const size_t additional_columns_num = 0)
118 : columns_num_(HOST_COLUMNS + additional_columns_num),
119 bind_(columns_num_), columns_(columns_num_),
120 error_(columns_num_,
MLM_FALSE), host_id_(0),
121 dhcp_identifier_length_(0), dhcp_identifier_type_(0),
122 dhcp4_subnet_id_(SUBNET_ID_UNUSED),
123 dhcp6_subnet_id_(SUBNET_ID_UNUSED), ipv4_address_(0),
124 hostname_length_(0), dhcp4_client_classes_length_(0),
125 dhcp6_client_classes_length_(0),
126 user_context_length_(0),
127 dhcp4_next_server_(0),
128 dhcp4_server_hostname_length_(0),
129 dhcp4_boot_file_name_length_(0),
143 memset(dhcp_identifier_buffer_, 0,
sizeof(dhcp_identifier_buffer_));
144 memset(hostname_, 0,
sizeof(hostname_));
145 memset(dhcp4_client_classes_, 0,
sizeof(dhcp4_client_classes_));
146 memset(dhcp6_client_classes_, 0,
sizeof(dhcp6_client_classes_));
147 memset(user_context_, 0,
sizeof(user_context_));
148 memset(dhcp4_server_hostname_, 0,
sizeof(dhcp4_server_hostname_));
149 memset(dhcp4_boot_file_name_, 0,
sizeof(dhcp4_boot_file_name_));
150 memset(auth_key_, 0,
sizeof(auth_key_));
155 columns_[HOST_ID_COL] =
"host_id";
156 columns_[DHCP_IDENTIFIER_COL] =
"dhcp_identifier";
157 columns_[DHCP_IDENTIFIER_TYPE_COL] =
"dhcp_identifier_type";
158 columns_[DHCP4_SUBNET_ID_COL] =
"dhcp4_subnet_id";
159 columns_[DHCP6_SUBNET_ID_COL] =
"dhcp6_subnet_id";
160 columns_[IPV4_ADDRESS_COL] =
"ipv4_address";
161 columns_[HOSTNAME_COL] =
"hostname";
162 columns_[DHCP4_CLIENT_CLASSES_COL] =
"dhcp4_client_classes";
163 columns_[DHCP6_CLIENT_CLASSES_COL] =
"dhcp6_client_classes";
164 columns_[USER_CONTEXT_COL] =
"user_context";
165 columns_[DHCP4_NEXT_SERVER_COL] =
"dhcp4_next_server";
166 columns_[DHCP4_SERVER_HOSTNAME_COL] =
"dhcp4_server_hostname";
167 columns_[DHCP4_BOOT_FILE_NAME_COL] =
"dhcp4_boot_file_name";
168 columns_[AUTH_KEY_COL] =
"auth_key";
170 BOOST_STATIC_ASSERT(13 < HOST_COLUMNS);
174 virtual ~MySqlHostExchange() {
191 size_t findAvailColumn()
const {
192 std::vector<std::string>::const_iterator empty_column =
193 std::find(columns_.begin(), columns_.end(), std::string());
194 return (std::distance(columns_.begin(), empty_column));
200 uint64_t getHostId()
const {
214 static void setErrorIndicators(std::vector<MYSQL_BIND>& bind,
215 std::vector<my_bools>&
error) {
216 for (
size_t i = 0; i <
error.size(); ++i) {
235 static std::string getColumnsInError(std::vector<my_bools>&
error,
236 const std::vector<std::string>& names) {
237 std::string result =
"";
240 for (
size_t i = 0; i < names.size(); ++i) {
242 if (!result.empty()) {
249 if (result.empty()) {
268 std::vector<MYSQL_BIND> createBindForSend(
const HostPtr& host,
const bool unique_ip) {
276 memset(&bind_[0], 0,
sizeof(MYSQL_BIND) * bind_.size());
285 bind_[0].buffer_type = MYSQL_TYPE_LONG;
286 bind_[0].buffer =
reinterpret_cast<char*
>(&host_id_);
290 dhcp_identifier_length_ = host->getIdentifier().size();
291 memcpy(
static_cast<void*
>(dhcp_identifier_buffer_),
292 &(host->getIdentifier())[0],
293 host->getIdentifier().size());
295 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
296 bind_[1].buffer = dhcp_identifier_buffer_;
297 bind_[1].buffer_length = dhcp_identifier_length_;
298 bind_[1].length = &dhcp_identifier_length_;
301 dhcp_identifier_type_ =
static_cast<uint8_t
>(host->getIdentifierType());
302 bind_[2].buffer_type = MYSQL_TYPE_TINY;
303 bind_[2].buffer =
reinterpret_cast<char*
>(&dhcp_identifier_type_);
309 dhcp4_subnet_id_ = host->getIPv4SubnetID();
310 dhcp4_subnet_id_null_ = host->getIPv4SubnetID() == SUBNET_ID_UNUSED ?
MLM_TRUE :
MLM_FALSE;
311 bind_[3].buffer_type = MYSQL_TYPE_LONG;
312 bind_[3].buffer =
reinterpret_cast<char*
>(&dhcp4_subnet_id_);
314 bind_[3].is_null = &dhcp4_subnet_id_null_;
319 dhcp6_subnet_id_ = host->getIPv6SubnetID();
320 dhcp6_subnet_id_null_ = host->getIPv6SubnetID() == SUBNET_ID_UNUSED ?
MLM_TRUE :
MLM_FALSE;
321 bind_[4].buffer_type = MYSQL_TYPE_LONG;
322 bind_[4].buffer =
reinterpret_cast<char*
>(&dhcp6_subnet_id_);
324 bind_[4].is_null = &dhcp6_subnet_id_null_;
329 ipv4_address_ = host->getIPv4Reservation().toUint32();
331 bind_[5].buffer_type = MYSQL_TYPE_LONG;
332 bind_[5].buffer =
reinterpret_cast<char*
>(&ipv4_address_);
334 bind_[5].is_null = &ipv4_address_null_;
338 hostname_length_ = host->getHostname().length();
339 bind_[6].buffer_type = MYSQL_TYPE_STRING;
340 bind_[6].buffer =
reinterpret_cast<char*
>(hostname_);
341 bind_[6].buffer_length = hostname_length_;
344 bind_[7].buffer_type = MYSQL_TYPE_STRING;
346 string classes4_txt = host->getClientClasses4().toText(
",");
348 bind_[7].buffer = dhcp4_client_classes_;
349 bind_[7].buffer_length = classes4_txt.length();
352 bind_[8].buffer_type = MYSQL_TYPE_STRING;
354 string classes6_txt = host->getClientClasses6().toText(
",");
356 bind_[8].buffer = dhcp6_client_classes_;
357 bind_[8].buffer_length = classes6_txt.length();
362 bind_[9].buffer_type = MYSQL_TYPE_STRING;
363 string ctx_txt = ctx->str();
365 bind_[9].buffer = user_context_;
366 bind_[9].buffer_length = ctx_txt.length();
368 bind_[9].buffer_type = MYSQL_TYPE_NULL;
374 dhcp4_next_server_ = host->getNextServer().toUint32();
375 bind_[10].buffer_type = MYSQL_TYPE_LONG;
376 bind_[10].buffer =
reinterpret_cast<char*
>(&dhcp4_next_server_);
382 bind_[11].buffer_type = MYSQL_TYPE_STRING;
383 std::string server_hostname = host->getServerHostname();
384 strncpy(dhcp4_server_hostname_, server_hostname.c_str(),
386 bind_[11].buffer = dhcp4_server_hostname_;
387 bind_[11].buffer_length = server_hostname.length();
390 bind_[12].buffer_type = MYSQL_TYPE_STRING;
391 std::string boot_file_name = host->getBootFileName();
392 strncpy(dhcp4_boot_file_name_, boot_file_name.c_str(),
394 bind_[12].buffer = dhcp4_boot_file_name_;
395 bind_[12].buffer_length = boot_file_name.length();
398 bind_[13].buffer_type = MYSQL_TYPE_STRING;
399 std::string auth_key = host->getKey().toText();
402 bind_[13].buffer = auth_key_;
403 bind_[13].buffer_length = auth_key.length();
405 }
catch (
const std::exception& ex) {
407 "Could not create bind array from Host: "
408 << host->getHostname() <<
", reason: " << ex.
what());
412 std::vector<MYSQL_BIND> vec(bind_.begin(), bind_.begin() + HOST_COLUMNS);
418 vec.push_back(bind_[5]);
419 vec.push_back(bind_[3]);
431 virtual std::vector<MYSQL_BIND> createBindForReceive() {
438 memset(&bind_[0], 0,
sizeof(MYSQL_BIND) * bind_.size());
441 bind_[0].buffer_type = MYSQL_TYPE_LONG;
442 bind_[0].buffer =
reinterpret_cast<char*
>(&host_id_);
446 dhcp_identifier_length_ =
sizeof(dhcp_identifier_buffer_);
447 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
448 bind_[1].buffer =
reinterpret_cast<char*
>(dhcp_identifier_buffer_);
449 bind_[1].buffer_length = dhcp_identifier_length_;
450 bind_[1].length = &dhcp_identifier_length_;
453 bind_[2].buffer_type = MYSQL_TYPE_TINY;
454 bind_[2].buffer =
reinterpret_cast<char*
>(&dhcp_identifier_type_);
459 bind_[3].buffer_type = MYSQL_TYPE_LONG;
460 bind_[3].buffer =
reinterpret_cast<char*
>(&dhcp4_subnet_id_);
462 bind_[3].is_null = &dhcp4_subnet_id_null_;
466 bind_[4].buffer_type = MYSQL_TYPE_LONG;
467 bind_[4].buffer =
reinterpret_cast<char*
>(&dhcp6_subnet_id_);
469 bind_[4].is_null = &dhcp6_subnet_id_null_;
473 bind_[5].buffer_type = MYSQL_TYPE_LONG;
474 bind_[5].buffer =
reinterpret_cast<char*
>(&ipv4_address_);
476 bind_[5].is_null = &ipv4_address_null_;
480 hostname_length_ =
sizeof(hostname_);
481 bind_[6].buffer_type = MYSQL_TYPE_STRING;
482 bind_[6].buffer =
reinterpret_cast<char*
>(hostname_);
483 bind_[6].buffer_length = hostname_length_;
484 bind_[6].length = &hostname_length_;
485 bind_[6].is_null = &hostname_null_;
489 dhcp4_client_classes_length_ =
sizeof(dhcp4_client_classes_);
490 bind_[7].buffer_type = MYSQL_TYPE_STRING;
491 bind_[7].buffer =
reinterpret_cast<char*
>(dhcp4_client_classes_);
492 bind_[7].buffer_length = dhcp4_client_classes_length_;
493 bind_[7].length = &dhcp4_client_classes_length_;
494 bind_[7].is_null = &dhcp4_client_classes_null_;
498 dhcp6_client_classes_length_ =
sizeof(dhcp6_client_classes_);
499 bind_[8].buffer_type = MYSQL_TYPE_STRING;
500 bind_[8].buffer =
reinterpret_cast<char*
>(dhcp6_client_classes_);
501 bind_[8].buffer_length = dhcp6_client_classes_length_;
502 bind_[8].length = &dhcp6_client_classes_length_;
503 bind_[8].is_null = &dhcp6_client_classes_null_;
507 user_context_length_ =
sizeof(user_context_);
508 bind_[9].buffer_type = MYSQL_TYPE_STRING;
509 bind_[9].buffer =
reinterpret_cast<char*
>(user_context_);
510 bind_[9].buffer_length = user_context_length_;
511 bind_[9].length = &user_context_length_;
512 bind_[9].is_null = &user_context_null_;
516 bind_[10].buffer_type = MYSQL_TYPE_LONG;
517 bind_[10].buffer =
reinterpret_cast<char*
>(&dhcp4_next_server_);
519 bind_[10].is_null = &dhcp4_next_server_null_;
523 dhcp4_server_hostname_length_ =
sizeof(dhcp4_server_hostname_);
524 bind_[11].buffer_type = MYSQL_TYPE_STRING;
525 bind_[11].buffer =
reinterpret_cast<char*
>(dhcp4_server_hostname_);
526 bind_[11].buffer_length = dhcp4_server_hostname_length_;
527 bind_[11].length = &dhcp4_server_hostname_length_;
528 bind_[11].is_null = &dhcp4_server_hostname_null_;
532 dhcp4_boot_file_name_length_ =
sizeof(dhcp4_boot_file_name_);
533 bind_[12].buffer_type = MYSQL_TYPE_STRING;
534 bind_[12].buffer =
reinterpret_cast<char*
>(dhcp4_boot_file_name_);
535 bind_[12].buffer_length = dhcp4_boot_file_name_length_;
536 bind_[12].length = &dhcp4_boot_file_name_length_;
537 bind_[12].is_null = &dhcp4_boot_file_name_null_;
541 auth_key_length_ =
sizeof(auth_key_);
542 bind_[13].buffer_type = MYSQL_TYPE_STRING;
543 bind_[13].buffer =
reinterpret_cast<char*
>(auth_key_);
544 bind_[13].buffer_length = auth_key_length_;
545 bind_[13].length = &auth_key_length_;
546 bind_[13].is_null = &auth_key_null_;
549 setErrorIndicators(bind_, error_);
566 if (dhcp_identifier_type_ > MAX_IDENTIFIER_TYPE) {
568 <<
static_cast<int>(dhcp_identifier_type_));
577 SubnetID ipv4_subnet_id(SUBNET_ID_UNUSED);
578 if (dhcp4_subnet_id_null_ ==
MLM_FALSE) {
579 ipv4_subnet_id =
static_cast<SubnetID>(dhcp4_subnet_id_);
584 SubnetID ipv6_subnet_id(SUBNET_ID_UNUSED);
585 if (dhcp6_subnet_id_null_ ==
MLM_FALSE) {
586 ipv6_subnet_id =
static_cast<SubnetID>(dhcp6_subnet_id_);
598 std::string hostname;
600 hostname = std::string(hostname_, hostname_length_);
604 std::string dhcp4_client_classes;
605 if (dhcp4_client_classes_null_ ==
MLM_FALSE) {
606 dhcp4_client_classes = std::string(dhcp4_client_classes_,
607 dhcp4_client_classes_length_);
611 std::string dhcp6_client_classes;
612 if (dhcp6_client_classes_null_ ==
MLM_FALSE) {
613 dhcp6_client_classes = std::string(dhcp6_client_classes_,
614 dhcp6_client_classes_length_);
618 std::string user_context;
620 user_context_[user_context_length_] =
'\0';
621 user_context.assign(user_context_);
626 if (dhcp4_next_server_null_ ==
MLM_FALSE) {
631 std::string dhcp4_server_hostname;
632 if (dhcp4_server_hostname_null_ ==
MLM_FALSE) {
633 dhcp4_server_hostname = std::string(dhcp4_server_hostname_,
634 dhcp4_server_hostname_length_);
638 std::string dhcp4_boot_file_name;
639 if (dhcp4_boot_file_name_null_ ==
MLM_FALSE) {
640 dhcp4_boot_file_name = std::string(dhcp4_boot_file_name_,
641 dhcp4_boot_file_name_length_);
645 std::string auth_key;
647 auth_key = std::string(auth_key_, auth_key_length_);
651 HostPtr h(
new Host(dhcp_identifier_buffer_, dhcp_identifier_length_,
652 type, ipv4_subnet_id, ipv6_subnet_id, ipv4_reservation,
653 hostname, dhcp4_client_classes, dhcp6_client_classes,
654 next_server, dhcp4_server_hostname,
655 dhcp4_boot_file_name,
AuthKey(auth_key)));
656 h->setHostId(host_id_);
659 if (!user_context.empty()) {
664 <<
"' is not a JSON map");
669 <<
"' is invalid JSON: " << ex.
what());
694 if (hosts.empty() || (hosts.back()->getHostId() != getHostId())) {
697 host = retrieveHost();
698 hosts.push_back(host);
712 std::string getErrorColumns() {
713 return (getColumnsInError(error_, columns_));
722 std::vector<MYSQL_BIND> bind_;
725 std::vector<std::string> columns_;
728 std::vector<my_bools> error_;
744 unsigned long dhcp_identifier_length_;
748 uint8_t dhcp_identifier_type_;
751 uint32_t dhcp4_subnet_id_;
754 uint32_t dhcp6_subnet_id_;
757 uint32_t ipv4_address_;
763 unsigned long hostname_length_;
770 unsigned long dhcp4_client_classes_length_;
777 unsigned long dhcp6_client_classes_length_;
783 unsigned long user_context_length_;
786 uint32_t dhcp4_next_server_;
792 unsigned long dhcp4_server_hostname_length_;
798 unsigned long dhcp4_boot_file_name_length_;
804 unsigned long auth_key_length_;
823 my_bool dhcp4_client_classes_null_;
827 my_bool dhcp6_client_classes_null_;
833 my_bool dhcp4_next_server_null_;
836 my_bool dhcp4_server_hostname_null_;
839 my_bool dhcp4_boot_file_name_null_;
856class MySqlHostWithOptionsExchange :
public MySqlHostExchange {
860 static const size_t OPTION_COLUMNS = 8;
876 class OptionProcessor {
886 const size_t start_column)
887 : universe_(universe), start_column_(start_column), option_id_(0),
888 code_(0), value_length_(0), formatted_value_length_(0),
889 space_length_(0), persistent_(false), cancelled_(false),
890 user_context_length_(0),
894 option_id_index_(start_column), code_index_(start_column_ + 1),
895 value_index_(start_column_ + 2),
896 formatted_value_index_(start_column_ + 3),
897 space_index_(start_column_ + 4),
898 persistent_index_(start_column_ + 5),
899 cancelled_index_(start_column_ + 6),
900 user_context_index_(start_column_ + 7),
901 most_recent_option_id_(0) {
903 memset(value_, 0,
sizeof(value_));
904 memset(formatted_value_, 0,
sizeof(formatted_value_));
905 memset(space_, 0,
sizeof(space_));
906 memset(user_context_, 0,
sizeof(user_context_));
910 uint64_t getOptionId()
const {
935 if ((option_id_null_ ==
MLM_TRUE) ||
936 (most_recent_option_id_ >= option_id_)) {
942 most_recent_option_id_ = option_id_;
949 space_[space_length_] =
'\0';
950 space.assign(space_);
960 std::string formatted_value;
961 if (formatted_value_null_ ==
MLM_FALSE) {
962 formatted_value_[formatted_value_length_] =
'\0';
963 formatted_value.assign(formatted_value_);
967 std::string user_context;
969 user_context_[user_context_length_] =
'\0';
970 user_context.assign(user_context_);
1014 option.reset(
new Option(universe_, code_, buf.begin(),
1017 option.reset(
new Option(universe_, code_));
1024 if (formatted_value.empty()) {
1028 option = def->optionFactory(universe_, code_, buf.begin(),
1034 std::vector<std::string> split_vec;
1035 boost::split(split_vec, formatted_value, boost::is_any_of(
","));
1036 option = def->optionFactory(universe_, code_, split_vec);
1044 if (!user_context.empty()) {
1049 <<
"' is no a JSON map");
1051 desc.setContext(ctx);
1054 <<
"' is invalid JSON: " << ex.
what());
1057 cfg->add(desc, space);
1064 void setColumnNames(std::vector<std::string>& columns) {
1065 columns[option_id_index_] =
"option_id";
1066 columns[code_index_] =
"code";
1067 columns[value_index_] =
"value";
1068 columns[formatted_value_index_] =
"formatted_value";
1069 columns[space_index_] =
"space";
1070 columns[persistent_index_] =
"persistent";
1071 columns[cancelled_index_] =
"cancelled";
1072 columns[user_context_index_] =
"user_context";
1081 void setBindFields(std::vector<MYSQL_BIND>& bind) {
1085 most_recent_option_id_ = 0;
1089 persistent_ =
false;
1098 memset(value_, 0,
sizeof(value_));
1099 memset(formatted_value_, 0,
sizeof(formatted_value_));
1100 memset(space_, 0,
sizeof(space_));
1101 memset(user_context_, 0,
sizeof(user_context_));
1104 bind[option_id_index_].buffer_type = MYSQL_TYPE_LONG;
1105 bind[option_id_index_].buffer =
reinterpret_cast<char*
>(&option_id_);
1106 bind[option_id_index_].is_unsigned =
MLM_TRUE;
1107 bind[option_id_index_].is_null = &option_id_null_;
1110 bind[code_index_].buffer_type = MYSQL_TYPE_SHORT;
1111 bind[code_index_].buffer =
reinterpret_cast<char*
>(&
code_);
1112 bind[code_index_].is_unsigned =
MLM_TRUE;
1113 bind[code_index_].is_null = &code_null_;
1116 value_length_ =
sizeof(value_);
1117 bind[value_index_].buffer_type = MYSQL_TYPE_BLOB;
1118 bind[value_index_].buffer =
reinterpret_cast<char*
>(value_);
1119 bind[value_index_].buffer_length = value_length_;
1120 bind[value_index_].length = &value_length_;
1121 bind[value_index_].is_null = &value_null_;
1124 formatted_value_length_ =
sizeof(formatted_value_);
1125 bind[formatted_value_index_].buffer_type = MYSQL_TYPE_STRING;
1126 bind[formatted_value_index_].buffer =
reinterpret_cast<char*
>(formatted_value_);
1127 bind[formatted_value_index_].buffer_length = formatted_value_length_;
1128 bind[formatted_value_index_].length = &formatted_value_length_;
1129 bind[formatted_value_index_].is_null = &formatted_value_null_;
1132 space_length_ =
sizeof(space_);
1133 bind[space_index_].buffer_type = MYSQL_TYPE_STRING;
1134 bind[space_index_].buffer =
reinterpret_cast<char*
>(space_);
1135 bind[space_index_].buffer_length = space_length_;
1136 bind[space_index_].length = &space_length_;
1137 bind[space_index_].is_null = &space_null_;
1140 bind[persistent_index_].buffer_type = MYSQL_TYPE_TINY;
1141 bind[persistent_index_].buffer =
reinterpret_cast<char*
>(&persistent_);
1142 bind[persistent_index_].is_unsigned =
MLM_TRUE;
1145 bind[cancelled_index_].buffer_type = MYSQL_TYPE_TINY;
1146 bind[cancelled_index_].buffer =
reinterpret_cast<char*
>(&cancelled_);
1147 bind[cancelled_index_].is_unsigned =
MLM_TRUE;
1150 user_context_length_ =
sizeof(user_context_);
1151 bind[user_context_index_].buffer_type = MYSQL_TYPE_STRING;
1152 bind[user_context_index_].buffer =
reinterpret_cast<char*
>(user_context_);
1153 bind[user_context_index_].buffer_length = user_context_length_;
1154 bind[user_context_index_].length = &user_context_length_;
1155 bind[user_context_index_].is_null = &user_context_null_;
1164 size_t start_column_;
1167 uint32_t option_id_;
1176 unsigned long value_length_;
1182 unsigned long formatted_value_length_;
1188 unsigned long space_length_;
1201 unsigned long user_context_length_;
1217 my_bool formatted_value_null_;
1229 size_t option_id_index_;
1235 size_t value_index_;
1238 size_t formatted_value_index_;
1241 size_t space_index_;
1244 size_t persistent_index_;
1247 size_t cancelled_index_;
1251 size_t user_context_index_;
1254 uint32_t most_recent_option_id_;
1258 typedef boost::shared_ptr<OptionProcessor> OptionProcessorPtr;
1268 enum FetchedOptions {
1282 MySqlHostWithOptionsExchange(
const FetchedOptions& fetched_options,
1283 const size_t additional_columns_num = 0)
1284 : MySqlHostExchange(getRequiredColumnsNum(fetched_options)
1285 + additional_columns_num),
1286 opt_proc4_(), opt_proc6_() {
1289 if ((fetched_options == DHCP4_ONLY) ||
1290 (fetched_options == DHCP4_AND_DHCP6)) {
1291 opt_proc4_.reset(
new OptionProcessor(
Option::V4,
1292 findAvailColumn()));
1293 opt_proc4_->setColumnNames(columns_);
1297 if ((fetched_options == DHCP6_ONLY) ||
1298 (fetched_options == DHCP4_AND_DHCP6)) {
1299 opt_proc6_.reset(
new OptionProcessor(
Option::V6,
1300 findAvailColumn()));
1301 opt_proc6_->setColumnNames(columns_);
1316 if (!hosts.empty()) {
1325 most_recent_host = boost::const_pointer_cast<Host>(hosts.back());
1331 if (!most_recent_host || (most_recent_host->getHostId() < getHostId())) {
1332 HostPtr host = retrieveHost();
1333 hosts.push_back(host);
1334 most_recent_host = host;
1340 opt_proc4_->retrieveOption(cfg);
1346 opt_proc6_->retrieveOption(cfg);
1353 virtual std::vector<MYSQL_BIND> createBindForReceive() {
1355 static_cast<void>(MySqlHostExchange::createBindForReceive());
1359 opt_proc4_->setBindFields(bind_);
1364 opt_proc6_->setBindFields(bind_);
1368 setErrorIndicators(bind_, error_);
1386 static size_t getRequiredColumnsNum(
const FetchedOptions& fetched_options) {
1387 return (fetched_options == DHCP4_AND_DHCP6 ? 2 * OPTION_COLUMNS :
1394 OptionProcessorPtr opt_proc4_;
1399 OptionProcessorPtr opt_proc6_;
1414class MySqlHostIPv6Exchange :
public MySqlHostWithOptionsExchange {
1418 static const size_t RESERVATION_COLUMNS = 5;
1426 MySqlHostIPv6Exchange(
const FetchedOptions& fetched_options)
1427 : MySqlHostWithOptionsExchange(fetched_options, RESERVATION_COLUMNS),
1429 reserv_type_(0), reserv_type_null_(
MLM_FALSE),
1430 ipv6_address_buffer_len_(0), prefix_len_(0), iaid_(0),
1431 reservation_id_index_(findAvailColumn()),
1432 address_index_(reservation_id_index_ + 1),
1433 prefix_len_index_(reservation_id_index_ + 2),
1434 type_index_(reservation_id_index_ + 3),
1435 iaid_index_(reservation_id_index_ + 4),
1436 most_recent_reservation_id_(0) {
1438 memset(ipv6_address_buffer_, 0,
sizeof(ipv6_address_buffer_));
1441 columns_[reservation_id_index_] =
"reservation_id";
1442 columns_[address_index_] =
"address";
1443 columns_[prefix_len_index_] =
"prefix_len";
1444 columns_[type_index_] =
"type";
1445 columns_[iaid_index_] =
"dhcp6_iaid";
1451 uint32_t getReservationId()
const {
1453 return (reservation_id_);
1468 switch (reserv_type_) {
1479 "invalid IPv6 reservation type returned: "
1480 <<
static_cast<int>(reserv_type_)
1481 <<
". Only 0 or 2 are allowed.");
1511 MySqlHostWithOptionsExchange::processFetchedData(hosts);
1513 if (getReservationId() == 0) {
1517 if (hosts.empty()) {
1519 " IPv6 reservation");
1521 HostPtr host = boost::const_pointer_cast<Host>(hosts.back());
1525 if (getReservationId() > most_recent_reservation_id_) {
1526 most_recent_reservation_id_ = getReservationId();
1528 if (most_recent_reservation_id_ > 0) {
1529 host->addReservation(retrieveReservation());
1542 virtual std::vector<MYSQL_BIND> createBindForReceive() {
1545 most_recent_reservation_id_ = 0;
1548 static_cast<void>(MySqlHostWithOptionsExchange::createBindForReceive());
1551 bind_[reservation_id_index_].buffer_type = MYSQL_TYPE_LONG;
1552 bind_[reservation_id_index_].buffer =
reinterpret_cast<char*
>(&reservation_id_);
1553 bind_[reservation_id_index_].is_unsigned =
MLM_TRUE;
1556 ipv6_address_buffer_len_ = isc::asiolink::V6ADDRESS_LEN;
1557 bind_[address_index_].buffer_type = MYSQL_TYPE_BLOB;
1558 bind_[address_index_].buffer =
reinterpret_cast<char*
>(ipv6_address_buffer_);
1559 bind_[address_index_].buffer_length = ipv6_address_buffer_len_;
1560 bind_[address_index_].length = &ipv6_address_buffer_len_;
1563 bind_[prefix_len_index_].buffer_type = MYSQL_TYPE_TINY;
1564 bind_[prefix_len_index_].buffer =
reinterpret_cast<char*
>(&prefix_len_);
1565 bind_[prefix_len_index_].is_unsigned =
MLM_TRUE;
1569 bind_[type_index_].buffer_type = MYSQL_TYPE_TINY;
1570 bind_[type_index_].buffer =
reinterpret_cast<char*
>(&reserv_type_);
1571 bind_[type_index_].is_unsigned =
MLM_TRUE;
1572 bind_[type_index_].is_null = &reserv_type_null_;
1575 bind_[iaid_index_].buffer_type = MYSQL_TYPE_LONG;
1576 bind_[iaid_index_].buffer =
reinterpret_cast<char*
>(&iaid_);
1577 bind_[iaid_index_].is_unsigned =
MLM_TRUE;
1580 setErrorIndicators(bind_, error_);
1588 uint32_t reservation_id_;
1591 uint8_t reserv_type_;
1600 uint8_t ipv6_address_buffer_[isc::asiolink::V6ADDRESS_LEN];
1603 unsigned long ipv6_address_buffer_len_;
1606 uint8_t prefix_len_;
1614 size_t reservation_id_index_;
1617 size_t address_index_;
1620 size_t prefix_len_index_;
1631 uint32_t most_recent_reservation_id_;
1644class MySqlIPv6ReservationExchange {
1648 static const size_t RESRV_COLUMNS = 6;
1655 MySqlIPv6ReservationExchange()
1656 : host_id_(0), prefix_len_(0), type_(0),
1660 std::fill(&error_[0], &error_[RESRV_COLUMNS],
MLM_FALSE);
1663 columns_[0] =
"host_id";
1664 columns_[1] =
"address";
1665 columns_[2] =
"prefix_len";
1666 columns_[3] =
"type";
1667 columns_[4] =
"dhcp6_iaid";
1669 BOOST_STATIC_ASSERT(4 < RESRV_COLUMNS);
1686 std::vector<MYSQL_BIND> createBindForSend(
const IPv6Resrv& resv,
1688 const bool unique_ip) {
1699 memset(bind_, 0,
sizeof(bind_));
1705 if (addr6_.size() != isc::asiolink::V6ADDRESS_LEN) {
1707 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
1710 addr6_length_ = isc::asiolink::V6ADDRESS_LEN;
1711 bind_[0].buffer_type = MYSQL_TYPE_BLOB;
1712 bind_[0].buffer =
reinterpret_cast<char*
>(&addr6_[0]);
1713 bind_[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
1714 bind_[0].length = &addr6_length_;
1718 bind_[1].buffer_type = MYSQL_TYPE_TINY;
1719 bind_[1].buffer =
reinterpret_cast<char*
>(&prefix_len_);
1725 bind_[2].buffer_type = MYSQL_TYPE_TINY;
1726 bind_[2].buffer =
reinterpret_cast<char*
>(&type_);
1732 bind_[3].buffer_type = MYSQL_TYPE_LONG;
1733 bind_[3].buffer =
reinterpret_cast<char*
>(&iaid_);
1737 bind_[4].buffer_type = MYSQL_TYPE_LONG;
1738 bind_[4].buffer =
reinterpret_cast<char*
>(&host_id_);
1741 }
catch (
const std::exception& ex) {
1743 "Could not create bind array from IPv6 Reservation: "
1744 << resv_.toText() <<
", reason: " << ex.
what());
1750 std::vector<MYSQL_BIND> vec(&bind_[0], &bind_[RESRV_COLUMNS-1]);
1756 vec.push_back(bind_[0]);
1757 vec.push_back(bind_[1]);
1769 uint8_t prefix_len_;
1781 MYSQL_BIND bind_[RESRV_COLUMNS];
1784 std::string columns_[RESRV_COLUMNS];
1788 my_bool error_[RESRV_COLUMNS];
1791 std::vector<uint8_t> addr6_;
1794 unsigned long addr6_length_;
1800class MySqlOptionExchange {
1803 static const size_t OPTION_ID_COL = 0;
1804 static const size_t CODE_COL = 1;
1805 static const size_t VALUE_COL = 2;
1806 static const size_t FORMATTED_VALUE_COL = 3;
1807 static const size_t SPACE_COL = 4;
1808 static const size_t PERSISTENT_COL = 5;
1809 static const size_t CANCELLED_COL = 6;
1810 static const size_t USER_CONTEXT_COL = 7;
1811 static const size_t DHCP_SUBNET_ID_COL = 8;
1812 static const size_t HOST_ID_COL = 9;
1814 static const size_t OPTION_COLUMNS = 10;
1819 MySqlOptionExchange()
1820 : type_(0), value_len_(0), formatted_value_len_(0), space_(),
1821 space_len_(0), persistent_(false), cancelled_(false),
1822 user_context_(), user_context_len_(0), subnet_id_(SUBNET_ID_UNUSED),
1823 host_id_(0), option_() {
1825 BOOST_STATIC_ASSERT(10 <= OPTION_COLUMNS);
1831 std::vector<MYSQL_BIND> createBindForSend(
const OptionDescriptor& opt_desc,
1832 const std::string& opt_space,
1840 memset(bind_, 0,
sizeof(bind_));
1846 bind_[0].buffer_type = MYSQL_TYPE_NULL;
1849 type_ = option_->getType();
1850 bind_[1].buffer_type = MYSQL_TYPE_SHORT;
1851 bind_[1].buffer =
reinterpret_cast<char*
>(&type_);
1862 const uint8_t* buf_ptr = buf.getData();
1863 value_.assign(buf_ptr + opt_desc.
option_->getHeaderLen(),
1864 buf_ptr + buf.getLength());
1865 value_len_ = value_.size();
1866 bind_[2].buffer_type = MYSQL_TYPE_BLOB;
1867 bind_[2].buffer = &value_[0];
1868 bind_[2].buffer_length = value_len_;
1869 bind_[2].length = &value_len_;
1875 bind_[2].buffer_type = MYSQL_TYPE_NULL;
1881 bind_[3].buffer_type = MYSQL_TYPE_STRING;
1883 bind_[3].buffer_length = formatted_value_len_;
1884 bind_[3].length = &formatted_value_len_;
1887 bind_[3].buffer_type = MYSQL_TYPE_NULL;
1892 space_len_ = space_.size();
1893 bind_[4].buffer_type = MYSQL_TYPE_STRING;
1894 bind_[4].buffer =
const_cast<char*
>(space_.c_str());
1895 bind_[4].buffer_length = space_len_;
1896 bind_[4].length = &space_len_;
1900 bind_[5].buffer_type = MYSQL_TYPE_TINY;
1901 bind_[5].buffer =
reinterpret_cast<char*
>(&persistent_);
1906 bind_[6].buffer_type = MYSQL_TYPE_TINY;
1907 bind_[6].buffer =
reinterpret_cast<char*
>(&cancelled_);
1913 user_context_ = ctx->str();
1914 user_context_len_ = user_context_.size();
1915 bind_[7].buffer_type = MYSQL_TYPE_STRING;
1916 bind_[7].buffer =
const_cast<char*
>(user_context_.c_str());
1917 bind_[7].buffer_length = user_context_len_;
1918 bind_[7].length = &user_context_len_;
1920 bind_[7].buffer_type = MYSQL_TYPE_NULL;
1925 subnet_id_ = subnet_id;
1926 bind_[8].buffer_type = MYSQL_TYPE_LONG;
1927 bind_[8].buffer =
reinterpret_cast<char*
>(subnet_id_);
1931 bind_[8].buffer_type = MYSQL_TYPE_NULL;
1936 bind_[9].buffer_type = MYSQL_TYPE_LONG;
1937 bind_[9].buffer =
reinterpret_cast<char*
>(&host_id_);
1940 }
catch (
const std::exception& ex) {
1942 "Could not create bind array for inserting DHCP "
1943 "option: " << option_->toText() <<
", reason: "
1947 return (std::vector<MYSQL_BIND>(&bind_[0], &bind_[OPTION_COLUMNS]));
1956 std::vector<uint8_t> value_;
1959 unsigned long value_len_;
1962 unsigned long formatted_value_len_;
1968 unsigned long space_len_;
1979 std::string user_context_;
1982 unsigned long user_context_len_;
1985 uint32_t subnet_id_;
1994 MYSQL_BIND bind_[OPTION_COLUMNS];
2182 std::pair<uint32_t, uint32_t>
getVersion(
const std::string& timer_name = std::string())
const;
2194 std::vector<MYSQL_BIND>& bind);
2229 const std::string& opt_space,
2243 const uint64_t host_id);
2259 const char* what)
const;
2282 boost::shared_ptr<MySqlHostExchange> exchange,
2306 const uint8_t* identifier_begin,
2307 const size_t identifier_len,
2309 boost::shared_ptr<MySqlHostExchange> exchange)
const;
2343typedef boost::array<TaggedStatement, MySqlHostDataSourceImpl::NUM_STATEMENTS>
2344TaggedStatementArray;
2348TaggedStatementArray tagged_statements = { {
2354 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2355 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, "
2356 "h.hostname, h.dhcp4_client_classes, h.dhcp6_client_classes, "
2358 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2359 "h.dhcp4_boot_file_name, h.auth_key, "
2360 "o4.option_id, o4.code, o4.value, o4.formatted_value, o4.space, "
2361 "o4.persistent, o4.cancelled, o4.user_context, "
2362 "o6.option_id, o6.code, o6.value, o6.formatted_value, o6.space, "
2363 "o6.persistent, o6.cancelled, o6.user_context, "
2364 "r.reservation_id, r.address, r.prefix_len, r.type, "
2367 "LEFT JOIN dhcp4_options AS o4 "
2368 "ON h.host_id = o4.host_id "
2369 "LEFT JOIN dhcp6_options AS o6 "
2370 "ON h.host_id = o6.host_id "
2371 "LEFT JOIN ipv6_reservations AS r "
2372 "ON h.host_id = r.host_id "
2373 "WHERE dhcp_identifier = ? AND dhcp_identifier_type = ? "
2374 "ORDER BY h.host_id, o4.option_id, o6.option_id, r.reservation_id"},
2380 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2381 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2382 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2383 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2384 "h.dhcp4_boot_file_name, h.auth_key, "
2385 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2386 "o.persistent, o.cancelled, o.user_context "
2388 "LEFT JOIN dhcp4_options AS o "
2389 "ON h.host_id = o.host_id "
2390 "WHERE ipv4_address = ? "
2391 "ORDER BY h.host_id, o.option_id"},
2397 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2398 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2399 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2400 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2401 "h.dhcp4_boot_file_name, h.auth_key, "
2402 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2403 "o.persistent, o.cancelled, o.user_context "
2405 "LEFT JOIN dhcp4_options AS o "
2406 "ON h.host_id = o.host_id "
2407 "WHERE h.dhcp4_subnet_id = ? AND h.dhcp_identifier_type = ? "
2408 "AND h.dhcp_identifier = ? "
2409 "ORDER BY h.host_id, o.option_id"},
2415 "SELECT h.host_id, h.dhcp_identifier, "
2416 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2417 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2418 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2419 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2420 "h.dhcp4_boot_file_name, h.auth_key, "
2421 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2422 "o.persistent, o.cancelled, o.user_context, "
2423 "r.reservation_id, r.address, r.prefix_len, r.type, "
2426 "LEFT JOIN dhcp6_options AS o "
2427 "ON h.host_id = o.host_id "
2428 "LEFT JOIN ipv6_reservations AS r "
2429 "ON h.host_id = r.host_id "
2430 "WHERE h.dhcp6_subnet_id = ? AND h.dhcp_identifier_type = ? "
2431 "AND h.dhcp_identifier = ? "
2432 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2439 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2440 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2441 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2442 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2443 "h.dhcp4_boot_file_name, h.auth_key, "
2444 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2445 "o.persistent, o.cancelled, o.user_context "
2447 "LEFT JOIN dhcp4_options AS o "
2448 "ON h.host_id = o.host_id "
2449 "WHERE h.dhcp4_subnet_id = ? AND h.ipv4_address = ? "
2450 "ORDER BY h.host_id, o.option_id"},
2459 "SELECT h.host_id, h.dhcp_identifier, "
2460 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2461 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2462 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2463 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2464 "h.dhcp4_boot_file_name, h.auth_key, "
2465 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2466 "o.persistent, o.cancelled, o.user_context,"
2467 "r.reservation_id, r.address, r.prefix_len, r.type, "
2470 "LEFT JOIN dhcp6_options AS o "
2471 "ON h.host_id = o.host_id "
2472 "LEFT JOIN ipv6_reservations AS r "
2473 "ON h.host_id = r.host_id "
2474 "WHERE h.host_id = "
2475 "( SELECT host_id FROM ipv6_reservations "
2476 "WHERE address = ? AND prefix_len = ? ) "
2477 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2486 "SELECT h.host_id, h.dhcp_identifier, "
2487 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2488 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2489 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2490 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2491 "h.dhcp4_boot_file_name, h.auth_key, "
2492 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2493 "o.persistent, o.cancelled, o.user_context, "
2494 "r.reservation_id, r.address, r.prefix_len, r.type, "
2497 "LEFT JOIN dhcp6_options AS o "
2498 "ON h.host_id = o.host_id "
2499 "LEFT JOIN ipv6_reservations AS r "
2500 "ON h.host_id = r.host_id "
2501 "WHERE h.dhcp6_subnet_id = ? AND h.host_id IN "
2502 "(SELECT host_id FROM ipv6_reservations "
2503 "WHERE address = ?) "
2504 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2514 "SELECT h.host_id, h.dhcp_identifier, "
2515 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2516 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2517 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2518 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2519 "h.dhcp4_boot_file_name, h.auth_key, "
2520 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2521 "o.persistent, o.cancelled, o.user_context, "
2522 "r.reservation_id, r.address, r.prefix_len, r.type, "
2525 "LEFT JOIN dhcp6_options AS o "
2526 "ON h.host_id = o.host_id "
2527 "LEFT JOIN ipv6_reservations AS r "
2528 "ON h.host_id = r.host_id "
2529 "WHERE h.host_id IN "
2530 "(SELECT host_id FROM ipv6_reservations "
2531 "WHERE address = ?) "
2532 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2538 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2539 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2540 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2541 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2542 "h.dhcp4_boot_file_name, h.auth_key, "
2543 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2544 "o.persistent, o.cancelled, o.user_context "
2546 "LEFT JOIN dhcp4_options AS o "
2547 "ON h.host_id = o.host_id "
2548 "WHERE h.dhcp4_subnet_id = ? "
2549 "ORDER BY h.host_id, o.option_id"},
2556 "SELECT h.host_id, h.dhcp_identifier, "
2557 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2558 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2559 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2560 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2561 "h.dhcp4_boot_file_name, h.auth_key, "
2562 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2563 "o.persistent, o.cancelled, o.user_context, "
2564 "r.reservation_id, r.address, r.prefix_len, r.type, "
2567 "LEFT JOIN dhcp6_options AS o "
2568 "ON h.host_id = o.host_id "
2569 "LEFT JOIN ipv6_reservations AS r "
2570 "ON h.host_id = r.host_id "
2571 "WHERE h.dhcp6_subnet_id = ? "
2572 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2579 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2580 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, "
2581 "h.hostname, h.dhcp4_client_classes, h.dhcp6_client_classes, "
2583 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2584 "h.dhcp4_boot_file_name, h.auth_key, "
2585 "o4.option_id, o4.code, o4.value, o4.formatted_value, o4.space, "
2586 "o4.persistent, o4.cancelled, o4.user_context, "
2587 "o6.option_id, o6.code, o6.value, o6.formatted_value, o6.space, "
2588 "o6.persistent, o6.cancelled, o6.user_context, "
2589 "r.reservation_id, r.address, r.prefix_len, r.type, "
2592 "LEFT JOIN dhcp4_options AS o4 "
2593 "ON h.host_id = o4.host_id "
2594 "LEFT JOIN dhcp6_options AS o6 "
2595 "ON h.host_id = o6.host_id "
2596 "LEFT JOIN ipv6_reservations AS r "
2597 "ON h.host_id = r.host_id "
2598 "WHERE h.hostname = ? "
2599 "ORDER BY h.host_id, o4.option_id, o6.option_id, r.reservation_id"},
2605 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2606 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2607 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2608 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2609 "h.dhcp4_boot_file_name, h.auth_key, "
2610 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2611 "o.persistent, o.cancelled, o.user_context "
2613 "LEFT JOIN dhcp4_options AS o "
2614 "ON h.host_id = o.host_id "
2615 "WHERE h.hostname = ? AND h.dhcp4_subnet_id = ? "
2616 "ORDER BY h.host_id, o.option_id"},
2622 "SELECT h.host_id, h.dhcp_identifier, "
2623 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2624 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2625 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2626 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2627 "h.dhcp4_boot_file_name, h.auth_key, "
2628 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2629 "o.persistent, o.cancelled, o.user_context, "
2630 "r.reservation_id, r.address, r.prefix_len, r.type, "
2633 "LEFT JOIN dhcp6_options AS o "
2634 "ON h.host_id = o.host_id "
2635 "LEFT JOIN ipv6_reservations AS r "
2636 "ON h.host_id = r.host_id "
2637 "WHERE h.hostname = ? AND h.dhcp6_subnet_id = ? "
2638 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2646 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2647 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2648 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2649 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2650 "h.dhcp4_boot_file_name, h.auth_key, "
2651 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2652 "o.persistent, o.cancelled, o.user_context "
2653 "FROM ( SELECT * FROM hosts AS h "
2654 "WHERE h.dhcp4_subnet_id = ? AND h.host_id > ? "
2655 "ORDER BY h.host_id "
2657 "LEFT JOIN dhcp4_options AS o "
2658 "ON h.host_id = o.host_id "
2659 "ORDER BY h.host_id, o.option_id"},
2667 "SELECT h.host_id, h.dhcp_identifier, "
2668 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2669 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2670 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2671 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2672 "h.dhcp4_boot_file_name, h.auth_key, "
2673 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2674 "o.persistent, o.cancelled, o.user_context, "
2675 "r.reservation_id, r.address, r.prefix_len, r.type, "
2677 "FROM ( SELECT * FROM hosts AS h "
2678 "WHERE h.dhcp6_subnet_id = ? AND h.host_id > ? "
2679 "ORDER BY h.host_id "
2681 "LEFT JOIN dhcp6_options AS o "
2682 "ON h.host_id = o.host_id "
2683 "LEFT JOIN ipv6_reservations AS r "
2684 "ON h.host_id = r.host_id "
2685 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2693 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2694 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2695 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2696 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2697 "h.dhcp4_boot_file_name, h.auth_key, "
2698 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2699 "o.persistent, o.cancelled, o.user_context "
2700 "FROM ( SELECT * FROM hosts AS h "
2701 "WHERE h.host_id > ? "
2702 "ORDER BY h.host_id "
2704 "LEFT JOIN dhcp4_options AS o "
2705 "ON h.host_id = o.host_id "
2706 "ORDER BY h.host_id, o.option_id"},
2714 "SELECT h.host_id, h.dhcp_identifier, "
2715 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2716 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2717 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2718 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2719 "h.dhcp4_boot_file_name, h.auth_key, "
2720 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2721 "o.persistent, o.cancelled, o.user_context, "
2722 "r.reservation_id, r.address, r.prefix_len, r.type, "
2724 "FROM ( SELECT * FROM hosts AS h "
2725 "WHERE h.host_id > ? "
2726 "ORDER BY h.host_id "
2728 "LEFT JOIN dhcp6_options AS o "
2729 "ON h.host_id = o.host_id "
2730 "LEFT JOIN ipv6_reservations AS r "
2731 "ON h.host_id = r.host_id "
2732 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2737 "INSERT INTO hosts(host_id, dhcp_identifier, dhcp_identifier_type, "
2738 "dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, "
2739 "dhcp4_client_classes, dhcp6_client_classes, "
2740 "user_context, dhcp4_next_server, "
2741 "dhcp4_server_hostname, dhcp4_boot_file_name, auth_key) "
2742 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
2756 "INSERT INTO hosts(host_id, dhcp_identifier, dhcp_identifier_type, "
2757 "dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, "
2758 "dhcp4_client_classes, dhcp6_client_classes, "
2759 "user_context, dhcp4_next_server, "
2760 "dhcp4_server_hostname, dhcp4_boot_file_name, auth_key) "
2761 "SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? FROM DUAL "
2762 "WHERE NOT EXISTS ("
2763 "SELECT 1 FROM hosts "
2764 "WHERE ipv4_address = ? AND dhcp4_subnet_id = ? "
2771 "INSERT INTO ipv6_reservations(address, prefix_len, type, "
2772 "dhcp6_iaid, host_id) "
2773 "VALUES (?, ?, ?, ?, ?)"},
2778 "INSERT INTO ipv6_reservations(address, prefix_len, type, "
2779 "dhcp6_iaid, host_id) "
2780 "SELECT ?, ?, ?, ?, ? FROM DUAL "
2781 "WHERE NOT EXISTS ("
2782 "SELECT 1 FROM ipv6_reservations "
2783 "WHERE address = ? AND prefix_len = ? "
2790 "INSERT INTO dhcp4_options(option_id, code, value, formatted_value, space, "
2791 "persistent, cancelled, user_context, dhcp4_subnet_id, host_id, scope_id) "
2792 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 3)"},
2797 "INSERT INTO dhcp6_options(option_id, code, value, formatted_value, space, "
2798 "persistent, cancelled, user_context, dhcp6_subnet_id, host_id, scope_id) "
2799 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 3)"},
2803 "DELETE FROM hosts WHERE dhcp4_subnet_id = ? AND ipv4_address = ?"},
2807 "DELETE h FROM hosts AS h "
2808 "INNER JOIN ipv6_reservations AS r "
2809 "ON h.host_id = r.host_id "
2810 "WHERE h.dhcp6_subnet_id = ? AND r.address = ?"},
2814 "DELETE FROM hosts WHERE dhcp4_subnet_id = ? AND dhcp_identifier_type=? "
2815 "AND dhcp_identifier = ?"},
2819 "DELETE FROM hosts WHERE dhcp6_subnet_id = ? AND dhcp_identifier_type=? "
2820 "AND dhcp_identifier = ?"}
2831 : conn_(parameters, io_service_accessor, db_reconnect_callback),
2832 is_readonly_(true) {
2844 lock_guard<mutex> lock(mgr_.
pool_->mutex_);
2845 if (!mgr_.
pool_->pool_.empty()) {
2847 mgr_.
pool_->pool_.pop_back();
2855 if (mgr_.
pool_->pool_.empty()) {
2865 lock_guard<mutex> lock(mgr_.pool_->mutex_);
2866 mgr_.pool_->pool_.push_back(ctx_);
2867 if (ctx_->conn_.isUnusable()) {
2868 mgr_.unusable_ =
true;
2870 }
else if (ctx_->conn_.isUnusable()) {
2871 mgr_.unusable_ =
true;
2876 : parameters_(parameters), ip_reservations_unique_(true), unusable_(false) {
2880 timer_name_ += boost::lexical_cast<std::string>(
reinterpret_cast<uint64_t
>(
this));
2901 ctx->conn_.openDatabase();
2904 if (ctx->conn_.getTls()) {
2905 std::string cipher = ctx->conn_.getTlsCipher();
2906 if (cipher.empty()) {
2918 ctx->conn_.prepareStatements(tagged_statements.begin(),
2923 ctx->is_readonly_ = ctx->conn_.configuredReadOnly();
2927 if (!ctx->is_readonly_) {
2930 tagged_statements.end());
2937 ctx->host_ipv4_exchange_.reset(
new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY));
2938 ctx->host_ipv6_exchange_.reset(
new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP6_ONLY));
2939 ctx->host_ipv46_exchange_.reset(
new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP4_AND_DHCP6));
2940 ctx->host_ipv6_reservation_exchange_.reset(
new MySqlIPv6ReservationExchange());
2941 ctx->host_option_exchange_.reset(
new MySqlOptionExchange());
2961 bool reopened =
false;
2963 const std::string timer_name = db_reconnect_ctl->timerName();
2968 std::list<std::string> host_db_access_list = cfg_db->getHostDbAccessStringList();
2969 for (std::string& hds : host_db_access_list) {
2976 }
catch (
const std::exception& ex) {
2992 if (!db_reconnect_ctl->checkRetries()) {
2995 .arg(db_reconnect_ctl->maxRetries());
3008 .arg(db_reconnect_ctl->maxRetries() - db_reconnect_ctl->retriesLeft() + 1)
3009 .arg(db_reconnect_ctl->maxRetries())
3010 .arg(db_reconnect_ctl->retryInterval());
3016 db_reconnect_ctl->retryInterval(),
3025std::pair<uint32_t, uint32_t>
3038 std::vector<MYSQL_BIND>& bind) {
3040 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), &bind[0]);
3041 checkError(ctx, status, stindex,
"unable to bind parameters");
3048 if (mysql_errno(ctx->conn_.mysql_) == ER_DUP_ENTRY) {
3051 checkError(ctx, status, stindex,
"unable to execute");
3059 my_ulonglong numrows = mysql_stmt_affected_rows(ctx->conn_.getStatement(stindex));
3070 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), &bind[0]);
3071 checkError(ctx, status, stindex,
"unable to bind parameters");
3077 checkError(ctx, status, stindex,
"unable to execute");
3081 my_ulonglong numrows = mysql_stmt_affected_rows(ctx->conn_.getStatement(stindex));
3083 return (numrows != 0);
3090 std::vector<MYSQL_BIND> bind = ctx->host_ipv6_reservation_exchange_->
3100 const std::string& opt_space,
3103 std::vector<MYSQL_BIND> bind = ctx->host_option_exchange_->createBindForSend(opt_desc, opt_space, subnet_id,
id);
3112 const uint64_t host_id) {
3115 std::list<std::string> option_spaces = options_cfg->getOptionSpaceNames();
3116 std::list<std::string> vendor_spaces = options_cfg->getVendorIdsSpaceNames();
3117 option_spaces.insert(option_spaces.end(), vendor_spaces.begin(),
3118 vendor_spaces.end());
3122 for (
auto const& space : option_spaces) {
3124 if (options && !options->empty()) {
3125 for (
auto const& opt : *options) {
3136 const char* what)
const {
3137 ctx->conn_.checkError(status, index, what);
3144 boost::shared_ptr<MySqlHostExchange> exchange,
3146 bool single)
const {
3149 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), bind);
3150 checkError(ctx, status, stindex,
"unable to bind WHERE clause parameter");
3154 std::vector<MYSQL_BIND> outbind = exchange->createBindForReceive();
3155 status = mysql_stmt_bind_result(ctx->conn_.getStatement(stindex), &outbind[0]);
3156 checkError(ctx, status, stindex,
"unable to bind SELECT clause parameters");
3160 checkError(ctx, status, stindex,
"unable to execute");
3164 status = mysql_stmt_store_result(ctx->conn_.getStatement(stindex));
3165 checkError(ctx, status, stindex,
"unable to set up for storing all results");
3172 while ((status = mysql_stmt_fetch(ctx->conn_.getStatement(stindex))) ==
3175 exchange->processFetchedData(result);
3180 ctx->conn_.text_statements_[stindex] <<
">");
3183 if (single && (result.size() > 1)) {
3185 "database where only one was expected for query "
3186 << ctx->conn_.text_statements_[stindex]);
3194 checkError(ctx, status, stindex,
"unable to fetch results");
3196 }
else if (status == MYSQL_DATA_TRUNCATED) {
3199 <<
" returned truncated data: columns affected are "
3200 << exchange->getErrorColumns());
3208 const uint8_t* identifier_begin,
3209 const size_t identifier_len,
3211 boost::shared_ptr<MySqlHostExchange> exchange)
const {
3214 MYSQL_BIND inbind[3];
3215 memset(inbind, 0,
sizeof(inbind));
3217 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3218 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3219 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3223 std::vector<char> identifier_vec(identifier_begin,
3224 identifier_begin + identifier_len);
3225 unsigned long length = identifier_vec.size();
3226 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3227 inbind[2].buffer = &identifier_vec[0];
3228 inbind[2].buffer_length = length;
3229 inbind[2].length = &length;
3232 char identifier_type_copy =
static_cast<char>(identifier_type);
3233 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3234 inbind[1].buffer =
reinterpret_cast<char*
>(&identifier_type_copy);
3242 if (!collection.empty()) {
3243 result = *collection.begin();
3251 if (ctx->is_readonly_) {
3253 " operate in read only mode");
3266 return (impl_->parameters_);
3276 impl_->checkReadOnly(ctx);
3288 bool unique_ip = impl_->ip_reservations_unique_ && !host->getIPv4Reservation().isV4Zero()
3289 && host->getIPv4SubnetID() != SUBNET_ID_UNUSED;
3292 std::vector<MYSQL_BIND> bind = ctx->host_ipv4_exchange_->createBindForSend(host, unique_ip);
3299 uint64_t host_id = mysql_insert_id(ctx->conn_.mysql_);
3305 cfg_option4, host_id);
3312 cfg_option6, host_id);
3317 if (std::distance(v6resv.first, v6resv.second) > 0) {
3318 BOOST_FOREACH(
auto const& resv, v6resv) {
3319 impl_->addResv(ctx, resv.second, host_id);
3335 impl_->checkReadOnly(ctx);
3338 MYSQL_BIND inbind[2];
3340 uint32_t subnet = subnet_id;
3341 memset(inbind, 0,
sizeof(inbind));
3342 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3343 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3349 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3350 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3357 std::vector<uint8_t>addr6 = addr.
toBytes();
3358 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3360 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3363 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3364 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3365 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3366 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3367 inbind[1].length = &addr6_length;
3375 const uint8_t* identifier_begin,
3376 const size_t identifier_len) {
3382 impl_->checkReadOnly(ctx);
3385 MYSQL_BIND inbind[3];
3388 memset(inbind, 0,
sizeof(inbind));
3389 uint32_t subnet =
static_cast<uint32_t
>(subnet_id);
3390 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3391 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3395 char identifier_type_copy =
static_cast<char>(identifier_type);
3396 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3397 inbind[1].buffer =
reinterpret_cast<char*
>(&identifier_type_copy);
3401 std::vector<char> identifier_vec(identifier_begin,
3402 identifier_begin + identifier_len);
3403 unsigned long length = identifier_vec.size();
3404 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3405 inbind[2].buffer = &identifier_vec[0];
3406 inbind[2].buffer_length = length;
3407 inbind[2].length = &length;
3416 const uint8_t* identifier_begin,
3417 const size_t identifier_len) {
3423 impl_->checkReadOnly(ctx);
3426 MYSQL_BIND inbind[3];
3429 memset(inbind, 0,
sizeof(inbind));
3430 uint32_t subnet =
static_cast<uint32_t
>(subnet_id);
3431 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3432 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3436 char identifier_type_copy =
static_cast<char>(identifier_type);
3437 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3438 inbind[1].buffer =
reinterpret_cast<char*
>(&identifier_type_copy);
3442 std::vector<char> identifier_vec(identifier_begin,
3443 identifier_begin + identifier_len);
3444 unsigned long length = identifier_vec.size();
3445 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3446 inbind[2].buffer = &identifier_vec[0];
3447 inbind[2].buffer_length = length;
3448 inbind[2].length = &length;
3456 const uint8_t* identifier_begin,
3457 const size_t identifier_len)
const {
3463 MYSQL_BIND inbind[2];
3464 memset(inbind, 0,
sizeof(inbind));
3467 char identifier_type_copy =
static_cast<char>(identifier_type);
3468 inbind[1].buffer = &identifier_type_copy;
3469 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3473 std::vector<char> identifier_vec(identifier_begin,
3474 identifier_begin + identifier_len);
3475 unsigned long int length = identifier_vec.size();
3476 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
3477 inbind[0].buffer = &identifier_vec[0];
3478 inbind[0].buffer_length = length;
3479 inbind[0].length = &length;
3483 ctx->host_ipv46_exchange_, result,
false);
3495 MYSQL_BIND inbind[1];
3496 memset(inbind, 0,
sizeof(inbind));
3497 uint32_t subnet = subnet_id;
3498 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3499 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3504 ctx->host_ipv4_exchange_, result,
false);
3516 MYSQL_BIND inbind[1];
3517 memset(inbind, 0,
sizeof(inbind));
3518 uint32_t subnet = subnet_id;
3519 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3520 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3525 ctx->host_ipv6_exchange_, result,
false);
3537 MYSQL_BIND inbind[1];
3538 memset(inbind, 0,
sizeof(inbind));
3543 unsigned long length = hostname.length();
3544 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3545 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3546 inbind[0].buffer_length = length;
3547 inbind[0].length = &length;
3551 ctx->host_ipv46_exchange_, result,
false);
3564 MYSQL_BIND inbind[2];
3565 memset(inbind, 0,
sizeof(inbind));
3570 unsigned long length = hostname.length();
3571 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3572 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3573 inbind[0].buffer_length = length;
3574 inbind[0].length = &length;
3577 uint32_t subnet = subnet_id;
3578 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3579 inbind[1].buffer =
reinterpret_cast<char*
>(&subnet);
3584 ctx->host_ipv4_exchange_, result,
false);
3597 MYSQL_BIND inbind[2];
3598 memset(inbind, 0,
sizeof(inbind));
3603 unsigned long length = hostname.length();
3604 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3605 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3606 inbind[0].buffer_length = length;
3607 inbind[0].length = &length;
3610 uint32_t subnet = subnet_id;
3611 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3612 inbind[1].buffer =
reinterpret_cast<char*
>(&subnet);
3617 ctx->host_ipv6_exchange_, result,
false);
3625 uint64_t lower_host_id,
3632 MYSQL_BIND inbind[3];
3633 memset(inbind, 0,
sizeof(inbind));
3636 uint32_t subnet = subnet_id;
3637 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3638 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3642 uint32_t host_id = lower_host_id;
3643 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3644 inbind[1].buffer =
reinterpret_cast<char*
>(&host_id);
3648 uint32_t page_size_data = page_size.
page_size_;
3649 inbind[2].buffer_type = MYSQL_TYPE_LONG;
3650 inbind[2].buffer =
reinterpret_cast<char*
>(&page_size_data);
3655 ctx->host_ipv4_exchange_, result,
false);
3663 uint64_t lower_host_id,
3670 MYSQL_BIND inbind[3];
3671 memset(inbind, 0,
sizeof(inbind));
3674 uint32_t subnet = subnet_id;
3675 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3676 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3680 uint32_t host_id = lower_host_id;
3681 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3682 inbind[1].buffer =
reinterpret_cast<char*
>(&host_id);
3686 uint32_t page_size_data = page_size.
page_size_;
3687 inbind[2].buffer_type = MYSQL_TYPE_LONG;
3688 inbind[2].buffer =
reinterpret_cast<char*
>(&page_size_data);
3693 ctx->host_ipv6_exchange_, result,
false);
3700 uint64_t lower_host_id,
3707 MYSQL_BIND inbind[2];
3708 memset(inbind, 0,
sizeof(inbind));
3711 uint32_t host_id = lower_host_id;
3712 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3713 inbind[0].buffer =
reinterpret_cast<char*
>(&host_id);
3717 uint32_t page_size_data = page_size.
page_size_;
3718 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3719 inbind[1].buffer =
reinterpret_cast<char*
>(&page_size_data);
3724 ctx->host_ipv4_exchange_, result,
false);
3731 uint64_t lower_host_id,
3738 MYSQL_BIND inbind[2];
3739 memset(inbind, 0,
sizeof(inbind));
3742 uint32_t host_id = lower_host_id;
3743 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3744 inbind[0].buffer =
reinterpret_cast<char*
>(&host_id);
3748 uint32_t page_size_data = page_size.
page_size_;
3749 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3750 inbind[1].buffer =
reinterpret_cast<char*
>(&page_size_data);
3755 ctx->host_ipv6_exchange_, result,
false);
3767 MYSQL_BIND inbind[1];
3768 memset(inbind, 0,
sizeof(inbind));
3770 uint32_t addr4 = address.
toUint32();
3771 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3772 inbind[0].buffer =
reinterpret_cast<char*
>(&addr4);
3777 ctx->host_ipv4_exchange_, result,
false);
3785 const uint8_t* identifier_begin,
3786 const size_t identifier_len)
const {
3791 return (impl_->getHost(ctx, subnet_id, identifier_type, identifier_begin, identifier_len,
3793 ctx->host_ipv4_exchange_));
3799 if (!address.
isV4()) {
3801 "wrong address type, address supplied is an IPv6 address");
3809 MYSQL_BIND inbind[2];
3810 uint32_t subnet = subnet_id;
3811 memset(inbind, 0,
sizeof(inbind));
3812 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3813 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3816 uint32_t addr4 = address.
toUint32();
3817 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3818 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3823 ctx->host_ipv4_exchange_, collection,
true);
3827 if (!collection.empty()) {
3828 result = *collection.begin();
3837 if (!address.
isV4()) {
3839 "wrong address type, address supplied is an IPv6 address");
3847 MYSQL_BIND inbind[2];
3848 uint32_t subnet = subnet_id;
3849 memset(inbind, 0,
sizeof(inbind));
3850 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3851 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3854 uint32_t addr4 = address.
toUint32();
3855 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3856 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3861 ctx->host_ipv4_exchange_, collection,
false);
3862 return (collection);
3868 const uint8_t* identifier_begin,
3869 const size_t identifier_len)
const {
3874 return (impl_->getHost(ctx, subnet_id, identifier_type, identifier_begin, identifier_len,
3876 ctx->host_ipv6_exchange_));
3881 const uint8_t prefix_len)
const {
3882 if (!prefix.
isV6()) {
3884 "wrong address type, address supplied is an IPv4 address");
3892 MYSQL_BIND inbind[2];
3893 memset(inbind, 0,
sizeof(inbind));
3895 std::vector<uint8_t>addr6 = prefix.
toBytes();
3896 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3898 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3901 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3902 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
3903 inbind[0].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3904 inbind[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3905 inbind[0].length = &addr6_length;
3907 uint8_t tmp = prefix_len;
3908 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3909 inbind[1].buffer =
reinterpret_cast<char*
>(&tmp);
3914 ctx->host_ipv6_exchange_, collection,
true);
3918 if (!collection.empty()) {
3919 result = *collection.begin();
3928 if (!address.
isV6()) {
3930 "wrong address type, address supplied is an IPv4 address");
3938 MYSQL_BIND inbind[2];
3939 memset(inbind, 0,
sizeof(inbind));
3941 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3942 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3943 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3946 std::vector<uint8_t>addr6 = address.
toBytes();
3947 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3949 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3952 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3953 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3954 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3955 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3956 inbind[1].length = &addr6_length;
3960 ctx->host_ipv6_exchange_, collection,
true);
3964 if (!collection.empty()) {
3965 result = *collection.begin();
3974 if (!address.
isV6()) {
3976 "wrong address type, address supplied is an IPv4 address");
3984 MYSQL_BIND inbind[2];
3985 memset(inbind, 0,
sizeof(inbind));
3987 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3988 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3989 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3992 std::vector<uint8_t>addr6 = address.
toBytes();
3993 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3995 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3998 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3999 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
4000 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
4001 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
4002 inbind[1].length = &addr6_length;
4006 ctx->host_ipv6_exchange_, collection,
false);
4007 return (collection);
4012 if (!address.
isV6()) {
4014 "wrong address type, address supplied is an IPv4 address");
4022 MYSQL_BIND inbind[1];
4023 memset(inbind, 0,
sizeof(inbind));
4025 std::vector<uint8_t>addr6 = address.
toBytes();
4026 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
4028 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
4031 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
4032 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
4033 inbind[0].buffer =
reinterpret_cast<char*
>(&addr6[0]);
4034 inbind[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
4035 inbind[0].length = &addr6_length;
4039 ctx->host_ipv6_exchange_, collection,
false);
4040 return (collection);
4050 impl_->checkReadOnly(ctx);
4073 std::string name =
"";
4079 name = ctx->conn_.getParameter(
"name");
4088 return (std::string(
"Host data source that stores host information"
4089 "in MySQL database"));
4092std::pair<uint32_t, uint32_t>
4094 return(impl_->getVersion(timer_name));
4104 impl_->checkReadOnly(ctx);
4105 if (ctx->conn_.isTransactionStarted()) {
4106 ctx->conn_.commit();
4117 impl_->checkReadOnly(ctx);
4118 if (ctx->conn_.isTransactionStarted()) {
4119 ctx->conn_.rollback();
4125 impl_->ip_reservations_unique_ = unique;
4131 return (impl_->unusable_);
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
bool isV6() const
Convenience function to check for an IPv6 address.
bool isV4() const
Convenience function to check for an IPv4 address.
std::vector< uint8_t > toBytes() const
Return address as set of bytes.
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
static ElementPtr fromJSON(const std::string &in, bool preproc=false)
These functions will parse the given string (JSON) representation of a compound element.
A standard Data module exception that is thrown if a parse error is encountered when constructing an ...
static bool invokeDbLostCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's lost connectivity callback.
static bool invokeDbFailedCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's restore failed connectivity callback.
static ParameterMap parse(const std::string &dbaccess)
Parse database access string.
static bool invokeDbRecoveredCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's restored connectivity callback.
static isc::asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Exception thrown on failure to execute a database function.
Database duplicate entry error.
Multiple lease records found where one expected.
Common MySQL Connector Pool.
static std::pair< uint32_t, uint32_t > getVersion(const ParameterMap ¶meters, const IOServiceAccessorPtr &ac=IOServiceAccessorPtr(), const DbCallback &cb=DbCallback(), const std::string &timer_name=std::string())
Get the schema version.
static void ensureSchemaVersion(const ParameterMap ¶meters, const DbCallback &cb=DbCallback(), const std::string &timer_name=std::string())
Retrieve schema version, validate it against the hardcoded version, and attempt to initialize the sch...
Fetch and Release MySQL Results.
RAII object representing MySQL transaction.
void commit()
Commits transaction.
Attempt to modify data in read-only database.
virtual void update(HostPtr const &host)
Attempts to update an existing host entry.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
static constexpr size_t MAX_CLIENT_ID_LEN
Maximum size of a client ID.
static bool delBackend(const std::string &db_type)
Delete an alternate host backend (aka host data source).
static void addBackend(const std::string &access)
Add an alternate host backend (aka host data source).
Wraps value holding size of the page with host reservations.
const size_t page_size_
Holds page size.
Represents a device with IPv4 and/or IPv6 reservations.
IdentifierType
Type of the host identifier.
static const IdentifierType LAST_IDENTIFIER_TYPE
Constant pointing to the last identifier of the IdentifierType enumeration.
IPv6 reservation for a host.
const asiolink::IOAddress & getPrefix() const
Returns prefix for the reservation.
Type getType() const
Returns reservation type.
Type
Type of the reservation.
uint8_t getPrefixLen() const
Returns prefix length.
static OptionDefinitionPtr getOptionDef(const std::string &space, const uint16_t code)
Return the first option definition matching a particular option code.
static OptionDefinitionPtr getVendorOptionDef(const Option::Universe u, const uint32_t vendor_id, const uint16_t code)
Returns vendor option definition for a given vendor-id and code.
static uint32_t optionSpaceToVendorId(const std::string &option_space)
Converts option space name to vendor id.
static OptionDefinitionPtr getRuntimeOptionDef(const std::string &space, const uint16_t code)
Returns runtime (non-standard) option definition by space and option code.
static OptionDefinitionPtr getLastResortOptionDef(const std::string &space, const uint16_t code)
Returns last resort option definition by space and option code.
std::vector< MySqlHostContextPtr > pool_
The vector of available contexts.
std::mutex mutex_
The mutex to protect pool access.
MySqlHostContext(const DatabaseConnection::ParameterMap ¶meters, IOServiceAccessorPtr io_service_accessor, db::DbCallback db_reconnect_callback)
Constructor.
boost::shared_ptr< MySqlHostIPv6Exchange > host_ipv46_exchange_
Pointer to an object representing an exchange which can be used to retrieve hosts,...
boost::shared_ptr< MySqlHostIPv6Exchange > host_ipv6_exchange_
Pointer to an object representing an exchange which can be used to retrieve hosts,...
boost::shared_ptr< MySqlIPv6ReservationExchange > host_ipv6_reservation_exchange_
Pointer to an object representing an exchange which can be used to insert new IPv6 reservation.
boost::shared_ptr< MySqlHostWithOptionsExchange > host_ipv4_exchange_
The exchange objects are used for transfer of data to/from the database.
boost::shared_ptr< MySqlOptionExchange > host_option_exchange_
Pointer to an object representing an exchange which can be used to insert DHCPv4 or DHCPv6 option int...
MySqlConnection conn_
MySQL connection.
bool is_readonly_
Indicates if the database is opened in read only mode.
Implementation of the MySqlHostDataSource.
void checkReadOnly(MySqlHostContextPtr &ctx) const
Throws exception if database is read only.
void checkError(MySqlHostContextPtr &ctx, const int status, const StatementIndex index, const char *what) const
Check Error and Throw Exception.
~MySqlHostDataSourceImpl()
Destructor.
std::string timer_name_
Timer name used to register database reconnect timer.
DatabaseConnection::ParameterMap parameters_
The parameters.
MySqlHostContextPtr createContext() const
Create a new context.
bool delStatement(MySqlHostContextPtr &ctx, StatementIndex stindex, MYSQL_BIND *bind)
Executes statements that delete records.
StatementIndex
Statement Tags.
@ GET_HOST_HOSTNAME_SUBID4
@ INSERT_V6_RESRV_NON_UNIQUE
@ GET_HOST_HOSTNAME_SUBID6
@ INSERT_HOST_NON_UNIQUE_IP
MySqlHostDataSourceImpl(const DatabaseConnection::ParameterMap ¶meters)
Constructor.
ConstHostPtr getHost(MySqlHostContextPtr &ctx, const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, StatementIndex stindex, boost::shared_ptr< MySqlHostExchange > exchange) const
Retrieves a host by subnet and client's unique identifier.
void addStatement(MySqlHostContextPtr &ctx, MySqlHostDataSourceImpl::StatementIndex stindex, std::vector< MYSQL_BIND > &bind)
Executes statements which inserts a row into one of the tables.
std::pair< uint32_t, uint32_t > getVersion(const std::string &timer_name=std::string()) const
Returns backend version.
void getHostCollection(MySqlHostContextPtr &ctx, StatementIndex stindex, MYSQL_BIND *bind, boost::shared_ptr< MySqlHostExchange > exchange, ConstHostCollection &result, bool single) const
Creates collection of Host objects with associated information such as IPv6 reservations and/or DHCP ...
bool ip_reservations_unique_
Holds the setting whether the IP reservations must be unique or may be non-unique.
void addOptions(MySqlHostContextPtr &ctx, const StatementIndex &stindex, const ConstCfgOptionPtr &options_cfg, const uint64_t host_id)
Inserts multiple options into the database.
MySqlHostContextPoolPtr pool_
The pool of contexts.
void addOption(MySqlHostContextPtr &ctx, const MySqlHostDataSourceImpl::StatementIndex &stindex, const OptionDescriptor &opt_desc, const std::string &opt_space, const Optional< SubnetID > &subnet_id, const HostID &host_id)
Inserts a single DHCP option into the database.
bool unusable_
Indicates if there is at least one connection that can no longer be used for normal operations.
void addResv(MySqlHostContextPtr &ctx, const IPv6Resrv &resv, const HostID &id)
Inserts IPv6 Reservation into ipv6_reservation table.
static bool dbReconnect(ReconnectCtlPtr db_reconnect_ctl)
Attempts to reconnect the server to the host DB backend manager.
static const StatementIndex WRITE_STMTS_BEGIN
Index of first statement performing write to the database.
MySqlHostContextAlloc(MySqlHostDataSourceImpl &mgr)
Constructor.
MySqlHostContextPtr ctx_
The context.
~MySqlHostContextAlloc()
Destructor.
virtual ConstHostCollection getAll(const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Return all hosts connected to any subnet for which reservations have been made using a specified iden...
virtual ConstHostPtr get6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Returns a host connected to the IPv6 subnet.
virtual std::pair< uint32_t, uint32_t > getVersion(const std::string &timer_name=std::string()) const
Returns backend version.
virtual void commit()
Commit Transactions.
virtual bool del(const SubnetID &subnet_id, const asiolink::IOAddress &addr)
Attempts to delete hosts by (subnet-id, address)
virtual ConstHostCollection getAll4(const SubnetID &subnet_id) const
Return all hosts in a DHCPv4 subnet.
virtual ConstHostCollection getAll6(const SubnetID &subnet_id) const
Return all hosts in a DHCPv6 subnet.
virtual std::string getDescription() const
Returns description of the backend.
MySqlHostDataSource(const db::DatabaseConnection::ParameterMap ¶meters)
Constructor.
virtual ~MySqlHostDataSource()
Virtual destructor.
virtual ConstHostCollection getAllbyHostname(const std::string &hostname) const
Return all hosts with a hostname.
virtual isc::db::DatabaseConnection::ParameterMap getParameters() const
Return backend parameters.
void update(HostPtr const &host)
Implements BaseHostDataSource::update() for MySQL.
virtual bool del6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len)
Attempts to delete a host by (subnet6-id, identifier type, identifier)
virtual ConstHostCollection getPage6(const SubnetID &subnet_id, size_t &source_index, uint64_t lower_host_id, const HostPageSize &page_size) const
Returns range of hosts in a DHCPv6 subnet.
virtual ConstHostCollection getAllbyHostname6(const std::string &hostname, const SubnetID &subnet_id) const
Return all hosts with a hostname in a DHCPv6 subnet.
virtual bool del4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len)
Attempts to delete a host by (subnet4-id, identifier type, identifier)
virtual ConstHostCollection getPage4(const SubnetID &subnet_id, size_t &source_index, uint64_t lower_host_id, const HostPageSize &page_size) const
Returns range of hosts in a DHCPv4 subnet.
virtual bool isUnusable()
Flag which indicates if the host manager has at least one unusable connection.
virtual ConstHostCollection getAllbyHostname4(const std::string &hostname, const SubnetID &subnet_id) const
Return all hosts with a hostname in a DHCPv4 subnet.
virtual void rollback()
Rollback Transactions.
virtual std::string getName() const
Returns backend name.
virtual void add(const HostPtr &host)
Adds a new host to the collection.
virtual ConstHostPtr get4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Returns a host connected to the IPv4 subnet.
virtual bool setIPReservationsUnique(const bool unique)
Controls whether IP reservations are unique or non-unique.
OptionPtr option_
Option instance.
bool cancelled_
Cancelled flag.
std::string formatted_value_
Option value in textual (CSV) format.
bool persistent_
Persistence flag.
Universe
defines option universe DHCPv4 or DHCPv6
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
RAII class creating a critical section.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
A template representing an optional value.
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
A wrapper interface for the ASIO library.
boost::shared_ptr< const Element > ConstElementPtr
const my_bool MLM_FALSE
MySQL false value.
boost::shared_ptr< IOServiceAccessor > IOServiceAccessorPtr
Pointer to an instance of IOServiceAccessor.
const my_bool MLM_TRUE
MySQL true value.
bool my_bool
my_bool type in MySQL 8.x.
const int MLM_MYSQL_FETCH_FAILURE
MySQL fetch failure code.
const int MLM_MYSQL_FETCH_SUCCESS
check for bool size
std::function< bool(util::ReconnectCtlPtr db_reconnect_ctl)> DbCallback
Defines a callback prototype for propagating events upward.
std::function< isc::asiolink::IOServicePtr()> IOServiceAccessor
Function which returns the IOService that can be used to recover the connection.
int MysqlExecuteStatement(MYSQL_STMT *stmt)
Execute a prepared statement.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
const size_t OPTION_FORMATTED_VALUE_MAX_LEN
Maximum length of option value specified in textual format.
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_GET_VERSION
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
const isc::log::MessageID DHCPSRV_MYSQL_NO_TLS
boost::shared_ptr< CfgDbAccess > CfgDbAccessPtr
A pointer to the CfgDbAccess.
const size_t CLIENT_CLASSES_MAX_LEN
Maximum length of classes stored in a dhcp4/6_client_classes columns.
std::pair< IPv6ResrvIterator, IPv6ResrvIterator > IPv6ResrvRange
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
const size_t TEXT_AUTH_KEY_LEN
Maximum length of authentication keys (coded in hexadecimal).
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_RECONNECT_FAILED
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
uint64_t HostID
HostID (used only when storing in MySQL or PostgreSQL backends)
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
boost::shared_ptr< MySqlHostContextPool > MySqlHostContextPoolPtr
Type of pointers to context pools.
const size_t HOSTNAME_MAX_LEN
Maximum length of the hostname stored in DNS.
boost::shared_ptr< MySqlHostContext > MySqlHostContextPtr
Type of pointers to contexts.
const size_t USER_CONTEXT_MAX_LEN
Maximum length of user context.
const size_t OPTION_VALUE_MAX_LEN
Maximum length of option value.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
const size_t SERVER_HOSTNAME_MAX_LEN
Maximum length of the server hostname.
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_READONLY
const size_t BOOT_FILE_NAME_MAX_LEN
Maximum length of the boot file name.
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_RECONNECT_ATTEMPT_SCHEDULE
boost::shared_ptr< Option > OptionPtr
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_RECONNECT_ATTEMPT_FAILED
const isc::log::MessageID DHCPSRV_MYSQL_TLS_CIPHER
boost::shared_ptr< const CfgOption > ConstCfgOptionPtr
Const pointer.
const size_t OPTION_SPACE_MAX_LEN
Maximum length of option space name.
boost::shared_ptr< ReconnectCtl > ReconnectCtlPtr
Pointer to an instance of ReconnectCtl.
Defines the logger used by the top-level component of kea-lfc.
#define DHCP4_OPTION_SPACE
global std option spaces
#define DHCP6_OPTION_SPACE
data::ConstElementPtr getContext() const
Returns const pointer to the user context.