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_);
1002 option.reset(
new Option(universe_,
code_, buf.begin(),
1009 if (formatted_value.empty()) {
1011 option = def->optionFactory(universe_,
code_, buf.begin(),
1016 std::vector<std::string> split_vec;
1017 boost::split(split_vec, formatted_value, boost::is_any_of(
","));
1018 option = def->optionFactory(universe_,
code_, split_vec);
1026 if (!user_context.empty()) {
1029 if (!ctx || (ctx->getType() != Element::map)) {
1031 <<
"' is no a JSON map");
1033 desc.setContext(ctx);
1036 <<
"' is invalid JSON: " << ex.
what());
1040 cfg->add(desc, space);
1047 void setColumnNames(std::vector<std::string>& columns) {
1048 columns[option_id_index_] =
"option_id";
1049 columns[code_index_] =
"code";
1050 columns[value_index_] =
"value";
1051 columns[formatted_value_index_] =
"formatted_value";
1052 columns[space_index_] =
"space";
1053 columns[persistent_index_] =
"persistent";
1054 columns[cancelled_index_] =
"cancelled";
1055 columns[user_context_index_] =
"user_context";
1064 void setBindFields(std::vector<MYSQL_BIND>& bind) {
1068 most_recent_option_id_ = 0;
1072 persistent_ =
false;
1081 memset(value_, 0,
sizeof(value_));
1082 memset(formatted_value_, 0,
sizeof(formatted_value_));
1083 memset(space_, 0,
sizeof(space_));
1084 memset(user_context_, 0,
sizeof(user_context_));
1087 bind[option_id_index_].buffer_type = MYSQL_TYPE_LONG;
1088 bind[option_id_index_].buffer =
reinterpret_cast<char*
>(&option_id_);
1089 bind[option_id_index_].is_unsigned =
MLM_TRUE;
1090 bind[option_id_index_].is_null = &option_id_null_;
1093 bind[code_index_].buffer_type = MYSQL_TYPE_SHORT;
1094 bind[code_index_].buffer =
reinterpret_cast<char*
>(&
code_);
1095 bind[code_index_].is_unsigned =
MLM_TRUE;
1096 bind[code_index_].is_null = &code_null_;
1099 value_length_ =
sizeof(value_);
1100 bind[value_index_].buffer_type = MYSQL_TYPE_BLOB;
1101 bind[value_index_].buffer =
reinterpret_cast<char*
>(value_);
1102 bind[value_index_].buffer_length = value_length_;
1103 bind[value_index_].length = &value_length_;
1104 bind[value_index_].is_null = &value_null_;
1107 formatted_value_length_ =
sizeof(formatted_value_);
1108 bind[formatted_value_index_].buffer_type = MYSQL_TYPE_STRING;
1109 bind[formatted_value_index_].buffer =
reinterpret_cast<char*
>(formatted_value_);
1110 bind[formatted_value_index_].buffer_length = formatted_value_length_;
1111 bind[formatted_value_index_].length = &formatted_value_length_;
1112 bind[formatted_value_index_].is_null = &formatted_value_null_;
1115 space_length_ =
sizeof(space_);
1116 bind[space_index_].buffer_type = MYSQL_TYPE_STRING;
1117 bind[space_index_].buffer =
reinterpret_cast<char*
>(space_);
1118 bind[space_index_].buffer_length = space_length_;
1119 bind[space_index_].length = &space_length_;
1120 bind[space_index_].is_null = &space_null_;
1123 bind[persistent_index_].buffer_type = MYSQL_TYPE_TINY;
1124 bind[persistent_index_].buffer =
reinterpret_cast<char*
>(&persistent_);
1125 bind[persistent_index_].is_unsigned =
MLM_TRUE;
1128 bind[cancelled_index_].buffer_type = MYSQL_TYPE_TINY;
1129 bind[cancelled_index_].buffer =
reinterpret_cast<char*
>(&cancelled_);
1130 bind[cancelled_index_].is_unsigned =
MLM_TRUE;
1133 user_context_length_ =
sizeof(user_context_);
1134 bind[user_context_index_].buffer_type = MYSQL_TYPE_STRING;
1135 bind[user_context_index_].buffer =
reinterpret_cast<char*
>(user_context_);
1136 bind[user_context_index_].buffer_length = user_context_length_;
1137 bind[user_context_index_].length = &user_context_length_;
1138 bind[user_context_index_].is_null = &user_context_null_;
1147 size_t start_column_;
1150 uint32_t option_id_;
1159 unsigned long value_length_;
1165 unsigned long formatted_value_length_;
1171 unsigned long space_length_;
1184 unsigned long user_context_length_;
1200 my_bool formatted_value_null_;
1211 size_t option_id_index_;
1218 size_t value_index_;
1221 size_t formatted_value_index_;
1224 size_t space_index_;
1227 size_t persistent_index_;
1230 size_t cancelled_index_;
1234 size_t user_context_index_;
1237 uint32_t most_recent_option_id_;
1241 typedef boost::shared_ptr<OptionProcessor> OptionProcessorPtr;
1251 enum FetchedOptions {
1265 MySqlHostWithOptionsExchange(
const FetchedOptions& fetched_options,
1266 const size_t additional_columns_num = 0)
1267 : MySqlHostExchange(getRequiredColumnsNum(fetched_options)
1268 + additional_columns_num),
1269 opt_proc4_(), opt_proc6_() {
1272 if ((fetched_options == DHCP4_ONLY) ||
1273 (fetched_options == DHCP4_AND_DHCP6)) {
1274 opt_proc4_.reset(
new OptionProcessor(Option::V4,
1275 findAvailColumn()));
1276 opt_proc4_->setColumnNames(columns_);
1280 if ((fetched_options == DHCP6_ONLY) ||
1281 (fetched_options == DHCP4_AND_DHCP6)) {
1282 opt_proc6_.reset(
new OptionProcessor(Option::V6,
1283 findAvailColumn()));
1284 opt_proc6_->setColumnNames(columns_);
1299 if (!hosts.empty()) {
1308 most_recent_host = boost::const_pointer_cast<Host>(hosts.back());
1314 if (!most_recent_host || (most_recent_host->getHostId() < getHostId())) {
1315 HostPtr host = retrieveHost();
1316 hosts.push_back(host);
1317 most_recent_host = host;
1323 opt_proc4_->retrieveOption(cfg);
1329 opt_proc6_->retrieveOption(cfg);
1336 virtual std::vector<MYSQL_BIND> createBindForReceive() {
1338 static_cast<void>(MySqlHostExchange::createBindForReceive());
1342 opt_proc4_->setBindFields(bind_);
1347 opt_proc6_->setBindFields(bind_);
1351 setErrorIndicators(bind_, error_);
1369 static size_t getRequiredColumnsNum(
const FetchedOptions& fetched_options) {
1370 return (fetched_options == DHCP4_AND_DHCP6 ? 2 * OPTION_COLUMNS :
1377 OptionProcessorPtr opt_proc4_;
1382 OptionProcessorPtr opt_proc6_;
1397 class MySqlHostIPv6Exchange :
public MySqlHostWithOptionsExchange {
1401 static const size_t RESERVATION_COLUMNS = 5;
1409 MySqlHostIPv6Exchange(
const FetchedOptions& fetched_options)
1410 : MySqlHostWithOptionsExchange(fetched_options, RESERVATION_COLUMNS),
1412 reserv_type_(0), reserv_type_null_(
MLM_FALSE),
1413 ipv6_address_buffer_len_(0), prefix_len_(0), iaid_(0),
1414 reservation_id_index_(findAvailColumn()),
1415 address_index_(reservation_id_index_ + 1),
1416 prefix_len_index_(reservation_id_index_ + 2),
1417 type_index_(reservation_id_index_ + 3),
1418 iaid_index_(reservation_id_index_ + 4),
1419 most_recent_reservation_id_(0) {
1421 memset(ipv6_address_buffer_, 0,
sizeof(ipv6_address_buffer_));
1424 columns_[reservation_id_index_] =
"reservation_id";
1425 columns_[address_index_] =
"address";
1426 columns_[prefix_len_index_] =
"prefix_len";
1427 columns_[type_index_] =
"type";
1428 columns_[iaid_index_] =
"dhcp6_iaid";
1434 uint32_t getReservationId()
const {
1436 return (reservation_id_);
1451 switch (reserv_type_) {
1453 type = IPv6Resrv::TYPE_NA;
1457 type = IPv6Resrv::TYPE_PD;
1462 "invalid IPv6 reservation type returned: "
1463 <<
static_cast<int>(reserv_type_)
1464 <<
". Only 0 or 2 are allowed.");
1467 ipv6_address_buffer_[ipv6_address_buffer_len_] =
'\0';
1468 std::string address = ipv6_address_buffer_;
1495 MySqlHostWithOptionsExchange::processFetchedData(hosts);
1497 if (getReservationId() == 0) {
1501 if (hosts.empty()) {
1503 " IPv6 reservation");
1505 HostPtr host = boost::const_pointer_cast<Host>(hosts.back());
1509 if (getReservationId() > most_recent_reservation_id_) {
1510 most_recent_reservation_id_ = getReservationId();
1512 if (most_recent_reservation_id_ > 0) {
1513 host->addReservation(retrieveReservation());
1526 virtual std::vector<MYSQL_BIND> createBindForReceive() {
1529 most_recent_reservation_id_ = 0;
1532 static_cast<void>(MySqlHostWithOptionsExchange::createBindForReceive());
1535 bind_[reservation_id_index_].buffer_type = MYSQL_TYPE_LONG;
1536 bind_[reservation_id_index_].buffer =
reinterpret_cast<char*
>(&reservation_id_);
1537 bind_[reservation_id_index_].is_unsigned =
MLM_TRUE;
1540 ipv6_address_buffer_len_ =
sizeof(ipv6_address_buffer_) - 1;
1541 bind_[address_index_].buffer_type = MYSQL_TYPE_STRING;
1542 bind_[address_index_].buffer = ipv6_address_buffer_;
1543 bind_[address_index_].buffer_length = ipv6_address_buffer_len_;
1544 bind_[address_index_].length = &ipv6_address_buffer_len_;
1547 bind_[prefix_len_index_].buffer_type = MYSQL_TYPE_TINY;
1548 bind_[prefix_len_index_].buffer =
reinterpret_cast<char*
>(&prefix_len_);
1549 bind_[prefix_len_index_].is_unsigned =
MLM_TRUE;
1553 bind_[type_index_].buffer_type = MYSQL_TYPE_TINY;
1554 bind_[type_index_].buffer =
reinterpret_cast<char*
>(&reserv_type_);
1555 bind_[type_index_].is_unsigned =
MLM_TRUE;
1556 bind_[type_index_].is_null = &reserv_type_null_;
1559 bind_[iaid_index_].buffer_type = MYSQL_TYPE_LONG;
1560 bind_[iaid_index_].buffer =
reinterpret_cast<char*
>(&iaid_);
1561 bind_[iaid_index_].is_unsigned =
MLM_TRUE;
1564 setErrorIndicators(bind_, error_);
1572 uint32_t reservation_id_;
1575 uint8_t reserv_type_;
1587 unsigned long ipv6_address_buffer_len_;
1590 uint8_t prefix_len_;
1597 size_t reservation_id_index_;
1601 size_t address_index_;
1604 size_t prefix_len_index_;
1615 uint32_t most_recent_reservation_id_;
1628 class MySqlIPv6ReservationExchange {
1632 static const size_t RESRV_COLUMNS = 6;
1639 MySqlIPv6ReservationExchange()
1640 : host_id_(0), address_(
"::"), address_len_(0), prefix_len_(0), type_(0),
1644 std::fill(&error_[0], &error_[RESRV_COLUMNS],
MLM_FALSE);
1647 columns_[0] =
"host_id";
1648 columns_[1] =
"address";
1649 columns_[2] =
"prefix_len";
1650 columns_[3] =
"type";
1651 columns_[4] =
"dhcp6_iaid";
1653 BOOST_STATIC_ASSERT(4 < RESRV_COLUMNS);
1670 std::vector<MYSQL_BIND> createBindForSend(
const IPv6Resrv& resv,
1672 const bool unique_ip) {
1683 memset(bind_, 0,
sizeof(bind_));
1690 address_len_ = address_.length();
1691 bind_[0].buffer_type = MYSQL_TYPE_BLOB;
1692 bind_[0].buffer =
reinterpret_cast<char*
>
1693 (
const_cast<char*
>(address_.c_str()));
1694 bind_[0].buffer_length = address_len_;
1695 bind_[0].length = &address_len_;
1699 bind_[1].buffer_type = MYSQL_TYPE_TINY;
1700 bind_[1].buffer =
reinterpret_cast<char*
>(&prefix_len_);
1705 type_ = resv.
getType() == IPv6Resrv::TYPE_NA ? 0 : 2;
1706 bind_[2].buffer_type = MYSQL_TYPE_TINY;
1707 bind_[2].buffer =
reinterpret_cast<char*
>(&type_);
1713 bind_[3].buffer_type = MYSQL_TYPE_LONG;
1714 bind_[3].buffer =
reinterpret_cast<char*
>(&iaid_);
1718 bind_[4].buffer_type = MYSQL_TYPE_LONG;
1719 bind_[4].buffer =
reinterpret_cast<char*
>(&host_id_);
1722 }
catch (
const std::exception& ex) {
1724 "Could not create bind array from IPv6 Reservation: "
1725 << resv_.toText() <<
", reason: " << ex.
what());
1731 std::vector<MYSQL_BIND> vec(&bind_[0], &bind_[RESRV_COLUMNS-1]);
1737 vec.push_back(bind_[0]);
1738 vec.push_back(bind_[1]);
1750 std::string address_;
1753 unsigned long address_len_;
1756 uint8_t prefix_len_;
1768 MYSQL_BIND bind_[RESRV_COLUMNS];
1771 std::string columns_[RESRV_COLUMNS];
1775 my_bool error_[RESRV_COLUMNS];
1781 class MySqlOptionExchange {
1784 static const size_t OPTION_ID_COL = 0;
1785 static const size_t CODE_COL = 1;
1786 static const size_t VALUE_COL = 2;
1787 static const size_t FORMATTED_VALUE_COL = 3;
1788 static const size_t SPACE_COL = 4;
1789 static const size_t PERSISTENT_COL = 5;
1790 static const size_t CANCELLED_COL = 6;
1791 static const size_t USER_CONTEXT_COL = 7;
1792 static const size_t DHCP_SUBNET_ID_COL = 8;
1793 static const size_t HOST_ID_COL = 9;
1795 static const size_t OPTION_COLUMNS = 10;
1800 MySqlOptionExchange()
1801 : type_(0), value_len_(0), formatted_value_len_(0), space_(),
1802 space_len_(0), persistent_(false), cancelled_(false),
1803 user_context_(), user_context_len_(0), subnet_id_(SUBNET_ID_UNUSED),
1804 host_id_(0), option_() {
1806 BOOST_STATIC_ASSERT(10 <= OPTION_COLUMNS);
1812 std::vector<MYSQL_BIND> createBindForSend(
const OptionDescriptor& opt_desc,
1813 const std::string& opt_space,
1821 memset(bind_, 0,
sizeof(bind_));
1827 bind_[0].buffer_type = MYSQL_TYPE_NULL;
1830 type_ = option_->getType();
1831 bind_[1].buffer_type = MYSQL_TYPE_SHORT;
1832 bind_[1].buffer =
reinterpret_cast<char*
>(&type_);
1843 const char* buf_ptr =
static_cast<const char*
>(buf.getData());
1844 value_.assign(buf_ptr + opt_desc.
option_->getHeaderLen(),
1845 buf_ptr + buf.getLength());
1846 value_len_ = value_.size();
1847 bind_[2].buffer_type = MYSQL_TYPE_BLOB;
1848 bind_[2].buffer = &value_[0];
1849 bind_[2].buffer_length = value_len_;
1850 bind_[2].length = &value_len_;
1856 bind_[2].buffer_type = MYSQL_TYPE_NULL;
1862 bind_[3].buffer_type = MYSQL_TYPE_STRING;
1864 bind_[3].buffer_length = formatted_value_len_;
1865 bind_[3].length = &formatted_value_len_;
1868 bind_[3].buffer_type = MYSQL_TYPE_NULL;
1873 space_len_ = space_.size();
1874 bind_[4].buffer_type = MYSQL_TYPE_STRING;
1875 bind_[4].buffer =
const_cast<char*
>(space_.c_str());
1876 bind_[4].buffer_length = space_len_;
1877 bind_[4].length = &space_len_;
1881 bind_[5].buffer_type = MYSQL_TYPE_TINY;
1882 bind_[5].buffer =
reinterpret_cast<char*
>(&persistent_);
1887 bind_[6].buffer_type = MYSQL_TYPE_TINY;
1888 bind_[6].buffer =
reinterpret_cast<char*
>(&cancelled_);
1894 user_context_ = ctx->str();
1895 user_context_len_ = user_context_.size();
1896 bind_[7].buffer_type = MYSQL_TYPE_STRING;
1897 bind_[7].buffer =
const_cast<char*
>(user_context_.c_str());
1898 bind_[7].buffer_length = user_context_len_;
1899 bind_[7].length = &user_context_len_;
1901 bind_[7].buffer_type = MYSQL_TYPE_NULL;
1906 subnet_id_ = subnet_id;
1907 bind_[8].buffer_type = MYSQL_TYPE_LONG;
1908 bind_[8].buffer =
reinterpret_cast<char*
>(subnet_id_);
1912 bind_[8].buffer_type = MYSQL_TYPE_NULL;
1917 bind_[9].buffer_type = MYSQL_TYPE_LONG;
1918 bind_[9].buffer =
reinterpret_cast<char*
>(&host_id_);
1921 }
catch (
const std::exception& ex) {
1923 "Could not create bind array for inserting DHCP "
1924 "option: " << option_->toText() <<
", reason: "
1928 return (std::vector<MYSQL_BIND>(&bind_[0], &bind_[OPTION_COLUMNS]));
1937 std::vector<uint8_t> value_;
1940 unsigned long value_len_;
1943 unsigned long formatted_value_len_;
1949 unsigned long space_len_;
1960 std::string user_context_;
1963 unsigned long user_context_len_;
1966 uint32_t subnet_id_;
1975 MYSQL_BIND bind_[OPTION_COLUMNS];
2161 std::pair<uint32_t, uint32_t> getVersion()
const;
2173 std::vector<MYSQL_BIND>& bind);
2208 const std::string& opt_space,
2222 const uint64_t host_id);
2238 const char* what)
const;
2261 boost::shared_ptr<MySqlHostExchange> exchange,
2285 const uint8_t* identifier_begin,
2286 const size_t identifier_len,
2288 boost::shared_ptr<MySqlHostExchange> exchange)
const;
2322 typedef boost::array<TaggedStatement, MySqlHostDataSourceImpl::NUM_STATEMENTS>
2323 TaggedStatementArray;
2327 TaggedStatementArray tagged_statements = { {
2332 {MySqlHostDataSourceImpl::GET_HOST_DHCPID,
2333 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2334 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, "
2335 "h.hostname, h.dhcp4_client_classes, h.dhcp6_client_classes, "
2337 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2338 "h.dhcp4_boot_file_name, h.auth_key, "
2339 "o4.option_id, o4.code, o4.value, o4.formatted_value, o4.space, "
2340 "o4.persistent, o4.cancelled, o4.user_context, "
2341 "o6.option_id, o6.code, o6.value, o6.formatted_value, o6.space, "
2342 "o6.persistent, o6.cancelled, o6.user_context, "
2343 "r.reservation_id, r.address, r.prefix_len, r.type, "
2346 "LEFT JOIN dhcp4_options AS o4 "
2347 "ON h.host_id = o4.host_id "
2348 "LEFT JOIN dhcp6_options AS o6 "
2349 "ON h.host_id = o6.host_id "
2350 "LEFT JOIN ipv6_reservations AS r "
2351 "ON h.host_id = r.host_id "
2352 "WHERE dhcp_identifier = ? AND dhcp_identifier_type = ? "
2353 "ORDER BY h.host_id, o4.option_id, o6.option_id, r.reservation_id"},
2358 {MySqlHostDataSourceImpl::GET_HOST_ADDR,
2359 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2360 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2361 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2362 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2363 "h.dhcp4_boot_file_name, h.auth_key, "
2364 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2365 "o.persistent, o.cancelled, o.user_context "
2367 "LEFT JOIN dhcp4_options AS o "
2368 "ON h.host_id = o.host_id "
2369 "WHERE ipv4_address = ? "
2370 "ORDER BY h.host_id, o.option_id"},
2375 {MySqlHostDataSourceImpl::GET_HOST_SUBID4_DHCPID,
2376 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2377 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2378 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2379 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2380 "h.dhcp4_boot_file_name, h.auth_key, "
2381 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2382 "o.persistent, o.cancelled, o.user_context "
2384 "LEFT JOIN dhcp4_options AS o "
2385 "ON h.host_id = o.host_id "
2386 "WHERE h.dhcp4_subnet_id = ? AND h.dhcp_identifier_type = ? "
2387 "AND h.dhcp_identifier = ? "
2388 "ORDER BY h.host_id, o.option_id"},
2393 {MySqlHostDataSourceImpl::GET_HOST_SUBID6_DHCPID,
2394 "SELECT h.host_id, h.dhcp_identifier, "
2395 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2396 "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, "
2402 "r.reservation_id, r.address, r.prefix_len, r.type, "
2405 "LEFT JOIN dhcp6_options AS o "
2406 "ON h.host_id = o.host_id "
2407 "LEFT JOIN ipv6_reservations AS r "
2408 "ON h.host_id = r.host_id "
2409 "WHERE h.dhcp6_subnet_id = ? AND h.dhcp_identifier_type = ? "
2410 "AND h.dhcp_identifier = ? "
2411 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2417 {MySqlHostDataSourceImpl::GET_HOST_SUBID_ADDR,
2418 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2419 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2420 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2421 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2422 "h.dhcp4_boot_file_name, h.auth_key, "
2423 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2424 "o.persistent, o.cancelled, o.user_context "
2426 "LEFT JOIN dhcp4_options AS o "
2427 "ON h.host_id = o.host_id "
2428 "WHERE h.dhcp4_subnet_id = ? AND h.ipv4_address = ? "
2429 "ORDER BY h.host_id, o.option_id"},
2437 {MySqlHostDataSourceImpl::GET_HOST_PREFIX,
2438 "SELECT h.host_id, h.dhcp_identifier, "
2439 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2440 "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,"
2446 "r.reservation_id, r.address, r.prefix_len, r.type, "
2449 "LEFT JOIN dhcp6_options AS o "
2450 "ON h.host_id = o.host_id "
2451 "LEFT JOIN ipv6_reservations AS r "
2452 "ON h.host_id = r.host_id "
2453 "WHERE h.host_id = "
2454 "( SELECT host_id FROM ipv6_reservations "
2455 "WHERE address = ? AND prefix_len = ? ) "
2456 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2464 {MySqlHostDataSourceImpl::GET_HOST_SUBID6_ADDR,
2465 "SELECT h.host_id, h.dhcp_identifier, "
2466 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2467 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2468 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2469 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2470 "h.dhcp4_boot_file_name, h.auth_key, "
2471 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2472 "o.persistent, o.cancelled, o.user_context, "
2473 "r.reservation_id, r.address, r.prefix_len, r.type, "
2476 "LEFT JOIN dhcp6_options AS o "
2477 "ON h.host_id = o.host_id "
2478 "LEFT JOIN ipv6_reservations AS r "
2479 "ON h.host_id = r.host_id "
2480 "WHERE h.dhcp6_subnet_id = ? AND r.address = ? "
2481 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2486 {MySqlHostDataSourceImpl::GET_HOST_SUBID4,
2487 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2488 "h.dhcp4_subnet_id, 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 "
2495 "LEFT JOIN dhcp4_options AS o "
2496 "ON h.host_id = o.host_id "
2497 "WHERE h.dhcp4_subnet_id = ? "
2498 "ORDER BY h.host_id, o.option_id"},
2504 {MySqlHostDataSourceImpl::GET_HOST_SUBID6,
2505 "SELECT h.host_id, h.dhcp_identifier, "
2506 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2507 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2508 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2509 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2510 "h.dhcp4_boot_file_name, h.auth_key, "
2511 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2512 "o.persistent, o.cancelled, o.user_context, "
2513 "r.reservation_id, r.address, r.prefix_len, r.type, "
2516 "LEFT JOIN dhcp6_options AS o "
2517 "ON h.host_id = o.host_id "
2518 "LEFT JOIN ipv6_reservations AS r "
2519 "ON h.host_id = r.host_id "
2520 "WHERE h.dhcp6_subnet_id = ? "
2521 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2527 {MySqlHostDataSourceImpl::GET_HOST_HOSTNAME,
2528 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2529 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, "
2530 "h.hostname, h.dhcp4_client_classes, h.dhcp6_client_classes, "
2532 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2533 "h.dhcp4_boot_file_name, h.auth_key, "
2534 "o4.option_id, o4.code, o4.value, o4.formatted_value, o4.space, "
2535 "o4.persistent, o4.cancelled, o4.user_context, "
2536 "o6.option_id, o6.code, o6.value, o6.formatted_value, o6.space, "
2537 "o6.persistent, o6.cancelled, o6.user_context, "
2538 "r.reservation_id, r.address, r.prefix_len, r.type, "
2541 "LEFT JOIN dhcp4_options AS o4 "
2542 "ON h.host_id = o4.host_id "
2543 "LEFT JOIN dhcp6_options AS o6 "
2544 "ON h.host_id = o6.host_id "
2545 "LEFT JOIN ipv6_reservations AS r "
2546 "ON h.host_id = r.host_id "
2547 "WHERE h.hostname = ? "
2548 "ORDER BY h.host_id, o4.option_id, o6.option_id, r.reservation_id"},
2553 {MySqlHostDataSourceImpl::GET_HOST_HOSTNAME_SUBID4,
2554 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2555 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2556 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2557 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2558 "h.dhcp4_boot_file_name, h.auth_key, "
2559 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2560 "o.persistent, o.cancelled, o.user_context "
2562 "LEFT JOIN dhcp4_options AS o "
2563 "ON h.host_id = o.host_id "
2564 "WHERE h.hostname = ? AND h.dhcp4_subnet_id = ? "
2565 "ORDER BY h.host_id, o.option_id"},
2570 {MySqlHostDataSourceImpl::GET_HOST_HOSTNAME_SUBID6,
2571 "SELECT h.host_id, h.dhcp_identifier, "
2572 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2573 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2574 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2575 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2576 "h.dhcp4_boot_file_name, h.auth_key, "
2577 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2578 "o.persistent, o.cancelled, o.user_context, "
2579 "r.reservation_id, r.address, r.prefix_len, r.type, "
2582 "LEFT JOIN dhcp6_options AS o "
2583 "ON h.host_id = o.host_id "
2584 "LEFT JOIN ipv6_reservations AS r "
2585 "ON h.host_id = r.host_id "
2586 "WHERE h.hostname = ? AND h.dhcp6_subnet_id = ? "
2587 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2594 {MySqlHostDataSourceImpl::GET_HOST_SUBID4_PAGE,
2595 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2596 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2597 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2598 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2599 "h.dhcp4_boot_file_name, h.auth_key, "
2600 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2601 "o.persistent, o.cancelled, o.user_context "
2602 "FROM ( SELECT * FROM hosts AS h "
2603 "WHERE h.dhcp4_subnet_id = ? AND h.host_id > ? "
2604 "ORDER BY h.host_id "
2606 "LEFT JOIN dhcp4_options AS o "
2607 "ON h.host_id = o.host_id "
2608 "ORDER BY h.host_id, o.option_id"},
2615 {MySqlHostDataSourceImpl::GET_HOST_SUBID6_PAGE,
2616 "SELECT h.host_id, h.dhcp_identifier, "
2617 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2618 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2619 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2620 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2621 "h.dhcp4_boot_file_name, h.auth_key, "
2622 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2623 "o.persistent, o.cancelled, o.user_context, "
2624 "r.reservation_id, r.address, r.prefix_len, r.type, "
2626 "FROM ( SELECT * FROM hosts AS h "
2627 "WHERE h.dhcp6_subnet_id = ? AND h.host_id > ? "
2628 "ORDER BY h.host_id "
2630 "LEFT JOIN dhcp6_options AS o "
2631 "ON h.host_id = o.host_id "
2632 "LEFT JOIN ipv6_reservations AS r "
2633 "ON h.host_id = r.host_id "
2634 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2641 {MySqlHostDataSourceImpl::GET_HOST_PAGE4,
2642 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2643 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2644 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2645 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2646 "h.dhcp4_boot_file_name, h.auth_key, "
2647 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2648 "o.persistent, o.cancelled, o.user_context "
2649 "FROM ( SELECT * FROM hosts AS h "
2650 "WHERE h.host_id > ? "
2651 "ORDER BY h.host_id "
2653 "LEFT JOIN dhcp4_options AS o "
2654 "ON h.host_id = o.host_id "
2655 "ORDER BY h.host_id, o.option_id"},
2662 {MySqlHostDataSourceImpl::GET_HOST_PAGE6,
2663 "SELECT h.host_id, h.dhcp_identifier, "
2664 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2665 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2666 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2667 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2668 "h.dhcp4_boot_file_name, h.auth_key, "
2669 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2670 "o.persistent, o.cancelled, o.user_context, "
2671 "r.reservation_id, r.address, r.prefix_len, r.type, "
2673 "FROM ( SELECT * FROM hosts AS h "
2674 "WHERE h.host_id > ? "
2675 "ORDER BY h.host_id "
2677 "LEFT JOIN dhcp6_options AS o "
2678 "ON h.host_id = o.host_id "
2679 "LEFT JOIN ipv6_reservations AS r "
2680 "ON h.host_id = r.host_id "
2681 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2685 {MySqlHostDataSourceImpl::INSERT_HOST_NON_UNIQUE_IP,
2686 "INSERT INTO hosts(host_id, dhcp_identifier, dhcp_identifier_type, "
2687 "dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, "
2688 "dhcp4_client_classes, dhcp6_client_classes, "
2689 "user_context, dhcp4_next_server, "
2690 "dhcp4_server_hostname, dhcp4_boot_file_name, auth_key) "
2691 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
2704 {MySqlHostDataSourceImpl::INSERT_HOST_UNIQUE_IP,
2705 "INSERT INTO hosts(host_id, dhcp_identifier, dhcp_identifier_type, "
2706 "dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, "
2707 "dhcp4_client_classes, dhcp6_client_classes, "
2708 "user_context, dhcp4_next_server, "
2709 "dhcp4_server_hostname, dhcp4_boot_file_name, auth_key) "
2710 "SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? FROM DUAL "
2711 "WHERE NOT EXISTS ("
2712 "SELECT 1 FROM hosts "
2713 "WHERE ipv4_address = ? AND dhcp4_subnet_id = ? "
2719 {MySqlHostDataSourceImpl::INSERT_V6_RESRV_NON_UNIQUE,
2720 "INSERT INTO ipv6_reservations(address, prefix_len, type, "
2721 "dhcp6_iaid, host_id) "
2722 "VALUES (?, ?, ?, ?, ?)"},
2726 {MySqlHostDataSourceImpl::INSERT_V6_RESRV_UNIQUE,
2727 "INSERT INTO ipv6_reservations(address, prefix_len, type, "
2728 "dhcp6_iaid, host_id) "
2729 "SELECT ?, ?, ?, ?, ? FROM DUAL "
2730 "WHERE NOT EXISTS ("
2731 "SELECT 1 FROM ipv6_reservations "
2732 "WHERE address = ? AND prefix_len = ? "
2738 {MySqlHostDataSourceImpl::INSERT_V4_HOST_OPTION,
2739 "INSERT INTO dhcp4_options(option_id, code, value, formatted_value, space, "
2740 "persistent, cancelled, user_context, dhcp4_subnet_id, host_id, scope_id) "
2741 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 3)"},
2745 {MySqlHostDataSourceImpl::INSERT_V6_HOST_OPTION,
2746 "INSERT INTO dhcp6_options(option_id, code, value, formatted_value, space, "
2747 "persistent, cancelled, user_context, dhcp6_subnet_id, host_id, scope_id) "
2748 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 3)"},
2751 {MySqlHostDataSourceImpl::DEL_HOST_ADDR4,
2752 "DELETE FROM hosts WHERE dhcp4_subnet_id = ? AND ipv4_address = ?"},
2755 {MySqlHostDataSourceImpl::DEL_HOST_ADDR6,
2756 "DELETE h FROM hosts AS h "
2757 "INNER JOIN ipv6_reservations AS r "
2758 "ON h.host_id = r.host_id "
2759 "WHERE h.dhcp6_subnet_id = ? AND r.address = ?"},
2762 {MySqlHostDataSourceImpl::DEL_HOST_SUBID4_ID,
2763 "DELETE FROM hosts WHERE dhcp4_subnet_id = ? AND dhcp_identifier_type=? "
2764 "AND dhcp_identifier = ?"},
2767 {MySqlHostDataSourceImpl::DEL_HOST_SUBID6_ID,
2768 "DELETE FROM hosts WHERE dhcp6_subnet_id = ? AND dhcp_identifier_type=? "
2769 "AND dhcp_identifier = ?"}
2780 : conn_(parameters, io_service_accessor, db_reconnect_callback),
2781 is_readonly_(true) {
2789 if (MultiThreadingMgr::instance().getMode()) {
2793 lock_guard<mutex> lock(mgr_.
pool_->mutex_);
2794 if (!mgr_.
pool_->pool_.empty()) {
2796 mgr_.
pool_->pool_.pop_back();
2804 if (mgr_.
pool_->pool_.empty()) {
2812 if (MultiThreadingMgr::instance().getMode()) {
2814 lock_guard<mutex> lock(mgr_.pool_->mutex_);
2815 mgr_.pool_->pool_.push_back(ctx_);
2816 if (ctx_->conn_.isUnusable()) {
2817 mgr_.unusable_ =
true;
2819 }
else if (ctx_->conn_.isUnusable()) {
2820 mgr_.unusable_ =
true;
2825 : parameters_(parameters), ip_reservations_unique_(true), unusable_(false),
2830 timer_name_ += boost::lexical_cast<std::string>(
reinterpret_cast<uint64_t
>(
this));
2836 std::pair<uint32_t, uint32_t> db_version =
getVersion();
2837 if (code_version != db_version) {
2839 "MySQL schema version mismatch: need version: "
2840 << code_version.first <<
"." << code_version.second
2841 <<
" found version: " << db_version.first <<
"."
2842 << db_version.second);
2859 ctx->conn_.openDatabase();
2862 if (ctx->conn_.getTls()) {
2863 std::string cipher = ctx->conn_.getTlsCipher();
2864 if (cipher.empty()) {
2876 ctx->conn_.prepareStatements(tagged_statements.begin(),
2881 ctx->is_readonly_ = ctx->conn_.configuredReadOnly();
2885 if (!ctx->is_readonly_) {
2888 tagged_statements.end());
2895 ctx->host_ipv4_exchange_.reset(
new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY));
2896 ctx->host_ipv6_exchange_.reset(
new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP6_ONLY));
2897 ctx->host_ipv46_exchange_.reset(
new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP4_AND_DHCP6));
2898 ctx->host_ipv6_reservation_exchange_.reset(
new MySqlIPv6ReservationExchange());
2899 ctx->host_option_exchange_.reset(
new MySqlOptionExchange());
2919 bool reopened =
false;
2921 const std::string timer_name = db_reconnect_ctl->timerName();
2926 std::list<std::string> host_db_access_list = cfg_db->getHostDbAccessStringList();
2927 for (std::string& hds : host_db_access_list) {
2934 }
catch (
const std::exception& ex) {
2950 if (!db_reconnect_ctl->checkRetries()) {
2953 .arg(db_reconnect_ctl->maxRetries());
2966 .arg(db_reconnect_ctl->maxRetries() - db_reconnect_ctl->retriesLeft() + 1)
2967 .arg(db_reconnect_ctl->maxRetries())
2968 .arg(db_reconnect_ctl->retryInterval());
2974 db_reconnect_ctl->retryInterval(),
2983 std::pair<uint32_t, uint32_t>
2994 std::vector<MYSQL_BIND>& bind) {
2996 int status = mysql_stmt_bind_param(ctx->conn_.statements_[stindex], &bind[0]);
2997 checkError(ctx, status, stindex,
"unable to bind parameters");
3004 if (mysql_errno(ctx->conn_.mysql_) == ER_DUP_ENTRY) {
3007 checkError(ctx, status, stindex,
"unable to execute");
3015 my_ulonglong numrows = mysql_stmt_affected_rows(ctx->conn_.statements_[stindex]);
3026 int status = mysql_stmt_bind_param(ctx->conn_.statements_[stindex], &bind[0]);
3027 checkError(ctx, status, stindex,
"unable to bind parameters");
3033 checkError(ctx, status, stindex,
"unable to execute");
3037 my_ulonglong numrows = mysql_stmt_affected_rows(ctx->conn_.statements_[stindex]);
3039 return (numrows != 0);
3046 std::vector<MYSQL_BIND> bind = ctx->host_ipv6_reservation_exchange_->
3056 const std::string& opt_space,
3059 std::vector<MYSQL_BIND> bind = ctx->host_option_exchange_->createBindForSend(opt_desc, opt_space, subnet_id,
id);
3068 const uint64_t host_id) {
3071 std::list<std::string> option_spaces = options_cfg->getOptionSpaceNames();
3072 std::list<std::string> vendor_spaces = options_cfg->getVendorIdsSpaceNames();
3073 option_spaces.insert(option_spaces.end(), vendor_spaces.begin(),
3074 vendor_spaces.end());
3078 for (
auto space = option_spaces.begin(); space != option_spaces.end(); ++space) {
3080 if (options && !options->empty()) {
3081 for (
auto opt = options->begin(); opt != options->end(); ++opt) {
3092 const char* what)
const {
3093 ctx->conn_.checkError(status, index, what);
3100 boost::shared_ptr<MySqlHostExchange> exchange,
3102 bool single)
const {
3105 int status = mysql_stmt_bind_param(ctx->conn_.statements_[stindex], bind);
3106 checkError(ctx, status, stindex,
"unable to bind WHERE clause parameter");
3110 std::vector<MYSQL_BIND> outbind = exchange->createBindForReceive();
3111 status = mysql_stmt_bind_result(ctx->conn_.statements_[stindex], &outbind[0]);
3112 checkError(ctx, status, stindex,
"unable to bind SELECT clause parameters");
3116 checkError(ctx, status, stindex,
"unable to execute");
3120 status = mysql_stmt_store_result(ctx->conn_.statements_[stindex]);
3121 checkError(ctx, status, stindex,
"unable to set up for storing all results");
3128 while ((status = mysql_stmt_fetch(ctx->conn_.statements_[stindex])) ==
3131 exchange->processFetchedData(result);
3136 ctx->conn_.text_statements_[stindex] <<
">");
3139 if (single && (result.size() > 1)) {
3141 "database where only one was expected for query "
3142 << ctx->conn_.text_statements_[stindex]);
3150 checkError(ctx, status, stindex,
"unable to fetch results");
3152 }
else if (status == MYSQL_DATA_TRUNCATED) {
3155 <<
" returned truncated data: columns affected are "
3156 << exchange->getErrorColumns());
3164 const uint8_t* identifier_begin,
3165 const size_t identifier_len,
3167 boost::shared_ptr<MySqlHostExchange> exchange)
const {
3170 MYSQL_BIND inbind[3];
3171 memset(inbind, 0,
sizeof(inbind));
3173 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3174 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3175 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3179 std::vector<char> identifier_vec(identifier_begin,
3180 identifier_begin + identifier_len);
3181 unsigned long length = identifier_vec.size();
3182 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3183 inbind[2].buffer = &identifier_vec[0];
3184 inbind[2].buffer_length = length;
3185 inbind[2].length = &length;
3188 char identifier_type_copy =
static_cast<char>(identifier_type);
3189 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3190 inbind[1].buffer =
reinterpret_cast<char*
>(&identifier_type_copy);
3198 if (!collection.empty()) {
3199 result = *collection.begin();
3207 if (ctx->is_readonly_) {
3209 " operate in read only mode");
3222 return (impl_->parameters_);
3232 impl_->checkReadOnly(ctx);
3244 bool unique_ip = impl_->ip_reservations_unique_ && !host->getIPv4Reservation().isV4Zero()
3245 && host->getIPv4SubnetID() != SUBNET_ID_UNUSED;
3248 std::vector<MYSQL_BIND> bind = ctx->host_ipv4_exchange_->createBindForSend(host, unique_ip);
3255 uint64_t host_id = mysql_insert_id(ctx->conn_.mysql_);
3261 cfg_option4, host_id);
3268 cfg_option6, host_id);
3273 if (std::distance(v6resv.first, v6resv.second) > 0) {
3276 impl_->addResv(ctx, resv->second, host_id);
3292 impl_->checkReadOnly(ctx);
3295 MYSQL_BIND inbind[2];
3297 uint32_t subnet = subnet_id;
3298 memset(inbind, 0,
sizeof(inbind));
3299 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3300 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3306 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3307 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3314 std::string addr_str = addr.
toText();
3315 unsigned long addr_len = addr_str.size();
3316 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3317 inbind[1].buffer =
reinterpret_cast<char*
>
3318 (
const_cast<char*
>(addr_str.c_str()));
3319 inbind[1].length = &addr_len;
3320 inbind[1].buffer_length = addr_len;
3328 const uint8_t* identifier_begin,
3329 const size_t identifier_len) {
3335 impl_->checkReadOnly(ctx);
3338 MYSQL_BIND inbind[3];
3341 memset(inbind, 0,
sizeof(inbind));
3342 uint32_t subnet =
static_cast<uint32_t
>(subnet_id);
3343 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3344 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3348 char identifier_type_copy =
static_cast<char>(identifier_type);
3349 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3350 inbind[1].buffer =
reinterpret_cast<char*
>(&identifier_type_copy);
3354 std::vector<char> identifier_vec(identifier_begin,
3355 identifier_begin + identifier_len);
3356 unsigned long length = identifier_vec.size();
3357 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3358 inbind[2].buffer = &identifier_vec[0];
3359 inbind[2].buffer_length = length;
3360 inbind[2].length = &length;
3369 const uint8_t* identifier_begin,
3370 const size_t identifier_len) {
3376 impl_->checkReadOnly(ctx);
3379 MYSQL_BIND inbind[3];
3382 memset(inbind, 0,
sizeof(inbind));
3383 uint32_t subnet =
static_cast<uint32_t
>(subnet_id);
3384 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3385 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3389 char identifier_type_copy =
static_cast<char>(identifier_type);
3390 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3391 inbind[1].buffer =
reinterpret_cast<char*
>(&identifier_type_copy);
3395 std::vector<char> identifier_vec(identifier_begin,
3396 identifier_begin + identifier_len);
3397 unsigned long length = identifier_vec.size();
3398 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3399 inbind[2].buffer = &identifier_vec[0];
3400 inbind[2].buffer_length = length;
3401 inbind[2].length = &length;
3409 const uint8_t* identifier_begin,
3410 const size_t identifier_len)
const {
3416 MYSQL_BIND inbind[2];
3417 memset(inbind, 0,
sizeof(inbind));
3420 char identifier_type_copy =
static_cast<char>(identifier_type);
3421 inbind[1].buffer = &identifier_type_copy;
3422 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3426 std::vector<char> identifier_vec(identifier_begin,
3427 identifier_begin + identifier_len);
3428 unsigned long int length = identifier_vec.size();
3429 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
3430 inbind[0].buffer = &identifier_vec[0];
3431 inbind[0].buffer_length = length;
3432 inbind[0].length = &length;
3436 ctx->host_ipv46_exchange_, result,
false);
3448 MYSQL_BIND inbind[1];
3449 memset(inbind, 0,
sizeof(inbind));
3450 uint32_t subnet = subnet_id;
3451 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3452 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3457 ctx->host_ipv4_exchange_, result,
false);
3469 MYSQL_BIND inbind[1];
3470 memset(inbind, 0,
sizeof(inbind));
3471 uint32_t subnet = subnet_id;
3472 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3473 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3478 ctx->host_ipv6_exchange_, result,
false);
3490 MYSQL_BIND inbind[1];
3491 memset(inbind, 0,
sizeof(inbind));
3496 unsigned long length = hostname.length();
3497 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3498 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3499 inbind[0].buffer_length = length;
3500 inbind[0].length = &length;
3504 ctx->host_ipv46_exchange_, result,
false);
3517 MYSQL_BIND inbind[2];
3518 memset(inbind, 0,
sizeof(inbind));
3523 unsigned long length = hostname.length();
3524 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3525 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3526 inbind[0].buffer_length = length;
3527 inbind[0].length = &length;
3530 uint32_t subnet = subnet_id;
3531 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3532 inbind[1].buffer =
reinterpret_cast<char*
>(&subnet);
3537 ctx->host_ipv4_exchange_, result,
false);
3550 MYSQL_BIND inbind[2];
3551 memset(inbind, 0,
sizeof(inbind));
3556 unsigned long length = hostname.length();
3557 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3558 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3559 inbind[0].buffer_length = length;
3560 inbind[0].length = &length;
3563 uint32_t subnet = subnet_id;
3564 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3565 inbind[1].buffer =
reinterpret_cast<char*
>(&subnet);
3570 ctx->host_ipv6_exchange_, result,
false);
3578 uint64_t lower_host_id,
3585 MYSQL_BIND inbind[3];
3586 memset(inbind, 0,
sizeof(inbind));
3589 uint32_t subnet = subnet_id;
3590 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3591 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3595 uint32_t host_id = lower_host_id;
3596 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3597 inbind[1].buffer =
reinterpret_cast<char*
>(&host_id);
3601 uint32_t page_size_data = page_size.
page_size_;
3602 inbind[2].buffer_type = MYSQL_TYPE_LONG;
3603 inbind[2].buffer =
reinterpret_cast<char*
>(&page_size_data);
3608 ctx->host_ipv4_exchange_, result,
false);
3616 uint64_t lower_host_id,
3623 MYSQL_BIND inbind[3];
3624 memset(inbind, 0,
sizeof(inbind));
3627 uint32_t subnet = subnet_id;
3628 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3629 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3633 uint32_t host_id = lower_host_id;
3634 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3635 inbind[1].buffer =
reinterpret_cast<char*
>(&host_id);
3639 uint32_t page_size_data = page_size.
page_size_;
3640 inbind[2].buffer_type = MYSQL_TYPE_LONG;
3641 inbind[2].buffer =
reinterpret_cast<char*
>(&page_size_data);
3646 ctx->host_ipv6_exchange_, result,
false);
3653 uint64_t lower_host_id,
3660 MYSQL_BIND inbind[2];
3661 memset(inbind, 0,
sizeof(inbind));
3664 uint32_t host_id = lower_host_id;
3665 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3666 inbind[0].buffer =
reinterpret_cast<char*
>(&host_id);
3670 uint32_t page_size_data = page_size.
page_size_;
3671 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3672 inbind[1].buffer =
reinterpret_cast<char*
>(&page_size_data);
3677 ctx->host_ipv4_exchange_, result,
false);
3684 uint64_t lower_host_id,
3691 MYSQL_BIND inbind[2];
3692 memset(inbind, 0,
sizeof(inbind));
3695 uint32_t host_id = lower_host_id;
3696 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3697 inbind[0].buffer =
reinterpret_cast<char*
>(&host_id);
3701 uint32_t page_size_data = page_size.
page_size_;
3702 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3703 inbind[1].buffer =
reinterpret_cast<char*
>(&page_size_data);
3708 ctx->host_ipv6_exchange_, result,
false);
3720 MYSQL_BIND inbind[1];
3721 memset(inbind, 0,
sizeof(inbind));
3723 uint32_t addr4 = address.
toUint32();
3724 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3725 inbind[0].buffer =
reinterpret_cast<char*
>(&addr4);
3730 ctx->host_ipv4_exchange_, result,
false);
3738 const uint8_t* identifier_begin,
3739 const size_t identifier_len)
const {
3744 return (impl_->getHost(ctx, subnet_id, identifier_type, identifier_begin, identifier_len,
3746 ctx->host_ipv4_exchange_));
3752 if (!address.
isV4()) {
3754 "wrong address type, address supplied is an IPv6 address");
3762 MYSQL_BIND inbind[2];
3763 uint32_t subnet = subnet_id;
3764 memset(inbind, 0,
sizeof(inbind));
3765 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3766 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3769 uint32_t addr4 = address.
toUint32();
3770 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3771 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3776 ctx->host_ipv4_exchange_, collection,
true);
3780 if (!collection.empty()) {
3781 result = *collection.begin();
3790 if (!address.
isV4()) {
3792 "wrong address type, address supplied is an IPv6 address");
3800 MYSQL_BIND inbind[2];
3801 uint32_t subnet = subnet_id;
3802 memset(inbind, 0,
sizeof(inbind));
3803 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3804 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3807 uint32_t addr4 = address.
toUint32();
3808 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3809 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3814 ctx->host_ipv4_exchange_, collection,
false);
3815 return (collection);
3821 const uint8_t* identifier_begin,
3822 const size_t identifier_len)
const {
3827 return (impl_->getHost(ctx, subnet_id, identifier_type, identifier_begin, identifier_len,
3829 ctx->host_ipv6_exchange_));
3834 const uint8_t prefix_len)
const {
3835 if (!prefix.
isV6()) {
3837 "wrong address type, address supplied is an IPv4 address");
3845 MYSQL_BIND inbind[2];
3846 memset(inbind, 0,
sizeof(inbind));
3848 std::string addr6 = prefix.
toText();
3849 unsigned long addr6_length = addr6.size();
3851 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
3852 inbind[0].buffer =
reinterpret_cast<char*
>
3853 (
const_cast<char*
>(addr6.c_str()));
3854 inbind[0].length = &addr6_length;
3855 inbind[0].buffer_length = addr6_length;
3857 uint8_t tmp = prefix_len;
3858 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3859 inbind[1].buffer =
reinterpret_cast<char*
>(&tmp);
3864 ctx->host_ipv6_exchange_, collection,
true);
3868 if (!collection.empty()) {
3869 result = *collection.begin();
3878 if (!address.
isV6()) {
3880 "wrong address type, address supplied is an IPv4 address");
3888 MYSQL_BIND inbind[2];
3889 memset(inbind, 0,
sizeof(inbind));
3891 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3892 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3893 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3896 std::string addr6 = address.
toText();
3897 unsigned long addr6_length = addr6.size();
3899 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3900 inbind[1].buffer =
reinterpret_cast<char*
>
3901 (
const_cast<char*
>(addr6.c_str()));
3902 inbind[1].length = &addr6_length;
3903 inbind[1].buffer_length = addr6_length;
3907 ctx->host_ipv6_exchange_, collection,
true);
3911 if (!collection.empty()) {
3912 result = *collection.begin();
3921 if (!address.
isV6()) {
3923 "wrong address type, address supplied is an IPv4 address");
3931 MYSQL_BIND inbind[2];
3932 memset(inbind, 0,
sizeof(inbind));
3934 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3935 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3936 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3939 std::string addr6 = address.
toText();
3940 unsigned long addr6_length = addr6.size();
3942 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3943 inbind[1].buffer =
reinterpret_cast<char*
>
3944 (
const_cast<char*
>(addr6.c_str()));
3945 inbind[1].length = &addr6_length;
3946 inbind[1].buffer_length = addr6_length;
3950 ctx->host_ipv6_exchange_, collection,
false);
3951 return (collection);
3961 impl_->checkReadOnly(ctx);
3984 std::string name =
"";
3990 name = ctx->conn_.getParameter(
"name");
3999 return (std::string(
"Host data source that stores host information"
4000 "in MySQL database"));
4003 std::pair<uint32_t, uint32_t>
4005 return(impl_->getVersion());
4015 impl_->checkReadOnly(ctx);
4016 if (ctx->conn_.isTransactionStarted()) {
4017 ctx->conn_.commit();
4028 impl_->checkReadOnly(ctx);
4029 if (ctx->conn_.isTransactionStarted()) {
4030 ctx->conn_.rollback();
4036 impl_->ip_reservations_unique_ = unique;
4042 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)
std::string toText() const
Convert the address to a string.
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.
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.
const size_t ADDRESS6_TEXT_MAX_LEN
Maximum size of an IPv6 address represented as a text string.
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.