Kea 1.5.0
cql_lease_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
2// Copyright (C) 2015-2018 Deutsche Telekom AG.
3//
4// Authors: Razvan Becheriu <razvan.becheriu@qualitance.com>
5// Andrei Pavel <andrei.pavel@qualitance.com>
6//
7// Licensed under the Apache License, Version 2.0 (the "License");
8// you may not use this file except in compliance with the License.
9// You may obtain a copy of the License at
10//
11// http://www.apache.org/licenses/LICENSE-2.0
12//
13// Unless required by applicable law or agreed to in writing, software
14// distributed under the License is distributed on an "AS IS" BASIS,
15// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16// See the License for the specific language governing permissions and
17// limitations under the License.
18
19#include <config.h>
20
23#include <dhcpsrv/dhcpsrv_log.h>
24
25#include <dhcp/duid.h>
26#include <dhcp/hwaddr.h>
27
28#include <asiolink/io_address.h>
29
30using namespace isc::data;
31using namespace isc::db;
33
34namespace isc {
35namespace dhcp {
36
37static constexpr size_t HOSTNAME_MAX_LEN = 255u;
38static constexpr size_t ADDRESS6_TEXT_MAX_LEN = 39u;
39static constexpr char NULL_USER_CONTEXT[] = "";
40
48public:
53 : connection_(connection), valid_lifetime_(0), expire_(0),
54 subnet_id_(0), fqdn_fwd_(cass_false), fqdn_rev_(cass_false),
55 state_(0), user_context_(NULL_USER_CONTEXT) {
56 }
57
65 virtual void
66 createBindForSelect(AnyArray &data, StatementTag statement_tag = NULL) override = 0;
67
75 virtual boost::any retrieve() override = 0;
76
77protected:
80
83
85 cass_int64_t valid_lifetime_;
86
88 cass_int64_t expire_;
89
91 cass_int32_t subnet_id_;
92
94 cass_bool_t fqdn_fwd_;
95
97 cass_bool_t fqdn_rev_;
98
100 std::string hostname_;
101
103 cass_int32_t state_;
104
106 std::string user_context_;
107};
108
122public:
130 explicit CqlLease4Exchange(const CqlConnection &connection);
131
139 void createBindForInsert(const Lease4Ptr &lease, AnyArray &data);
140
149 void createBindForUpdate(const Lease4Ptr &lease, AnyArray &data,
150 StatementTag statement_tag = NULL);
151
160 void createBindForDelete(const IOAddress &address,
161 AnyArray &data,
162 StatementTag statement_tag = NULL);
163
170 virtual void
171 createBindForSelect(AnyArray &data, StatementTag statement_tag = NULL) override;
172
176 virtual boost::any retrieve() override;
177
183 void getLeaseCollection(StatementTag &statement_tag, AnyArray &data,
184 Lease4Collection &result);
185
191 void
192 getLease(StatementTag &statement_tag, AnyArray &data, Lease4Ptr &result);
193
201 void getExpiredLeases(const size_t &max_leases, Lease4Collection &expired_leases);
202
205
208 // Add entry to lease4 table
209 static constexpr StatementTag INSERT_LEASE4 = "INSERT_LEASE4";
210 // Update a Lease4 entry
211 static constexpr StatementTag UPDATE_LEASE4 = "UPDATE_LEASE4";
212 // Delete from lease4 by address
213 static constexpr StatementTag DELETE_LEASE4 = "DELETE_LEASE4";
214 // Delete expired lease4s in certain state
215 static constexpr StatementTag GET_LEASE4_EXPIRE = "GET_LEASE4_EXPIRE";
216 // Get lease4
217 static constexpr StatementTag GET_LEASE4 = "GET_LEASE4";
218 // Get lease4 by address
219 static constexpr StatementTag GET_LEASE4_ADDR = "GET_LEASE4_ADDR";
220 // Get lease4 by client ID
221 static constexpr StatementTag GET_LEASE4_CLIENTID = "GET_LEASE4_CLIENTID";
222 // Get lease4 by client ID & subnet ID
223 static constexpr StatementTag GET_LEASE4_CLIENTID_SUBID = "GET_LEASE4_CLIENTID_SUBID";
224 // Get lease4 by HW address
225 static constexpr StatementTag GET_LEASE4_HWADDR = "GET_LEASE4_HWADDR";
226 // Get lease4 by HW address & subnet ID
227 static constexpr StatementTag GET_LEASE4_HWADDR_SUBID = "GET_LEASE4_HWADDR_SUBID";
228 // Get range of lease4 from first lease with a limit
229 static constexpr StatementTag GET_LEASE4_LIMIT = "GET_LEASE4_LIMIT";
230 // Get range of lease4 from address with limit (paging)
231 static constexpr StatementTag GET_LEASE4_PAGE = "GET_LEASE4_PAGE";
232 // Get lease4 by subnet ID
233 static constexpr StatementTag GET_LEASE4_SUBID = "GET_LEASE4_SUBID";
235
236private:
237 // Pointer to lease object
238 Lease4Ptr lease_;
239 // IPv4 address
240 cass_int32_t address_;
241 // Client identification
242 CassBlob client_id_;
243}; // CqlLease4Exchange
244
258
260
261 // Inserts new IPv4 lease
262 {INSERT_LEASE4,
263 {INSERT_LEASE4,
264 "INSERT INTO lease4( "
265 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
266 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
267 ") VALUES ( "
268 "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? "
269 ") "
270 "IF NOT EXISTS "}},
271
272 // Updates existing IPv4 lease
273 {UPDATE_LEASE4,
274 {UPDATE_LEASE4,
275 "UPDATE lease4 SET "
276 "hwaddr = ?, "
277 "client_id = ?, "
278 "subnet_id = ?, "
279 "valid_lifetime = ?, "
280 "expire = ?, "
281 "fqdn_fwd = ?, "
282 "fqdn_rev = ?, "
283 "hostname = ?, "
284 "state = ?, "
285 "user_context = ? "
286 "WHERE address = ? "
287 "IF EXISTS "}},
288
289 // Deletes existing IPv4 lease
290 {DELETE_LEASE4,
291 {DELETE_LEASE4,
292 "DELETE FROM lease4 "
293 "WHERE address = ? "
294 "IF EXISTS "}},
295
296 // Gets up to a certain number of expired IPv4 leases
297 {GET_LEASE4_EXPIRE,
298 {GET_LEASE4_EXPIRE,
299 "SELECT "
300 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
301 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
302 "FROM lease4 "
303 "WHERE state = ? "
304 "AND expire < ? "
305 "LIMIT ? "
306 "ALLOW FILTERING "}},
307
308 // Gets an IPv4 lease(s)
309 {GET_LEASE4,
310 {GET_LEASE4,
311 "SELECT "
312 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
313 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
314 "FROM lease4 "}},
315
316 // Gets an IPv4 lease with specified IPv4 address
317 {GET_LEASE4_ADDR,
318 {GET_LEASE4_ADDR,
319 "SELECT "
320 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
321 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
322 "FROM lease4 "
323 "WHERE address = ? "}},
324
325 // Gets an IPv4 lease(s) with specified client-id
326 {GET_LEASE4_CLIENTID,
327 {GET_LEASE4_CLIENTID,
328 "SELECT "
329 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
330 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
331 "FROM lease4 "
332 "WHERE client_id = ? "
333 "ALLOW FILTERING "}},
334
335 // Gets an IPv4 lease with specified client-id and subnet-id
336 {GET_LEASE4_CLIENTID_SUBID,
337 {GET_LEASE4_CLIENTID_SUBID,
338 "SELECT "
339 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
340 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
341 "FROM lease4 "
342 "WHERE client_id = ? "
343 "AND subnet_id = ? "
344 "ALLOW FILTERING "}},
345
346 // Gets all IPv4 leases with specified hardware address
347 {GET_LEASE4_HWADDR,
348 {GET_LEASE4_HWADDR,
349 "SELECT "
350 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
351 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
352 "FROM lease4 "
353 "WHERE hwaddr = ? "
354 "ALLOW FILTERING "}},
355
356 // Gets an IPv4 lease with specified hardware addr and subnet-id
357 {GET_LEASE4_HWADDR_SUBID,
358 {GET_LEASE4_HWADDR_SUBID,
359 "SELECT "
360 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
361 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
362 "FROM lease4 "
363 "WHERE hwaddr = ? "
364 "AND subnet_id = ? "
365 "ALLOW FILTERING "}},
366
367 // Get range of lease4 from first lease with a limit (paging)
368 {GET_LEASE4_LIMIT,
369 {GET_LEASE4_LIMIT,
370 "SELECT "
371 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
372 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
373 "FROM lease4 "
374 "LIMIT ? "
375 "ALLOW FILTERING "}},
376
377 // Get range of lease4 from address with a limit (paging)
378 {GET_LEASE4_PAGE,
379 {GET_LEASE4_PAGE,
380 "SELECT "
381 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
382 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
383 "FROM lease4 "
384 "WHERE TOKEN(address) > TOKEN(?) "
385 "LIMIT ? "
386 "ALLOW FILTERING "}},
387
388 // Gets an IPv4 lease(s) with specified subnet-id
389 {GET_LEASE4_SUBID,
390 {GET_LEASE4_SUBID,
391 "SELECT "
392 "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
393 "fqdn_fwd, fqdn_rev, hostname, state, user_context "
394 "FROM lease4 "
395 "WHERE subnet_id = ? "
396 "ALLOW FILTERING "}}
397};
398
400 : CqlLeaseExchange(connection), address_(0) {
401}
402
403void
405 if (!lease) {
406 isc_throw(BadValue, "CqlLease4Exchange::createBindForInsert(): "
407 "Lease4 object is NULL");
408 }
409 // Store lease object to ensure it remains valid.
410 lease_ = lease;
411 // Set up the structures for the various components of the lease4
412 // structure.
413
414 try {
415 // address: int
416 // The address in the Lease structure is an IOAddress object.
417 // Convert this to an integer for storage.
418 address_ = static_cast<cass_int32_t>(lease->addr_.toUint32());
419
420 // hwaddr: blob
421 if (lease_->hwaddr_ && lease_->hwaddr_->hwaddr_.size() > 0) {
422 if (lease_->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
424 "hardware address "
425 << lease_->hwaddr_->toText() << " of length "
426 << lease_->hwaddr_->hwaddr_.size()
427 << " exceeds maximum allowed length of "
429 }
430 hwaddr_ = lease_->hwaddr_->hwaddr_;
431 } else {
432 hwaddr_.clear();
433 }
434
435 // client_id: blob
436 if (lease_->client_id_ && lease_->client_id_->getClientId().size() > 0) {
437 client_id_ = lease_->client_id_->getClientId();
438 } else {
439 client_id_.clear();
440 }
441
442 // valid lifetime: bigint
443 valid_lifetime_ = static_cast<cass_int64_t>(lease_->valid_lft_);
444
445 // expire: bigint
446 // The lease structure holds the client last transmission time
448 // For convenience for external tools, this is converted to lease
449 // expiry time (expire). The relationship is given by:
450 // expire = cltt_ + valid_lft_
451 CqlExchange::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_,
452 expire_);
453
454 // subnet_id: int
455 subnet_id_ = static_cast<cass_int32_t>(lease_->subnet_id_);
456
457 // fqdn_fwd: boolean
458 fqdn_fwd_ = lease_->fqdn_fwd_ ? cass_true : cass_false;
459
460 // fqdn_rev: boolean
461 fqdn_rev_ = lease_->fqdn_rev_ ? cass_true : cass_false;
462
463 // hostname: varchar
464 if (lease_->hostname_.size() > HOSTNAME_MAX_LEN) {
466 "hostname " << lease_->hostname_ << " of length "
467 << lease_->hostname_.size()
468 << " exceeds maximum allowed length of "
469 << HOSTNAME_MAX_LEN);
470 }
471 hostname_ = lease_->hostname_;
472
473 // state: int
474 state_ = static_cast<cass_int32_t>(lease_->state_);
475
476 // user_context: text
477 ConstElementPtr ctx = lease_->getContext();
478 if (ctx) {
479 user_context_ = ctx->str();
480 } else {
481 user_context_ = NULL_USER_CONTEXT;
482 }
483
484 // Start with a fresh array.
485 data.clear();
486 data.add(&address_);
487 data.add(&hwaddr_);
488 data.add(&client_id_);
489 data.add(&valid_lifetime_);
490 data.add(&expire_);
491 data.add(&subnet_id_);
492 data.add(&fqdn_fwd_);
493 data.add(&fqdn_rev_);
494 data.add(&hostname_);
495 data.add(&state_);
496 data.add(&user_context_);
497
498 } catch (const Exception &ex) {
499 isc_throw(DbOperationError, "CqlLease4Exchange::createBindForInsert(): "
500 "could not create bind array from Lease4: " << lease_->addr_.toText()
501 << ", reason: " << ex.what());
502 }
503}
504
505void
507 StatementTag /* unused */) {
508 if (!lease) {
509 isc_throw(BadValue, "CqlLease4Exchange::createBindForUpdate(): "
510 "Lease4 object is NULL");
511 }
512 // Store lease object to ensure it remains valid.
513 lease_ = lease;
514 // Set up the structures for the various components of the lease4
515 // structure.
516
517 try {
518 // address: int
519 // The address in the Lease structure is an IOAddress object.
520 // Convert this to an integer for storage.
521 address_ = static_cast<cass_int32_t>(lease->addr_.toUint32());
522
523 // hwaddr: blob
524 if (lease_->hwaddr_ && lease_->hwaddr_->hwaddr_.size() > 0) {
525 if (lease_->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
527 "hardware address "
528 << lease_->hwaddr_->toText() << " of length "
529 << lease_->hwaddr_->hwaddr_.size()
530 << " exceeds maximum allowed length of "
532 }
533 hwaddr_ = lease_->hwaddr_->hwaddr_;
534 } else {
535 hwaddr_.clear();
536 }
537
538 // client_id: blob
539 if (lease_->client_id_ && lease_->client_id_->getClientId().size() > 0) {
540 client_id_ = lease_->client_id_->getClientId();
541 } else {
542 client_id_.clear();
543 }
544
545 // valid lifetime: bigint
546 valid_lifetime_ = static_cast<cass_int64_t>(lease_->valid_lft_);
547
548 // expire: bigint
549 // The lease structure holds the client last transmission time
551 // For convenience for external tools, this is converted to lease
552 // expiry time (expire). The relationship is given by:
553 // expire = cltt_ + valid_lft_
554 CqlExchange::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_,
555 expire_);
556
557 // subnet_id: int
558 subnet_id_ = static_cast<cass_int32_t>(lease_->subnet_id_);
559
560 // fqdn_fwd: boolean
561 fqdn_fwd_ = lease_->fqdn_fwd_ ? cass_true : cass_false;
562
563 // fqdn_rev: boolean
564 fqdn_rev_ = lease_->fqdn_rev_ ? cass_true : cass_false;
565
566 // hostname: varchar
567 if (lease_->hostname_.size() > HOSTNAME_MAX_LEN) {
569 "hostname " << lease_->hostname_ << " of length "
570 << lease_->hostname_.size()
571 << " exceeds maximum allowed length of "
572 << HOSTNAME_MAX_LEN);
573 }
574 hostname_ = lease_->hostname_;
575
576 // state: int
577 state_ = static_cast<cass_int32_t>(lease_->state_);
578
579 // user_context: text
580 ConstElementPtr ctx = lease_->getContext();
581 if (ctx) {
582 user_context_ = ctx->str();
583 } else {
584 user_context_ = NULL_USER_CONTEXT;
585 }
586
587 // Start with a fresh array.
588 data.clear();
589 data.add(&hwaddr_);
590 data.add(&client_id_);
591 data.add(&subnet_id_);
592 data.add(&valid_lifetime_);
593 data.add(&expire_);
594 data.add(&fqdn_fwd_);
595 data.add(&fqdn_rev_);
596 data.add(&hostname_);
597 data.add(&state_);
598 data.add(&user_context_);
599 data.add(&address_);
600
601 } catch (const Exception &ex) {
603 "CqlLease4Exchange::createBindUpdate(): "
604 "could not create bind array from Lease4: "
605 << lease_->addr_.toText() << ", reason: " << ex.what());
606 }
607}
608
609void
611 StatementTag /* unused */) {
612 // Set up the structures for the various components of the lease4
613 // structure.
614
615 try {
616 // address: int
617 address_ = static_cast<cass_int32_t>(address.toUint32());
618
619 // Start with a fresh array.
620 data.clear();
621 data.add(&address_);
622
623 } catch (const Exception &ex) {
625 "CqlLease4Exchange::createBindForDelete(): "
626 "could not create bind array with address: "
627 << address_ << ", reason: " << ex.what());
628 }
629}
630
631void
633
634 // Start with a fresh array.
635 data.clear();
636
637 // address: blob
638 data.add(&address_);
639
640 // hwaddr: blob
641 data.add(&hwaddr_);
642
643 // client_id: blob
644 data.add(&client_id_);
645
646 // valid_lifetime: bigint
647 data.add(&valid_lifetime_);
648
649 // expire: bigint
650 data.add(&expire_);
651
652 // subnet_id: int
653 data.add(&subnet_id_);
654
655 // fqdn_fwd: boolean
656 data.add(&fqdn_fwd_);
657
658 // fqdn_rev: boolean
659 data.add(&fqdn_rev_);
660
661 // hostname: varchar
662 data.add(&hostname_);
663
664 // state: int
665 data.add(&state_);
666
667 // user_context: text
668 data.add(&user_context_);
669}
670
671boost::any
673 try {
674 // Sanity checks
675 if (hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
677 "hardware address "
678 << HWAddr(hwaddr_, HTYPE_ETHER).toText()
679 << " of length " << hwaddr_.size()
680 << " exceeds maximum allowed length of "
682 }
683 if (client_id_.size() > ClientId::MAX_CLIENT_ID_LEN) {
685 "client ID " << ClientId(client_id_).toText()
686 << " of length " << client_id_.size()
687 << " exceeds maximum allowed length of "
689 }
690 if (hostname_.size() > HOSTNAME_MAX_LEN) {
692 "hostname" << hostname_ << " of length "
693 << hostname_.size()
694 << " exceeds maximum allowed length of "
695 << HOSTNAME_MAX_LEN);
696 }
697
698 time_t cltt = 0;
700
701 HWAddrPtr hwaddr(new HWAddr(hwaddr_, HTYPE_ETHER));
702
703 uint32_t addr4 = static_cast<uint32_t>(address_);
704
705 ConstElementPtr ctx;
706 if (!user_context_.empty()) {
708 if (!ctx || (ctx->getType() != Element::map)) {
709 isc_throw(BadValue, "user context '" << user_context_
710 << "' is not a JSON map");
711 }
712 }
713
714 Lease4Ptr result(new Lease4(addr4, hwaddr, client_id_.data(),
715 client_id_.size(), valid_lifetime_, 0, 0,
717 hostname_));
718
719 result->state_ = state_;
720
721 if (ctx) {
722 result->setContext(ctx);
723 }
724
725 return (result);
726 } catch (const Exception &ex) {
728 "CqlLease4Exchange::retrieve(): "
729 "could not convert data to Lease4, reason: "
730 << ex.what());
731 }
732}
733
734void
736 Lease4Collection &result) {
737 AnyArray collection = executeSelect(connection_, data, statement_tag);
738
739 // Transfer Lease4 objects to result.
740 for (boost::any &element : collection) {
741 result.push_back(boost::any_cast<Lease4Ptr>(element));
742 }
743}
744
745void
747 Lease4Ptr &result) {
748 // This particular method is called when only one or zero matches is
749 // expected.
750 Lease4Collection collection;
751 getLeaseCollection(statement_tag, data, collection);
752
753 // Return single record if present, else clear the lease.
754 const size_t collection_size = collection.size();
755 if (collection_size >= 2u) {
757 "CqlLease4Exchange::getLease(): multiple records were found in "
758 "the database where only one was expected for statement "
759 << statement_tag);
760 } else if (collection_size == 0u) {
761 result.reset();
762 } else {
763 result = *collection.begin();
764 }
765}
766
767void
768CqlLease4Exchange::getExpiredLeases(const size_t &max_leases,
769 Lease4Collection &expired_leases) {
770 // Set up the WHERE clause value
771 cass_int32_t keep_state = Lease::STATE_EXPIRED_RECLAIMED;
772 cass_int64_t timestamp = static_cast<cass_int64_t>(time(NULL));
773
774 // If the number of leases is 0, we will return all leases. This is
775 // achieved by setting the limit to a very high value.
776 cass_int32_t limit = max_leases > 0u ?
777 static_cast<cass_int32_t>(max_leases) :
778 std::numeric_limits<cass_int32_t>::max();
779
780 for (cass_int32_t state = Lease::STATE_DEFAULT;
781 state <= Lease::STATE_EXPIRED_RECLAIMED; state++) {
782 if (state == keep_state) {
783 continue;
784 }
785
786 AnyArray data;
787 data.add(&state);
788 data.add(&timestamp);
789 data.add(&limit);
790
791 // Retrieve leases from the database.
792 Lease4Collection temp_collection;
794 temp_collection);
795
796 for (Lease4Ptr &lease : temp_collection) {
797 expired_leases.push_back(lease);
798 }
799 }
800}
801
815public:
823 explicit CqlLease6Exchange(const CqlConnection &connection);
824
832 void createBindForInsert(const Lease6Ptr &lease, AnyArray &data);
833
842 void createBindForUpdate(const Lease6Ptr &lease, AnyArray &data,
843 StatementTag statement_tag = NULL);
844
853 void createBindForDelete(const IOAddress &address,
854 AnyArray &data,
855 StatementTag statement_tag = NULL);
856
863 virtual void
864 createBindForSelect(AnyArray &data, StatementTag statement_tag = NULL) override;
865
869 virtual boost::any retrieve() override;
870
876 void getLeaseCollection(StatementTag &statement_tag, AnyArray &data,
877 Lease6Collection &result);
878
884 void
885 getLease(StatementTag &statement_tag, AnyArray &data, Lease6Ptr &result);
886
894 void getExpiredLeases(const size_t &max_leases, Lease6Collection &expired_leases);
895
898
901 static constexpr StatementTag INSERT_LEASE6 = "INSERT_LEASE6";
902 static constexpr StatementTag UPDATE_LEASE6 = "UPDATE_LEASE6";
903 static constexpr StatementTag DELETE_LEASE6 = "DELETE_LEASE6";
904 static constexpr StatementTag GET_LEASE6_EXPIRE = "GET_LEASE6_EXPIRE";
905 static constexpr StatementTag GET_LEASE6_ADDR = "GET_LEASE6_ADDR";
906 static constexpr StatementTag GET_LEASE6_DUID = "GET_LEASE6_DUID";
907 static constexpr StatementTag GET_LEASE6_DUID_IAID = "GET_LEASE6_DUID_IAID";
908 static constexpr StatementTag GET_LEASE6_DUID_IAID_SUBID = "GET_LEASE6_DUID_IAID_SUBID";
909 static constexpr StatementTag GET_LEASE6_LIMIT = "GET_LEASE6_LIMIT";
910 static constexpr StatementTag GET_LEASE6_PAGE = "GET_LEASE6_PAGE";
911 // @}
912
913private:
915 Lease6Ptr lease_;
916
918 std::string address_;
919
921 cass_int64_t pref_lifetime_;
922
924 CassBlob duid_;
925
927 cass_int32_t iaid_;
928
930 cass_int32_t lease_type_;
931
933 cass_int32_t prefix_len_;
934
936 cass_int32_t hwtype_;
937
939 cass_int32_t hwaddr_source_;
940}; // CqlLease6Exchange
941
952
954
955 // Inserts new IPv6 lease
956 {INSERT_LEASE6,
957 {INSERT_LEASE6,
958 "INSERT INTO lease6("
959 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
960 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
961 "hwaddr_source, state, user_context "
962 ") VALUES ("
963 "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"
964 ") "
965 "IF NOT EXISTS "}},
966
967 // Updates existing IPv6 lease
968 {UPDATE_LEASE6,
969 {UPDATE_LEASE6,
970 "UPDATE lease6 SET "
971 "valid_lifetime = ?, "
972 "expire = ?, "
973 "pref_lifetime = ?, "
974 "duid = ?, "
975 "iaid = ?, "
976 "subnet_id = ?, "
977 "lease_type = ?, "
978 "prefix_len = ?, "
979 "fqdn_fwd = ?, "
980 "fqdn_rev = ?, "
981 "hostname = ?, "
982 "hwaddr = ?, "
983 "hwtype = ?, "
984 "hwaddr_source = ?, "
985 "state = ?, "
986 "user_context = ? "
987 "WHERE address = ? "
988 "IF EXISTS "}},
989
990 // Deletes existing IPv6 lease
991 {DELETE_LEASE6,
992 {DELETE_LEASE6,
993 "DELETE FROM lease6 "
994 "WHERE address = ? "
995 "IF EXISTS "}},
996
997 // Gets up to a certain number of expired IPv6 leases
998 {GET_LEASE6_EXPIRE,
999 {GET_LEASE6_EXPIRE,
1000 "SELECT "
1001 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1002 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1003 "hwaddr_source, state, user_context "
1004 "FROM lease6 "
1005 "WHERE state = ? "
1006 "AND expire < ? "
1007 "LIMIT ? "
1008 "ALLOW FILTERING "}},
1009
1010 // Gets an IPv6 lease with specified IPv6 address
1011 {GET_LEASE6_ADDR,
1012 {GET_LEASE6_ADDR,
1013 "SELECT "
1014 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1015 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1016 "hwaddr_source, state, user_context "
1017 "FROM lease6 "
1018 "WHERE address = ? "
1019 "AND lease_type = ? "
1020 "ALLOW FILTERING "}},
1021
1022 // Gets an IPv6 lease with specified duid
1023 {GET_LEASE6_DUID,
1024 {GET_LEASE6_DUID,
1025 "SELECT "
1026 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1027 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1028 "hwaddr_source, state, user_context "
1029 "FROM lease6 "
1030 "WHERE duid = ? "
1031 "ALLOW FILTERING "}},
1032
1033 // Gets an IPv6 lease(s) with specified duid and iaid
1034 {GET_LEASE6_DUID_IAID,
1035 {GET_LEASE6_DUID_IAID,
1036 "SELECT "
1037 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1038 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1039 "hwaddr_source, state, user_context "
1040 "FROM lease6 "
1041 "WHERE duid = ? AND iaid = ? "
1042 "AND lease_type = ? "
1043 "ALLOW FILTERING "}},
1044
1045 // Gets an IPv6 lease with specified duid, iaid and subnet-id
1046 {GET_LEASE6_DUID_IAID_SUBID,
1047 {GET_LEASE6_DUID_IAID_SUBID,
1048 "SELECT "
1049 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1050 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1051 "hwaddr_source, state, user_context "
1052 "FROM lease6 "
1053 "WHERE duid = ? AND iaid = ? "
1054 "AND lease_type = ? "
1055 "AND subnet_id = ? "
1056 "ALLOW FILTERING "}},
1057
1058 // Get range of IPv6 leases from first lease with a limit (paging)
1059 {GET_LEASE6_LIMIT,
1060 {GET_LEASE6_LIMIT,
1061 "SELECT "
1062 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1063 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1064 "hwaddr_source, state, user_context "
1065 "FROM lease6 "
1066 "LIMIT ? "
1067 "ALLOW FILTERING "}},
1068
1069 // Get range of IPv6 leases from address with a limit (paging)
1070 {GET_LEASE6_PAGE,
1071 {GET_LEASE6_PAGE,
1072 "SELECT "
1073 "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
1074 "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
1075 "hwaddr_source, state, user_context "
1076 "FROM lease6 "
1077 "WHERE TOKEN(address) > TOKEN(?) "
1078 "LIMIT ? "
1079 "ALLOW FILTERING "}}
1080};
1081
1083 : CqlLeaseExchange(connection), pref_lifetime_(0), iaid_(0), lease_type_(0),
1084 prefix_len_(0), hwtype_(0), hwaddr_source_(0) {
1085}
1086
1087void
1089 if (!lease) {
1090 isc_throw(BadValue, "CqlLease6Exchange::createBindForInsert(): "
1091 "Lease6 object is NULL");
1092 }
1093 // Store lease object to ensure it remains valid.
1094 lease_ = lease;
1095
1096 // Set up the structures for the various components of the lease4
1097 // structure.
1098 try {
1099 // address: varchar
1100 address_ = lease_->addr_.toText();
1101 if (address_.size() > ADDRESS6_TEXT_MAX_LEN) {
1102 isc_throw(BadValue, "address " << address_ << " of length " << address_.size()
1103 << " exceeds maximum allowed length of " << ADDRESS6_TEXT_MAX_LEN);
1104 }
1105
1106 // valid lifetime: bigint
1107 valid_lifetime_ = static_cast<cass_int64_t>(lease_->valid_lft_);
1108
1109 // expire: bigint
1110 // The lease structure holds the client last transmission time
1111 // (cltt_)
1112 // For convenience for external tools, this is converted to lease
1113 // expiry time (expire). The relationship is given by:
1114 // expire = cltt_ + valid_lft_
1115 CqlExchange::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_, expire_);
1116
1117 // subnet_id: int
1118 subnet_id_ = static_cast<cass_int32_t>(lease_->subnet_id_);
1119
1120 // pref_lifetime: bigint
1121 pref_lifetime_ = static_cast<cass_int64_t>(lease_->preferred_lft_);
1122
1123 // duid: blob
1124 if (!lease_->duid_) {
1125 isc_throw(DbOperationError, "lease6 with address " << address_
1126 << " is missing mandatory duid");
1127 }
1128 duid_ = lease_->duid_->getDuid();
1129
1130 // iaid: int
1131 iaid_ = static_cast<cass_int32_t>(lease_->iaid_);
1132
1133 // lease_type: int
1134 lease_type_ = static_cast<cass_int32_t>(lease_->type_);
1135
1136 // prefix_len: int
1137 prefix_len_ = static_cast<cass_int32_t>(lease_->prefixlen_);
1138
1139 // fqdn_fwd: boolean
1140 fqdn_fwd_ = lease_->fqdn_fwd_ ? cass_true : cass_false;
1141
1142 // fqdn_rev: boolean
1143 fqdn_rev_ = lease_->fqdn_rev_ ? cass_true : cass_false;
1144
1145 // hostname: varchar
1146 if (lease_->hostname_.size() > HOSTNAME_MAX_LEN) {
1147 isc_throw(BadValue, "hostname" << lease_->hostname_ << " of length "
1148 << lease_->hostname_.size() << " exceeds maximum allowed length of "
1149 << HOSTNAME_MAX_LEN);
1150 }
1151 hostname_ = lease_->hostname_;
1152
1153 // hwaddr: blob
1154 if (lease_->hwaddr_ && lease_->hwaddr_->hwaddr_.size() > 0) {
1155 if (lease_->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
1156 isc_throw(DbOperationError, "hardware address " << lease_->hwaddr_->toText()
1157 << " of length " << lease_->hwaddr_->hwaddr_.size()
1158 << " exceeds maximum allowed length of " << HWAddr::MAX_HWADDR_LEN);
1159 }
1160 hwaddr_ = lease_->hwaddr_->hwaddr_;
1161 } else {
1162 hwaddr_.clear();
1163 }
1164
1165 // hwtype: int
1166 if (lease_->hwaddr_) {
1167 hwtype_ = static_cast<cass_int32_t>(lease_->hwaddr_->htype_);
1168 } else {
1169 hwtype_ = 0;
1170 }
1171
1172 // hwaddr_source: int
1173 if (lease_->hwaddr_) {
1174 hwaddr_source_ = static_cast<cass_int32_t>(lease_->hwaddr_->source_);
1175 } else {
1176 hwaddr_source_ = 0;
1177 }
1178
1179 // state: int
1180 state_ = static_cast<cass_int32_t>(lease_->state_);
1181
1182 // user_context: text
1183 ConstElementPtr ctx = lease_->getContext();
1184 if (ctx) {
1185 user_context_ = ctx->str();
1186 } else {
1187 user_context_ = NULL_USER_CONTEXT;
1188 }
1189
1190 // Start with a fresh array.
1191 data.clear();
1192
1193 // Add them all to data.
1194 data.add(&address_);
1195 data.add(&valid_lifetime_);
1196 data.add(&expire_);
1197 data.add(&subnet_id_);
1198 data.add(&pref_lifetime_);
1199 data.add(&duid_);
1200 data.add(&iaid_);
1201 data.add(&lease_type_);
1202 data.add(&prefix_len_);
1203 data.add(&fqdn_fwd_);
1204 data.add(&fqdn_rev_);
1205 data.add(&hostname_);
1206 data.add(&hwaddr_);
1207 data.add(&hwtype_);
1208 data.add(&hwaddr_source_);
1209 data.add(&state_);
1210 data.add(&user_context_);
1211
1212 } catch (const Exception &ex) {
1213 isc_throw(DbOperationError, "CqlLease6Exchange::createBindForInsert(): "
1214 "could not create bind array from Lease6: " << lease_->addr_.toText()
1215 << ", reason: " << ex.what());
1216 }
1217}
1218
1219void
1221 StatementTag /* unused */) {
1222 if (!lease) {
1223 isc_throw(BadValue, "CqlLease6Exchange::createBindForUpdate(): "
1224 "Lease6 object is NULL");
1225 }
1226 // Store lease object to ensure it remains valid.
1227 lease_ = lease;
1228
1229 // Set up the structures for the various components of the lease4
1230 // structure.
1231 try {
1232 // address: varchar
1233 address_ = lease_->addr_.toText();
1234 if (address_.size() > ADDRESS6_TEXT_MAX_LEN) {
1236 "address " << address_ << " of length " << address_.size()
1237 << " exceeds maximum allowed length of "
1238 << ADDRESS6_TEXT_MAX_LEN);
1239 }
1240
1241 // valid lifetime: bigint
1242 valid_lifetime_ = static_cast<cass_int64_t>(lease_->valid_lft_);
1243
1244 // expire: bigint
1245 // The lease structure holds the client last transmission time
1246 // (cltt_)
1247 // For convenience for external tools, this is converted to lease
1248 // expiry time (expire). The relationship is given by:
1249 // expire = cltt_ + valid_lft_
1250 CqlExchange::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_,
1251 expire_);
1252
1253 // subnet_id: int
1254 subnet_id_ = static_cast<cass_int32_t>(lease_->subnet_id_);
1255
1256 // pref_lifetime: bigint
1257 pref_lifetime_ = static_cast<cass_int64_t>(lease_->preferred_lft_);
1258
1259 // duid: blob
1260 if (!lease_->duid_) {
1262 "lease6 with address " << address_
1263 << " is missing mandatory duid");
1264 }
1265 duid_ = lease_->duid_->getDuid();
1266
1267 // iaid: int
1268 iaid_ = static_cast<cass_int32_t>(lease_->iaid_);
1269
1270 // lease_type: int
1271 lease_type_ = static_cast<cass_int32_t>(lease_->type_);
1272
1273 // prefix_len: int
1274 prefix_len_ = static_cast<cass_int32_t>(lease_->prefixlen_);
1275
1276 // fqdn_fwd: boolean
1277 fqdn_fwd_ = lease_->fqdn_fwd_ ? cass_true : cass_false;
1278
1279 // fqdn_rev: boolean
1280 fqdn_rev_ = lease_->fqdn_rev_ ? cass_true : cass_false;
1281
1282 // hostname: varchar
1283 if (lease_->hostname_.size() > HOSTNAME_MAX_LEN) {
1285 "hostname" << lease_->hostname_ << " of length "
1286 << lease_->hostname_.size()
1287 << " exceeds maximum allowed length of "
1288 << HOSTNAME_MAX_LEN);
1289 }
1290 hostname_ = lease_->hostname_;
1291
1292 // hwaddr: blob
1293 if (lease_->hwaddr_ && lease_->hwaddr_->hwaddr_.size() > 0) {
1294 if (lease_->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
1296 "hardware address "
1297 << lease_->hwaddr_->toText() << " of length "
1298 << lease_->hwaddr_->hwaddr_.size()
1299 << " exceeds maximum allowed length of "
1301 }
1302 hwaddr_ = lease_->hwaddr_->hwaddr_;
1303 } else {
1304 hwaddr_.clear();
1305 }
1306
1307 // hwtype: int
1308 if (lease_->hwaddr_) {
1309 hwtype_ = static_cast<cass_int32_t>(lease_->hwaddr_->htype_);
1310 } else {
1311 hwtype_ = 0;
1312 }
1313
1314 // hwaddr_source: int
1315 if (lease_->hwaddr_) {
1316 hwaddr_source_ = static_cast<cass_int32_t>(lease_->hwaddr_->source_);
1317 } else {
1318 hwaddr_source_ = 0;
1319 }
1320
1321 // state: int
1322 state_ = static_cast<cass_int32_t>(lease_->state_);
1323
1324 // user_context: text
1325 ConstElementPtr ctx = lease_->getContext();
1326 if (ctx) {
1327 user_context_ = ctx->str();
1328 } else {
1329 user_context_ = NULL_USER_CONTEXT;
1330 }
1331
1332 // Start with a fresh array.
1333 data.clear();
1334
1335 // Add them all to data.
1336 data.add(&valid_lifetime_);
1337 data.add(&expire_);
1338 data.add(&pref_lifetime_);
1339 data.add(&duid_);
1340 data.add(&iaid_);
1341 data.add(&subnet_id_);
1342 data.add(&lease_type_);
1343 data.add(&prefix_len_);
1344 data.add(&fqdn_fwd_);
1345 data.add(&fqdn_rev_);
1346 data.add(&hostname_);
1347 data.add(&hwaddr_);
1348 data.add(&hwtype_);
1349 data.add(&hwaddr_source_);
1350 data.add(&state_);
1351 data.add(&user_context_);
1352 data.add(&address_);
1353
1354 } catch (const Exception &ex) {
1356 "CqlLease6Exchange::createBindForUpdate(): "
1357 "could not create bind array from Lease6: "
1358 << lease_->addr_.toText() << ", reason: " << ex.what());
1359 }
1360}
1361
1362void
1364 StatementTag /* unused */) {
1365
1366 // Set up the structures for the various components of the lease4
1367 // structure.
1368 try {
1369 // address: varchar
1370 address_ = address.toText();
1371
1372 // Start with a fresh array.
1373 data.clear();
1374 data.add(&address_);
1375
1376 } catch (const Exception &ex) {
1378 "CqlLease6Exchange::createBindForDelete(): "
1379 "could not create bind array with address: "
1380 << address_ << ", reason: " << ex.what());
1381 }
1382}
1383
1384void
1386
1387 // Start with a fresh array.
1388 data.clear();
1389
1390 // address: varchar
1391 data.add(&address_);
1392
1393 // valid_lifetime_: bigint
1394 data.add(&valid_lifetime_);
1395
1396 // expire: bigint
1397 data.add(&expire_);
1398
1399 // subnet_id: int
1400 data.add(&subnet_id_);
1401
1402 // pref_lifetime: bigint
1403 data.add(&pref_lifetime_);
1404
1405 // duid: blob
1406 data.add(&duid_);
1407
1408 // iaid: int
1409 data.add(&iaid_);
1410
1411 // lease_type: int
1412 data.add(&lease_type_);
1413
1414 // prefix_len: int
1415 data.add(&prefix_len_);
1416
1417 // fqdn_fwd: boolean
1418 data.add(&fqdn_fwd_);
1419
1420 // fqdn_rev: boolean
1421 data.add(&fqdn_rev_);
1422
1423 // hostname: varchar
1424 data.add(&hostname_);
1425
1426 // hwaddr: blob
1427 data.add(&hwaddr_);
1428
1429 // hwtype: int
1430 data.add(&hwtype_);
1431
1432 // hwaddr_source: int
1433 data.add(&hwaddr_source_);
1434
1435 // state: int
1436 data.add(&state_);
1437
1438 // user_context: text
1439 data.add(&user_context_);
1440}
1441
1442boost::any
1444 try {
1445 // Sanity checks
1446 if (address_.size() > ADDRESS6_TEXT_MAX_LEN) {
1448 "address " << address_ << " of length " << address_.size()
1449 << " exceeds maximum allowed length of "
1450 << ADDRESS6_TEXT_MAX_LEN);
1451 }
1452 if (duid_.size() > DUID::MAX_DUID_LEN) {
1454 "duid " << DUID(duid_).toText() << " of length "
1455 << duid_.size()
1456 << " exceeds maximum allowed length of "
1458 }
1459 if (lease_type_ != Lease::TYPE_NA && lease_type_ != Lease::TYPE_TA &&
1460 lease_type_ != Lease::TYPE_PD) {
1462 "invalid lease type "
1463 << lease_type_ << " for lease with address "
1464 << address_ << ". Expected 0, 1 or 2.");
1465 }
1466 if (hostname_.size() > HOSTNAME_MAX_LEN) {
1468 "hostname " << hostname_ << " of length "
1469 << hostname_.size()
1470 << " exceeds maximum allowed length of "
1471 << HOSTNAME_MAX_LEN);
1472 }
1473 if (hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
1475 "hwaddr " << HWAddr(hwaddr_, hwtype_).toText(false)
1476 << " of length " << hwaddr_.size()
1477 << " exceeds maximum allowed length of "
1479 }
1480
1481 IOAddress addr(address_);
1482
1483 DuidPtr duid(new DUID(duid_));
1484
1485 HWAddrPtr hwaddr;
1486 if (hwaddr_.size()) {
1487 hwaddr.reset(new HWAddr(hwaddr_, hwtype_));
1488 hwaddr->source_ = hwaddr_source_;
1489 }
1490
1491 ConstElementPtr ctx;
1492 if (!user_context_.empty()) {
1494 if (!ctx ||(ctx->getType() != Element::map)) {
1495 isc_throw(BadValue, "user context '" << user_context_
1496 << "' is not a JSON map");
1497 }
1498 }
1499
1500 // Create the lease and set the cltt (after converting from the
1501 // expire time retrieved from the database).
1502 Lease6Ptr result(
1503 new Lease6(static_cast<Lease::Type>(lease_type_), addr, duid, iaid_,
1504 pref_lifetime_, valid_lifetime_, 0, 0, subnet_id_,
1505 fqdn_fwd_, fqdn_rev_, hostname_, hwaddr, prefix_len_));
1506
1507 time_t cltt = 0;
1509 result->cltt_ = cltt;
1510
1511 result->state_ = state_;
1512
1513 if (ctx) {
1514 result->setContext(ctx);
1515 }
1516
1517 return (result);
1518 } catch (const Exception &ex) {
1520 "CqlLease6Exchange::retrieve(): "
1521 "could not convert data to Lease6, reason: "
1522 << ex.what());
1523 }
1524 return Lease6Ptr();
1525}
1526
1527void
1529 Lease6Collection &result) {
1530 AnyArray collection = executeSelect(connection_, data, statement_tag);
1531
1532 // Transfer Lease6 objects to result.
1533 for (boost::any &lease : collection) {
1534 result.push_back(boost::any_cast<Lease6Ptr>(lease));
1535 }
1536}
1537
1538void
1540 Lease6Ptr &result) {
1541 // This particular method is called when only one or zero matches is
1542 // expected.
1543 Lease6Collection collection;
1544 getLeaseCollection(statement_tag, data, collection);
1545
1546 // Return single record if present, else clear the lease.
1547 const size_t collection_size = collection.size();
1548 if (collection_size >= 2u) {
1550 "CqlLease6Exchange::getLease(): multiple records were found in "
1551 "the database where only one was expected for statement "
1552 << statement_tag);
1553 } else if (collection_size == 0u) {
1554 result.reset();
1555 } else {
1556 result = *collection.begin();
1557 }
1558}
1559
1560void
1562 Lease6Collection &expired_leases) {
1563 // Set up the WHERE clause value
1564 cass_int32_t keep_state = Lease::STATE_EXPIRED_RECLAIMED;
1565 cass_int64_t timestamp = static_cast<cass_int64_t>(time(NULL));
1566
1567 // If the number of leases is 0, we will return all leases. This is
1568 // achieved by setting the limit to a very high value.
1569 cass_int32_t limit = max_leases > 0u ?
1570 static_cast<cass_int32_t>(max_leases) :
1571 std::numeric_limits<cass_int32_t>::max();
1572
1573 for (cass_int32_t state = Lease::STATE_DEFAULT;
1574 state <= Lease::STATE_EXPIRED_RECLAIMED; state++) {
1575 if (state == keep_state) {
1576 continue;
1577 }
1578
1579 AnyArray data;
1580 data.add(&state);
1581 data.add(&timestamp);
1582 data.add(&limit);
1583
1584 // Retrieve leases from the database.
1585 Lease6Collection temp_collection;
1587 temp_collection);
1588
1589 for (Lease6Ptr &lease : temp_collection) {
1590 expired_leases.push_back(lease);
1591 }
1592 }
1593}
1594
1601public:
1611 const bool fetch_type)
1612 : conn_(conn), statement_(statement), fetch_type_(fetch_type),
1613 cummulative_rows_(), next_row_(cummulative_rows_.begin()),
1614 subnet_id_(0), lease_type_(0), lease_state_(0) {
1615 }
1616
1627 const bool fetch_type, const SubnetID& subnet_id)
1628 : LeaseStatsQuery(subnet_id), conn_(conn), statement_(statement),
1629 fetch_type_(fetch_type), cummulative_rows_(),
1630 next_row_(cummulative_rows_.begin()),
1631 subnet_id_(0), lease_type_(0), lease_state_(0) {
1632 }
1633
1646 const bool fetch_type, const SubnetID& first_subnet_id,
1647 const SubnetID& last_subnet_id)
1648 : LeaseStatsQuery(first_subnet_id, last_subnet_id), conn_(conn),
1649 statement_(statement), fetch_type_(fetch_type), cummulative_rows_(),
1650 next_row_(cummulative_rows_.begin()),
1651 subnet_id_(0), lease_type_(0), lease_state_(0) {
1652 }
1653
1656
1663 void start();
1664
1691 void executeSelect(const CqlConnection& connection, const AnyArray& data,
1692 StatementTag statement_tag);
1693
1705 bool getNextRow(LeaseStatsRow& row);
1706
1714 virtual void
1715 createBindForSelect(AnyArray& data, StatementTag statement_tag = NULL);
1716
1719 // Return lease4 lease statistics for all subnets
1720 static constexpr StatementTag ALL_LEASE4_STATS = "ALL_LEASE4_STATS";
1722 static constexpr StatementTag SUBNET_LEASE4_STATS = "SUBNET_LEASE4_STATS";
1724 static constexpr StatementTag SUBNET_RANGE_LEASE4_STATS = "SUBNET_RANGE_LEASE4_STATS";
1725
1726 // Return lease6 lease statistics for all subnets
1727 static constexpr StatementTag ALL_LEASE6_STATS = "ALL_LEASE6_STATS";
1729 static constexpr StatementTag SUBNET_LEASE6_STATS = "SUBNET_LEASE6_STATS";
1731 static constexpr StatementTag SUBNET_RANGE_LEASE6_STATS = "SUBNET_RANGE_LEASE6_STATS";
1733
1736
1737private:
1739 CqlConnection& conn_;
1740
1742 StatementTag statement_;
1743
1745 bool fetch_type_;
1746
1747
1749 std::map<LeaseStatsRow, int> cummulative_rows_;
1750
1752 std::map<LeaseStatsRow, int>::iterator next_row_;
1753
1755 int subnet_id_;
1757 int lease_type_;
1759 int lease_state_;
1760};
1761
1768
1770 // Return subnet_id and state of each v4 lease
1771 {ALL_LEASE4_STATS,
1772 {ALL_LEASE4_STATS,
1773 "SELECT "
1774 "subnet_id, state "
1775 "FROM lease4 "
1776 }},
1777
1778 // Return state of each v4 lease for a single subnet
1779 {SUBNET_LEASE4_STATS,
1780 {SUBNET_LEASE4_STATS,
1781 "SELECT "
1782 "subnet_id, state "
1783 "FROM lease4 "
1784 "WHERE subnet_id = ? "
1785 }},
1786
1787 // Return state of each v4 lease for a subnet range
1788 {SUBNET_RANGE_LEASE4_STATS,
1789 {SUBNET_RANGE_LEASE4_STATS,
1790 "SELECT "
1791 "subnet_id, state "
1792 "FROM lease4 "
1793 "WHERE subnet_id >= ? and subnet_id <= ? "
1794 "ALLOW FILTERING "
1795 }},
1796
1797 // Return subnet_id, lease_type, and state of each v6 lease
1798 {ALL_LEASE6_STATS,
1799 {ALL_LEASE6_STATS,
1800 "SELECT "
1801 "subnet_id, lease_type, state "
1802 "FROM lease6 "
1803 }},
1804
1805 // Return type and state of each v6 lease for a single subnet
1806 {SUBNET_LEASE6_STATS,
1807 {SUBNET_LEASE6_STATS,
1808 "SELECT "
1809 "subnet_id, lease_type, state "
1810 "FROM lease6 "
1811 "WHERE subnet_id = ? "
1812 }},
1813
1814 // Return type and state of each v6 lease for single range
1815 {SUBNET_RANGE_LEASE6_STATS,
1816 {SUBNET_RANGE_LEASE6_STATS,
1817 "SELECT "
1818 "subnet_id, lease_type, state "
1819 "FROM lease6 "
1820 "WHERE subnet_id >= ? and subnet_id <= ? "
1821 "ALLOW FILTERING "
1822 }},
1823
1824};
1825
1826void
1828
1829 // Set up where clause parameters as needed
1830 AnyArray data;
1831 cass_int32_t first_subnet_id_data;
1832 cass_int32_t last_subnet_id_data;
1833 if (getSelectMode() != ALL_SUBNETS) {
1834 first_subnet_id_data = static_cast<cass_int32_t>(first_subnet_id_);
1835 data.add(&first_subnet_id_data);
1836
1837 if (getSelectMode() == SUBNET_RANGE) {
1838 last_subnet_id_data = static_cast<cass_int32_t>(last_subnet_id_);
1839 data.add(&last_subnet_id_data);
1840 }
1841 }
1842
1843 // This gets a collection of "raw" data for all leases that match
1844 // the subnet selection criteria (all, range, or single subnets)
1845 // then rolls them up into cummulative_rows_
1846 executeSelect(conn_, data, statement_);
1847
1848 // Set our row iterator to the beginning
1849 next_row_ = cummulative_rows_.begin();
1850}
1851
1852bool
1854 // If we're past the end, punt.
1855 if (next_row_ == cummulative_rows_.end()) {
1856 return (false);
1857 }
1858
1859 // Start by copying from the map row key
1860 row.subnet_id_ = next_row_->first.subnet_id_;
1861 row.lease_type_ = next_row_->first.lease_type_;
1862 row.lease_state_ = next_row_->first.lease_state_;
1863
1864 // Grab the count from the map value
1865 row.state_count_ = next_row_->second;
1866
1867 // Point to the next row.
1868 ++next_row_;
1869 return (true);
1870}
1871
1872void
1874 data.clear();
1875 data.add(&subnet_id_);
1876 if (fetch_type_) {
1877 data.add(&lease_type_);
1878 }
1879
1880 data.add(&lease_state_);
1881}
1882
1883void
1885 StatementTag statement_tag) {
1886 CassError rc;
1887 CassStatement* statement = NULL;
1888 CassFuture* future = NULL;
1889 AnyArray local_data = data;
1890
1891 // Find the query statement first.
1892 StatementMap::const_iterator it = connection.statements_.find(statement_tag);
1893 if (it == connection.statements_.end()) {
1895 "CqlLeastStatsQuery::executeSelect(): Statement "
1896 << statement_tag << "has not been prepared.");
1897 }
1898
1899 // Bind the data before the query is executed.
1900 CqlTaggedStatement tagged_statement = it->second;
1901 if (tagged_statement.is_raw_) {
1902 // The entire query is the first element in data.
1903 std::string* query = boost::any_cast<std::string*>(local_data.back());
1904 local_data.pop_back();
1905 statement = cass_statement_new(query->c_str(), local_data.size());
1906 } else {
1907 statement = cass_prepared_bind(tagged_statement.prepared_statement_);
1908 if (!statement) {
1910 "CqlLeaseStatsQuery::executeSelect(): unable to bind statement "
1911 << tagged_statement.name_);
1912 }
1913 }
1914
1915 // Set specific level of consistency if we're told to do so.
1916 if (connection.force_consistency_) {
1917 rc = cass_statement_set_consistency(statement, connection.consistency_);
1918 if (rc != CASS_OK) {
1919 cass_statement_free(statement);
1921 "CqlLeaseStatsQuery::executeSelect(): unable to set statement "
1922 "consistency for statement "
1923 << tagged_statement.name_
1924 << ", Cassandra error code: " << cass_error_desc(rc));
1925 }
1926 }
1927
1928 CqlCommon::bindData(local_data, statement);
1929
1930 // Everything's ready. Call the actual statement.
1931 future = cass_session_execute(connection.session_, statement);
1932 if (!future) {
1933 cass_statement_free(statement);
1935 "CqlLeaseStatsQuery::executeSelect(): no CassFuture for statement "
1936 << tagged_statement.name_);
1937 }
1938
1939 // Wait for the statement execution to complete.
1940 cass_future_wait(future);
1941 const std::string error = connection.checkFutureError(
1942 "CqlLeaseStatsQuery::executeSelect(): cass_session_execute() != CASS_OK",
1943 future, statement_tag);
1944 rc = cass_future_error_code(future);
1945 if (rc != CASS_OK) {
1946 cass_future_free(future);
1947 cass_statement_free(statement);
1949 }
1950
1951 // Get column values.
1952 const CassResult* result_collection = cass_future_get_result(future);
1953
1954 // lease type is always NA for v4
1955 if (!fetch_type_) {
1956 lease_type_ = Lease::TYPE_NA;
1957 }
1958
1959 // Since we're currently forced to pull data for all leases, we
1960 // iterate over them, aggregating them into cummulative LeaseStatsRows
1961 AnyArray return_values;
1962 CassIterator* rows = cass_iterator_from_result(result_collection);
1963 while (cass_iterator_next(rows)) {
1964 const CassRow* row = cass_iterator_get_row(rows);
1965 createBindForSelect(return_values, statement_tag);
1966 CqlCommon::getData(row, return_values);
1967
1968 if (lease_state_ != Lease::STATE_DEFAULT &&
1969 lease_state_ != Lease::STATE_DECLINED) {
1970 continue;
1971 }
1972
1973 LeaseStatsRow raw_row(subnet_id_, static_cast<Lease::Type>(lease_type_),
1974 lease_state_, 1);
1975
1976 auto cum_row = cummulative_rows_.find(raw_row);
1977 if (cum_row != cummulative_rows_.end()) {
1978 cummulative_rows_[raw_row] = cum_row->second + 1;
1979 } else {
1980 cummulative_rows_.insert(std::make_pair(raw_row, 1));
1981 }
1982 }
1983
1984 // Free resources.
1985 cass_iterator_free(rows);
1986 cass_result_free(result_collection);
1987 cass_future_free(future);
1988 cass_statement_free(statement);
1989 return;
1990}
1991
1993 : LeaseMgr(), dbconn_(parameters) {
1994 dbconn_.openDatabase();
1995
1996 // Prepare the version exchange first.
1998
1999 // Validate the schema version.
2000 std::pair<uint32_t, uint32_t> code_version(CQL_SCHEMA_VERSION_MAJOR,
2002 std::pair<uint32_t, uint32_t> db_version = getVersion();
2003 if (code_version != db_version) {
2004 isc_throw(DbOpenError, "Cassandra schema version mismatch: need version: "
2005 << code_version.first << "." << code_version.second
2006 << " found version: " << db_version.first << "."
2007 << db_version.second);
2008 }
2009
2010 // Now prepare the rest of the exchanges.
2014}
2015
2017 // There is no need to close the database in this destructor: it is
2018 // closed in the destructor of the dbconn_ member variable.
2019}
2020
2021std::string
2023 std::stringstream tmp;
2024 tmp << "CQL backend " << CQL_SCHEMA_VERSION_MAJOR;
2025 tmp << "." << CQL_SCHEMA_VERSION_MINOR;
2026 tmp << ", library cassandra";
2027 return tmp.str();
2028}
2029
2030bool
2032 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_ADD_ADDR4)
2033 .arg(lease->addr_.toText());
2034
2035 AnyArray data;
2036
2037 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2038 exchange4->createBindForInsert(lease, data);
2039 try {
2040 exchange4->executeMutation(dbconn_, data, CqlLease4Exchange::INSERT_LEASE4);
2041 } catch (const Exception &exception) {
2042 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_LEASE_EXCEPTION_THROWN)
2043 .arg(exception.what());
2044 return false;
2045 }
2046 return true;
2047}
2048
2049bool
2051 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_ADD_ADDR6)
2052 .arg(lease->addr_.toText());
2053
2054 AnyArray data;
2055
2056 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2057 exchange6->createBindForInsert(lease, data);
2058 try {
2059 exchange6->executeMutation(dbconn_, data, CqlLease6Exchange::INSERT_LEASE6);
2060 } catch (const Exception &exception) {
2061 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_LEASE_EXCEPTION_THROWN)
2062 .arg(exception.what());
2063 return false;
2064 }
2065 return true;
2066}
2067
2070 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_ADDR4)
2071 .arg(addr.toText());
2072
2073 // Set up the WHERE clause value
2074 AnyArray data;
2075
2076 cass_int32_t address = static_cast<cass_int32_t>(addr.toUint32());
2077 data.add(&address);
2078
2079 // Get the data.
2080 Lease4Ptr result;
2081
2082 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2083 exchange4->getLease(CqlLease4Exchange::GET_LEASE4_ADDR, data, result);
2084
2085 return (result);
2086}
2087
2089CqlLeaseMgr::getLease4(const HWAddr &hwaddr) const {
2090 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_HWADDR)
2091 .arg(hwaddr.toText());
2092
2093 // Set up the WHERE clause value
2094 AnyArray data;
2095
2096 CassBlob hwaddr_data(hwaddr.hwaddr_);
2097 data.add(&hwaddr_data);
2098
2099 // Get the data.
2100 Lease4Collection result;
2101 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2102 exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4_HWADDR, data, result);
2103
2104 return (result);
2105}
2106
2108CqlLeaseMgr::getLease4(const HWAddr &hwaddr, SubnetID subnet_id) const {
2110 DHCPSRV_CQL_GET_SUBID_HWADDR)
2111 .arg(subnet_id)
2112 .arg(hwaddr.toText());
2113
2114 // Set up the WHERE clause value
2115 AnyArray data;
2116
2117 CassBlob hwaddr_data(hwaddr.hwaddr_);
2118 data.add(&hwaddr_data);
2119
2120 cass_int32_t subnet_id_data = static_cast<cass_int32_t>(subnet_id);
2121 data.add(&subnet_id_data);
2122
2123 // Get the data.
2124 Lease4Ptr result;
2125 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2126 exchange4->getLease(CqlLease4Exchange::GET_LEASE4_HWADDR_SUBID, data, result);
2127
2128 return (result);
2129}
2130
2132CqlLeaseMgr::getLease4(const ClientId &clientid) const {
2133 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_CLIENTID)
2134 .arg(clientid.toText());
2135
2136 // Set up the WHERE clause value
2137 AnyArray data;
2138
2139 CassBlob client_id_data(clientid.getClientId());
2140 data.add(&client_id_data);
2141
2142 // Get the data.
2143 Lease4Collection result;
2144 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2145 exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4_CLIENTID, data, result);
2146
2147 return (result);
2148}
2149
2151CqlLeaseMgr::getLease4(const ClientId &clientid, const HWAddr &hwaddr,
2152 SubnetID subnet_id) const {
2158 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_CLIENTID_HWADDR_SUBID)
2159 .arg(clientid.toText())
2160 .arg(hwaddr.toText())
2161 .arg(subnet_id);
2162
2163 isc_throw(NotImplemented, "CqlLeaseMgr::getLease4() is obsolete");
2164}
2165
2167CqlLeaseMgr::getLease4(const ClientId &clientid, SubnetID subnet_id) const {
2168 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_SUBID_CLIENTID)
2169 .arg(subnet_id)
2170 .arg(clientid.toText());
2171
2172 // Set up the WHERE clause value
2173 AnyArray data;
2174
2175 CassBlob client_id_data(clientid.getClientId());
2176 data.add(&client_id_data);
2177
2178 cass_int32_t subnet_id_data = static_cast<cass_int32_t>(subnet_id);
2179 data.add(&subnet_id_data);
2180
2181 // Get the data.
2182 Lease4Ptr result;
2183 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2184 exchange4->getLease(CqlLease4Exchange::GET_LEASE4_CLIENTID_SUBID, data, result);
2185
2186 return (result);
2187}
2188
2191 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_SUBID4)
2192 .arg(subnet_id);
2193
2194 // Set up the WHERE clause value
2195 AnyArray data;
2196
2197 cass_int32_t subnet_id_data = static_cast<cass_int32_t>(subnet_id);
2198 data.add(&subnet_id_data);
2199
2200 // Get the data.
2201 Lease4Collection result;
2202 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2203 exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4_SUBID, data, result);
2204
2205 return (result);
2206}
2207
2211
2212 // Set up the WHERE clause value
2213 AnyArray data;
2214
2215 // Get the data.
2216 Lease4Collection result;
2217 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2218 exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4, data, result);
2219
2220 return (result);
2221}
2222
2225 const LeasePageSize& page_size) const {
2226 // Expecting IPv4 address.
2227 if (!lower_bound_address.isV4()) {
2228 isc_throw(InvalidAddressFamily, "expected IPv4 address while "
2229 "retrieving leases from the lease database, got "
2230 << lower_bound_address);
2231 }
2232
2233 if (page_size.page_size_ == 0) {
2234 isc_throw(OutOfRange, "page size of retrieved leases must not be 0");
2235 }
2236
2237 if (page_size.page_size_ > std::numeric_limits<uint32_t>::max()) {
2238 isc_throw(OutOfRange, "page size of retrieved leases must not be greater than "
2239 << std::numeric_limits<uint32_t>::max());
2240 }
2241
2242 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_PAGE4)
2243 .arg(page_size.page_size_)
2244 .arg(lower_bound_address.toText());
2245
2246 AnyArray data;
2247
2248 cass_int32_t address_data = 0;
2249 if (!lower_bound_address.isV4Zero()) {
2250 address_data = static_cast<cass_int32_t>(lower_bound_address.toUint32());
2251 data.add(&address_data);
2252 }
2253
2254 cass_int32_t page_size_data = static_cast<cass_int32_t>(page_size.page_size_);
2255 data.add(&page_size_data);
2256
2257 // Get the data.
2258 Lease4Collection result;
2259 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2260 exchange4->getLeaseCollection(lower_bound_address.isV4Zero() ?
2263 data, result);
2264
2265 return (result);
2266}
2267
2269CqlLeaseMgr::getLease6(Lease::Type lease_type, const IOAddress &addr) const {
2270 std::string addr_data = addr.toText();
2271 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_ADDR6)
2272 .arg(addr_data)
2273 .arg(lease_type);
2274
2275 // Set up the WHERE clause value
2276 AnyArray data;
2277
2278 if (addr_data.size() > ADDRESS6_TEXT_MAX_LEN) {
2280 "CqlLeaseMgr::getLease6(): "
2281 "address "
2282 << addr_data << " of length " << addr_data.size()
2283 << " exceeds maximum allowed length of "
2284 << ADDRESS6_TEXT_MAX_LEN);
2285 }
2286 data.add(&addr_data);
2287
2288 cass_int32_t lease_type_data = static_cast<cass_int32_t>(lease_type);
2289 data.add(&lease_type_data);
2290
2291 Lease6Ptr result;
2292 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2293 exchange6->getLease(CqlLease6Exchange::GET_LEASE6_ADDR, data, result);
2294
2295 return (result);
2296}
2297
2299CqlLeaseMgr::getLeases6(const DUID& duid) const {
2300
2301 // Set up the WHERE clause value
2302 AnyArray data;
2303
2304 CassBlob duid_data(duid.getDuid());
2305
2306 data.add(&duid_data);
2307
2308 // Get the data.
2309 Lease6Collection result;
2310 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2311 exchange6->getLeaseCollection(CqlLease6Exchange::GET_LEASE6_DUID,
2312 data, result);
2313
2314 return (result);
2315}
2316
2318CqlLeaseMgr::getLeases6(Lease::Type lease_type, const DUID &duid, uint32_t iaid) const {
2319 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_IAID_DUID)
2320 .arg(iaid)
2321 .arg(duid.toText())
2322 .arg(lease_type);
2323
2324 // Set up the WHERE clause value
2325 AnyArray data;
2326
2327 CassBlob duid_data(duid.getDuid());
2328 cass_int32_t iaid_data = static_cast<cass_int32_t>(iaid);
2329
2330 data.add(&duid_data);
2331 data.add(&iaid_data);
2332
2333 cass_int32_t lease_type_data = static_cast<cass_int32_t>(lease_type);
2334 data.add(&lease_type_data);
2335
2336 // Get the data.
2337 Lease6Collection result;
2338 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2339 exchange6->getLeaseCollection(CqlLease6Exchange::GET_LEASE6_DUID_IAID, data, result);
2340
2341 return (result);
2342}
2343
2345CqlLeaseMgr::getLeases6(Lease::Type lease_type, const DUID &duid, uint32_t iaid,
2346 SubnetID subnet_id) const {
2347 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_IAID_SUBID_DUID)
2348 .arg(iaid)
2349 .arg(subnet_id)
2350 .arg(duid.toText())
2351 .arg(lease_type);
2352
2353 // Set up the WHERE clause value
2354 AnyArray data;
2355
2356 CassBlob duid_data(duid.getDuid());
2357 cass_int32_t iaid_data = static_cast<cass_int32_t>(iaid);
2358
2359 data.add(&duid_data);
2360 data.add(&iaid_data);
2361
2362 cass_int32_t lease_type_data = static_cast<cass_int32_t>(lease_type);
2363 data.add(&lease_type_data);
2364
2365 cass_int32_t subnet_id_data = static_cast<cass_int32_t>(subnet_id);
2366 data.add(&subnet_id_data);
2367
2368 // Get the data.
2369 Lease6Collection result;
2370 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2371 exchange6->getLeaseCollection(CqlLease6Exchange::GET_LEASE6_DUID_IAID_SUBID, data, result);
2372
2373 return (result);
2374}
2375
2378 isc_throw(NotImplemented, "getLeases6(subnet_id) is not implemented");
2379}
2380
2383 isc_throw(NotImplemented, "getLeases6() is not implemented");
2384}
2385
2388 const LeasePageSize& page_size) const {
2389 // Expecting IPv6 address.
2390 if (!lower_bound_address.isV6()) {
2391 isc_throw(InvalidAddressFamily, "expected IPv6 address while "
2392 "retrieving leases from the lease database, got "
2393 << lower_bound_address);
2394 }
2395
2396 if (page_size.page_size_ == 0) {
2397 isc_throw(OutOfRange, "page size of retrieved leases must not be 0");
2398 }
2399
2400 if (page_size.page_size_ > std::numeric_limits<uint32_t>::max()) {
2401 isc_throw(OutOfRange, "page size of retrieved leases must not be greater than "
2402 << std::numeric_limits<uint32_t>::max());
2403 }
2404
2405 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_PAGE6)
2406 .arg(page_size.page_size_)
2407 .arg(lower_bound_address.toText());
2408
2409 AnyArray data;
2410
2411 std::string lb_address_data;
2412 if (!lower_bound_address.isV6Zero()) {
2413 lb_address_data = lower_bound_address.toText();
2414 if (lb_address_data.size() > ADDRESS6_TEXT_MAX_LEN) {
2416 "CqlLeaseMgr::getLeases6(lower_bound_address, page_size): "
2417 "address "
2418 << lb_address_data << " of length " << lb_address_data.size()
2419 << " exceeds maximum allowed length of "
2420 << ADDRESS6_TEXT_MAX_LEN);
2421 }
2422 data.add(&lb_address_data);
2423 }
2424
2425 cass_int32_t page_size_data = static_cast<cass_int32_t>(page_size.page_size_);
2426 data.add(&page_size_data);
2427
2428 // Get the leases.
2429 Lease6Collection result;
2430 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2431 exchange6->getLeaseCollection(lower_bound_address.isV6Zero() ?
2434 data, result);
2435
2436 return (result);
2437}
2438
2439void
2441 const size_t max_leases) const {
2442 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_EXPIRED4)
2443 .arg(max_leases);
2444
2445 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2446 exchange4->getExpiredLeases(max_leases, expired_leases);
2447}
2448
2449void
2451 const size_t max_leases) const {
2452 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_EXPIRED6)
2453 .arg(max_leases);
2454
2455 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2456 exchange6->getExpiredLeases(max_leases, expired_leases);
2457}
2458
2459void
2461 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_UPDATE_ADDR4)
2462 .arg(lease->addr_.toText());
2463
2464 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2465
2466 try {
2467 AnyArray data;
2468 exchange4->createBindForUpdate(lease, data, CqlLease4Exchange::UPDATE_LEASE4);
2469 exchange4->executeMutation(dbconn_, data, CqlLease4Exchange::UPDATE_LEASE4);
2470 } catch (const StatementNotApplied &exception) {
2471 isc_throw(NoSuchLease, exception.what());
2472 }
2473}
2474
2475void
2477 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_UPDATE_ADDR6)
2478 .arg(lease->addr_.toText());
2479
2480 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2481
2482 try {
2483 AnyArray data;
2484 exchange6->createBindForUpdate(lease, data, CqlLease6Exchange::UPDATE_LEASE6);
2485 exchange6->executeMutation(dbconn_, data, CqlLease6Exchange::UPDATE_LEASE6);
2486 } catch (const StatementNotApplied &exception) {
2487 isc_throw(NoSuchLease, exception.what());
2488 }
2489}
2490
2491bool
2493 std::string addr_data = addr.toText();
2494 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_DELETE_ADDR)
2495 .arg(addr_data);
2496
2497 // Set up the WHERE clause value
2498 AnyArray data;
2499
2500 try {
2501 if (addr.isV4()) {
2502 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2503 exchange4->createBindForDelete(addr, data, CqlLease4Exchange::DELETE_LEASE4);
2504 exchange4->executeMutation(dbconn_, data, CqlLease4Exchange::DELETE_LEASE4);
2505 } else if (addr.isV6()) {
2506 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2507 exchange6->createBindForDelete(addr, data, CqlLease6Exchange::DELETE_LEASE6);
2508 exchange6->executeMutation(dbconn_, data, CqlLease6Exchange::DELETE_LEASE6);
2509 } else {
2510 return false;
2511 }
2512 } catch (const Exception &exception) {
2513 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_LEASE_EXCEPTION_THROWN)
2514 .arg(exception.what());
2515 return false;
2516 }
2517 return true;
2518}
2519
2520uint64_t
2523 DHCPSRV_CQL_DELETE_EXPIRED_RECLAIMED4)
2524 .arg(secs);
2525 AnyArray data;
2526 uint64_t deleted = 0u;
2527 cass_int32_t limit = 1024;
2528
2529 // State is reclaimed.
2530 cass_int32_t state = static_cast<cass_int32_t>(Lease::STATE_EXPIRED_RECLAIMED);
2531 data.add(&state);
2532
2533 // Expiration timestamp.
2534 cass_int64_t expiration = static_cast<cass_int64_t>(time(NULL) - static_cast<time_t>(secs));
2535 data.add(&expiration);
2536
2537 data.add(&limit);
2538
2539 // Get the data.
2540 Lease4Collection leases;
2541 std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
2542 exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4_EXPIRE, data, leases);
2543 for (Lease4Ptr &lease : leases) {
2544 if (deleteLease(lease->addr_)) {
2545 ++deleted;
2546 }
2547 }
2548 return (deleted);
2549}
2550
2551uint64_t
2554 DHCPSRV_CQL_DELETE_EXPIRED_RECLAIMED6)
2555 .arg(secs);
2556 AnyArray data;
2557 uint64_t n_of_deleted_leases = 0u;
2558 cass_int32_t limit = 1024;
2559
2560 // State is reclaimed.
2561 cass_int32_t state = static_cast<cass_int32_t>(Lease::STATE_EXPIRED_RECLAIMED);
2562 data.add(&state);
2563
2564 // Expiration timestamp.
2565 cass_int64_t expiration = static_cast<cass_int64_t>(time(NULL) - static_cast<time_t>(secs));
2566 data.add(&expiration);
2567
2568 data.add(&limit);
2569
2570 // Get the data.
2571 Lease6Collection leases;
2572 std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
2573 exchange6->getLeaseCollection(CqlLease6Exchange::GET_LEASE6_EXPIRE, data, leases);
2574 for (Lease6Ptr &lease : leases) {
2575 if (deleteLease(lease->addr_)) {
2576 ++n_of_deleted_leases;
2577 }
2578 }
2579 return n_of_deleted_leases;
2580}
2581
2584 LeaseStatsQueryPtr query(
2586 false));
2587 query->start();
2588 return(query);
2589}
2590
2593 LeaseStatsQueryPtr query(
2595 false, subnet_id));
2596 query->start();
2597 return(query);
2598}
2599
2602 const SubnetID& last_subnet_id) {
2603 LeaseStatsQueryPtr query(
2605 false, first_subnet_id, last_subnet_id));
2606 query->start();
2607 return(query);
2608}
2609
2612 LeaseStatsQueryPtr query(
2614 true));
2615 query->start();
2616 return(query);
2617}
2618
2621 LeaseStatsQueryPtr query(
2623 true, subnet_id));
2624 query->start();
2625 return(query);
2626}
2627
2630 const SubnetID& last_subnet_id) {
2631 LeaseStatsQueryPtr query(
2633 true, first_subnet_id, last_subnet_id));
2634 query->start();
2635 return(query);
2636}
2637
2638size_t
2639CqlLeaseMgr::wipeLeases4(const SubnetID & /*subnet_id*/) {
2641 isc_throw(NotImplemented, "wipeLeases4 is not implemented for Cassandra backend");
2642}
2643
2644size_t
2645CqlLeaseMgr::wipeLeases6(const SubnetID & /*subnet_id*/) {
2647 isc_throw(NotImplemented, "wipeLeases6 is not implemented for Cassandra backend");
2648}
2649
2650std::string
2652 std::string name = "";
2653 try {
2654 name = dbconn_.getParameter("name");
2655 } catch (...) {
2656 // Return an empty name
2657 }
2658 return name;
2659}
2660
2661std::string
2663 return std::string("Cassandra Database");
2664}
2665
2668 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_VERSION);
2669
2670 std::unique_ptr<CqlVersionExchange> version_exchange(new CqlVersionExchange());
2671 return version_exchange->retrieveVersion(dbconn_);
2672}
2673
2674void
2677 dbconn_.commit();
2678}
2679
2680void
2682 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_ROLLBACK);
2683 dbconn_.rollback();
2684}
2685
2686} // namespace dhcp
2687} // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
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...
static ElementPtr fromJSON(const std::string &in, bool preproc=false)
These functions will parse the given string (JSON) representation of a compound element.
Definition: data.cc:750
Structure used to bind C++ input values to dynamic CQL parameters.
Definition: cql_exchange.h:50
void add(const boost::any &value)
Add a value at the end of the vector.
static void bindData(const AnyArray &data, CassStatement *statement)
Assigns values to every column of an INSERT or an UPDATE statement.
static void getData(const CassRow *row, AnyArray &data)
Retrieves data returned by Cassandra.
Common CQL connector pool.
StatementMap statements_
Pointer to external array of tagged statements containing statement name, array of names of bind para...
virtual void commit()
Commit Transactions.
virtual void rollback()
Rollback Transactions.
CassSession * session_
CQL session handle.
bool force_consistency_
CQL consistency enabled.
void openDatabase()
Open database.
CassConsistency consistency_
CQL consistency.
static const std::string checkFutureError(const std::string &what, CassFuture *future, StatementTag statement_tag=NULL)
Check for errors.
void prepareStatements(StatementMap &statements)
Prepare statements.
Cassandra Exchange.
Definition: cql_exchange.h:142
AnyArray executeSelect(const CqlConnection &connection, const AnyArray &where_values, StatementTag statement_tag, const bool &single=false)
Executes SELECT statements.
static void convertFromDatabaseTime(const cass_int64_t &expire, const cass_int64_t &valid_lifetime, time_t &cltt)
Converts time from Cassandra format.
static void convertToDatabaseTime(const time_t &cltt, const uint32_t &valid_lifetime, cass_int64_t &expire)
Exchange used to retrieve schema version from the keyspace.
Definition: cql_exchange.h:236
static StatementMap tagged_statements_
Cassandra statements.
Definition: cql_exchange.h:280
std::string getParameter(const std::string &name) const
Returns value of a connection parameter.
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.
Definition: db_exceptions.h:64
Multiple lease records found where one expected.
Definition: db_exceptions.h:28
Database statement not applied.
Definition: db_exceptions.h:20
Holds Client identifier or client IPv4 address.
Definition: duid.h:111
static const size_t MAX_CLIENT_ID_LEN
Maximum size of a client ID.
Definition: duid.h:128
const std::vector< uint8_t > & getClientId() const
Returns reference to the client-id data.
Definition: duid.cc:116
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Definition: duid.cc:121
Exchange Lease4 information between Kea and CQL.
static constexpr StatementTag GET_LEASE4_HWADDR_SUBID
static constexpr StatementTag GET_LEASE4_EXPIRE
void createBindForUpdate(const Lease4Ptr &lease, AnyArray &data, StatementTag statement_tag=NULL)
Create CQL_BIND objects for Lease4 Pointer.
static StatementMap tagged_statements_
Cassandra statements.
static constexpr StatementTag GET_LEASE4_PAGE
void createBindForDelete(const IOAddress &address, AnyArray &data, StatementTag statement_tag=NULL)
Create CQL_BIND objects for Lease4 Pointer.
void getLeaseCollection(StatementTag &statement_tag, AnyArray &data, Lease4Collection &result)
Retrieves zero or more IPv4 leases.
static constexpr StatementTag GET_LEASE4_LIMIT
void createBindForInsert(const Lease4Ptr &lease, AnyArray &data)
Create CQL_BIND objects for Lease4 Pointer.
void getLease(StatementTag &statement_tag, AnyArray &data, Lease4Ptr &result)
Retrieves one IPv4 lease.
virtual void createBindForSelect(AnyArray &data, StatementTag statement_tag=NULL) override
Create BIND array to receive data.
static constexpr StatementTag INSERT_LEASE4
Statement tags definitions.
CqlLease4Exchange(const CqlConnection &connection)
Constructor.
static constexpr StatementTag GET_LEASE4_CLIENTID_SUBID
static constexpr StatementTag UPDATE_LEASE4
virtual boost::any retrieve() override
Retrieves the Lease4 object in Kea format.
static constexpr StatementTag DELETE_LEASE4
static constexpr StatementTag GET_LEASE4
static constexpr StatementTag GET_LEASE4_ADDR
static constexpr StatementTag GET_LEASE4_SUBID
void getExpiredLeases(const size_t &max_leases, Lease4Collection &expired_leases)
Returns expired leases.
static constexpr StatementTag GET_LEASE4_CLIENTID
static constexpr StatementTag GET_LEASE4_HWADDR
Exchange Lease6 information between Kea and CQL.
static constexpr StatementTag DELETE_LEASE6
virtual boost::any retrieve() override
Retrieves the Lease6 object in Kea format.
static StatementMap tagged_statements_
Cassandra statements.
static constexpr StatementTag GET_LEASE6_DUID
static constexpr StatementTag UPDATE_LEASE6
void createBindForInsert(const Lease6Ptr &lease, AnyArray &data)
Create CQL_BIND objects for Lease6 Pointer.
void getLease(StatementTag &statement_tag, AnyArray &data, Lease6Ptr &result)
Retrieves one IPv6 lease.
void createBindForDelete(const IOAddress &address, AnyArray &data, StatementTag statement_tag=NULL)
Create CQL_BIND objects for Lease4 Pointer.
static constexpr StatementTag GET_LEASE6_PAGE
virtual void createBindForSelect(AnyArray &data, StatementTag statement_tag=NULL) override
Create BIND array to receive data.
void getExpiredLeases(const size_t &max_leases, Lease6Collection &expired_leases)
Returns expired leases.
static constexpr StatementTag INSERT_LEASE6
Statement tags definitions.
static constexpr StatementTag GET_LEASE6_EXPIRE
static constexpr StatementTag GET_LEASE6_DUID_IAID
static constexpr StatementTag GET_LEASE6_ADDR
void createBindForUpdate(const Lease6Ptr &lease, AnyArray &data, StatementTag statement_tag=NULL)
Create CQL_BIND objects for Lease6 Pointer.
void getLeaseCollection(StatementTag &statement_tag, AnyArray &data, Lease6Collection &result)
Retrieves zero or more IPv6 leases.
static constexpr StatementTag GET_LEASE6_LIMIT
CqlLease6Exchange(const CqlConnection &connection)
Constructor.
static constexpr StatementTag GET_LEASE6_DUID_IAID_SUBID
Common CQL and Lease Data Methods.
virtual void createBindForSelect(AnyArray &data, StatementTag statement_tag=NULL) override=0
Create BIND array to receive C++ data.
cass_bool_t fqdn_fwd_
Has forward DNS update been performed?
std::string user_context_
User context.
std::string hostname_
Client hostname.
cass_int64_t valid_lifetime_
Lease timer.
cass_int32_t subnet_id_
Subnet identifier.
cass_int32_t state_
Lease state.
cass_bool_t fqdn_rev_
Has reverse DNS update been performed?
cass_int64_t expire_
Lease expiry time.
virtual boost::any retrieve() override=0
Copy received data into the derived class' object.
const CqlConnection & connection_
Database connection.
CqlLeaseExchange(const CqlConnection &connection)
Constructor.
CassBlob hwaddr_
Hardware address.
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 LeaseStatsQueryPtr startLeaseStatsQuery4() override
Creates and runs the IPv4 lease stats query.
virtual Lease6Collection getLeases6() const override
Returns all IPv6 leases.
virtual void updateLease6(const Lease6Ptr &lease6) override
Updates IPv6 lease.
virtual std::string getDescription() const override
Returns description of the backend.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const override
Basic lease access methods.
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID &subnet_id) override
Creates and runs the IPv6 lease stats query for a single subnet.
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID &subnet_id) override
Creates and runs the IPv4 lease stats query for a single subnet.
static std::string getDBVersion()
Local version of getDBVersion() class method.
virtual std::string getName() const override
Returns name of the database.
virtual size_t wipeLeases4(const SubnetID &subnet_id) override
Removes specified IPv4 leases.
virtual void getExpiredLeases6(Lease6Collection &expired_leases, const size_t max_leases) const override
Returns a collection of expired DHCPv6 leases.
virtual bool addLease(const Lease4Ptr &lease) override
Adds an IPv4 lease.
virtual Lease4Collection getLeases4() const override
Returns all IPv4 leases.
virtual VersionPair getVersion() const override
Returns backend version.
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.
virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs) override
Deletes all expired and reclaimed DHCPv4 leases.
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 void rollback() override
Rollback Transactions.
virtual void updateLease4(const Lease4Ptr &lease4) override
Updates IPv4 lease.
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs) override
Deletes all expired and reclaimed DHCPv6 leases.
virtual bool deleteLease(const isc::asiolink::IOAddress &addr) override
Deletes a lease.
CqlLeaseMgr(const db::DatabaseConnection::ParameterMap &parameters)
Constructor.
virtual ~CqlLeaseMgr()
Destructor (closes database)
virtual void commit() override
Commit Transactions.
virtual LeaseStatsQueryPtr startLeaseStatsQuery6() override
Creates and runs the IPv6 lease stats query.
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const override
Returns existing IPv6 lease for a given IPv6 address.
Base CQL derivation of the statistical lease data query.
static constexpr StatementTag ALL_LEASE6_STATS
bool getNextRow(LeaseStatsRow &row)
Fetches the next row in the result set.
void executeSelect(const CqlConnection &connection, const AnyArray &data, StatementTag statement_tag)
Executes protocol specific lease query SELECT statement.
static StatementMap tagged_statements_
Cassandra statements.
static constexpr StatementTag SUBNET_LEASE4_STATS
Return lease4 lease statistics for a single subnet.
static constexpr StatementTag ALL_LEASE4_STATS
Statement tags definitions.
static constexpr StatementTag SUBNET_LEASE6_STATS
Return lease6 lease statistics for a single subnet.
static constexpr StatementTag SUBNET_RANGE_LEASE6_STATS
Return lease6 lease statistics for a range of subnets.
void start()
Creates the lease statistical data result set.
virtual ~CqlLeaseStatsQuery()
Destructor.
virtual void createBindForSelect(AnyArray &data, StatementTag statement_tag=NULL)
Create BIND array to receive C++ data.
CqlLeaseStatsQuery(CqlConnection &conn, StatementTag &statement, const bool fetch_type, const SubnetID &subnet_id)
Constructor to query for a single subnet's stats.
static constexpr StatementTag SUBNET_RANGE_LEASE4_STATS
Return lease4 lease statistics for a range of subnets.
CqlLeaseStatsQuery(CqlConnection &conn, StatementTag &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.
CqlLeaseStatsQuery(CqlConnection &conn, StatementTag &statement, const bool fetch_type)
Constructor to query for all subnets' stats.
Holds DUID (DHCPv6 Unique Identifier)
Definition: duid.h:27
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Definition: duid.cc:74
static const size_t MAX_DUID_LEN
maximum duid size As defined in RFC 8415, section 11.1
Definition: duid.h:31
const std::vector< uint8_t > & getDuid() const
Returns a const reference to the actual DUID value.
Definition: duid.cc:44
Abstract Lease Manager.
Definition: lease_mgr.h:222
Wraps value holding size of the page with leases.
Definition: lease_mgr.h:43
const size_t page_size_
Holds page size.
Definition: lease_mgr.h:53
Base class for fulfilling a statistical lease data query.
Definition: lease_mgr.h:128
SubnetID first_subnet_id_
First (or only) subnet_id in the selection criteria.
Definition: lease_mgr.h:196
SelectMode getSelectMode() const
Returns the selection criteria mode The value returned is based upon the constructor variant used and...
Definition: lease_mgr.h:190
SubnetID last_subnet_id_
Last subnet_id in the selection criteria when a range is given.
Definition: lease_mgr.h:199
Attempt to update lease that was not there.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
char const *const StatementTag
Statement index representing the statement name.
std::vector< cass_byte_t > CassBlob
Host identifier converted to Cassandra data type.
Definition: cql_exchange.h:37
constexpr uint32_t CQL_SCHEMA_VERSION_MINOR
constexpr uint32_t CQL_SCHEMA_VERSION_MAJOR
Define CQL schema version: 3.0.
std::unordered_map< StatementTag, CqlTaggedStatement, StatementTagHash, StatementTagEqual > StatementMap
A container for all statements.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition: dhcpsrv_log.h:56
std::pair< uint32_t, uint32_t > VersionPair
Pair containing major and minor versions.
Definition: lease_mgr.h:40
boost::shared_ptr< DUID > DuidPtr
Definition: duid.h:21
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:463
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition: lease.h:604
boost::shared_ptr< LeaseStatsQuery > LeaseStatsQueryPtr
Defines a pointer to a LeaseStatsQuery.
Definition: lease_mgr.h:207
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition: hwaddr.h:154
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
Definition: dhcpsrv_log.h:38
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
Definition: lease.h:24
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
Definition: lease.h:455
@ HTYPE_ETHER
Ethernet 10Mbps.
Definition: dhcp4.h:56
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition: lease.h:248
Defines the logger used by the top-level component of kea-dhcp-ddns.
Defines a single statement or query.
StatementTag name_
Short description of the query.
bool is_raw_
Should the statement be executed raw or with binds?
const CassPrepared * prepared_statement_
Internal Cassandra object representing the prepared statement.
Hardware type that represents information from DHCPv4 packet.
Definition: hwaddr.h:20
static const size_t MAX_HWADDR_LEN
Maximum size of a hardware address.
Definition: hwaddr.h:27
std::vector< uint8_t > hwaddr_
Definition: hwaddr.h:98
std::string toText(bool include_htype=true) const
Returns textual representation of a hardware address (e.g.
Definition: hwaddr.cc:51
Structure that holds a lease for IPv4 address.
Definition: lease.h:256
Structure that holds a lease for IPv6 address and/or prefix.
Definition: lease.h:471
Contains a single row of lease statistical data.
Definition: lease_mgr.h:61
int64_t state_count_
state_count The count of leases in the lease state
Definition: lease_mgr.h:120
uint32_t lease_state_
The lease_state to which the count applies.
Definition: lease_mgr.h:118
SubnetID subnet_id_
The subnet ID to which this data applies.
Definition: lease_mgr.h:114
Lease::Type lease_type_
The lease_type to which the count applies.
Definition: lease_mgr.h:116
static const uint32_t STATE_DEFAULT
A lease in the default state.
Definition: lease.h:61
static const uint32_t STATE_DECLINED
Declined lease.
Definition: lease.h:64
static const uint32_t STATE_EXPIRED_RECLAIMED
Expired and reclaimed lease.
Definition: lease.h:67
Type
Type of lease or pool.
Definition: lease.h:38
@ TYPE_TA
the lease contains temporary IPv6 address
Definition: lease.h:40
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition: lease.h:41
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition: lease.h:39