lease.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. // Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <dhcpsrv/lease.h>
  7. #include <util/pointer_util.h>
  8. #include <sstream>
  9. #include <iostream>
  10. using namespace isc::util;
  11. using namespace std;
  12. namespace isc {
  13. namespace dhcp {
  14. const uint32_t Lease::STATE_DEFAULT = 0x0;
  15. const uint32_t Lease::STATE_DECLINED = 0x1;
  16. const uint32_t Lease::STATE_EXPIRED_RECLAIMED = 0x2;
  17. Lease::Lease(const isc::asiolink::IOAddress& addr, uint32_t t1, uint32_t t2,
  18. uint32_t valid_lft, SubnetID subnet_id, time_t cltt,
  19. const bool fqdn_fwd, const bool fqdn_rev,
  20. const std::string& hostname, const HWAddrPtr& hwaddr)
  21. :addr_(addr), t1_(t1), t2_(t2), valid_lft_(valid_lft), cltt_(cltt),
  22. subnet_id_(subnet_id), hostname_(hostname), fqdn_fwd_(fqdn_fwd),
  23. fqdn_rev_(fqdn_rev), hwaddr_(hwaddr), state_(STATE_DEFAULT) {
  24. }
  25. std::string
  26. Lease::typeToText(Lease::Type type) {
  27. switch (type) {
  28. case Lease::TYPE_V4:
  29. return string("V4");
  30. case Lease::TYPE_NA:
  31. return string("IA_NA");
  32. case Lease::TYPE_TA:
  33. return string("IA_TA");
  34. case Lease::TYPE_PD:
  35. return string("IA_PD");
  36. break;
  37. default: {
  38. stringstream tmp;
  39. tmp << "unknown (" << type << ")";
  40. return (tmp.str());
  41. }
  42. }
  43. }
  44. std::string
  45. Lease::basicStatesToText(const uint32_t state) {
  46. switch (state) {
  47. case STATE_DEFAULT:
  48. return ("default");
  49. case STATE_DECLINED:
  50. return ("declined");
  51. case STATE_EXPIRED_RECLAIMED:
  52. return ("expired-reclaimed");
  53. default:
  54. // The default case will be handled further on
  55. ;
  56. }
  57. std::ostringstream s;
  58. s << "unknown (" << state << ")";
  59. return s.str();
  60. }
  61. bool
  62. Lease::expired() const {
  63. return (getExpirationTime() < time(NULL));
  64. }
  65. bool
  66. Lease::stateExpiredReclaimed() const {
  67. return (state_ == STATE_EXPIRED_RECLAIMED);
  68. }
  69. bool
  70. Lease::stateDeclined() const {
  71. return (state_ == STATE_DECLINED);
  72. }
  73. int64_t
  74. Lease::getExpirationTime() const {
  75. return (static_cast<int64_t>(cltt_) + valid_lft_);
  76. }
  77. bool
  78. Lease::hasIdenticalFqdn(const Lease& other) const {
  79. return (hostname_ == other.hostname_ &&
  80. fqdn_fwd_ == other.fqdn_fwd_ &&
  81. fqdn_rev_ == other.fqdn_rev_);
  82. }
  83. Lease4::Lease4(const Lease4& other)
  84. : Lease(other.addr_, other.t1_, other.t2_, other.valid_lft_,
  85. other.subnet_id_, other.cltt_, other.fqdn_fwd_,
  86. other.fqdn_rev_, other.hostname_, other.hwaddr_) {
  87. // Copy over fields derived from Lease.
  88. state_ = other.state_;
  89. // Copy the hardware address if it is defined.
  90. if (other.hwaddr_) {
  91. hwaddr_.reset(new HWAddr(*other.hwaddr_));
  92. } else {
  93. hwaddr_.reset();
  94. }
  95. if (other.client_id_) {
  96. client_id_.reset(new ClientId(other.client_id_->getClientId()));
  97. } else {
  98. client_id_.reset();
  99. }
  100. }
  101. Lease4::Lease4(const isc::asiolink::IOAddress& address,
  102. const HWAddrPtr& hw_address,
  103. const ClientIdPtr& client_id,
  104. const uint32_t valid_lifetime,
  105. const uint32_t t1,
  106. const uint32_t t2,
  107. const time_t cltt,
  108. const SubnetID subnet_id,
  109. const bool fqdn_fwd,
  110. const bool fqdn_rev,
  111. const std::string& hostname)
  112. : Lease(address, t1, t2, valid_lifetime, subnet_id, cltt, fqdn_fwd,
  113. fqdn_rev, hostname, hw_address),
  114. client_id_(client_id) {
  115. }
  116. std::string
  117. Lease4::statesToText(const uint32_t state) {
  118. return (Lease::basicStatesToText(state));
  119. }
  120. const std::vector<uint8_t>&
  121. Lease4::getClientIdVector() const {
  122. if(!client_id_) {
  123. static std::vector<uint8_t> empty_vec;
  124. return (empty_vec);
  125. }
  126. return (client_id_->getClientId());
  127. }
  128. const std::vector<uint8_t>&
  129. Lease::getHWAddrVector() const {
  130. if (!hwaddr_) {
  131. static std::vector<uint8_t> empty_vec;
  132. return (empty_vec);
  133. }
  134. return (hwaddr_->hwaddr_);
  135. }
  136. bool
  137. Lease4::belongsToClient(const HWAddrPtr& hw_address,
  138. const ClientIdPtr& client_id) const {
  139. // If client id matches, lease matches.
  140. if (equalValues(client_id, client_id_)) {
  141. return (true);
  142. } else if (!client_id || !client_id_) {
  143. // If client id is unspecified, use HW address.
  144. if (equalValues(hw_address, hwaddr_)) {
  145. return (true);
  146. }
  147. }
  148. return (false);
  149. }
  150. void
  151. Lease4::decline(uint32_t probation_period) {
  152. hwaddr_.reset(new HWAddr());
  153. client_id_.reset();
  154. t1_ = 0;
  155. t2_ = 0;
  156. cltt_ = time(NULL);
  157. hostname_ = string("");
  158. fqdn_fwd_ = false;
  159. fqdn_rev_ = false;
  160. state_ = STATE_DECLINED;
  161. valid_lft_ = probation_period;
  162. }
  163. Lease4&
  164. Lease4::operator=(const Lease4& other) {
  165. if (this != &other) {
  166. addr_ = other.addr_;
  167. t1_ = other.t1_;
  168. t2_ = other.t2_;
  169. valid_lft_ = other.valid_lft_;
  170. cltt_ = other.cltt_;
  171. subnet_id_ = other.subnet_id_;
  172. hostname_ = other.hostname_;
  173. fqdn_fwd_ = other.fqdn_fwd_;
  174. fqdn_rev_ = other.fqdn_rev_;
  175. state_ = other.state_;
  176. // Copy the hardware address if it is defined.
  177. if (other.hwaddr_) {
  178. hwaddr_.reset(new HWAddr(*other.hwaddr_));
  179. } else {
  180. hwaddr_.reset();
  181. }
  182. if (other.client_id_) {
  183. client_id_.reset(new ClientId(other.client_id_->getClientId()));
  184. } else {
  185. client_id_.reset();
  186. }
  187. }
  188. return (*this);
  189. }
  190. Lease6::Lease6(Lease::Type type, const isc::asiolink::IOAddress& addr,
  191. DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid,
  192. uint32_t t1, uint32_t t2, SubnetID subnet_id,
  193. const HWAddrPtr& hwaddr, uint8_t prefixlen)
  194. : Lease(addr, t1, t2, valid, subnet_id, 0/*cltt*/, false, false, "", hwaddr),
  195. type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
  196. preferred_lft_(preferred) {
  197. if (!duid) {
  198. isc_throw(InvalidOperation, "DUID is mandatory for an IPv6 lease");
  199. }
  200. cltt_ = time(NULL);
  201. }
  202. Lease6::Lease6(Lease::Type type, const isc::asiolink::IOAddress& addr,
  203. DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid,
  204. uint32_t t1, uint32_t t2, SubnetID subnet_id,
  205. const bool fqdn_fwd, const bool fqdn_rev,
  206. const std::string& hostname, const HWAddrPtr& hwaddr,
  207. uint8_t prefixlen)
  208. : Lease(addr, t1, t2, valid, subnet_id, 0/*cltt*/,
  209. fqdn_fwd, fqdn_rev, hostname, hwaddr),
  210. type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
  211. preferred_lft_(preferred) {
  212. if (!duid) {
  213. isc_throw(InvalidOperation, "DUID is mandatory for an IPv6 lease");
  214. }
  215. cltt_ = time(NULL);
  216. }
  217. Lease6::Lease6()
  218. : Lease(isc::asiolink::IOAddress("::"), 0, 0, 0, 0, 0, false, false, "",
  219. HWAddrPtr()), type_(TYPE_NA), prefixlen_(0), iaid_(0),
  220. duid_(DuidPtr()), preferred_lft_(0) {
  221. }
  222. std::string
  223. Lease6::statesToText(const uint32_t state) {
  224. return (Lease::basicStatesToText(state));
  225. }
  226. const std::vector<uint8_t>&
  227. Lease6::getDuidVector() const {
  228. if (!duid_) {
  229. static std::vector<uint8_t> empty_vec;
  230. return (empty_vec);
  231. }
  232. return (duid_->getDuid());
  233. }
  234. void
  235. Lease6::decline(uint32_t probation_period) {
  236. hwaddr_.reset();
  237. duid_.reset(new DUID(DUID::EMPTY()));
  238. t1_ = 0;
  239. t2_ = 0;
  240. preferred_lft_ = 0;
  241. valid_lft_ = probation_period;
  242. cltt_ = time(NULL);
  243. hostname_ = string("");
  244. fqdn_fwd_ = false;
  245. fqdn_rev_ = false;
  246. state_ = Lease::STATE_DECLINED;
  247. }
  248. std::string
  249. Lease6::toText() const {
  250. ostringstream stream;
  251. /// @todo: print out DUID
  252. stream << "Type: " << typeToText(type_) << "("
  253. << static_cast<int>(type_) << ")\n"
  254. << "Address: " << addr_ << "\n"
  255. << "Prefix length: " << static_cast<int>(prefixlen_) << "\n"
  256. << "IAID: " << iaid_ << "\n"
  257. << "Pref life: " << preferred_lft_ << "\n"
  258. << "Valid life: " << valid_lft_ << "\n"
  259. << "Cltt: " << cltt_ << "\n"
  260. << "DUID: " << (duid_?duid_->toText():"(none)") << "\n"
  261. << "Hardware addr: " << (hwaddr_?hwaddr_->toText(false):"(none)") << "\n"
  262. << "Subnet ID: " << subnet_id_ << "\n"
  263. << "State: " << statesToText(state_) << "\n";
  264. return (stream.str());
  265. }
  266. std::string
  267. Lease4::toText() const {
  268. ostringstream stream;
  269. stream << "Address: " << addr_ << "\n"
  270. << "Valid life: " << valid_lft_ << "\n"
  271. << "T1: " << t1_ << "\n"
  272. << "T2: " << t2_ << "\n"
  273. << "Cltt: " << cltt_ << "\n"
  274. << "Hardware addr: " << (hwaddr_ ? hwaddr_->toText(false) : "(none)") << "\n"
  275. << "Client id: " << (client_id_ ? client_id_->toText() : "(none)") << "\n"
  276. << "Subnet ID: " << subnet_id_ << "\n"
  277. << "State: " << statesToText(state_) << "\n";
  278. return (stream.str());
  279. }
  280. bool
  281. Lease4::operator==(const Lease4& other) const {
  282. return (nullOrEqualValues(hwaddr_, other.hwaddr_) &&
  283. nullOrEqualValues(client_id_, other.client_id_) &&
  284. addr_ == other.addr_ &&
  285. subnet_id_ == other.subnet_id_ &&
  286. t1_ == other.t1_ &&
  287. t2_ == other.t2_ &&
  288. valid_lft_ == other.valid_lft_ &&
  289. cltt_ == other.cltt_ &&
  290. hostname_ == other.hostname_ &&
  291. fqdn_fwd_ == other.fqdn_fwd_ &&
  292. fqdn_rev_ == other.fqdn_rev_ &&
  293. state_ == other.state_);
  294. }
  295. bool
  296. Lease6::operator==(const Lease6& other) const {
  297. return (nullOrEqualValues(duid_, other.duid_) &&
  298. nullOrEqualValues(hwaddr_, other.hwaddr_) &&
  299. addr_ == other.addr_ &&
  300. type_ == other.type_ &&
  301. prefixlen_ == other.prefixlen_ &&
  302. iaid_ == other.iaid_ &&
  303. preferred_lft_ == other.preferred_lft_ &&
  304. valid_lft_ == other.valid_lft_ &&
  305. t1_ == other.t1_ &&
  306. t2_ == other.t2_ &&
  307. cltt_ == other.cltt_ &&
  308. subnet_id_ == other.subnet_id_ &&
  309. hostname_ == other.hostname_ &&
  310. fqdn_fwd_ == other.fqdn_fwd_ &&
  311. fqdn_rev_ == other.fqdn_rev_ &&
  312. state_ == other.state_);
  313. }
  314. std::ostream&
  315. operator<<(std::ostream& os, const Lease& lease) {
  316. os << lease.toText();
  317. return (os);
  318. }
  319. } // namespace isc::dhcp
  320. } // namespace isc