16 #include <boost/array.hpp> 17 #include <boost/static_assert.hpp> 18 #include <mysqld_error.h> 82 const size_t HOSTNAME_MAX_LEN = 255;
88 const size_t ADDRESS6_TEXT_MAX_LEN = 39;
91 const size_t USER_CONTEXT_MAX_LEN = 8192;
93 boost::array<TaggedStatement, MySqlLeaseMgr::NUM_STATEMENTS>
95 {MySqlLeaseMgr::DELETE_LEASE4,
96 "DELETE FROM lease4 WHERE address = ?"},
97 {MySqlLeaseMgr::DELETE_LEASE4_STATE_EXPIRED,
99 "WHERE state = ? AND expire < ?"},
100 {MySqlLeaseMgr::DELETE_LEASE6,
101 "DELETE FROM lease6 WHERE address = ?"},
102 {MySqlLeaseMgr::DELETE_LEASE6_STATE_EXPIRED,
103 "DELETE FROM lease6 " 104 "WHERE state = ? AND expire < ?"},
105 {MySqlLeaseMgr::GET_LEASE4,
106 "SELECT address, hwaddr, client_id, " 107 "valid_lifetime, expire, subnet_id, " 108 "fqdn_fwd, fqdn_rev, hostname, " 109 "state, user_context " 111 {MySqlLeaseMgr::GET_LEASE4_ADDR,
112 "SELECT address, hwaddr, client_id, " 113 "valid_lifetime, expire, subnet_id, " 114 "fqdn_fwd, fqdn_rev, hostname, " 115 "state, user_context " 117 "WHERE address = ?"},
118 {MySqlLeaseMgr::GET_LEASE4_CLIENTID,
119 "SELECT address, hwaddr, client_id, " 120 "valid_lifetime, expire, subnet_id, " 121 "fqdn_fwd, fqdn_rev, hostname, " 122 "state, user_context " 124 "WHERE client_id = ?"},
125 {MySqlLeaseMgr::GET_LEASE4_CLIENTID_SUBID,
126 "SELECT address, hwaddr, client_id, " 127 "valid_lifetime, expire, subnet_id, " 128 "fqdn_fwd, fqdn_rev, hostname, " 129 "state, user_context " 131 "WHERE client_id = ? AND subnet_id = ?"},
132 {MySqlLeaseMgr::GET_LEASE4_HWADDR,
133 "SELECT address, hwaddr, client_id, " 134 "valid_lifetime, expire, subnet_id, " 135 "fqdn_fwd, fqdn_rev, hostname, " 136 "state, user_context " 139 {MySqlLeaseMgr::GET_LEASE4_HWADDR_SUBID,
140 "SELECT address, hwaddr, client_id, " 141 "valid_lifetime, expire, subnet_id, " 142 "fqdn_fwd, fqdn_rev, hostname, " 143 "state, user_context " 145 "WHERE hwaddr = ? AND subnet_id = ?"},
146 {MySqlLeaseMgr::GET_LEASE4_PAGE,
147 "SELECT address, hwaddr, client_id, " 148 "valid_lifetime, expire, subnet_id, " 149 "fqdn_fwd, fqdn_rev, hostname, " 150 "state, user_context " 155 {MySqlLeaseMgr::GET_LEASE4_SUBID,
156 "SELECT address, hwaddr, client_id, " 157 "valid_lifetime, expire, subnet_id, " 158 "fqdn_fwd, fqdn_rev, hostname, " 159 "state, user_context " 161 "WHERE subnet_id = ?"},
162 {MySqlLeaseMgr::GET_LEASE4_EXPIRE,
163 "SELECT address, hwaddr, client_id, " 164 "valid_lifetime, expire, subnet_id, " 165 "fqdn_fwd, fqdn_rev, hostname, " 166 "state, user_context " 168 "WHERE state != ? AND expire < ? " 169 "ORDER BY expire ASC " 171 {MySqlLeaseMgr::GET_LEASE6,
172 "SELECT address, duid, valid_lifetime, " 173 "expire, subnet_id, pref_lifetime, " 174 "lease_type, iaid, prefix_len, " 175 "fqdn_fwd, fqdn_rev, hostname, " 176 "hwaddr, hwtype, hwaddr_source, " 177 "state, user_context " 179 {MySqlLeaseMgr::GET_LEASE6_ADDR,
180 "SELECT address, duid, valid_lifetime, " 181 "expire, subnet_id, pref_lifetime, " 182 "lease_type, iaid, prefix_len, " 183 "fqdn_fwd, fqdn_rev, hostname, " 184 "hwaddr, hwtype, hwaddr_source, " 185 "state, user_context " 187 "WHERE address = ? AND lease_type = ?"},
188 {MySqlLeaseMgr::GET_LEASE6_DUID_IAID,
189 "SELECT address, duid, valid_lifetime, " 190 "expire, subnet_id, pref_lifetime, " 191 "lease_type, iaid, prefix_len, " 192 "fqdn_fwd, fqdn_rev, hostname, " 193 "hwaddr, hwtype, hwaddr_source, " 194 "state, user_context " 196 "WHERE duid = ? AND iaid = ? AND lease_type = ?"},
197 {MySqlLeaseMgr::GET_LEASE6_DUID_IAID_SUBID,
198 "SELECT address, duid, valid_lifetime, " 199 "expire, subnet_id, pref_lifetime, " 200 "lease_type, iaid, prefix_len, " 201 "fqdn_fwd, fqdn_rev, hostname, " 202 "hwaddr, hwtype, hwaddr_source, " 203 "state, user_context " 205 "WHERE duid = ? AND iaid = ? AND subnet_id = ? " 206 "AND lease_type = ?"},
207 {MySqlLeaseMgr::GET_LEASE6_PAGE,
208 "SELECT address, duid, valid_lifetime, " 209 "expire, subnet_id, pref_lifetime, " 210 "lease_type, iaid, prefix_len, " 211 "fqdn_fwd, fqdn_rev, hostname, " 212 "hwaddr, hwtype, hwaddr_source, " 213 "state, user_context " 218 {MySqlLeaseMgr::GET_LEASE6_SUBID,
219 "SELECT address, duid, valid_lifetime, " 220 "expire, subnet_id, pref_lifetime, " 221 "lease_type, iaid, prefix_len, " 222 "fqdn_fwd, fqdn_rev, hostname, " 223 "hwaddr, hwtype, hwaddr_source, " 224 "state, user_context " 226 "WHERE subnet_id = ?"},
227 {MySqlLeaseMgr::GET_LEASE6_DUID,
228 "SELECT address, duid, valid_lifetime, " 229 "expire, subnet_id, pref_lifetime, " 230 "lease_type, iaid, prefix_len, " 231 "fqdn_fwd, fqdn_rev, hostname, " 232 "hwaddr, hwtype, hwaddr_source, " 233 "state, user_context " 236 {MySqlLeaseMgr::GET_LEASE6_EXPIRE,
237 "SELECT address, duid, valid_lifetime, " 238 "expire, subnet_id, pref_lifetime, " 239 "lease_type, iaid, prefix_len, " 240 "fqdn_fwd, fqdn_rev, hostname, " 241 "hwaddr, hwtype, hwaddr_source, " 242 "state, user_context " 244 "WHERE state != ? AND expire < ? " 245 "ORDER BY expire ASC " 247 {MySqlLeaseMgr::INSERT_LEASE4,
248 "INSERT INTO lease4(address, hwaddr, client_id, " 249 "valid_lifetime, expire, subnet_id, " 250 "fqdn_fwd, fqdn_rev, hostname, " 251 "state, user_context) " 252 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
253 {MySqlLeaseMgr::INSERT_LEASE6,
254 "INSERT INTO lease6(address, duid, valid_lifetime, " 255 "expire, subnet_id, pref_lifetime, " 256 "lease_type, iaid, prefix_len, " 257 "fqdn_fwd, fqdn_rev, hostname, " 258 "hwaddr, hwtype, hwaddr_source, " 259 "state, user_context) " 260 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
261 {MySqlLeaseMgr::UPDATE_LEASE4,
262 "UPDATE lease4 SET address = ?, hwaddr = ?, " 263 "client_id = ?, valid_lifetime = ?, expire = ?, " 264 "subnet_id = ?, fqdn_fwd = ?, fqdn_rev = ?, " 266 "state = ?, user_context = ? " 267 "WHERE address = ?"},
268 {MySqlLeaseMgr::UPDATE_LEASE6,
269 "UPDATE lease6 SET address = ?, duid = ?, " 270 "valid_lifetime = ?, expire = ?, subnet_id = ?, " 271 "pref_lifetime = ?, lease_type = ?, iaid = ?, " 272 "prefix_len = ?, fqdn_fwd = ?, fqdn_rev = ?, " 273 "hostname = ?, hwaddr = ?, hwtype = ?, hwaddr_source = ?, " 274 "state = ?, user_context = ? " 275 "WHERE address = ?"},
276 {MySqlLeaseMgr::ALL_LEASE4_STATS,
277 "SELECT subnet_id, state, leases as state_count" 278 " FROM lease4_stat ORDER BY subnet_id, state"},
280 {MySqlLeaseMgr::SUBNET_LEASE4_STATS,
281 "SELECT subnet_id, state, leases as state_count" 283 " WHERE subnet_id = ? " 286 {MySqlLeaseMgr::SUBNET_RANGE_LEASE4_STATS,
287 "SELECT subnet_id, state, leases as state_count" 289 " WHERE subnet_id >= ? and subnet_id <= ? " 290 " ORDER BY subnet_id, state"},
292 {MySqlLeaseMgr::ALL_LEASE6_STATS,
293 "SELECT subnet_id, lease_type, state, leases as state_count" 294 " FROM lease6_stat ORDER BY subnet_id, lease_type, state" },
296 {MySqlLeaseMgr::SUBNET_LEASE6_STATS,
297 "SELECT subnet_id, lease_type, state, leases as state_count" 299 " WHERE subnet_id = ? " 300 " ORDER BY lease_type, state" },
302 {MySqlLeaseMgr::SUBNET_RANGE_LEASE6_STATS,
303 "SELECT subnet_id, lease_type, state, leases as state_count" 305 " WHERE subnet_id >= ? and subnet_id <= ? " 306 " ORDER BY subnet_id, lease_type, state" }
337 for (
size_t i = 0; i < count; ++i) {
339 bind[i].error = reinterpret_cast<char*>(&error[i]);
358 std::string result =
"";
361 for (
size_t i = 0; i < count; ++i) {
363 if (!result.empty()) {
370 if (result.empty()) {
393 static const size_t LEASE_COLUMNS = 11;
401 client_id_length_(0), client_id_null_(
MLM_FALSE),
402 subnet_id_(0), valid_lifetime_(0),
403 fqdn_fwd_(false), fqdn_rev_(false), hostname_length_(0),
404 state_(0), user_context_length_(0),
406 memset(hwaddr_buffer_, 0,
sizeof(hwaddr_buffer_));
407 memset(client_id_buffer_, 0,
sizeof(client_id_buffer_));
408 memset(hostname_buffer_, 0,
sizeof(hostname_buffer_));
409 memset(user_context_, 0,
sizeof(user_context_));
410 std::fill(&error_[0], &error_[LEASE_COLUMNS],
MLM_FALSE);
413 columns_[0] =
"address";
414 columns_[1] =
"hwaddr";
415 columns_[2] =
"client_id";
416 columns_[3] =
"valid_lifetime";
417 columns_[4] =
"expire";
418 columns_[5] =
"subnet_id";
419 columns_[6] =
"fqdn_fwd";
420 columns_[7] =
"fqdn_rev";
421 columns_[8] =
"hostname";
422 columns_[9] =
"state";
423 columns_[10] =
"user_context";
424 BOOST_STATIC_ASSERT(10 < LEASE_COLUMNS);
446 memset(bind_, 0,
sizeof(bind_));
455 addr4_ = lease_->addr_.toUint32();
456 bind_[0].buffer_type = MYSQL_TYPE_LONG;
457 bind_[0].buffer = reinterpret_cast<char*>(&addr4_);
465 hwaddr_ = hwaddr->hwaddr_;
466 hwaddr_length_ = hwaddr->hwaddr_.size();
473 if (hwaddr_.empty()) {
477 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
478 bind_[1].buffer = reinterpret_cast<char*>(&(hwaddr_[0]));
479 bind_[1].buffer_length = hwaddr_length_;
480 bind_[1].length = &hwaddr_length_;
482 bind_[1].buffer_type = MYSQL_TYPE_NULL;
489 bind_[1].buffer = NULL;
490 bind_[1].is_null = &hwaddr_null_;
494 if (lease_->client_id_) {
495 client_id_ = lease_->client_id_->getClientId();
496 client_id_length_ = client_id_.size();
503 if (client_id_.empty()) {
504 client_id_.resize(1);
507 bind_[2].buffer_type = MYSQL_TYPE_BLOB;
508 bind_[2].buffer = reinterpret_cast<char*>(&client_id_[0]);
509 bind_[2].buffer_length = client_id_length_;
510 bind_[2].length = &client_id_length_;
514 bind_[2].buffer_type = MYSQL_TYPE_NULL;
521 bind_[2].buffer = NULL;
522 bind_[2].is_null = &client_id_null_;
526 bind_[3].buffer_type = MYSQL_TYPE_LONG;
527 bind_[3].buffer = reinterpret_cast<char*>(&lease_->valid_lft_);
538 MySqlConnection::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_,
540 bind_[4].buffer_type = MYSQL_TYPE_TIMESTAMP;
541 bind_[4].buffer = reinterpret_cast<char*>(&expire_);
542 bind_[4].buffer_length =
sizeof(expire_);
548 bind_[5].buffer_type = MYSQL_TYPE_LONG;
549 bind_[5].buffer = reinterpret_cast<char*>(&lease_->subnet_id_);
555 bind_[6].buffer_type = MYSQL_TYPE_TINY;
556 bind_[6].buffer = reinterpret_cast<char*>(&lease_->fqdn_fwd_);
562 bind_[7].buffer_type = MYSQL_TYPE_TINY;
563 bind_[7].buffer = reinterpret_cast<char*>(&lease_->fqdn_rev_);
572 bind_[8].buffer_type = MYSQL_TYPE_STRING;
573 bind_[8].buffer = const_cast<char*>(lease_->hostname_.c_str());
574 bind_[8].buffer_length = lease_->hostname_.length();
579 bind_[9].buffer_type = MYSQL_TYPE_LONG;
580 bind_[9].buffer = reinterpret_cast<char*>(&lease_->state_);
588 bind_[10].buffer_type = MYSQL_TYPE_STRING;
589 string ctx_txt = ctx->str();
590 strncpy(user_context_, ctx_txt.c_str(), USER_CONTEXT_MAX_LEN - 1);
591 bind_[10].buffer = user_context_;
592 bind_[10].buffer_length = ctx_txt.length();
596 bind_[10].buffer_type = MYSQL_TYPE_NULL;
600 setErrorIndicators(bind_, error_, LEASE_COLUMNS);
603 BOOST_STATIC_ASSERT(10 < LEASE_COLUMNS);
605 }
catch (
const std::exception& ex) {
607 "Could not create bind array from Lease4: " 608 << lease_->addr_.toText() <<
", reason: " << ex.
what());
613 return (std::vector<MYSQL_BIND>(&bind_[0], &bind_[LEASE_COLUMNS]));
629 memset(bind_, 0,
sizeof(bind_));
632 bind_[0].buffer_type = MYSQL_TYPE_LONG;
633 bind_[0].buffer = reinterpret_cast<char*>(&addr4_);
639 hwaddr_length_ =
sizeof(hwaddr_buffer_);
640 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
641 bind_[1].buffer = reinterpret_cast<char*>(hwaddr_buffer_);
642 bind_[1].buffer_length = hwaddr_length_;
643 bind_[1].length = &hwaddr_length_;
648 client_id_length_ =
sizeof(client_id_buffer_);
649 bind_[2].buffer_type = MYSQL_TYPE_BLOB;
650 bind_[2].buffer = reinterpret_cast<char*>(client_id_buffer_);
651 bind_[2].buffer_length = client_id_length_;
652 bind_[2].length = &client_id_length_;
653 bind_[2].is_null = &client_id_null_;
658 bind_[3].buffer_type = MYSQL_TYPE_LONG;
659 bind_[3].buffer = reinterpret_cast<char*>(&valid_lifetime_);
665 bind_[4].buffer_type = MYSQL_TYPE_TIMESTAMP;
666 bind_[4].buffer = reinterpret_cast<char*>(&expire_);
667 bind_[4].buffer_length =
sizeof(expire_);
672 bind_[5].buffer_type = MYSQL_TYPE_LONG;
673 bind_[5].buffer = reinterpret_cast<char*>(&subnet_id_);
679 bind_[6].buffer_type = MYSQL_TYPE_TINY;
680 bind_[6].buffer = reinterpret_cast<char*>(&fqdn_fwd_);
686 bind_[7].buffer_type = MYSQL_TYPE_TINY;
687 bind_[7].buffer = reinterpret_cast<char*>(&fqdn_rev_);
696 hostname_length_ =
sizeof(hostname_buffer_);
697 bind_[8].buffer_type = MYSQL_TYPE_STRING;
698 bind_[8].buffer = reinterpret_cast<char*>(hostname_buffer_);
699 bind_[8].buffer_length = hostname_length_;
700 bind_[8].length = &hostname_length_;
705 bind_[9].buffer_type = MYSQL_TYPE_LONG;
706 bind_[9].buffer = reinterpret_cast<char*>(&state_);
713 user_context_length_ =
sizeof(user_context_);
714 bind_[10].buffer_type = MYSQL_TYPE_STRING;
715 bind_[10].buffer = reinterpret_cast<char*>(user_context_);
716 bind_[10].buffer_length = user_context_length_;
717 bind_[10].length= &user_context_length_;
718 bind_[10].is_null = &user_context_null_;
721 setErrorIndicators(bind_, error_, LEASE_COLUMNS);
724 BOOST_STATIC_ASSERT(10 < LEASE_COLUMNS);
728 return(std::vector<MYSQL_BIND>(&bind_[0], &bind_[LEASE_COLUMNS]));
743 MySqlConnection::convertFromDatabaseTime(expire_, valid_lifetime_, cltt);
747 client_id_length_ = 0;
752 std::string hostname(hostname_buffer_,
753 hostname_buffer_ + hostname_length_);
762 std::string user_context;
764 user_context_[user_context_length_] =
'\0';
765 user_context.assign(user_context_);
770 if (!user_context.empty()) {
771 ctx = Element::fromJSON(user_context);
772 if (!ctx || (ctx->getType() != Element::map)) {
774 <<
"' is not a JSON map");
780 client_id_buffer_, client_id_length_,
781 valid_lifetime_, 0, 0, cltt, subnet_id_,
782 fqdn_fwd_, fqdn_rev_, hostname));
785 lease->state_ = state_;
788 lease->setContext(ctx);
805 return (getColumnsInError(error_, columns_, LEASE_COLUMNS));
814 MYSQL_BIND bind_[LEASE_COLUMNS];
815 std::string columns_[LEASE_COLUMNS];
816 my_bool error_[LEASE_COLUMNS];
817 std::vector<uint8_t> hwaddr_;
818 uint8_t hwaddr_buffer_[HWAddr::MAX_HWADDR_LEN];
819 unsigned long hwaddr_length_;
820 my_bool hwaddr_null_;
821 std::vector<uint8_t> client_id_;
822 uint8_t client_id_buffer_[ClientId::MAX_CLIENT_ID_LEN];
823 unsigned long client_id_length_;
824 my_bool client_id_null_;
828 uint32_t valid_lifetime_;
831 char hostname_buffer_[HOSTNAME_MAX_LEN];
832 unsigned long hostname_length_;
834 char user_context_[USER_CONTEXT_MAX_LEN];
835 unsigned long user_context_length_;
836 my_bool user_context_null_;
854 static const size_t LEASE_COLUMNS = 17;
862 iaid_(0), lease_type_(0), prefixlen_(0),
863 pref_lifetime_(0), subnet_id_(0), valid_lifetime_(0),
864 fqdn_fwd_(false), fqdn_rev_(false),
865 hostname_length_(0), hwaddr_length_(0),
866 hwaddr_null_(
MLM_FALSE), hwtype_(0), hwaddr_source_(0),
867 state_(0), user_context_length_(0),
869 memset(addr6_buffer_, 0,
sizeof(addr6_buffer_));
870 memset(duid_buffer_, 0,
sizeof(duid_buffer_));
871 memset(hostname_buffer_, 0,
sizeof(hostname_buffer_));
872 memset(hwaddr_buffer_, 0,
sizeof(hwaddr_buffer_));
873 memset(user_context_, 0,
sizeof(user_context_));
874 std::fill(&error_[0], &error_[LEASE_COLUMNS],
MLM_FALSE);
877 columns_[0] =
"address";
878 columns_[1] =
"duid";
879 columns_[2] =
"valid_lifetime";
880 columns_[3] =
"expire";
881 columns_[4] =
"subnet_id";
882 columns_[5] =
"pref_lifetime";
883 columns_[6] =
"lease_type";
884 columns_[7] =
"iaid";
885 columns_[8] =
"prefix_len";
886 columns_[9] =
"fqdn_fwd";
887 columns_[10] =
"fqdn_rev";
888 columns_[11] =
"hostname";
889 columns_[12] =
"hwaddr";
890 columns_[13] =
"hwtype";
891 columns_[14] =
"hwaddr_source";
892 columns_[15] =
"state";
893 columns_[16] =
"user_context";
894 BOOST_STATIC_ASSERT(16 < LEASE_COLUMNS);
915 memset(bind_, 0,
sizeof(bind_));
919 addr6_ = lease_->addr_.toText();
920 addr6_length_ = addr6_.size();
936 bind_[0].buffer_type = MYSQL_TYPE_STRING;
937 bind_[0].buffer = const_cast<char*>(addr6_.c_str());
938 bind_[0].buffer_length = addr6_length_;
939 bind_[0].length = &addr6_length_;
944 if (!lease_->duid_) {
946 <<
" is missing mandatory client-id.");
948 duid_ = lease_->duid_->getDuid();
949 duid_length_ = duid_.size();
951 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
952 bind_[1].buffer = reinterpret_cast<char*>(&(duid_[0]));
953 bind_[1].buffer_length = duid_length_;
954 bind_[1].length = &duid_length_;
959 bind_[2].buffer_type = MYSQL_TYPE_LONG;
960 bind_[2].buffer = reinterpret_cast<char*>(&lease_->valid_lft_);
971 MySqlConnection::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_,
973 bind_[3].buffer_type = MYSQL_TYPE_TIMESTAMP;
974 bind_[3].buffer = reinterpret_cast<char*>(&expire_);
975 bind_[3].buffer_length =
sizeof(expire_);
981 bind_[4].buffer_type = MYSQL_TYPE_LONG;
982 bind_[4].buffer = reinterpret_cast<char*>(&lease_->subnet_id_);
989 bind_[5].buffer_type = MYSQL_TYPE_LONG;
990 bind_[5].buffer = reinterpret_cast<char*>(&lease_->preferred_lft_);
997 lease_type_ = lease_->type_;
998 bind_[6].buffer_type = MYSQL_TYPE_TINY;
999 bind_[6].buffer = reinterpret_cast<char*>(&lease_type_);
1006 bind_[7].buffer_type = MYSQL_TYPE_LONG;
1007 bind_[7].buffer = reinterpret_cast<char*>(&lease_->iaid_);
1014 bind_[8].buffer_type = MYSQL_TYPE_TINY;
1015 bind_[8].buffer = reinterpret_cast<char*>(&lease_->prefixlen_);
1021 bind_[9].buffer_type = MYSQL_TYPE_TINY;
1022 bind_[9].buffer = reinterpret_cast<char*>(&lease_->fqdn_fwd_);
1028 bind_[10].buffer_type = MYSQL_TYPE_TINY;
1029 bind_[10].buffer = reinterpret_cast<char*>(&lease_->fqdn_rev_);
1035 bind_[11].buffer_type = MYSQL_TYPE_STRING;
1036 bind_[11].buffer = const_cast<char*>(lease_->hostname_.c_str());
1037 bind_[11].buffer_length = lease_->hostname_.length();
1044 hwaddr_ = hwaddr->hwaddr_;
1045 hwaddr_length_ = hwaddr->hwaddr_.size();
1052 if (hwaddr_.empty()) {
1056 bind_[12].buffer_type = MYSQL_TYPE_BLOB;
1057 bind_[12].buffer = reinterpret_cast<char*>(&(hwaddr_[0]));
1058 bind_[12].buffer_length = hwaddr_length_;
1059 bind_[12].length = &hwaddr_length_;
1061 bind_[12].buffer_type = MYSQL_TYPE_NULL;
1068 bind_[12].buffer = NULL;
1069 bind_[12].is_null = &hwaddr_null_;
1074 hwtype_ = lease->hwaddr_->htype_;
1075 bind_[13].buffer_type = MYSQL_TYPE_SHORT;
1076 bind_[13].buffer = reinterpret_cast<char*>(&hwtype_);
1080 bind_[13].buffer_type = MYSQL_TYPE_NULL;
1087 bind_[13].buffer = NULL;
1088 bind_[13].is_null = &hwaddr_null_;
1093 hwaddr_source_ = lease->hwaddr_->source_;
1094 bind_[14].buffer_type = MYSQL_TYPE_LONG;
1095 bind_[14].buffer = reinterpret_cast<char*>(&hwaddr_source_);
1099 bind_[14].buffer_type = MYSQL_TYPE_NULL;
1106 bind_[14].buffer = NULL;
1107 bind_[14].is_null = &hwaddr_null_;
1111 bind_[15].buffer_type = MYSQL_TYPE_LONG;
1112 bind_[15].buffer = reinterpret_cast<char*>(&lease_->state_);
1120 bind_[16].buffer_type = MYSQL_TYPE_STRING;
1121 string ctx_txt = ctx->str();
1122 strncpy(user_context_, ctx_txt.c_str(), USER_CONTEXT_MAX_LEN - 1);
1123 bind_[16].buffer = user_context_;
1124 bind_[16].buffer_length = ctx_txt.length();
1128 bind_[16].buffer_type = MYSQL_TYPE_NULL;
1132 setErrorIndicators(bind_, error_, LEASE_COLUMNS);
1135 BOOST_STATIC_ASSERT(16 < LEASE_COLUMNS);
1137 }
catch (
const std::exception& ex) {
1139 "Could not create bind array from Lease6: " 1140 << lease_->addr_.toText() <<
", reason: " << ex.
what());
1145 return (std::vector<MYSQL_BIND>(&bind_[0], &bind_[LEASE_COLUMNS]));
1163 memset(bind_, 0,
sizeof(bind_));
1169 addr6_length_ =
sizeof(addr6_buffer_) - 1;
1170 bind_[0].buffer_type = MYSQL_TYPE_STRING;
1171 bind_[0].buffer = addr6_buffer_;
1172 bind_[0].buffer_length = addr6_length_;
1173 bind_[0].length = &addr6_length_;
1178 duid_length_ =
sizeof(duid_buffer_);
1179 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
1180 bind_[1].buffer = reinterpret_cast<char*>(duid_buffer_);
1181 bind_[1].buffer_length = duid_length_;
1182 bind_[1].length = &duid_length_;
1187 bind_[2].buffer_type = MYSQL_TYPE_LONG;
1188 bind_[2].buffer = reinterpret_cast<char*>(&valid_lifetime_);
1194 bind_[3].buffer_type = MYSQL_TYPE_TIMESTAMP;
1195 bind_[3].buffer = reinterpret_cast<char*>(&expire_);
1196 bind_[3].buffer_length =
sizeof(expire_);
1201 bind_[4].buffer_type = MYSQL_TYPE_LONG;
1202 bind_[4].buffer = reinterpret_cast<char*>(&subnet_id_);
1208 bind_[5].buffer_type = MYSQL_TYPE_LONG;
1209 bind_[5].buffer = reinterpret_cast<char*>(&pref_lifetime_);
1215 bind_[6].buffer_type = MYSQL_TYPE_TINY;
1216 bind_[6].buffer = reinterpret_cast<char*>(&lease_type_);
1222 bind_[7].buffer_type = MYSQL_TYPE_LONG;
1223 bind_[7].buffer = reinterpret_cast<char*>(&iaid_);
1229 bind_[8].buffer_type = MYSQL_TYPE_TINY;
1230 bind_[8].buffer = reinterpret_cast<char*>(&prefixlen_);
1236 bind_[9].buffer_type = MYSQL_TYPE_TINY;
1237 bind_[9].buffer = reinterpret_cast<char*>(&fqdn_fwd_);
1243 bind_[10].buffer_type = MYSQL_TYPE_TINY;
1244 bind_[10].buffer = reinterpret_cast<char*>(&fqdn_rev_);
1250 hostname_length_ =
sizeof(hostname_buffer_);
1251 bind_[11].buffer_type = MYSQL_TYPE_STRING;
1252 bind_[11].buffer = reinterpret_cast<char*>(hostname_buffer_);
1253 bind_[11].buffer_length = hostname_length_;
1254 bind_[11].length = &hostname_length_;
1260 hwaddr_length_ =
sizeof(hwaddr_buffer_);
1261 bind_[12].buffer_type = MYSQL_TYPE_BLOB;
1262 bind_[12].buffer = reinterpret_cast<char*>(hwaddr_buffer_);
1263 bind_[12].buffer_length = hwaddr_length_;
1264 bind_[12].length = &hwaddr_length_;
1265 bind_[12].is_null = &hwaddr_null_;
1268 bind_[13].buffer_type = MYSQL_TYPE_SHORT;
1269 bind_[13].buffer = reinterpret_cast<char*>(&hwtype_);
1273 bind_[14].buffer_type = MYSQL_TYPE_LONG;
1274 bind_[14].buffer = reinterpret_cast<char*>(&hwaddr_source_);
1278 bind_[15].buffer_type = MYSQL_TYPE_LONG;
1279 bind_[15].buffer = reinterpret_cast<char*>(&state_);
1286 user_context_length_ =
sizeof(user_context_);
1287 bind_[16].buffer_type = MYSQL_TYPE_STRING;
1288 bind_[16].buffer = reinterpret_cast<char*>(user_context_);
1289 bind_[16].buffer_length = user_context_length_;
1290 bind_[16].length= &user_context_length_;
1291 bind_[16].is_null = &user_context_null_;
1294 setErrorIndicators(bind_, error_, LEASE_COLUMNS);
1297 BOOST_STATIC_ASSERT(16 < LEASE_COLUMNS);
1301 return(std::vector<MYSQL_BIND>(&bind_[0], &bind_[LEASE_COLUMNS]));
1318 addr6_buffer_[addr6_length_] =
'\0';
1319 std::string address = addr6_buffer_;
1325 switch (lease_type_) {
1326 case Lease::TYPE_NA:
1327 type = Lease::TYPE_NA;
1330 case Lease::TYPE_TA:
1331 type = Lease::TYPE_TA;
1334 case Lease::TYPE_PD:
1335 type = Lease::TYPE_PD;
1340 static_cast<int>(lease_type_) <<
") for lease with " 1341 <<
"address " << address <<
". Only 0, 1, or 2 are " 1346 DuidPtr duid_ptr(
new DUID(duid_buffer_, duid_length_));
1350 std::string hostname(hostname_buffer_,
1351 hostname_buffer_ + hostname_length_);
1356 hwaddr.reset(
new HWAddr(hwaddr_buffer_, hwaddr_length_, hwtype_));
1357 hwaddr->source_ = hwaddr_source_;
1361 std::string user_context;
1363 user_context_[user_context_length_] =
'\0';
1364 user_context.assign(user_context_);
1369 if (!user_context.empty()) {
1370 ctx = Element::fromJSON(user_context);
1371 if (!ctx || (ctx->getType() != Element::map)) {
1373 <<
"' is not a JSON map");
1380 pref_lifetime_, valid_lifetime_, 0, 0,
1381 subnet_id_, fqdn_fwd_, fqdn_rev_,
1382 hostname, hwaddr, prefixlen_));
1384 MySqlConnection::convertFromDatabaseTime(expire_, valid_lifetime_, cltt);
1385 result->cltt_ = cltt;
1388 result->state_ = state_;
1391 result->setContext(ctx);
1408 return (getColumnsInError(error_, columns_, LEASE_COLUMNS));
1416 char addr6_buffer_[ADDRESS6_TEXT_MAX_LEN + 1];
1417 unsigned long addr6_length_;
1419 MYSQL_BIND bind_[LEASE_COLUMNS];
1420 std::string columns_[LEASE_COLUMNS];
1421 std::vector<uint8_t> duid_;
1422 uint8_t duid_buffer_[DUID::MAX_DUID_LEN];
1423 unsigned long duid_length_;
1424 my_bool error_[LEASE_COLUMNS];
1428 uint8_t lease_type_;
1430 uint32_t pref_lifetime_;
1431 uint32_t subnet_id_;
1432 uint32_t valid_lifetime_;
1435 char hostname_buffer_[HOSTNAME_MAX_LEN];
1436 unsigned long hostname_length_;
1437 uint8_t hwaddr_buffer_[HWAddr::MAX_HWADDR_LEN];
1438 std::vector<uint8_t> hwaddr_;
1439 unsigned long hwaddr_length_;
1440 my_bool hwaddr_null_;
1442 uint32_t hwaddr_source_;
1444 char user_context_[USER_CONTEXT_MAX_LEN];
1445 unsigned long user_context_length_;
1446 my_bool user_context_null_;
1467 const bool fetch_type)
1468 : conn_(conn), statement_index_(statement_index), statement_(NULL),
1469 fetch_type_(fetch_type),
1472 bind_(fetch_type_ ? 4 : 3),
1473 subnet_id_(0), lease_type_(0), lease_state_(0), state_count_(0) {
1474 validateStatement();
1487 const bool fetch_type,
const SubnetID& subnet_id)
1488 :
LeaseStatsQuery(subnet_id), conn_(conn), statement_index_(statement_index),
1489 statement_(NULL), fetch_type_(fetch_type),
1492 bind_(fetch_type_ ? 4 : 3),
1493 subnet_id_(0), lease_type_(0), lease_state_(0), state_count_(0) {
1494 validateStatement();
1510 const bool fetch_type,
const SubnetID& first_subnet_id,
1513 statement_index_(statement_index), statement_(NULL), fetch_type_(fetch_type),
1516 bind_(fetch_type_ ? 4 : 3),
1517 subnet_id_(0), lease_type_(0), lease_state_(0), state_count_(0) {
1518 validateStatement();
1523 (void) mysql_stmt_free_result(statement_);
1535 if (getSelectMode() != ALL_SUBNETS) {
1536 MYSQL_BIND inbind[2];
1537 memset(inbind, 0,
sizeof(inbind));
1540 inbind[0].buffer_type = MYSQL_TYPE_LONG;
1541 inbind[0].buffer = reinterpret_cast<char*>(&first_subnet_id_);
1545 if (getSelectMode() == SUBNET_RANGE) {
1546 inbind[1].buffer_type = MYSQL_TYPE_LONG;
1547 inbind[1].buffer = reinterpret_cast<char*>(&last_subnet_id_);
1552 int status = mysql_stmt_bind_param(statement_, &inbind[0]);
1553 conn_.checkError(status, statement_index_,
"unable to bind parameters");
1558 bind_[col].buffer_type = MYSQL_TYPE_LONG;
1559 bind_[col].buffer = reinterpret_cast<char*>(&subnet_id_);
1566 bind_[col].buffer_type = MYSQL_TYPE_LONG;
1567 bind_[col].buffer = reinterpret_cast<char*>(&lease_type_);
1571 fetch_type_ = Lease::TYPE_NA;
1575 bind_[col].buffer_type = MYSQL_TYPE_LONG;
1576 bind_[col].buffer = reinterpret_cast<char*>(&lease_state_);
1581 bind_[col].buffer_type = MYSQL_TYPE_LONGLONG;
1582 bind_[col].buffer = reinterpret_cast<char*>(&state_count_);
1587 int status = mysql_stmt_bind_result(statement_, &bind_[0]);
1588 conn_.checkError(status, statement_index_,
"outbound binding failed");
1591 status = mysql_stmt_execute(statement_);
1592 conn_.checkError(status, statement_index_,
"unable to execute");
1596 status = mysql_stmt_store_result(statement_);
1597 conn_.checkError(status, statement_index_,
"results storage failed");
1612 bool have_row =
false;
1613 int status = mysql_stmt_fetch(statement_);
1615 row.
subnet_id_ = static_cast<SubnetID>(subnet_id_);
1616 row.
lease_type_ = static_cast<Lease::Type>(lease_type_);
1620 }
else if (status != MYSQL_NO_DATA) {
1621 conn_.checkError(status, statement_index_,
"getNextRow failed");
1631 void validateStatement() {
1632 if (statement_index_ >= MySqlLeaseMgr::NUM_STATEMENTS) {
1634 " - invalid statement index" << statement_index_);
1637 statement_ = conn_.statements_[statement_index_];
1644 size_t statement_index_;
1647 MYSQL_STMT *statement_;
1653 std::vector<MYSQL_BIND> bind_;
1656 uint32_t subnet_id_;
1658 uint32_t lease_type_;
1660 uint32_t lease_state_;
1662 int64_t state_count_;
1667 MySqlLeaseMgr::MySqlLeaseMgr(
const MySqlConnection::ParameterMap& parameters)
1668 : conn_(parameters) {
1676 std::pair<uint32_t, uint32_t> db_version =
getVersion();
1677 if (code_version != db_version) {
1679 "MySQL schema version mismatch: need version: " 1680 << code_version.first <<
"." << code_version.second
1681 <<
" found version: " << db_version.first <<
"." 1682 << db_version.second);
1690 my_bool result = mysql_autocommit(conn_.
mysql_, 1);
1711 std::stringstream tmp;
1714 tmp <<
", library " << mysql_get_client_info();
1723 MySqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
1724 std::vector<MYSQL_BIND>& bind) {
1727 int status = mysql_stmt_bind_param(conn_.
statements_[stindex], &bind[0]);
1728 checkError(status, stindex,
"unable to bind parameters");
1731 status = mysql_stmt_execute(conn_.
statements_[stindex]);
1737 if (mysql_errno(conn_.
mysql_) == ER_DUP_ENTRY) {
1740 checkError(status, stindex,
"unable to execute");
1750 DHCPSRV_MYSQL_ADD_ADDR4).arg(lease->addr_.toText());
1753 std::vector<MYSQL_BIND> bind = exchange4_->createBindForSend(lease);
1762 DHCPSRV_MYSQL_ADD_ADDR6).arg(lease->addr_.toText())
1766 std::vector<MYSQL_BIND> bind = exchange6_->createBindForSend(lease);
1797 template <
typename Exchange,
typename LeaseCollection>
1798 void MySqlLeaseMgr::getLeaseCollection(StatementIndex stindex,
1801 LeaseCollection& result,
1802 bool single)
const {
1808 status = mysql_stmt_bind_param(conn_.
statements_[stindex], bind);
1809 checkError(status, stindex,
"unable to bind WHERE clause parameter");
1814 std::vector<MYSQL_BIND> outbind = exchange->createBindForReceive();
1815 status = mysql_stmt_bind_result(conn_.
statements_[stindex], &outbind[0]);
1816 checkError(status, stindex,
"unable to bind SELECT clause parameters");
1819 status = mysql_stmt_execute(conn_.
statements_[stindex]);
1820 checkError(status, stindex,
"unable to execute");
1824 status = mysql_stmt_store_result(conn_.
statements_[stindex]);
1825 checkError(status, stindex,
"unable to set up for storing all results");
1832 while ((status = mysql_stmt_fetch(conn_.
statements_[stindex])) == 0) {
1834 result.push_back(exchange->getLeaseData());
1842 if (single && (++count > 1)) {
1844 "database where only one was expected for query " 1852 checkError(status, stindex,
"unable to fetch results");
1853 }
else if (status == MYSQL_DATA_TRUNCATED) {
1856 <<
" returned truncated data: columns affected are " 1857 << exchange->getErrorColumns());
1861 void MySqlLeaseMgr::getLease(StatementIndex stindex, MYSQL_BIND* bind,
1869 getLeaseCollection(stindex, bind, exchange4_, collection,
true);
1872 if (collection.empty()) {
1875 result = *collection.begin();
1879 void MySqlLeaseMgr::getLease(StatementIndex stindex, MYSQL_BIND* bind,
1887 getLeaseCollection(stindex, bind, exchange6_, collection,
true);
1890 if (collection.empty()) {
1893 result = *collection.begin();
1903 DHCPSRV_MYSQL_GET_ADDR4).arg(addr.
toText());
1906 MYSQL_BIND inbind[1];
1907 memset(inbind, 0,
sizeof(inbind));
1910 inbind[0].buffer_type = MYSQL_TYPE_LONG;
1911 inbind[0].buffer = reinterpret_cast<char*>(&addr4);
1924 DHCPSRV_MYSQL_GET_HWADDR).arg(hwaddr.
toText());
1927 MYSQL_BIND inbind[1];
1928 memset(inbind, 0,
sizeof(inbind));
1930 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
1932 unsigned long hwaddr_length = hwaddr.
hwaddr_.size();
1936 uint8_t single_byte_data = 0;
1943 uint8_t* data = !hwaddr.
hwaddr_.empty() ? const_cast<uint8_t*>(&hwaddr.
hwaddr_[0])
1944 : &single_byte_data;
1946 inbind[0].buffer = reinterpret_cast<char*>(data);
1947 inbind[0].buffer_length = hwaddr_length;
1948 inbind[0].length = &hwaddr_length;
1960 DHCPSRV_MYSQL_GET_SUBID_HWADDR)
1961 .arg(subnet_id).arg(hwaddr.
toText());
1964 MYSQL_BIND inbind[2];
1965 memset(inbind, 0,
sizeof(inbind));
1967 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
1969 unsigned long hwaddr_length = hwaddr.
hwaddr_.size();
1973 std::vector<uint8_t> single_byte_vec(1);
1980 uint8_t* data = !hwaddr.
hwaddr_.empty() ? const_cast<uint8_t*>(&hwaddr.
hwaddr_[0])
1981 : &single_byte_vec[0];
1983 inbind[0].buffer = reinterpret_cast<char*>(data);
1984 inbind[0].buffer_length = hwaddr_length;
1985 inbind[0].length = &hwaddr_length;
1987 inbind[1].buffer_type = MYSQL_TYPE_LONG;
1988 inbind[1].buffer = reinterpret_cast<char*>(&subnet_id);
2001 DHCPSRV_MYSQL_GET_CLIENTID).arg(clientid.
toText());
2004 MYSQL_BIND inbind[1];
2005 memset(inbind, 0,
sizeof(inbind));
2007 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
2009 std::vector<uint8_t> client_data = clientid.
getClientId();
2010 unsigned long client_data_length = client_data.size();
2014 if (client_data.empty()) {
2015 client_data.resize(1);
2018 inbind[0].buffer = reinterpret_cast<char*>(&client_data[0]);
2019 inbind[0].buffer_length = client_data_length;
2020 inbind[0].length = &client_data_length;
2036 " called, but it is not implemented");
2042 DHCPSRV_MYSQL_GET_SUBID_CLIENTID)
2043 .arg(subnet_id).arg(clientid.
toText());
2046 MYSQL_BIND inbind[2];
2047 memset(inbind, 0,
sizeof(inbind));
2049 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
2051 std::vector<uint8_t> client_data = clientid.
getClientId();
2052 unsigned long client_data_length = client_data.size();
2056 if (client_data.empty()) {
2057 client_data.resize(1);
2060 inbind[0].buffer = reinterpret_cast<char*>(&client_data[0]);
2061 inbind[0].buffer_length = client_data_length;
2062 inbind[0].length = &client_data_length;
2064 inbind[1].buffer_type = MYSQL_TYPE_LONG;
2065 inbind[1].buffer = reinterpret_cast<char*>(&subnet_id);
2081 MYSQL_BIND inbind[1];
2082 memset(inbind, 0,
sizeof(inbind));
2085 inbind[0].buffer_type = MYSQL_TYPE_LONG;
2086 inbind[0].buffer = reinterpret_cast<char*>(&subnet_id);
2110 if (!lower_bound_address.
isV4()) {
2112 "retrieving leases from the lease database, got " 2113 << lower_bound_address);
2118 .arg(lower_bound_address.
toText());
2121 MYSQL_BIND inbind[2];
2122 memset(inbind, 0,
sizeof(inbind));
2125 uint32_t lb_address_data = lower_bound_address.
toUint32();
2126 inbind[0].buffer_type = MYSQL_TYPE_LONG;
2127 inbind[0].buffer = reinterpret_cast<char*>(&lb_address_data);
2131 size_t* ps = const_cast<size_t*>(&page_size.
page_size_);
2132 inbind[1].buffer_type = MYSQL_TYPE_LONG;
2133 inbind[1].buffer = reinterpret_cast<char*>(ps);
2147 DHCPSRV_MYSQL_GET_ADDR6).arg(addr.
toText())
2151 MYSQL_BIND inbind[2];
2152 memset(inbind, 0,
sizeof(inbind));
2154 std::string addr6 = addr.
toText();
2155 unsigned long addr6_length = addr6.size();
2159 inbind[0].buffer_type = MYSQL_TYPE_STRING;
2160 inbind[0].buffer = const_cast<char*>(addr6.c_str());
2161 inbind[0].buffer_length = addr6_length;
2162 inbind[0].length = &addr6_length;
2165 inbind[1].buffer_type = MYSQL_TYPE_TINY;
2166 inbind[1].buffer = reinterpret_cast<char*>(&lease_type);
2177 const DUID& duid, uint32_t iaid)
const {
2179 DHCPSRV_MYSQL_GET_IAID_DUID).arg(iaid).arg(duid.
toText())
2183 MYSQL_BIND inbind[3];
2184 memset(inbind, 0,
sizeof(inbind));
2198 const vector<uint8_t>& duid_vector = duid.
getDuid();
2199 unsigned long duid_length = duid_vector.size();
2206 uint8_t single_byte_data = 0;
2207 uint8_t* data = !duid_vector.empty() ? const_cast<uint8_t*>(&duid_vector[0])
2208 : &single_byte_data;
2210 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
2211 inbind[0].buffer = reinterpret_cast<char*>(data);
2212 inbind[0].buffer_length = duid_length;
2213 inbind[0].length = &duid_length;
2216 inbind[1].buffer_type = MYSQL_TYPE_LONG;
2217 inbind[1].buffer = reinterpret_cast<char*>(&iaid);
2221 inbind[2].buffer_type = MYSQL_TYPE_TINY;
2222 inbind[2].buffer = reinterpret_cast<char*>(&lease_type);
2234 const DUID& duid, uint32_t iaid,
2237 DHCPSRV_MYSQL_GET_IAID_SUBID_DUID)
2238 .arg(iaid).arg(subnet_id).arg(duid.
toText())
2242 MYSQL_BIND inbind[4];
2243 memset(inbind, 0,
sizeof(inbind));
2247 const vector<uint8_t>& duid_vector = duid.
getDuid();
2248 unsigned long duid_length = duid_vector.size();
2249 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
2250 inbind[0].buffer = reinterpret_cast<char*>(
2251 const_cast<uint8_t*>(&duid_vector[0]));
2252 inbind[0].buffer_length = duid_length;
2253 inbind[0].length = &duid_length;
2256 inbind[1].buffer_type = MYSQL_TYPE_LONG;
2257 inbind[1].buffer = reinterpret_cast<char*>(&iaid);
2261 inbind[2].buffer_type = MYSQL_TYPE_LONG;
2262 inbind[2].buffer = reinterpret_cast<char*>(&subnet_id);
2266 inbind[3].buffer_type = MYSQL_TYPE_TINY;
2267 inbind[3].buffer = reinterpret_cast<char*>(&lease_type);
2283 MYSQL_BIND inbind[1];
2284 memset(inbind, 0,
sizeof(inbind));
2287 inbind[0].buffer_type = MYSQL_TYPE_LONG;
2288 inbind[0].buffer = reinterpret_cast<char*>(&subnet_id);
2314 MYSQL_BIND inbind[1];
2315 memset(inbind, 0,
sizeof(inbind));
2317 const vector<uint8_t>& duid_vector = duid.
getDuid();
2318 unsigned long duid_length = duid_vector.size();
2320 inbind[0].buffer_type = MYSQL_TYPE_BLOB;
2321 inbind[0].buffer = reinterpret_cast<char*>(
2322 const_cast<uint8_t*>(&duid_vector[0]));
2323 inbind[0].buffer_length = duid_length;
2324 inbind[0].length = &duid_length;
2337 if (!lower_bound_address.
isV6()) {
2339 "retrieving leases from the lease database, got " 2340 << lower_bound_address);
2345 .arg(lower_bound_address.
toText());
2348 MYSQL_BIND inbind[2];
2349 memset(inbind, 0,
sizeof(inbind));
2354 std::string lb_address_data =
"0";
2355 if (!lower_bound_address.
isV6Zero()) {
2356 lb_address_data = lower_bound_address.
toText();
2360 unsigned long lb_address_data_size = lb_address_data.size();
2361 inbind[0].buffer_type = MYSQL_TYPE_STRING;
2362 inbind[0].buffer = const_cast<char*>(lb_address_data.c_str());
2363 inbind[0].buffer_length = lb_address_data_size;
2364 inbind[0].length = &lb_address_data_size;
2367 size_t* ps = const_cast<size_t*>(&page_size.
page_size_);
2368 inbind[1].buffer_type = MYSQL_TYPE_LONG;
2369 inbind[1].buffer = reinterpret_cast<char*>(ps);
2381 const size_t max_leases)
const {
2389 const size_t max_leases)
const {
2395 template<
typename LeaseCollection>
2397 MySqlLeaseMgr::getExpiredLeasesCommon(LeaseCollection& expired_leases,
2398 const size_t max_leases,
2399 StatementIndex statement_index)
const {
2401 MYSQL_BIND inbind[3];
2402 memset(inbind, 0,
sizeof(inbind));
2406 inbind[0].buffer_type = MYSQL_TYPE_LONG;
2407 inbind[0].buffer = reinterpret_cast<char*>(&state);
2411 MYSQL_TIME expire_time;
2413 inbind[1].buffer_type = MYSQL_TYPE_TIMESTAMP;
2414 inbind[1].buffer = reinterpret_cast<char*>(&expire_time);
2415 inbind[1].buffer_length =
sizeof(expire_time);
2419 uint32_t limit = max_leases > 0 ? static_cast<uint32_t>(max_leases) :
2420 std::numeric_limits<uint32_t>::max();
2421 inbind[2].buffer_type = MYSQL_TYPE_LONG;
2422 inbind[2].buffer = reinterpret_cast<char*>(&limit);
2426 getLeaseCollection(statement_index, inbind, expired_leases);
2433 template <
typename LeasePtr>
2435 MySqlLeaseMgr::updateLeaseCommon(StatementIndex stindex, MYSQL_BIND* bind,
2439 int status = mysql_stmt_bind_param(conn_.
statements_[stindex], bind);
2440 checkError(status, stindex,
"unable to bind parameters");
2443 status = mysql_stmt_execute(conn_.
statements_[stindex]);
2444 checkError(status, stindex,
"unable to execute");
2448 int affected_rows = mysql_stmt_affected_rows(conn_.
statements_[stindex]);
2449 if (affected_rows == 0) {
2451 lease->addr_ <<
" as it does not exist");
2452 }
else if (affected_rows > 1) {
2456 "that had the address " << lease->addr_);
2465 DHCPSRV_MYSQL_UPDATE_ADDR4).arg(lease->addr_.toText());
2468 std::vector<MYSQL_BIND> bind = exchange4_->createBindForSend(lease);
2472 memset(&where, 0,
sizeof(where));
2474 uint32_t addr4 = lease->addr_.toUint32();
2475 where.buffer_type = MYSQL_TYPE_LONG;
2476 where.buffer = reinterpret_cast<char*>(&addr4);
2478 bind.push_back(where);
2481 updateLeaseCommon(stindex, &bind[0], lease);
2489 DHCPSRV_MYSQL_UPDATE_ADDR6).arg(lease->addr_.toText())
2493 std::vector<MYSQL_BIND> bind = exchange6_->createBindForSend(lease);
2497 memset(&where, 0,
sizeof(where));
2499 std::string addr6 = lease->addr_.toText();
2500 unsigned long addr6_length = addr6.size();
2504 where.buffer_type = MYSQL_TYPE_STRING;
2505 where.buffer = const_cast<char*>(addr6.c_str());
2506 where.buffer_length = addr6_length;
2507 where.length = &addr6_length;
2508 bind.push_back(where);
2511 updateLeaseCommon(stindex, &bind[0], lease);
2520 MySqlLeaseMgr::deleteLeaseCommon(StatementIndex stindex, MYSQL_BIND* bind) {
2523 int status = mysql_stmt_bind_param(conn_.
statements_[stindex], bind);
2524 checkError(status, stindex,
"unable to bind WHERE clause parameter");
2527 status = mysql_stmt_execute(conn_.
statements_[stindex]);
2528 checkError(status, stindex,
"unable to execute");
2532 return (static_cast<uint64_t>(mysql_stmt_affected_rows(conn_.
statements_[stindex])));
2538 DHCPSRV_MYSQL_DELETE_ADDR).arg(addr.
toText());
2541 MYSQL_BIND inbind[1];
2542 memset(inbind, 0,
sizeof(inbind));
2547 inbind[0].buffer_type = MYSQL_TYPE_LONG;
2548 inbind[0].buffer = reinterpret_cast<char*>(&addr4);
2554 std::string addr6 = addr.
toText();
2555 unsigned long addr6_length = addr6.size();
2559 inbind[0].buffer_type = MYSQL_TYPE_STRING;
2560 inbind[0].buffer = const_cast<char*>(addr6.c_str());
2561 inbind[0].buffer_length = addr6_length;
2562 inbind[0].length = &addr6_length;
2571 DHCPSRV_MYSQL_DELETE_EXPIRED_RECLAIMED4)
2579 DHCPSRV_MYSQL_DELETE_EXPIRED_RECLAIMED6)
2585 MySqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(
const uint32_t secs,
2586 StatementIndex statement_index) {
2588 MYSQL_BIND inbind[2];
2589 memset(inbind, 0,
sizeof(inbind));
2593 inbind[0].buffer_type = MYSQL_TYPE_LONG;
2594 inbind[0].buffer = reinterpret_cast<char*>(&state);
2598 MYSQL_TIME expire_time;
2600 inbind[1].buffer_type = MYSQL_TYPE_TIMESTAMP;
2601 inbind[1].buffer = reinterpret_cast<char*>(&expire_time);
2602 inbind[1].buffer_length =
sizeof(expire_time);
2605 uint64_t deleted_leases = deleteLeaseCommon(statement_index, inbind);
2607 DHCPSRV_MYSQL_DELETED_EXPIRED_RECLAIMED)
2608 .arg(deleted_leases);
2610 return (deleted_leases);
2638 first_subnet_id, last_subnet_id));
2668 first_subnet_id, last_subnet_id));
2687 std::string name =
"";
2698 return (std::string(
"MySQL Database"));
2701 std::pair<uint32_t, uint32_t>
2704 DHCPSRV_MYSQL_GET_VERSION);
2707 MYSQL_STMT *stmt = mysql_stmt_init(conn_.
mysql_);
2710 "statement structure, reason: " << mysql_error(conn_.
mysql_));
2714 const char* version_sql =
"SELECT version, minor FROM schema_version";
2715 int status = mysql_stmt_prepare(stmt, version_sql, strlen(version_sql));
2718 << version_sql <<
">, reason: " << mysql_error(conn_.
mysql_));
2722 if (mysql_stmt_execute(stmt) != 0) {
2724 << version_sql <<
">, reason: " << mysql_errno(conn_.
mysql_));
2729 memset(bind, 0,
sizeof(bind));
2732 bind[0].buffer_type = MYSQL_TYPE_LONG;
2733 bind[0].is_unsigned = 1;
2734 bind[0].buffer = &major;
2735 bind[0].buffer_length =
sizeof(major);
2738 bind[1].buffer_type = MYSQL_TYPE_LONG;
2739 bind[1].is_unsigned = 1;
2740 bind[1].buffer = &minor;
2741 bind[1].buffer_length =
sizeof(minor);
2743 if (mysql_stmt_bind_result(stmt, bind)) {
2745 << version_sql <<
">, reason: " << mysql_errno(conn_.
mysql_));
2749 if (mysql_stmt_fetch(stmt)) {
2750 mysql_stmt_close(stmt);
2752 << version_sql <<
">, reason: " << mysql_errno(conn_.
mysql_));
2756 mysql_stmt_close(stmt);
2758 return (std::make_pair(major, minor));
2764 if (mysql_commit(conn_.
mysql_) != 0) {
2772 if (mysql_rollback(conn_.
mysql_) != 0) {
2778 MySqlLeaseMgr::checkError(
int status, StatementIndex index,
2779 const char* what)
const {
std::vector< std::string > text_statements_
Raw text of statements.
void start()
Creates the IPv4 lease statistical data result set.
boost::shared_ptr< DUID > DuidPtr
MySqlHolder mysql_
MySQL connection handle.
virtual std::pair< uint32_t, uint32_t > getVersion() const
Returns backend version.
boost::shared_ptr< LeaseStatsQuery > LeaseStatsQueryPtr
Defines a pointer to a LeaseStatsQuery.
Fetch and Release MySQL Results.
A generic exception that is thrown when a function is not implemented.
static const uint32_t STATE_EXPIRED_RECLAIMED
Expired and reclaimed lease.
const std::vector< uint8_t > & getClientId() const
Returns reference to the client-id data.
Structure that holds a lease for IPv4 address.
static std::string getDBVersion()
Local version of getDBVersion() class method.
static void convertToDatabaseTime(const time_t input_time, MYSQL_TIME &output_time)
Convert time_t value to database time.
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs)
Deletes all expired-reclaimed DHCPv6 leases.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const
Returns an IPv4 lease for specified IPv4 address.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
static void setErrorIndicators(MYSQL_BIND *bind, my_bool *error, size_t count)
Set error indicators.
MySqlLeaseStatsQuery(MySqlConnection &conn, const size_t statement_index, const bool fetch_type, const SubnetID &subnet_id)
Constructor to query for a single subnet's stats.
virtual void getExpiredLeases4(Lease4Collection &expired_leases, const size_t max_leases) const
Returns a collection of expired DHCPv4 leases.
virtual size_t wipeLeases6(const SubnetID &subnet_id)
Removed specified IPv6 leases.
std::string getErrorColumns()
Return columns in error.
Attempt to update lease that was not there.
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
const uint32_t MYSQL_SCHEMA_VERSION_MAJOR
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const
Returns existing IPv6 lease for a given IPv6 address.
virtual void updateLease6(const Lease6Ptr &lease6)
Updates IPv6 lease.
std::vector< uint8_t > hwaddr_
Base class for fulfilling a statistical lease data query.
const uint32_t MYSQL_SCHEMA_VERSION_MINOR
virtual LeaseStatsQueryPtr startLeaseStatsQuery4()
Creates and runs the IPv4 lease stats query.
virtual size_t wipeLeases4(const SubnetID &subnet_id)
Removes specified IPv4 leases.
virtual Lease6Collection getLeases6() const
Returns all IPv6 leases.
boost::shared_ptr< Lease > LeasePtr
Pointer to the lease object.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Holds DUID (DHCPv6 Unique Identifier)
virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs)
Deletes all expired-reclaimed DHCPv4 leases.
Exception thrown on failure to open database.
std::vector< MYSQL_BIND > createBindForReceive()
Create BIND array to receive data.
virtual void rollback()
Rollback Transactions.
virtual bool addLease(const Lease4Ptr &lease)
Adds an IPv4 lease.
TaggedStatementArray tagged_statements
Prepared MySQL statements used by the backend to insert and retrieve hosts from the database.
Multiple lease records found where one expected.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID &subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
MySqlLease6Exchange()
Constructor.
const my_bool MLM_FALSE
MySQL false value.
std::vector< MYSQL_BIND > createBindForSend(const Lease4Ptr &lease)
Create MYSQL_BIND objects for Lease4 Pointer.
const size_t page_size_
Holds page size.
StatementIndex
Statement Tags.
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
bool getNextRow(LeaseStatsRow &row)
Fetches the next row in the result set.
virtual std::string getDescription() const
Returns description of the backend.
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
virtual Lease4Collection getLeases4() const
Returns all IPv4 leases.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
bool isV6Zero() const
Convenience function to check if it is an IPv4 zero address.
SubnetID subnet_id_
The subnet ID to which this data applies.
virtual ~MySqlLeaseMgr()
Destructor (closes database)
boost::shared_ptr< const Element > ConstElementPtr
Structure that holds a lease for IPv6 address and/or prefix.
std::vector< MYSQL_BIND > createBindForSend(const Lease6Ptr &lease)
Create MYSQL_BIND objects for Lease6 Pointer.
std::string getParameter(const std::string &name) const
Returns value of a connection parameter.
MySqlLease4Exchange()
Constructor.
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
virtual void updateLease4(const Lease4Ptr &lease4)
Updates IPv4 lease.
bool isV6() const
Convenience function to check for an IPv6 address.
MySql derivation of the statistical lease data query.
bool isV4() const
Convenience function to check for an IPv4 address.
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
const std::vector< uint8_t > & getDuid() const
Returns a const reference to the actual DUID value.
const int MLM_MYSQL_FETCH_SUCCESS
MySQL fetch success code.
Lease6Ptr getLeaseData()
Copy Received Data into Lease6 Object.
MySqlLeaseStatsQuery(MySqlConnection &conn, const size_t statement_index, const bool fetch_type)
Constructor to query for all subnets' stats.
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID &subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
Invalid address family used as input to Lease Manager.
Defines the logger used by the top-level component of kea-dhcp-ddns.
std::string toText() const
Convert the address to a string.
Common MySQL and Lease Data Methods.
Lease4Ptr getLeaseData()
Copy Received Data into Lease4 Object.
Exchange MySQL and Lease6 Data.
Exchange MySQL and Lease4 Data.
std::vector< MYSQL_STMT * > statements_
Prepared statements.
uint32_t lease_state_
The lease_state to which the count applies.
Type
Type of lease or pool.
Holds Client identifier or client IPv4 address.
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
MySqlLeaseStatsQuery(MySqlConnection &conn, const size_t statement_index, const bool fetch_type, const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Constructor to query for the stats for a range of subnets.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Hardware type that represents information from DHCPv4 packet.
std::vector< MYSQL_BIND > createBindForReceive()
Create BIND array to receive data.
int64_t state_count_
state_count The count of leases in the lease state
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Contains a single row of lease statistical data.
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
virtual LeaseStatsQueryPtr startLeaseStatsQuery6()
Creates and runs the IPv6 lease stats query.
Wraps value holding size of the page with leases.
virtual std::string getName() const
Returns backend name.
Lease::Type lease_type_
The lease_type to which the count applies.
The IOAddress class represents an IP addresses (version agnostic)
virtual bool deleteLease(const isc::asiolink::IOAddress &addr)
Deletes a lease.
virtual void getExpiredLeases6(Lease6Collection &expired_leases, const size_t max_leases) const
Returns a collection of expired DHCPv6 leases.
void checkError(const int status, const StatementIndex &index, const char *what) const
Check Error and Throw Exception.
virtual ~MySqlLeaseStatsQuery()
Destructor.
void prepareStatements(const TaggedStatement *start_statement, const TaggedStatement *end_statement)
Prepare statements.
void openDatabase()
Open Database.
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
virtual void commit()
Commit Transactions.
static std::string getColumnsInError(my_bool *error, std::string *names, size_t count)
Return columns in error.
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Exception thrown on failure to execute a database function.
const my_bool MLM_TRUE
MySQL true value.
std::string toText(bool include_htype=true) const
Returns textual representation of a hardware address (e.g.
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
Common MySQL Connector Pool.
std::string getErrorColumns()
Return columns in error.