26 #include <boost/algorithm/string/split.hpp>
27 #include <boost/algorithm/string/classification.hpp>
28 #include <boost/array.hpp>
29 #include <boost/pointer_cast.hpp>
30 #include <boost/static_assert.hpp>
33 #include <mysqld_error.h>
53 const uint8_t MAX_IDENTIFIER_TYPE =
static_cast<uint8_t
>(Host::LAST_IDENTIFIER_TYPE);
83 class MySqlHostExchange {
90 static const size_t HOST_ID_COL = 0;
91 static const size_t DHCP_IDENTIFIER_COL = 1;
92 static const size_t DHCP_IDENTIFIER_TYPE_COL = 2;
93 static const size_t DHCP4_SUBNET_ID_COL = 3;
94 static const size_t DHCP6_SUBNET_ID_COL = 4;
95 static const size_t IPV4_ADDRESS_COL = 5;
96 static const size_t HOSTNAME_COL = 6;
97 static const size_t DHCP4_CLIENT_CLASSES_COL = 7;
98 static const size_t DHCP6_CLIENT_CLASSES_COL = 8;
99 static const size_t USER_CONTEXT_COL = 9;
100 static const size_t DHCP4_NEXT_SERVER_COL = 10;
101 static const size_t DHCP4_SERVER_HOSTNAME_COL = 11;
102 static const size_t DHCP4_BOOT_FILE_NAME_COL = 12;
103 static const size_t AUTH_KEY_COL = 13;
105 static const size_t HOST_COLUMNS = 14;
116 MySqlHostExchange(
const size_t additional_columns_num = 0)
117 : columns_num_(HOST_COLUMNS + additional_columns_num),
118 bind_(columns_num_), columns_(columns_num_),
119 error_(columns_num_,
MLM_FALSE), host_id_(0),
120 dhcp_identifier_length_(0), dhcp_identifier_type_(0),
121 dhcp4_subnet_id_(SUBNET_ID_UNUSED),
122 dhcp6_subnet_id_(SUBNET_ID_UNUSED), ipv4_address_(0),
123 hostname_length_(0), dhcp4_client_classes_length_(0),
124 dhcp6_client_classes_length_(0),
125 user_context_length_(0),
126 dhcp4_next_server_(0),
127 dhcp4_server_hostname_length_(0),
128 dhcp4_boot_file_name_length_(0),
142 memset(dhcp_identifier_buffer_, 0,
sizeof(dhcp_identifier_buffer_));
143 memset(hostname_, 0,
sizeof(hostname_));
144 memset(dhcp4_client_classes_, 0,
sizeof(dhcp4_client_classes_));
145 memset(dhcp6_client_classes_, 0,
sizeof(dhcp6_client_classes_));
146 memset(user_context_, 0,
sizeof(user_context_));
147 memset(dhcp4_server_hostname_, 0,
sizeof(dhcp4_server_hostname_));
148 memset(dhcp4_boot_file_name_, 0,
sizeof(dhcp4_boot_file_name_));
149 memset(auth_key_, 0,
sizeof(auth_key_));
154 columns_[HOST_ID_COL] =
"host_id";
155 columns_[DHCP_IDENTIFIER_COL] =
"dhcp_identifier";
156 columns_[DHCP_IDENTIFIER_TYPE_COL] =
"dhcp_identifier_type";
157 columns_[DHCP4_SUBNET_ID_COL] =
"dhcp4_subnet_id";
158 columns_[DHCP6_SUBNET_ID_COL] =
"dhcp6_subnet_id";
159 columns_[IPV4_ADDRESS_COL] =
"ipv4_address";
160 columns_[HOSTNAME_COL] =
"hostname";
161 columns_[DHCP4_CLIENT_CLASSES_COL] =
"dhcp4_client_classes";
162 columns_[DHCP6_CLIENT_CLASSES_COL] =
"dhcp6_client_classes";
163 columns_[USER_CONTEXT_COL] =
"user_context";
164 columns_[DHCP4_NEXT_SERVER_COL] =
"dhcp4_next_server";
165 columns_[DHCP4_SERVER_HOSTNAME_COL] =
"dhcp4_server_hostname";
166 columns_[DHCP4_BOOT_FILE_NAME_COL] =
"dhcp4_boot_file_name";
167 columns_[AUTH_KEY_COL] =
"auth_key";
169 BOOST_STATIC_ASSERT(13 < HOST_COLUMNS);
173 virtual ~MySqlHostExchange() {
190 size_t findAvailColumn()
const {
191 std::vector<std::string>::const_iterator empty_column =
192 std::find(columns_.begin(), columns_.end(), std::string());
193 return (std::distance(columns_.begin(), empty_column));
199 uint64_t getHostId()
const {
213 static void setErrorIndicators(std::vector<MYSQL_BIND>& bind,
214 std::vector<my_bools>&
error) {
215 for (
size_t i = 0; i <
error.size(); ++i) {
234 static std::string getColumnsInError(std::vector<my_bools>&
error,
235 const std::vector<std::string>& names) {
236 std::string result =
"";
239 for (
size_t i = 0; i < names.size(); ++i) {
241 if (!result.empty()) {
248 if (result.empty()) {
267 std::vector<MYSQL_BIND> createBindForSend(
const HostPtr& host,
const bool unique_ip) {
275 memset(&bind_[0], 0,
sizeof(MYSQL_BIND) * bind_.size());
284 bind_[0].buffer_type = MYSQL_TYPE_LONG;
285 bind_[0].buffer =
reinterpret_cast<char*
>(&host_id_);
289 dhcp_identifier_length_ = host->getIdentifier().size();
290 memcpy(
static_cast<void*
>(dhcp_identifier_buffer_),
291 &(host->getIdentifier())[0],
292 host->getIdentifier().size());
294 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
295 bind_[1].buffer = dhcp_identifier_buffer_;
296 bind_[1].buffer_length = dhcp_identifier_length_;
297 bind_[1].length = &dhcp_identifier_length_;
300 dhcp_identifier_type_ =
static_cast<uint8_t
>(host->getIdentifierType());
301 bind_[2].buffer_type = MYSQL_TYPE_TINY;
302 bind_[2].buffer =
reinterpret_cast<char*
>(&dhcp_identifier_type_);
308 dhcp4_subnet_id_ = host->getIPv4SubnetID();
309 dhcp4_subnet_id_null_ = host->getIPv4SubnetID() == SUBNET_ID_UNUSED ?
MLM_TRUE :
MLM_FALSE;
310 bind_[3].buffer_type = MYSQL_TYPE_LONG;
311 bind_[3].buffer =
reinterpret_cast<char*
>(&dhcp4_subnet_id_);
313 bind_[3].is_null = &dhcp4_subnet_id_null_;
318 dhcp6_subnet_id_ = host->getIPv6SubnetID();
319 dhcp6_subnet_id_null_ = host->getIPv6SubnetID() == SUBNET_ID_UNUSED ?
MLM_TRUE :
MLM_FALSE;
320 bind_[4].buffer_type = MYSQL_TYPE_LONG;
321 bind_[4].buffer =
reinterpret_cast<char*
>(&dhcp6_subnet_id_);
323 bind_[4].is_null = &dhcp6_subnet_id_null_;
328 ipv4_address_ = host->getIPv4Reservation().toUint32();
330 bind_[5].buffer_type = MYSQL_TYPE_LONG;
331 bind_[5].buffer =
reinterpret_cast<char*
>(&ipv4_address_);
333 bind_[5].is_null = &ipv4_address_null_;
337 hostname_length_ = host->getHostname().length();
338 bind_[6].buffer_type = MYSQL_TYPE_STRING;
339 bind_[6].buffer =
reinterpret_cast<char*
>(hostname_);
340 bind_[6].buffer_length = hostname_length_;
343 bind_[7].buffer_type = MYSQL_TYPE_STRING;
345 string classes4_txt = host->getClientClasses4().toText(
",");
347 bind_[7].buffer = dhcp4_client_classes_;
348 bind_[7].buffer_length = classes4_txt.length();
351 bind_[8].buffer_type = MYSQL_TYPE_STRING;
353 string classes6_txt = host->getClientClasses6().toText(
",");
355 bind_[8].buffer = dhcp6_client_classes_;
356 bind_[8].buffer_length = classes6_txt.length();
361 bind_[9].buffer_type = MYSQL_TYPE_STRING;
362 string ctx_txt = ctx->str();
364 bind_[9].buffer = user_context_;
365 bind_[9].buffer_length = ctx_txt.length();
367 bind_[9].buffer_type = MYSQL_TYPE_NULL;
373 dhcp4_next_server_ = host->getNextServer().toUint32();
374 bind_[10].buffer_type = MYSQL_TYPE_LONG;
375 bind_[10].buffer =
reinterpret_cast<char*
>(&dhcp4_next_server_);
381 bind_[11].buffer_type = MYSQL_TYPE_STRING;
382 std::string server_hostname = host->getServerHostname();
383 strncpy(dhcp4_server_hostname_, server_hostname.c_str(),
385 bind_[11].buffer = dhcp4_server_hostname_;
386 bind_[11].buffer_length = server_hostname.length();
389 bind_[12].buffer_type = MYSQL_TYPE_STRING;
390 std::string boot_file_name = host->getBootFileName();
391 strncpy(dhcp4_boot_file_name_, boot_file_name.c_str(),
393 bind_[12].buffer = dhcp4_boot_file_name_;
394 bind_[12].buffer_length = boot_file_name.length();
397 bind_[13].buffer_type = MYSQL_TYPE_STRING;
398 std::string auth_key = host->getKey().toText();
401 bind_[13].buffer = auth_key_;
402 bind_[13].buffer_length = auth_key.length();
404 }
catch (
const std::exception& ex) {
406 "Could not create bind array from Host: "
407 << host->getHostname() <<
", reason: " << ex.
what());
411 std::vector<MYSQL_BIND> vec(bind_.begin(), bind_.begin() + HOST_COLUMNS);
417 vec.push_back(bind_[5]);
418 vec.push_back(bind_[3]);
430 virtual std::vector<MYSQL_BIND> createBindForReceive() {
437 memset(&bind_[0], 0,
sizeof(MYSQL_BIND) * bind_.size());
440 bind_[0].buffer_type = MYSQL_TYPE_LONG;
441 bind_[0].buffer =
reinterpret_cast<char*
>(&host_id_);
445 dhcp_identifier_length_ =
sizeof(dhcp_identifier_buffer_);
446 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
447 bind_[1].buffer =
reinterpret_cast<char*
>(dhcp_identifier_buffer_);
448 bind_[1].buffer_length = dhcp_identifier_length_;
449 bind_[1].length = &dhcp_identifier_length_;
452 bind_[2].buffer_type = MYSQL_TYPE_TINY;
453 bind_[2].buffer =
reinterpret_cast<char*
>(&dhcp_identifier_type_);
458 bind_[3].buffer_type = MYSQL_TYPE_LONG;
459 bind_[3].buffer =
reinterpret_cast<char*
>(&dhcp4_subnet_id_);
461 bind_[3].is_null = &dhcp4_subnet_id_null_;
465 bind_[4].buffer_type = MYSQL_TYPE_LONG;
466 bind_[4].buffer =
reinterpret_cast<char*
>(&dhcp6_subnet_id_);
468 bind_[4].is_null = &dhcp6_subnet_id_null_;
472 bind_[5].buffer_type = MYSQL_TYPE_LONG;
473 bind_[5].buffer =
reinterpret_cast<char*
>(&ipv4_address_);
475 bind_[5].is_null = &ipv4_address_null_;
479 hostname_length_ =
sizeof(hostname_);
480 bind_[6].buffer_type = MYSQL_TYPE_STRING;
481 bind_[6].buffer =
reinterpret_cast<char*
>(hostname_);
482 bind_[6].buffer_length = hostname_length_;
483 bind_[6].length = &hostname_length_;
484 bind_[6].is_null = &hostname_null_;
488 dhcp4_client_classes_length_ =
sizeof(dhcp4_client_classes_);
489 bind_[7].buffer_type = MYSQL_TYPE_STRING;
490 bind_[7].buffer =
reinterpret_cast<char*
>(dhcp4_client_classes_);
491 bind_[7].buffer_length = dhcp4_client_classes_length_;
492 bind_[7].length = &dhcp4_client_classes_length_;
493 bind_[7].is_null = &dhcp4_client_classes_null_;
497 dhcp6_client_classes_length_ =
sizeof(dhcp6_client_classes_);
498 bind_[8].buffer_type = MYSQL_TYPE_STRING;
499 bind_[8].buffer =
reinterpret_cast<char*
>(dhcp6_client_classes_);
500 bind_[8].buffer_length = dhcp6_client_classes_length_;
501 bind_[8].length = &dhcp6_client_classes_length_;
502 bind_[8].is_null = &dhcp6_client_classes_null_;
506 user_context_length_ =
sizeof(user_context_);
507 bind_[9].buffer_type = MYSQL_TYPE_STRING;
508 bind_[9].buffer =
reinterpret_cast<char*
>(user_context_);
509 bind_[9].buffer_length = user_context_length_;
510 bind_[9].length = &user_context_length_;
511 bind_[9].is_null = &user_context_null_;
515 bind_[10].buffer_type = MYSQL_TYPE_LONG;
516 bind_[10].buffer =
reinterpret_cast<char*
>(&dhcp4_next_server_);
518 bind_[10].is_null = &dhcp4_next_server_null_;
522 dhcp4_server_hostname_length_ =
sizeof(dhcp4_server_hostname_);
523 bind_[11].buffer_type = MYSQL_TYPE_STRING;
524 bind_[11].buffer =
reinterpret_cast<char*
>(dhcp4_server_hostname_);
525 bind_[11].buffer_length = dhcp4_server_hostname_length_;
526 bind_[11].length = &dhcp4_server_hostname_length_;
527 bind_[11].is_null = &dhcp4_server_hostname_null_;
531 dhcp4_boot_file_name_length_ =
sizeof(dhcp4_boot_file_name_);
532 bind_[12].buffer_type = MYSQL_TYPE_STRING;
533 bind_[12].buffer =
reinterpret_cast<char*
>(dhcp4_boot_file_name_);
534 bind_[12].buffer_length = dhcp4_boot_file_name_length_;
535 bind_[12].length = &dhcp4_boot_file_name_length_;
536 bind_[12].is_null = &dhcp4_boot_file_name_null_;
540 auth_key_length_ =
sizeof(auth_key_);
541 bind_[13].buffer_type = MYSQL_TYPE_STRING;
542 bind_[13].buffer =
reinterpret_cast<char*
>(auth_key_);
543 bind_[13].buffer_length = auth_key_length_;
544 bind_[13].length = &auth_key_length_;
545 bind_[13].is_null = &auth_key_null_;
548 setErrorIndicators(bind_, error_);
565 if (dhcp_identifier_type_ > MAX_IDENTIFIER_TYPE) {
567 <<
static_cast<int>(dhcp_identifier_type_));
576 SubnetID ipv4_subnet_id(SUBNET_ID_UNUSED);
577 if (dhcp4_subnet_id_null_ ==
MLM_FALSE) {
578 ipv4_subnet_id =
static_cast<SubnetID>(dhcp4_subnet_id_);
583 SubnetID ipv6_subnet_id(SUBNET_ID_UNUSED);
584 if (dhcp6_subnet_id_null_ ==
MLM_FALSE) {
585 ipv6_subnet_id =
static_cast<SubnetID>(dhcp6_subnet_id_);
592 ipv4_reservation = asiolink::IOAddress(ipv4_address_);
597 std::string hostname;
599 hostname = std::string(hostname_, hostname_length_);
603 std::string dhcp4_client_classes;
604 if (dhcp4_client_classes_null_ ==
MLM_FALSE) {
605 dhcp4_client_classes = std::string(dhcp4_client_classes_,
606 dhcp4_client_classes_length_);
610 std::string dhcp6_client_classes;
611 if (dhcp6_client_classes_null_ ==
MLM_FALSE) {
612 dhcp6_client_classes = std::string(dhcp6_client_classes_,
613 dhcp6_client_classes_length_);
617 std::string user_context;
619 user_context_[user_context_length_] =
'\0';
620 user_context.assign(user_context_);
625 if (dhcp4_next_server_null_ ==
MLM_FALSE) {
626 next_server = asiolink::IOAddress(dhcp4_next_server_);
630 std::string dhcp4_server_hostname;
631 if (dhcp4_server_hostname_null_ ==
MLM_FALSE) {
632 dhcp4_server_hostname = std::string(dhcp4_server_hostname_,
633 dhcp4_server_hostname_length_);
637 std::string dhcp4_boot_file_name;
638 if (dhcp4_boot_file_name_null_ ==
MLM_FALSE) {
639 dhcp4_boot_file_name = std::string(dhcp4_boot_file_name_,
640 dhcp4_boot_file_name_length_);
644 std::string auth_key;
646 auth_key = std::string(auth_key_, auth_key_length_);
650 HostPtr h(
new Host(dhcp_identifier_buffer_, dhcp_identifier_length_,
651 type, ipv4_subnet_id, ipv6_subnet_id, ipv4_reservation,
652 hostname, dhcp4_client_classes, dhcp6_client_classes,
653 next_server, dhcp4_server_hostname,
654 dhcp4_boot_file_name,
AuthKey(auth_key)));
655 h->setHostId(host_id_);
658 if (!user_context.empty()) {
661 if (!ctx || (ctx->getType() != Element::map)) {
663 <<
"' is not a JSON map");
668 <<
"' is invalid JSON: " << ex.
what());
693 if (hosts.empty() || (hosts.back()->getHostId() != getHostId())) {
696 host = retrieveHost();
697 hosts.push_back(host);
711 std::string getErrorColumns() {
712 return (getColumnsInError(error_, columns_));
721 std::vector<MYSQL_BIND> bind_;
724 std::vector<std::string> columns_;
727 std::vector<my_bools> error_;
740 uint8_t dhcp_identifier_buffer_[ClientId::MAX_CLIENT_ID_LEN];
743 unsigned long dhcp_identifier_length_;
747 uint8_t dhcp_identifier_type_;
750 uint32_t dhcp4_subnet_id_;
753 uint32_t dhcp6_subnet_id_;
756 uint32_t ipv4_address_;
762 unsigned long hostname_length_;
769 unsigned long dhcp4_client_classes_length_;
776 unsigned long dhcp6_client_classes_length_;
782 unsigned long user_context_length_;
785 uint32_t dhcp4_next_server_;
791 unsigned long dhcp4_server_hostname_length_;
797 unsigned long dhcp4_boot_file_name_length_;
803 unsigned long auth_key_length_;
822 my_bool dhcp4_client_classes_null_;
826 my_bool dhcp6_client_classes_null_;
832 my_bool dhcp4_next_server_null_;
835 my_bool dhcp4_server_hostname_null_;
838 my_bool dhcp4_boot_file_name_null_;
855 class MySqlHostWithOptionsExchange :
public MySqlHostExchange {
859 static const size_t OPTION_COLUMNS = 8;
875 class OptionProcessor {
885 const size_t start_column)
886 : universe_(universe), start_column_(start_column), option_id_(0),
887 code_(0), value_length_(0), formatted_value_length_(0),
888 space_length_(0), persistent_(false), cancelled_(false),
889 user_context_length_(0),
893 option_id_index_(start_column), code_index_(start_column_ + 1),
894 value_index_(start_column_ + 2),
895 formatted_value_index_(start_column_ + 3),
896 space_index_(start_column_ + 4),
897 persistent_index_(start_column_ + 5),
898 cancelled_index_(start_column_ + 6),
899 user_context_index_(start_column_ + 7),
900 most_recent_option_id_(0) {
902 memset(value_, 0,
sizeof(value_));
903 memset(formatted_value_, 0,
sizeof(formatted_value_));
904 memset(space_, 0,
sizeof(space_));
905 memset(user_context_, 0,
sizeof(user_context_));
909 uint64_t getOptionId()
const {
934 if ((option_id_null_ ==
MLM_TRUE) ||
935 (most_recent_option_id_ >= option_id_)) {
941 most_recent_option_id_ = option_id_;
948 space_[space_length_] =
'\0';
949 space.assign(space_);
954 space = (universe_ == Option::V4 ?
959 std::string formatted_value;
960 if (formatted_value_null_ ==
MLM_FALSE) {
961 formatted_value_[formatted_value_length_] =
'\0';
962 formatted_value.assign(formatted_value_);
966 std::string user_context;
968 user_context_[user_context_length_] =
'\0';
969 user_context.assign(user_context_);
985 uint32_t vendor_id = LibDHCP::optionSpaceToVendorId(space);
987 def = LibDHCP::getVendorOptionDef(universe_, vendor_id,
code_);
994 def = LibDHCP::getRuntimeOptionDef(space,
code_);
999 def = LibDHCP::getLastResortOptionDef(space,
code_);
1013 option.reset(
new Option(universe_,
code_, buf.begin(),
1023 if (formatted_value.empty()) {
1027 option = def->optionFactory(universe_,
code_, buf.begin(),
1033 std::vector<std::string> split_vec;
1034 boost::split(split_vec, formatted_value, boost::is_any_of(
","));
1035 option = def->optionFactory(universe_,
code_, split_vec);
1043 if (!user_context.empty()) {
1046 if (!ctx || (ctx->getType() != Element::map)) {
1048 <<
"' is no a JSON map");
1050 desc.setContext(ctx);
1053 <<
"' is invalid JSON: " << ex.
what());
1056 cfg->add(desc, space);
1063 void setColumnNames(std::vector<std::string>& columns) {
1064 columns[option_id_index_] =
"option_id";
1065 columns[code_index_] =
"code";
1066 columns[value_index_] =
"value";
1067 columns[formatted_value_index_] =
"formatted_value";
1068 columns[space_index_] =
"space";
1069 columns[persistent_index_] =
"persistent";
1070 columns[cancelled_index_] =
"cancelled";
1071 columns[user_context_index_] =
"user_context";
1080 void setBindFields(std::vector<MYSQL_BIND>& bind) {
1084 most_recent_option_id_ = 0;
1088 persistent_ =
false;
1097 memset(value_, 0,
sizeof(value_));
1098 memset(formatted_value_, 0,
sizeof(formatted_value_));
1099 memset(space_, 0,
sizeof(space_));
1100 memset(user_context_, 0,
sizeof(user_context_));
1103 bind[option_id_index_].buffer_type = MYSQL_TYPE_LONG;
1104 bind[option_id_index_].buffer =
reinterpret_cast<char*
>(&option_id_);
1105 bind[option_id_index_].is_unsigned =
MLM_TRUE;
1106 bind[option_id_index_].is_null = &option_id_null_;
1109 bind[code_index_].buffer_type = MYSQL_TYPE_SHORT;
1110 bind[code_index_].buffer =
reinterpret_cast<char*
>(&
code_);
1111 bind[code_index_].is_unsigned =
MLM_TRUE;
1112 bind[code_index_].is_null = &code_null_;
1115 value_length_ =
sizeof(value_);
1116 bind[value_index_].buffer_type = MYSQL_TYPE_BLOB;
1117 bind[value_index_].buffer =
reinterpret_cast<char*
>(value_);
1118 bind[value_index_].buffer_length = value_length_;
1119 bind[value_index_].length = &value_length_;
1120 bind[value_index_].is_null = &value_null_;
1123 formatted_value_length_ =
sizeof(formatted_value_);
1124 bind[formatted_value_index_].buffer_type = MYSQL_TYPE_STRING;
1125 bind[formatted_value_index_].buffer =
reinterpret_cast<char*
>(formatted_value_);
1126 bind[formatted_value_index_].buffer_length = formatted_value_length_;
1127 bind[formatted_value_index_].length = &formatted_value_length_;
1128 bind[formatted_value_index_].is_null = &formatted_value_null_;
1131 space_length_ =
sizeof(space_);
1132 bind[space_index_].buffer_type = MYSQL_TYPE_STRING;
1133 bind[space_index_].buffer =
reinterpret_cast<char*
>(space_);
1134 bind[space_index_].buffer_length = space_length_;
1135 bind[space_index_].length = &space_length_;
1136 bind[space_index_].is_null = &space_null_;
1139 bind[persistent_index_].buffer_type = MYSQL_TYPE_TINY;
1140 bind[persistent_index_].buffer =
reinterpret_cast<char*
>(&persistent_);
1141 bind[persistent_index_].is_unsigned =
MLM_TRUE;
1144 bind[cancelled_index_].buffer_type = MYSQL_TYPE_TINY;
1145 bind[cancelled_index_].buffer =
reinterpret_cast<char*
>(&cancelled_);
1146 bind[cancelled_index_].is_unsigned =
MLM_TRUE;
1149 user_context_length_ =
sizeof(user_context_);
1150 bind[user_context_index_].buffer_type = MYSQL_TYPE_STRING;
1151 bind[user_context_index_].buffer =
reinterpret_cast<char*
>(user_context_);
1152 bind[user_context_index_].buffer_length = user_context_length_;
1153 bind[user_context_index_].length = &user_context_length_;
1154 bind[user_context_index_].is_null = &user_context_null_;
1163 size_t start_column_;
1166 uint32_t option_id_;
1175 unsigned long value_length_;
1181 unsigned long formatted_value_length_;
1187 unsigned long space_length_;
1200 unsigned long user_context_length_;
1216 my_bool formatted_value_null_;
1227 size_t option_id_index_;
1234 size_t value_index_;
1237 size_t formatted_value_index_;
1240 size_t space_index_;
1243 size_t persistent_index_;
1246 size_t cancelled_index_;
1250 size_t user_context_index_;
1253 uint32_t most_recent_option_id_;
1257 typedef boost::shared_ptr<OptionProcessor> OptionProcessorPtr;
1267 enum FetchedOptions {
1281 MySqlHostWithOptionsExchange(
const FetchedOptions& fetched_options,
1282 const size_t additional_columns_num = 0)
1283 : MySqlHostExchange(getRequiredColumnsNum(fetched_options)
1284 + additional_columns_num),
1285 opt_proc4_(), opt_proc6_() {
1288 if ((fetched_options == DHCP4_ONLY) ||
1289 (fetched_options == DHCP4_AND_DHCP6)) {
1290 opt_proc4_.reset(
new OptionProcessor(Option::V4,
1291 findAvailColumn()));
1292 opt_proc4_->setColumnNames(columns_);
1296 if ((fetched_options == DHCP6_ONLY) ||
1297 (fetched_options == DHCP4_AND_DHCP6)) {
1298 opt_proc6_.reset(
new OptionProcessor(Option::V6,
1299 findAvailColumn()));
1300 opt_proc6_->setColumnNames(columns_);
1315 if (!hosts.empty()) {
1324 most_recent_host = boost::const_pointer_cast<Host>(hosts.back());
1330 if (!most_recent_host || (most_recent_host->getHostId() < getHostId())) {
1331 HostPtr host = retrieveHost();
1332 hosts.push_back(host);
1333 most_recent_host = host;
1339 opt_proc4_->retrieveOption(cfg);
1345 opt_proc6_->retrieveOption(cfg);
1352 virtual std::vector<MYSQL_BIND> createBindForReceive() {
1354 static_cast<void>(MySqlHostExchange::createBindForReceive());
1358 opt_proc4_->setBindFields(bind_);
1363 opt_proc6_->setBindFields(bind_);
1367 setErrorIndicators(bind_, error_);
1385 static size_t getRequiredColumnsNum(
const FetchedOptions& fetched_options) {
1386 return (fetched_options == DHCP4_AND_DHCP6 ? 2 * OPTION_COLUMNS :
1393 OptionProcessorPtr opt_proc4_;
1398 OptionProcessorPtr opt_proc6_;
1413 class MySqlHostIPv6Exchange :
public MySqlHostWithOptionsExchange {
1417 static const size_t RESERVATION_COLUMNS = 5;
1425 MySqlHostIPv6Exchange(
const FetchedOptions& fetched_options)
1426 : MySqlHostWithOptionsExchange(fetched_options, RESERVATION_COLUMNS),
1428 reserv_type_(0), reserv_type_null_(
MLM_FALSE),
1429 ipv6_address_buffer_len_(0), prefix_len_(0), iaid_(0),
1430 reservation_id_index_(findAvailColumn()),
1431 address_index_(reservation_id_index_ + 1),
1432 prefix_len_index_(reservation_id_index_ + 2),
1433 type_index_(reservation_id_index_ + 3),
1434 iaid_index_(reservation_id_index_ + 4),
1435 most_recent_reservation_id_(0) {
1437 memset(ipv6_address_buffer_, 0,
sizeof(ipv6_address_buffer_));
1440 columns_[reservation_id_index_] =
"reservation_id";
1441 columns_[address_index_] =
"address";
1442 columns_[prefix_len_index_] =
"prefix_len";
1443 columns_[type_index_] =
"type";
1444 columns_[iaid_index_] =
"dhcp6_iaid";
1450 uint32_t getReservationId()
const {
1452 return (reservation_id_);
1467 switch (reserv_type_) {
1469 type = IPv6Resrv::TYPE_NA;
1473 type = IPv6Resrv::TYPE_PD;
1478 "invalid IPv6 reservation type returned: "
1479 <<
static_cast<int>(reserv_type_)
1480 <<
". Only 0 or 2 are allowed.");
1510 MySqlHostWithOptionsExchange::processFetchedData(hosts);
1512 if (getReservationId() == 0) {
1516 if (hosts.empty()) {
1518 " IPv6 reservation");
1520 HostPtr host = boost::const_pointer_cast<Host>(hosts.back());
1524 if (getReservationId() > most_recent_reservation_id_) {
1525 most_recent_reservation_id_ = getReservationId();
1527 if (most_recent_reservation_id_ > 0) {
1528 host->addReservation(retrieveReservation());
1541 virtual std::vector<MYSQL_BIND> createBindForReceive() {
1544 most_recent_reservation_id_ = 0;
1547 static_cast<void>(MySqlHostWithOptionsExchange::createBindForReceive());
1550 bind_[reservation_id_index_].buffer_type = MYSQL_TYPE_LONG;
1551 bind_[reservation_id_index_].buffer =
reinterpret_cast<char*
>(&reservation_id_);
1552 bind_[reservation_id_index_].is_unsigned =
MLM_TRUE;
1555 ipv6_address_buffer_len_ = isc::asiolink::V6ADDRESS_LEN;
1556 bind_[address_index_].buffer_type = MYSQL_TYPE_BLOB;
1557 bind_[address_index_].buffer =
reinterpret_cast<char*
>(ipv6_address_buffer_);
1558 bind_[address_index_].buffer_length = ipv6_address_buffer_len_;
1559 bind_[address_index_].length = &ipv6_address_buffer_len_;
1562 bind_[prefix_len_index_].buffer_type = MYSQL_TYPE_TINY;
1563 bind_[prefix_len_index_].buffer =
reinterpret_cast<char*
>(&prefix_len_);
1564 bind_[prefix_len_index_].is_unsigned =
MLM_TRUE;
1568 bind_[type_index_].buffer_type = MYSQL_TYPE_TINY;
1569 bind_[type_index_].buffer =
reinterpret_cast<char*
>(&reserv_type_);
1570 bind_[type_index_].is_unsigned =
MLM_TRUE;
1571 bind_[type_index_].is_null = &reserv_type_null_;
1574 bind_[iaid_index_].buffer_type = MYSQL_TYPE_LONG;
1575 bind_[iaid_index_].buffer =
reinterpret_cast<char*
>(&iaid_);
1576 bind_[iaid_index_].is_unsigned =
MLM_TRUE;
1579 setErrorIndicators(bind_, error_);
1587 uint32_t reservation_id_;
1590 uint8_t reserv_type_;
1599 uint8_t ipv6_address_buffer_[isc::asiolink::V6ADDRESS_LEN];
1602 unsigned long ipv6_address_buffer_len_;
1605 uint8_t prefix_len_;
1612 size_t reservation_id_index_;
1616 size_t address_index_;
1619 size_t prefix_len_index_;
1630 uint32_t most_recent_reservation_id_;
1643 class MySqlIPv6ReservationExchange {
1647 static const size_t RESRV_COLUMNS = 6;
1654 MySqlIPv6ReservationExchange()
1655 : host_id_(0), prefix_len_(0), type_(0),
1659 std::fill(&error_[0], &error_[RESRV_COLUMNS],
MLM_FALSE);
1662 columns_[0] =
"host_id";
1663 columns_[1] =
"address";
1664 columns_[2] =
"prefix_len";
1665 columns_[3] =
"type";
1666 columns_[4] =
"dhcp6_iaid";
1668 BOOST_STATIC_ASSERT(4 < RESRV_COLUMNS);
1685 std::vector<MYSQL_BIND> createBindForSend(
const IPv6Resrv& resv,
1687 const bool unique_ip) {
1698 memset(bind_, 0,
sizeof(bind_));
1704 if (addr6_.size() != isc::asiolink::V6ADDRESS_LEN) {
1706 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
1709 addr6_length_ = isc::asiolink::V6ADDRESS_LEN;
1710 bind_[0].buffer_type = MYSQL_TYPE_BLOB;
1711 bind_[0].buffer =
reinterpret_cast<char*
>(&addr6_[0]);
1712 bind_[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
1713 bind_[0].length = &addr6_length_;
1717 bind_[1].buffer_type = MYSQL_TYPE_TINY;
1718 bind_[1].buffer =
reinterpret_cast<char*
>(&prefix_len_);
1723 type_ = resv.
getType() == IPv6Resrv::TYPE_NA ? 0 : 2;
1724 bind_[2].buffer_type = MYSQL_TYPE_TINY;
1725 bind_[2].buffer =
reinterpret_cast<char*
>(&type_);
1731 bind_[3].buffer_type = MYSQL_TYPE_LONG;
1732 bind_[3].buffer =
reinterpret_cast<char*
>(&iaid_);
1736 bind_[4].buffer_type = MYSQL_TYPE_LONG;
1737 bind_[4].buffer =
reinterpret_cast<char*
>(&host_id_);
1740 }
catch (
const std::exception& ex) {
1742 "Could not create bind array from IPv6 Reservation: "
1743 << resv_.toText() <<
", reason: " << ex.
what());
1749 std::vector<MYSQL_BIND> vec(&bind_[0], &bind_[RESRV_COLUMNS-1]);
1755 vec.push_back(bind_[0]);
1756 vec.push_back(bind_[1]);
1768 uint8_t prefix_len_;
1780 MYSQL_BIND bind_[RESRV_COLUMNS];
1783 std::string columns_[RESRV_COLUMNS];
1787 my_bool error_[RESRV_COLUMNS];
1790 std::vector<uint8_t> addr6_;
1793 unsigned long addr6_length_;
1799 class MySqlOptionExchange {
1802 static const size_t OPTION_ID_COL = 0;
1803 static const size_t CODE_COL = 1;
1804 static const size_t VALUE_COL = 2;
1805 static const size_t FORMATTED_VALUE_COL = 3;
1806 static const size_t SPACE_COL = 4;
1807 static const size_t PERSISTENT_COL = 5;
1808 static const size_t CANCELLED_COL = 6;
1809 static const size_t USER_CONTEXT_COL = 7;
1810 static const size_t DHCP_SUBNET_ID_COL = 8;
1811 static const size_t HOST_ID_COL = 9;
1813 static const size_t OPTION_COLUMNS = 10;
1818 MySqlOptionExchange()
1819 : type_(0), value_len_(0), formatted_value_len_(0), space_(),
1820 space_len_(0), persistent_(false), cancelled_(false),
1821 user_context_(), user_context_len_(0), subnet_id_(SUBNET_ID_UNUSED),
1822 host_id_(0), option_() {
1824 BOOST_STATIC_ASSERT(10 <= OPTION_COLUMNS);
1830 std::vector<MYSQL_BIND> createBindForSend(
const OptionDescriptor& opt_desc,
1831 const std::string& opt_space,
1839 memset(bind_, 0,
sizeof(bind_));
1845 bind_[0].buffer_type = MYSQL_TYPE_NULL;
1848 type_ = option_->getType();
1849 bind_[1].buffer_type = MYSQL_TYPE_SHORT;
1850 bind_[1].buffer =
reinterpret_cast<char*
>(&type_);
1861 const char* buf_ptr =
static_cast<const char*
>(buf.getData());
1862 value_.assign(buf_ptr + opt_desc.
option_->getHeaderLen(),
1863 buf_ptr + buf.getLength());
1864 value_len_ = value_.size();
1865 bind_[2].buffer_type = MYSQL_TYPE_BLOB;
1866 bind_[2].buffer = &value_[0];
1867 bind_[2].buffer_length = value_len_;
1868 bind_[2].length = &value_len_;
1874 bind_[2].buffer_type = MYSQL_TYPE_NULL;
1880 bind_[3].buffer_type = MYSQL_TYPE_STRING;
1882 bind_[3].buffer_length = formatted_value_len_;
1883 bind_[3].length = &formatted_value_len_;
1886 bind_[3].buffer_type = MYSQL_TYPE_NULL;
1891 space_len_ = space_.size();
1892 bind_[4].buffer_type = MYSQL_TYPE_STRING;
1893 bind_[4].buffer =
const_cast<char*
>(space_.c_str());
1894 bind_[4].buffer_length = space_len_;
1895 bind_[4].length = &space_len_;
1899 bind_[5].buffer_type = MYSQL_TYPE_TINY;
1900 bind_[5].buffer =
reinterpret_cast<char*
>(&persistent_);
1905 bind_[6].buffer_type = MYSQL_TYPE_TINY;
1906 bind_[6].buffer =
reinterpret_cast<char*
>(&cancelled_);
1912 user_context_ = ctx->str();
1913 user_context_len_ = user_context_.size();
1914 bind_[7].buffer_type = MYSQL_TYPE_STRING;
1915 bind_[7].buffer =
const_cast<char*
>(user_context_.c_str());
1916 bind_[7].buffer_length = user_context_len_;
1917 bind_[7].length = &user_context_len_;
1919 bind_[7].buffer_type = MYSQL_TYPE_NULL;
1924 subnet_id_ = subnet_id;
1925 bind_[8].buffer_type = MYSQL_TYPE_LONG;
1926 bind_[8].buffer =
reinterpret_cast<char*
>(subnet_id_);
1930 bind_[8].buffer_type = MYSQL_TYPE_NULL;
1935 bind_[9].buffer_type = MYSQL_TYPE_LONG;
1936 bind_[9].buffer =
reinterpret_cast<char*
>(&host_id_);
1939 }
catch (
const std::exception& ex) {
1941 "Could not create bind array for inserting DHCP "
1942 "option: " << option_->toText() <<
", reason: "
1946 return (std::vector<MYSQL_BIND>(&bind_[0], &bind_[OPTION_COLUMNS]));
1955 std::vector<uint8_t> value_;
1958 unsigned long value_len_;
1961 unsigned long formatted_value_len_;
1967 unsigned long space_len_;
1978 std::string user_context_;
1981 unsigned long user_context_len_;
1984 uint32_t subnet_id_;
1993 MYSQL_BIND bind_[OPTION_COLUMNS];
2180 std::pair<uint32_t, uint32_t> getVersion()
const;
2192 std::vector<MYSQL_BIND>& bind);
2227 const std::string& opt_space,
2241 const uint64_t host_id);
2257 const char* what)
const;
2280 boost::shared_ptr<MySqlHostExchange> exchange,
2304 const uint8_t* identifier_begin,
2305 const size_t identifier_len,
2307 boost::shared_ptr<MySqlHostExchange> exchange)
const;
2341 typedef boost::array<TaggedStatement, MySqlHostDataSourceImpl::NUM_STATEMENTS>
2342 TaggedStatementArray;
2346 TaggedStatementArray tagged_statements = { {
2351 {MySqlHostDataSourceImpl::GET_HOST_DHCPID,
2352 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2353 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, "
2354 "h.hostname, h.dhcp4_client_classes, h.dhcp6_client_classes, "
2356 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2357 "h.dhcp4_boot_file_name, h.auth_key, "
2358 "o4.option_id, o4.code, o4.value, o4.formatted_value, o4.space, "
2359 "o4.persistent, o4.cancelled, o4.user_context, "
2360 "o6.option_id, o6.code, o6.value, o6.formatted_value, o6.space, "
2361 "o6.persistent, o6.cancelled, o6.user_context, "
2362 "r.reservation_id, r.address, r.prefix_len, r.type, "
2365 "LEFT JOIN dhcp4_options AS o4 "
2366 "ON h.host_id = o4.host_id "
2367 "LEFT JOIN dhcp6_options AS o6 "
2368 "ON h.host_id = o6.host_id "
2369 "LEFT JOIN ipv6_reservations AS r "
2370 "ON h.host_id = r.host_id "
2371 "WHERE dhcp_identifier = ? AND dhcp_identifier_type = ? "
2372 "ORDER BY h.host_id, o4.option_id, o6.option_id, r.reservation_id"},
2377 {MySqlHostDataSourceImpl::GET_HOST_ADDR,
2378 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2379 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2380 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2381 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2382 "h.dhcp4_boot_file_name, h.auth_key, "
2383 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2384 "o.persistent, o.cancelled, o.user_context "
2386 "LEFT JOIN dhcp4_options AS o "
2387 "ON h.host_id = o.host_id "
2388 "WHERE ipv4_address = ? "
2389 "ORDER BY h.host_id, o.option_id"},
2394 {MySqlHostDataSourceImpl::GET_HOST_SUBID4_DHCPID,
2395 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2396 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2397 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2398 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2399 "h.dhcp4_boot_file_name, h.auth_key, "
2400 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2401 "o.persistent, o.cancelled, o.user_context "
2403 "LEFT JOIN dhcp4_options AS o "
2404 "ON h.host_id = o.host_id "
2405 "WHERE h.dhcp4_subnet_id = ? AND h.dhcp_identifier_type = ? "
2406 "AND h.dhcp_identifier = ? "
2407 "ORDER BY h.host_id, o.option_id"},
2412 {MySqlHostDataSourceImpl::GET_HOST_SUBID6_DHCPID,
2413 "SELECT h.host_id, h.dhcp_identifier, "
2414 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2415 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2416 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2417 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2418 "h.dhcp4_boot_file_name, h.auth_key, "
2419 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2420 "o.persistent, o.cancelled, o.user_context, "
2421 "r.reservation_id, r.address, r.prefix_len, r.type, "
2424 "LEFT JOIN dhcp6_options AS o "
2425 "ON h.host_id = o.host_id "
2426 "LEFT JOIN ipv6_reservations AS r "
2427 "ON h.host_id = r.host_id "
2428 "WHERE h.dhcp6_subnet_id = ? AND h.dhcp_identifier_type = ? "
2429 "AND h.dhcp_identifier = ? "
2430 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2436 {MySqlHostDataSourceImpl::GET_HOST_SUBID_ADDR,
2437 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2438 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2439 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2440 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2441 "h.dhcp4_boot_file_name, h.auth_key, "
2442 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2443 "o.persistent, o.cancelled, o.user_context "
2445 "LEFT JOIN dhcp4_options AS o "
2446 "ON h.host_id = o.host_id "
2447 "WHERE h.dhcp4_subnet_id = ? AND h.ipv4_address = ? "
2448 "ORDER BY h.host_id, o.option_id"},
2456 {MySqlHostDataSourceImpl::GET_HOST_PREFIX,
2457 "SELECT h.host_id, h.dhcp_identifier, "
2458 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2459 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2460 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2461 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2462 "h.dhcp4_boot_file_name, h.auth_key, "
2463 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2464 "o.persistent, o.cancelled, o.user_context,"
2465 "r.reservation_id, r.address, r.prefix_len, r.type, "
2468 "LEFT JOIN dhcp6_options AS o "
2469 "ON h.host_id = o.host_id "
2470 "LEFT JOIN ipv6_reservations AS r "
2471 "ON h.host_id = r.host_id "
2472 "WHERE h.host_id = "
2473 "( SELECT host_id FROM ipv6_reservations "
2474 "WHERE address = ? AND prefix_len = ? ) "
2475 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2483 {MySqlHostDataSourceImpl::GET_HOST_SUBID6_ADDR,
2484 "SELECT h.host_id, h.dhcp_identifier, "
2485 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2486 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2487 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2488 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2489 "h.dhcp4_boot_file_name, h.auth_key, "
2490 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2491 "o.persistent, o.cancelled, o.user_context, "
2492 "r.reservation_id, r.address, r.prefix_len, r.type, "
2495 "LEFT JOIN dhcp6_options AS o "
2496 "ON h.host_id = o.host_id "
2497 "LEFT JOIN ipv6_reservations AS r "
2498 "ON h.host_id = r.host_id "
2499 "WHERE h.dhcp6_subnet_id = ? AND h.host_id IN "
2500 "(SELECT host_id FROM ipv6_reservations "
2501 "WHERE address = ?) "
2502 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2511 {MySqlHostDataSourceImpl::GET_HOST_ADDR6,
2512 "SELECT h.host_id, h.dhcp_identifier, "
2513 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2514 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2515 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2516 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2517 "h.dhcp4_boot_file_name, h.auth_key, "
2518 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2519 "o.persistent, o.cancelled, o.user_context, "
2520 "r.reservation_id, r.address, r.prefix_len, r.type, "
2523 "LEFT JOIN dhcp6_options AS o "
2524 "ON h.host_id = o.host_id "
2525 "LEFT JOIN ipv6_reservations AS r "
2526 "ON h.host_id = r.host_id "
2527 "WHERE h.host_id IN "
2528 "(SELECT host_id FROM ipv6_reservations "
2529 "WHERE address = ?) "
2530 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2535 {MySqlHostDataSourceImpl::GET_HOST_SUBID4,
2536 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2537 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2538 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2539 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2540 "h.dhcp4_boot_file_name, h.auth_key, "
2541 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2542 "o.persistent, o.cancelled, o.user_context "
2544 "LEFT JOIN dhcp4_options AS o "
2545 "ON h.host_id = o.host_id "
2546 "WHERE h.dhcp4_subnet_id = ? "
2547 "ORDER BY h.host_id, o.option_id"},
2553 {MySqlHostDataSourceImpl::GET_HOST_SUBID6,
2554 "SELECT h.host_id, h.dhcp_identifier, "
2555 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2556 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2557 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2558 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2559 "h.dhcp4_boot_file_name, h.auth_key, "
2560 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2561 "o.persistent, o.cancelled, o.user_context, "
2562 "r.reservation_id, r.address, r.prefix_len, r.type, "
2565 "LEFT JOIN dhcp6_options AS o "
2566 "ON h.host_id = o.host_id "
2567 "LEFT JOIN ipv6_reservations AS r "
2568 "ON h.host_id = r.host_id "
2569 "WHERE h.dhcp6_subnet_id = ? "
2570 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2576 {MySqlHostDataSourceImpl::GET_HOST_HOSTNAME,
2577 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2578 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, "
2579 "h.hostname, h.dhcp4_client_classes, h.dhcp6_client_classes, "
2581 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2582 "h.dhcp4_boot_file_name, h.auth_key, "
2583 "o4.option_id, o4.code, o4.value, o4.formatted_value, o4.space, "
2584 "o4.persistent, o4.cancelled, o4.user_context, "
2585 "o6.option_id, o6.code, o6.value, o6.formatted_value, o6.space, "
2586 "o6.persistent, o6.cancelled, o6.user_context, "
2587 "r.reservation_id, r.address, r.prefix_len, r.type, "
2590 "LEFT JOIN dhcp4_options AS o4 "
2591 "ON h.host_id = o4.host_id "
2592 "LEFT JOIN dhcp6_options AS o6 "
2593 "ON h.host_id = o6.host_id "
2594 "LEFT JOIN ipv6_reservations AS r "
2595 "ON h.host_id = r.host_id "
2596 "WHERE h.hostname = ? "
2597 "ORDER BY h.host_id, o4.option_id, o6.option_id, r.reservation_id"},
2602 {MySqlHostDataSourceImpl::GET_HOST_HOSTNAME_SUBID4,
2603 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2604 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2605 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2606 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2607 "h.dhcp4_boot_file_name, h.auth_key, "
2608 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2609 "o.persistent, o.cancelled, o.user_context "
2611 "LEFT JOIN dhcp4_options AS o "
2612 "ON h.host_id = o.host_id "
2613 "WHERE h.hostname = ? AND h.dhcp4_subnet_id = ? "
2614 "ORDER BY h.host_id, o.option_id"},
2619 {MySqlHostDataSourceImpl::GET_HOST_HOSTNAME_SUBID6,
2620 "SELECT h.host_id, h.dhcp_identifier, "
2621 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2622 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2623 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2624 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2625 "h.dhcp4_boot_file_name, h.auth_key, "
2626 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2627 "o.persistent, o.cancelled, o.user_context, "
2628 "r.reservation_id, r.address, r.prefix_len, r.type, "
2631 "LEFT JOIN dhcp6_options AS o "
2632 "ON h.host_id = o.host_id "
2633 "LEFT JOIN ipv6_reservations AS r "
2634 "ON h.host_id = r.host_id "
2635 "WHERE h.hostname = ? AND h.dhcp6_subnet_id = ? "
2636 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2643 {MySqlHostDataSourceImpl::GET_HOST_SUBID4_PAGE,
2644 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2645 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2646 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2647 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2648 "h.dhcp4_boot_file_name, h.auth_key, "
2649 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2650 "o.persistent, o.cancelled, o.user_context "
2651 "FROM ( SELECT * FROM hosts AS h "
2652 "WHERE h.dhcp4_subnet_id = ? AND h.host_id > ? "
2653 "ORDER BY h.host_id "
2655 "LEFT JOIN dhcp4_options AS o "
2656 "ON h.host_id = o.host_id "
2657 "ORDER BY h.host_id, o.option_id"},
2664 {MySqlHostDataSourceImpl::GET_HOST_SUBID6_PAGE,
2665 "SELECT h.host_id, h.dhcp_identifier, "
2666 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2667 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2668 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2669 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2670 "h.dhcp4_boot_file_name, h.auth_key, "
2671 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2672 "o.persistent, o.cancelled, o.user_context, "
2673 "r.reservation_id, r.address, r.prefix_len, r.type, "
2675 "FROM ( SELECT * FROM hosts AS h "
2676 "WHERE h.dhcp6_subnet_id = ? AND h.host_id > ? "
2677 "ORDER BY h.host_id "
2679 "LEFT JOIN dhcp6_options AS o "
2680 "ON h.host_id = o.host_id "
2681 "LEFT JOIN ipv6_reservations AS r "
2682 "ON h.host_id = r.host_id "
2683 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2690 {MySqlHostDataSourceImpl::GET_HOST_PAGE4,
2691 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2692 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2693 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2694 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2695 "h.dhcp4_boot_file_name, h.auth_key, "
2696 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2697 "o.persistent, o.cancelled, o.user_context "
2698 "FROM ( SELECT * FROM hosts AS h "
2699 "WHERE h.host_id > ? "
2700 "ORDER BY h.host_id "
2702 "LEFT JOIN dhcp4_options AS o "
2703 "ON h.host_id = o.host_id "
2704 "ORDER BY h.host_id, o.option_id"},
2711 {MySqlHostDataSourceImpl::GET_HOST_PAGE6,
2712 "SELECT h.host_id, h.dhcp_identifier, "
2713 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2714 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2715 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2716 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2717 "h.dhcp4_boot_file_name, h.auth_key, "
2718 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2719 "o.persistent, o.cancelled, o.user_context, "
2720 "r.reservation_id, r.address, r.prefix_len, r.type, "
2722 "FROM ( SELECT * FROM hosts AS h "
2723 "WHERE h.host_id > ? "
2724 "ORDER BY h.host_id "
2726 "LEFT JOIN dhcp6_options AS o "
2727 "ON h.host_id = o.host_id "
2728 "LEFT JOIN ipv6_reservations AS r "
2729 "ON h.host_id = r.host_id "
2730 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2734 {MySqlHostDataSourceImpl::INSERT_HOST_NON_UNIQUE_IP,
2735 "INSERT INTO hosts(host_id, dhcp_identifier, dhcp_identifier_type, "
2736 "dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, "
2737 "dhcp4_client_classes, dhcp6_client_classes, "
2738 "user_context, dhcp4_next_server, "
2739 "dhcp4_server_hostname, dhcp4_boot_file_name, auth_key) "
2740 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
2753 {MySqlHostDataSourceImpl::INSERT_HOST_UNIQUE_IP,
2754 "INSERT INTO hosts(host_id, dhcp_identifier, dhcp_identifier_type, "
2755 "dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, "
2756 "dhcp4_client_classes, dhcp6_client_classes, "
2757 "user_context, dhcp4_next_server, "
2758 "dhcp4_server_hostname, dhcp4_boot_file_name, auth_key) "
2759 "SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? FROM DUAL "
2760 "WHERE NOT EXISTS ("
2761 "SELECT 1 FROM hosts "
2762 "WHERE ipv4_address = ? AND dhcp4_subnet_id = ? "
2768 {MySqlHostDataSourceImpl::INSERT_V6_RESRV_NON_UNIQUE,
2769 "INSERT INTO ipv6_reservations(address, prefix_len, type, "
2770 "dhcp6_iaid, host_id) "
2771 "VALUES (?, ?, ?, ?, ?)"},
2775 {MySqlHostDataSourceImpl::INSERT_V6_RESRV_UNIQUE,
2776 "INSERT INTO ipv6_reservations(address, prefix_len, type, "
2777 "dhcp6_iaid, host_id) "
2778 "SELECT ?, ?, ?, ?, ? FROM DUAL "
2779 "WHERE NOT EXISTS ("
2780 "SELECT 1 FROM ipv6_reservations "
2781 "WHERE address = ? AND prefix_len = ? "
2787 {MySqlHostDataSourceImpl::INSERT_V4_HOST_OPTION,
2788 "INSERT INTO dhcp4_options(option_id, code, value, formatted_value, space, "
2789 "persistent, cancelled, user_context, dhcp4_subnet_id, host_id, scope_id) "
2790 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 3)"},
2794 {MySqlHostDataSourceImpl::INSERT_V6_HOST_OPTION,
2795 "INSERT INTO dhcp6_options(option_id, code, value, formatted_value, space, "
2796 "persistent, cancelled, user_context, dhcp6_subnet_id, host_id, scope_id) "
2797 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 3)"},
2800 {MySqlHostDataSourceImpl::DEL_HOST_ADDR4,
2801 "DELETE FROM hosts WHERE dhcp4_subnet_id = ? AND ipv4_address = ?"},
2804 {MySqlHostDataSourceImpl::DEL_HOST_ADDR6,
2805 "DELETE h FROM hosts AS h "
2806 "INNER JOIN ipv6_reservations AS r "
2807 "ON h.host_id = r.host_id "
2808 "WHERE h.dhcp6_subnet_id = ? AND r.address = ?"},
2811 {MySqlHostDataSourceImpl::DEL_HOST_SUBID4_ID,
2812 "DELETE FROM hosts WHERE dhcp4_subnet_id = ? AND dhcp_identifier_type=? "
2813 "AND dhcp_identifier = ?"},
2816 {MySqlHostDataSourceImpl::DEL_HOST_SUBID6_ID,
2817 "DELETE FROM hosts WHERE dhcp6_subnet_id = ? AND dhcp_identifier_type=? "
2818 "AND dhcp_identifier = ?"}
2829 : conn_(parameters, io_service_accessor, db_reconnect_callback),
2830 is_readonly_(true) {
2838 if (MultiThreadingMgr::instance().getMode()) {
2842 lock_guard<mutex> lock(mgr_.
pool_->mutex_);
2843 if (!mgr_.
pool_->pool_.empty()) {
2845 mgr_.
pool_->pool_.pop_back();
2853 if (mgr_.
pool_->pool_.empty()) {
2861 if (MultiThreadingMgr::instance().getMode()) {
2863 lock_guard<mutex> lock(mgr_.pool_->mutex_);
2864 mgr_.pool_->pool_.push_back(ctx_);
2865 if (ctx_->conn_.isUnusable()) {
2866 mgr_.unusable_ =
true;
2868 }
else if (ctx_->conn_.isUnusable()) {
2869 mgr_.unusable_ =
true;
2874 : parameters_(parameters), ip_reservations_unique_(true), unusable_(false),
2879 timer_name_ += boost::lexical_cast<std::string>(
reinterpret_cast<uint64_t
>(
this));
2885 std::pair<uint32_t, uint32_t> db_version =
getVersion();
2886 if (code_version != db_version) {
2888 "MySQL schema version mismatch: need version: "
2889 << code_version.first <<
"." << code_version.second
2890 <<
" found version: " << db_version.first <<
"."
2891 << db_version.second);
2908 ctx->conn_.openDatabase();
2911 if (ctx->conn_.getTls()) {
2912 std::string cipher = ctx->conn_.getTlsCipher();
2913 if (cipher.empty()) {
2925 ctx->conn_.prepareStatements(tagged_statements.begin(),
2930 ctx->is_readonly_ = ctx->conn_.configuredReadOnly();
2934 if (!ctx->is_readonly_) {
2937 tagged_statements.end());
2944 ctx->host_ipv4_exchange_.reset(
new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY));
2945 ctx->host_ipv6_exchange_.reset(
new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP6_ONLY));
2946 ctx->host_ipv46_exchange_.reset(
new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP4_AND_DHCP6));
2947 ctx->host_ipv6_reservation_exchange_.reset(
new MySqlIPv6ReservationExchange());
2948 ctx->host_option_exchange_.reset(
new MySqlOptionExchange());
2968 bool reopened =
false;
2970 const std::string timer_name = db_reconnect_ctl->timerName();
2975 std::list<std::string> host_db_access_list = cfg_db->getHostDbAccessStringList();
2976 for (std::string& hds : host_db_access_list) {
2983 }
catch (
const std::exception& ex) {
2999 if (!db_reconnect_ctl->checkRetries()) {
3002 .arg(db_reconnect_ctl->maxRetries());
3015 .arg(db_reconnect_ctl->maxRetries() - db_reconnect_ctl->retriesLeft() + 1)
3016 .arg(db_reconnect_ctl->maxRetries())
3017 .arg(db_reconnect_ctl->retryInterval());
3023 db_reconnect_ctl->retryInterval(),
3032 std::pair<uint32_t, uint32_t>
3043 std::vector<MYSQL_BIND>& bind) {
3045 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), &bind[0]);
3046 checkError(ctx, status, stindex,
"unable to bind parameters");
3053 if (mysql_errno(ctx->conn_.mysql_) == ER_DUP_ENTRY) {
3056 checkError(ctx, status, stindex,
"unable to execute");
3064 my_ulonglong numrows = mysql_stmt_affected_rows(ctx->conn_.getStatement(stindex));
3075 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), &bind[0]);
3076 checkError(ctx, status, stindex,
"unable to bind parameters");
3082 checkError(ctx, status, stindex,
"unable to execute");
3086 my_ulonglong numrows = mysql_stmt_affected_rows(ctx->conn_.getStatement(stindex));
3088 return (numrows != 0);
3095 std::vector<MYSQL_BIND> bind = ctx->host_ipv6_reservation_exchange_->
3105 const std::string& opt_space,
3108 std::vector<MYSQL_BIND> bind = ctx->host_option_exchange_->createBindForSend(opt_desc, opt_space, subnet_id,
id);
3117 const uint64_t host_id) {
3120 std::list<std::string> option_spaces = options_cfg->getOptionSpaceNames();
3121 std::list<std::string> vendor_spaces = options_cfg->getVendorIdsSpaceNames();
3122 option_spaces.insert(option_spaces.end(), vendor_spaces.begin(),
3123 vendor_spaces.end());
3127 for (
auto space = option_spaces.begin(); space != option_spaces.end(); ++space) {
3129 if (options && !options->empty()) {
3130 for (
auto opt = options->begin(); opt != options->end(); ++opt) {
3141 const char* what)
const {
3142 ctx->conn_.checkError(status, index, what);
3149 boost::shared_ptr<MySqlHostExchange> exchange,
3151 bool single)
const {
3154 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), bind);
3155 checkError(ctx, status, stindex,
"unable to bind WHERE clause parameter");
3159 std::vector<MYSQL_BIND> outbind = exchange->createBindForReceive();
3160 status = mysql_stmt_bind_result(ctx->conn_.getStatement(stindex), &outbind[0]);
3161 checkError(ctx, status, stindex,
"unable to bind SELECT clause parameters");
3165 checkError(ctx, status, stindex,
"unable to execute");
3169 status = mysql_stmt_store_result(ctx->conn_.getStatement(stindex));
3170 checkError(ctx, status, stindex,
"unable to set up for storing all results");
3177 while ((status = mysql_stmt_fetch(ctx->conn_.getStatement(stindex))) ==
3180 exchange->processFetchedData(result);
3185 ctx->conn_.text_statements_[stindex] <<
">");
3188 if (single && (result.size() > 1)) {
3190 "database where only one was expected for query "
3191 << ctx->conn_.text_statements_[stindex]);
3199 checkError(ctx, status, stindex,
"unable to fetch results");
3201 }
else if (status == MYSQL_DATA_TRUNCATED) {
3204 <<
" returned truncated data: columns affected are "
3205 << exchange->getErrorColumns());
3213 const uint8_t* identifier_begin,
3214 const size_t identifier_len,
3216 boost::shared_ptr<MySqlHostExchange> exchange)
const {
3219 MYSQL_BIND inbind[3];
3220 memset(inbind, 0,
sizeof(inbind));
3222 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3223 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3224 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3228 std::vector<char> identifier_vec(identifier_begin,
3229 identifier_begin + identifier_len);
3230 unsigned long length = identifier_vec.size();
3231 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3232 inbind[2].buffer = &identifier_vec[0];
3233 inbind[2].buffer_length = length;
3234 inbind[2].length = &length;
3237 char identifier_type_copy =
static_cast<char>(identifier_type);
3238 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3239 inbind[1].buffer =
reinterpret_cast<char*
>(&identifier_type_copy);
3247 if (!collection.empty()) {
3248 result = *collection.begin();
3256 if (ctx->is_readonly_) {
3258 " operate in read only mode");
3271 return (impl_->parameters_);
3281 impl_->checkReadOnly(ctx);
3293 bool unique_ip = impl_->ip_reservations_unique_ && !host->getIPv4Reservation().isV4Zero()
3294 && host->getIPv4SubnetID() != SUBNET_ID_UNUSED;
3297 std::vector<MYSQL_BIND> bind = ctx->host_ipv4_exchange_->createBindForSend(host, unique_ip);
3304 uint64_t host_id = mysql_insert_id(ctx->conn_.mysql_);
3310 cfg_option4, host_id);
3317 cfg_option6, host_id);
3322 if (std::distance(v6resv.first, v6resv.second) > 0) {
3325 impl_->addResv(ctx, resv->second, host_id);
3341 impl_->checkReadOnly(ctx);
3344 MYSQL_BIND inbind[2];
3346 uint32_t subnet = subnet_id;
3347 memset(inbind, 0,
sizeof(inbind));
3348 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3349 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3355 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3356 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3363 std::vector<uint8_t>addr6 = addr.
toBytes();
3364 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3366 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3369 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3370 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3371 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3372 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3373 inbind[1].length = &addr6_length;
3381 const uint8_t* identifier_begin,
3382 const size_t identifier_len) {
3388 impl_->checkReadOnly(ctx);
3391 MYSQL_BIND inbind[3];
3394 memset(inbind, 0,
sizeof(inbind));
3395 uint32_t subnet =
static_cast<uint32_t
>(subnet_id);
3396 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3397 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3401 char identifier_type_copy =
static_cast<char>(identifier_type);
3402 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3403 inbind[1].buffer =
reinterpret_cast<char*
>(&identifier_type_copy);
3407 std::vector<char> identifier_vec(identifier_begin,
3408 identifier_begin + identifier_len);
3409 unsigned long length = identifier_vec.size();
3410 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3411 inbind[2].buffer = &identifier_vec[0];
3412 inbind[2].buffer_length = length;
3413 inbind[2].length = &length;
3422 const uint8_t* identifier_begin,
3423 const size_t identifier_len) {
3429 impl_->checkReadOnly(ctx);
3432 MYSQL_BIND inbind[3];
3435 memset(inbind, 0,
sizeof(inbind));
3436 uint32_t subnet =
static_cast<uint32_t
>(subnet_id);
3437 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3438 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3442 char identifier_type_copy =
static_cast<char>(identifier_type);
3443 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3444 inbind[1].buffer =
reinterpret_cast<char*
>(&identifier_type_copy);
3448 std::vector<char> identifier_vec(identifier_begin,
3449 identifier_begin + identifier_len);
3450 unsigned long length = identifier_vec.size();
3451 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3452 inbind[2].buffer = &identifier_vec[0];
3453 inbind[2].buffer_length = length;
3454 inbind[2].length = &length;
3462 const uint8_t* identifier_begin,
3463 const size_t identifier_len)
const {
3469 MYSQL_BIND inbind[2];
3470 memset(inbind, 0,
sizeof(inbind));
3473 char identifier_type_copy =
static_cast<char>(identifier_type);
3474 inbind[1].buffer = &identifier_type_copy;
3475 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3479 std::vector<char> identifier_vec(identifier_begin,
3480 identifier_begin + identifier_len);
3481 unsigned long int length = identifier_vec.size();
3482 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
3483 inbind[0].buffer = &identifier_vec[0];
3484 inbind[0].buffer_length = length;
3485 inbind[0].length = &length;
3489 ctx->host_ipv46_exchange_, result,
false);
3501 MYSQL_BIND inbind[1];
3502 memset(inbind, 0,
sizeof(inbind));
3503 uint32_t subnet = subnet_id;
3504 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3505 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3510 ctx->host_ipv4_exchange_, result,
false);
3522 MYSQL_BIND inbind[1];
3523 memset(inbind, 0,
sizeof(inbind));
3524 uint32_t subnet = subnet_id;
3525 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3526 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3531 ctx->host_ipv6_exchange_, result,
false);
3543 MYSQL_BIND inbind[1];
3544 memset(inbind, 0,
sizeof(inbind));
3549 unsigned long length = hostname.length();
3550 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3551 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3552 inbind[0].buffer_length = length;
3553 inbind[0].length = &length;
3557 ctx->host_ipv46_exchange_, result,
false);
3570 MYSQL_BIND inbind[2];
3571 memset(inbind, 0,
sizeof(inbind));
3576 unsigned long length = hostname.length();
3577 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3578 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3579 inbind[0].buffer_length = length;
3580 inbind[0].length = &length;
3583 uint32_t subnet = subnet_id;
3584 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3585 inbind[1].buffer =
reinterpret_cast<char*
>(&subnet);
3590 ctx->host_ipv4_exchange_, result,
false);
3603 MYSQL_BIND inbind[2];
3604 memset(inbind, 0,
sizeof(inbind));
3609 unsigned long length = hostname.length();
3610 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3611 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3612 inbind[0].buffer_length = length;
3613 inbind[0].length = &length;
3616 uint32_t subnet = subnet_id;
3617 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3618 inbind[1].buffer =
reinterpret_cast<char*
>(&subnet);
3623 ctx->host_ipv6_exchange_, result,
false);
3631 uint64_t lower_host_id,
3638 MYSQL_BIND inbind[3];
3639 memset(inbind, 0,
sizeof(inbind));
3642 uint32_t subnet = subnet_id;
3643 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3644 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3648 uint32_t host_id = lower_host_id;
3649 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3650 inbind[1].buffer =
reinterpret_cast<char*
>(&host_id);
3654 uint32_t page_size_data = page_size.
page_size_;
3655 inbind[2].buffer_type = MYSQL_TYPE_LONG;
3656 inbind[2].buffer =
reinterpret_cast<char*
>(&page_size_data);
3661 ctx->host_ipv4_exchange_, result,
false);
3669 uint64_t lower_host_id,
3676 MYSQL_BIND inbind[3];
3677 memset(inbind, 0,
sizeof(inbind));
3680 uint32_t subnet = subnet_id;
3681 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3682 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3686 uint32_t host_id = lower_host_id;
3687 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3688 inbind[1].buffer =
reinterpret_cast<char*
>(&host_id);
3692 uint32_t page_size_data = page_size.
page_size_;
3693 inbind[2].buffer_type = MYSQL_TYPE_LONG;
3694 inbind[2].buffer =
reinterpret_cast<char*
>(&page_size_data);
3699 ctx->host_ipv6_exchange_, result,
false);
3706 uint64_t lower_host_id,
3713 MYSQL_BIND inbind[2];
3714 memset(inbind, 0,
sizeof(inbind));
3717 uint32_t host_id = lower_host_id;
3718 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3719 inbind[0].buffer =
reinterpret_cast<char*
>(&host_id);
3723 uint32_t page_size_data = page_size.
page_size_;
3724 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3725 inbind[1].buffer =
reinterpret_cast<char*
>(&page_size_data);
3730 ctx->host_ipv4_exchange_, result,
false);
3737 uint64_t lower_host_id,
3744 MYSQL_BIND inbind[2];
3745 memset(inbind, 0,
sizeof(inbind));
3748 uint32_t host_id = lower_host_id;
3749 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3750 inbind[0].buffer =
reinterpret_cast<char*
>(&host_id);
3754 uint32_t page_size_data = page_size.
page_size_;
3755 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3756 inbind[1].buffer =
reinterpret_cast<char*
>(&page_size_data);
3761 ctx->host_ipv6_exchange_, result,
false);
3773 MYSQL_BIND inbind[1];
3774 memset(inbind, 0,
sizeof(inbind));
3776 uint32_t addr4 = address.
toUint32();
3777 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3778 inbind[0].buffer =
reinterpret_cast<char*
>(&addr4);
3783 ctx->host_ipv4_exchange_, result,
false);
3791 const uint8_t* identifier_begin,
3792 const size_t identifier_len)
const {
3797 return (impl_->getHost(ctx, subnet_id, identifier_type, identifier_begin, identifier_len,
3799 ctx->host_ipv4_exchange_));
3805 if (!address.
isV4()) {
3807 "wrong address type, address supplied is an IPv6 address");
3815 MYSQL_BIND inbind[2];
3816 uint32_t subnet = subnet_id;
3817 memset(inbind, 0,
sizeof(inbind));
3818 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3819 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3822 uint32_t addr4 = address.
toUint32();
3823 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3824 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3829 ctx->host_ipv4_exchange_, collection,
true);
3833 if (!collection.empty()) {
3834 result = *collection.begin();
3843 if (!address.
isV4()) {
3845 "wrong address type, address supplied is an IPv6 address");
3853 MYSQL_BIND inbind[2];
3854 uint32_t subnet = subnet_id;
3855 memset(inbind, 0,
sizeof(inbind));
3856 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3857 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3860 uint32_t addr4 = address.
toUint32();
3861 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3862 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3867 ctx->host_ipv4_exchange_, collection,
false);
3868 return (collection);
3874 const uint8_t* identifier_begin,
3875 const size_t identifier_len)
const {
3880 return (impl_->getHost(ctx, subnet_id, identifier_type, identifier_begin, identifier_len,
3882 ctx->host_ipv6_exchange_));
3887 const uint8_t prefix_len)
const {
3888 if (!prefix.
isV6()) {
3890 "wrong address type, address supplied is an IPv4 address");
3898 MYSQL_BIND inbind[2];
3899 memset(inbind, 0,
sizeof(inbind));
3901 std::vector<uint8_t>addr6 = prefix.
toBytes();
3902 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3904 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3907 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3908 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
3909 inbind[0].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3910 inbind[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3911 inbind[0].length = &addr6_length;
3913 uint8_t tmp = prefix_len;
3914 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3915 inbind[1].buffer =
reinterpret_cast<char*
>(&tmp);
3920 ctx->host_ipv6_exchange_, collection,
true);
3924 if (!collection.empty()) {
3925 result = *collection.begin();
3934 if (!address.
isV6()) {
3936 "wrong address type, address supplied is an IPv4 address");
3944 MYSQL_BIND inbind[2];
3945 memset(inbind, 0,
sizeof(inbind));
3947 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3948 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3949 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3952 std::vector<uint8_t>addr6 = address.
toBytes();
3953 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3955 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3958 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3959 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3960 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3961 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3962 inbind[1].length = &addr6_length;
3966 ctx->host_ipv6_exchange_, collection,
true);
3970 if (!collection.empty()) {
3971 result = *collection.begin();
3980 if (!address.
isV6()) {
3982 "wrong address type, address supplied is an IPv4 address");
3990 MYSQL_BIND inbind[2];
3991 memset(inbind, 0,
sizeof(inbind));
3993 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3994 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3995 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3998 std::vector<uint8_t>addr6 = address.
toBytes();
3999 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
4001 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
4004 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
4005 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
4006 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
4007 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
4008 inbind[1].length = &addr6_length;
4012 ctx->host_ipv6_exchange_, collection,
false);
4013 return (collection);
4018 if (!address.
isV6()) {
4020 "wrong address type, address supplied is an IPv4 address");
4028 MYSQL_BIND inbind[1];
4029 memset(inbind, 0,
sizeof(inbind));
4031 std::vector<uint8_t>addr6 = address.
toBytes();
4032 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
4034 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
4037 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
4038 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
4039 inbind[0].buffer =
reinterpret_cast<char*
>(&addr6[0]);
4040 inbind[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
4041 inbind[0].length = &addr6_length;
4045 ctx->host_ipv6_exchange_, collection,
false);
4046 return (collection);
4056 impl_->checkReadOnly(ctx);
4079 std::string name =
"";
4085 name = ctx->conn_.getParameter(
"name");
4094 return (std::string(
"Host data source that stores host information"
4095 "in MySQL database"));
4098 std::pair<uint32_t, uint32_t>
4100 return(impl_->getVersion());
4110 impl_->checkReadOnly(ctx);
4111 if (ctx->conn_.isTransactionStarted()) {
4112 ctx->conn_.commit();
4123 impl_->checkReadOnly(ctx);
4124 if (ctx->conn_.isTransactionStarted()) {
4125 ctx->conn_.rollback();
4131 impl_->ip_reservations_unique_ = unique;
4137 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)
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 const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
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.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Exception thrown on failure to open database.
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)
Get the schema version.
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 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).
static isc::asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service.
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.
IPv6 reservation for a host.
Type getType() const
Returns reservation type.
const asiolink::IOAddress & getPrefix() const
Returns prefix for the reservation.
Type
Type of the reservation.
uint8_t getPrefixLen() const
Returns prefix length.
std::vector< MySqlHostContextPtr > pool_
The vector of available contexts.
std::mutex mutex_
The mutex to protect pool access.
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.
std::pair< uint32_t, uint32_t > getVersion() const
Returns backend version.
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.
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 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 std::pair< uint32_t, uint32_t > getVersion() const
Returns backend version.
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.
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.
const uint32_t MYSQL_SCHEMA_VERSION_MAJOR
boost::shared_ptr< IOServiceAccessor > IOServiceAccessorPtr
Pointer to an instance of IOServiceAccessor.
const uint32_t MYSQL_SCHEMA_VERSION_MINOR
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.
IPv6ResrvCollection::const_iterator IPv6ResrvIterator
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.