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 = cast($1 as inet) 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, relay_id, remote_id, pool_id "
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, relay_id, remote_id, pool_id "
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, relay_id, remote_id, pool_id "
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, relay_id, remote_id, pool_id "
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, relay_id, remote_id, pool_id "
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, relay_id, remote_id, pool_id "
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, relay_id, remote_id, pool_id "
133 "WHERE address > $1 "
139 "get_lease4_uctx_page",
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, relay_id, remote_id, pool_id "
145 "WHERE address > $1 AND user_context IS NOT NULL "
152 "SELECT address, hwaddr, client_id, "
153 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
154 "fqdn_fwd, fqdn_rev, hostname, "
155 "state, user_context, relay_id, remote_id, pool_id "
157 "WHERE subnet_id = $1" },
161 "get_lease4_hostname",
162 "SELECT address, hwaddr, client_id, "
163 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
164 "fqdn_fwd, fqdn_rev, hostname, "
165 "state, user_context, relay_id, remote_id, pool_id "
167 "WHERE lower(hostname) = $1" },
172 "SELECT address, hwaddr, client_id, "
173 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
174 "fqdn_fwd, fqdn_rev, hostname, "
175 "state, user_context, relay_id, remote_id, pool_id "
177 "WHERE state != $1 AND valid_lifetime != 4294967295 AND expire < $2 "
183 "get_lease4_relayid",
184 "SELECT address, hwaddr, client_id, "
185 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
186 "fqdn_fwd, fqdn_rev, hostname, "
187 "state, user_context, relay_id, remote_id, pool_id "
189 "WHERE relay_id = $1 and address > $2 "
195 "get_lease4_relayid_qst",
196 "SELECT address, hwaddr, client_id, "
197 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
198 "fqdn_fwd, fqdn_rev, hostname, "
199 "state, user_context, relay_id, remote_id, pool_id "
201 "WHERE relay_id = $1 and address > $2 "
202 "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
203 "THEN 0 ELSE valid_lifetime END) >= $3 "
209 "get_lease4_relayid_qset",
210 "SELECT address, hwaddr, client_id, "
211 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
212 "fqdn_fwd, fqdn_rev, hostname, "
213 "state, user_context, relay_id, remote_id, pool_id "
215 "WHERE relay_id = $1 and address > $2 "
216 "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
217 "THEN 0 ELSE valid_lifetime END) >= $3 "
218 "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
219 "THEN 0 ELSE valid_lifetime END) <= $4 "
225 "get_lease4_relayid_qet",
226 "SELECT address, hwaddr, client_id, "
227 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
228 "fqdn_fwd, fqdn_rev, hostname, "
229 "state, user_context, relay_id, remote_id, pool_id "
231 "WHERE relay_id = $1 and address > $2 "
232 "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
233 "THEN 0 ELSE valid_lifetime END) <= $3 "
239 "get_lease4_remoteid",
240 "SELECT address, hwaddr, client_id, "
241 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
242 "fqdn_fwd, fqdn_rev, hostname, "
243 "state, user_context, relay_id, remote_id, pool_id "
245 "WHERE remote_id = $1 and address > $2 "
251 "get_lease4_remoteid_qst",
252 "SELECT address, hwaddr, client_id, "
253 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
254 "fqdn_fwd, fqdn_rev, hostname, "
255 "state, user_context, relay_id, remote_id, pool_id "
257 "WHERE remote_id = $1 and address > $2 "
258 "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
259 "THEN 0 ELSE valid_lifetime END) >= $3 "
265 "get_lease4_remoteid_qset",
266 "SELECT address, hwaddr, client_id, "
267 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
268 "fqdn_fwd, fqdn_rev, hostname, "
269 "state, user_context, relay_id, remote_id, pool_id "
271 "WHERE remote_id = $1 and address > $2 "
272 "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
273 "THEN 0 ELSE valid_lifetime END) >= $3 "
274 "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
275 "THEN 0 ELSE valid_lifetime END) <= $4 "
281 "get_lease4_remoteid_qet",
282 "SELECT address, hwaddr, client_id, "
283 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
284 "fqdn_fwd, fqdn_rev, hostname, "
285 "state, user_context, relay_id, remote_id, pool_id "
287 "WHERE remote_id = $1 and address > $2 "
288 "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
289 "THEN 0 ELSE valid_lifetime END) <= $3 "
296 "SELECT host(address), duid, valid_lifetime, "
297 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
298 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
299 "hwaddr, hwtype, hwaddr_source, "
300 "state, user_context, pool_id "
302 "ORDER BY address "},
307 "SELECT host(address), duid, valid_lifetime, "
308 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
309 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
310 "hwaddr, hwtype, hwaddr_source, "
311 "state, user_context, pool_id "
313 "WHERE address = cast($1 as inet) AND lease_type = $2"},
317 "get_lease6_duid_iaid",
318 "SELECT host(address), duid, valid_lifetime, "
319 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
320 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
321 "hwaddr, hwtype, hwaddr_source, "
322 "state, user_context, pool_id "
324 "WHERE duid = $1 AND iaid = $2 AND lease_type = $3" },
328 "get_lease6_duid_iaid_subid",
329 "SELECT host(address), duid, valid_lifetime, "
330 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
331 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
332 "hwaddr, hwtype, hwaddr_source, "
333 "state, user_context, pool_id "
335 "WHERE lease_type = $1 "
336 "AND duid = $2 AND iaid = $3 AND subnet_id = $4" },
341 "SELECT host(address), duid, valid_lifetime, "
342 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
343 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
344 "hwaddr, hwtype, hwaddr_source, "
345 "state, user_context, pool_id "
347 "WHERE address > cast($1 as inet) "
353 "get_lease6_uctx_page",
354 "SELECT host(address), duid, valid_lifetime, "
355 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
356 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
357 "hwaddr, hwtype, hwaddr_source, "
358 "state, user_context, pool_id "
360 "WHERE address > cast($1 as inet) AND user_context IS NOT NULL "
367 "SELECT host(address), duid, valid_lifetime, "
368 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
369 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
370 "hwaddr, hwtype, hwaddr_source, "
371 "state, user_context, pool_id "
373 "WHERE subnet_id = $1" },
378 "SELECT host(address), duid, valid_lifetime, "
379 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
380 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
381 "hwaddr, hwtype, hwaddr_source, "
382 "state, user_context, pool_id "
388 "get_lease6_hostname",
389 "SELECT host(address), duid, valid_lifetime, "
390 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
391 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
392 "hwaddr, hwtype, hwaddr_source, "
393 "state, user_context, pool_id "
395 "WHERE lower(hostname) = $1" },
400 "SELECT host(address), duid, valid_lifetime, "
401 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
402 "lease_type, iaid, prefix_len, "
403 "fqdn_fwd, fqdn_rev, hostname, "
404 "hwaddr, hwtype, hwaddr_source, "
405 "state, user_context, pool_id "
407 "WHERE state != $1 AND valid_lifetime != 4294967295 AND expire < $2 "
414 "SELECT host(address), duid, valid_lifetime, "
415 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
416 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
417 "hwaddr, hwtype, hwaddr_source, "
418 "state, user_context, pool_id "
420 "WHERE address BETWEEN cast($1 as inet) and cast($2 as inet) "
429 "INSERT INTO lease4(address, hwaddr, client_id, "
430 "valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, "
431 "state, user_context, relay_id, remote_id, pool_id) "
432 "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)" },
440 "INSERT INTO lease6(address, duid, valid_lifetime, "
441 "expire, subnet_id, pref_lifetime, "
442 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
443 "hwaddr, hwtype, hwaddr_source, "
444 "state, user_context, pool_id) "
445 "VALUES (cast($1 as inet), $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)" },
452 "UPDATE lease4 SET address = $1, hwaddr = $2, "
453 "client_id = $3, valid_lifetime = $4, expire = $5, "
454 "subnet_id = $6, fqdn_fwd = $7, fqdn_rev = $8, hostname = $9, "
455 "state = $10, user_context = $11, relay_id = $12, remote_id = $13, pool_id = $14 "
456 "WHERE address = $15 AND expire = $16" },
464 "UPDATE lease6 SET address = cast($1 as inet), duid = $2, "
465 "valid_lifetime = $3, expire = $4, subnet_id = $5, "
466 "pref_lifetime = $6, lease_type = $7, iaid = $8, "
467 "prefix_len = $9, fqdn_fwd = $10, fqdn_rev = $11, hostname = $12, "
468 "hwaddr = $13, hwtype = $14, hwaddr_source = $15, "
469 "state = $16, user_context = $17, pool_id = $18 "
470 "WHERE address = cast($19 as inet) AND expire = $20" },
475 "SELECT subnet_id, state, leases as state_count"
476 " FROM lease4_stat ORDER BY subnet_id, state" },
480 "subnet_lease4_stats",
481 "SELECT subnet_id, state, leases as state_count"
483 " WHERE subnet_id = $1 "
488 "subnet_range_lease4_stats",
489 "SELECT subnet_id, state, leases as state_count"
491 " WHERE subnet_id >= $1 and subnet_id <= $2 "
492 " ORDER BY subnet_id, state" },
496 "all_pool_lease4_stats",
497 "SELECT subnet_id, pool_id, state, leases as state_count"
498 " FROM lease4_pool_stat ORDER BY subnet_id, pool_id, state" },
503 "SELECT subnet_id, lease_type, state, leases as state_count"
504 " FROM lease6_stat ORDER BY subnet_id, lease_type, state" },
508 "subnet_lease6_stats",
509 "SELECT subnet_id, lease_type, state, leases as state_count"
511 " WHERE subnet_id = $1 "
512 " ORDER BY lease_type, state" },
516 "subnet_range_lease6_stats",
517 "SELECT subnet_id, lease_type, state, leases as state_count"
519 " WHERE subnet_id >= $1 and subnet_id <= $2 "
520 " ORDER BY subnet_id, lease_type, state" },
524 "all_pool_lease6_stats",
525 "SELECT subnet_id, pool_id, lease_type, state, leases as state_count"
526 " FROM lease6_pool_stat ORDER BY subnet_id, pool_id, lease_type, state" },
530 "check_lease4_limits",
531 "SELECT checkLease4Limits($1)" },
535 "check_lease6_limits",
536 "SELECT checkLease6Limits($1)" },
541 "SELECT isJsonSupported()" },
545 "get_lease4_count_by_class",
547 "FROM lease4_stat_by_client_class "
548 "WHERE client_class = $1" },
552 "get_lease6_count_by_class",
554 "FROM lease6_stat_by_client_class "
555 "WHERE client_class = $1 AND lease_type = $2" },
560 "DELETE FROM lease6_relay_id" },
565 "DELETE FROM lease6_remote_id" },
570 "DELETE FROM lease6_relay_id WHERE lease_addr = cast($1 as inet)" },
575 "DELETE FROM lease6_remote_id WHERE lease_addr = cast($1 as inet)" },
580 "INSERT INTO lease6_relay_id(relay_id, lease_addr) "
581 "VALUES ($1, cast($2 as inet))" },
586 "INSERT INTO lease6_remote_id(remote_id, lease_addr) "
587 "VALUES ($1, cast($2 as inet))" },
592 "SELECT DISTINCT ON(l.address) "
593 "host(l.address), l.duid, l.valid_lifetime, "
594 "extract(epoch from l.expire)::bigint, l.subnet_id, l.pref_lifetime, "
595 "l.lease_type, l.iaid, l.prefix_len, l.fqdn_fwd, l.fqdn_rev, "
596 "l.hostname, l.hwaddr, l.hwtype, l.hwaddr_source, "
597 "l.state, l.user_context, l.pool_id "
599 "INNER JOIN lease6_relay_id AS r "
600 " ON l.address = r.lease_addr "
601 " WHERE r.relay_id = $1 AND r.lease_addr > cast($2 as inet) "
602 "ORDER BY l.address "
608 "SELECT DISTINCT ON(l.address) "
609 "host(l.address), l.duid, l.valid_lifetime, "
610 "extract(epoch from l.expire)::bigint, l.subnet_id, l.pref_lifetime, "
611 "l.lease_type, l.iaid, l.prefix_len, l.fqdn_fwd, l.fqdn_rev, "
612 "l.hostname, l.hwaddr, l.hwtype, l.hwaddr_source, "
613 "l.state, l.user_context, l.pool_id "
615 "INNER JOIN lease6_remote_id AS r "
616 " ON l.address = r.lease_addr "
617 " WHERE r.remote_id = $1 AND r.lease_addr > cast($2 as inet) "
618 "ORDER BY l.address "
623 "get_relay_id6_link",
624 "SELECT DISTINCT ON(l.address) "
625 "host(l.address), l.duid, l.valid_lifetime, "
626 "extract(epoch from l.expire)::bigint, l.subnet_id, l.pref_lifetime, "
627 "l.lease_type, l.iaid, l.prefix_len, l.fqdn_fwd, l.fqdn_rev, "
628 "l.hostname, l.hwaddr, l.hwtype, l.hwaddr_source, "
629 "l.state, l.user_context, l.pool_id "
631 "INNER JOIN lease6_relay_id AS r "
632 " ON l.address = r.lease_addr "
633 " WHERE r.relay_id = $1 AND r.lease_addr "
634 "BETWEEN cast($2 as inet) and cast($3 as inet) "
635 "ORDER BY l.address "
640 "get_remote_id6_link",
641 "SELECT DISTINCT ON(l.address) "
642 "host(l.address), l.duid, l.valid_lifetime, "
643 "extract(epoch from l.expire)::bigint, l.subnet_id, l.pref_lifetime, "
644 "l.lease_type, l.iaid, l.prefix_len, l.fqdn_fwd, l.fqdn_rev, "
645 "l.hostname, l.hwaddr, l.hwtype, l.hwaddr_source, "
646 "l.state, l.user_context, l.pool_id "
648 "INNER JOIN lease6_remote_id AS r "
649 " ON l.address = r.lease_addr "
650 " WHERE r.remote_id = $1 AND r.lease_addr "
651 "BETWEEN cast($2 as inet) and cast($3 as inet) "
652 "ORDER BY l.address "
658 "SELECT COUNT(*) FROM lease6_relay_id" },
663 "SELECT COUNT(*) FROM lease6_remote_id" },
683 : addr_str_(
""), hwaddr_length_(0), hwaddr_(hwaddr_length_),
684 valid_lifetime_(0), valid_lifetime_str_(
""), expire_(0),
685 expire_str_(
""), subnet_id_(0), subnet_id_str_(
""), pool_id_(0),
686 pool_id_str_(
""), cltt_(0), fqdn_fwd_(false), fqdn_rev_(false),
687 hostname_(
""), state_str_(
""), user_context_(
""), addr_bin_(16) {
699 uint8_t hwaddr_buffer_[HWAddr::MAX_HWADDR_LEN];
727 static const size_t ADDRESS_COL = 0;
728 static const size_t HWADDR_COL = 1;
729 static const size_t CLIENT_ID_COL = 2;
730 static const size_t VALID_LIFETIME_COL = 3;
731 static const size_t EXPIRE_COL = 4;
732 static const size_t SUBNET_ID_COL = 5;
733 static const size_t FQDN_FWD_COL = 6;
734 static const size_t FQDN_REV_COL = 7;
735 static const size_t HOSTNAME_COL = 8;
736 static const size_t STATE_COL = 9;
737 static const size_t USER_CONTEXT_COL = 10;
738 static const size_t RELAY_ID_COL = 11;
739 static const size_t REMOTE_ID_COL = 12;
740 static const size_t POOL_ID_COL = 13;
742 static const size_t LEASE_COLUMNS = 14;
749 : lease_(), addr4_(0), client_id_length_(0),
750 relay_id_length_(0), remote_id_length_(0) {
752 BOOST_STATIC_ASSERT(13 < LEASE_COLUMNS);
754 memset(hwaddr_buffer_, 0,
sizeof(hwaddr_buffer_));
755 memset(client_id_buffer_, 0,
sizeof(client_id_buffer_));
756 memset(relay_id_buffer_, 0,
sizeof(relay_id_buffer_));
757 memset(remote_id_buffer_, 0,
sizeof(remote_id_buffer_));
760 columns_.push_back(
"address");
761 columns_.push_back(
"hwaddr");
762 columns_.push_back(
"client_id");
763 columns_.push_back(
"valid_lifetime");
764 columns_.push_back(
"expire");
765 columns_.push_back(
"subnet_id");
766 columns_.push_back(
"fqdn_fwd");
767 columns_.push_back(
"fqdn_rev");
768 columns_.push_back(
"hostname");
769 columns_.push_back(
"state");
770 columns_.push_back(
"user_context");
771 columns_.push_back(
"relay_id");
772 columns_.push_back(
"remote_id");
773 columns_.push_back(
"pool_id");
797 addr_str_ = boost::lexical_cast<std::string>(lease->addr_.toUint32());
798 bind_array.
add(addr_str_);
800 if (lease->hwaddr_ && !lease->hwaddr_->hwaddr_.empty()) {
803 if (lease->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
805 << lease_->hwaddr_->hwaddr_.size()
806 <<
" exceeds maximum allowed of: "
807 << HWAddr::MAX_HWADDR_LEN);
809 bind_array.
add(lease->hwaddr_->hwaddr_);
814 if (lease->client_id_) {
815 bind_array.
add(lease->client_id_->getClientId());
820 valid_lifetime_str_ = boost::lexical_cast<std::string>(lease->valid_lft_);
821 bind_array.
add(valid_lifetime_str_);
829 if (lease_->valid_lft_ == Lease::INFINITY_LFT) {
830 expire_str_ = convertToDatabaseTime(lease->cltt_, 0);
832 expire_str_ = convertToDatabaseTime(lease->cltt_,
835 bind_array.
add(expire_str_);
837 subnet_id_str_ = boost::lexical_cast<std::string>(lease->subnet_id_);
838 bind_array.
add(subnet_id_str_);
840 bind_array.
add(lease->fqdn_fwd_);
842 bind_array.
add(lease->fqdn_rev_);
844 bind_array.
add(lease->hostname_);
846 state_str_ = boost::lexical_cast<std::string>(lease->state_);
847 bind_array.
add(state_str_);
851 user_context_ = ctx->str();
855 bind_array.
add(user_context_);
857 if (!lease->relay_id_.empty()) {
858 bind_array.
add(lease->relay_id_);
863 if (!lease->remote_id_.empty()) {
864 bind_array.
add(lease->remote_id_);
869 pool_id_str_ = boost::lexical_cast<std::string>(lease->pool_id_);
870 bind_array.
add(pool_id_str_);
871 }
catch (
const std::exception& ex) {
873 "Could not create bind array from Lease4: "
874 << lease_->addr_.toText() <<
", reason: " << ex.
what());
888 getColumnValue(r, row, ADDRESS_COL, addr4_);
890 convertFromBytea(r, row, HWADDR_COL, hwaddr_buffer_,
891 sizeof(hwaddr_buffer_), hwaddr_length_);
893 convertFromBytea(r, row, CLIENT_ID_COL, client_id_buffer_,
894 sizeof(client_id_buffer_), client_id_length_);
896 getColumnValue(r, row, VALID_LIFETIME_COL, valid_lifetime_);
898 expire_ = convertFromDatabaseTime(getRawColumnValue(r, row,
901 getColumnValue(r, row, SUBNET_ID_COL, subnet_id_);
904 if (valid_lifetime_ == Lease::INFINITY_LFT) {
907 cltt_ = expire_ - valid_lifetime_;
910 getColumnValue(r, row, FQDN_FWD_COL, fqdn_fwd_);
912 getColumnValue(r, row, FQDN_REV_COL, fqdn_rev_);
914 hostname_ = getRawColumnValue(r, row, HOSTNAME_COL);
917 getColumnValue(r, row, STATE_COL, state);
922 user_context_ = getRawColumnValue(r, row, USER_CONTEXT_COL);
924 if (!user_context_.empty()) {
925 ctx = Element::fromJSON(user_context_);
926 if (!ctx || (ctx->getType() != Element::map)) {
928 <<
"' is not a JSON map");
932 convertFromBytea(r, row, RELAY_ID_COL, relay_id_buffer_,
933 sizeof(relay_id_buffer_), relay_id_length_);
935 convertFromBytea(r, row, REMOTE_ID_COL, remote_id_buffer_,
936 sizeof(remote_id_buffer_), remote_id_length_);
938 getColumnValue(r, row, POOL_ID_COL, pool_id_);
940 Lease4Ptr result(boost::make_shared<Lease4>(addr4_, hwaddr,
943 valid_lifetime_, cltt_,
944 subnet_id_, fqdn_fwd_,
945 fqdn_rev_, hostname_));
947 result->state_ = state;
950 result->setContext(ctx);
953 if (relay_id_length_) {
954 result->relay_id_.assign(relay_id_buffer_,
955 relay_id_buffer_ + relay_id_length_);
958 if (remote_id_length_) {
959 result->remote_id_.assign(remote_id_buffer_,
960 remote_id_buffer_ + remote_id_length_);
963 result->pool_id_ = pool_id_;
966 }
catch (
const std::exception& ex) {
968 "Could not convert data to Lease4, reason: "
982 size_t client_id_length_;
983 uint8_t client_id_buffer_[ClientId::MAX_CLIENT_ID_LEN];
984 size_t relay_id_length_;
985 uint8_t relay_id_buffer_[ClientId::MAX_CLIENT_ID_LEN];
986 size_t remote_id_length_;
987 uint8_t remote_id_buffer_[ClientId::MAX_CLIENT_ID_LEN];
999 static const size_t ADDRESS_COL = 0;
1000 static const size_t DUID_COL = 1;
1001 static const size_t VALID_LIFETIME_COL = 2;
1002 static const size_t EXPIRE_COL = 3;
1003 static const size_t SUBNET_ID_COL = 4;
1004 static const size_t PREF_LIFETIME_COL = 5;
1005 static const size_t LEASE_TYPE_COL = 6;
1006 static const size_t IAID_COL = 7;
1007 static const size_t PREFIX_LEN_COL = 8;
1008 static const size_t FQDN_FWD_COL = 9;
1009 static const size_t FQDN_REV_COL = 10;
1010 static const size_t HOSTNAME_COL = 11;
1011 static const size_t HWADDR_COL = 12;
1012 static const size_t HWTYPE_COL = 13;
1013 static const size_t HWADDR_SOURCE_COL = 14;
1014 static const size_t STATE_COL = 15;
1015 static const size_t USER_CONTEXT_COL = 16;
1016 static const size_t POOL_ID_COL = 17;
1018 static const size_t LEASE_COLUMNS = 18;
1040 return (boost::lexical_cast<std::string>(ival_));
1048 : lease_(), duid_length_(0), duid_(duid_length_), iaid_u_(0),
1049 iaid_str_(
""), lease_type_(
Lease6::TYPE_NA), lease_type_str_(
""),
1050 prefix_len_(0), prefix_len_str_(
""), pref_lifetime_(0),
1051 preferred_lifetime_str_(
""), hwtype_(0), hwtype_str_(
""),
1052 hwaddr_source_(0), hwaddr_source_str_(
"") {
1054 BOOST_STATIC_ASSERT(17 < LEASE_COLUMNS);
1056 memset(duid_buffer_, 0,
sizeof(duid_buffer_));
1059 columns_.push_back(
"address");
1060 columns_.push_back(
"duid");
1061 columns_.push_back(
"valid_lifetime");
1062 columns_.push_back(
"expire");
1063 columns_.push_back(
"subnet_id");
1064 columns_.push_back(
"pref_lifetime");
1065 columns_.push_back(
"lease_type");
1066 columns_.push_back(
"iaid");
1067 columns_.push_back(
"prefix_len");
1068 columns_.push_back(
"fqdn_fwd");
1069 columns_.push_back(
"fqdn_rev");
1070 columns_.push_back(
"hostname");
1071 columns_.push_back(
"hwaddr");
1072 columns_.push_back(
"hwtype");
1073 columns_.push_back(
"hwaddr_source");
1074 columns_.push_back(
"state");
1075 columns_.push_back(
"user_context");
1076 columns_.push_back(
"pool_id");
1099 addr_str_ = lease_->addr_.toText();
1100 bind_array.
add(addr_str_);
1102 if (lease_->duid_) {
1103 bind_array.
add(lease_->duid_->getDuid());
1108 valid_lifetime_str_ = boost::lexical_cast<std::string>(lease->valid_lft_);
1109 bind_array.
add(valid_lifetime_str_);
1117 if (lease_->valid_lft_ == Lease::INFINITY_LFT) {
1118 expire_str_ = convertToDatabaseTime(lease->cltt_, 0);
1120 expire_str_ = convertToDatabaseTime(lease->cltt_,
1121 lease_->valid_lft_);
1123 bind_array.
add(expire_str_);
1125 subnet_id_str_ = boost::lexical_cast<std::string>(lease->subnet_id_);
1126 bind_array.
add(subnet_id_str_);
1128 preferred_lifetime_str_ = boost::lexical_cast<std::string>(lease_->preferred_lft_);
1129 bind_array.
add(preferred_lifetime_str_);
1131 lease_type_str_ = boost::lexical_cast<std::string>(lease_->type_);
1132 bind_array.
add(lease_type_str_);
1137 iaid_u_.uval_ = lease_->iaid_;
1138 iaid_str_ = iaid_u_.dbInputString();
1139 bind_array.
add(iaid_str_);
1141 prefix_len_str_ = boost::lexical_cast<std::string>
1142 (
static_cast<unsigned int>(lease_->prefixlen_));
1143 bind_array.
add(prefix_len_str_);
1145 bind_array.
add(lease->fqdn_fwd_);
1147 bind_array.
add(lease->fqdn_rev_);
1149 bind_array.
add(lease->hostname_);
1151 if (lease->hwaddr_ && !lease->hwaddr_->hwaddr_.empty()) {
1154 if (lease->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
1156 << lease_->hwaddr_->hwaddr_.size()
1157 <<
" exceeds maximum allowed of: "
1158 << HWAddr::MAX_HWADDR_LEN);
1160 bind_array.
add(lease->hwaddr_->hwaddr_);
1165 if (lease->hwaddr_) {
1166 hwtype_str_ = boost::lexical_cast<std::string>
1167 (
static_cast<unsigned int>(lease_->hwaddr_->htype_));
1168 hwaddr_source_str_ = boost::lexical_cast<std::string>
1169 (
static_cast<unsigned int>(lease_->hwaddr_->source_));
1171 hwtype_str_ = boost::lexical_cast<std::string>
1173 hwaddr_source_str_ = boost::lexical_cast<std::string>
1174 (
static_cast<unsigned int>(HWAddr::HWADDR_SOURCE_UNKNOWN));
1177 bind_array.
add(hwtype_str_);
1179 bind_array.
add(hwaddr_source_str_);
1181 state_str_ = boost::lexical_cast<std::string>(lease->state_);
1182 bind_array.
add(state_str_);
1186 user_context_ = ctx->str();
1190 bind_array.
add(user_context_);
1192 pool_id_str_ = boost::lexical_cast<std::string>(lease->pool_id_);
1193 bind_array.
add(pool_id_str_);
1194 }
catch (
const std::exception& ex) {
1196 "Could not create bind array from Lease6: "
1197 << lease_->addr_.toText() <<
", reason: " << ex.
what());
1220 IOAddress addr(getIPv6Value(r, row, ADDRESS_COL));
1222 convertFromBytea(r, row, DUID_COL, duid_buffer_,
sizeof(duid_buffer_), duid_length_);
1223 DuidPtr duid_ptr(
new DUID(duid_buffer_, duid_length_));
1225 getColumnValue(r, row, VALID_LIFETIME_COL, valid_lifetime_);
1227 expire_ = convertFromDatabaseTime(getRawColumnValue(r, row,
1231 if (valid_lifetime_ == Lease::INFINITY_LFT) {
1234 cltt_ = expire_ - valid_lifetime_;
1237 getColumnValue(r, row, SUBNET_ID_COL, subnet_id_);
1239 getColumnValue(r, row, PREF_LIFETIME_COL, pref_lifetime_);
1241 getLeaseTypeColumnValue(r, row, LEASE_TYPE_COL, lease_type_);
1243 getColumnValue(r, row, IAID_COL, iaid_u_.ival_);
1245 getColumnValue(r, row, PREFIX_LEN_COL, prefix_len_);
1247 getColumnValue(r, row, FQDN_FWD_COL, fqdn_fwd_);
1249 getColumnValue(r, row, FQDN_REV_COL, fqdn_rev_);
1251 hostname_ = getRawColumnValue(r, row, HOSTNAME_COL);
1253 convertFromBytea(r, row, HWADDR_COL, hwaddr_buffer_,
1254 sizeof(hwaddr_buffer_), hwaddr_length_);
1256 getColumnValue(r, row, HWTYPE_COL, hwtype_);
1258 getColumnValue(r, row, HWADDR_SOURCE_COL, hwaddr_source_);
1262 if (hwaddr_length_) {
1263 hwaddr.reset(
new HWAddr(hwaddr_buffer_, hwaddr_length_,
1266 hwaddr->source_ = hwaddr_source_;
1270 getColumnValue(r, row, STATE_COL, state);
1272 user_context_ = getRawColumnValue(r, row, USER_CONTEXT_COL);
1274 if (!user_context_.empty()) {
1275 ctx = Element::fromJSON(user_context_);
1276 if (!ctx || (ctx->getType() != Element::map)) {
1278 <<
"' is not a JSON map");
1282 getColumnValue(r, row, POOL_ID_COL, pool_id_);
1284 if (lease_type_ != Lease::TYPE_PD) {
1288 Lease6Ptr result(boost::make_shared<Lease6>(lease_type_, addr,
1293 subnet_id_, fqdn_fwd_,
1294 fqdn_rev_, hostname_,
1295 hwaddr, prefix_len_));
1297 result->cltt_ = cltt_;
1298 result->current_cltt_ = cltt_;
1300 result->state_ = state;
1303 result->setContext(ctx);
1306 result->pool_id_ = pool_id_;
1309 }
catch (
const std::exception& ex) {
1311 "Could not convert data to Lease6, reason: "
1330 uint32_t raw_value = 0;
1331 getColumnValue(r, row, col, raw_value);
1332 switch (raw_value) {
1333 case Lease6::TYPE_NA:
1334 case Lease6::TYPE_TA:
1335 case Lease6::TYPE_PD:
1341 <<
" for: " << getColumnLabel(r, col) <<
" row:" << row);
1353 size_t duid_length_;
1354 std::vector<uint8_t> duid_;
1355 uint8_t duid_buffer_[DUID::MAX_DUID_LEN];
1356 union Uiaid iaid_u_;
1357 std::string iaid_str_;
1359 std::string lease_type_str_;
1360 uint8_t prefix_len_;
1361 std::string prefix_len_str_;
1362 uint32_t pref_lifetime_;
1363 std::string preferred_lifetime_str_;
1365 std::string hwtype_str_;
1366 uint32_t hwaddr_source_;
1367 std::string hwaddr_source_str_;
1389 const bool fetch_type,
const bool fetch_pool =
false)
1390 : conn_(conn), statement_(statement), result_set_(), next_row_(0),
1391 fetch_type_(fetch_type), fetch_pool_(fetch_pool) {
1403 const bool fetch_type,
const SubnetID& subnet_id)
1404 :
LeaseStatsQuery(subnet_id), conn_(conn), statement_(statement), result_set_(),
1405 next_row_(0), fetch_type_(fetch_type), fetch_pool_(false) {
1419 const bool fetch_type,
const SubnetID& first_subnet_id,
1421 :
LeaseStatsQuery(first_subnet_id, last_subnet_id), conn_(conn), statement_(statement),
1422 result_set_(), next_row_(0), fetch_type_(fetch_type), fetch_pool_(false) {
1439 if (getSelectMode() == ALL_SUBNETS || getSelectMode() == ALL_SUBNET_POOLS) {
1441 result_set_.reset(
new PgSqlResult(PQexecPrepared(conn_, statement_.name,
1448 parms.
addTempString(boost::lexical_cast<std::string>(getFirstSubnetID()));
1451 if (getSelectMode() == SUBNET_RANGE) {
1453 parms.
addTempString(boost::lexical_cast<std::string>(getLastSubnetID()));
1457 result_set_.reset(
new PgSqlResult(PQexecPrepared(conn_, statement_.name,
1462 conn_.checkStatementError(*result_set_, statement_);
1481 if (next_row_ >= result_set_->getRows()) {
1488 PgSqlExchange::getColumnValue(*result_set_, next_row_, col, subnet_id);
1494 PgSqlExchange::getColumnValue(*result_set_, next_row_, col,
1501 uint32_t lease_type;
1502 PgSqlExchange::getColumnValue(*result_set_, next_row_, col,
1511 PgSqlExchange::getColumnValue(*result_set_, next_row_, col,
1516 PgSqlExchange::getColumnValue(*result_set_, next_row_, col,
1522 if (!negative_count_) {
1523 negative_count_ =
true;
1558 bool PgSqlLeaseStatsQuery::negative_count_ =
false;
1565 : conn_(parameters, io_service_accessor, db_reconnect_callback) {
1570 PgSqlLeaseMgr::PgSqlLeaseContextAlloc::PgSqlLeaseContextAlloc(
1573 if (MultiThreadingMgr::instance().getMode()) {
1577 lock_guard<mutex> lock(mgr_.pool_->mutex_);
1578 if (!mgr_.pool_->pool_.empty()) {
1579 ctx_ = mgr_.pool_->pool_.back();
1580 mgr_.pool_->pool_.pop_back();
1584 ctx_ = mgr_.createContext();
1588 if (mgr_.pool_->pool_.empty()) {
1591 ctx_ = mgr_.pool_->pool_.back();
1595 PgSqlLeaseMgr::PgSqlLeaseContextAlloc::~PgSqlLeaseContextAlloc() {
1596 if (MultiThreadingMgr::instance().getMode()) {
1598 lock_guard<mutex> lock(mgr_.pool_->mutex_);
1599 mgr_.pool_->pool_.push_back(ctx_);
1606 PgSqlLeaseMgr::PgSqlLeaseTrackingContextAlloc::PgSqlLeaseTrackingContextAlloc(
1609 if (MultiThreadingMgr::instance().getMode()) {
1613 lock_guard<mutex> lock(mgr_.pool_->mutex_);
1614 if (mgr_.hasCallbacks() && !mgr_.tryLock(lease)) {
1617 if (!mgr_.pool_->pool_.empty()) {
1618 ctx_ = mgr_.pool_->pool_.back();
1619 mgr_.pool_->pool_.pop_back();
1623 ctx_ = mgr_.createContext();
1627 if (mgr_.pool_->pool_.empty()) {
1630 ctx_ = mgr_.pool_->pool_.back();
1634 PgSqlLeaseMgr::PgSqlLeaseTrackingContextAlloc::~PgSqlLeaseTrackingContextAlloc() {
1635 if (MultiThreadingMgr::instance().getMode()) {
1637 lock_guard<mutex> lock(mgr_.pool_->mutex_);
1638 if (mgr_.hasCallbacks()) {
1639 mgr_.unlock(lease_);
1641 mgr_.pool_->pool_.push_back(ctx_);
1655 timer_name_ =
"PgSqlLeaseMgr[";
1656 timer_name_ += boost::lexical_cast<std::string>(
reinterpret_cast<uint64_t
>(
this));
1657 timer_name_ +=
"]DbReconnectTimer";
1661 tls += parameters.count(
"trust-anchor");
1662 tls += parameters.count(
"cert-file");
1663 tls += parameters.count(
"key-file");
1664 tls += parameters.count(
"cipher-list");
1665 #ifdef HAVE_PGSQL_SSL
1677 <<
"backend (built with this feature disabled)");
1684 std::pair<uint32_t, uint32_t> db_version =
getVersion();
1685 if (code_version != db_version) {
1687 "PostgreSQL schema version mismatch: need version: "
1688 << code_version.first <<
"." << code_version.second
1689 <<
" found version: " << db_version.first <<
"."
1690 << db_version.second);
1710 bool reopened =
false;
1712 const std::string timer_name = db_reconnect_ctl->timerName();
1719 }
catch (
const std::exception& ex) {
1735 if (!db_reconnect_ctl->checkRetries()) {
1738 .arg(db_reconnect_ctl->maxRetries());
1751 .arg(db_reconnect_ctl->maxRetries() - db_reconnect_ctl->retriesLeft() + 1)
1752 .arg(db_reconnect_ctl->maxRetries())
1753 .arg(db_reconnect_ctl->retryInterval());
1759 db_reconnect_ctl->retryInterval(),
1777 ctx->conn_.openDatabase();
1781 for (; tagged_statements[i].text != NULL; ++i) {
1782 ctx->conn_.prepareStatement(tagged_statements[i]);
1797 ctx->conn_.makeReconnectCtl(timer_name_);
1804 std::stringstream tmp;
1807 tmp <<
", library " << PQlibVersion();
1813 StatementIndex stindex,
1815 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
1816 tagged_statements[stindex].nbparams,
1821 int s = PQresultStatus(r);
1823 if (s != PGRES_COMMAND_OK) {
1830 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
1839 .arg(lease->addr_.toText());
1842 PgSqlLeaseTrackingContextAlloc get_context(*
this, lease);
1846 ctx->exchange4_->createBindForSend(lease, bind_array);
1847 auto result = addLeaseCommon(ctx,
INSERT_LEASE4, bind_array);
1851 lease->updateCurrentExpirationTime();
1864 .arg(lease->addr_.toText())
1870 PgSqlLeaseTrackingContextAlloc get_context(*
this, lease);
1874 ctx->exchange6_->createBindForSend(lease, bind_array);
1876 auto result = addLeaseCommon(ctx,
INSERT_LEASE6, bind_array);
1880 lease->updateCurrentExpirationTime();
1894 template <
typename Exchange,
typename LeaseCollection>
1897 StatementIndex stindex,
1900 LeaseCollection& result,
1901 bool single)
const {
1902 const int n = tagged_statements[stindex].nbparams;
1904 tagged_statements[stindex].name, n,
1905 n > 0 ? &bind_array.
values_[0] : NULL,
1906 n > 0 ? &bind_array.
lengths_[0] : NULL,
1907 n > 0 ? &bind_array.
formats_[0] : NULL, 0));
1909 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
1911 int rows = PQntuples(r);
1912 if (single && rows > 1) {
1914 "database where only one was expected for query "
1915 << tagged_statements[stindex].name);
1918 for(
int i = 0; i < rows; ++i) {
1919 result.push_back(exchange->convertFromDatabase(r, i));
1933 getLeaseCollection(ctx, stindex, bind_array, ctx->exchange4_,
1937 if (collection.empty()) {
1940 result = *collection.begin();
1954 getLeaseCollection(ctx, stindex, bind_array, ctx->exchange6_,
1958 if (collection.empty()) {
1961 result = *collection.begin();
1974 std::string addr_str = boost::lexical_cast<std::string>(addr.
toUint32());
1975 bind_array.
add(addr_str);
1981 PgSqlLeaseContextAlloc get_context(*
this);
1998 if (!hwaddr.
hwaddr_.empty()) {
2008 PgSqlLeaseContextAlloc get_context(*
this);
2026 if (!hwaddr.
hwaddr_.empty()) {
2033 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
2034 bind_array.
add(subnet_id_str);
2040 PgSqlLeaseContextAlloc get_context(*
this);
2063 PgSqlLeaseContextAlloc get_context(*
this);
2084 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
2085 bind_array.
add(subnet_id_str);
2091 PgSqlLeaseContextAlloc get_context(*
this);
2108 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
2109 bind_array.
add(subnet_id_str);
2115 PgSqlLeaseContextAlloc get_context(*
this);
2132 bind_array.
add(hostname);
2138 PgSqlLeaseContextAlloc get_context(*
this);
2156 PgSqlLeaseContextAlloc get_context(*
this);
2159 getLeaseCollection(ctx,
GET_LEASE4, bind_array, result);
2168 if (!lower_bound_address.
isV4()) {
2170 "retrieving leases from the lease database, got "
2171 << lower_bound_address);
2176 .arg(lower_bound_address.
toText());
2182 std::string lb_address_data = boost::lexical_cast<std::string>(lower_bound_address.
toUint32());
2183 bind_array.
add(lb_address_data);
2186 std::string page_size_data = boost::lexical_cast<std::string>(page_size.
page_size_);
2187 bind_array.
add(page_size_data);
2193 PgSqlLeaseContextAlloc get_context(*
this);
2212 std::string addr_str = addr.
toText();
2213 bind_array.
add(addr_str);
2216 std::string type_str_ = boost::lexical_cast<std::string>(lease_type);
2217 bind_array.
add(type_str_);
2223 PgSqlLeaseContextAlloc get_context(*
this);
2233 uint32_t iaid)
const {
2247 bind_array.
add(iaid_str);
2250 std::string lease_type_str = boost::lexical_cast<std::string>(lease_type);
2251 bind_array.
add(lease_type_str);
2257 PgSqlLeaseContextAlloc get_context(*
this);
2267 uint32_t iaid,
SubnetID subnet_id)
const {
2278 std::string lease_type_str = boost::lexical_cast<std::string>(lease_type);
2279 bind_array.
add(lease_type_str);
2286 bind_array.
add(iaid_str);
2289 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
2290 bind_array.
add(subnet_id_str);
2296 PgSqlLeaseContextAlloc get_context(*
this);
2313 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
2314 bind_array.
add(subnet_id_str);
2320 PgSqlLeaseContextAlloc get_context(*
this);
2341 PgSqlLeaseContextAlloc get_context(*
this);
2359 bind_array.
add(hostname);
2365 PgSqlLeaseContextAlloc get_context(*
this);
2383 PgSqlLeaseContextAlloc get_context(*
this);
2386 getLeaseCollection(ctx,
GET_LEASE6, bind_array, result);
2395 if (!lower_bound_address.
isV6()) {
2397 "retrieving leases from the lease database, got "
2398 << lower_bound_address);
2403 .arg(lower_bound_address.
toText());
2409 std::string lb_address_data = lower_bound_address.
toText();
2410 bind_array.
add(lb_address_data);
2413 std::string page_size_data =
2414 boost::lexical_cast<std::string>(page_size.
page_size_);
2415 bind_array.
add(page_size_data);
2421 PgSqlLeaseContextAlloc get_context(*
this);
2431 const size_t max_leases)
const {
2439 const size_t max_leases)
const {
2445 template<
typename LeaseCollection>
2447 PgSqlLeaseMgr::getExpiredLeasesCommon(LeaseCollection& expired_leases,
2448 const size_t max_leases,
2449 StatementIndex statement_index)
const {
2454 bind_array.
add(state_str);
2458 bind_array.
add(timestamp_str);
2462 uint32_t limit = max_leases > 0 ?
static_cast<uint32_t
>(max_leases) :
2463 std::numeric_limits<uint32_t>::max();
2464 std::string limit_str = boost::lexical_cast<std::string>(limit);
2465 bind_array.
add(limit_str);
2468 PgSqlLeaseContextAlloc get_context(*
this);
2472 getLeaseCollection(ctx, statement_index, bind_array, expired_leases);
2475 template<
typename LeasePtr>
2478 StatementIndex stindex,
2481 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
2482 tagged_statements[stindex].nbparams,
2487 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
2489 int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
2492 if (affected_rows == 1) {
2497 if (affected_rows == 0) {
2499 lease->addr_.toText() <<
" as it does not exist");
2505 "that had the address " << lease->addr_.toText());
2513 .arg(lease->addr_.toText());
2516 PgSqlLeaseTrackingContextAlloc get_context(*
this, lease);
2521 ctx->exchange4_->createBindForSend(lease, bind_array);
2524 std::string addr4_str = boost::lexical_cast<std::string>(lease->addr_.toUint32());
2525 bind_array.
add(addr4_str);
2527 std::string expire_str;
2533 lease->current_valid_lft_);
2535 bind_array.
add(expire_str);
2538 updateLeaseCommon(ctx, stindex, bind_array, lease);
2541 lease->updateCurrentExpirationTime();
2554 .arg(lease->addr_.toText())
2562 PgSqlLeaseTrackingContextAlloc get_context(*
this, lease);
2567 ctx->exchange6_->createBindForSend(lease, bind_array);
2570 std::string addr_str = lease->addr_.
toText();
2571 bind_array.
add(addr_str);
2573 std::string expire_str;
2579 lease->current_valid_lft_);
2581 bind_array.
add(expire_str);
2584 updateLeaseCommon(ctx, stindex, bind_array, lease);
2587 lease->updateCurrentExpirationTime();
2591 switch (recorded_action) {
2614 StatementIndex stindex,
2616 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
2617 tagged_statements[stindex].nbparams,
2622 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
2623 int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
2625 return (affected_rows);
2637 std::string addr4_str = boost::lexical_cast<std::string>(addr.
toUint32());
2638 bind_array.
add(addr4_str);
2640 std::string expire_str;
2646 lease->current_valid_lft_);
2648 bind_array.
add(expire_str);
2651 PgSqlLeaseTrackingContextAlloc get_context(*
this, lease);
2654 auto affected_rows = deleteLeaseCommon(ctx,
DELETE_LEASE4, bind_array);
2657 if (affected_rows == 1) {
2665 if (affected_rows == 0) {
2672 "that had the address " << lease->addr_.toText());
2687 std::string addr6_str = addr.
toText();
2688 bind_array.
add(addr6_str);
2690 std::string expire_str;
2696 lease->current_valid_lft_);
2698 bind_array.
add(expire_str);
2701 PgSqlLeaseTrackingContextAlloc get_context(*
this, lease);
2704 auto affected_rows = deleteLeaseCommon(ctx,
DELETE_LEASE6, bind_array);
2707 if (affected_rows == 1) {
2719 if (affected_rows == 0) {
2726 "that had the address " << lease->addr_.toText());
2744 PgSqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(
const uint32_t secs,
2745 StatementIndex statement_index) {
2750 bind_array.
add(state_str);
2754 static_cast<time_t
>(secs));
2755 bind_array.
add(expiration_str);
2758 PgSqlLeaseContextAlloc get_context(*
this);
2762 return (deleteLeaseCommon(ctx, statement_index, bind_array));
2766 PgSqlLeaseMgr::checkLimits(
ConstElementPtr const& user_context, StatementIndex
const stindex)
const {
2768 if (!user_context) {
2773 PgSqlLeaseContextAlloc get_context(*
this);
2778 std::string
const user_context_str(user_context->str());
2779 bind_array.
add(user_context_str);
2783 tagged_statements[stindex].name,
2784 tagged_statements[stindex].nbparams,
2788 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
2808 PgSqlLeaseContextAlloc get_context(*
this);
2813 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
2815 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
2817 bool json_supported;
2819 return json_supported;
2826 PgSqlLeaseContextAlloc get_context(*
this);
2831 bind_array.
add(client_class);
2833 bind_array.
add(ltype);
2840 tagged_statements[stindex].name,
2841 tagged_statements[stindex].nbparams,
2845 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
2847 int rows = PQntuples(r);
2886 PgSqlLeaseContextAlloc get_context(*
this);
2899 PgSqlLeaseContextAlloc get_context(*
this);
2912 PgSqlLeaseContextAlloc get_context(*
this);
2927 PgSqlLeaseContextAlloc get_context(*
this);
2942 PgSqlLeaseContextAlloc get_context(*
this);
2955 PgSqlLeaseContextAlloc get_context(*
this);
2968 PgSqlLeaseContextAlloc get_context(*
this);
2983 PgSqlLeaseContextAlloc get_context(*
this);
3008 PgSqlLeaseContextAlloc get_context(*
this);
3011 std::string name =
"";
3013 name = ctx->conn_.getParameter(
"name");
3022 return (std::string(
"PostgreSQL Database"));
3025 std::pair<uint32_t, uint32_t>
3044 deleteRelayId6(addr);
3045 deleteRemoteId6(addr);
3049 PgSqlLeaseMgr::deleteRelayId6(
const IOAddress& addr) {
3053 std::string addr_data = addr.
toText();
3054 bind_array.
add(addr_data);
3057 PgSqlLeaseContextAlloc get_context(*
this);
3063 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
3064 tagged_statements[stindex].nbparams,
3069 int s = PQresultStatus(r);
3071 if (s != PGRES_COMMAND_OK) {
3072 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
3077 PgSqlLeaseMgr::deleteRemoteId6(
const IOAddress& addr) {
3081 std::string addr_data = addr.
toText();
3082 bind_array.
add(addr_data);
3085 PgSqlLeaseContextAlloc get_context(*
this);
3091 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
3092 tagged_statements[stindex].nbparams,
3097 int s = PQresultStatus(r);
3099 if (s != PGRES_COMMAND_OK) {
3100 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
3106 const vector<uint8_t>& relay_id) {
3111 if (relay_id.empty()) {
3114 bind_array.
add(relay_id);
3117 std::string lease_addr_data = lease_addr.
toText();
3118 bind_array.
add(lease_addr_data);
3121 PgSqlLeaseContextAlloc get_context(*
this);
3127 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
3128 tagged_statements[stindex].nbparams,
3133 int s = PQresultStatus(r);
3135 if (s != PGRES_COMMAND_OK) {
3136 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
3142 const vector<uint8_t>& remote_id) {
3147 if (remote_id.empty()) {
3150 bind_array.
add(remote_id);
3153 std::string lease_addr_data = lease_addr.
toText();
3154 bind_array.
add(lease_addr_data);
3157 PgSqlLeaseContextAlloc get_context(*
this);
3163 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
3164 tagged_statements[stindex].nbparams,
3169 int s = PQresultStatus(r);
3171 if (s != PGRES_COMMAND_OK) {
3172 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
3180 std::stringstream tmp;
3183 for (std::vector<uint8_t>::const_iterator it =
id.begin();
3184 it !=
id.end(); ++it) {
3188 tmp << std::setw(2) << std::setfill(
'0')
3189 <<
static_cast<unsigned int>(*it);
3201 const time_t& qry_start_time ,
3202 const time_t& qry_end_time ) {
3204 if (!lower_bound_address.
isV4()) {
3206 "retrieving leases from the lease database, got "
3207 << lower_bound_address);
3211 if ((qry_start_time < 0) || (qry_end_time < 0)) {
3215 bool have_qst = (qry_start_time > 0);
3216 bool have_qet = (qry_end_time > 0);
3219 if (have_qst && have_qet && (qry_start_time > qry_end_time)) {
3226 .arg(lower_bound_address.
toText())
3227 .arg(idToText(relay_id))
3228 .arg(qry_start_time)
3235 if (!relay_id.empty()) {
3236 bind_array.
add(relay_id);
3242 std::string lb_address_data =
3243 boost::lexical_cast<std::string>(lower_bound_address.
toUint32());
3244 bind_array.
add(lb_address_data);
3247 std::string start_time_str;
3249 start_time_str = boost::lexical_cast<std::string>(qry_start_time);
3250 bind_array.
add(start_time_str);
3254 std::string end_time_str;
3256 end_time_str = boost::lexical_cast<std::string>(qry_end_time);
3257 bind_array.
add(end_time_str);
3261 std::string page_size_data =
3262 boost::lexical_cast<std::string>(page_size.
page_size_);
3263 bind_array.
add(page_size_data);
3266 if (have_qst && !have_qet) {
3268 }
else if (have_qst && have_qet) {
3270 }
else if (!have_qst && have_qet) {
3278 PgSqlLeaseContextAlloc get_context(*
this);
3281 getLeaseCollection(ctx, stindex, bind_array, result);
3290 const time_t& qry_start_time ,
3291 const time_t& qry_end_time ) {
3293 if (!lower_bound_address.
isV4()) {
3295 "retrieving leases from the lease database, got "
3296 << lower_bound_address);
3300 if ((qry_start_time < 0) || (qry_end_time < 0)) {
3304 bool have_qst = (qry_start_time > 0);
3305 bool have_qet = (qry_end_time > 0);
3308 if (have_qst && have_qet && (qry_start_time > qry_end_time)) {
3315 .arg(lower_bound_address.
toText())
3316 .arg(idToText(remote_id))
3317 .arg(qry_start_time)
3324 if (!remote_id.empty()) {
3325 bind_array.
add(remote_id);
3331 std::string lb_address_data =
3332 boost::lexical_cast<std::string>(lower_bound_address.
toUint32());
3333 bind_array.
add(lb_address_data);
3336 std::string start_time_str;
3338 start_time_str = boost::lexical_cast<std::string>(qry_start_time);
3339 bind_array.
add(start_time_str);
3343 std::string end_time_str;
3345 end_time_str = boost::lexical_cast<std::string>(qry_end_time);
3346 bind_array.
add(end_time_str);
3350 std::string page_size_data =
3351 boost::lexical_cast<std::string>(page_size.
page_size_);
3352 bind_array.
add(page_size_data);
3355 if (have_qst && !have_qet) {
3357 }
else if (have_qst && have_qet) {
3359 }
else if (!have_qst && have_qet) {
3367 PgSqlLeaseContextAlloc get_context(*
this);
3370 getLeaseCollection(ctx, stindex, bind_array, result);
3378 getConsistency()->getExtendedInfoSanityCheck();
3387 .arg(start_addr.
toText())
3394 uint32_t start_addr_data = start_addr.
toUint32();
3395 bind_array.
add(start_addr_data);
3398 std::string page_size_data =
3399 boost::lexical_cast<std::string>(page_size.
page_size_);
3400 bind_array.
add(page_size_data);
3406 PgSqlLeaseContextAlloc get_context(*
this);
3412 if (leases.empty()) {
3418 start_addr = leases.back()->addr_;
3419 for (
auto lease : leases) {
3421 vector<uint8_t> previous_relay_id = lease->relay_id_;
3422 vector<uint8_t> previous_remote_id = lease->remote_id_;
3423 if (!previous_user_context &&
3424 previous_relay_id.empty() &&
3425 previous_remote_id.empty()) {
3430 lease->relay_id_.clear();
3431 lease->remote_id_.clear();
3434 (previous_relay_id != lease->relay_id_) ||
3435 (previous_remote_id != lease->remote_id_)) {
3443 }
catch (
const std::exception& ex) {
3447 .arg(lease->addr_.toText())
3469 .arg(lower_bound_address.
toText())
3472 .arg(
static_cast<unsigned>(link_len));
3475 if (!link_addr.
isV6()) {
3477 "retrieving leases from the lease database, got "
3480 if (link_len > 128) {
3482 <<
static_cast<unsigned>(link_len));
3484 if (!lower_bound_address.
isV6()) {
3486 "retrieving leases from the lease database, got "
3487 << lower_bound_address);
3490 std::vector<uint8_t> relay_id_data = relay_id.
getDuid();
3491 if (relay_id_data.size() == 0) {
3502 bind_array.
add(relay_id_data);
3505 std::string lb_addr_data = lower_bound_address.
toText();
3506 bind_array.
add(lb_addr_data);
3509 std::string page_size_data =
3510 boost::lexical_cast<std::string>(page_size.
page_size_);
3511 bind_array.
add(page_size_data);
3514 PgSqlLeaseContextAlloc get_context(*
this);
3521 IOAddress start_addr = lower_bound_address;
3522 if (lower_bound_address < first_addr) {
3523 start_addr = first_addr;
3524 }
else if (last_addr <= lower_bound_address) {
3536 bind_array.
add(relay_id_data);
3539 std::string start_addr_data = start_addr.
toText();
3540 bind_array.
add(start_addr_data);
3543 std::string last_addr_data = last_addr.
toText();
3544 bind_array.
add(last_addr_data);
3547 std::string page_size_data =
3548 boost::lexical_cast<std::string>(page_size.
page_size_);
3549 bind_array.
add(page_size_data);
3552 PgSqlLeaseContextAlloc get_context(*
this);
3570 .arg(lower_bound_address.
toText())
3571 .arg(idToText(remote_id))
3573 .arg(
static_cast<unsigned>(link_len));
3576 if (!link_addr.
isV6()) {
3578 "retrieving leases from the lease database, got "
3581 if (link_len > 128) {
3583 <<
static_cast<unsigned>(link_len));
3585 if (!lower_bound_address.
isV6()) {
3587 "retrieving leases from the lease database, got "
3588 << lower_bound_address);
3591 if (remote_id.size() == 0) {
3602 bind_array.
add(remote_id);
3605 std::string lb_addr_data = lower_bound_address.
toText();
3606 bind_array.
add(lb_addr_data);
3609 std::string page_size_data =
3610 boost::lexical_cast<std::string>(page_size.
page_size_);
3611 bind_array.
add(page_size_data);
3614 PgSqlLeaseContextAlloc get_context(*
this);
3621 IOAddress start_addr = lower_bound_address;
3622 if (lower_bound_address < first_addr) {
3623 start_addr = first_addr;
3624 }
else if (last_addr <= lower_bound_address) {
3636 bind_array.
add(remote_id);
3639 std::string start_addr_data = start_addr.
toText();
3640 bind_array.
add(start_addr_data);
3643 std::string last_addr_data = last_addr.
toText();
3644 bind_array.
add(last_addr_data);
3647 std::string page_size_data =
3648 boost::lexical_cast<std::string>(page_size.
page_size_);
3649 bind_array.
add(page_size_data);
3652 PgSqlLeaseContextAlloc get_context(*
this);
3669 .arg(lower_bound_address.
toText())
3671 .arg(
static_cast<unsigned>(link_len));
3674 if (!link_addr.
isV6()) {
3676 "retrieving leases from the lease database, got "
3680 if ((link_len == 0) || (link_len > 128)) {
3682 <<
static_cast<unsigned>(link_len));
3685 if (!lower_bound_address.
isV6()) {
3687 "retrieving leases from the lease database, got "
3688 << lower_bound_address);
3694 IOAddress start_addr = lower_bound_address;
3695 if (lower_bound_address < first_addr) {
3696 start_addr = first_addr;
3697 }
else if (last_addr <= lower_bound_address) {
3709 std::string start_addr_str = start_addr.
toText();
3710 bind_array.
add(start_addr_str);
3713 std::string last_addr_str = last_addr.
toText();
3714 bind_array.
add(last_addr_str);
3717 std::string page_size_data =
3718 boost::lexical_cast<std::string>(page_size.
page_size_);
3719 bind_array.
add(page_size_data);
3722 PgSqlLeaseContextAlloc get_context(*
this);
3734 getConsistency()->getExtendedInfoSanityCheck();
3748 .arg(start_addr.
toText())
3755 std::string start_addr_str = start_addr.
toText();
3756 bind_array.
add(start_addr_str);
3759 std::string page_size_data =
3760 boost::lexical_cast<std::string>(page_size.
page_size_);
3761 bind_array.
add(page_size_data);
3767 PgSqlLeaseContextAlloc get_context(*
this);
3773 if (leases.empty()) {
3779 start_addr = leases.back()->addr_;
3780 for (
auto lease : leases) {
3788 if (modified || added) {
3795 }
catch (
const std::exception& ex) {
3799 .arg(lease->addr_.toText())
3815 PgSqlLeaseContextAlloc get_context(*
this);
3820 PgSqlResult r1(PQexecPrepared(ctx->conn_, tagged_statements[stindex1].name,
3822 ctx->conn_.checkStatementError(r1, tagged_statements[stindex1]);
3826 PgSqlResult r2(PQexecPrepared(ctx->conn_, tagged_statements[stindex2].name,
3828 ctx->conn_.checkStatementError(r2, tagged_statements[stindex2]);
3834 PgSqlLeaseContextAlloc get_context(*
this);
3839 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
3841 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
3844 return (
static_cast<size_t>(count));
3850 PgSqlLeaseContextAlloc get_context(*
this);
3855 PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
3857 ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
3860 return (
static_cast<size_t>(count));
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 if a parameter given to a method would refer to or modify out-of-r...
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
std::string toText() const
Convert the address to a string.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
bool isV6() const
Convenience function to check for an IPv6 address.
bool isV4() const
Convenience function to check for an IPv4 address.
static IOAddress increase(const IOAddress &addr)
Returns an address increased by one.
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
static bool invokeDbLostCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's lost connectivity callback.
static std::string redactedAccessString(const ParameterMap ¶meters)
Redact database access string.
static bool invokeDbFailedCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's restore failed connectivity callback.
static bool invokeDbRecoveredCallback(const util::ReconnectCtlPtr &db_reconnect_ctl)
Invokes the connection's restored connectivity callback.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Exception thrown on failure to open database.
Exception thrown on failure to execute a database function.
Invalid address family used as input to Lease Manager.
Multiple lease records found where one expected.
Common PgSql Connector Pool.
static bool warned_about_tls
Emit the TLS support warning only once.
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.
Base class for marshalling data to and from PostgreSQL.
static std::string convertToDatabaseTime(const time_t input_time)
Converts UTC time_t value to a text representation in local time.
static void getColumnValue(const PgSqlResult &r, const int row, const size_t col, std::string &value)
Fetches text column value as a string.
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.
const std::vector< uint8_t > & getClientId() const
Returns reference to the client-id data.
Holds DUID (DHCPv6 Unique Identifier)
const std::vector< uint8_t > & getDuid() const
Returns a const reference to the actual DUID value.
std::string toText() const
Returns textual representation of the identifier (e.g.
static void recreate(const std::string &dbaccess, bool preserve_callbacks=true)
Recreate an instance of a lease manager with optionally preserving registered callbacks.
void setExtendedInfoTablesEnabled(const bool enabled)
Modifies the setting whether the lease6 extended info tables are enabled.
static bool upgradeLease6ExtendedInfo(const Lease6Ptr &lease, CfgConsistency::ExtendedInfoSanity check=CfgConsistency::EXTENDED_INFO_CHECK_FIX)
Upgrade a V6 lease user context to the new extended info entry.
bool getExtendedInfoTablesEnabled() const
Returns the setting indicating if lease6 extended info tables are enabled.
static isc::asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service.
static void extractLease4ExtendedInfo(const Lease4Ptr &lease, bool ignore_errors=true)
Extract relay and remote identifiers from the extended info.
static bool upgradeLease4ExtendedInfo(const Lease4Ptr &lease, CfgConsistency::ExtendedInfoSanity check=CfgConsistency::EXTENDED_INFO_CHECK_FIX)
The following queries are used to fulfill Bulk Lease Query queries.
virtual bool addExtendedInfo6(const Lease6Ptr &lease)
Extract extended info from a lease6 and add it into tables.
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.
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.
Base class for marshalling leases to and from PostgreSQL.
std::string valid_lifetime_str_
std::vector< uint8_t > addr_bin_
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 Lease6Collection getLeases6ByRelayId(const DUID &relay_id, const asiolink::IOAddress &link_addr, uint8_t link_len, const asiolink::IOAddress &lower_bound_address, const LeasePageSize &page_size) override
Returns existing IPv6 leases with a given relay-id.
virtual void recountClassLeases6() override
Recount the leases per class for V6 leases.
virtual LeaseStatsQueryPtr startLeaseStatsQuery4() override
Creates and runs the IPv4 lease stats query.
virtual size_t wipeLeases4(const SubnetID &subnet_id) override
Removes specified IPv4 leases.
PgSqlLeaseContextPtr createContext() const
Create a new context.
virtual Lease4Collection getLeases4() const override
Returns all IPv4 leases.
virtual LeaseStatsQueryPtr startLeaseStatsQuery6() override
Creates and runs the IPv6 lease stats query.
virtual Lease4Collection getLeases4ByRemoteId(const OptionBuffer &remote_id, const asiolink::IOAddress &lower_bound_address, const LeasePageSize &page_size, const time_t &qry_start_time=0, const time_t &qry_end_time=0) override
Returns existing IPv4 leases with a given remote-id.
virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery4() override
Creates and runs the IPv4 lease stats query for all subnets and pools.
virtual std::string checkLimits6(isc::data::ConstElementPtr const &user_context) const override
Checks if the IPv6 lease limits set in the given user context are exceeded.
virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs) override
Deletes all expired-reclaimed DHCPv4 leases.
virtual Lease6Collection getLeases6ByRemoteId(const OptionBuffer &remote_id, const asiolink::IOAddress &link_addr, uint8_t link_len, const asiolink::IOAddress &lower_bound_address, const LeasePageSize &page_size) override
Returns existing IPv6 leases with a given remote-id.
static std::string getDBVersion()
Local version of getDBVersion() class method.
virtual std::string checkLimits4(isc::data::ConstElementPtr const &user_context) const override
Checks if the IPv4 lease limits set in the given user context are exceeded.
virtual size_t byRemoteId6size() const override
Return the by-remote-id table size.
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID &subnet_id) override
Creates and runs the IPv4 lease stats query for a single subnet.
virtual void addRelayId6(const isc::asiolink::IOAddress &lease_addr, const std::vector< uint8_t > &relay_id) override
Add lease6 extended info into by-relay-id table.
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs) override
Deletes all expired-reclaimed DHCPv6 leases.
virtual void deleteExtendedInfo6(const isc::asiolink::IOAddress &addr) override
Extended information / Bulk Lease Query shared interface.
virtual void recountClassLeases4() override
Recount the leases per class for V4 leases.
virtual size_t upgradeExtendedInfo4(const LeasePageSize &page_size) override
Upgrade extended info (v4).
virtual size_t wipeLeases6(const SubnetID &subnet_id) override
Removed specified IPv6 leases.
virtual void getExpiredLeases4(Lease4Collection &expired_leases, const size_t max_leases) const override
Returns a collection of expired DHCPv4 leases.
virtual void updateLease6(const Lease6Ptr &lease6) override
Updates IPv6 lease.
virtual std::pair< uint32_t, uint32_t > getVersion() const override
Returns backend version.
virtual std::string getDescription() const override
Returns description of the backend.
virtual void wipeExtendedInfoTables6() override
Wipe extended info table (v6).
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id) override
Creates and runs the IPv6 lease stats query for a single subnet.
virtual size_t upgradeExtendedInfo6(const LeasePageSize &page_size) override
Upgrade extended info (v6).
virtual size_t byRelayId6size() const override
Return the by-relay-id table size.
virtual Lease4Collection getLeases4ByRelayId(const OptionBuffer &relay_id, const asiolink::IOAddress &lower_bound_address, const LeasePageSize &page_size, const time_t &qry_start_time=0, const time_t &qry_end_time=0) override
The following queries are used to fulfill Bulk Lease Query queries.
virtual void commit() override
Commit Transactions.
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID &subnet_id) override
Creates and runs the IPv6 lease stats query for a single subnet.
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const override
Returns existing IPv6 lease for a given IPv6 address.
virtual Lease6Collection getLeases6() const override
Returns all IPv6 leases.
virtual void addRemoteId6(const isc::asiolink::IOAddress &lease_addr, const std::vector< uint8_t > &remote_id) override
Add lease6 extended info into by-remote-id table.
StatementIndex
Statement Tags.
@ SUBNET_RANGE_LEASE4_STATS
@ GET_LEASE4_REMOTEID_QST
@ SUBNET_RANGE_LEASE6_STATS
@ GET_LEASE4_COUNT_BY_CLASS
@ GET_LEASE6_DUID_IAID_SUBID
@ GET_LEASE6_COUNT_BY_CLASS
@ GET_LEASE4_HWADDR_SUBID
@ GET_LEASE4_REMOTEID_QET
@ GET_LEASE4_CLIENTID_SUBID
@ DELETE_LEASE6_STATE_EXPIRED
@ GET_LEASE4_RELAYID_QSET
@ DELETE_LEASE4_STATE_EXPIRED
@ GET_LEASE4_REMOTEID_QSET
virtual void rollback() override
Rollback Transactions.
virtual void updateLease4(const Lease4Ptr &lease4) override
Updates IPv4 lease.
virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery6() override
Creates and runs the IPv6 lease stats query for all subnets and pools.
virtual void writeLeases6(const std::string &) override
Write V6 leases to a file.
virtual void getExpiredLeases6(Lease6Collection &expired_leases, const size_t max_leases) const override
Returns a collection of expired DHCPv6 leases.
virtual std::string getName() const override
Returns backend name.
PgSqlLeaseMgr(const db::DatabaseConnection::ParameterMap ¶meters)
Constructor.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const override
Returns an IPv4 lease for specified IPv4 address.
virtual void clearClassLeaseCounts() override
Clears the class-lease count map.
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id) override
Creates and runs the IPv4 lease stats query for a single subnet.
static bool dbReconnect(util::ReconnectCtlPtr db_reconnect_ctl)
Attempts to reconnect the server to the lease DB backend manager.
virtual ~PgSqlLeaseMgr()
Destructor (closes database)
virtual bool isJsonSupported() const override
Checks if JSON support is enabled in the database.
virtual size_t getClassLeaseCount(const ClientClass &client_class, const Lease::Type <ype=Lease::TYPE_V4) const override
Returns the class lease count for a given class and lease type.
virtual Lease6Collection getLeases6ByLink(const asiolink::IOAddress &link_addr, uint8_t link_len, const asiolink::IOAddress &lower_bound_address, const LeasePageSize &page_size) override
Returns existing IPv6 leases with on a given link.
virtual bool addLease(const Lease4Ptr &lease) override
Adds an IPv4 lease.
virtual void writeLeases4(const std::string &) override
Write V4 leases to a file.
virtual bool deleteLease(const Lease4Ptr &lease) override
Deletes an IPv4 lease.
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.
bool fetch_pool_
Indicates if query requires pool data.
PgSqlLeaseStatsQuery(PgSqlConnection &conn, PgSqlTaggedStatement &statement, const bool fetch_type, const bool fetch_pool=false)
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.
Introduces callbacks into the LeaseMgr.
void trackUpdateLease(const LeasePtr &lease, bool mt_safe)
Invokes the callbacks when a lease is updated.
void trackAddLease(const LeasePtr &lease, bool mt_safe)
Invokes the callbacks when a new lease is added.
void trackDeleteLease(const LeasePtr &lease, bool mt_safe)
Invokes the callbacks when a lease is deleted.
bool hasCallbacks() const
Checks if any callbacks have been registered.
RAII class creating a critical section.
#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_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.
IOAddress firstAddrInPrefix(const IOAddress &prefix, uint8_t len)
This code is based on similar code from the Dibbler project.
IOAddress lastAddrInPrefix(const IOAddress &prefix, uint8_t len)
returns a last address in a given prefix
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< IOServiceAccessor > IOServiceAccessorPtr
Pointer to an instance of IOServiceAccessor.
const size_t OID_NONE
Constants for PostgreSQL data types These are defined by PostgreSQL in <catalog/pg_type....
const size_t OID_TIMESTAMP
const uint32_t PGSQL_SCHEMA_VERSION_MINOR
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.
const uint32_t PGSQL_SCHEMA_VERSION_MAJOR
Define the PostgreSQL backend version.
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
std::string ClientClass
Defines a single class name.
const isc::log::MessageID DHCPSRV_PGSQL_GET_REMOTEID6
const isc::log::MessageID DHCPSRV_PGSQL_UPGRADE_EXTENDED_INFO6_PAGE
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_UPGRADE_EXTENDED_INFO6
const isc::log::MessageID DHCPSRV_PGSQL_UPGRADE_EXTENDED_INFO6_ERROR
const isc::log::MessageID DHCPSRV_PGSQL_GET_HOSTNAME4
const isc::log::MessageID DHCPSRV_PGSQL_UPGRADE_EXTENDED_INFO4
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_NO_TLS_SUPPORT
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_GET_REMOTEID4
const isc::log::MessageID DHCPSRV_PGSQL_UPGRADE_EXTENDED_INFO4_PAGE
const isc::log::MessageID DHCPSRV_PGSQL_LEASE_DB_RECONNECT_ATTEMPT_FAILED
const isc::log::MessageID DHCPSRV_PGSQL_TLS_SUPPORT
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
boost::shared_ptr< Lease > LeasePtr
Pointer to the lease object.
const isc::log::MessageID DHCPSRV_PGSQL_GET_LINKADDR6
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_RELAYID6
const isc::log::MessageID DHCPSRV_PGSQL_GET_IAID_DUID
const isc::log::MessageID DHCPSRV_PGSQL_UPDATE_ADDR6
const isc::log::MessageID DHCPSRV_PGSQL_GET_RELAYID4
boost::shared_ptr< PgSqlLeaseContext > PgSqlLeaseContextPtr
Type of pointers to contexts.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
const isc::log::MessageID DHCPSRV_PGSQL_LEASE_DB_RECONNECT_FAILED
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
const isc::log::MessageID DHCPSRV_PGSQL_UPGRADE_EXTENDED_INFO4_ERROR
@ 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 int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
const isc::log::MessageID DHCPSRV_PGSQL_DELETE_EXPIRED_RECLAIMED6
boost::shared_ptr< ReconnectCtl > ReconnectCtlPtr
Pointer to an instance of ReconnectCtl.
Defines the logger used by the top-level component of kea-lfc.
Define a PostgreSQL statement.
void addTempString(const std::string &str)
Binds the given string to the bind array.
std::vector< const char * > values_
Vector of pointers to the data values.
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.
void addNull(const int format=PsqlBindArray::TEXT_FMT)
Adds a NULL value to the bind array.
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.
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.
ExtendedInfoAction
Action on extended info tables.
@ ACTION_UPDATE
update extended info tables.
@ ACTION_DELETE
delete reference to the lease
@ ACTION_IGNORE
ignore extended info,
Contains a single row of lease statistical data.
uint32_t pool_id_
The pool ID to which this data applies.
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.
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.