27#include <boost/algorithm/string/split.hpp>
28#include <boost/algorithm/string/classification.hpp>
29#include <boost/array.hpp>
30#include <boost/foreach.hpp>
31#include <boost/pointer_cast.hpp>
32#include <boost/static_assert.hpp>
35#include <mysqld_error.h>
85class MySqlHostExchange {
92 static const size_t HOST_ID_COL = 0;
93 static const size_t DHCP_IDENTIFIER_COL = 1;
94 static const size_t DHCP_IDENTIFIER_TYPE_COL = 2;
95 static const size_t DHCP4_SUBNET_ID_COL = 3;
96 static const size_t DHCP6_SUBNET_ID_COL = 4;
97 static const size_t IPV4_ADDRESS_COL = 5;
98 static const size_t HOSTNAME_COL = 6;
99 static const size_t DHCP4_CLIENT_CLASSES_COL = 7;
100 static const size_t DHCP6_CLIENT_CLASSES_COL = 8;
101 static const size_t USER_CONTEXT_COL = 9;
102 static const size_t DHCP4_NEXT_SERVER_COL = 10;
103 static const size_t DHCP4_SERVER_HOSTNAME_COL = 11;
104 static const size_t DHCP4_BOOT_FILE_NAME_COL = 12;
105 static const size_t AUTH_KEY_COL = 13;
108 static const size_t HOST_COLUMNS = 14;
118 MySqlHostExchange(
const size_t additional_columns_num = 0)
119 : columns_num_(HOST_COLUMNS + additional_columns_num),
120 bind_(columns_num_), columns_(columns_num_),
121 error_(columns_num_,
MLM_FALSE), host_id_(0),
122 dhcp_identifier_length_(0), dhcp_identifier_type_(0),
123 dhcp4_subnet_id_(SUBNET_ID_UNUSED),
124 dhcp6_subnet_id_(SUBNET_ID_UNUSED), ipv4_address_(0),
125 hostname_length_(0), dhcp4_client_classes_length_(0),
126 dhcp6_client_classes_length_(0),
127 user_context_length_(0),
128 dhcp4_next_server_(0),
129 dhcp4_server_hostname_length_(0),
130 dhcp4_boot_file_name_length_(0),
144 memset(dhcp_identifier_buffer_, 0,
sizeof(dhcp_identifier_buffer_));
145 memset(hostname_, 0,
sizeof(hostname_));
146 memset(dhcp4_client_classes_, 0,
sizeof(dhcp4_client_classes_));
147 memset(dhcp6_client_classes_, 0,
sizeof(dhcp6_client_classes_));
148 memset(user_context_, 0,
sizeof(user_context_));
149 memset(dhcp4_server_hostname_, 0,
sizeof(dhcp4_server_hostname_));
150 memset(dhcp4_boot_file_name_, 0,
sizeof(dhcp4_boot_file_name_));
151 memset(auth_key_, 0,
sizeof(auth_key_));
156 columns_[HOST_ID_COL] =
"host_id";
157 columns_[DHCP_IDENTIFIER_COL] =
"dhcp_identifier";
158 columns_[DHCP_IDENTIFIER_TYPE_COL] =
"dhcp_identifier_type";
159 columns_[DHCP4_SUBNET_ID_COL] =
"dhcp4_subnet_id";
160 columns_[DHCP6_SUBNET_ID_COL] =
"dhcp6_subnet_id";
161 columns_[IPV4_ADDRESS_COL] =
"ipv4_address";
162 columns_[HOSTNAME_COL] =
"hostname";
163 columns_[DHCP4_CLIENT_CLASSES_COL] =
"dhcp4_client_classes";
164 columns_[DHCP6_CLIENT_CLASSES_COL] =
"dhcp6_client_classes";
165 columns_[USER_CONTEXT_COL] =
"user_context";
166 columns_[DHCP4_NEXT_SERVER_COL] =
"dhcp4_next_server";
167 columns_[DHCP4_SERVER_HOSTNAME_COL] =
"dhcp4_server_hostname";
168 columns_[DHCP4_BOOT_FILE_NAME_COL] =
"dhcp4_boot_file_name";
169 columns_[AUTH_KEY_COL] =
"auth_key";
171 BOOST_STATIC_ASSERT(13 < HOST_COLUMNS);
175 virtual ~MySqlHostExchange() {
192 size_t findAvailColumn()
const {
193 std::vector<std::string>::const_iterator empty_column =
194 std::find(columns_.begin(), columns_.end(), std::string());
195 return (std::distance(columns_.begin(), empty_column));
201 uint64_t getHostId()
const {
215 static void setErrorIndicators(std::vector<MYSQL_BIND>& bind,
216 std::vector<my_bools>&
error) {
217 for (
size_t i = 0; i <
error.size(); ++i) {
236 static std::string getColumnsInError(std::vector<my_bools>&
error,
237 const std::vector<std::string>& names) {
241 for (
size_t i = 0; i < names.size(); ++i) {
269 std::vector<MYSQL_BIND> createBindForSend(
const HostPtr& host,
const bool unique_ip) {
277 memset(&bind_[0], 0,
sizeof(MYSQL_BIND) * bind_.size());
286 bind_[0].buffer_type = MYSQL_TYPE_LONG;
287 bind_[0].buffer =
reinterpret_cast<char*
>(&host_id_);
291 dhcp_identifier_length_ = host->getIdentifier().size();
292 memcpy(
static_cast<void*
>(dhcp_identifier_buffer_),
293 &(host->getIdentifier())[0],
294 host->getIdentifier().size());
296 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
297 bind_[1].buffer = dhcp_identifier_buffer_;
298 bind_[1].buffer_length = dhcp_identifier_length_;
299 bind_[1].length = &dhcp_identifier_length_;
302 dhcp_identifier_type_ =
static_cast<uint8_t
>(host->getIdentifierType());
303 bind_[2].buffer_type = MYSQL_TYPE_TINY;
304 bind_[2].buffer =
reinterpret_cast<char*
>(&dhcp_identifier_type_);
310 dhcp4_subnet_id_ = host->getIPv4SubnetID();
311 dhcp4_subnet_id_null_ = host->getIPv4SubnetID() == SUBNET_ID_UNUSED ?
MLM_TRUE :
MLM_FALSE;
312 bind_[3].buffer_type = MYSQL_TYPE_LONG;
313 bind_[3].buffer =
reinterpret_cast<char*
>(&dhcp4_subnet_id_);
315 bind_[3].is_null = &dhcp4_subnet_id_null_;
320 dhcp6_subnet_id_ = host->getIPv6SubnetID();
321 dhcp6_subnet_id_null_ = host->getIPv6SubnetID() == SUBNET_ID_UNUSED ?
MLM_TRUE :
MLM_FALSE;
322 bind_[4].buffer_type = MYSQL_TYPE_LONG;
323 bind_[4].buffer =
reinterpret_cast<char*
>(&dhcp6_subnet_id_);
325 bind_[4].is_null = &dhcp6_subnet_id_null_;
330 ipv4_address_ = host->getIPv4Reservation().toUint32();
332 bind_[5].buffer_type = MYSQL_TYPE_LONG;
333 bind_[5].buffer =
reinterpret_cast<char*
>(&ipv4_address_);
335 bind_[5].is_null = &ipv4_address_null_;
339 hostname_length_ = host->getHostname().length();
340 bind_[6].buffer_type = MYSQL_TYPE_STRING;
341 bind_[6].buffer =
reinterpret_cast<char*
>(hostname_);
342 bind_[6].buffer_length = hostname_length_;
345 bind_[7].buffer_type = MYSQL_TYPE_STRING;
347 string classes4_txt = host->getClientClasses4().toText(
",");
349 bind_[7].buffer = dhcp4_client_classes_;
350 bind_[7].buffer_length = classes4_txt.length();
353 bind_[8].buffer_type = MYSQL_TYPE_STRING;
355 string classes6_txt = host->getClientClasses6().toText(
",");
357 bind_[8].buffer = dhcp6_client_classes_;
358 bind_[8].buffer_length = classes6_txt.length();
363 bind_[9].buffer_type = MYSQL_TYPE_STRING;
364 string ctx_txt = ctx->str();
366 bind_[9].buffer = user_context_;
367 bind_[9].buffer_length = ctx_txt.length();
369 bind_[9].buffer_type = MYSQL_TYPE_NULL;
375 dhcp4_next_server_ = host->getNextServer().toUint32();
376 bind_[10].buffer_type = MYSQL_TYPE_LONG;
377 bind_[10].buffer =
reinterpret_cast<char*
>(&dhcp4_next_server_);
383 bind_[11].buffer_type = MYSQL_TYPE_STRING;
384 std::string server_hostname = host->getServerHostname();
385 strncpy(dhcp4_server_hostname_, server_hostname.c_str(),
387 bind_[11].buffer = dhcp4_server_hostname_;
388 bind_[11].buffer_length = server_hostname.length();
391 bind_[12].buffer_type = MYSQL_TYPE_STRING;
392 std::string boot_file_name = host->getBootFileName();
393 strncpy(dhcp4_boot_file_name_, boot_file_name.c_str(),
395 bind_[12].buffer = dhcp4_boot_file_name_;
396 bind_[12].buffer_length = boot_file_name.length();
399 bind_[13].buffer_type = MYSQL_TYPE_STRING;
400 std::string auth_key = host->getKey().toText();
403 bind_[13].buffer = auth_key_;
404 bind_[13].buffer_length = auth_key.length();
406 }
catch (
const std::exception& ex) {
408 "Could not create bind array from Host: "
409 << host->getHostname() <<
", reason: " << ex.what());
413 std::vector<MYSQL_BIND> vec(bind_.begin(), bind_.begin() + HOST_COLUMNS);
419 vec.push_back(bind_[5]);
420 vec.push_back(bind_[3]);
432 virtual std::vector<MYSQL_BIND> createBindForReceive() {
439 memset(&bind_[0], 0,
sizeof(MYSQL_BIND) * bind_.size());
442 bind_[0].buffer_type = MYSQL_TYPE_LONG;
443 bind_[0].buffer =
reinterpret_cast<char*
>(&host_id_);
447 dhcp_identifier_length_ =
sizeof(dhcp_identifier_buffer_);
448 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
449 bind_[1].buffer =
reinterpret_cast<char*
>(dhcp_identifier_buffer_);
450 bind_[1].buffer_length = dhcp_identifier_length_;
451 bind_[1].length = &dhcp_identifier_length_;
454 bind_[2].buffer_type = MYSQL_TYPE_TINY;
455 bind_[2].buffer =
reinterpret_cast<char*
>(&dhcp_identifier_type_);
460 bind_[3].buffer_type = MYSQL_TYPE_LONG;
461 bind_[3].buffer =
reinterpret_cast<char*
>(&dhcp4_subnet_id_);
463 bind_[3].is_null = &dhcp4_subnet_id_null_;
467 bind_[4].buffer_type = MYSQL_TYPE_LONG;
468 bind_[4].buffer =
reinterpret_cast<char*
>(&dhcp6_subnet_id_);
470 bind_[4].is_null = &dhcp6_subnet_id_null_;
474 bind_[5].buffer_type = MYSQL_TYPE_LONG;
475 bind_[5].buffer =
reinterpret_cast<char*
>(&ipv4_address_);
477 bind_[5].is_null = &ipv4_address_null_;
481 hostname_length_ =
sizeof(hostname_);
482 bind_[6].buffer_type = MYSQL_TYPE_STRING;
483 bind_[6].buffer =
reinterpret_cast<char*
>(hostname_);
484 bind_[6].buffer_length = hostname_length_;
485 bind_[6].length = &hostname_length_;
486 bind_[6].is_null = &hostname_null_;
490 dhcp4_client_classes_length_ =
sizeof(dhcp4_client_classes_);
491 bind_[7].buffer_type = MYSQL_TYPE_STRING;
492 bind_[7].buffer =
reinterpret_cast<char*
>(dhcp4_client_classes_);
493 bind_[7].buffer_length = dhcp4_client_classes_length_;
494 bind_[7].length = &dhcp4_client_classes_length_;
495 bind_[7].is_null = &dhcp4_client_classes_null_;
499 dhcp6_client_classes_length_ =
sizeof(dhcp6_client_classes_);
500 bind_[8].buffer_type = MYSQL_TYPE_STRING;
501 bind_[8].buffer =
reinterpret_cast<char*
>(dhcp6_client_classes_);
502 bind_[8].buffer_length = dhcp6_client_classes_length_;
503 bind_[8].length = &dhcp6_client_classes_length_;
504 bind_[8].is_null = &dhcp6_client_classes_null_;
508 user_context_length_ =
sizeof(user_context_);
509 bind_[9].buffer_type = MYSQL_TYPE_STRING;
510 bind_[9].buffer =
reinterpret_cast<char*
>(user_context_);
511 bind_[9].buffer_length = user_context_length_;
512 bind_[9].length = &user_context_length_;
513 bind_[9].is_null = &user_context_null_;
517 bind_[10].buffer_type = MYSQL_TYPE_LONG;
518 bind_[10].buffer =
reinterpret_cast<char*
>(&dhcp4_next_server_);
520 bind_[10].is_null = &dhcp4_next_server_null_;
524 dhcp4_server_hostname_length_ =
sizeof(dhcp4_server_hostname_);
525 bind_[11].buffer_type = MYSQL_TYPE_STRING;
526 bind_[11].buffer =
reinterpret_cast<char*
>(dhcp4_server_hostname_);
527 bind_[11].buffer_length = dhcp4_server_hostname_length_;
528 bind_[11].length = &dhcp4_server_hostname_length_;
529 bind_[11].is_null = &dhcp4_server_hostname_null_;
533 dhcp4_boot_file_name_length_ =
sizeof(dhcp4_boot_file_name_);
534 bind_[12].buffer_type = MYSQL_TYPE_STRING;
535 bind_[12].buffer =
reinterpret_cast<char*
>(dhcp4_boot_file_name_);
536 bind_[12].buffer_length = dhcp4_boot_file_name_length_;
537 bind_[12].length = &dhcp4_boot_file_name_length_;
538 bind_[12].is_null = &dhcp4_boot_file_name_null_;
542 auth_key_length_ =
sizeof(auth_key_);
543 bind_[13].buffer_type = MYSQL_TYPE_STRING;
544 bind_[13].buffer =
reinterpret_cast<char*
>(auth_key_);
545 bind_[13].buffer_length = auth_key_length_;
546 bind_[13].length = &auth_key_length_;
547 bind_[13].is_null = &auth_key_null_;
550 setErrorIndicators(bind_, error_);
567 if (dhcp_identifier_type_ > MAX_IDENTIFIER_TYPE) {
568 isc_throw(BadValue,
"invalid dhcp identifier type returned: "
569 <<
static_cast<int>(dhcp_identifier_type_));
578 SubnetID ipv4_subnet_id(SUBNET_ID_UNUSED);
579 if (dhcp4_subnet_id_null_ ==
MLM_FALSE) {
580 ipv4_subnet_id = dhcp4_subnet_id_;
585 SubnetID ipv6_subnet_id(SUBNET_ID_UNUSED);
586 if (dhcp6_subnet_id_null_ ==
MLM_FALSE) {
587 ipv6_subnet_id = dhcp6_subnet_id_;
594 ipv4_reservation = asiolink::IOAddress(ipv4_address_);
599 std::string hostname;
601 hostname = std::string(hostname_, hostname_length_);
605 std::string dhcp4_client_classes;
606 if (dhcp4_client_classes_null_ ==
MLM_FALSE) {
607 dhcp4_client_classes = std::string(dhcp4_client_classes_,
608 dhcp4_client_classes_length_);
612 std::string dhcp6_client_classes;
613 if (dhcp6_client_classes_null_ ==
MLM_FALSE) {
614 dhcp6_client_classes = std::string(dhcp6_client_classes_,
615 dhcp6_client_classes_length_);
619 std::string user_context;
621 user_context_[user_context_length_] =
'\0';
622 user_context.assign(user_context_);
627 if (dhcp4_next_server_null_ ==
MLM_FALSE) {
628 next_server = asiolink::IOAddress(dhcp4_next_server_);
632 std::string dhcp4_server_hostname;
633 if (dhcp4_server_hostname_null_ ==
MLM_FALSE) {
634 dhcp4_server_hostname = std::string(dhcp4_server_hostname_,
635 dhcp4_server_hostname_length_);
639 std::string dhcp4_boot_file_name;
640 if (dhcp4_boot_file_name_null_ ==
MLM_FALSE) {
641 dhcp4_boot_file_name = std::string(dhcp4_boot_file_name_,
642 dhcp4_boot_file_name_length_);
646 std::string auth_key;
648 auth_key = std::string(auth_key_, auth_key_length_);
652 HostPtr h(
new Host(dhcp_identifier_buffer_, dhcp_identifier_length_,
653 type, ipv4_subnet_id, ipv6_subnet_id, ipv4_reservation,
654 hostname, dhcp4_client_classes, dhcp6_client_classes,
655 next_server, dhcp4_server_hostname,
656 dhcp4_boot_file_name, AuthKey(auth_key)));
657 h->setHostId(host_id_);
660 if (!user_context.empty()) {
664 isc_throw(BadValue,
"user context '" << user_context
665 <<
"' is not a JSON map");
668 }
catch (
const isc::data::JSONError& ex) {
669 isc_throw(BadValue,
"user context '" << user_context
670 <<
"' is invalid JSON: " << ex.
what());
695 if (hosts.empty() || (hosts.back()->getHostId() != getHostId())) {
698 host = retrieveHost();
699 hosts.push_back(host);
713 std::string getErrorColumns() {
714 return (getColumnsInError(error_, columns_));
723 std::vector<MYSQL_BIND> bind_;
726 std::vector<std::string> columns_;
729 std::vector<my_bools> error_;
745 unsigned long dhcp_identifier_length_;
749 uint8_t dhcp_identifier_type_;
752 uint32_t dhcp4_subnet_id_;
755 uint32_t dhcp6_subnet_id_;
758 uint32_t ipv4_address_;
764 unsigned long hostname_length_;
771 unsigned long dhcp4_client_classes_length_;
778 unsigned long dhcp6_client_classes_length_;
784 unsigned long user_context_length_;
787 uint32_t dhcp4_next_server_;
793 unsigned long dhcp4_server_hostname_length_;
799 unsigned long dhcp4_boot_file_name_length_;
805 unsigned long auth_key_length_;
824 my_bool dhcp4_client_classes_null_;
828 my_bool dhcp6_client_classes_null_;
834 my_bool dhcp4_next_server_null_;
837 my_bool dhcp4_server_hostname_null_;
840 my_bool dhcp4_boot_file_name_null_;
857class MySqlHostWithOptionsExchange :
public MySqlHostExchange {
861 static const size_t OPTION_COLUMNS = 8;
877 class OptionProcessor {
887 const size_t start_column)
888 : universe_(universe), start_column_(start_column), option_id_(0),
889 code_(0), value_length_(0), formatted_value_length_(0),
890 space_length_(0), persistent_(false), cancelled_(false),
891 user_context_length_(0),
895 option_id_index_(start_column), code_index_(start_column_ + 1),
896 value_index_(start_column_ + 2),
897 formatted_value_index_(start_column_ + 3),
898 space_index_(start_column_ + 4),
899 persistent_index_(start_column_ + 5),
900 cancelled_index_(start_column_ + 6),
901 user_context_index_(start_column_ + 7),
902 most_recent_option_id_(0) {
904 memset(value_, 0,
sizeof(value_));
905 memset(formatted_value_, 0,
sizeof(formatted_value_));
906 memset(space_, 0,
sizeof(space_));
907 memset(user_context_, 0,
sizeof(user_context_));
911 uint64_t getOptionId()
const {
936 if ((option_id_null_ ==
MLM_TRUE) ||
937 (most_recent_option_id_ >= option_id_)) {
943 most_recent_option_id_ = option_id_;
950 space_[space_length_] =
'\0';
951 space.assign(space_);
961 std::string formatted_value;
962 if (formatted_value_null_ ==
MLM_FALSE) {
963 formatted_value_[formatted_value_length_] =
'\0';
964 formatted_value.assign(formatted_value_);
968 std::string user_context;
970 user_context_[user_context_length_] =
'\0';
971 user_context.assign(user_context_);
1015 option.reset(
new Option(universe_, code_, buf.begin(),
1018 option.reset(
new Option(universe_, code_));
1025 if (formatted_value.empty()) {
1029 option = def->optionFactory(universe_, code_, buf.begin(),
1035 std::vector<std::string> split_vec;
1036 boost::split(split_vec, formatted_value, boost::is_any_of(
","));
1037 option = def->optionFactory(universe_, code_, split_vec);
1041 OptionDescriptor desc(option, persistent_, cancelled_,
1045 if (!user_context.empty()) {
1049 isc_throw(BadValue,
"user context '" << user_context
1050 <<
"' is no a JSON map");
1052 desc.setContext(ctx);
1053 }
catch (
const isc::data::JSONError& ex) {
1054 isc_throw(BadValue,
"user context '" << user_context
1055 <<
"' is invalid JSON: " << ex.
what());
1058 cfg->add(desc, space);
1065 void setColumnNames(std::vector<std::string>& columns) {
1066 columns[option_id_index_] =
"option_id";
1067 columns[code_index_] =
"code";
1068 columns[value_index_] =
"value";
1069 columns[formatted_value_index_] =
"formatted_value";
1070 columns[space_index_] =
"space";
1071 columns[persistent_index_] =
"persistent";
1072 columns[cancelled_index_] =
"cancelled";
1073 columns[user_context_index_] =
"user_context";
1082 void setBindFields(std::vector<MYSQL_BIND>& bind) {
1086 most_recent_option_id_ = 0;
1090 persistent_ =
false;
1099 memset(value_, 0,
sizeof(value_));
1100 memset(formatted_value_, 0,
sizeof(formatted_value_));
1101 memset(space_, 0,
sizeof(space_));
1102 memset(user_context_, 0,
sizeof(user_context_));
1105 bind[option_id_index_].buffer_type = MYSQL_TYPE_LONG;
1106 bind[option_id_index_].buffer =
reinterpret_cast<char*
>(&option_id_);
1107 bind[option_id_index_].is_unsigned =
MLM_TRUE;
1108 bind[option_id_index_].is_null = &option_id_null_;
1111 bind[code_index_].buffer_type = MYSQL_TYPE_SHORT;
1112 bind[code_index_].buffer =
reinterpret_cast<char*
>(&code_);
1113 bind[code_index_].is_unsigned =
MLM_TRUE;
1114 bind[code_index_].is_null = &code_null_;
1117 value_length_ =
sizeof(value_);
1118 bind[value_index_].buffer_type = MYSQL_TYPE_BLOB;
1119 bind[value_index_].buffer =
reinterpret_cast<char*
>(value_);
1120 bind[value_index_].buffer_length = value_length_;
1121 bind[value_index_].length = &value_length_;
1122 bind[value_index_].is_null = &value_null_;
1125 formatted_value_length_ =
sizeof(formatted_value_);
1126 bind[formatted_value_index_].buffer_type = MYSQL_TYPE_STRING;
1127 bind[formatted_value_index_].buffer =
reinterpret_cast<char*
>(formatted_value_);
1128 bind[formatted_value_index_].buffer_length = formatted_value_length_;
1129 bind[formatted_value_index_].length = &formatted_value_length_;
1130 bind[formatted_value_index_].is_null = &formatted_value_null_;
1133 space_length_ =
sizeof(space_);
1134 bind[space_index_].buffer_type = MYSQL_TYPE_STRING;
1135 bind[space_index_].buffer =
reinterpret_cast<char*
>(space_);
1136 bind[space_index_].buffer_length = space_length_;
1137 bind[space_index_].length = &space_length_;
1138 bind[space_index_].is_null = &space_null_;
1141 bind[persistent_index_].buffer_type = MYSQL_TYPE_TINY;
1142 bind[persistent_index_].buffer =
reinterpret_cast<char*
>(&persistent_);
1143 bind[persistent_index_].is_unsigned =
MLM_TRUE;
1146 bind[cancelled_index_].buffer_type = MYSQL_TYPE_TINY;
1147 bind[cancelled_index_].buffer =
reinterpret_cast<char*
>(&cancelled_);
1148 bind[cancelled_index_].is_unsigned =
MLM_TRUE;
1151 user_context_length_ =
sizeof(user_context_);
1152 bind[user_context_index_].buffer_type = MYSQL_TYPE_STRING;
1153 bind[user_context_index_].buffer =
reinterpret_cast<char*
>(user_context_);
1154 bind[user_context_index_].buffer_length = user_context_length_;
1155 bind[user_context_index_].length = &user_context_length_;
1156 bind[user_context_index_].is_null = &user_context_null_;
1165 size_t start_column_;
1168 uint32_t option_id_;
1177 unsigned long value_length_;
1183 unsigned long formatted_value_length_;
1189 unsigned long space_length_;
1202 unsigned long user_context_length_;
1218 my_bool formatted_value_null_;
1230 size_t option_id_index_;
1236 size_t value_index_;
1239 size_t formatted_value_index_;
1242 size_t space_index_;
1245 size_t persistent_index_;
1248 size_t cancelled_index_;
1252 size_t user_context_index_;
1255 uint32_t most_recent_option_id_;
1259 typedef boost::shared_ptr<OptionProcessor> OptionProcessorPtr;
1269 enum FetchedOptions {
1283 MySqlHostWithOptionsExchange(
const FetchedOptions& fetched_options,
1284 const size_t additional_columns_num = 0)
1285 : MySqlHostExchange(getRequiredColumnsNum(fetched_options)
1286 + additional_columns_num),
1287 opt_proc4_(), opt_proc6_() {
1290 if ((fetched_options == DHCP4_ONLY) ||
1291 (fetched_options == DHCP4_AND_DHCP6)) {
1292 opt_proc4_.reset(
new OptionProcessor(
Option::V4,
1293 findAvailColumn()));
1294 opt_proc4_->setColumnNames(columns_);
1298 if ((fetched_options == DHCP6_ONLY) ||
1299 (fetched_options == DHCP4_AND_DHCP6)) {
1300 opt_proc6_.reset(
new OptionProcessor(
Option::V6,
1301 findAvailColumn()));
1302 opt_proc6_->setColumnNames(columns_);
1317 if (!hosts.empty()) {
1326 most_recent_host = boost::const_pointer_cast<Host>(hosts.back());
1332 if (!most_recent_host || (most_recent_host->getHostId() < getHostId())) {
1333 HostPtr host = retrieveHost();
1334 hosts.push_back(host);
1335 most_recent_host = host;
1341 opt_proc4_->retrieveOption(cfg);
1347 opt_proc6_->retrieveOption(cfg);
1354 virtual std::vector<MYSQL_BIND> createBindForReceive()
override {
1356 static_cast<void>(MySqlHostExchange::createBindForReceive());
1360 opt_proc4_->setBindFields(bind_);
1365 opt_proc6_->setBindFields(bind_);
1369 setErrorIndicators(bind_, error_);
1387 static size_t getRequiredColumnsNum(
const FetchedOptions& fetched_options) {
1388 return (fetched_options == DHCP4_AND_DHCP6 ? 2 * OPTION_COLUMNS :
1395 OptionProcessorPtr opt_proc4_;
1400 OptionProcessorPtr opt_proc6_;
1415class MySqlHostIPv6Exchange :
public MySqlHostWithOptionsExchange {
1419 static const size_t RESERVATION_COLUMNS = 5;
1427 MySqlHostIPv6Exchange(
const FetchedOptions& fetched_options)
1428 : MySqlHostWithOptionsExchange(fetched_options, RESERVATION_COLUMNS),
1430 reserv_type_(0), reserv_type_null_(
MLM_FALSE),
1431 ipv6_address_buffer_len_(0), prefix_len_(0), iaid_(0),
1432 reservation_id_index_(findAvailColumn()),
1433 address_index_(reservation_id_index_ + 1),
1434 prefix_len_index_(reservation_id_index_ + 2),
1435 type_index_(reservation_id_index_ + 3),
1436 iaid_index_(reservation_id_index_ + 4),
1437 most_recent_reservation_id_(0) {
1439 memset(ipv6_address_buffer_, 0,
sizeof(ipv6_address_buffer_));
1442 columns_[reservation_id_index_] =
"reservation_id";
1443 columns_[address_index_] =
"address";
1444 columns_[prefix_len_index_] =
"prefix_len";
1445 columns_[type_index_] =
"type";
1446 columns_[iaid_index_] =
"dhcp6_iaid";
1452 uint32_t getReservationId()
const {
1454 return (reservation_id_);
1465 IPv6Resrv retrieveReservation() {
1469 switch (reserv_type_) {
1480 "invalid IPv6 reservation type returned: "
1481 <<
static_cast<int>(reserv_type_)
1482 <<
". Only 0 or 2 are allowed.");
1486 IPv6Resrv r(type, addr6, prefix_len_);
1512 MySqlHostWithOptionsExchange::processFetchedData(hosts);
1514 if (getReservationId() == 0) {
1518 if (hosts.empty()) {
1519 isc_throw(Unexpected,
"no host information while retrieving"
1520 " IPv6 reservation");
1522 HostPtr host = boost::const_pointer_cast<Host>(hosts.back());
1526 if (getReservationId() > most_recent_reservation_id_) {
1527 most_recent_reservation_id_ = getReservationId();
1529 if (most_recent_reservation_id_ > 0) {
1530 host->addReservation(retrieveReservation());
1543 virtual std::vector<MYSQL_BIND> createBindForReceive()
override {
1546 most_recent_reservation_id_ = 0;
1549 static_cast<void>(MySqlHostWithOptionsExchange::createBindForReceive());
1552 bind_[reservation_id_index_].buffer_type = MYSQL_TYPE_LONG;
1553 bind_[reservation_id_index_].buffer =
reinterpret_cast<char*
>(&reservation_id_);
1554 bind_[reservation_id_index_].is_unsigned =
MLM_TRUE;
1557 ipv6_address_buffer_len_ = isc::asiolink::V6ADDRESS_LEN;
1558 bind_[address_index_].buffer_type = MYSQL_TYPE_BLOB;
1559 bind_[address_index_].buffer =
reinterpret_cast<char*
>(ipv6_address_buffer_);
1560 bind_[address_index_].buffer_length = ipv6_address_buffer_len_;
1561 bind_[address_index_].length = &ipv6_address_buffer_len_;
1564 bind_[prefix_len_index_].buffer_type = MYSQL_TYPE_TINY;
1565 bind_[prefix_len_index_].buffer =
reinterpret_cast<char*
>(&prefix_len_);
1566 bind_[prefix_len_index_].is_unsigned =
MLM_TRUE;
1570 bind_[type_index_].buffer_type = MYSQL_TYPE_TINY;
1571 bind_[type_index_].buffer =
reinterpret_cast<char*
>(&reserv_type_);
1572 bind_[type_index_].is_unsigned =
MLM_TRUE;
1573 bind_[type_index_].is_null = &reserv_type_null_;
1576 bind_[iaid_index_].buffer_type = MYSQL_TYPE_LONG;
1577 bind_[iaid_index_].buffer =
reinterpret_cast<char*
>(&iaid_);
1578 bind_[iaid_index_].is_unsigned =
MLM_TRUE;
1581 setErrorIndicators(bind_, error_);
1589 uint32_t reservation_id_;
1592 uint8_t reserv_type_;
1601 uint8_t ipv6_address_buffer_[isc::asiolink::V6ADDRESS_LEN];
1604 unsigned long ipv6_address_buffer_len_;
1607 uint8_t prefix_len_;
1615 size_t reservation_id_index_;
1618 size_t address_index_;
1621 size_t prefix_len_index_;
1632 uint32_t most_recent_reservation_id_;
1645class MySqlIPv6ReservationExchange {
1649 static const size_t RESRV_COLUMNS = 6;
1656 MySqlIPv6ReservationExchange()
1657 : host_id_(0), prefix_len_(0), type_(0),
1658 iaid_(0), resv_(IPv6Resrv::TYPE_NA, asiolink::IOAddress(
"::"), 128) {
1661 std::fill(&error_[0], &error_[RESRV_COLUMNS],
MLM_FALSE);
1664 columns_[0] =
"host_id";
1665 columns_[1] =
"address";
1666 columns_[2] =
"prefix_len";
1667 columns_[3] =
"type";
1668 columns_[4] =
"dhcp6_iaid";
1670 BOOST_STATIC_ASSERT(4 < RESRV_COLUMNS);
1687 std::vector<MYSQL_BIND> createBindForSend(
const IPv6Resrv& resv,
1689 const bool unique_ip) {
1700 memset(bind_, 0,
sizeof(bind_));
1706 if (addr6_.size() != isc::asiolink::V6ADDRESS_LEN) {
1707 isc_throw(DbOperationError,
"createBindForSend() - prefix is not "
1708 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
1711 addr6_length_ = isc::asiolink::V6ADDRESS_LEN;
1712 bind_[0].buffer_type = MYSQL_TYPE_BLOB;
1713 bind_[0].buffer =
reinterpret_cast<char*
>(&addr6_[0]);
1714 bind_[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
1715 bind_[0].length = &addr6_length_;
1719 bind_[1].buffer_type = MYSQL_TYPE_TINY;
1720 bind_[1].buffer =
reinterpret_cast<char*
>(&prefix_len_);
1726 bind_[2].buffer_type = MYSQL_TYPE_TINY;
1727 bind_[2].buffer =
reinterpret_cast<char*
>(&type_);
1733 bind_[3].buffer_type = MYSQL_TYPE_LONG;
1734 bind_[3].buffer =
reinterpret_cast<char*
>(&iaid_);
1738 bind_[4].buffer_type = MYSQL_TYPE_LONG;
1739 bind_[4].buffer =
reinterpret_cast<char*
>(&host_id_);
1742 }
catch (
const std::exception& ex) {
1744 "Could not create bind array from IPv6 Reservation: "
1745 << resv_.toText() <<
", reason: " << ex.what());
1751 std::vector<MYSQL_BIND> vec(&bind_[0], &bind_[RESRV_COLUMNS-1]);
1757 vec.push_back(bind_[0]);
1758 vec.push_back(bind_[1]);
1770 uint8_t prefix_len_;
1782 MYSQL_BIND bind_[RESRV_COLUMNS];
1785 std::string columns_[RESRV_COLUMNS];
1789 my_bool error_[RESRV_COLUMNS];
1792 std::vector<uint8_t> addr6_;
1795 unsigned long addr6_length_;
1801class MySqlOptionExchange {
1803 static const size_t OPTION_COLUMNS = 10;
1808 MySqlOptionExchange()
1809 : type_(0), value_len_(0), formatted_value_len_(0), space_(),
1810 space_len_(0), persistent_(false), cancelled_(false),
1811 user_context_(), user_context_len_(0), subnet_id_(SUBNET_ID_UNUSED),
1812 host_id_(0), option_() {
1814 BOOST_STATIC_ASSERT(10 <= OPTION_COLUMNS);
1820 std::vector<MYSQL_BIND> createBindForSend(
const OptionDescriptor& opt_desc,
1821 const std::string& opt_space,
1822 const Optional<SubnetID>& subnet_id,
1829 memset(bind_, 0,
sizeof(bind_));
1835 bind_[0].buffer_type = MYSQL_TYPE_NULL;
1838 type_ = option_->getType();
1839 bind_[1].buffer_type = MYSQL_TYPE_SHORT;
1840 bind_[1].buffer =
reinterpret_cast<char*
>(&type_);
1849 OutputBuffer buf(opt_desc.
option_->len());
1851 const uint8_t* buf_ptr = buf.getData();
1852 value_.assign(buf_ptr + opt_desc.
option_->getHeaderLen(),
1853 buf_ptr + buf.getLength());
1854 value_len_ = value_.size();
1855 bind_[2].buffer_type = MYSQL_TYPE_BLOB;
1856 bind_[2].buffer = &value_[0];
1857 bind_[2].buffer_length = value_len_;
1858 bind_[2].length = &value_len_;
1864 bind_[2].buffer_type = MYSQL_TYPE_NULL;
1870 bind_[3].buffer_type = MYSQL_TYPE_STRING;
1872 bind_[3].buffer_length = formatted_value_len_;
1873 bind_[3].length = &formatted_value_len_;
1876 bind_[3].buffer_type = MYSQL_TYPE_NULL;
1881 space_len_ = space_.size();
1882 bind_[4].buffer_type = MYSQL_TYPE_STRING;
1883 bind_[4].buffer =
const_cast<char*
>(space_.c_str());
1884 bind_[4].buffer_length = space_len_;
1885 bind_[4].length = &space_len_;
1889 bind_[5].buffer_type = MYSQL_TYPE_TINY;
1890 bind_[5].buffer =
reinterpret_cast<char*
>(&persistent_);
1895 bind_[6].buffer_type = MYSQL_TYPE_TINY;
1896 bind_[6].buffer =
reinterpret_cast<char*
>(&cancelled_);
1902 user_context_ = ctx->str();
1903 user_context_len_ = user_context_.size();
1904 bind_[7].buffer_type = MYSQL_TYPE_STRING;
1905 bind_[7].buffer =
const_cast<char*
>(user_context_.c_str());
1906 bind_[7].buffer_length = user_context_len_;
1907 bind_[7].length = &user_context_len_;
1909 bind_[7].buffer_type = MYSQL_TYPE_NULL;
1914 subnet_id_ = subnet_id;
1915 bind_[8].buffer_type = MYSQL_TYPE_LONG;
1916 bind_[8].buffer =
reinterpret_cast<char*
>(subnet_id_);
1920 bind_[8].buffer_type = MYSQL_TYPE_NULL;
1925 bind_[9].buffer_type = MYSQL_TYPE_LONG;
1926 bind_[9].buffer =
reinterpret_cast<char*
>(&host_id_);
1929 }
catch (
const std::exception& ex) {
1931 "Could not create bind array for inserting DHCP "
1932 "option: " << option_->toText() <<
", reason: "
1936 return (std::vector<MYSQL_BIND>(&bind_[0], &bind_[OPTION_COLUMNS]));
1945 std::vector<uint8_t> value_;
1948 unsigned long value_len_;
1951 unsigned long formatted_value_len_;
1957 unsigned long space_len_;
1968 std::string user_context_;
1971 unsigned long user_context_len_;
1974 uint32_t subnet_id_;
1983 MYSQL_BIND bind_[OPTION_COLUMNS];
2171 std::pair<uint32_t, uint32_t>
getVersion(
const std::string& timer_name = std::string())
const;
2183 std::vector<MYSQL_BIND>& bind);
2218 const std::string& opt_space,
2232 const uint64_t host_id);
2248 const char* what)
const;
2271 boost::shared_ptr<MySqlHostExchange> exchange,
2295 const uint8_t* identifier_begin,
2296 const size_t identifier_len,
2298 boost::shared_ptr<MySqlHostExchange> exchange)
const;
2332typedef boost::array<TaggedStatement, MySqlHostDataSourceImpl::NUM_STATEMENTS>
2333TaggedStatementArray;
2337TaggedStatementArray tagged_statements = { {
2343 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2344 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, "
2345 "h.hostname, h.dhcp4_client_classes, h.dhcp6_client_classes, "
2347 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2348 "h.dhcp4_boot_file_name, h.auth_key, "
2349 "o4.option_id, o4.code, o4.value, o4.formatted_value, o4.space, "
2350 "o4.persistent, o4.cancelled, o4.user_context, "
2351 "o6.option_id, o6.code, o6.value, o6.formatted_value, o6.space, "
2352 "o6.persistent, o6.cancelled, o6.user_context, "
2353 "r.reservation_id, r.address, r.prefix_len, r.type, "
2356 "LEFT JOIN dhcp4_options AS o4 "
2357 "ON h.host_id = o4.host_id "
2358 "LEFT JOIN dhcp6_options AS o6 "
2359 "ON h.host_id = o6.host_id "
2360 "LEFT JOIN ipv6_reservations AS r "
2361 "ON h.host_id = r.host_id "
2362 "WHERE dhcp_identifier = ? AND dhcp_identifier_type = ? "
2363 "ORDER BY h.host_id, o4.option_id, o6.option_id, r.reservation_id"},
2369 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2370 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2371 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2372 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2373 "h.dhcp4_boot_file_name, h.auth_key, "
2374 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2375 "o.persistent, o.cancelled, o.user_context "
2377 "LEFT JOIN dhcp4_options AS o "
2378 "ON h.host_id = o.host_id "
2379 "WHERE ipv4_address = ? "
2380 "ORDER BY h.host_id, o.option_id"},
2386 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2387 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2388 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2389 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2390 "h.dhcp4_boot_file_name, h.auth_key, "
2391 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2392 "o.persistent, o.cancelled, o.user_context "
2394 "LEFT JOIN dhcp4_options AS o "
2395 "ON h.host_id = o.host_id "
2396 "WHERE h.dhcp4_subnet_id = ? AND h.dhcp_identifier_type = ? "
2397 "AND h.dhcp_identifier = ? "
2398 "ORDER BY h.host_id, o.option_id"},
2404 "SELECT h.host_id, h.dhcp_identifier, "
2405 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2406 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2407 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2408 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2409 "h.dhcp4_boot_file_name, h.auth_key, "
2410 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2411 "o.persistent, o.cancelled, o.user_context, "
2412 "r.reservation_id, r.address, r.prefix_len, r.type, "
2415 "LEFT JOIN dhcp6_options AS o "
2416 "ON h.host_id = o.host_id "
2417 "LEFT JOIN ipv6_reservations AS r "
2418 "ON h.host_id = r.host_id "
2419 "WHERE h.dhcp6_subnet_id = ? AND h.dhcp_identifier_type = ? "
2420 "AND h.dhcp_identifier = ? "
2421 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2428 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2429 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2430 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2431 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2432 "h.dhcp4_boot_file_name, h.auth_key, "
2433 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2434 "o.persistent, o.cancelled, o.user_context "
2436 "LEFT JOIN dhcp4_options AS o "
2437 "ON h.host_id = o.host_id "
2438 "WHERE h.dhcp4_subnet_id = ? AND h.ipv4_address = ? "
2439 "ORDER BY h.host_id, o.option_id"},
2448 "SELECT h.host_id, h.dhcp_identifier, "
2449 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2450 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2451 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2452 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2453 "h.dhcp4_boot_file_name, h.auth_key, "
2454 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2455 "o.persistent, o.cancelled, o.user_context,"
2456 "r.reservation_id, r.address, r.prefix_len, r.type, "
2459 "LEFT JOIN dhcp6_options AS o "
2460 "ON h.host_id = o.host_id "
2461 "LEFT JOIN ipv6_reservations AS r "
2462 "ON h.host_id = r.host_id "
2463 "WHERE h.host_id = "
2464 "( SELECT host_id FROM ipv6_reservations "
2465 "WHERE address = ? AND prefix_len = ? ) "
2466 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2475 "SELECT h.host_id, h.dhcp_identifier, "
2476 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2477 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2478 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2479 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2480 "h.dhcp4_boot_file_name, h.auth_key, "
2481 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2482 "o.persistent, o.cancelled, o.user_context, "
2483 "r.reservation_id, r.address, r.prefix_len, r.type, "
2486 "LEFT JOIN dhcp6_options AS o "
2487 "ON h.host_id = o.host_id "
2488 "LEFT JOIN ipv6_reservations AS r "
2489 "ON h.host_id = r.host_id "
2490 "WHERE h.dhcp6_subnet_id = ? AND h.host_id IN "
2491 "(SELECT host_id FROM ipv6_reservations "
2492 "WHERE address = ?) "
2493 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2503 "SELECT h.host_id, h.dhcp_identifier, "
2504 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2505 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2506 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2507 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2508 "h.dhcp4_boot_file_name, h.auth_key, "
2509 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2510 "o.persistent, o.cancelled, o.user_context, "
2511 "r.reservation_id, r.address, r.prefix_len, r.type, "
2514 "LEFT JOIN dhcp6_options AS o "
2515 "ON h.host_id = o.host_id "
2516 "LEFT JOIN ipv6_reservations AS r "
2517 "ON h.host_id = r.host_id "
2518 "WHERE h.host_id IN "
2519 "(SELECT host_id FROM ipv6_reservations "
2520 "WHERE address = ?) "
2521 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2527 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2528 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2529 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2530 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2531 "h.dhcp4_boot_file_name, h.auth_key, "
2532 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2533 "o.persistent, o.cancelled, o.user_context "
2535 "LEFT JOIN dhcp4_options AS o "
2536 "ON h.host_id = o.host_id "
2537 "WHERE h.dhcp4_subnet_id = ? "
2538 "ORDER BY h.host_id, o.option_id"},
2545 "SELECT h.host_id, h.dhcp_identifier, "
2546 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2547 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2548 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2549 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2550 "h.dhcp4_boot_file_name, h.auth_key, "
2551 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2552 "o.persistent, o.cancelled, o.user_context, "
2553 "r.reservation_id, r.address, r.prefix_len, r.type, "
2556 "LEFT JOIN dhcp6_options AS o "
2557 "ON h.host_id = o.host_id "
2558 "LEFT JOIN ipv6_reservations AS r "
2559 "ON h.host_id = r.host_id "
2560 "WHERE h.dhcp6_subnet_id = ? "
2561 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2568 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2569 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, "
2570 "h.hostname, h.dhcp4_client_classes, h.dhcp6_client_classes, "
2572 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2573 "h.dhcp4_boot_file_name, h.auth_key, "
2574 "o4.option_id, o4.code, o4.value, o4.formatted_value, o4.space, "
2575 "o4.persistent, o4.cancelled, o4.user_context, "
2576 "o6.option_id, o6.code, o6.value, o6.formatted_value, o6.space, "
2577 "o6.persistent, o6.cancelled, o6.user_context, "
2578 "r.reservation_id, r.address, r.prefix_len, r.type, "
2581 "LEFT JOIN dhcp4_options AS o4 "
2582 "ON h.host_id = o4.host_id "
2583 "LEFT JOIN dhcp6_options AS o6 "
2584 "ON h.host_id = o6.host_id "
2585 "LEFT JOIN ipv6_reservations AS r "
2586 "ON h.host_id = r.host_id "
2587 "WHERE h.hostname = ? "
2588 "ORDER BY h.host_id, o4.option_id, o6.option_id, r.reservation_id"},
2594 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2595 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2596 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2597 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2598 "h.dhcp4_boot_file_name, h.auth_key, "
2599 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2600 "o.persistent, o.cancelled, o.user_context "
2602 "LEFT JOIN dhcp4_options AS o "
2603 "ON h.host_id = o.host_id "
2604 "WHERE h.hostname = ? AND h.dhcp4_subnet_id = ? "
2605 "ORDER BY h.host_id, o.option_id"},
2611 "SELECT h.host_id, h.dhcp_identifier, "
2612 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2613 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2614 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2615 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2616 "h.dhcp4_boot_file_name, h.auth_key, "
2617 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2618 "o.persistent, o.cancelled, o.user_context, "
2619 "r.reservation_id, r.address, r.prefix_len, r.type, "
2622 "LEFT JOIN dhcp6_options AS o "
2623 "ON h.host_id = o.host_id "
2624 "LEFT JOIN ipv6_reservations AS r "
2625 "ON h.host_id = r.host_id "
2626 "WHERE h.hostname = ? AND h.dhcp6_subnet_id = ? "
2627 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2635 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2636 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2637 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2638 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2639 "h.dhcp4_boot_file_name, h.auth_key, "
2640 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2641 "o.persistent, o.cancelled, o.user_context "
2642 "FROM ( SELECT * FROM hosts AS h "
2643 "WHERE h.dhcp4_subnet_id = ? AND h.host_id > ? "
2644 "ORDER BY h.host_id "
2646 "LEFT JOIN dhcp4_options AS o "
2647 "ON h.host_id = o.host_id "
2648 "ORDER BY h.host_id, o.option_id"},
2656 "SELECT h.host_id, h.dhcp_identifier, "
2657 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2658 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2659 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2660 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2661 "h.dhcp4_boot_file_name, h.auth_key, "
2662 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2663 "o.persistent, o.cancelled, o.user_context, "
2664 "r.reservation_id, r.address, r.prefix_len, r.type, "
2666 "FROM ( SELECT * FROM hosts AS h "
2667 "WHERE h.dhcp6_subnet_id = ? AND h.host_id > ? "
2668 "ORDER BY h.host_id "
2670 "LEFT JOIN dhcp6_options AS o "
2671 "ON h.host_id = o.host_id "
2672 "LEFT JOIN ipv6_reservations AS r "
2673 "ON h.host_id = r.host_id "
2674 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2682 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2683 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2684 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2685 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2686 "h.dhcp4_boot_file_name, h.auth_key, "
2687 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2688 "o.persistent, o.cancelled, o.user_context "
2689 "FROM ( SELECT * FROM hosts AS h "
2690 "WHERE h.host_id > ? "
2691 "ORDER BY h.host_id "
2693 "LEFT JOIN dhcp4_options AS o "
2694 "ON h.host_id = o.host_id "
2695 "ORDER BY h.host_id, o.option_id"},
2703 "SELECT h.host_id, h.dhcp_identifier, "
2704 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2705 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2706 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2707 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2708 "h.dhcp4_boot_file_name, h.auth_key, "
2709 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2710 "o.persistent, o.cancelled, o.user_context, "
2711 "r.reservation_id, r.address, r.prefix_len, r.type, "
2713 "FROM ( SELECT * FROM hosts AS h "
2714 "WHERE h.host_id > ? "
2715 "ORDER BY h.host_id "
2717 "LEFT JOIN dhcp6_options AS o "
2718 "ON h.host_id = o.host_id "
2719 "LEFT JOIN ipv6_reservations AS r "
2720 "ON h.host_id = r.host_id "
2721 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2726 "INSERT INTO hosts(host_id, dhcp_identifier, dhcp_identifier_type, "
2727 "dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, "
2728 "dhcp4_client_classes, dhcp6_client_classes, "
2729 "user_context, dhcp4_next_server, "
2730 "dhcp4_server_hostname, dhcp4_boot_file_name, auth_key) "
2731 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
2745 "INSERT INTO hosts(host_id, dhcp_identifier, dhcp_identifier_type, "
2746 "dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, "
2747 "dhcp4_client_classes, dhcp6_client_classes, "
2748 "user_context, dhcp4_next_server, "
2749 "dhcp4_server_hostname, dhcp4_boot_file_name, auth_key) "
2750 "SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? FROM DUAL "
2751 "WHERE NOT EXISTS ("
2752 "SELECT 1 FROM hosts "
2753 "WHERE ipv4_address = ? AND dhcp4_subnet_id = ? "
2760 "INSERT INTO ipv6_reservations(address, prefix_len, type, "
2761 "dhcp6_iaid, host_id) "
2762 "VALUES (?, ?, ?, ?, ?)"},
2767 "INSERT INTO ipv6_reservations(address, prefix_len, type, "
2768 "dhcp6_iaid, host_id) "
2769 "SELECT ?, ?, ?, ?, ? FROM DUAL "
2770 "WHERE NOT EXISTS ("
2771 "SELECT 1 FROM ipv6_reservations "
2772 "WHERE address = ? AND prefix_len = ? "
2779 "INSERT INTO dhcp4_options(option_id, code, value, formatted_value, space, "
2780 "persistent, cancelled, user_context, dhcp4_subnet_id, host_id, scope_id) "
2781 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 3)"},
2786 "INSERT INTO dhcp6_options(option_id, code, value, formatted_value, space, "
2787 "persistent, cancelled, user_context, dhcp6_subnet_id, host_id, scope_id) "
2788 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 3)"},
2792 "DELETE FROM hosts WHERE dhcp4_subnet_id = ? AND ipv4_address = ?"},
2796 "DELETE h FROM hosts AS h "
2797 "INNER JOIN ipv6_reservations AS r "
2798 "ON h.host_id = r.host_id "
2799 "WHERE h.dhcp6_subnet_id = ? AND r.address = ?"},
2803 "DELETE FROM hosts WHERE dhcp4_subnet_id = ? AND dhcp_identifier_type=? "
2804 "AND dhcp_identifier = ?"},
2808 "DELETE FROM hosts WHERE dhcp6_subnet_id = ? AND dhcp_identifier_type=? "
2809 "AND dhcp_identifier = ?"}
2820 :
conn_(parameters, io_service_accessor, db_reconnect_callback),
2833 lock_guard<mutex> lock(mgr_.pool_->mutex_);
2834 if (!mgr_.pool_->pool_.empty()) {
2835 ctx_ = mgr_.pool_->pool_.back();
2836 mgr_.pool_->pool_.pop_back();
2840 ctx_ = mgr_.createContext();
2844 if (mgr_.pool_->pool_.empty()) {
2847 ctx_ = mgr_.pool_->pool_.back();
2854 lock_guard<mutex> lock(mgr_.pool_->mutex_);
2855 mgr_.pool_->pool_.push_back(
ctx_);
2856 if (
ctx_->conn_.isUnusable()) {
2857 mgr_.unusable_ =
true;
2859 }
else if (
ctx_->conn_.isUnusable()) {
2860 mgr_.unusable_ =
true;
2869 timer_name_ += boost::lexical_cast<std::string>(
reinterpret_cast<uint64_t
>(
this));
2890 ctx->conn_.openDatabase();
2893 if (ctx->conn_.getTls()) {
2894 std::string cipher = ctx->conn_.getTlsCipher();
2895 if (cipher.empty()) {
2907 ctx->conn_.prepareStatements(tagged_statements.begin(),
2912 ctx->is_readonly_ = ctx->conn_.configuredReadOnly();
2916 if (!ctx->is_readonly_) {
2919 tagged_statements.end());
2926 ctx->host_ipv4_exchange_.reset(
new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY));
2927 ctx->host_ipv6_exchange_.reset(
new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP6_ONLY));
2928 ctx->host_ipv46_exchange_.reset(
new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP4_AND_DHCP6));
2929 ctx->host_ipv6_reservation_exchange_.reset(
new MySqlIPv6ReservationExchange());
2930 ctx->host_option_exchange_.reset(
new MySqlOptionExchange());
2950 bool reopened =
false;
2952 const std::string timer_name = db_reconnect_ctl->timerName();
2953 bool check = db_reconnect_ctl->checkRetries();
2958 std::list<std::string> host_db_access_list = cfg_db->getHostDbAccessStringList();
2959 for (std::string& hds : host_db_access_list) {
2966 }
catch (
const std::exception& ex) {
2985 .arg(db_reconnect_ctl->maxRetries());
2998 .arg(db_reconnect_ctl->maxRetries() - db_reconnect_ctl->retriesLeft() + 1)
2999 .arg(db_reconnect_ctl->maxRetries())
3000 .arg(db_reconnect_ctl->retryInterval());
3006 db_reconnect_ctl->retryInterval(),
3015std::pair<uint32_t, uint32_t>
3028 std::vector<MYSQL_BIND>& bind) {
3030 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), &bind[0]);
3031 checkError(ctx, status, stindex,
"unable to bind parameters");
3038 if (mysql_errno(ctx->conn_.mysql_) == ER_DUP_ENTRY) {
3041 checkError(ctx, status, stindex,
"unable to execute");
3049 my_ulonglong numrows = mysql_stmt_affected_rows(ctx->conn_.getStatement(stindex));
3060 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), &bind[0]);
3061 checkError(ctx, status, stindex,
"unable to bind parameters");
3067 checkError(ctx, status, stindex,
"unable to execute");
3071 my_ulonglong numrows = mysql_stmt_affected_rows(ctx->conn_.getStatement(stindex));
3073 return (numrows != 0);
3080 std::vector<MYSQL_BIND> bind = ctx->host_ipv6_reservation_exchange_->
3090 const std::string& opt_space,
3093 std::vector<MYSQL_BIND> bind = ctx->host_option_exchange_->createBindForSend(opt_desc, opt_space, subnet_id,
id);
3102 const uint64_t host_id) {
3105 std::list<std::string> option_spaces = options_cfg->getOptionSpaceNames();
3106 std::list<std::string> vendor_spaces = options_cfg->getVendorIdsSpaceNames();
3107 option_spaces.insert(option_spaces.end(), vendor_spaces.begin(),
3108 vendor_spaces.end());
3112 for (
auto const& space : option_spaces) {
3114 if (options && !options->empty()) {
3115 for (
auto const& opt : *options) {
3126 const char* what)
const {
3127 ctx->conn_.checkError(status, index, what);
3134 boost::shared_ptr<MySqlHostExchange> exchange,
3136 bool single)
const {
3139 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), bind);
3140 checkError(ctx, status, stindex,
"unable to bind WHERE clause parameter");
3144 std::vector<MYSQL_BIND> outbind = exchange->createBindForReceive();
3145 status = mysql_stmt_bind_result(ctx->conn_.getStatement(stindex), &outbind[0]);
3146 checkError(ctx, status, stindex,
"unable to bind SELECT clause parameters");
3150 checkError(ctx, status, stindex,
"unable to execute");
3154 status = mysql_stmt_store_result(ctx->conn_.getStatement(stindex));
3155 checkError(ctx, status, stindex,
"unable to set up for storing all results");
3162 while ((status = mysql_stmt_fetch(ctx->conn_.getStatement(stindex))) ==
3165 exchange->processFetchedData(
result);
3170 ctx->conn_.text_statements_[stindex] <<
">");
3173 if (single && (
result.size() > 1)) {
3175 "database where only one was expected for query "
3176 << ctx->conn_.text_statements_[stindex]);
3184 checkError(ctx, status, stindex,
"unable to fetch results");
3186 }
else if (status == MYSQL_DATA_TRUNCATED) {
3189 <<
" returned truncated data: columns affected are "
3190 << exchange->getErrorColumns());
3198 const uint8_t* identifier_begin,
3199 const size_t identifier_len,
3201 boost::shared_ptr<MySqlHostExchange> exchange)
const {
3204 MYSQL_BIND inbind[3];
3205 memset(inbind, 0,
sizeof(inbind));
3207 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3208 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3209 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3213 std::vector<char> identifier_vec(identifier_begin,
3214 identifier_begin + identifier_len);
3215 unsigned long length = identifier_vec.size();
3216 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3217 inbind[2].buffer = &identifier_vec[0];
3218 inbind[2].buffer_length = length;
3219 inbind[2].length = &length;
3222 char identifier_type_copy =
static_cast<char>(identifier_type);
3223 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3224 inbind[1].buffer = &identifier_type_copy;
3232 if (!collection.empty()) {
3233 result = *collection.begin();
3241 if (ctx->is_readonly_) {
3243 " operate in read only mode");
3256 return (impl_->parameters_);
3266 impl_->checkReadOnly(ctx);
3278 bool unique_ip = impl_->ip_reservations_unique_ && !host->getIPv4Reservation().isV4Zero()
3279 && host->getIPv4SubnetID() != SUBNET_ID_UNUSED;
3282 std::vector<MYSQL_BIND> bind = ctx->host_ipv4_exchange_->createBindForSend(host, unique_ip);
3289 uint64_t host_id = mysql_insert_id(ctx->conn_.mysql_);
3295 cfg_option4, host_id);
3302 cfg_option6, host_id);
3307 if (std::distance(v6resv.first, v6resv.second) > 0) {
3308 BOOST_FOREACH(
auto const& resv, v6resv) {
3309 impl_->addResv(ctx, resv.second, host_id);
3325 impl_->checkReadOnly(ctx);
3328 MYSQL_BIND inbind[2];
3330 uint32_t subnet = subnet_id;
3331 memset(inbind, 0,
sizeof(inbind));
3332 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3333 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3339 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3340 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3347 std::vector<uint8_t>addr6 = addr.
toBytes();
3348 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3350 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3353 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3354 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3355 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3356 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3357 inbind[1].length = &addr6_length;
3365 const uint8_t* identifier_begin,
3366 const size_t identifier_len) {
3372 impl_->checkReadOnly(ctx);
3375 MYSQL_BIND inbind[3];
3378 memset(inbind, 0,
sizeof(inbind));
3379 uint32_t subnet =
static_cast<uint32_t
>(subnet_id);
3380 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3381 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3385 char identifier_type_copy =
static_cast<char>(identifier_type);
3386 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3387 inbind[1].buffer = &identifier_type_copy;
3391 std::vector<char> identifier_vec(identifier_begin,
3392 identifier_begin + identifier_len);
3393 unsigned long length = identifier_vec.size();
3394 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3395 inbind[2].buffer = &identifier_vec[0];
3396 inbind[2].buffer_length = length;
3397 inbind[2].length = &length;
3406 const uint8_t* identifier_begin,
3407 const size_t identifier_len) {
3413 impl_->checkReadOnly(ctx);
3416 MYSQL_BIND inbind[3];
3419 memset(inbind, 0,
sizeof(inbind));
3420 uint32_t subnet =
static_cast<uint32_t
>(subnet_id);
3421 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3422 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3426 char identifier_type_copy =
static_cast<char>(identifier_type);
3427 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3428 inbind[1].buffer = &identifier_type_copy;
3432 std::vector<char> identifier_vec(identifier_begin,
3433 identifier_begin + identifier_len);
3434 unsigned long length = identifier_vec.size();
3435 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3436 inbind[2].buffer = &identifier_vec[0];
3437 inbind[2].buffer_length = length;
3438 inbind[2].length = &length;
3446 const uint8_t* identifier_begin,
3447 const size_t identifier_len)
const {
3453 MYSQL_BIND inbind[2];
3454 memset(inbind, 0,
sizeof(inbind));
3457 char identifier_type_copy =
static_cast<char>(identifier_type);
3458 inbind[1].buffer = &identifier_type_copy;
3459 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3463 std::vector<char> identifier_vec(identifier_begin,
3464 identifier_begin + identifier_len);
3465 unsigned long int length = identifier_vec.size();
3466 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
3467 inbind[0].buffer = &identifier_vec[0];
3468 inbind[0].buffer_length = length;
3469 inbind[0].length = &length;
3473 ctx->host_ipv46_exchange_,
result,
false);
3485 MYSQL_BIND inbind[1];
3486 memset(inbind, 0,
sizeof(inbind));
3487 uint32_t subnet = subnet_id;
3488 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3489 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3494 ctx->host_ipv4_exchange_,
result,
false);
3506 MYSQL_BIND inbind[1];
3507 memset(inbind, 0,
sizeof(inbind));
3508 uint32_t subnet = subnet_id;
3509 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3510 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3515 ctx->host_ipv6_exchange_,
result,
false);
3527 MYSQL_BIND inbind[1];
3528 memset(inbind, 0,
sizeof(inbind));
3533 unsigned long length = hostname.length();
3534 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3535 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3536 inbind[0].buffer_length = length;
3537 inbind[0].length = &length;
3541 ctx->host_ipv46_exchange_,
result,
false);
3554 MYSQL_BIND inbind[2];
3555 memset(inbind, 0,
sizeof(inbind));
3560 unsigned long length = hostname.length();
3561 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3562 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3563 inbind[0].buffer_length = length;
3564 inbind[0].length = &length;
3567 uint32_t subnet = subnet_id;
3568 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3569 inbind[1].buffer =
reinterpret_cast<char*
>(&subnet);
3574 ctx->host_ipv4_exchange_,
result,
false);
3587 MYSQL_BIND inbind[2];
3588 memset(inbind, 0,
sizeof(inbind));
3593 unsigned long length = hostname.length();
3594 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3595 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3596 inbind[0].buffer_length = length;
3597 inbind[0].length = &length;
3600 uint32_t subnet = subnet_id;
3601 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3602 inbind[1].buffer =
reinterpret_cast<char*
>(&subnet);
3607 ctx->host_ipv6_exchange_,
result,
false);
3615 uint64_t lower_host_id,
3622 MYSQL_BIND inbind[3];
3623 memset(inbind, 0,
sizeof(inbind));
3626 uint32_t subnet = subnet_id;
3627 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3628 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3632 uint32_t host_id = lower_host_id;
3633 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3634 inbind[1].buffer =
reinterpret_cast<char*
>(&host_id);
3638 uint32_t page_size_data = page_size.
page_size_;
3639 inbind[2].buffer_type = MYSQL_TYPE_LONG;
3640 inbind[2].buffer =
reinterpret_cast<char*
>(&page_size_data);
3645 ctx->host_ipv4_exchange_,
result,
false);
3653 uint64_t lower_host_id,
3660 MYSQL_BIND inbind[3];
3661 memset(inbind, 0,
sizeof(inbind));
3664 uint32_t subnet = subnet_id;
3665 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3666 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3670 uint32_t host_id = lower_host_id;
3671 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3672 inbind[1].buffer =
reinterpret_cast<char*
>(&host_id);
3676 uint32_t page_size_data = page_size.
page_size_;
3677 inbind[2].buffer_type = MYSQL_TYPE_LONG;
3678 inbind[2].buffer =
reinterpret_cast<char*
>(&page_size_data);
3683 ctx->host_ipv6_exchange_,
result,
false);
3690 uint64_t lower_host_id,
3697 MYSQL_BIND inbind[2];
3698 memset(inbind, 0,
sizeof(inbind));
3701 uint32_t host_id = lower_host_id;
3702 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3703 inbind[0].buffer =
reinterpret_cast<char*
>(&host_id);
3707 uint32_t page_size_data = page_size.
page_size_;
3708 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3709 inbind[1].buffer =
reinterpret_cast<char*
>(&page_size_data);
3714 ctx->host_ipv4_exchange_,
result,
false);
3721 uint64_t lower_host_id,
3728 MYSQL_BIND inbind[2];
3729 memset(inbind, 0,
sizeof(inbind));
3732 uint32_t host_id = lower_host_id;
3733 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3734 inbind[0].buffer =
reinterpret_cast<char*
>(&host_id);
3738 uint32_t page_size_data = page_size.
page_size_;
3739 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3740 inbind[1].buffer =
reinterpret_cast<char*
>(&page_size_data);
3745 ctx->host_ipv6_exchange_,
result,
false);
3757 MYSQL_BIND inbind[1];
3758 memset(inbind, 0,
sizeof(inbind));
3760 uint32_t addr4 = address.
toUint32();
3761 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3762 inbind[0].buffer =
reinterpret_cast<char*
>(&addr4);
3767 ctx->host_ipv4_exchange_,
result,
false);
3775 const uint8_t* identifier_begin,
3776 const size_t identifier_len)
const {
3781 return (impl_->getHost(ctx, subnet_id, identifier_type, identifier_begin, identifier_len,
3783 ctx->host_ipv4_exchange_));
3789 if (!address.
isV4()) {
3791 "wrong address type, address supplied is an IPv6 address");
3799 MYSQL_BIND inbind[2];
3800 uint32_t subnet = subnet_id;
3801 memset(inbind, 0,
sizeof(inbind));
3802 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3803 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3806 uint32_t addr4 = address.
toUint32();
3807 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3808 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3813 ctx->host_ipv4_exchange_, collection,
true);
3817 if (!collection.empty()) {
3818 result = *collection.begin();
3827 if (!address.
isV4()) {
3829 "wrong address type, address supplied is an IPv6 address");
3837 MYSQL_BIND inbind[2];
3838 uint32_t subnet = subnet_id;
3839 memset(inbind, 0,
sizeof(inbind));
3840 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3841 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3844 uint32_t addr4 = address.
toUint32();
3845 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3846 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3851 ctx->host_ipv4_exchange_, collection,
false);
3852 return (collection);
3858 const uint8_t* identifier_begin,
3859 const size_t identifier_len)
const {
3864 return (impl_->getHost(ctx, subnet_id, identifier_type, identifier_begin, identifier_len,
3866 ctx->host_ipv6_exchange_));
3871 const uint8_t prefix_len)
const {
3872 if (!prefix.
isV6()) {
3874 "wrong address type, address supplied is an IPv4 address");
3882 MYSQL_BIND inbind[2];
3883 memset(inbind, 0,
sizeof(inbind));
3885 std::vector<uint8_t>addr6 = prefix.
toBytes();
3886 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3888 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3891 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3892 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
3893 inbind[0].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3894 inbind[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3895 inbind[0].length = &addr6_length;
3897 uint8_t tmp = prefix_len;
3898 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3899 inbind[1].buffer =
reinterpret_cast<char*
>(&tmp);
3904 ctx->host_ipv6_exchange_, collection,
true);
3908 if (!collection.empty()) {
3909 result = *collection.begin();
3918 if (!address.
isV6()) {
3920 "wrong address type, address supplied is an IPv4 address");
3928 MYSQL_BIND inbind[2];
3929 memset(inbind, 0,
sizeof(inbind));
3931 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3932 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3933 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3936 std::vector<uint8_t>addr6 = address.
toBytes();
3937 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3939 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3942 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3943 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3944 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3945 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3946 inbind[1].length = &addr6_length;
3950 ctx->host_ipv6_exchange_, collection,
true);
3954 if (!collection.empty()) {
3955 result = *collection.begin();
3964 if (!address.
isV6()) {
3966 "wrong address type, address supplied is an IPv4 address");
3974 MYSQL_BIND inbind[2];
3975 memset(inbind, 0,
sizeof(inbind));
3977 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3978 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3979 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3982 std::vector<uint8_t>addr6 = address.
toBytes();
3983 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3985 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3988 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3989 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3990 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3991 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3992 inbind[1].length = &addr6_length;
3996 ctx->host_ipv6_exchange_, collection,
false);
3997 return (collection);
4002 if (!address.
isV6()) {
4004 "wrong address type, address supplied is an IPv4 address");
4012 MYSQL_BIND inbind[1];
4013 memset(inbind, 0,
sizeof(inbind));
4015 std::vector<uint8_t>addr6 = address.
toBytes();
4016 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
4018 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
4021 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
4022 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
4023 inbind[0].buffer =
reinterpret_cast<char*
>(&addr6[0]);
4024 inbind[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
4025 inbind[0].length = &addr6_length;
4029 ctx->host_ipv6_exchange_, collection,
false);
4030 return (collection);
4040 impl_->checkReadOnly(ctx);
4063 std::string name =
"";
4069 name = ctx->conn_.getParameter(
"name");
4078 return (std::string(
"Host data source that stores host information"
4079 "in MySQL database"));
4082std::pair<uint32_t, uint32_t>
4084 return (impl_->getVersion(timer_name));
4094 impl_->checkReadOnly(ctx);
4095 if (ctx->conn_.isTransactionStarted()) {
4096 ctx->conn_.commit();
4107 impl_->checkReadOnly(ctx);
4108 if (ctx->conn_.isTransactionStarted()) {
4109 ctx->conn_.rollback();
4115 impl_->ip_reservations_unique_ = unique;
4121 return (impl_->unusable_);
when the call the UDPServer carries on at the same position As a result
static ElementPtr fromJSON(const std::string &in, bool preproc=false)
These functions will parse the given string (JSON) representation of a compound element.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
bool isV6() const
Convenience function to check for an IPv6 address.
bool isV4() const
Convenience function to check for an IPv4 address.
std::vector< uint8_t > toBytes() const
Return address as set of bytes.
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
static bool invokeDbLostCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's lost connectivity callback.
static bool invokeDbFailedCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's restore failed connectivity callback.
static ParameterMap parse(const std::string &dbaccess)
Parse database access string.
static bool invokeDbRecoveredCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's restored connectivity callback.
static isc::asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Exception thrown on failure to execute a database function.
Database duplicate entry error.
Multiple lease records found where one expected.
Common MySQL Connector Pool.
static std::pair< uint32_t, uint32_t > getVersion(const ParameterMap ¶meters, const IOServiceAccessorPtr &ac=IOServiceAccessorPtr(), const DbCallback &cb=DbCallback(), const std::string &timer_name=std::string(), unsigned int id=0)
Get the schema version.
static void ensureSchemaVersion(const ParameterMap ¶meters, const DbCallback &cb=DbCallback(), const std::string &timer_name=std::string())
Retrieve schema version, validate it against the hardcoded version, and attempt to initialize the sch...
Fetch and Release MySQL Results.
RAII object representing MySQL transaction.
void commit()
Commits transaction.
Attempt to modify data in read-only database.
virtual void update(HostPtr const &host)
Attempts to update an existing host entry.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
static constexpr size_t MAX_CLIENT_ID_LEN
Maximum size of a client ID.
static bool delBackend(const std::string &db_type)
Delete an alternate host backend (aka host data source).
static void addBackend(const std::string &access)
Add an alternate host backend (aka host data source).
Wraps value holding size of the page with host reservations.
const size_t page_size_
Holds page size.
IdentifierType
Type of the host identifier.
static const IdentifierType LAST_IDENTIFIER_TYPE
Constant pointing to the last identifier of the IdentifierType enumeration.
IPv6 reservation for a host.
const asiolink::IOAddress & getPrefix() const
Returns prefix for the reservation.
Type getType() const
Returns reservation type.
Type
Type of the reservation.
uint8_t getPrefixLen() const
Returns prefix length.
static OptionDefinitionPtr getOptionDef(const std::string &space, const uint16_t code)
Return the first option definition matching a particular option code.
static OptionDefinitionPtr getVendorOptionDef(const Option::Universe u, const uint32_t vendor_id, const uint16_t code)
Returns vendor option definition for a given vendor-id and code.
static uint32_t optionSpaceToVendorId(const std::string &option_space)
Converts option space name to vendor id.
static OptionDefinitionPtr getRuntimeOptionDef(const std::string &space, const uint16_t code)
Returns runtime (non-standard) option definition by space and option code.
static OptionDefinitionPtr getLastResortOptionDef(const std::string &space, const uint16_t code)
Returns last resort option definition by space and option code.
std::vector< MySqlHostContextPtr > pool_
The vector of available contexts.
std::mutex mutex_
The mutex to protect pool access.
MySqlHostContext(const DatabaseConnection::ParameterMap ¶meters, IOServiceAccessorPtr io_service_accessor, db::DbCallback db_reconnect_callback)
Constructor.
boost::shared_ptr< MySqlHostIPv6Exchange > host_ipv46_exchange_
Pointer to an object representing an exchange which can be used to retrieve hosts,...
boost::shared_ptr< MySqlHostIPv6Exchange > host_ipv6_exchange_
Pointer to an object representing an exchange which can be used to retrieve hosts,...
boost::shared_ptr< MySqlIPv6ReservationExchange > host_ipv6_reservation_exchange_
Pointer to an object representing an exchange which can be used to insert new IPv6 reservation.
boost::shared_ptr< MySqlHostWithOptionsExchange > host_ipv4_exchange_
The exchange objects are used for transfer of data to/from the database.
boost::shared_ptr< MySqlOptionExchange > host_option_exchange_
Pointer to an object representing an exchange which can be used to insert DHCPv4 or DHCPv6 option int...
MySqlConnection conn_
MySQL connection.
bool is_readonly_
Indicates if the database is opened in read only mode.
Implementation of the MySqlHostDataSource.
void checkReadOnly(MySqlHostContextPtr &ctx) const
Throws exception if database is read only.
void checkError(MySqlHostContextPtr &ctx, const int status, const StatementIndex index, const char *what) const
Check Error and Throw Exception.
~MySqlHostDataSourceImpl()
Destructor.
std::string timer_name_
Timer name used to register database reconnect timer.
DatabaseConnection::ParameterMap parameters_
The parameters.
MySqlHostContextPtr createContext() const
Create a new context.
bool delStatement(MySqlHostContextPtr &ctx, StatementIndex stindex, MYSQL_BIND *bind)
Executes statements that delete records.
StatementIndex
Statement Tags.
@ GET_HOST_HOSTNAME_SUBID4
@ INSERT_V6_RESRV_NON_UNIQUE
@ GET_HOST_HOSTNAME_SUBID6
@ INSERT_HOST_NON_UNIQUE_IP
MySqlHostDataSourceImpl(const DatabaseConnection::ParameterMap ¶meters)
Constructor.
ConstHostPtr getHost(MySqlHostContextPtr &ctx, const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, StatementIndex stindex, boost::shared_ptr< MySqlHostExchange > exchange) const
Retrieves a host by subnet and client's unique identifier.
void addStatement(MySqlHostContextPtr &ctx, MySqlHostDataSourceImpl::StatementIndex stindex, std::vector< MYSQL_BIND > &bind)
Executes statements which inserts a row into one of the tables.
std::pair< uint32_t, uint32_t > getVersion(const std::string &timer_name=std::string()) const
Returns backend version.
void getHostCollection(MySqlHostContextPtr &ctx, StatementIndex stindex, MYSQL_BIND *bind, boost::shared_ptr< MySqlHostExchange > exchange, ConstHostCollection &result, bool single) const
Creates collection of Host objects with associated information such as IPv6 reservations and/or DHCP ...
bool ip_reservations_unique_
Holds the setting whether the IP reservations must be unique or may be non-unique.
void addOptions(MySqlHostContextPtr &ctx, const StatementIndex &stindex, const ConstCfgOptionPtr &options_cfg, const uint64_t host_id)
Inserts multiple options into the database.
MySqlHostContextPoolPtr pool_
The pool of contexts.
void addOption(MySqlHostContextPtr &ctx, const MySqlHostDataSourceImpl::StatementIndex &stindex, const OptionDescriptor &opt_desc, const std::string &opt_space, const Optional< SubnetID > &subnet_id, const HostID &host_id)
Inserts a single DHCP option into the database.
bool unusable_
Indicates if there is at least one connection that can no longer be used for normal operations.
void addResv(MySqlHostContextPtr &ctx, const IPv6Resrv &resv, const HostID &id)
Inserts IPv6 Reservation into ipv6_reservation table.
static bool dbReconnect(ReconnectCtlPtr db_reconnect_ctl)
Attempts to reconnect the server to the host DB backend manager.
static const StatementIndex WRITE_STMTS_BEGIN
Index of first statement performing write to the database.
MySqlHostContextAlloc(MySqlHostDataSourceImpl &mgr)
Constructor.
MySqlHostContextPtr ctx_
The context.
~MySqlHostContextAlloc()
Destructor.
virtual ConstHostCollection getAll(const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Return all hosts connected to any subnet for which reservations have been made using a specified iden...
virtual ConstHostPtr get6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Returns a host connected to the IPv6 subnet.
virtual std::pair< uint32_t, uint32_t > getVersion(const std::string &timer_name=std::string()) const
Returns backend version.
virtual void commit()
Commit Transactions.
virtual bool del(const SubnetID &subnet_id, const asiolink::IOAddress &addr)
Attempts to delete hosts by (subnet-id, address)
virtual ConstHostCollection getAll4(const SubnetID &subnet_id) const
Return all hosts in a DHCPv4 subnet.
virtual ConstHostCollection getAll6(const SubnetID &subnet_id) const
Return all hosts in a DHCPv6 subnet.
virtual std::string getDescription() const
Returns description of the backend.
MySqlHostDataSource(const db::DatabaseConnection::ParameterMap ¶meters)
Constructor.
virtual ~MySqlHostDataSource()
Virtual destructor.
virtual ConstHostCollection getAllbyHostname(const std::string &hostname) const
Return all hosts with a hostname.
virtual isc::db::DatabaseConnection::ParameterMap getParameters() const
Return backend parameters.
void update(HostPtr const &host)
Implements BaseHostDataSource::update() for MySQL.
virtual bool del6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len)
Attempts to delete a host by (subnet6-id, identifier type, identifier)
virtual ConstHostCollection getPage6(const SubnetID &subnet_id, size_t &source_index, uint64_t lower_host_id, const HostPageSize &page_size) const
Returns range of hosts in a DHCPv6 subnet.
virtual ConstHostCollection getAllbyHostname6(const std::string &hostname, const SubnetID &subnet_id) const
Return all hosts with a hostname in a DHCPv6 subnet.
virtual bool del4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len)
Attempts to delete a host by (subnet4-id, identifier type, identifier)
virtual ConstHostCollection getPage4(const SubnetID &subnet_id, size_t &source_index, uint64_t lower_host_id, const HostPageSize &page_size) const
Returns range of hosts in a DHCPv4 subnet.
virtual bool isUnusable()
Flag which indicates if the host manager has at least one unusable connection.
virtual ConstHostCollection getAllbyHostname4(const std::string &hostname, const SubnetID &subnet_id) const
Return all hosts with a hostname in a DHCPv4 subnet.
virtual void rollback()
Rollback Transactions.
virtual std::string getName() const
Returns backend name.
virtual void add(const HostPtr &host)
Adds a new host to the collection.
virtual ConstHostPtr get4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Returns a host connected to the IPv4 subnet.
virtual bool setIPReservationsUnique(const bool unique)
Controls whether IP reservations are unique or non-unique.
static const unsigned int DB_CONNECTION
The network state is being altered by the DB connection recovery mechanics.
OptionPtr option_
Option instance.
bool cancelled_
Cancelled flag.
std::string formatted_value_
Option value in textual (CSV) format.
bool persistent_
Persistence flag.
Universe
defines option universe DHCPv4 or DHCPv6
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
RAII class creating a critical section.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
A template representing an optional value.
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
#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.
boost::shared_ptr< const Element > ConstElementPtr
const my_bool MLM_FALSE
MySQL false value.
boost::shared_ptr< IOServiceAccessor > IOServiceAccessorPtr
Pointer to an instance of IOServiceAccessor.
const my_bool MLM_TRUE
MySQL true value.
bool my_bool
my_bool type in MySQL 8.x.
const int MLM_MYSQL_FETCH_FAILURE
MySQL fetch failure code.
const int MLM_MYSQL_FETCH_SUCCESS
check for bool size
std::function< bool(util::ReconnectCtlPtr db_reconnect_ctl)> DbCallback
Defines a callback prototype for propagating events upward.
std::function< isc::asiolink::IOServicePtr()> IOServiceAccessor
Function which returns the IOService that can be used to recover the connection.
int MysqlExecuteStatement(MYSQL_STMT *stmt)
Execute a prepared statement.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
const size_t OPTION_FORMATTED_VALUE_MAX_LEN
Maximum length of option value specified in textual format.
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_GET_VERSION
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
const isc::log::MessageID DHCPSRV_MYSQL_NO_TLS
boost::shared_ptr< CfgDbAccess > CfgDbAccessPtr
A pointer to the CfgDbAccess.
const size_t CLIENT_CLASSES_MAX_LEN
Maximum length of classes stored in a dhcp4/6_client_classes columns.
std::pair< IPv6ResrvIterator, IPv6ResrvIterator > IPv6ResrvRange
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
const size_t TEXT_AUTH_KEY_LEN
Maximum length of authentication keys (coded in hexadecimal).
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_RECONNECT_FAILED
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
uint64_t HostID
HostID (used only when storing in MySQL or PostgreSQL backends)
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
boost::shared_ptr< MySqlHostContextPool > MySqlHostContextPoolPtr
Type of pointers to context pools.
const size_t HOSTNAME_MAX_LEN
Maximum length of the hostname stored in DNS.
boost::shared_ptr< MySqlHostContext > MySqlHostContextPtr
Type of pointers to contexts.
const size_t USER_CONTEXT_MAX_LEN
Maximum length of user context.
const size_t OPTION_VALUE_MAX_LEN
Maximum length of option value.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
const size_t SERVER_HOSTNAME_MAX_LEN
Maximum length of the server hostname.
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_READONLY
const size_t BOOT_FILE_NAME_MAX_LEN
Maximum length of the boot file name.
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_RECONNECT_ATTEMPT_SCHEDULE
boost::shared_ptr< Option > OptionPtr
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_RECONNECT_ATTEMPT_FAILED
const isc::log::MessageID DHCPSRV_MYSQL_TLS_CIPHER
boost::shared_ptr< const CfgOption > ConstCfgOptionPtr
Const pointer.
const size_t OPTION_SPACE_MAX_LEN
Maximum length of option space name.
boost::shared_ptr< ReconnectCtl > ReconnectCtlPtr
Pointer to an instance of ReconnectCtl.
Defines the logger used by the top-level component of kea-lfc.
#define DHCP4_OPTION_SPACE
global std option spaces
#define DHCP6_OPTION_SPACE
data::ConstElementPtr getContext() const
Returns const pointer to the user context.