26#include <boost/algorithm/string/split.hpp>
27#include <boost/algorithm/string/classification.hpp>
28#include <boost/array.hpp>
29#include <boost/foreach.hpp>
30#include <boost/pointer_cast.hpp>
31#include <boost/static_assert.hpp>
34#include <mysqld_error.h>
84class MySqlHostExchange {
91 static const size_t HOST_ID_COL = 0;
92 static const size_t DHCP_IDENTIFIER_COL = 1;
93 static const size_t DHCP_IDENTIFIER_TYPE_COL = 2;
94 static const size_t DHCP4_SUBNET_ID_COL = 3;
95 static const size_t DHCP6_SUBNET_ID_COL = 4;
96 static const size_t IPV4_ADDRESS_COL = 5;
97 static const size_t HOSTNAME_COL = 6;
98 static const size_t DHCP4_CLIENT_CLASSES_COL = 7;
99 static const size_t DHCP6_CLIENT_CLASSES_COL = 8;
100 static const size_t USER_CONTEXT_COL = 9;
101 static const size_t DHCP4_NEXT_SERVER_COL = 10;
102 static const size_t DHCP4_SERVER_HOSTNAME_COL = 11;
103 static const size_t DHCP4_BOOT_FILE_NAME_COL = 12;
104 static const size_t AUTH_KEY_COL = 13;
107 static const size_t HOST_COLUMNS = 14;
117 MySqlHostExchange(
const size_t additional_columns_num = 0)
118 : columns_num_(HOST_COLUMNS + additional_columns_num),
119 bind_(columns_num_), columns_(columns_num_),
120 error_(columns_num_,
MLM_FALSE), host_id_(0),
121 dhcp_identifier_length_(0), dhcp_identifier_type_(0),
122 dhcp4_subnet_id_(SUBNET_ID_UNUSED),
123 dhcp6_subnet_id_(SUBNET_ID_UNUSED), ipv4_address_(0),
124 hostname_length_(0), dhcp4_client_classes_length_(0),
125 dhcp6_client_classes_length_(0),
126 user_context_length_(0),
127 dhcp4_next_server_(0),
128 dhcp4_server_hostname_length_(0),
129 dhcp4_boot_file_name_length_(0),
143 memset(dhcp_identifier_buffer_, 0,
sizeof(dhcp_identifier_buffer_));
144 memset(hostname_, 0,
sizeof(hostname_));
145 memset(dhcp4_client_classes_, 0,
sizeof(dhcp4_client_classes_));
146 memset(dhcp6_client_classes_, 0,
sizeof(dhcp6_client_classes_));
147 memset(user_context_, 0,
sizeof(user_context_));
148 memset(dhcp4_server_hostname_, 0,
sizeof(dhcp4_server_hostname_));
149 memset(dhcp4_boot_file_name_, 0,
sizeof(dhcp4_boot_file_name_));
150 memset(auth_key_, 0,
sizeof(auth_key_));
155 columns_[HOST_ID_COL] =
"host_id";
156 columns_[DHCP_IDENTIFIER_COL] =
"dhcp_identifier";
157 columns_[DHCP_IDENTIFIER_TYPE_COL] =
"dhcp_identifier_type";
158 columns_[DHCP4_SUBNET_ID_COL] =
"dhcp4_subnet_id";
159 columns_[DHCP6_SUBNET_ID_COL] =
"dhcp6_subnet_id";
160 columns_[IPV4_ADDRESS_COL] =
"ipv4_address";
161 columns_[HOSTNAME_COL] =
"hostname";
162 columns_[DHCP4_CLIENT_CLASSES_COL] =
"dhcp4_client_classes";
163 columns_[DHCP6_CLIENT_CLASSES_COL] =
"dhcp6_client_classes";
164 columns_[USER_CONTEXT_COL] =
"user_context";
165 columns_[DHCP4_NEXT_SERVER_COL] =
"dhcp4_next_server";
166 columns_[DHCP4_SERVER_HOSTNAME_COL] =
"dhcp4_server_hostname";
167 columns_[DHCP4_BOOT_FILE_NAME_COL] =
"dhcp4_boot_file_name";
168 columns_[AUTH_KEY_COL] =
"auth_key";
170 BOOST_STATIC_ASSERT(13 < HOST_COLUMNS);
174 virtual ~MySqlHostExchange() {
191 size_t findAvailColumn()
const {
192 std::vector<std::string>::const_iterator empty_column =
193 std::find(columns_.begin(), columns_.end(), std::string());
194 return (std::distance(columns_.begin(), empty_column));
200 uint64_t getHostId()
const {
214 static void setErrorIndicators(std::vector<MYSQL_BIND>& bind,
215 std::vector<my_bools>&
error) {
216 for (
size_t i = 0; i <
error.size(); ++i) {
235 static std::string getColumnsInError(std::vector<my_bools>&
error,
236 const std::vector<std::string>& names) {
237 std::string result =
"";
240 for (
size_t i = 0; i < names.size(); ++i) {
242 if (!result.empty()) {
249 if (result.empty()) {
268 std::vector<MYSQL_BIND> createBindForSend(
const HostPtr& host,
const bool unique_ip) {
276 memset(&bind_[0], 0,
sizeof(MYSQL_BIND) * bind_.size());
285 bind_[0].buffer_type = MYSQL_TYPE_LONG;
286 bind_[0].buffer =
reinterpret_cast<char*
>(&host_id_);
290 dhcp_identifier_length_ = host->getIdentifier().size();
291 memcpy(
static_cast<void*
>(dhcp_identifier_buffer_),
292 &(host->getIdentifier())[0],
293 host->getIdentifier().size());
295 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
296 bind_[1].buffer = dhcp_identifier_buffer_;
297 bind_[1].buffer_length = dhcp_identifier_length_;
298 bind_[1].length = &dhcp_identifier_length_;
301 dhcp_identifier_type_ =
static_cast<uint8_t
>(host->getIdentifierType());
302 bind_[2].buffer_type = MYSQL_TYPE_TINY;
303 bind_[2].buffer =
reinterpret_cast<char*
>(&dhcp_identifier_type_);
309 dhcp4_subnet_id_ = host->getIPv4SubnetID();
310 dhcp4_subnet_id_null_ = host->getIPv4SubnetID() == SUBNET_ID_UNUSED ?
MLM_TRUE :
MLM_FALSE;
311 bind_[3].buffer_type = MYSQL_TYPE_LONG;
312 bind_[3].buffer =
reinterpret_cast<char*
>(&dhcp4_subnet_id_);
314 bind_[3].is_null = &dhcp4_subnet_id_null_;
319 dhcp6_subnet_id_ = host->getIPv6SubnetID();
320 dhcp6_subnet_id_null_ = host->getIPv6SubnetID() == SUBNET_ID_UNUSED ?
MLM_TRUE :
MLM_FALSE;
321 bind_[4].buffer_type = MYSQL_TYPE_LONG;
322 bind_[4].buffer =
reinterpret_cast<char*
>(&dhcp6_subnet_id_);
324 bind_[4].is_null = &dhcp6_subnet_id_null_;
329 ipv4_address_ = host->getIPv4Reservation().toUint32();
331 bind_[5].buffer_type = MYSQL_TYPE_LONG;
332 bind_[5].buffer =
reinterpret_cast<char*
>(&ipv4_address_);
334 bind_[5].is_null = &ipv4_address_null_;
338 hostname_length_ = host->getHostname().length();
339 bind_[6].buffer_type = MYSQL_TYPE_STRING;
340 bind_[6].buffer =
reinterpret_cast<char*
>(hostname_);
341 bind_[6].buffer_length = hostname_length_;
344 bind_[7].buffer_type = MYSQL_TYPE_STRING;
346 string classes4_txt = host->getClientClasses4().toText(
",");
348 bind_[7].buffer = dhcp4_client_classes_;
349 bind_[7].buffer_length = classes4_txt.length();
352 bind_[8].buffer_type = MYSQL_TYPE_STRING;
354 string classes6_txt = host->getClientClasses6().toText(
",");
356 bind_[8].buffer = dhcp6_client_classes_;
357 bind_[8].buffer_length = classes6_txt.length();
362 bind_[9].buffer_type = MYSQL_TYPE_STRING;
363 string ctx_txt = ctx->str();
365 bind_[9].buffer = user_context_;
366 bind_[9].buffer_length = ctx_txt.length();
368 bind_[9].buffer_type = MYSQL_TYPE_NULL;
374 dhcp4_next_server_ = host->getNextServer().toUint32();
375 bind_[10].buffer_type = MYSQL_TYPE_LONG;
376 bind_[10].buffer =
reinterpret_cast<char*
>(&dhcp4_next_server_);
382 bind_[11].buffer_type = MYSQL_TYPE_STRING;
383 std::string server_hostname = host->getServerHostname();
384 strncpy(dhcp4_server_hostname_, server_hostname.c_str(),
386 bind_[11].buffer = dhcp4_server_hostname_;
387 bind_[11].buffer_length = server_hostname.length();
390 bind_[12].buffer_type = MYSQL_TYPE_STRING;
391 std::string boot_file_name = host->getBootFileName();
392 strncpy(dhcp4_boot_file_name_, boot_file_name.c_str(),
394 bind_[12].buffer = dhcp4_boot_file_name_;
395 bind_[12].buffer_length = boot_file_name.length();
398 bind_[13].buffer_type = MYSQL_TYPE_STRING;
399 std::string auth_key = host->getKey().toText();
402 bind_[13].buffer = auth_key_;
403 bind_[13].buffer_length = auth_key.length();
405 }
catch (
const std::exception& ex) {
407 "Could not create bind array from Host: "
408 << host->getHostname() <<
", reason: " << ex.
what());
412 std::vector<MYSQL_BIND> vec(bind_.begin(), bind_.begin() + HOST_COLUMNS);
418 vec.push_back(bind_[5]);
419 vec.push_back(bind_[3]);
431 virtual std::vector<MYSQL_BIND> createBindForReceive() {
438 memset(&bind_[0], 0,
sizeof(MYSQL_BIND) * bind_.size());
441 bind_[0].buffer_type = MYSQL_TYPE_LONG;
442 bind_[0].buffer =
reinterpret_cast<char*
>(&host_id_);
446 dhcp_identifier_length_ =
sizeof(dhcp_identifier_buffer_);
447 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
448 bind_[1].buffer =
reinterpret_cast<char*
>(dhcp_identifier_buffer_);
449 bind_[1].buffer_length = dhcp_identifier_length_;
450 bind_[1].length = &dhcp_identifier_length_;
453 bind_[2].buffer_type = MYSQL_TYPE_TINY;
454 bind_[2].buffer =
reinterpret_cast<char*
>(&dhcp_identifier_type_);
459 bind_[3].buffer_type = MYSQL_TYPE_LONG;
460 bind_[3].buffer =
reinterpret_cast<char*
>(&dhcp4_subnet_id_);
462 bind_[3].is_null = &dhcp4_subnet_id_null_;
466 bind_[4].buffer_type = MYSQL_TYPE_LONG;
467 bind_[4].buffer =
reinterpret_cast<char*
>(&dhcp6_subnet_id_);
469 bind_[4].is_null = &dhcp6_subnet_id_null_;
473 bind_[5].buffer_type = MYSQL_TYPE_LONG;
474 bind_[5].buffer =
reinterpret_cast<char*
>(&ipv4_address_);
476 bind_[5].is_null = &ipv4_address_null_;
480 hostname_length_ =
sizeof(hostname_);
481 bind_[6].buffer_type = MYSQL_TYPE_STRING;
482 bind_[6].buffer =
reinterpret_cast<char*
>(hostname_);
483 bind_[6].buffer_length = hostname_length_;
484 bind_[6].length = &hostname_length_;
485 bind_[6].is_null = &hostname_null_;
489 dhcp4_client_classes_length_ =
sizeof(dhcp4_client_classes_);
490 bind_[7].buffer_type = MYSQL_TYPE_STRING;
491 bind_[7].buffer =
reinterpret_cast<char*
>(dhcp4_client_classes_);
492 bind_[7].buffer_length = dhcp4_client_classes_length_;
493 bind_[7].length = &dhcp4_client_classes_length_;
494 bind_[7].is_null = &dhcp4_client_classes_null_;
498 dhcp6_client_classes_length_ =
sizeof(dhcp6_client_classes_);
499 bind_[8].buffer_type = MYSQL_TYPE_STRING;
500 bind_[8].buffer =
reinterpret_cast<char*
>(dhcp6_client_classes_);
501 bind_[8].buffer_length = dhcp6_client_classes_length_;
502 bind_[8].length = &dhcp6_client_classes_length_;
503 bind_[8].is_null = &dhcp6_client_classes_null_;
507 user_context_length_ =
sizeof(user_context_);
508 bind_[9].buffer_type = MYSQL_TYPE_STRING;
509 bind_[9].buffer =
reinterpret_cast<char*
>(user_context_);
510 bind_[9].buffer_length = user_context_length_;
511 bind_[9].length = &user_context_length_;
512 bind_[9].is_null = &user_context_null_;
516 bind_[10].buffer_type = MYSQL_TYPE_LONG;
517 bind_[10].buffer =
reinterpret_cast<char*
>(&dhcp4_next_server_);
519 bind_[10].is_null = &dhcp4_next_server_null_;
523 dhcp4_server_hostname_length_ =
sizeof(dhcp4_server_hostname_);
524 bind_[11].buffer_type = MYSQL_TYPE_STRING;
525 bind_[11].buffer =
reinterpret_cast<char*
>(dhcp4_server_hostname_);
526 bind_[11].buffer_length = dhcp4_server_hostname_length_;
527 bind_[11].length = &dhcp4_server_hostname_length_;
528 bind_[11].is_null = &dhcp4_server_hostname_null_;
532 dhcp4_boot_file_name_length_ =
sizeof(dhcp4_boot_file_name_);
533 bind_[12].buffer_type = MYSQL_TYPE_STRING;
534 bind_[12].buffer =
reinterpret_cast<char*
>(dhcp4_boot_file_name_);
535 bind_[12].buffer_length = dhcp4_boot_file_name_length_;
536 bind_[12].length = &dhcp4_boot_file_name_length_;
537 bind_[12].is_null = &dhcp4_boot_file_name_null_;
541 auth_key_length_ =
sizeof(auth_key_);
542 bind_[13].buffer_type = MYSQL_TYPE_STRING;
543 bind_[13].buffer =
reinterpret_cast<char*
>(auth_key_);
544 bind_[13].buffer_length = auth_key_length_;
545 bind_[13].length = &auth_key_length_;
546 bind_[13].is_null = &auth_key_null_;
549 setErrorIndicators(bind_, error_);
566 if (dhcp_identifier_type_ > MAX_IDENTIFIER_TYPE) {
568 <<
static_cast<int>(dhcp_identifier_type_));
577 SubnetID ipv4_subnet_id(SUBNET_ID_UNUSED);
578 if (dhcp4_subnet_id_null_ ==
MLM_FALSE) {
579 ipv4_subnet_id = dhcp4_subnet_id_;
584 SubnetID ipv6_subnet_id(SUBNET_ID_UNUSED);
585 if (dhcp6_subnet_id_null_ ==
MLM_FALSE) {
586 ipv6_subnet_id = dhcp6_subnet_id_;
598 std::string hostname;
600 hostname = std::string(hostname_, hostname_length_);
604 std::string dhcp4_client_classes;
605 if (dhcp4_client_classes_null_ ==
MLM_FALSE) {
606 dhcp4_client_classes = std::string(dhcp4_client_classes_,
607 dhcp4_client_classes_length_);
611 std::string dhcp6_client_classes;
612 if (dhcp6_client_classes_null_ ==
MLM_FALSE) {
613 dhcp6_client_classes = std::string(dhcp6_client_classes_,
614 dhcp6_client_classes_length_);
618 std::string user_context;
620 user_context_[user_context_length_] =
'\0';
621 user_context.assign(user_context_);
626 if (dhcp4_next_server_null_ ==
MLM_FALSE) {
631 std::string dhcp4_server_hostname;
632 if (dhcp4_server_hostname_null_ ==
MLM_FALSE) {
633 dhcp4_server_hostname = std::string(dhcp4_server_hostname_,
634 dhcp4_server_hostname_length_);
638 std::string dhcp4_boot_file_name;
639 if (dhcp4_boot_file_name_null_ ==
MLM_FALSE) {
640 dhcp4_boot_file_name = std::string(dhcp4_boot_file_name_,
641 dhcp4_boot_file_name_length_);
645 std::string auth_key;
647 auth_key = std::string(auth_key_, auth_key_length_);
651 HostPtr h(
new Host(dhcp_identifier_buffer_, dhcp_identifier_length_,
652 type, ipv4_subnet_id, ipv6_subnet_id, ipv4_reservation,
653 hostname, dhcp4_client_classes, dhcp6_client_classes,
654 next_server, dhcp4_server_hostname,
655 dhcp4_boot_file_name,
AuthKey(auth_key)));
656 h->setHostId(host_id_);
659 if (!user_context.empty()) {
664 <<
"' is not a JSON map");
669 <<
"' is invalid JSON: " << ex.
what());
694 if (hosts.empty() || (hosts.back()->getHostId() != getHostId())) {
697 host = retrieveHost();
698 hosts.push_back(host);
712 std::string getErrorColumns() {
713 return (getColumnsInError(error_, columns_));
722 std::vector<MYSQL_BIND> bind_;
725 std::vector<std::string> columns_;
728 std::vector<my_bools> error_;
744 unsigned long dhcp_identifier_length_;
748 uint8_t dhcp_identifier_type_;
751 uint32_t dhcp4_subnet_id_;
754 uint32_t dhcp6_subnet_id_;
757 uint32_t ipv4_address_;
763 unsigned long hostname_length_;
770 unsigned long dhcp4_client_classes_length_;
777 unsigned long dhcp6_client_classes_length_;
783 unsigned long user_context_length_;
786 uint32_t dhcp4_next_server_;
792 unsigned long dhcp4_server_hostname_length_;
798 unsigned long dhcp4_boot_file_name_length_;
804 unsigned long auth_key_length_;
823 my_bool dhcp4_client_classes_null_;
827 my_bool dhcp6_client_classes_null_;
833 my_bool dhcp4_next_server_null_;
836 my_bool dhcp4_server_hostname_null_;
839 my_bool dhcp4_boot_file_name_null_;
856class MySqlHostWithOptionsExchange :
public MySqlHostExchange {
860 static const size_t OPTION_COLUMNS = 8;
876 class OptionProcessor {
886 const size_t start_column)
887 : universe_(universe), start_column_(start_column), option_id_(0),
888 code_(0), value_length_(0), formatted_value_length_(0),
889 space_length_(0), persistent_(false), cancelled_(false),
890 user_context_length_(0),
894 option_id_index_(start_column), code_index_(start_column_ + 1),
895 value_index_(start_column_ + 2),
896 formatted_value_index_(start_column_ + 3),
897 space_index_(start_column_ + 4),
898 persistent_index_(start_column_ + 5),
899 cancelled_index_(start_column_ + 6),
900 user_context_index_(start_column_ + 7),
901 most_recent_option_id_(0) {
903 memset(value_, 0,
sizeof(value_));
904 memset(formatted_value_, 0,
sizeof(formatted_value_));
905 memset(space_, 0,
sizeof(space_));
906 memset(user_context_, 0,
sizeof(user_context_));
910 uint64_t getOptionId()
const {
935 if ((option_id_null_ ==
MLM_TRUE) ||
936 (most_recent_option_id_ >= option_id_)) {
942 most_recent_option_id_ = option_id_;
949 space_[space_length_] =
'\0';
950 space.assign(space_);
960 std::string formatted_value;
961 if (formatted_value_null_ ==
MLM_FALSE) {
962 formatted_value_[formatted_value_length_] =
'\0';
963 formatted_value.assign(formatted_value_);
967 std::string user_context;
969 user_context_[user_context_length_] =
'\0';
970 user_context.assign(user_context_);
1014 option.reset(
new Option(universe_, code_, buf.begin(),
1017 option.reset(
new Option(universe_, code_));
1024 if (formatted_value.empty()) {
1028 option = def->optionFactory(universe_, code_, buf.begin(),
1034 std::vector<std::string> split_vec;
1035 boost::split(split_vec, formatted_value, boost::is_any_of(
","));
1036 option = def->optionFactory(universe_, code_, split_vec);
1044 if (!user_context.empty()) {
1049 <<
"' is no a JSON map");
1051 desc.setContext(ctx);
1054 <<
"' is invalid JSON: " << ex.
what());
1057 cfg->add(desc, space);
1064 void setColumnNames(std::vector<std::string>& columns) {
1065 columns[option_id_index_] =
"option_id";
1066 columns[code_index_] =
"code";
1067 columns[value_index_] =
"value";
1068 columns[formatted_value_index_] =
"formatted_value";
1069 columns[space_index_] =
"space";
1070 columns[persistent_index_] =
"persistent";
1071 columns[cancelled_index_] =
"cancelled";
1072 columns[user_context_index_] =
"user_context";
1081 void setBindFields(std::vector<MYSQL_BIND>& bind) {
1085 most_recent_option_id_ = 0;
1089 persistent_ =
false;
1098 memset(value_, 0,
sizeof(value_));
1099 memset(formatted_value_, 0,
sizeof(formatted_value_));
1100 memset(space_, 0,
sizeof(space_));
1101 memset(user_context_, 0,
sizeof(user_context_));
1104 bind[option_id_index_].buffer_type = MYSQL_TYPE_LONG;
1105 bind[option_id_index_].buffer =
reinterpret_cast<char*
>(&option_id_);
1106 bind[option_id_index_].is_unsigned =
MLM_TRUE;
1107 bind[option_id_index_].is_null = &option_id_null_;
1110 bind[code_index_].buffer_type = MYSQL_TYPE_SHORT;
1111 bind[code_index_].buffer =
reinterpret_cast<char*
>(&
code_);
1112 bind[code_index_].is_unsigned =
MLM_TRUE;
1113 bind[code_index_].is_null = &code_null_;
1116 value_length_ =
sizeof(value_);
1117 bind[value_index_].buffer_type = MYSQL_TYPE_BLOB;
1118 bind[value_index_].buffer =
reinterpret_cast<char*
>(value_);
1119 bind[value_index_].buffer_length = value_length_;
1120 bind[value_index_].length = &value_length_;
1121 bind[value_index_].is_null = &value_null_;
1124 formatted_value_length_ =
sizeof(formatted_value_);
1125 bind[formatted_value_index_].buffer_type = MYSQL_TYPE_STRING;
1126 bind[formatted_value_index_].buffer =
reinterpret_cast<char*
>(formatted_value_);
1127 bind[formatted_value_index_].buffer_length = formatted_value_length_;
1128 bind[formatted_value_index_].length = &formatted_value_length_;
1129 bind[formatted_value_index_].is_null = &formatted_value_null_;
1132 space_length_ =
sizeof(space_);
1133 bind[space_index_].buffer_type = MYSQL_TYPE_STRING;
1134 bind[space_index_].buffer =
reinterpret_cast<char*
>(space_);
1135 bind[space_index_].buffer_length = space_length_;
1136 bind[space_index_].length = &space_length_;
1137 bind[space_index_].is_null = &space_null_;
1140 bind[persistent_index_].buffer_type = MYSQL_TYPE_TINY;
1141 bind[persistent_index_].buffer =
reinterpret_cast<char*
>(&persistent_);
1142 bind[persistent_index_].is_unsigned =
MLM_TRUE;
1145 bind[cancelled_index_].buffer_type = MYSQL_TYPE_TINY;
1146 bind[cancelled_index_].buffer =
reinterpret_cast<char*
>(&cancelled_);
1147 bind[cancelled_index_].is_unsigned =
MLM_TRUE;
1150 user_context_length_ =
sizeof(user_context_);
1151 bind[user_context_index_].buffer_type = MYSQL_TYPE_STRING;
1152 bind[user_context_index_].buffer =
reinterpret_cast<char*
>(user_context_);
1153 bind[user_context_index_].buffer_length = user_context_length_;
1154 bind[user_context_index_].length = &user_context_length_;
1155 bind[user_context_index_].is_null = &user_context_null_;
1164 size_t start_column_;
1167 uint32_t option_id_;
1176 unsigned long value_length_;
1182 unsigned long formatted_value_length_;
1188 unsigned long space_length_;
1201 unsigned long user_context_length_;
1217 my_bool formatted_value_null_;
1229 size_t option_id_index_;
1235 size_t value_index_;
1238 size_t formatted_value_index_;
1241 size_t space_index_;
1244 size_t persistent_index_;
1247 size_t cancelled_index_;
1251 size_t user_context_index_;
1254 uint32_t most_recent_option_id_;
1258 typedef boost::shared_ptr<OptionProcessor> OptionProcessorPtr;
1268 enum FetchedOptions {
1282 MySqlHostWithOptionsExchange(
const FetchedOptions& fetched_options,
1283 const size_t additional_columns_num = 0)
1284 : MySqlHostExchange(getRequiredColumnsNum(fetched_options)
1285 + additional_columns_num),
1286 opt_proc4_(), opt_proc6_() {
1289 if ((fetched_options == DHCP4_ONLY) ||
1290 (fetched_options == DHCP4_AND_DHCP6)) {
1291 opt_proc4_.reset(
new OptionProcessor(
Option::V4,
1292 findAvailColumn()));
1293 opt_proc4_->setColumnNames(columns_);
1297 if ((fetched_options == DHCP6_ONLY) ||
1298 (fetched_options == DHCP4_AND_DHCP6)) {
1299 opt_proc6_.reset(
new OptionProcessor(
Option::V6,
1300 findAvailColumn()));
1301 opt_proc6_->setColumnNames(columns_);
1316 if (!hosts.empty()) {
1325 most_recent_host = boost::const_pointer_cast<Host>(hosts.back());
1331 if (!most_recent_host || (most_recent_host->getHostId() < getHostId())) {
1332 HostPtr host = retrieveHost();
1333 hosts.push_back(host);
1334 most_recent_host = host;
1340 opt_proc4_->retrieveOption(cfg);
1346 opt_proc6_->retrieveOption(cfg);
1353 virtual std::vector<MYSQL_BIND> createBindForReceive()
override {
1355 static_cast<void>(MySqlHostExchange::createBindForReceive());
1359 opt_proc4_->setBindFields(bind_);
1364 opt_proc6_->setBindFields(bind_);
1368 setErrorIndicators(bind_, error_);
1386 static size_t getRequiredColumnsNum(
const FetchedOptions& fetched_options) {
1387 return (fetched_options == DHCP4_AND_DHCP6 ? 2 * OPTION_COLUMNS :
1394 OptionProcessorPtr opt_proc4_;
1399 OptionProcessorPtr opt_proc6_;
1414class MySqlHostIPv6Exchange :
public MySqlHostWithOptionsExchange {
1418 static const size_t RESERVATION_COLUMNS = 5;
1426 MySqlHostIPv6Exchange(
const FetchedOptions& fetched_options)
1427 : MySqlHostWithOptionsExchange(fetched_options, RESERVATION_COLUMNS),
1429 reserv_type_(0), reserv_type_null_(
MLM_FALSE),
1430 ipv6_address_buffer_len_(0), prefix_len_(0), iaid_(0),
1431 reservation_id_index_(findAvailColumn()),
1432 address_index_(reservation_id_index_ + 1),
1433 prefix_len_index_(reservation_id_index_ + 2),
1434 type_index_(reservation_id_index_ + 3),
1435 iaid_index_(reservation_id_index_ + 4),
1436 most_recent_reservation_id_(0) {
1438 memset(ipv6_address_buffer_, 0,
sizeof(ipv6_address_buffer_));
1441 columns_[reservation_id_index_] =
"reservation_id";
1442 columns_[address_index_] =
"address";
1443 columns_[prefix_len_index_] =
"prefix_len";
1444 columns_[type_index_] =
"type";
1445 columns_[iaid_index_] =
"dhcp6_iaid";
1451 uint32_t getReservationId()
const {
1453 return (reservation_id_);
1468 switch (reserv_type_) {
1479 "invalid IPv6 reservation type returned: "
1480 <<
static_cast<int>(reserv_type_)
1481 <<
". Only 0 or 2 are allowed.");
1511 MySqlHostWithOptionsExchange::processFetchedData(hosts);
1513 if (getReservationId() == 0) {
1517 if (hosts.empty()) {
1519 " IPv6 reservation");
1521 HostPtr host = boost::const_pointer_cast<Host>(hosts.back());
1525 if (getReservationId() > most_recent_reservation_id_) {
1526 most_recent_reservation_id_ = getReservationId();
1528 if (most_recent_reservation_id_ > 0) {
1529 host->addReservation(retrieveReservation());
1542 virtual std::vector<MYSQL_BIND> createBindForReceive()
override {
1545 most_recent_reservation_id_ = 0;
1548 static_cast<void>(MySqlHostWithOptionsExchange::createBindForReceive());
1551 bind_[reservation_id_index_].buffer_type = MYSQL_TYPE_LONG;
1552 bind_[reservation_id_index_].buffer =
reinterpret_cast<char*
>(&reservation_id_);
1553 bind_[reservation_id_index_].is_unsigned =
MLM_TRUE;
1556 ipv6_address_buffer_len_ = isc::asiolink::V6ADDRESS_LEN;
1557 bind_[address_index_].buffer_type = MYSQL_TYPE_BLOB;
1558 bind_[address_index_].buffer =
reinterpret_cast<char*
>(ipv6_address_buffer_);
1559 bind_[address_index_].buffer_length = ipv6_address_buffer_len_;
1560 bind_[address_index_].length = &ipv6_address_buffer_len_;
1563 bind_[prefix_len_index_].buffer_type = MYSQL_TYPE_TINY;
1564 bind_[prefix_len_index_].buffer =
reinterpret_cast<char*
>(&prefix_len_);
1565 bind_[prefix_len_index_].is_unsigned =
MLM_TRUE;
1569 bind_[type_index_].buffer_type = MYSQL_TYPE_TINY;
1570 bind_[type_index_].buffer =
reinterpret_cast<char*
>(&reserv_type_);
1571 bind_[type_index_].is_unsigned =
MLM_TRUE;
1572 bind_[type_index_].is_null = &reserv_type_null_;
1575 bind_[iaid_index_].buffer_type = MYSQL_TYPE_LONG;
1576 bind_[iaid_index_].buffer =
reinterpret_cast<char*
>(&iaid_);
1577 bind_[iaid_index_].is_unsigned =
MLM_TRUE;
1580 setErrorIndicators(bind_, error_);
1588 uint32_t reservation_id_;
1591 uint8_t reserv_type_;
1600 uint8_t ipv6_address_buffer_[isc::asiolink::V6ADDRESS_LEN];
1603 unsigned long ipv6_address_buffer_len_;
1606 uint8_t prefix_len_;
1614 size_t reservation_id_index_;
1617 size_t address_index_;
1620 size_t prefix_len_index_;
1631 uint32_t most_recent_reservation_id_;
1644class MySqlIPv6ReservationExchange {
1648 static const size_t RESRV_COLUMNS = 6;
1655 MySqlIPv6ReservationExchange()
1656 : host_id_(0), prefix_len_(0), type_(0),
1660 std::fill(&error_[0], &error_[RESRV_COLUMNS],
MLM_FALSE);
1663 columns_[0] =
"host_id";
1664 columns_[1] =
"address";
1665 columns_[2] =
"prefix_len";
1666 columns_[3] =
"type";
1667 columns_[4] =
"dhcp6_iaid";
1669 BOOST_STATIC_ASSERT(4 < RESRV_COLUMNS);
1686 std::vector<MYSQL_BIND> createBindForSend(
const IPv6Resrv& resv,
1688 const bool unique_ip) {
1699 memset(bind_, 0,
sizeof(bind_));
1704 addr6_ = resv.getPrefix().toBytes();
1705 if (addr6_.size() != isc::asiolink::V6ADDRESS_LEN) {
1707 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
1710 addr6_length_ = isc::asiolink::V6ADDRESS_LEN;
1711 bind_[0].buffer_type = MYSQL_TYPE_BLOB;
1712 bind_[0].buffer =
reinterpret_cast<char*
>(&addr6_[0]);
1713 bind_[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
1714 bind_[0].length = &addr6_length_;
1717 prefix_len_ = resv.getPrefixLen();
1718 bind_[1].buffer_type = MYSQL_TYPE_TINY;
1719 bind_[1].buffer =
reinterpret_cast<char*
>(&prefix_len_);
1725 bind_[2].buffer_type = MYSQL_TYPE_TINY;
1726 bind_[2].buffer =
reinterpret_cast<char*
>(&type_);
1732 bind_[3].buffer_type = MYSQL_TYPE_LONG;
1733 bind_[3].buffer =
reinterpret_cast<char*
>(&iaid_);
1737 bind_[4].buffer_type = MYSQL_TYPE_LONG;
1738 bind_[4].buffer =
reinterpret_cast<char*
>(&host_id_);
1741 }
catch (
const std::exception& ex) {
1743 "Could not create bind array from IPv6 Reservation: "
1744 << resv_.toText() <<
", reason: " << ex.
what());
1750 std::vector<MYSQL_BIND> vec(&bind_[0], &bind_[RESRV_COLUMNS-1]);
1756 vec.push_back(bind_[0]);
1757 vec.push_back(bind_[1]);
1769 uint8_t prefix_len_;
1781 MYSQL_BIND bind_[RESRV_COLUMNS];
1784 std::string columns_[RESRV_COLUMNS];
1788 my_bool error_[RESRV_COLUMNS];
1791 std::vector<uint8_t> addr6_;
1794 unsigned long addr6_length_;
1800class MySqlOptionExchange {
1802 static const size_t OPTION_COLUMNS = 10;
1807 MySqlOptionExchange()
1808 : type_(0), value_len_(0), formatted_value_len_(0), space_(),
1809 space_len_(0), persistent_(false), cancelled_(false),
1810 user_context_(), user_context_len_(0), subnet_id_(SUBNET_ID_UNUSED),
1811 host_id_(0), option_() {
1813 BOOST_STATIC_ASSERT(10 <= OPTION_COLUMNS);
1819 std::vector<MYSQL_BIND> createBindForSend(
const OptionDescriptor& opt_desc,
1820 const std::string& opt_space,
1821 const Optional<SubnetID>& subnet_id,
1826 option_ = opt_desc.option_;
1828 memset(bind_, 0,
sizeof(bind_));
1834 bind_[0].buffer_type = MYSQL_TYPE_NULL;
1837 type_ = option_->getType();
1838 bind_[1].buffer_type = MYSQL_TYPE_SHORT;
1839 bind_[1].buffer =
reinterpret_cast<char*
>(&type_);
1843 if (opt_desc.formatted_value_.empty() &&
1844 (opt_desc.option_->len() > opt_desc.option_->getHeaderLen())) {
1849 opt_desc.option_->pack(buf);
1850 const uint8_t* buf_ptr = buf.getData();
1851 value_.assign(buf_ptr + opt_desc.option_->getHeaderLen(),
1852 buf_ptr + buf.getLength());
1853 value_len_ = value_.size();
1854 bind_[2].buffer_type = MYSQL_TYPE_BLOB;
1855 bind_[2].buffer = &value_[0];
1856 bind_[2].buffer_length = value_len_;
1857 bind_[2].length = &value_len_;
1863 bind_[2].buffer_type = MYSQL_TYPE_NULL;
1867 if (!opt_desc.formatted_value_.empty()) {
1868 formatted_value_len_ = opt_desc.formatted_value_.size();
1869 bind_[3].buffer_type = MYSQL_TYPE_STRING;
1870 bind_[3].buffer =
const_cast<char*
>(opt_desc.formatted_value_.c_str());
1871 bind_[3].buffer_length = formatted_value_len_;
1872 bind_[3].length = &formatted_value_len_;
1875 bind_[3].buffer_type = MYSQL_TYPE_NULL;
1880 space_len_ = space_.size();
1881 bind_[4].buffer_type = MYSQL_TYPE_STRING;
1882 bind_[4].buffer =
const_cast<char*
>(space_.c_str());
1883 bind_[4].buffer_length = space_len_;
1884 bind_[4].length = &space_len_;
1887 persistent_ = opt_desc.persistent_;
1888 bind_[5].buffer_type = MYSQL_TYPE_TINY;
1889 bind_[5].buffer =
reinterpret_cast<char*
>(&persistent_);
1893 cancelled_ = opt_desc.cancelled_;
1894 bind_[6].buffer_type = MYSQL_TYPE_TINY;
1895 bind_[6].buffer =
reinterpret_cast<char*
>(&cancelled_);
1901 user_context_ = ctx->str();
1902 user_context_len_ = user_context_.size();
1903 bind_[7].buffer_type = MYSQL_TYPE_STRING;
1904 bind_[7].buffer =
const_cast<char*
>(user_context_.c_str());
1905 bind_[7].buffer_length = user_context_len_;
1906 bind_[7].length = &user_context_len_;
1908 bind_[7].buffer_type = MYSQL_TYPE_NULL;
1912 if (!subnet_id.unspecified()) {
1913 subnet_id_ = subnet_id;
1914 bind_[8].buffer_type = MYSQL_TYPE_LONG;
1915 bind_[8].buffer =
reinterpret_cast<char*
>(subnet_id_);
1919 bind_[8].buffer_type = MYSQL_TYPE_NULL;
1924 bind_[9].buffer_type = MYSQL_TYPE_LONG;
1925 bind_[9].buffer =
reinterpret_cast<char*
>(&host_id_);
1928 }
catch (
const std::exception& ex) {
1930 "Could not create bind array for inserting DHCP "
1931 "option: " << option_->toText() <<
", reason: "
1935 return (std::vector<MYSQL_BIND>(&bind_[0], &bind_[OPTION_COLUMNS]));
1944 std::vector<uint8_t> value_;
1947 unsigned long value_len_;
1950 unsigned long formatted_value_len_;
1956 unsigned long space_len_;
1967 std::string user_context_;
1970 unsigned long user_context_len_;
1973 uint32_t subnet_id_;
1982 MYSQL_BIND bind_[OPTION_COLUMNS];
2170 std::pair<uint32_t, uint32_t>
getVersion(
const std::string& timer_name = std::string())
const;
2182 std::vector<MYSQL_BIND>& bind);
2217 const std::string& opt_space,
2218 const Optional<SubnetID>& subnet_id,
2231 const uint64_t host_id);
2247 const char* what)
const;
2270 boost::shared_ptr<MySqlHostExchange> exchange,
2294 const uint8_t* identifier_begin,
2295 const size_t identifier_len,
2297 boost::shared_ptr<MySqlHostExchange> exchange)
const;
2331typedef boost::array<TaggedStatement, MySqlHostDataSourceImpl::NUM_STATEMENTS>
2332TaggedStatementArray;
2336TaggedStatementArray tagged_statements = { {
2342 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2343 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, "
2344 "h.hostname, h.dhcp4_client_classes, h.dhcp6_client_classes, "
2346 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2347 "h.dhcp4_boot_file_name, h.auth_key, "
2348 "o4.option_id, o4.code, o4.value, o4.formatted_value, o4.space, "
2349 "o4.persistent, o4.cancelled, o4.user_context, "
2350 "o6.option_id, o6.code, o6.value, o6.formatted_value, o6.space, "
2351 "o6.persistent, o6.cancelled, o6.user_context, "
2352 "r.reservation_id, r.address, r.prefix_len, r.type, "
2355 "LEFT JOIN dhcp4_options AS o4 "
2356 "ON h.host_id = o4.host_id "
2357 "LEFT JOIN dhcp6_options AS o6 "
2358 "ON h.host_id = o6.host_id "
2359 "LEFT JOIN ipv6_reservations AS r "
2360 "ON h.host_id = r.host_id "
2361 "WHERE dhcp_identifier = ? AND dhcp_identifier_type = ? "
2362 "ORDER BY h.host_id, o4.option_id, o6.option_id, r.reservation_id"},
2368 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2369 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2370 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2371 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2372 "h.dhcp4_boot_file_name, h.auth_key, "
2373 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2374 "o.persistent, o.cancelled, o.user_context "
2376 "LEFT JOIN dhcp4_options AS o "
2377 "ON h.host_id = o.host_id "
2378 "WHERE ipv4_address = ? "
2379 "ORDER BY h.host_id, o.option_id"},
2385 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2386 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2387 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2388 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2389 "h.dhcp4_boot_file_name, h.auth_key, "
2390 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2391 "o.persistent, o.cancelled, o.user_context "
2393 "LEFT JOIN dhcp4_options AS o "
2394 "ON h.host_id = o.host_id "
2395 "WHERE h.dhcp4_subnet_id = ? AND h.dhcp_identifier_type = ? "
2396 "AND h.dhcp_identifier = ? "
2397 "ORDER BY h.host_id, o.option_id"},
2403 "SELECT h.host_id, h.dhcp_identifier, "
2404 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2405 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2406 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2407 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2408 "h.dhcp4_boot_file_name, h.auth_key, "
2409 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2410 "o.persistent, o.cancelled, o.user_context, "
2411 "r.reservation_id, r.address, r.prefix_len, r.type, "
2414 "LEFT JOIN dhcp6_options AS o "
2415 "ON h.host_id = o.host_id "
2416 "LEFT JOIN ipv6_reservations AS r "
2417 "ON h.host_id = r.host_id "
2418 "WHERE h.dhcp6_subnet_id = ? AND h.dhcp_identifier_type = ? "
2419 "AND h.dhcp_identifier = ? "
2420 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2427 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2428 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2429 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2430 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2431 "h.dhcp4_boot_file_name, h.auth_key, "
2432 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2433 "o.persistent, o.cancelled, o.user_context "
2435 "LEFT JOIN dhcp4_options AS o "
2436 "ON h.host_id = o.host_id "
2437 "WHERE h.dhcp4_subnet_id = ? AND h.ipv4_address = ? "
2438 "ORDER BY h.host_id, o.option_id"},
2447 "SELECT h.host_id, h.dhcp_identifier, "
2448 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2449 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2450 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2451 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2452 "h.dhcp4_boot_file_name, h.auth_key, "
2453 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2454 "o.persistent, o.cancelled, o.user_context,"
2455 "r.reservation_id, r.address, r.prefix_len, r.type, "
2458 "LEFT JOIN dhcp6_options AS o "
2459 "ON h.host_id = o.host_id "
2460 "LEFT JOIN ipv6_reservations AS r "
2461 "ON h.host_id = r.host_id "
2462 "WHERE h.host_id = "
2463 "( SELECT host_id FROM ipv6_reservations "
2464 "WHERE address = ? AND prefix_len = ? ) "
2465 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2474 "SELECT h.host_id, h.dhcp_identifier, "
2475 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2476 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2477 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2478 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2479 "h.dhcp4_boot_file_name, h.auth_key, "
2480 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2481 "o.persistent, o.cancelled, o.user_context, "
2482 "r.reservation_id, r.address, r.prefix_len, r.type, "
2485 "LEFT JOIN dhcp6_options AS o "
2486 "ON h.host_id = o.host_id "
2487 "LEFT JOIN ipv6_reservations AS r "
2488 "ON h.host_id = r.host_id "
2489 "WHERE h.dhcp6_subnet_id = ? AND h.host_id IN "
2490 "(SELECT host_id FROM ipv6_reservations "
2491 "WHERE address = ?) "
2492 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2502 "SELECT h.host_id, h.dhcp_identifier, "
2503 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2504 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2505 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2506 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2507 "h.dhcp4_boot_file_name, h.auth_key, "
2508 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2509 "o.persistent, o.cancelled, o.user_context, "
2510 "r.reservation_id, r.address, r.prefix_len, r.type, "
2513 "LEFT JOIN dhcp6_options AS o "
2514 "ON h.host_id = o.host_id "
2515 "LEFT JOIN ipv6_reservations AS r "
2516 "ON h.host_id = r.host_id "
2517 "WHERE h.host_id IN "
2518 "(SELECT host_id FROM ipv6_reservations "
2519 "WHERE address = ?) "
2520 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2526 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2527 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2528 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2529 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2530 "h.dhcp4_boot_file_name, h.auth_key, "
2531 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2532 "o.persistent, o.cancelled, o.user_context "
2534 "LEFT JOIN dhcp4_options AS o "
2535 "ON h.host_id = o.host_id "
2536 "WHERE h.dhcp4_subnet_id = ? "
2537 "ORDER BY h.host_id, o.option_id"},
2544 "SELECT h.host_id, h.dhcp_identifier, "
2545 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2546 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2547 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2548 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2549 "h.dhcp4_boot_file_name, h.auth_key, "
2550 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2551 "o.persistent, o.cancelled, o.user_context, "
2552 "r.reservation_id, r.address, r.prefix_len, r.type, "
2555 "LEFT JOIN dhcp6_options AS o "
2556 "ON h.host_id = o.host_id "
2557 "LEFT JOIN ipv6_reservations AS r "
2558 "ON h.host_id = r.host_id "
2559 "WHERE h.dhcp6_subnet_id = ? "
2560 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2567 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2568 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, "
2569 "h.hostname, h.dhcp4_client_classes, h.dhcp6_client_classes, "
2571 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2572 "h.dhcp4_boot_file_name, h.auth_key, "
2573 "o4.option_id, o4.code, o4.value, o4.formatted_value, o4.space, "
2574 "o4.persistent, o4.cancelled, o4.user_context, "
2575 "o6.option_id, o6.code, o6.value, o6.formatted_value, o6.space, "
2576 "o6.persistent, o6.cancelled, o6.user_context, "
2577 "r.reservation_id, r.address, r.prefix_len, r.type, "
2580 "LEFT JOIN dhcp4_options AS o4 "
2581 "ON h.host_id = o4.host_id "
2582 "LEFT JOIN dhcp6_options AS o6 "
2583 "ON h.host_id = o6.host_id "
2584 "LEFT JOIN ipv6_reservations AS r "
2585 "ON h.host_id = r.host_id "
2586 "WHERE h.hostname = ? "
2587 "ORDER BY h.host_id, o4.option_id, o6.option_id, r.reservation_id"},
2593 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2594 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2595 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2596 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2597 "h.dhcp4_boot_file_name, h.auth_key, "
2598 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2599 "o.persistent, o.cancelled, o.user_context "
2601 "LEFT JOIN dhcp4_options AS o "
2602 "ON h.host_id = o.host_id "
2603 "WHERE h.hostname = ? AND h.dhcp4_subnet_id = ? "
2604 "ORDER BY h.host_id, o.option_id"},
2610 "SELECT h.host_id, h.dhcp_identifier, "
2611 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2612 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2613 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2614 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2615 "h.dhcp4_boot_file_name, h.auth_key, "
2616 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2617 "o.persistent, o.cancelled, o.user_context, "
2618 "r.reservation_id, r.address, r.prefix_len, r.type, "
2621 "LEFT JOIN dhcp6_options AS o "
2622 "ON h.host_id = o.host_id "
2623 "LEFT JOIN ipv6_reservations AS r "
2624 "ON h.host_id = r.host_id "
2625 "WHERE h.hostname = ? AND h.dhcp6_subnet_id = ? "
2626 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2634 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2635 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2636 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2637 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2638 "h.dhcp4_boot_file_name, h.auth_key, "
2639 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2640 "o.persistent, o.cancelled, o.user_context "
2641 "FROM ( SELECT * FROM hosts AS h "
2642 "WHERE h.dhcp4_subnet_id = ? AND h.host_id > ? "
2643 "ORDER BY h.host_id "
2645 "LEFT JOIN dhcp4_options AS o "
2646 "ON h.host_id = o.host_id "
2647 "ORDER BY h.host_id, o.option_id"},
2655 "SELECT h.host_id, h.dhcp_identifier, "
2656 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2657 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2658 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2659 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2660 "h.dhcp4_boot_file_name, h.auth_key, "
2661 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2662 "o.persistent, o.cancelled, o.user_context, "
2663 "r.reservation_id, r.address, r.prefix_len, r.type, "
2665 "FROM ( SELECT * FROM hosts AS h "
2666 "WHERE h.dhcp6_subnet_id = ? AND h.host_id > ? "
2667 "ORDER BY h.host_id "
2669 "LEFT JOIN dhcp6_options AS o "
2670 "ON h.host_id = o.host_id "
2671 "LEFT JOIN ipv6_reservations AS r "
2672 "ON h.host_id = r.host_id "
2673 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2681 "SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
2682 "h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2683 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2684 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2685 "h.dhcp4_boot_file_name, h.auth_key, "
2686 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2687 "o.persistent, o.cancelled, o.user_context "
2688 "FROM ( SELECT * FROM hosts AS h "
2689 "WHERE h.host_id > ? "
2690 "ORDER BY h.host_id "
2692 "LEFT JOIN dhcp4_options AS o "
2693 "ON h.host_id = o.host_id "
2694 "ORDER BY h.host_id, o.option_id"},
2702 "SELECT h.host_id, h.dhcp_identifier, "
2703 "h.dhcp_identifier_type, h.dhcp4_subnet_id, "
2704 "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
2705 "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
2706 "h.dhcp4_next_server, h.dhcp4_server_hostname, "
2707 "h.dhcp4_boot_file_name, h.auth_key, "
2708 "o.option_id, o.code, o.value, o.formatted_value, o.space, "
2709 "o.persistent, o.cancelled, o.user_context, "
2710 "r.reservation_id, r.address, r.prefix_len, r.type, "
2712 "FROM ( SELECT * FROM hosts AS h "
2713 "WHERE h.host_id > ? "
2714 "ORDER BY h.host_id "
2716 "LEFT JOIN dhcp6_options AS o "
2717 "ON h.host_id = o.host_id "
2718 "LEFT JOIN ipv6_reservations AS r "
2719 "ON h.host_id = r.host_id "
2720 "ORDER BY h.host_id, o.option_id, r.reservation_id"},
2725 "INSERT INTO hosts(host_id, dhcp_identifier, dhcp_identifier_type, "
2726 "dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, "
2727 "dhcp4_client_classes, dhcp6_client_classes, "
2728 "user_context, dhcp4_next_server, "
2729 "dhcp4_server_hostname, dhcp4_boot_file_name, auth_key) "
2730 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
2744 "INSERT INTO hosts(host_id, dhcp_identifier, dhcp_identifier_type, "
2745 "dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, "
2746 "dhcp4_client_classes, dhcp6_client_classes, "
2747 "user_context, dhcp4_next_server, "
2748 "dhcp4_server_hostname, dhcp4_boot_file_name, auth_key) "
2749 "SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? FROM DUAL "
2750 "WHERE NOT EXISTS ("
2751 "SELECT 1 FROM hosts "
2752 "WHERE ipv4_address = ? AND dhcp4_subnet_id = ? "
2759 "INSERT INTO ipv6_reservations(address, prefix_len, type, "
2760 "dhcp6_iaid, host_id) "
2761 "VALUES (?, ?, ?, ?, ?)"},
2766 "INSERT INTO ipv6_reservations(address, prefix_len, type, "
2767 "dhcp6_iaid, host_id) "
2768 "SELECT ?, ?, ?, ?, ? FROM DUAL "
2769 "WHERE NOT EXISTS ("
2770 "SELECT 1 FROM ipv6_reservations "
2771 "WHERE address = ? AND prefix_len = ? "
2778 "INSERT INTO dhcp4_options(option_id, code, value, formatted_value, space, "
2779 "persistent, cancelled, user_context, dhcp4_subnet_id, host_id, scope_id) "
2780 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 3)"},
2785 "INSERT INTO dhcp6_options(option_id, code, value, formatted_value, space, "
2786 "persistent, cancelled, user_context, dhcp6_subnet_id, host_id, scope_id) "
2787 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 3)"},
2791 "DELETE FROM hosts WHERE dhcp4_subnet_id = ? AND ipv4_address = ?"},
2795 "DELETE h FROM hosts AS h "
2796 "INNER JOIN ipv6_reservations AS r "
2797 "ON h.host_id = r.host_id "
2798 "WHERE h.dhcp6_subnet_id = ? AND r.address = ?"},
2802 "DELETE FROM hosts WHERE dhcp4_subnet_id = ? AND dhcp_identifier_type=? "
2803 "AND dhcp_identifier = ?"},
2807 "DELETE FROM hosts WHERE dhcp6_subnet_id = ? AND dhcp_identifier_type=? "
2808 "AND dhcp_identifier = ?"}
2819 : conn_(parameters, io_service_accessor, db_reconnect_callback),
2820 is_readonly_(true) {
2832 lock_guard<mutex> lock(mgr_.
pool_->mutex_);
2833 if (!mgr_.
pool_->pool_.empty()) {
2835 mgr_.
pool_->pool_.pop_back();
2843 if (mgr_.
pool_->pool_.empty()) {
2853 lock_guard<mutex> lock(mgr_.pool_->mutex_);
2854 mgr_.pool_->pool_.push_back(ctx_);
2855 if (ctx_->conn_.isUnusable()) {
2856 mgr_.unusable_ =
true;
2858 }
else if (ctx_->conn_.isUnusable()) {
2859 mgr_.unusable_ =
true;
2864 : parameters_(parameters), ip_reservations_unique_(true), unusable_(false) {
2868 timer_name_ += boost::lexical_cast<std::string>(
reinterpret_cast<uint64_t
>(
this));
2889 ctx->conn_.openDatabase();
2892 if (ctx->conn_.getTls()) {
2893 std::string cipher = ctx->conn_.getTlsCipher();
2894 if (cipher.empty()) {
2906 ctx->conn_.prepareStatements(tagged_statements.begin(),
2911 ctx->is_readonly_ = ctx->conn_.configuredReadOnly();
2915 if (!ctx->is_readonly_) {
2918 tagged_statements.end());
2925 ctx->host_ipv4_exchange_.reset(
new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY));
2926 ctx->host_ipv6_exchange_.reset(
new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP6_ONLY));
2927 ctx->host_ipv46_exchange_.reset(
new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP4_AND_DHCP6));
2928 ctx->host_ipv6_reservation_exchange_.reset(
new MySqlIPv6ReservationExchange());
2929 ctx->host_option_exchange_.reset(
new MySqlOptionExchange());
2949 bool reopened =
false;
2951 const std::string timer_name = db_reconnect_ctl->timerName();
2956 std::list<std::string> host_db_access_list = cfg_db->getHostDbAccessStringList();
2957 for (std::string& hds : host_db_access_list) {
2964 }
catch (
const std::exception& ex) {
2980 if (!db_reconnect_ctl->checkRetries()) {
2983 .arg(db_reconnect_ctl->maxRetries());
2996 .arg(db_reconnect_ctl->maxRetries() - db_reconnect_ctl->retriesLeft() + 1)
2997 .arg(db_reconnect_ctl->maxRetries())
2998 .arg(db_reconnect_ctl->retryInterval());
3004 db_reconnect_ctl->retryInterval(),
3013std::pair<uint32_t, uint32_t>
3026 std::vector<MYSQL_BIND>& bind) {
3028 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), &bind[0]);
3029 checkError(ctx, status, stindex,
"unable to bind parameters");
3036 if (mysql_errno(ctx->conn_.mysql_) == ER_DUP_ENTRY) {
3039 checkError(ctx, status, stindex,
"unable to execute");
3047 my_ulonglong numrows = mysql_stmt_affected_rows(ctx->conn_.getStatement(stindex));
3058 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), &bind[0]);
3059 checkError(ctx, status, stindex,
"unable to bind parameters");
3065 checkError(ctx, status, stindex,
"unable to execute");
3069 my_ulonglong numrows = mysql_stmt_affected_rows(ctx->conn_.getStatement(stindex));
3071 return (numrows != 0);
3078 std::vector<MYSQL_BIND> bind = ctx->host_ipv6_reservation_exchange_->
3088 const std::string& opt_space,
3089 const Optional<SubnetID>& subnet_id,
3091 std::vector<MYSQL_BIND> bind = ctx->host_option_exchange_->createBindForSend(opt_desc, opt_space, subnet_id,
id);
3100 const uint64_t host_id) {
3103 std::list<std::string> option_spaces = options_cfg->getOptionSpaceNames();
3104 std::list<std::string> vendor_spaces = options_cfg->getVendorIdsSpaceNames();
3105 option_spaces.insert(option_spaces.end(), vendor_spaces.begin(),
3106 vendor_spaces.end());
3110 for (
auto const& space : option_spaces) {
3112 if (options && !options->empty()) {
3113 for (
auto const& opt : *options) {
3114 addOption(ctx, stindex, opt, space, Optional<SubnetID>(), host_id);
3124 const char* what)
const {
3125 ctx->conn_.checkError(status, index, what);
3132 boost::shared_ptr<MySqlHostExchange> exchange,
3134 bool single)
const {
3137 int status = mysql_stmt_bind_param(ctx->conn_.getStatement(stindex), bind);
3138 checkError(ctx, status, stindex,
"unable to bind WHERE clause parameter");
3142 std::vector<MYSQL_BIND> outbind = exchange->createBindForReceive();
3143 status = mysql_stmt_bind_result(ctx->conn_.getStatement(stindex), &outbind[0]);
3144 checkError(ctx, status, stindex,
"unable to bind SELECT clause parameters");
3148 checkError(ctx, status, stindex,
"unable to execute");
3152 status = mysql_stmt_store_result(ctx->conn_.getStatement(stindex));
3153 checkError(ctx, status, stindex,
"unable to set up for storing all results");
3160 while ((status = mysql_stmt_fetch(ctx->conn_.getStatement(stindex))) ==
3163 exchange->processFetchedData(result);
3168 ctx->conn_.text_statements_[stindex] <<
">");
3171 if (single && (result.size() > 1)) {
3173 "database where only one was expected for query "
3174 << ctx->conn_.text_statements_[stindex]);
3182 checkError(ctx, status, stindex,
"unable to fetch results");
3184 }
else if (status == MYSQL_DATA_TRUNCATED) {
3187 <<
" returned truncated data: columns affected are "
3188 << exchange->getErrorColumns());
3196 const uint8_t* identifier_begin,
3197 const size_t identifier_len,
3199 boost::shared_ptr<MySqlHostExchange> exchange)
const {
3202 MYSQL_BIND inbind[3];
3203 memset(inbind, 0,
sizeof(inbind));
3205 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3206 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3207 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3211 std::vector<char> identifier_vec(identifier_begin,
3212 identifier_begin + identifier_len);
3213 unsigned long length = identifier_vec.size();
3214 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3215 inbind[2].buffer = &identifier_vec[0];
3216 inbind[2].buffer_length = length;
3217 inbind[2].length = &length;
3220 char identifier_type_copy =
static_cast<char>(identifier_type);
3221 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3222 inbind[1].buffer = &identifier_type_copy;
3230 if (!collection.empty()) {
3231 result = *collection.begin();
3239 if (ctx->is_readonly_) {
3241 " operate in read only mode");
3254 return (impl_->parameters_);
3264 impl_->checkReadOnly(ctx);
3276 bool unique_ip = impl_->ip_reservations_unique_ && !host->getIPv4Reservation().isV4Zero()
3277 && host->getIPv4SubnetID() != SUBNET_ID_UNUSED;
3280 std::vector<MYSQL_BIND> bind = ctx->host_ipv4_exchange_->createBindForSend(host, unique_ip);
3287 uint64_t host_id = mysql_insert_id(ctx->conn_.mysql_);
3293 cfg_option4, host_id);
3300 cfg_option6, host_id);
3305 if (std::distance(v6resv.first, v6resv.second) > 0) {
3306 BOOST_FOREACH(
auto const& resv, v6resv) {
3307 impl_->addResv(ctx, resv.second, host_id);
3312 transaction.commit();
3323 impl_->checkReadOnly(ctx);
3326 MYSQL_BIND inbind[2];
3328 uint32_t subnet = subnet_id;
3329 memset(inbind, 0,
sizeof(inbind));
3330 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3331 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3337 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3338 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3345 std::vector<uint8_t>addr6 = addr.
toBytes();
3346 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3348 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3351 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3352 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3353 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3354 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3355 inbind[1].length = &addr6_length;
3363 const uint8_t* identifier_begin,
3364 const size_t identifier_len) {
3370 impl_->checkReadOnly(ctx);
3373 MYSQL_BIND inbind[3];
3376 memset(inbind, 0,
sizeof(inbind));
3377 uint32_t subnet =
static_cast<uint32_t
>(subnet_id);
3378 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3379 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3383 char identifier_type_copy =
static_cast<char>(identifier_type);
3384 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3385 inbind[1].buffer = &identifier_type_copy;
3389 std::vector<char> identifier_vec(identifier_begin,
3390 identifier_begin + identifier_len);
3391 unsigned long length = identifier_vec.size();
3392 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3393 inbind[2].buffer = &identifier_vec[0];
3394 inbind[2].buffer_length = length;
3395 inbind[2].length = &length;
3404 const uint8_t* identifier_begin,
3405 const size_t identifier_len) {
3411 impl_->checkReadOnly(ctx);
3414 MYSQL_BIND inbind[3];
3417 memset(inbind, 0,
sizeof(inbind));
3418 uint32_t subnet =
static_cast<uint32_t
>(subnet_id);
3419 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3420 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3424 char identifier_type_copy =
static_cast<char>(identifier_type);
3425 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3426 inbind[1].buffer = &identifier_type_copy;
3430 std::vector<char> identifier_vec(identifier_begin,
3431 identifier_begin + identifier_len);
3432 unsigned long length = identifier_vec.size();
3433 inbind[2].buffer_type = MYSQL_TYPE_BLOB;
3434 inbind[2].buffer = &identifier_vec[0];
3435 inbind[2].buffer_length = length;
3436 inbind[2].length = &length;
3444 const uint8_t* identifier_begin,
3445 const size_t identifier_len)
const {
3451 MYSQL_BIND inbind[2];
3452 memset(inbind, 0,
sizeof(inbind));
3455 char identifier_type_copy =
static_cast<char>(identifier_type);
3456 inbind[1].buffer = &identifier_type_copy;
3457 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3461 std::vector<char> identifier_vec(identifier_begin,
3462 identifier_begin + identifier_len);
3463 unsigned long int length = identifier_vec.size();
3464 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
3465 inbind[0].buffer = &identifier_vec[0];
3466 inbind[0].buffer_length = length;
3467 inbind[0].length = &length;
3471 ctx->host_ipv46_exchange_, result,
false);
3483 MYSQL_BIND inbind[1];
3484 memset(inbind, 0,
sizeof(inbind));
3485 uint32_t subnet = subnet_id;
3486 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3487 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3492 ctx->host_ipv4_exchange_, result,
false);
3504 MYSQL_BIND inbind[1];
3505 memset(inbind, 0,
sizeof(inbind));
3506 uint32_t subnet = subnet_id;
3507 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3508 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3513 ctx->host_ipv6_exchange_, result,
false);
3525 MYSQL_BIND inbind[1];
3526 memset(inbind, 0,
sizeof(inbind));
3531 unsigned long length = hostname.length();
3532 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3533 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3534 inbind[0].buffer_length = length;
3535 inbind[0].length = &length;
3539 ctx->host_ipv46_exchange_, result,
false);
3552 MYSQL_BIND inbind[2];
3553 memset(inbind, 0,
sizeof(inbind));
3558 unsigned long length = hostname.length();
3559 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3560 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3561 inbind[0].buffer_length = length;
3562 inbind[0].length = &length;
3565 uint32_t subnet = subnet_id;
3566 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3567 inbind[1].buffer =
reinterpret_cast<char*
>(&subnet);
3572 ctx->host_ipv4_exchange_, result,
false);
3585 MYSQL_BIND inbind[2];
3586 memset(inbind, 0,
sizeof(inbind));
3591 unsigned long length = hostname.length();
3592 inbind[0].buffer_type = MYSQL_TYPE_STRING;
3593 inbind[0].buffer =
reinterpret_cast<char*
>(hostname_);
3594 inbind[0].buffer_length = length;
3595 inbind[0].length = &length;
3598 uint32_t subnet = subnet_id;
3599 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3600 inbind[1].buffer =
reinterpret_cast<char*
>(&subnet);
3605 ctx->host_ipv6_exchange_, result,
false);
3613 uint64_t lower_host_id,
3620 MYSQL_BIND inbind[3];
3621 memset(inbind, 0,
sizeof(inbind));
3624 uint32_t subnet = subnet_id;
3625 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3626 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3630 uint32_t host_id = lower_host_id;
3631 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3632 inbind[1].buffer =
reinterpret_cast<char*
>(&host_id);
3636 uint32_t page_size_data = page_size.page_size_;
3637 inbind[2].buffer_type = MYSQL_TYPE_LONG;
3638 inbind[2].buffer =
reinterpret_cast<char*
>(&page_size_data);
3643 ctx->host_ipv4_exchange_, result,
false);
3651 uint64_t lower_host_id,
3658 MYSQL_BIND inbind[3];
3659 memset(inbind, 0,
sizeof(inbind));
3662 uint32_t subnet = subnet_id;
3663 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3664 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3668 uint32_t host_id = lower_host_id;
3669 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3670 inbind[1].buffer =
reinterpret_cast<char*
>(&host_id);
3674 uint32_t page_size_data = page_size.page_size_;
3675 inbind[2].buffer_type = MYSQL_TYPE_LONG;
3676 inbind[2].buffer =
reinterpret_cast<char*
>(&page_size_data);
3681 ctx->host_ipv6_exchange_, result,
false);
3688 uint64_t lower_host_id,
3695 MYSQL_BIND inbind[2];
3696 memset(inbind, 0,
sizeof(inbind));
3699 uint32_t host_id = lower_host_id;
3700 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3701 inbind[0].buffer =
reinterpret_cast<char*
>(&host_id);
3705 uint32_t page_size_data = page_size.page_size_;
3706 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3707 inbind[1].buffer =
reinterpret_cast<char*
>(&page_size_data);
3712 ctx->host_ipv4_exchange_, result,
false);
3719 uint64_t lower_host_id,
3726 MYSQL_BIND inbind[2];
3727 memset(inbind, 0,
sizeof(inbind));
3730 uint32_t host_id = lower_host_id;
3731 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3732 inbind[0].buffer =
reinterpret_cast<char*
>(&host_id);
3736 uint32_t page_size_data = page_size.page_size_;
3737 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3738 inbind[1].buffer =
reinterpret_cast<char*
>(&page_size_data);
3743 ctx->host_ipv6_exchange_, result,
false);
3755 MYSQL_BIND inbind[1];
3756 memset(inbind, 0,
sizeof(inbind));
3758 uint32_t addr4 = address.toUint32();
3759 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3760 inbind[0].buffer =
reinterpret_cast<char*
>(&addr4);
3765 ctx->host_ipv4_exchange_, result,
false);
3773 const uint8_t* identifier_begin,
3774 const size_t identifier_len)
const {
3779 return (impl_->getHost(ctx, subnet_id, identifier_type, identifier_begin, identifier_len,
3781 ctx->host_ipv4_exchange_));
3787 if (!address.isV4()) {
3789 "wrong address type, address supplied is an IPv6 address");
3797 MYSQL_BIND inbind[2];
3798 uint32_t subnet = subnet_id;
3799 memset(inbind, 0,
sizeof(inbind));
3800 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3801 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3804 uint32_t addr4 = address.toUint32();
3805 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3806 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3811 ctx->host_ipv4_exchange_, collection,
true);
3815 if (!collection.empty()) {
3816 result = *collection.begin();
3825 if (!address.isV4()) {
3827 "wrong address type, address supplied is an IPv6 address");
3835 MYSQL_BIND inbind[2];
3836 uint32_t subnet = subnet_id;
3837 memset(inbind, 0,
sizeof(inbind));
3838 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3839 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet);
3842 uint32_t addr4 = address.toUint32();
3843 inbind[1].buffer_type = MYSQL_TYPE_LONG;
3844 inbind[1].buffer =
reinterpret_cast<char*
>(&addr4);
3849 ctx->host_ipv4_exchange_, collection,
false);
3850 return (collection);
3856 const uint8_t* identifier_begin,
3857 const size_t identifier_len)
const {
3862 return (impl_->getHost(ctx, subnet_id, identifier_type, identifier_begin, identifier_len,
3864 ctx->host_ipv6_exchange_));
3869 const uint8_t prefix_len)
const {
3870 if (!prefix.isV6()) {
3872 "wrong address type, address supplied is an IPv4 address");
3880 MYSQL_BIND inbind[2];
3881 memset(inbind, 0,
sizeof(inbind));
3883 std::vector<uint8_t>addr6 = prefix.toBytes();
3884 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3886 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3889 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3890 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
3891 inbind[0].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3892 inbind[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3893 inbind[0].length = &addr6_length;
3895 uint8_t tmp = prefix_len;
3896 inbind[1].buffer_type = MYSQL_TYPE_TINY;
3897 inbind[1].buffer =
reinterpret_cast<char*
>(&tmp);
3902 ctx->host_ipv6_exchange_, collection,
true);
3906 if (!collection.empty()) {
3907 result = *collection.begin();
3916 if (!address.isV6()) {
3918 "wrong address type, address supplied is an IPv4 address");
3926 MYSQL_BIND inbind[2];
3927 memset(inbind, 0,
sizeof(inbind));
3929 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3930 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3931 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3934 std::vector<uint8_t>addr6 = address.toBytes();
3935 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3937 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3940 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3941 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3942 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3943 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3944 inbind[1].length = &addr6_length;
3948 ctx->host_ipv6_exchange_, collection,
true);
3952 if (!collection.empty()) {
3953 result = *collection.begin();
3962 if (!address.isV6()) {
3964 "wrong address type, address supplied is an IPv4 address");
3972 MYSQL_BIND inbind[2];
3973 memset(inbind, 0,
sizeof(inbind));
3975 uint32_t subnet_buffer =
static_cast<uint32_t
>(subnet_id);
3976 inbind[0].buffer_type = MYSQL_TYPE_LONG;
3977 inbind[0].buffer =
reinterpret_cast<char*
>(&subnet_buffer);
3980 std::vector<uint8_t>addr6 = address.toBytes();
3981 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
3983 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
3986 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
3987 inbind[1].buffer_type = MYSQL_TYPE_BLOB;
3988 inbind[1].buffer =
reinterpret_cast<char*
>(&addr6[0]);
3989 inbind[1].buffer_length = isc::asiolink::V6ADDRESS_LEN;
3990 inbind[1].length = &addr6_length;
3994 ctx->host_ipv6_exchange_, collection,
false);
3995 return (collection);
4000 if (!address.isV6()) {
4002 "wrong address type, address supplied is an IPv4 address");
4010 MYSQL_BIND inbind[1];
4011 memset(inbind, 0,
sizeof(inbind));
4013 std::vector<uint8_t>addr6 = address.toBytes();
4014 if (addr6.size() != isc::asiolink::V6ADDRESS_LEN) {
4016 << isc::asiolink::V6ADDRESS_LEN <<
" bytes long");
4019 unsigned long addr6_length = isc::asiolink::V6ADDRESS_LEN;
4020 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
4021 inbind[0].buffer =
reinterpret_cast<char*
>(&addr6[0]);
4022 inbind[0].buffer_length = isc::asiolink::V6ADDRESS_LEN;
4023 inbind[0].length = &addr6_length;
4027 ctx->host_ipv6_exchange_, collection,
false);
4028 return (collection);
4038 impl_->checkReadOnly(ctx);
4054 transaction.commit();
4061 std::string name =
"";
4067 name = ctx->conn_.getParameter(
"name");
4076 return (std::string(
"Host data source that stores host information"
4077 "in MySQL database"));
4080std::pair<uint32_t, uint32_t>
4082 return(impl_->getVersion(timer_name));
4092 impl_->checkReadOnly(ctx);
4093 if (ctx->conn_.isTransactionStarted()) {
4094 ctx->conn_.commit();
4105 impl_->checkReadOnly(ctx);
4106 if (ctx->conn_.isTransactionStarted()) {
4107 ctx->conn_.rollback();
4113 impl_->ip_reservations_unique_ = unique;
4119 return (impl_->unusable_);
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
bool isV4() const
Convenience function to check for an IPv4 address.
std::vector< uint8_t > toBytes() const
Return address as set of bytes.
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
static ElementPtr fromJSON(const std::string &in, bool preproc=false)
These functions will parse the given string (JSON) representation of a compound element.
A standard Data module exception that is thrown if a parse error is encountered when constructing an ...
static bool invokeDbLostCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's lost connectivity callback.
static bool invokeDbFailedCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's restore failed connectivity callback.
static ParameterMap parse(const std::string &dbaccess)
Parse database access string.
static bool invokeDbRecoveredCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's restored connectivity callback.
static isc::asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Exception thrown on failure to execute a database function.
Database duplicate entry error.
Multiple lease records found where one expected.
Common MySQL Connector Pool.
static std::pair< uint32_t, uint32_t > getVersion(const ParameterMap ¶meters, const IOServiceAccessorPtr &ac=IOServiceAccessorPtr(), const DbCallback &cb=DbCallback(), const std::string &timer_name=std::string())
Get the schema version.
static void ensureSchemaVersion(const ParameterMap ¶meters, const DbCallback &cb=DbCallback(), const std::string &timer_name=std::string())
Retrieve schema version, validate it against the hardcoded version, and attempt to initialize the sch...
Fetch and Release MySQL Results.
RAII object representing MySQL transaction.
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
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.
Represents a device with IPv4 and/or IPv6 reservations.
IdentifierType
Type of the host identifier.
static const IdentifierType LAST_IDENTIFIER_TYPE
Constant pointing to the last identifier of the IdentifierType enumeration.
IPv6 reservation for a host.
Type
Type of the reservation.
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.
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.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
A wrapper interface for the ASIO library.
boost::shared_ptr< const Element > ConstElementPtr
const my_bool MLM_FALSE
MySQL false value.
boost::shared_ptr< IOServiceAccessor > IOServiceAccessorPtr
Pointer to an instance of IOServiceAccessor.
const my_bool MLM_TRUE
MySQL true value.
bool my_bool
my_bool type in MySQL 8.x.
const int MLM_MYSQL_FETCH_FAILURE
MySQL fetch failure code.
const int MLM_MYSQL_FETCH_SUCCESS
check for bool size
std::function< bool(util::ReconnectCtlPtr db_reconnect_ctl)> DbCallback
Defines a callback prototype for propagating events upward.
std::function< isc::asiolink::IOServicePtr()> IOServiceAccessor
Function which returns the IOService that can be used to recover the connection.
int MysqlExecuteStatement(MYSQL_STMT *stmt)
Execute a prepared statement.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
const size_t OPTION_FORMATTED_VALUE_MAX_LEN
Maximum length of option value specified in textual format.
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_GET_VERSION
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
const isc::log::MessageID DHCPSRV_MYSQL_NO_TLS
boost::shared_ptr< CfgDbAccess > CfgDbAccessPtr
A pointer to the CfgDbAccess.
const size_t CLIENT_CLASSES_MAX_LEN
Maximum length of classes stored in a dhcp4/6_client_classes columns.
std::pair< IPv6ResrvIterator, IPv6ResrvIterator > IPv6ResrvRange
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
const size_t TEXT_AUTH_KEY_LEN
Maximum length of authentication keys (coded in hexadecimal).
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_RECONNECT_FAILED
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
uint64_t HostID
HostID (used only when storing in MySQL or PostgreSQL backends)
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
boost::shared_ptr< MySqlHostContextPool > MySqlHostContextPoolPtr
Type of pointers to context pools.
const size_t HOSTNAME_MAX_LEN
Maximum length of the hostname stored in DNS.
boost::shared_ptr< MySqlHostContext > MySqlHostContextPtr
Type of pointers to contexts.
const size_t USER_CONTEXT_MAX_LEN
Maximum length of user context.
const size_t OPTION_VALUE_MAX_LEN
Maximum length of option value.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
const size_t SERVER_HOSTNAME_MAX_LEN
Maximum length of the server hostname.
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_READONLY
const size_t BOOT_FILE_NAME_MAX_LEN
Maximum length of the boot file name.
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_RECONNECT_ATTEMPT_SCHEDULE
boost::shared_ptr< Option > OptionPtr
const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_RECONNECT_ATTEMPT_FAILED
const isc::log::MessageID DHCPSRV_MYSQL_TLS_CIPHER
boost::shared_ptr< const CfgOption > ConstCfgOptionPtr
Const pointer.
const size_t OPTION_SPACE_MAX_LEN
Maximum length of option space name.
boost::shared_ptr< ReconnectCtl > ReconnectCtlPtr
Pointer to an instance of ReconnectCtl.
Defines the logger used by the top-level component of kea-lfc.
#define DHCP4_OPTION_SPACE
global std option spaces
#define DHCP6_OPTION_SPACE