21#include <boost/make_shared.hpp>
22#include <boost/static_assert.hpp>
47 "DELETE FROM lease4 WHERE address = $1 AND expire = $2"},
51 "delete_lease4_state_expired",
53 "WHERE state = $1 AND expire < $2"},
58 "DELETE FROM lease6 WHERE address = $1 AND expire = $2"},
62 "delete_lease6_state_expired",
64 "WHERE state = $1 AND expire < $2"},
69 "SELECT address, hwaddr, client_id, "
70 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
71 "fqdn_fwd, fqdn_rev, hostname, "
72 "state, user_context "
78 "SELECT address, hwaddr, client_id, "
79 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
80 "fqdn_fwd, fqdn_rev, hostname, "
81 "state, user_context "
83 "WHERE address = $1"},
87 "get_lease4_clientid",
88 "SELECT address, hwaddr, client_id, "
89 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
90 "fqdn_fwd, fqdn_rev, hostname, "
91 "state, user_context "
93 "WHERE client_id = $1"},
97 "get_lease4_clientid_subid",
98 "SELECT address, hwaddr, client_id, "
99 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
100 "fqdn_fwd, fqdn_rev, hostname, "
101 "state, user_context "
103 "WHERE client_id = $1 AND subnet_id = $2"},
108 "SELECT address, hwaddr, client_id, "
109 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
110 "fqdn_fwd, fqdn_rev, hostname, "
111 "state, user_context "
113 "WHERE hwaddr = $1"},
117 "get_lease4_hwaddr_subid",
118 "SELECT address, hwaddr, client_id, "
119 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
120 "fqdn_fwd, fqdn_rev, hostname, "
121 "state, user_context "
123 "WHERE hwaddr = $1 AND subnet_id = $2"},
128 "SELECT address, hwaddr, client_id, "
129 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
130 "fqdn_fwd, fqdn_rev, hostname, "
131 "state, user_context "
133 "WHERE address > $1 "
140 "SELECT address, hwaddr, client_id, "
141 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
142 "fqdn_fwd, fqdn_rev, hostname, "
143 "state, user_context "
145 "WHERE subnet_id = $1"},
149 "get_lease4_hostname",
150 "SELECT address, hwaddr, client_id, "
151 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
152 "fqdn_fwd, fqdn_rev, hostname, "
153 "state, user_context "
155 "WHERE lower(hostname) = $1"},
160 "SELECT address, hwaddr, client_id, "
161 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
162 "fqdn_fwd, fqdn_rev, hostname, "
163 "state, user_context "
165 "WHERE state != $1 AND valid_lifetime != 4294967295 AND expire < $2 "
172 "SELECT address, duid, valid_lifetime, "
173 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
174 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
175 "hwaddr, hwtype, hwaddr_source, "
176 "state, user_context "
182 "SELECT address, duid, valid_lifetime, "
183 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
184 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
185 "hwaddr, hwtype, hwaddr_source, "
186 "state, user_context "
188 "WHERE address = $1 AND lease_type = $2"},
192 "get_lease6_duid_iaid",
193 "SELECT address, duid, valid_lifetime, "
194 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
195 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
196 "hwaddr, hwtype, hwaddr_source, "
197 "state, user_context "
199 "WHERE duid = $1 AND iaid = $2 AND lease_type = $3"},
203 "get_lease6_duid_iaid_subid",
204 "SELECT address, duid, valid_lifetime, "
205 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
206 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
207 "hwaddr, hwtype, hwaddr_source, "
208 "state, user_context "
210 "WHERE lease_type = $1 "
211 "AND duid = $2 AND iaid = $3 AND subnet_id = $4"},
216 "SELECT address, duid, valid_lifetime, "
217 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
218 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
219 "hwaddr, hwtype, hwaddr_source, "
220 "state, user_context "
222 "WHERE address > $1 "
229 "SELECT address, duid, valid_lifetime, "
230 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
231 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
232 "hwaddr, hwtype, hwaddr_source, "
233 "state, user_context "
235 "WHERE subnet_id = $1"},
240 "SELECT address, duid, valid_lifetime, "
241 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
242 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
243 "hwaddr, hwtype, hwaddr_source, "
244 "state, user_context "
250 "get_lease6_hostname",
251 "SELECT address, duid, valid_lifetime, "
252 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
253 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
254 "hwaddr, hwtype, hwaddr_source, "
255 "state, user_context "
257 "WHERE lower(hostname) = $1"},
262 "SELECT address, duid, valid_lifetime, "
263 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
264 "lease_type, iaid, prefix_len, "
265 "fqdn_fwd, fqdn_rev, hostname, "
266 "hwaddr, hwtype, hwaddr_source, "
267 "state, user_context "
269 "WHERE state != $1 AND valid_lifetime != 4294967295 AND expire < $2 "
277 "INSERT INTO lease4(address, hwaddr, client_id, "
278 "valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, "
279 "state, user_context) "
280 "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)"},
287 "INSERT INTO lease6(address, duid, valid_lifetime, "
288 "expire, subnet_id, pref_lifetime, "
289 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
290 "hwaddr, hwtype, hwaddr_source, "
291 "state, user_context) "
292 "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)"},
298 "UPDATE lease4 SET address = $1, hwaddr = $2, "
299 "client_id = $3, valid_lifetime = $4, expire = $5, "
300 "subnet_id = $6, fqdn_fwd = $7, fqdn_rev = $8, hostname = $9, "
301 "state = $10, user_context = $11 "
302 "WHERE address = $12 AND expire = $13"},
310 "UPDATE lease6 SET address = $1, duid = $2, "
311 "valid_lifetime = $3, expire = $4, subnet_id = $5, "
312 "pref_lifetime = $6, lease_type = $7, iaid = $8, "
313 "prefix_len = $9, fqdn_fwd = $10, fqdn_rev = $11, hostname = $12, "
314 "hwaddr = $13, hwtype = $14, hwaddr_source = $15, "
315 "state = $16, user_context = $17 "
316 "WHERE address = $18 AND expire = $19"},
321 "SELECT subnet_id, state, leases as state_count"
322 " FROM lease4_stat ORDER BY subnet_id, state"},
326 "subnet_lease4_stats",
327 "SELECT subnet_id, state, leases as state_count"
329 " WHERE subnet_id = $1 "
334 "subnet_range_lease4_stats",
335 "SELECT subnet_id, state, leases as state_count"
337 " WHERE subnet_id >= $1 and subnet_id <= $2 "
338 " ORDER BY subnet_id, state"},
343 "SELECT subnet_id, lease_type, state, leases as state_count"
344 " FROM lease6_stat ORDER BY subnet_id, lease_type, state" },
348 "subnet_lease6_stats",
349 "SELECT subnet_id, lease_type, state, leases as state_count"
351 " WHERE subnet_id = $1 "
352 " ORDER BY lease_type, state" },
356 "subnet_range_lease6_stats",
357 "SELECT subnet_id, lease_type, state, leases as state_count"
359 " WHERE subnet_id >= $1 and subnet_id <= $2 "
360 " ORDER BY subnet_id, lease_type, state" },
362 { 0, { 0 }, NULL, NULL}
419 static const size_t ADDRESS_COL = 0;
420 static const size_t HWADDR_COL = 1;
421 static const size_t CLIENT_ID_COL = 2;
422 static const size_t VALID_LIFETIME_COL = 3;
423 static const size_t EXPIRE_COL = 4;
424 static const size_t SUBNET_ID_COL = 5;
425 static const size_t FQDN_FWD_COL = 6;
426 static const size_t FQDN_REV_COL = 7;
427 static const size_t HOSTNAME_COL = 8;
428 static const size_t STATE_COL = 9;
429 static const size_t USER_CONTEXT_COL = 10;
431 static const size_t LEASE_COLUMNS = 11;
437 : lease_(), addr4_(0), client_id_length_(0) {
439 BOOST_STATIC_ASSERT(9 < LEASE_COLUMNS);
442 memset(client_id_buffer_, 0,
sizeof(client_id_buffer_));
448 columns_.push_back(
"valid_lifetime");
479 addr_str_ = boost::lexical_cast<std::string>(lease->addr_.toUint32());
482 if (lease->hwaddr_ && !lease->hwaddr_->hwaddr_.empty()) {
487 << lease_->hwaddr_->hwaddr_.size()
488 <<
" exceeds maximum allowed of: "
491 bind_array.
add(lease->hwaddr_->hwaddr_);
496 if (lease->client_id_) {
497 bind_array.
add(lease->client_id_->getClientId());
514 subnet_id_str_ = boost::lexical_cast<std::string>(lease->subnet_id_);
517 bind_array.
add(lease->fqdn_fwd_);
519 bind_array.
add(lease->fqdn_rev_);
521 bind_array.
add(lease->hostname_);
523 state_str_ = boost::lexical_cast<std::string>(lease->state_);
533 }
catch (
const std::exception& ex) {
535 "Could not create bind array from Lease4: "
536 << lease_->addr_.toText() <<
", reason: " << ex.what());
556 sizeof(client_id_buffer_), client_id_length_);
588 if (!ctx || (ctx->getType() != Element::map)) {
590 <<
"' is not a JSON map");
594 Lease4Ptr result(boost::make_shared<Lease4>(addr4_, hwaddr,
601 result->state_ = state;
604 result->setContext(ctx);
608 }
catch (
const std::exception& ex) {
610 "Could not convert data to Lease4, reason: "
624 size_t client_id_length_;
637 static const int ADDRESS_COL = 0;
638 static const int DUID_COL = 1;
639 static const int VALID_LIFETIME_COL = 2;
640 static const int EXPIRE_COL = 3;
641 static const int SUBNET_ID_COL = 4;
642 static const int PREF_LIFETIME_COL = 5;
643 static const int LEASE_TYPE_COL = 6;
644 static const int IAID_COL = 7;
645 static const int PREFIX_LEN_COL = 8;
646 static const int FQDN_FWD_COL = 9;
647 static const int FQDN_REV_COL = 10;
648 static const int HOSTNAME_COL = 11;
649 static const int HWADDR_COL = 12;
650 static const int HWTYPE_COL = 13;
651 static const int HWADDR_SOURCE_COL = 14;
652 static const int STATE_COL = 15;
653 static const size_t USER_CONTEXT_COL = 16;
656 static const size_t LEASE_COLUMNS = 17;
677 return (boost::lexical_cast<std::string>(
ival_));
685 : lease_(), duid_length_(0), duid_(duid_length_), iaid_u_(0),
686 iaid_str_(
""), lease_type_(
Lease6::TYPE_NA), lease_type_str_(
""),
687 prefix_len_(0), prefix_len_str_(
""), pref_lifetime_(0),
688 preferred_lifetime_str_(
""), hwtype_(0), hwtype_str_(
""),
689 hwaddr_source_(0), hwaddr_source_str_(
"") {
691 BOOST_STATIC_ASSERT(15 < LEASE_COLUMNS);
693 memset(duid_buffer_, 0,
sizeof(duid_buffer_));
698 columns_.push_back(
"valid_lifetime");
701 columns_.push_back(
"pref_lifetime");
710 columns_.push_back(
"hwaddr_source");
739 bind_array.
add(lease_->duid_->getDuid());
756 subnet_id_str_ = boost::lexical_cast<std::string>(lease->subnet_id_);
759 preferred_lifetime_str_ = boost::lexical_cast<std::string>(lease_->preferred_lft_);
760 bind_array.
add(preferred_lifetime_str_);
762 lease_type_str_ = boost::lexical_cast<std::string>(lease_->type_);
763 bind_array.
add(lease_type_str_);
768 iaid_u_.
uval_ = lease_->iaid_;
770 bind_array.
add(iaid_str_);
772 prefix_len_str_ = boost::lexical_cast<std::string>
773 (
static_cast<unsigned int>(lease_->prefixlen_));
774 bind_array.
add(prefix_len_str_);
776 bind_array.
add(lease->fqdn_fwd_);
778 bind_array.
add(lease->fqdn_rev_);
780 bind_array.
add(lease->hostname_);
782 if (lease->hwaddr_ && !lease->hwaddr_->hwaddr_.empty()) {
787 << lease_->hwaddr_->hwaddr_.size()
788 <<
" exceeds maximum allowed of: "
791 bind_array.
add(lease->hwaddr_->hwaddr_);
796 if (lease->hwaddr_) {
797 hwtype_str_ = boost::lexical_cast<std::string>
798 (
static_cast<unsigned int>(lease_->hwaddr_->htype_));
799 hwaddr_source_str_ = boost::lexical_cast<std::string>
800 (
static_cast<unsigned int>(lease_->hwaddr_->source_));
802 hwtype_str_ = boost::lexical_cast<std::string>
804 hwaddr_source_str_ = boost::lexical_cast<std::string>
808 bind_array.
add(hwtype_str_);
810 bind_array.
add(hwaddr_source_str_);
812 state_str_ = boost::lexical_cast<std::string>(lease->state_);
822 }
catch (
const std::exception& ex) {
824 "Could not create bind array from Lease6: "
825 << lease_->addr_.toText() <<
", reason: " << ex.what());
850 convertFromBytea(r, row, DUID_COL, duid_buffer_,
sizeof(duid_buffer_), duid_length_);
851 DuidPtr duid_ptr(
new DUID(duid_buffer_, duid_length_));
894 hwaddr->source_ = hwaddr_source_;
904 if (!ctx || (ctx->getType() != Element::map)) {
906 <<
"' is not a JSON map");
910 Lease6Ptr result(boost::make_shared<Lease6>(lease_type_, addr,
917 hwaddr, prefix_len_));
919 result->cltt_ =
cltt_;
920 result->current_cltt_ =
cltt_;
922 result->state_ = state;
925 result->setContext(ctx);
929 }
catch (
const std::exception& ex) {
931 "Could not convert data to Lease6, reason: "
950 uint32_t raw_value = 0;
974 std::vector<uint8_t> duid_;
977 std::string iaid_str_;
979 std::string lease_type_str_;
981 std::string prefix_len_str_;
982 uint32_t pref_lifetime_;
983 std::string preferred_lifetime_str_;
985 std::string hwtype_str_;
986 uint32_t hwaddr_source_;
987 std::string hwaddr_source_str_;
1008 const bool fetch_type)
1022 const bool fetch_type,
const SubnetID& subnet_id)
1038 const bool fetch_type,
const SubnetID& first_subnet_id,
1067 std::string subnet_id_str = boost::lexical_cast<std::string>(
getFirstSubnetID());
1068 parms.
add(subnet_id_str);
1073 std::string subnet_id_str = boost::lexical_cast<std::string>(
getLastSubnetID());
1074 parms.
add(subnet_id_str);
1115 uint32_t lease_type;
1176 : conn_(parameters, io_service_accessor, db_reconnect_callback) {
1181PgSqlLeaseMgr::PgSqlLeaseContextAlloc::PgSqlLeaseContextAlloc(
1184 if (MultiThreadingMgr::instance().getMode()) {
1188 lock_guard<mutex> lock(mgr_.pool_->mutex_);
1189 if (!mgr_.pool_->pool_.empty()) {
1190 ctx_ = mgr_.pool_->pool_.back();
1191 mgr_.pool_->pool_.pop_back();
1195 ctx_ = mgr_.createContext();
1199 if (mgr_.pool_->pool_.empty()) {
1202 ctx_ = mgr_.pool_->pool_.back();
1206PgSqlLeaseMgr::PgSqlLeaseContextAlloc::~PgSqlLeaseContextAlloc() {
1207 if (MultiThreadingMgr::instance().getMode()) {
1209 lock_guard<mutex> lock(mgr_.pool_->mutex_);
1210 mgr_.pool_->pool_.push_back(ctx_);
1218 : parameters_(parameters), timer_name_(
"") {
1221 timer_name_ =
"PgSqlLeaseMgr[";
1222 timer_name_ += boost::lexical_cast<std::string>(
reinterpret_cast<uint64_t
>(
this));
1223 timer_name_ +=
"]DbReconnectTimer";
1228 std::pair<uint32_t, uint32_t> db_version =
getVersion();
1229 if (code_version != db_version) {
1231 "PostgreSQL schema version mismatch: need version: "
1232 << code_version.first <<
"." << code_version.second
1233 <<
" found version: " << db_version.first <<
"."
1234 << db_version.second);
1254 bool reopened =
false;
1256 const std::string timer_name = db_reconnect_ctl->timerName();
1264 }
catch (
const std::exception& ex) {
1280 if (!db_reconnect_ctl->checkRetries()) {
1283 .arg(db_reconnect_ctl->maxRetries());
1296 .arg(db_reconnect_ctl->maxRetries() - db_reconnect_ctl->retriesLeft() + 1)
1297 .arg(db_reconnect_ctl->maxRetries())
1298 .arg(db_reconnect_ctl->retryInterval());
1304 db_reconnect_ctl->retryInterval(),
1322 ctx->conn_.openDatabase();
1326 for (; tagged_statements[i].text != NULL; ++i) {
1327 ctx->conn_.prepareStatement(tagged_statements[i]);
1342 ctx->conn_.makeReconnectCtl(timer_name_);
1349 std::stringstream tmp;
1352 tmp <<
", library " << PQlibVersion();
1358 StatementIndex stindex,
1360 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
1361 tagged_statements[stindex].nbparams,
1366 int s = PQresultStatus(r);
1368 if (s != PGRES_COMMAND_OK) {
1375 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
1384 .arg(lease->addr_.toText());
1387 PgSqlLeaseContextAlloc get_context(*
this);
1391 ctx->exchange4_->createBindForSend(lease, bind_array);
1392 auto result = addLeaseCommon(ctx,
INSERT_LEASE4, bind_array);
1396 lease->updateCurrentExpirationTime();
1404 .arg(lease->addr_.toText())
1408 PgSqlLeaseContextAlloc get_context(*
this);
1412 ctx->exchange6_->createBindForSend(lease, bind_array);
1414 auto result = addLeaseCommon(ctx,
INSERT_LEASE6, bind_array);
1418 lease->updateCurrentExpirationTime();
1423template <
typename Exchange,
typename LeaseCollection>
1426 StatementIndex stindex,
1429 LeaseCollection& result,
1430 bool single)
const {
1431 const int n = tagged_statements[stindex].nbparams;
1433 tagged_statements[stindex].name, n,
1434 n > 0 ? &bind_array.
values_[0] : NULL,
1435 n > 0 ? &bind_array.
lengths_[0] : NULL,
1436 n > 0 ? &bind_array.
formats_[0] : NULL, 0));
1438 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
1440 int rows = PQntuples(r);
1441 if (single && rows > 1) {
1443 "database where only one was expected for query "
1444 << tagged_statements[stindex].name);
1447 for(
int i = 0; i < rows; ++ i) {
1448 result.push_back(exchange->convertFromDatabase(r, i));
1462 getLeaseCollection(ctx, stindex, bind_array, ctx->exchange4_,
1466 if (collection.empty()) {
1469 result = *collection.begin();
1483 getLeaseCollection(ctx, stindex, bind_array, ctx->exchange6_,
1487 if (collection.empty()) {
1490 result = *collection.begin();
1503 std::string addr_str = boost::lexical_cast<std::string>(addr.
toUint32());
1504 bind_array.
add(addr_str);
1510 PgSqlLeaseContextAlloc get_context(*
this);
1527 if (!hwaddr.
hwaddr_.empty()) {
1537 PgSqlLeaseContextAlloc get_context(*
this);
1555 if (!hwaddr.
hwaddr_.empty()) {
1562 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
1563 bind_array.
add(subnet_id_str);
1569 PgSqlLeaseContextAlloc get_context(*
this);
1592 PgSqlLeaseContextAlloc get_context(*
this);
1613 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
1614 bind_array.
add(subnet_id_str);
1620 PgSqlLeaseContextAlloc get_context(*
this);
1637 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
1638 bind_array.
add(subnet_id_str);
1644 PgSqlLeaseContextAlloc get_context(*
this);
1661 bind_array.
add(hostname);
1667 PgSqlLeaseContextAlloc get_context(*
this);
1685 PgSqlLeaseContextAlloc get_context(*
this);
1688 getLeaseCollection(ctx,
GET_LEASE4, bind_array, result);
1697 if (!lower_bound_address.
isV4()) {
1699 "retrieving leases from the lease database, got "
1700 << lower_bound_address);
1705 .arg(lower_bound_address.
toText());
1711 std::string lb_address_data = boost::lexical_cast<std::string>(lower_bound_address.
toUint32());
1712 bind_array.
add(lb_address_data);
1715 std::string page_size_data = boost::lexical_cast<std::string>(page_size.
page_size_);
1716 bind_array.
add(page_size_data);
1722 PgSqlLeaseContextAlloc get_context(*
this);
1741 std::string addr_str = addr.
toText();
1742 bind_array.
add(addr_str);
1745 std::string type_str_ = boost::lexical_cast<std::string>(lease_type);
1746 bind_array.
add(type_str_);
1752 PgSqlLeaseContextAlloc get_context(*
this);
1762 uint32_t iaid)
const {
1776 bind_array.
add(iaid_str);
1779 std::string lease_type_str = boost::lexical_cast<std::string>(lease_type);
1780 bind_array.
add(lease_type_str);
1786 PgSqlLeaseContextAlloc get_context(*
this);
1796 uint32_t iaid,
SubnetID subnet_id)
const {
1807 std::string lease_type_str = boost::lexical_cast<std::string>(lease_type);
1808 bind_array.
add(lease_type_str);
1815 bind_array.
add(iaid_str);
1818 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
1819 bind_array.
add(subnet_id_str);
1825 PgSqlLeaseContextAlloc get_context(*
this);
1842 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
1843 bind_array.
add(subnet_id_str);
1849 PgSqlLeaseContextAlloc get_context(*
this);
1870 PgSqlLeaseContextAlloc get_context(*
this);
1888 bind_array.
add(hostname);
1894 PgSqlLeaseContextAlloc get_context(*
this);
1912 PgSqlLeaseContextAlloc get_context(*
this);
1915 getLeaseCollection(ctx,
GET_LEASE6, bind_array, result);
1924 if (!lower_bound_address.
isV6()) {
1926 "retrieving leases from the lease database, got "
1927 << lower_bound_address);
1932 .arg(lower_bound_address.
toText());
1940 std::string lb_address_data =
"0";
1941 if (!lower_bound_address.
isV6Zero()) {
1942 lb_address_data = lower_bound_address.
toText();
1946 bind_array.
add(lb_address_data);
1949 std::string page_size_data = boost::lexical_cast<std::string>(page_size.
page_size_);
1950 bind_array.
add(page_size_data);
1956 PgSqlLeaseContextAlloc get_context(*
this);
1966 const size_t max_leases)
const {
1974 const size_t max_leases)
const {
1980template<
typename LeaseCollection>
1982PgSqlLeaseMgr::getExpiredLeasesCommon(LeaseCollection& expired_leases,
1983 const size_t max_leases,
1984 StatementIndex statement_index)
const {
1989 bind_array.
add(state_str);
1993 bind_array.
add(timestamp_str);
1997 uint32_t limit = max_leases > 0 ?
static_cast<uint32_t
>(max_leases) :
1998 std::numeric_limits<uint32_t>::max();
1999 std::string limit_str = boost::lexical_cast<std::string>(limit);
2000 bind_array.
add(limit_str);
2003 PgSqlLeaseContextAlloc get_context(*
this);
2007 getLeaseCollection(ctx, statement_index, bind_array, expired_leases);
2010template<
typename LeasePtr>
2013 StatementIndex stindex,
2016 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
2017 tagged_statements[stindex].nbparams,
2022 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
2024 int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
2027 if (affected_rows == 1) {
2032 if (affected_rows == 0) {
2034 lease->addr_.toText() <<
" as it does not exist");
2040 "that had the address " << lease->addr_.toText());
2048 .arg(lease->addr_.toText());
2051 PgSqlLeaseContextAlloc get_context(*
this);
2056 ctx->exchange4_->createBindForSend(lease, bind_array);
2059 std::string addr4_str = boost::lexical_cast<std::string>(lease->addr_.toUint32());
2060 bind_array.
add(addr4_str);
2063 lease->current_valid_lft_);
2064 bind_array.
add(expire_str);
2067 updateLeaseCommon(ctx, stindex, bind_array, lease);
2070 lease->updateCurrentExpirationTime();
2078 .arg(lease->addr_.toText())
2082 PgSqlLeaseContextAlloc get_context(*
this);
2087 ctx->exchange6_->createBindForSend(lease, bind_array);
2090 std::string addr_str = lease->addr_.
toText();
2091 bind_array.
add(addr_str);
2094 lease->current_valid_lft_);
2095 bind_array.
add(expire_str);
2098 updateLeaseCommon(ctx, stindex, bind_array, lease);
2101 lease->updateCurrentExpirationTime();
2105PgSqlLeaseMgr::deleteLeaseCommon(StatementIndex stindex,
2108 PgSqlLeaseContextAlloc get_context(*
this);
2111 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
2112 tagged_statements[stindex].nbparams,
2117 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
2118 int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
2120 return (affected_rows);
2132 std::string addr4_str = boost::lexical_cast<std::string>(addr.
toUint32());
2133 bind_array.
add(addr4_str);
2136 lease->current_valid_lft_);
2137 bind_array.
add(expire_str);
2139 auto affected_rows = deleteLeaseCommon(
DELETE_LEASE4, bind_array);
2142 if (affected_rows == 1) {
2147 if (affected_rows == 0) {
2154 "that had the address " << lease->addr_.toText());
2167 std::string addr6_str = addr.
toText();
2168 bind_array.
add(addr6_str);
2171 lease->current_valid_lft_);
2172 bind_array.
add(expire_str);
2174 auto affected_rows = deleteLeaseCommon(
DELETE_LEASE6, bind_array);
2177 if (affected_rows == 1) {
2182 if (affected_rows == 0) {
2189 "that had the address " << lease->addr_.toText());
2207PgSqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(
const uint32_t secs,
2208 StatementIndex statement_index) {
2213 bind_array.
add(state_str);
2217 static_cast<time_t
>(secs));
2218 bind_array.
add(expiration_str);
2221 return (deleteLeaseCommon(statement_index, bind_array));
2227 PgSqlLeaseContextAlloc get_context(*
this);
2240 PgSqlLeaseContextAlloc get_context(*
this);
2255 PgSqlLeaseContextAlloc get_context(*
this);
2270 PgSqlLeaseContextAlloc get_context(*
this);
2283 PgSqlLeaseContextAlloc get_context(*
this);
2298 PgSqlLeaseContextAlloc get_context(*
this);
2323 PgSqlLeaseContextAlloc get_context(*
this);
2326 std::string name =
"";
2328 name = ctx->conn_.getParameter(
"name");
2337 return (std::string(
"PostgreSQL Database"));
2340std::pair<uint32_t, uint32_t>
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 a function is not implemented.
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
std::string toText() const
Convert the address to a string.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
bool isV6() const
Convenience function to check for an IPv6 address.
bool isV4() const
Convenience function to check for an IPv4 address.
bool isV6Zero() const
Convenience function to check if it is an IPv4 zero address.
static bool invokeDbLostCallback(const ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's lost connectivity callback.
static bool invokeDbFailedCallback(const ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's restore failed connectivity callback.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
static bool invokeDbRecoveredCallback(const ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's restored connectivity callback.
Exception thrown on failure to open database.
Exception thrown on failure to execute a database function.
Invalid address family used as input to Lease Manager.
Multiple lease records found where one expected.
Common PgSql Connector Pool.
static const char DUPLICATE_KEY[]
Define the PgSql error state for a duplicate key error.
static std::pair< uint32_t, uint32_t > getVersion(const ParameterMap ¶meters)
Get the schema version.
void checkStatementError(const PgSqlResult &r, PgSqlTaggedStatement &statement)
Checks result of the r object.
Base class for marshalling data to and from PostgreSQL.
static const char * getRawColumnValue(const PgSqlResult &r, const int row, const size_t col)
Gets a pointer to the raw column value in a result set row.
static std::string convertToDatabaseTime(const time_t input_time)
Converts time_t value to a text representation in local time.
static std::string getColumnLabel(const PgSqlResult &r, const size_t col)
Fetches the name of the column in a result set.
static void convertFromBytea(const PgSqlResult &r, const int row, const size_t col, uint8_t *buffer, const size_t buffer_size, size_t &bytes_converted)
Converts a column in a row in a result set to a binary bytes.
static void getColumnValue(const PgSqlResult &r, const int row, const size_t col, std::string &value)
Fetches text column value as a string.
static time_t convertFromDatabaseTime(const std::string &db_time_val)
Converts time stamp from the database to a time_t.
std::vector< std::string > columns_
Stores text labels for columns, currently only used for logging and errors.
static isc::asiolink::IOAddress getIPv6Value(const PgSqlResult &r, const int row, const size_t col)
Converts a column in a row in a result set into IPv6 address.
RAII wrapper for PostgreSQL Result sets.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Holds Client identifier or client IPv4 address.
static const size_t MAX_CLIENT_ID_LEN
Maximum size of a client ID.
const std::vector< uint8_t > & getClientId() const
Returns reference to the client-id data.
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Holds DUID (DHCPv6 Unique Identifier)
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
static const size_t MAX_DUID_LEN
maximum duid size As defined in RFC 8415, section 11.1
const std::vector< uint8_t > & getDuid() const
Returns a const reference to the actual DUID value.
static void create(const std::string &dbaccess)
Create an instance of a lease manager.
static void destroy()
Destroy lease manager.
static isc::asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service.
Wraps value holding size of the page with leases.
const size_t page_size_
Holds page size.
Base class for fulfilling a statistical lease data query.
SubnetID getLastSubnetID() const
Returns the value of last subnet ID specified (or zero)
SubnetID getFirstSubnetID() const
Returns the value of first subnet ID specified (or zero)
SelectMode getSelectMode() const
Returns the selection criteria mode The value returned is based upon the constructor variant used and...
Attempt to update lease that was not there.
Supports exchanging IPv4 leases with PostgreSQL.
Lease4Ptr convertFromDatabase(const PgSqlResult &r, int row)
Creates a Lease4 object from a given row in a result set.
PgSqlLease4Exchange()
Constructor.
void createBindForSend(const Lease4Ptr &lease, PsqlBindArray &bind_array)
Creates the bind array for sending Lease4 data to the database.
Supports exchanging IPv6 leases with PostgreSQL.
void createBindForSend(const Lease6Ptr &lease, PsqlBindArray &bind_array)
Creates the bind array for sending Lease6 data to the database.
void getLeaseTypeColumnValue(const PgSqlResult &r, const int row, const size_t col, Lease6::Type &value) const
Fetches an integer text column as a Lease6::Type.
Lease6Ptr convertFromDatabase(const PgSqlResult &r, int row)
Creates a Lease6 object from a given row in a result set.
PostgreSQL Lease Context Pool.
PostgreSQL Lease Context.
PgSqlLeaseContext(const db::DatabaseConnection::ParameterMap ¶meters, db::IOServiceAccessorPtr io_service_accessor, db::DbCallback db_reconnect_callback)
Constructor.
Base class for marshalling leases to and from PostgreSQL.
std::string valid_lifetime_str_
uint8_t hwaddr_buffer_[HWAddr::MAX_HWADDR_LEN]
virtual ~PgSqlLeaseExchange()
std::string subnet_id_str_
std::vector< uint8_t > hwaddr_
std::string user_context_
std::string addr_str_
Common Instance members used for binding and conversion.
PostgreSQL Lease Manager.
virtual std::string getName() const
Returns backend name.
virtual bool addLease(const Lease4Ptr &lease)
Adds an IPv4 lease.
virtual Lease6Collection getLeases6() const
Returns all IPv6 leases.
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.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const
Returns an IPv4 lease for specified IPv4 address.
virtual void rollback()
Rollback Transactions.
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const
Returns existing IPv6 lease for a given IPv6 address.
PgSqlLeaseContextPtr createContext() const
Create a new context.
virtual bool deleteLease(const Lease4Ptr &lease)
Deletes an IPv4 lease.
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.
static std::string getDBVersion()
Local version of getDBVersion() class method.
virtual Lease4Collection getLeases4() const
Returns all IPv4 leases.
virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs)
Deletes all expired-reclaimed DHCPv4 leases.
virtual void updateLease4(const Lease4Ptr &lease4)
Updates IPv4 lease.
virtual size_t wipeLeases4(const SubnetID &subnet_id)
Removes specified IPv4 leases.
virtual std::pair< uint32_t, uint32_t > getVersion() const
Returns backend version.
virtual void updateLease6(const Lease6Ptr &lease6)
Updates IPv6 lease.
virtual LeaseStatsQueryPtr startLeaseStatsQuery6()
Creates and runs the IPv6 lease stats query.
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs)
Deletes all expired-reclaimed DHCPv6 leases.
virtual std::string getDescription() const
Returns description of the backend.
StatementIndex
Statement Tags.
@ SUBNET_RANGE_LEASE4_STATS
@ SUBNET_RANGE_LEASE6_STATS
@ GET_LEASE6_DUID_IAID_SUBID
@ GET_LEASE4_HWADDR_SUBID
@ GET_LEASE4_CLIENTID_SUBID
@ DELETE_LEASE6_STATE_EXPIRED
@ DELETE_LEASE4_STATE_EXPIRED
virtual void commit()
Commit Transactions.
PgSqlLeaseMgr(const db::DatabaseConnection::ParameterMap ¶meters)
Constructor.
virtual size_t wipeLeases6(const SubnetID &subnet_id)
Removed specified IPv6 leases.
virtual void getExpiredLeases6(Lease6Collection &expired_leases, const size_t max_leases) const
Returns a collection of expired DHCPv6 leases.
virtual LeaseStatsQueryPtr startLeaseStatsQuery4()
Creates and runs the IPv4 lease stats query.
static bool dbReconnect(db::ReconnectCtlPtr db_reconnect_ctl)
Attempts to reconnect the server to the lease DB backend manager.
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID &subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
virtual ~PgSqlLeaseMgr()
Destructor (closes database)
virtual void getExpiredLeases4(Lease4Collection &expired_leases, const size_t max_leases) const
Returns a collection of expired DHCPv4 leases.
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID &subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
Base PgSql derivation of the statistical lease data query.
bool fetch_type_
Indicates if query supplies lease type.
boost::shared_ptr< PgSqlResult > result_set_
The result set returned by Postgres.
PgSqlLeaseStatsQuery(PgSqlConnection &conn, PgSqlTaggedStatement &statement, 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.
PgSqlConnection & conn_
Database connection to use to execute the query.
virtual ~PgSqlLeaseStatsQuery()
Destructor.
PgSqlTaggedStatement & statement_
The query's prepared statement.
static bool negative_count_
Received negative state count showing a problem.
bool getNextRow(LeaseStatsRow &row)
Fetches the next row in the result set.
PgSqlLeaseStatsQuery(PgSqlConnection &conn, PgSqlTaggedStatement &statement, const bool fetch_type)
Constructor to query for all subnets' stats.
PgSqlLeaseStatsQuery(PgSqlConnection &conn, PgSqlTaggedStatement &statement, const bool fetch_type, const SubnetID &subnet_id)
Constructor to query for a single subnet's stats.
void start()
Creates the lease statistical data result set.
uint32_t next_row_
Index of the next row to fetch.
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
RAII class creating a critical section.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
static const uint32_t HWADDR_SOURCE_UNKNOWN
Used when actual origin is not known, e.g.
#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_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< const Element > ConstElementPtr
std::function< bool(ReconnectCtlPtr db_reconnect_ctl)> DbCallback
Defines a callback prototype for propagating events upward.
const uint32_t PG_SCHEMA_VERSION_MAJOR
Define PostgreSQL backend version: 6.2.
boost::shared_ptr< IOServiceAccessor > IOServiceAccessorPtr
Pointer to an instance of IOServiceAccessor.
const uint32_t PG_SCHEMA_VERSION_MINOR
const size_t OID_NONE
Constants for PostgreSQL data types These are defined by PostgreSQL in <catalog/pg_type....
const size_t OID_TIMESTAMP
std::function< isc::asiolink::IOServicePtr()> IOServiceAccessor
Function which returns the IOService that can be used to recover the connection.
boost::shared_ptr< ReconnectCtl > ReconnectCtlPtr
Pointer to an instance of ReconnectCtl.
const isc::log::MessageID DHCPSRV_PGSQL_GET_SUBID4
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
const isc::log::MessageID DHCPSRV_PGSQL_ADD_ADDR4
const isc::log::MessageID DHCPSRV_PGSQL_GET_SUBID_CLIENTID
const isc::log::MessageID DHCPSRV_PGSQL_GET_ADDR6
const isc::log::MessageID DHCPSRV_PGSQL_GET_DUID
const isc::log::MessageID DHCPSRV_PGSQL_GET6
const isc::log::MessageID DHCPSRV_PGSQL_GET_SUBID6
const isc::log::MessageID DHCPSRV_PGSQL_GET_PAGE4
boost::shared_ptr< CfgDbAccess > CfgDbAccessPtr
A pointer to the CfgDbAccess.
boost::shared_ptr< DUID > DuidPtr
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
const isc::log::MessageID DHCPSRV_PGSQL_GET_HOSTNAME6
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
boost::shared_ptr< LeaseStatsQuery > LeaseStatsQueryPtr
Defines a pointer to a LeaseStatsQuery.
const isc::log::MessageID DHCPSRV_PGSQL_GET_IAID_SUBID_DUID
const isc::log::MessageID DHCPSRV_PGSQL_GET_ADDR4
const isc::log::MessageID DHCPSRV_PGSQL_GET_HOSTNAME4
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
const isc::log::MessageID DHCPSRV_PGSQL_ROLLBACK
const isc::log::MessageID DHCPSRV_PGSQL_GET_HWADDR
const isc::log::MessageID DHCPSRV_PGSQL_GET_PAGE6
const isc::log::MessageID DHCPSRV_PGSQL_DELETE_EXPIRED_RECLAIMED4
const isc::log::MessageID DHCPSRV_PGSQL_UPDATE_ADDR4
const isc::log::MessageID DHCPSRV_PGSQL_GET_SUBID_HWADDR
const isc::log::MessageID DHCPSRV_PGSQL_GET_VERSION
const isc::log::MessageID DHCPSRV_PGSQL_LEASE_DB_RECONNECT_ATTEMPT_FAILED
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
boost::shared_ptr< Lease > LeasePtr
Pointer to the lease object.
const isc::log::MessageID DHCPSRV_PGSQL_GET4
const isc::log::MessageID DHCPSRV_PGSQL_ADD_ADDR6
const isc::log::MessageID DHCPSRV_PGSQL_GET_CLIENTID
const isc::log::MessageID DHCPSRV_PGSQL_GET_IAID_DUID
const isc::log::MessageID DHCPSRV_PGSQL_UPDATE_ADDR6
boost::shared_ptr< PgSqlLeaseContext > PgSqlLeaseContextPtr
Type of pointers to contexts.
const isc::log::MessageID DHCPSRV_PGSQL_LEASE_DB_RECONNECT_FAILED
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
@ HTYPE_UNDEFINED
not specified or undefined
@ HTYPE_ETHER
Ethernet 10Mbps.
const isc::log::MessageID DHCPSRV_PGSQL_NEGATIVE_LEASES_STAT
const isc::log::MessageID DHCPSRV_PGSQL_GET_EXPIRED4
const isc::log::MessageID DHCPSRV_PGSQL_GET_EXPIRED6
const isc::log::MessageID DHCPSRV_PGSQL_LEASE_DB_RECONNECT_ATTEMPT_SCHEDULE
const isc::log::MessageID DHCPSRV_PGSQL_DELETE_ADDR
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
const isc::log::MessageID DHCPSRV_PGSQL_COMMIT
const isc::log::MessageID DHCPSRV_PGSQL_DELETE_EXPIRED_RECLAIMED6
Defines the logger used by the top-level component of kea-lfc.
Define a PostgreSQL statement.
const char * name
Short name of the query.
std::vector< int > formats_
Vector of "format" for each value.
void add(const char *value)
Adds a char array to bind array based.
size_t size() const
Fetches the number of entries in the array.
std::vector< const char * > values_
Vector of pointers to the data values.
std::string toText() const
Dumps the contents of the array to a string.
std::vector< int > lengths_
Vector of data lengths for each value.
Hardware type that represents information from DHCPv4 packet.
static const size_t MAX_HWADDR_LEN
Maximum size of a hardware address.
std::vector< uint8_t > hwaddr_
std::string toText(bool include_htype=true) const
Returns textual representation of a hardware address (e.g.
Structure that holds a lease for IPv6 address and/or prefix.
Contains a single row of lease statistical data.
int64_t state_count_
state_count The count of leases in the lease state
uint32_t lease_state_
The lease_state to which the count applies.
SubnetID subnet_id_
The subnet ID to which this data applies.
Lease::Type lease_type_
The lease_type to which the count applies.
static const uint32_t INFINITY_LFT
Infinity (means static, i.e. never expire)
static const uint32_t STATE_EXPIRED_RECLAIMED
Expired and reclaimed lease.
Type
Type of lease or pool.
@ TYPE_TA
the lease contains temporary IPv6 address
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
@ TYPE_NA
the lease contains non-temporary IPv6 address
Union for marshalling IAID into and out of the database IAID is defined in the RFC as 4 octets,...
Uiaid(uint32_t val)
Constructor.
std::string dbInputString()
Return a string representing the signed 32-bit value.
Uiaid(int32_t val)
Constructor.