12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265 |
- #include <config.h>
- #include <asiolink/io_address.h>
- #include <dhcp/duid.h>
- #include <dhcp/hwaddr.h>
- #include <dhcpsrv/dhcpsrv_log.h>
- #include <dhcpsrv/pgsql_lease_mgr.h>
- #include <boost/static_assert.hpp>
- #include <iomanip>
- #include <limits>
- #include <sstream>
- #include <string>
- #include <time.h>
- using namespace isc;
- using namespace isc::dhcp;
- using namespace std;
- namespace {
- PgSqlTaggedStatement tagged_statements[] = {
-
- { 1, { OID_INT8 },
- "delete_lease4",
- "DELETE FROM lease4 WHERE address = $1"},
-
- { 2, { OID_INT8, OID_TIMESTAMP },
- "delete_lease4_state_expired",
- "DELETE FROM lease4 "
- "WHERE state = $1 AND expire < $2"},
-
- { 1, { OID_VARCHAR },
- "delete_lease6",
- "DELETE FROM lease6 WHERE address = $1"},
-
- { 2, { OID_INT8, OID_TIMESTAMP },
- "delete_lease6_state_expired",
- "DELETE FROM lease6 "
- "WHERE state = $1 AND expire < $2"},
-
- { 1, { OID_INT8 },
- "get_lease4_addr",
- "SELECT address, hwaddr, client_id, "
- "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
- "fqdn_fwd, fqdn_rev, hostname, state "
- "FROM lease4 "
- "WHERE address = $1"},
-
- { 1, { OID_BYTEA },
- "get_lease4_clientid",
- "SELECT address, hwaddr, client_id, "
- "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
- "fqdn_fwd, fqdn_rev, hostname, state "
- "FROM lease4 "
- "WHERE client_id = $1"},
-
- { 2, { OID_BYTEA, OID_INT8 },
- "get_lease4_clientid_subid",
- "SELECT address, hwaddr, client_id, "
- "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
- "fqdn_fwd, fqdn_rev, hostname, state "
- "FROM lease4 "
- "WHERE client_id = $1 AND subnet_id = $2"},
-
- { 1, { OID_BYTEA },
- "get_lease4_hwaddr",
- "SELECT address, hwaddr, client_id, "
- "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
- "fqdn_fwd, fqdn_rev, hostname, state "
- "FROM lease4 "
- "WHERE hwaddr = $1"},
-
- { 2, { OID_BYTEA, OID_INT8 },
- "get_lease4_hwaddr_subid",
- "SELECT address, hwaddr, client_id, "
- "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
- "fqdn_fwd, fqdn_rev, hostname, state "
- "FROM lease4 "
- "WHERE hwaddr = $1 AND subnet_id = $2"},
-
- { 3, { OID_INT8, OID_TIMESTAMP, OID_INT8 },
- "get_lease4_expire",
- "SELECT address, hwaddr, client_id, "
- "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
- "fqdn_fwd, fqdn_rev, hostname, state "
- "FROM lease4 "
- "WHERE state != $1 AND expire < $2 "
- "ORDER BY expire "
- "LIMIT $3"},
-
- { 2, { OID_VARCHAR, OID_INT2 },
- "get_lease6_addr",
- "SELECT address, duid, valid_lifetime, "
- "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
- "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
- "state "
- "FROM lease6 "
- "WHERE address = $1 AND lease_type = $2"},
-
- { 3, { OID_BYTEA, OID_INT8, OID_INT2 },
- "get_lease6_duid_iaid",
- "SELECT address, duid, valid_lifetime, "
- "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
- "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
- "state "
- "FROM lease6 "
- "WHERE duid = $1 AND iaid = $2 AND lease_type = $3"},
-
- { 4, { OID_INT2, OID_BYTEA, OID_INT8, OID_INT8 },
- "get_lease6_duid_iaid_subid",
- "SELECT address, duid, valid_lifetime, "
- "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
- "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
- "state "
- "FROM lease6 "
- "WHERE lease_type = $1 "
- "AND duid = $2 AND iaid = $3 AND subnet_id = $4"},
-
- { 3, { OID_INT8, OID_TIMESTAMP, OID_INT8 },
- "get_lease6_expire",
- "SELECT address, duid, valid_lifetime, "
- "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
- "lease_type, iaid, prefix_len, "
- "fqdn_fwd, fqdn_rev, hostname, state "
- "state "
- "FROM lease6 "
- "WHERE state != $1 AND expire < $2 "
- "ORDER BY expire "
- "LIMIT $3"},
-
- { 0, { OID_NONE },
- "get_version",
- "SELECT version, minor FROM schema_version"},
-
- { 10, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
- OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8, OID_INT8 },
- "insert_lease4",
- "INSERT INTO lease4(address, hwaddr, client_id, "
- "valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, "
- "state) "
- "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)"},
-
- { 13, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
- OID_INT8, OID_INT2, OID_INT8, OID_INT2, OID_BOOL, OID_BOOL,
- OID_VARCHAR, OID_INT8 },
- "insert_lease6",
- "INSERT INTO lease6(address, duid, valid_lifetime, "
- "expire, subnet_id, pref_lifetime, "
- "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, state) "
- "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)"},
-
- { 11, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
- OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8, OID_INT8 },
- "update_lease4",
- "UPDATE lease4 SET address = $1, hwaddr = $2, "
- "client_id = $3, valid_lifetime = $4, expire = $5, "
- "subnet_id = $6, fqdn_fwd = $7, fqdn_rev = $8, hostname = $9, "
- "state = $10"
- "WHERE address = $11"},
-
- { 14, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8, OID_INT8,
- OID_INT2, OID_INT8, OID_INT2, OID_BOOL, OID_BOOL, OID_VARCHAR,
- OID_INT8, OID_VARCHAR },
- "update_lease6",
- "UPDATE lease6 SET address = $1, duid = $2, "
- "valid_lifetime = $3, expire = $4, subnet_id = $5, "
- "pref_lifetime = $6, lease_type = $7, iaid = $8, "
- "prefix_len = $9, fqdn_fwd = $10, fqdn_rev = $11, hostname = $12, "
- "state = $13 "
- "WHERE address = $14"},
-
- { 0, { 0 }, NULL, NULL}
- };
- };
- namespace isc {
- namespace dhcp {
- class PgSqlLeaseExchange : public PgSqlExchange {
- public:
- PgSqlLeaseExchange()
- : addr_str_(""), valid_lifetime_(0), valid_lft_str_(""),
- expire_(0), expire_str_(""), subnet_id_(0), subnet_id_str_(""),
- cltt_(0), fqdn_fwd_(false), fqdn_rev_(false), hostname_(""),
- state_str_("") {
- }
- virtual ~PgSqlLeaseExchange(){}
- protected:
-
-
- std::string addr_str_;
- uint32_t valid_lifetime_;
- std::string valid_lft_str_;
- time_t expire_;
- std::string expire_str_;
- uint32_t subnet_id_;
- std::string subnet_id_str_;
- time_t cltt_;
- bool fqdn_fwd_;
- bool fqdn_rev_;
- std::string hostname_;
- std::string state_str_;
-
- };
- class PgSqlLease4Exchange : public PgSqlLeaseExchange {
- private:
-
-
-
-
- static const size_t ADDRESS_COL = 0;
- static const size_t HWADDR_COL = 1;
- static const size_t CLIENT_ID_COL = 2;
- static const size_t VALID_LIFETIME_COL = 3;
- static const size_t EXPIRE_COL = 4;
- static const size_t SUBNET_ID_COL = 5;
- static const size_t FQDN_FWD_COL = 6;
- static const size_t FQDN_REV_COL = 7;
- static const size_t HOSTNAME_COL = 8;
- static const size_t STATE_COL = 9;
-
- static const size_t LEASE_COLUMNS = 10;
- public:
-
- PgSqlLease4Exchange()
- : lease_(), addr4_(0), hwaddr_length_(0), hwaddr_(hwaddr_length_),
- client_id_length_(0) {
- BOOST_STATIC_ASSERT(9 < LEASE_COLUMNS);
- memset(hwaddr_buffer_, 0, sizeof(hwaddr_buffer_));
- memset(client_id_buffer_, 0, sizeof(client_id_buffer_));
-
- columns_.push_back("address");
- columns_.push_back("hwaddr");
- columns_.push_back("client_id");
- columns_.push_back("valid_lifetime");
- columns_.push_back("expire");
- columns_.push_back("subnet_id");
- columns_.push_back("fqdn_fwd");
- columns_.push_back("fqdn_rev");
- columns_.push_back("hostname");
- columns_.push_back("state");
- }
-
-
-
-
-
-
-
-
-
-
-
-
- void createBindForSend(const Lease4Ptr& lease, PsqlBindArray& bind_array) {
- if (!lease) {
- isc_throw(BadValue, "createBindForSend:: Lease4 object is NULL");
- }
-
- lease_ = lease;
- try {
- addr_str_ = boost::lexical_cast<std::string>
- (static_cast<uint32_t>(lease->addr_));
- bind_array.add(addr_str_);
- if (lease->hwaddr_ && !lease->hwaddr_->hwaddr_.empty()) {
-
-
- if (lease->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
- isc_throw(DbOperationError, "Hardware address length : "
- << lease_->hwaddr_->hwaddr_.size()
- << " exceeds maximum allowed of: "
- << HWAddr::MAX_HWADDR_LEN);
- }
- bind_array.add(lease->hwaddr_->hwaddr_);
- } else {
- bind_array.add("");
- }
- if (lease->client_id_) {
- bind_array.add(lease->client_id_->getClientId());
- } else {
- bind_array.add("");
- }
- valid_lft_str_ = boost::lexical_cast<std::string>
- (lease->valid_lft_);
- bind_array.add(valid_lft_str_);
- expire_str_ = convertToDatabaseTime(lease->cltt_, lease_->valid_lft_);
- bind_array.add(expire_str_);
- subnet_id_str_ = boost::lexical_cast<std::string>
- (lease->subnet_id_);
- bind_array.add(subnet_id_str_);
- bind_array.add(lease->fqdn_fwd_);
- bind_array.add(lease->fqdn_rev_);
- bind_array.add(lease->hostname_);
- state_str_ = boost::lexical_cast<std::string>(lease->state_);
- bind_array.add(state_str_);
- } catch (const std::exception& ex) {
- isc_throw(DbOperationError,
- "Could not create bind array from Lease4: "
- << lease_->addr_.toText() << ", reason: " << ex.what());
- }
- }
-
-
-
-
-
-
-
-
- Lease4Ptr convertFromDatabase(const PgSqlResult& r, int row) {
- try {
- getColumnValue(r, row, ADDRESS_COL, addr4_);
- convertFromBytea(r, row, HWADDR_COL, hwaddr_buffer_,
- sizeof(hwaddr_buffer_), hwaddr_length_);
- convertFromBytea(r, row, CLIENT_ID_COL, client_id_buffer_,
- sizeof(client_id_buffer_), client_id_length_);
- getColumnValue(r, row, VALID_LIFETIME_COL, valid_lifetime_);
- expire_ = convertFromDatabaseTime(getRawColumnValue(r, row,
- EXPIRE_COL));
- getColumnValue(r, row , SUBNET_ID_COL, subnet_id_);
- cltt_ = expire_ - valid_lifetime_;
- getColumnValue(r, row, FQDN_FWD_COL, fqdn_fwd_);
- getColumnValue(r, row, FQDN_REV_COL, fqdn_rev_);
- hostname_ = getRawColumnValue(r, row, HOSTNAME_COL);
- HWAddrPtr hwaddr(new HWAddr(hwaddr_buffer_, hwaddr_length_,
- HTYPE_ETHER));
- return (Lease4Ptr(new Lease4(addr4_, hwaddr,
- client_id_buffer_, client_id_length_,
- valid_lifetime_, 0, 0, cltt_,
- subnet_id_, fqdn_fwd_, fqdn_rev_,
- hostname_)));
- } catch (const std::exception& ex) {
- isc_throw(DbOperationError,
- "Could not convert data to Lease4, reason: "
- << ex.what());
- }
- }
- private:
-
-
-
- Lease4Ptr lease_;
-
- uint32_t addr4_;
- size_t hwaddr_length_;
- std::vector<uint8_t> hwaddr_;
- uint8_t hwaddr_buffer_[HWAddr::MAX_HWADDR_LEN];
- size_t client_id_length_;
- uint8_t client_id_buffer_[ClientId::MAX_CLIENT_ID_LEN];
- };
- class PgSqlLease6Exchange : public PgSqlLeaseExchange {
- private:
-
-
-
-
-
- static const int ADDRESS_COL = 0;
- static const int DUID_COL = 1;
- static const int VALID_LIFETIME_COL = 2;
- static const int EXPIRE_COL = 3;
- static const int SUBNET_ID_COL = 4;
- static const int PREF_LIFETIME_COL = 5;
- static const int LEASE_TYPE_COL = 6;
- static const int IAID_COL = 7;
- static const int PREFIX_LEN_COL = 8;
- static const int FQDN_FWD_COL = 9;
- static const int FQDN_REV_COL = 10;
- static const int HOSTNAME_COL = 11;
- static const int STATE_COL = 12;
-
-
- static const size_t LEASE_COLUMNS = 13;
- public:
- PgSqlLease6Exchange()
- : lease_(), duid_length_(0), duid_(), iaid_u_(0), iaid_str_(""),
- lease_type_(Lease6::TYPE_NA), lease_type_str_(""), prefix_len_(0),
- prefix_len_str_(""), pref_lifetime_(0), preferred_lft_str_("") {
- BOOST_STATIC_ASSERT(12 < LEASE_COLUMNS);
- memset(duid_buffer_, 0, sizeof(duid_buffer_));
-
- columns_.push_back("address");
- columns_.push_back("duid");
- columns_.push_back("valid_lifetime");
- columns_.push_back("expire");
- columns_.push_back("subnet_id");
- columns_.push_back("pref_lifetime");
- columns_.push_back("lease_type");
- columns_.push_back("iaid");
- columns_.push_back("prefix_len");
- columns_.push_back("fqdn_fwd");
- columns_.push_back("fqdn_rev");
- columns_.push_back("hostname");
- columns_.push_back("state");
- }
-
-
-
-
-
-
-
-
-
-
-
-
- void createBindForSend(const Lease6Ptr& lease, PsqlBindArray& bind_array) {
- if (!lease) {
- isc_throw(BadValue, "createBindForSend:: Lease6 object is NULL");
- }
-
- lease_ = lease;
- try {
- addr_str_ = lease_->addr_.toText();
- bind_array.add(addr_str_);
- if (lease_->duid_) {
- bind_array.add(lease_->duid_->getDuid());
- } else {
- isc_throw (BadValue, "IPv6 Lease cannot have a null DUID");
- }
- valid_lft_str_ = boost::lexical_cast<std::string>
- (lease->valid_lft_);
- bind_array.add(valid_lft_str_);
- expire_str_ = convertToDatabaseTime(lease->cltt_, lease_->valid_lft_);
- bind_array.add(expire_str_);
- subnet_id_str_ = boost::lexical_cast<std::string>
- (lease->subnet_id_);
- bind_array.add(subnet_id_str_);
- preferred_lft_str_ = boost::lexical_cast<std::string>
- (lease_->preferred_lft_);
- bind_array.add(preferred_lft_str_);
- lease_type_str_ = boost::lexical_cast<std::string>(lease_->type_);
- bind_array.add(lease_type_str_);
-
-
-
- iaid_u_.uval_ = lease_->iaid_;
- iaid_str_ = boost::lexical_cast<std::string>(iaid_u_.ival_);
- bind_array.add(iaid_str_);
- prefix_len_str_ = boost::lexical_cast<std::string>
- (static_cast<unsigned int>(lease_->prefixlen_));
- bind_array.add(prefix_len_str_);
- bind_array.add(lease->fqdn_fwd_);
- bind_array.add(lease->fqdn_rev_);
- bind_array.add(lease->hostname_);
- state_str_ = boost::lexical_cast<std::string>(lease->state_);
- bind_array.add(state_str_);
- } catch (const std::exception& ex) {
- isc_throw(DbOperationError,
- "Could not create bind array from Lease6: "
- << lease_->addr_.toText() << ", reason: " << ex.what());
- }
- }
-
-
-
-
-
-
-
-
- Lease6Ptr convertFromDatabase(const PgSqlResult& r, int row) {
- try {
- isc::asiolink::IOAddress addr(getIPv6Value(r, row, ADDRESS_COL));
- convertFromBytea(r, row, DUID_COL, duid_buffer_,
- sizeof(duid_buffer_), duid_length_);
- DuidPtr duid_ptr(new DUID(duid_buffer_, duid_length_));
- getColumnValue(r, row, VALID_LIFETIME_COL, valid_lifetime_);
- expire_ = convertFromDatabaseTime(getRawColumnValue(r, row,
- EXPIRE_COL));
- cltt_ = expire_ - valid_lifetime_;
- getColumnValue(r, row , SUBNET_ID_COL, subnet_id_);
- getColumnValue(r, row , PREF_LIFETIME_COL, pref_lifetime_);
- getLeaseTypeColumnValue(r, row, LEASE_TYPE_COL, lease_type_);
- getColumnValue(r, row , IAID_COL, iaid_u_.ival_);
- getColumnValue(r, row , PREFIX_LEN_COL, prefix_len_);
- getColumnValue(r, row, FQDN_FWD_COL, fqdn_fwd_);
- getColumnValue(r, row, FQDN_REV_COL, fqdn_rev_);
- hostname_ = getRawColumnValue(r, row, HOSTNAME_COL);
-
- HWAddrPtr hwaddr;
- Lease6Ptr result(new Lease6(lease_type_, addr, duid_ptr,
- iaid_u_.uval_, pref_lifetime_,
- valid_lifetime_, 0, 0,
- subnet_id_, fqdn_fwd_, fqdn_rev_,
- hostname_, hwaddr, prefix_len_));
- result->cltt_ = cltt_;
- return (result);
- } catch (const std::exception& ex) {
- isc_throw(DbOperationError,
- "Could not convert data to Lease6, reason: "
- << ex.what());
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
- void getLeaseTypeColumnValue(const PgSqlResult& r, const int row,
- const size_t col, Lease6::Type& value) const {
- uint32_t raw_value = 0;
- getColumnValue(r, row , col, raw_value);
- switch (raw_value) {
- case Lease6::TYPE_NA:
- case Lease6::TYPE_TA:
- case Lease6::TYPE_PD:
- value = static_cast<Lease6::Type>(raw_value);
- break;
- default:
- isc_throw(DbOperationError, "Invalid lease type: " << raw_value
- << " for: " << getColumnLabel(r, col) << " row:" << row);
- }
- }
- private:
-
-
-
- Lease6Ptr lease_;
-
-
- size_t duid_length_;
- vector<uint8_t> duid_;
- uint8_t duid_buffer_[DUID::MAX_DUID_LEN];
-
-
-
-
-
-
- union Uiaid {
- Uiaid(uint32_t val) : uval_(val){};
- Uiaid(int32_t val) : ival_(val){};
- uint32_t uval_;
- int32_t ival_;
- } iaid_u_;
- std::string iaid_str_;
- Lease6::Type lease_type_;
- std::string lease_type_str_;
- uint8_t prefix_len_;
- std::string prefix_len_str_;
- uint32_t pref_lifetime_;
- std::string preferred_lft_str_;
-
- };
- PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
- : LeaseMgr(), exchange4_(new PgSqlLease4Exchange()),
- exchange6_(new PgSqlLease6Exchange()), conn_(parameters) {
- conn_.openDatabase();
- int i = 0;
- for( ; tagged_statements[i].text != NULL ; ++i) {
- conn_.prepareStatement(tagged_statements[i]);
- }
-
- if (i != NUM_STATEMENTS) {
- isc_throw(DbOpenError, "Number of statements prepared: " << i
- << " does not match expected count:" << NUM_STATEMENTS);
- }
- pair<uint32_t, uint32_t> code_version(PG_CURRENT_VERSION, PG_CURRENT_MINOR);
- pair<uint32_t, uint32_t> db_version = getVersion();
- if (code_version != db_version) {
- isc_throw(DbOpenError, "Posgresql schema version mismatch: need version: "
- << code_version.first << "." << code_version.second
- << " found version: " << db_version.first << "." << db_version.second);
- }
- }
- PgSqlLeaseMgr::~PgSqlLeaseMgr() {
- }
- std::string
- PgSqlLeaseMgr::getDBVersion() {
- std::stringstream tmp;
- tmp << "PostgreSQL backend " << PG_CURRENT_VERSION;
- tmp << "." << PG_CURRENT_MINOR;
- tmp << ", library " << PQlibVersion();
- return (tmp.str());
- }
- bool
- PgSqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
- PsqlBindArray& bind_array) {
- PgSqlResult r(PQexecPrepared(conn_, tagged_statements[stindex].name,
- tagged_statements[stindex].nbparams,
- &bind_array.values_[0],
- &bind_array.lengths_[0],
- &bind_array.formats_[0], 0));
- int s = PQresultStatus(r);
- if (s != PGRES_COMMAND_OK) {
-
-
-
- if (conn_.compareError(r, PgSqlConnection::DUPLICATE_KEY)) {
- return (false);
- }
- conn_.checkStatementError(r, tagged_statements[stindex]);
- }
- return (true);
- }
- bool
- PgSqlLeaseMgr::addLease(const Lease4Ptr& lease) {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_ADD_ADDR4).arg(lease->addr_.toText());
- PsqlBindArray bind_array;
- exchange4_->createBindForSend(lease, bind_array);
- return (addLeaseCommon(INSERT_LEASE4, bind_array));
- }
- bool
- PgSqlLeaseMgr::addLease(const Lease6Ptr& lease) {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_ADD_ADDR6).arg(lease->addr_.toText());
- PsqlBindArray bind_array;
- exchange6_->createBindForSend(lease, bind_array);
- return (addLeaseCommon(INSERT_LEASE6, bind_array));
- }
- template <typename Exchange, typename LeaseCollection>
- void PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex,
- PsqlBindArray& bind_array,
- Exchange& exchange,
- LeaseCollection& result,
- bool single) const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_GET_ADDR4).arg(tagged_statements[stindex].name);
- PgSqlResult r(PQexecPrepared(conn_, tagged_statements[stindex].name,
- tagged_statements[stindex].nbparams,
- &bind_array.values_[0],
- &bind_array.lengths_[0],
- &bind_array.formats_[0], 0));
- conn_.checkStatementError(r, tagged_statements[stindex]);
- int rows = PQntuples(r);
- if (single && rows > 1) {
- isc_throw(MultipleRecords, "multiple records were found in the "
- "database where only one was expected for query "
- << tagged_statements[stindex].name);
- }
- for(int i = 0; i < rows; ++ i) {
- result.push_back(exchange->convertFromDatabase(r, i));
- }
- }
- void
- PgSqlLeaseMgr::getLease(StatementIndex stindex, PsqlBindArray& bind_array,
- Lease4Ptr& result) const {
-
-
-
-
-
- Lease4Collection collection;
- getLeaseCollection(stindex, bind_array, exchange4_, collection, true);
-
- if (collection.empty()) {
- result.reset();
- } else {
- result = *collection.begin();
- }
- }
- void
- PgSqlLeaseMgr::getLease(StatementIndex stindex, PsqlBindArray& bind_array,
- Lease6Ptr& result) const {
-
-
-
-
-
- Lease6Collection collection;
- getLeaseCollection(stindex, bind_array, exchange6_, collection, true);
-
- if (collection.empty()) {
- result.reset();
- } else {
- result = *collection.begin();
- }
- }
- Lease4Ptr
- PgSqlLeaseMgr::getLease4(const isc::asiolink::IOAddress& addr) const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_GET_ADDR4).arg(addr.toText());
-
- PsqlBindArray bind_array;
-
- std::string addr_str = boost::lexical_cast<std::string>
- (static_cast<uint32_t>(addr));
- bind_array.add(addr_str);
-
- Lease4Ptr result;
- getLease(GET_LEASE4_ADDR, bind_array, result);
- return (result);
- }
- Lease4Collection
- PgSqlLeaseMgr::getLease4(const HWAddr& hwaddr) const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_GET_HWADDR).arg(hwaddr.toText());
-
- PsqlBindArray bind_array;
-
- if (!hwaddr.hwaddr_.empty()) {
- bind_array.add(hwaddr.hwaddr_);
- } else {
- bind_array.add("");
- }
-
- Lease4Collection result;
- getLeaseCollection(GET_LEASE4_HWADDR, bind_array, result);
- return (result);
- }
- Lease4Ptr
- PgSqlLeaseMgr::getLease4(const HWAddr& hwaddr, SubnetID subnet_id) const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_GET_SUBID_HWADDR)
- .arg(subnet_id).arg(hwaddr.toText());
-
- PsqlBindArray bind_array;
-
- if (!hwaddr.hwaddr_.empty()) {
- bind_array.add(hwaddr.hwaddr_);
- } else {
- bind_array.add("");
- }
-
- std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
- bind_array.add(subnet_id_str);
-
- Lease4Ptr result;
- getLease(GET_LEASE4_HWADDR_SUBID, bind_array, result);
- return (result);
- }
- Lease4Collection
- PgSqlLeaseMgr::getLease4(const ClientId& clientid) const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_GET_CLIENTID).arg(clientid.toText());
-
- PsqlBindArray bind_array;
-
- bind_array.add(clientid.getClientId());
-
- Lease4Collection result;
- getLeaseCollection(GET_LEASE4_CLIENTID, bind_array, result);
- return (result);
- }
- Lease4Ptr
- PgSqlLeaseMgr::getLease4(const ClientId& clientid, SubnetID subnet_id) const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_GET_SUBID_CLIENTID)
- .arg(subnet_id).arg(clientid.toText());
-
- PsqlBindArray bind_array;
-
- bind_array.add(clientid.getClientId());
-
- std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
- bind_array.add(subnet_id_str);
-
- Lease4Ptr result;
- getLease(GET_LEASE4_CLIENTID_SUBID, bind_array, result);
- return (result);
- }
- Lease4Ptr
- PgSqlLeaseMgr::getLease4(const ClientId&, const HWAddr&, SubnetID) const {
-
-
-
-
- isc_throw(NotImplemented, "The PgSqlLeaseMgr::getLease4 function was"
- " called, but it is not implemented");
- }
- Lease6Ptr
- PgSqlLeaseMgr::getLease6(Lease::Type lease_type,
- const isc::asiolink::IOAddress& addr) const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_ADDR6)
- .arg(addr.toText()).arg(lease_type);
-
- PsqlBindArray bind_array;
-
- std::string addr_str = addr.toText();
- bind_array.add(addr_str);
-
- std::string type_str_ = boost::lexical_cast<std::string>(lease_type);
- bind_array.add(type_str_);
-
- Lease6Ptr result;
- getLease(GET_LEASE6_ADDR, bind_array, result);
- return (result);
- }
- Lease6Collection
- PgSqlLeaseMgr::getLeases6(Lease::Type lease_type, const DUID& duid,
- uint32_t iaid) const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_GET_IAID_DUID)
- .arg(iaid).arg(duid.toText()).arg(lease_type);
-
- PsqlBindArray bind_array;
-
- bind_array.add(duid.getDuid());
-
- std::string iaid_str = boost::lexical_cast<std::string>(iaid);
- bind_array.add(iaid_str);
-
- std::string lease_type_str = boost::lexical_cast<std::string>(lease_type);
- bind_array.add(lease_type_str);
-
- Lease6Collection result;
- getLeaseCollection(GET_LEASE6_DUID_IAID, bind_array, result);
- return (result);
- }
- Lease6Collection
- PgSqlLeaseMgr::getLeases6(Lease::Type lease_type, const DUID& duid,
- uint32_t iaid, SubnetID subnet_id) const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_GET_IAID_SUBID_DUID)
- .arg(iaid).arg(subnet_id).arg(duid.toText()).arg(lease_type);
-
- PsqlBindArray bind_array;
-
- std::string lease_type_str = boost::lexical_cast<std::string>(lease_type);
- bind_array.add(lease_type_str);
-
- bind_array.add(duid.getDuid());
-
- std::string iaid_str = boost::lexical_cast<std::string>(iaid);
- bind_array.add(iaid_str);
-
- std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
- bind_array.add(subnet_id_str);
-
- Lease6Collection result;
- getLeaseCollection(GET_LEASE6_DUID_IAID_SUBID, bind_array, result);
- return (result);
- }
- void
- PgSqlLeaseMgr::getExpiredLeases6(Lease6Collection& expired_leases,
- const size_t max_leases) const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_EXPIRED6)
- .arg(max_leases);
- getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE6_EXPIRE);
- }
- void
- PgSqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
- const size_t max_leases) const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_EXPIRED4)
- .arg(max_leases);
- getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE4_EXPIRE);
- }
- template<typename LeaseCollection>
- void
- PgSqlLeaseMgr::getExpiredLeasesCommon(LeaseCollection& expired_leases,
- const size_t max_leases,
- StatementIndex statement_index) const {
- PsqlBindArray bind_array;
-
- std::string state_str = boost::lexical_cast<std::string>(Lease::STATE_EXPIRED_RECLAIMED);
- bind_array.add(state_str);
-
- std::string timestamp_str = PgSqlLeaseExchange::convertToDatabaseTime(time(NULL));
- bind_array.add(timestamp_str);
-
-
- uint32_t limit = max_leases > 0 ? static_cast<uint32_t>(max_leases) :
- std::numeric_limits<uint32_t>::max();
- std::string limit_str = boost::lexical_cast<std::string>(limit);
- bind_array.add(limit_str);
-
- getLeaseCollection(statement_index, bind_array, expired_leases);
- }
- template<typename LeasePtr>
- void
- PgSqlLeaseMgr::updateLeaseCommon(StatementIndex stindex,
- PsqlBindArray& bind_array,
- const LeasePtr& lease) {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_ADD_ADDR4).arg(tagged_statements[stindex].name);
- PgSqlResult r(PQexecPrepared(conn_, tagged_statements[stindex].name,
- tagged_statements[stindex].nbparams,
- &bind_array.values_[0],
- &bind_array.lengths_[0],
- &bind_array.formats_[0], 0));
- conn_.checkStatementError(r, tagged_statements[stindex]);
- int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
-
- if (affected_rows == 1) {
- return;
- }
-
- if (affected_rows == 0) {
- isc_throw(NoSuchLease, "unable to update lease for address " <<
- lease->addr_.toText() << " as it does not exist");
- }
-
-
- isc_throw(DbOperationError, "apparently updated more than one lease "
- "that had the address " << lease->addr_.toText());
- }
- void
- PgSqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
- const StatementIndex stindex = UPDATE_LEASE4;
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_UPDATE_ADDR4).arg(lease->addr_.toText());
-
- PsqlBindArray bind_array;
- exchange4_->createBindForSend(lease, bind_array);
-
- std::string addr4_ = boost::lexical_cast<std::string>
- (static_cast<uint32_t>(lease->addr_));
- bind_array.add(addr4_);
-
- updateLeaseCommon(stindex, bind_array, lease);
- }
- void
- PgSqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
- const StatementIndex stindex = UPDATE_LEASE6;
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_UPDATE_ADDR6).arg(lease->addr_.toText());
-
- PsqlBindArray bind_array;
- exchange6_->createBindForSend(lease, bind_array);
-
- std::string addr_str = lease->addr_.toText();
- bind_array.add(addr_str);
-
- updateLeaseCommon(stindex, bind_array, lease);
- }
- uint64_t
- PgSqlLeaseMgr::deleteLeaseCommon(StatementIndex stindex,
- PsqlBindArray& bind_array) {
- PgSqlResult r(PQexecPrepared(conn_, tagged_statements[stindex].name,
- tagged_statements[stindex].nbparams,
- &bind_array.values_[0],
- &bind_array.lengths_[0],
- &bind_array.formats_[0], 0));
- conn_.checkStatementError(r, tagged_statements[stindex]);
- int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
- return (affected_rows);
- }
- bool
- PgSqlLeaseMgr::deleteLease(const isc::asiolink::IOAddress& addr) {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_DELETE_ADDR).arg(addr.toText());
-
- PsqlBindArray bind_array;
- if (addr.isV4()) {
- std::string addr4_str = boost::lexical_cast<std::string>
- (static_cast<uint32_t>(addr));
- bind_array.add(addr4_str);
- return (deleteLeaseCommon(DELETE_LEASE4, bind_array) > 0);
- }
- std::string addr6_str = addr.toText();
- bind_array.add(addr6_str);
- return (deleteLeaseCommon(DELETE_LEASE6, bind_array) > 0);
- }
- uint64_t
- PgSqlLeaseMgr::deleteExpiredReclaimedLeases4(const uint32_t secs) {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_DELETE_EXPIRED_RECLAIMED4)
- .arg(secs);
- return (deleteExpiredReclaimedLeasesCommon(secs, DELETE_LEASE4_STATE_EXPIRED));
- }
- uint64_t
- PgSqlLeaseMgr::deleteExpiredReclaimedLeases6(const uint32_t secs) {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_DELETE_EXPIRED_RECLAIMED6)
- .arg(secs);
- return (deleteExpiredReclaimedLeasesCommon(secs, DELETE_LEASE6_STATE_EXPIRED));
- }
- uint64_t
- PgSqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(const uint32_t secs,
- StatementIndex statement_index) {
- PsqlBindArray bind_array;
-
- std::string state_str = boost::lexical_cast<std::string>(Lease::STATE_EXPIRED_RECLAIMED);
- bind_array.add(state_str);
-
- std::string expiration_str =
- PgSqlLeaseExchange::convertToDatabaseTime(time(NULL) - static_cast<time_t>(secs));
- bind_array.add(expiration_str);
-
- return (deleteLeaseCommon(statement_index, bind_array));
- }
- string
- PgSqlLeaseMgr::getName() const {
- string name = "";
- try {
- name = conn_.getParameter("name");
- } catch (...) {
-
- }
- return (name);
- }
- string
- PgSqlLeaseMgr::getDescription() const {
- return (string("PostgreSQL Database"));
- }
- pair<uint32_t, uint32_t>
- PgSqlLeaseMgr::getVersion() const {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_PGSQL_GET_VERSION);
- PgSqlResult r(PQexecPrepared(conn_, "get_version", 0, NULL, NULL, NULL, 0));
- conn_.checkStatementError(r, tagged_statements[GET_VERSION]);
- istringstream tmp;
- uint32_t version;
- tmp.str(PQgetvalue(r, 0, 0));
- tmp >> version;
- tmp.str("");
- tmp.clear();
- uint32_t minor;
- tmp.str(PQgetvalue(r, 0, 1));
- tmp >> minor;
- return make_pair<uint32_t, uint32_t>(version, minor);
- }
- void
- PgSqlLeaseMgr::commit() {
- conn_.commit();
- }
- void
- PgSqlLeaseMgr::rollback() {
- conn_.rollback();
- }
- };
- };
|