dhcp6_client.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. // Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef DHCP6_CLIENT_H
  15. #define DHCP6_CLIENT_H
  16. #include <asiolink/io_address.h>
  17. #include <dhcp/duid.h>
  18. #include <dhcp/option.h>
  19. #include <dhcp/option6_client_fqdn.h>
  20. #include <dhcp6/tests/dhcp6_test_utils.h>
  21. #include <boost/noncopyable.hpp>
  22. #include <boost/shared_ptr.hpp>
  23. #include <set>
  24. #include <vector>
  25. namespace isc {
  26. namespace dhcp {
  27. namespace test {
  28. /// @brief DHCPv6 client used for unit testing.
  29. ///
  30. /// This class implements a DHCPv6 "client" which interoperates with the
  31. /// @c NakedDhcpv6Srv class. It calls @c NakedDhcpv6Srv::fakeRecive to
  32. /// deliver client messages to the server for processing. The server places
  33. /// the response in the @c NakedDhcpv6Srv::fake_sent_ container. The client
  34. /// pops messages from this container which simulates reception of the
  35. /// response from the server.
  36. ///
  37. /// The client maintains the leases it acquired from the server. If it has
  38. /// acquired the lease as a result of SARR exchange, it will use this lease
  39. /// when the Rebind process is triggered by the unit test.
  40. ///
  41. /// The client exposes a set of functions which simulate different exchange
  42. /// types between the client and the server. It also provides the access to
  43. /// the objects encapsulating responses from the server so as it is possible
  44. /// to verify from the unit test that the server's response is correct.
  45. ///
  46. /// @todo This class has been implemented to simplify the structure of the
  47. /// unit test and to make unit tests code self-explanatory. Currently,
  48. /// this class is mostly used by the unit tests which test Rebind processing
  49. /// logic. At some point we may want to use this class to test some other
  50. /// message types, e.g. Renew, in which case it may need to be extended.
  51. /// Also, once we implement the support for multiple IAAddr and IAPrefix
  52. /// options within single IA, the logic which maintains leases will have
  53. /// to be extended to support it.
  54. class Dhcp6Client : public boost::noncopyable {
  55. public:
  56. /// @brief Holds an information about single lease.
  57. struct LeaseInfo {
  58. /// @brief A structure describing the lease.
  59. Lease6 lease_;
  60. /// @brief Holds the last status code that server has sent for
  61. /// the particular lease.
  62. uint16_t status_code_;
  63. /// @brief Default constructor for the structure.
  64. LeaseInfo() :
  65. lease_(), status_code_(0) { }
  66. /// @brief Constructor which sets the lease type.
  67. ///
  68. /// @param lease_type One of the D6O_IA_NA or D6O_IA_PD.
  69. LeaseInfo(const uint16_t lease_type) :
  70. lease_(), status_code_(0) {
  71. lease_.type_ = lease_type == D6O_IA_NA ? Lease::TYPE_NA :
  72. Lease::TYPE_PD;
  73. }
  74. };
  75. /// @brief Holds the current client configuration obtained from the
  76. /// server over DHCP.
  77. ///
  78. /// Currently it simply contains the collection of leases acquired
  79. /// and a list of options. Note: this is a simple copy of all
  80. /// non-IA options and often includes "protocol" options, like
  81. /// server-id and client-id.
  82. struct Configuration {
  83. /// @brief List of received leases
  84. std::vector<Lease6> leases_;
  85. /// @brief A map of IAID, status code tuples.
  86. std::map<uint32_t, uint16_t> status_codes_;
  87. /// @brief List of received options
  88. OptionCollection options_;
  89. /// @brief Status code received in the global option scope.
  90. uint16_t status_code_;
  91. /// @brief Indicates if the status code has been received in the
  92. /// last transaction.
  93. bool received_status_code_;
  94. /// @brief Constructor.
  95. Configuration() {
  96. clear();
  97. }
  98. /// @brief Clears configuration.
  99. void clear() {
  100. leases_.clear();
  101. status_codes_.clear();
  102. resetGlobalStatusCode();
  103. }
  104. /// @brief Clears global status code.
  105. ///
  106. /// This function should be called before the new message is received.
  107. void resetGlobalStatusCode() {
  108. status_code_ = 0;
  109. received_status_code_ = false;
  110. }
  111. /// @brief Finds an option with the specific code in the received
  112. /// configuration.
  113. ///
  114. /// @param code Option code.
  115. ///
  116. /// @return Pointer to the option if the option exists, or NULL if
  117. /// the option doesn't exist.
  118. OptionPtr findOption(const uint16_t code) const {
  119. std::multimap<unsigned int, OptionPtr>::const_iterator it = options_.find(code);
  120. if (it != options_.end()) {
  121. return (it->second);
  122. }
  123. return (OptionPtr());
  124. }
  125. };
  126. /// @brief Holds the DHCPv6 messages taking part in transaction between
  127. /// the client and the server.
  128. struct Context {
  129. /// @brief Holds the last sent message from the client to the server.
  130. Pkt6Ptr query_;
  131. /// @brief Holds the last sent message by the server to the client.
  132. Pkt6Ptr response_;
  133. };
  134. /// @brief Creates a new client.
  135. ///
  136. /// This constructor initializes the class members to default values:
  137. /// - relay link-addr = 3000:1::1
  138. /// - first transaction id = 0
  139. /// - dest-addr = All_DHCP_Relay_Agents_and_Servers
  140. /// - duid (LLT) = <random 4 bytes>00010203040506
  141. /// - link-local-addr = fe80::3a60:77ff:fed5:cdef
  142. /// - IA_NA not requested
  143. /// - IA_PD not requested
  144. /// - not relayed
  145. Dhcp6Client();
  146. /// @brief Creates a new client that communicates with a specified server.
  147. ///
  148. /// This constructor allows passing a pointer to the server object which
  149. /// should be used in a test. The server may be preconfigured before passed
  150. /// to the constructor. The default configuration used by the client is:
  151. /// - relay link-addr = 3000:1::1
  152. /// - first transaction id = 0
  153. /// - dest-addr = All_DHCP_Relay_Agents_and_Servers
  154. /// - duid (LLT) = <random 4 bytes>00010203040506
  155. /// - link-local-addr = fe80::3a60:77ff:fed5:cdef
  156. /// - IA_NA not requested
  157. /// - IA_PD not requested
  158. /// - not relayed
  159. ///
  160. /// @param srv Object representing server under test.
  161. Dhcp6Client(boost::shared_ptr<isc::dhcp::test::NakedDhcpv6Srv>& srv);
  162. /// @brief Create lease for the client.
  163. ///
  164. /// This function creates new lease on the client side without contacting
  165. /// the server. This may be useful for the negative tests in which the
  166. /// client is supposed to send invalid addresses/prefixes to the server
  167. /// and expect certain responses.
  168. ///
  169. /// @param lease A lease to be applied for the client.
  170. void createLease(const Lease6& lease);
  171. /// @brief Performs a 4-way exchange between the client and the server.
  172. ///
  173. /// If the 4-way exchange is successful, the client should acquire leases
  174. /// according to the server's current configuration and the type of leases
  175. /// that have been requested (IA_NA, IA_PD).
  176. ///
  177. /// The leases acquired are accessible through the @c config_ member.
  178. ///
  179. /// @throw This function doesn't throw exceptions on its own, but it calls
  180. /// functions that are not exception safe, so it may throw exceptions if
  181. /// error occurs.
  182. ///
  183. /// @todo Perform sanity checks on returned messages.
  184. void doSARR();
  185. /// @brief Send Solicit and receive Advertise.
  186. ///
  187. /// This function simulates the first transaction of the 4-way exchange,
  188. /// i.e. sends a Solicit to the server and receives Advertise. It doesn't
  189. /// set the lease configuration in the @c config_.
  190. ///
  191. /// @throw This function doesn't throw exceptions on its own, but it calls
  192. /// functions that are not exception safe, so it may throw exceptions if
  193. /// error occurs.
  194. ///
  195. /// @todo Perform sanity checks on returned messages.
  196. void doSolicit();
  197. /// @brief Sends a Renew to the server and receives the Reply.
  198. ///
  199. /// This function simulates sending the Renew message to the server and
  200. /// receiving server's response (if any). The client uses existing leases
  201. /// (either address or prefixes) and places them in the Renew message.
  202. /// If the server responds to the Renew (and extends the lease lifetimes)
  203. /// the current lease configuration is updated.
  204. ///
  205. /// @throw This function doesn't throw exceptions on its own, but it calls
  206. /// functions that are not exception safe, so it may throw exceptions if
  207. /// error occurs.
  208. ///
  209. /// @todo Perform sanity checks on returned messages.
  210. void doRenew();
  211. /// @brief Sends a Rebind to the server and receives the Reply.
  212. ///
  213. /// This function simulates sending the Rebind message to the server and
  214. /// receiving server's response (if any). The client uses existing leases
  215. /// (either address or prefixes) and places them in the Rebind message.
  216. /// If the server responds to the Rebind (and extends the lease lifetimes)
  217. /// the current lease configuration is updated.
  218. ///
  219. /// @throw This function doesn't throw exceptions on its own, but it calls
  220. /// functions that are not exception safe, so it may throw exceptions if
  221. /// error occurs.
  222. ///
  223. /// @todo Perform sanity checks on returned messages.
  224. void doRebind();
  225. /// @brief Sends Request to the server and receives Reply.
  226. ///
  227. /// This function simulates sending the Request message to the server and
  228. /// receiving server's response (if any). The client copies IA options
  229. /// from the current context (server's Advertise) to request acquisition
  230. /// of offered IAs. If the server responds to the Request (leases are
  231. /// acquired) the client's lease configuration is updated.
  232. ///
  233. /// @throw This function doesn't throw exceptions on its own, but it calls
  234. /// functions that are not exception safe, so it may throw exceptions if
  235. /// error occurs.
  236. ///
  237. /// @todo Perform sanity checks on returned messages.
  238. void doRequest();
  239. /// @brief Sends Confirm to the server and receives Reply.
  240. ///
  241. /// This function simulates sending the Confirm message to the server and
  242. /// receiving server's response (if any).
  243. void doConfirm();
  244. /// @brief Sends Decline to the server and receives Reply.
  245. ///
  246. /// This function simulates sending the Decline message to the server and
  247. /// receiving the server's response.
  248. void doDecline();
  249. /// @brief Performs stateless (inf-request / reply) exchange.
  250. ///
  251. /// This function generates Information-request message, sends it
  252. /// to the server and then receives the reply. Contents of the Inf-Request
  253. /// are controlled by use_na_, use_pd_, use_client_id_ and use_oro_
  254. /// fields. This method does not process the response in any specific
  255. /// way, just stores it.
  256. void doInfRequest();
  257. /// @brief Removes the stateful configuration obtained from the server.
  258. ///
  259. /// It removes all leases held by the client.
  260. void clearConfig() {
  261. config_.clear();
  262. }
  263. /// @brief Simulates aging of leases by the specified number of seconds.
  264. ///
  265. /// This function moves back the time of acquired leases by the specified
  266. /// number of seconds. It is useful for checking whether the particular
  267. /// lease has been later updated (e.g. as a result of Rebind) as it is
  268. /// expected that the fresh lease has cltt set to "now" (not to the time
  269. /// in the past).
  270. void fastFwdTime(const uint32_t secs);
  271. /// @brief Returns DUID option used by the client.
  272. OptionPtr getClientId() const;
  273. /// @brief Returns current context.
  274. const Context& getContext() const {
  275. return (context_);
  276. }
  277. /// @brief Returns the collection of IAIDs held by the client.
  278. std::set<uint32_t> getIAIDs() const;
  279. /// @brief Returns lease at specified index.
  280. ///
  281. /// @warning This method doesn't check if the specified index is out of
  282. /// range. The caller is responsible for using a correct offset by
  283. /// invoking the @c getLeaseNum function.
  284. ///
  285. /// @param at Index of the lease held by the client.
  286. /// @return A lease at the specified index.
  287. Lease6 getLease(const size_t at) const {
  288. return (config_.leases_[at]);
  289. }
  290. /// @brief Returns collection of leases for specified IAID.
  291. ///
  292. /// @param iaid IAID for which the leases should be returned.
  293. ///
  294. /// @return Vector containing leases for the IAID.
  295. std::vector<Lease6> getLeasesByIAID(const uint32_t iaid) const;
  296. /// @brief Returns collection of leases by type.
  297. ///
  298. /// @param type Lease type: D6O_IA_NA or D6O_IA_PD.
  299. ///
  300. /// @return Vector containing leases of the specified type.
  301. std::vector<Lease6> getLeasesByType(const Lease::Type& lease_type) const;
  302. /// @brief Returns leases with non-zero lifetimes.
  303. std::vector<Lease6> getLeasesWithNonZeroLifetime() const;
  304. /// @brief Returns leases with zero lifetimes.
  305. std::vector<Lease6> getLeasesWithZeroLifetime() const;
  306. /// @brief Returns the value of the global status code for the last
  307. /// transaction.
  308. uint16_t getStatusCode() const {
  309. return (config_.status_code_);
  310. }
  311. /// @brief Returns status code set by the server for the IAID.
  312. ///
  313. /// @warning This method doesn't check if the specified index is out of
  314. /// range. The caller is responsible for using a correct offset by
  315. /// invoking the @c getLeaseNum function.
  316. ///
  317. /// @param at Index of the lease held by the client.
  318. /// @return A status code for the lease at the specified index.
  319. uint16_t getStatusCode(const uint32_t iaid) const;
  320. /// @brief Returns number of acquired leases.
  321. size_t getLeaseNum() const {
  322. return (config_.leases_.size());
  323. }
  324. /// @brief Returns the server that the client is communicating with.
  325. boost::shared_ptr<isc::dhcp::test::NakedDhcpv6Srv> getServer() const {
  326. return (srv_);
  327. }
  328. /// @brief Sets the client's DUID from a string value
  329. ///
  330. /// Replaces the client's DUID with one constructed from the given
  331. /// string. The string is expected to contain hexadecimal digits with or
  332. /// without ":" separators.
  333. ///
  334. /// @param str The string of digits from which to create the DUID
  335. ///
  336. /// The DUID modification affects the value returned by the
  337. /// @c Dhcp6Client::getClientId
  338. void setDUID(const std::string& duid_str);
  339. /// @brief Modifies the client's DUID (adds one to it).
  340. ///
  341. /// The DUID should be modified to test negative scenarios when the client
  342. /// acquires a lease and tries to renew it with a different DUID. The server
  343. /// should detect the DUID mismatch and react accordingly.
  344. ///
  345. /// The DUID modification affects the value returned by the
  346. /// @c Dhcp6Client::getClientId
  347. void modifyDUID();
  348. /// @brief Checks if the global status code was received in the response
  349. /// from the server.
  350. ///
  351. /// @return true if the global status code option was received.
  352. bool receivedStatusCode() const {
  353. return (config_.received_status_code_);
  354. }
  355. /// @brief Sets destination address for the messages being sent by the
  356. /// client.
  357. ///
  358. /// By default, the client uses All_DHCP_Relay_Agents_and_Servers
  359. /// multicast address to communicate with the server. In certain cases
  360. /// it may be desired that different address is used (e.g. unicast in Renew).
  361. /// This function sets the new address for all future exchanges with the
  362. /// server.
  363. ///
  364. /// @param dest_addr New destination address.
  365. void setDestAddress(const asiolink::IOAddress& dest_addr) {
  366. dest_addr_ = dest_addr;
  367. }
  368. /// @brief Sets the interface to be used by the client.
  369. ///
  370. /// @param iface_name Interface name.
  371. void setInterface(const std::string& iface_name) {
  372. iface_name_ = iface_name;
  373. }
  374. /// @brief Set an address hint to be sent to a server.
  375. ///
  376. /// @param pref_lft Preferred lifetime.
  377. /// @param valid_lft Valid lifetime.
  378. /// @param address Address for which the client has a preference.
  379. void useHint(const uint32_t pref_lft, const uint32_t valid_lft,
  380. const std::string& address);
  381. /// @brief Sets a prefix hint to be sent to a server.
  382. ///
  383. /// @param pref_lft Preferred lifetime.
  384. /// @param valid_lft Valid lifetime.
  385. /// @param len Prefix length.
  386. /// @param prefix Prefix for which the client has a preference.
  387. void useHint(const uint32_t pref_lft, const uint32_t valid_lft,
  388. const uint8_t len, const std::string& prefix);
  389. /// @brief Place IA_NA options to request address assignment.
  390. ///
  391. /// This function configures the client to place IA_NA options in its
  392. /// Solicit messages to request the IPv6 address assignment.
  393. ///
  394. /// @param iaid IAID to be used in the IA_NA.
  395. void useNA(const uint32_t iaid) {
  396. useNA(true, iaid);
  397. }
  398. /// @brief Place IA_NA options to request address assignment.
  399. ///
  400. /// This function configures the client to place IA_NA options in its
  401. /// Solicit messages to request the IPv6 address assignment.
  402. ///
  403. /// @param use Parameter which 'true' value indicates that client should
  404. /// request address assignment.
  405. /// @param iaid IAID to be used in the IA_NA.
  406. void useNA(const bool use = true, const uint32_t iaid = 1234) {
  407. use_na_ = use;
  408. na_iaid_ = iaid;
  409. }
  410. /// @brief Place IA_PD options to request address assignment.
  411. ///
  412. /// This function configures the client to place IA_NA options in its
  413. /// Solicit messages to request the IPv6 address assignment.
  414. ///
  415. /// @param iaid IAID to be used in the IA_PD.
  416. void usePD(const uint32_t iaid) {
  417. usePD(true, iaid);
  418. }
  419. /// @brief Place IA_PD options to request prefix assignment.
  420. ///
  421. /// This function configures the client to place IA_PD options in its
  422. /// Solicit messages to request the IPv6 address assignment.
  423. ///
  424. /// @param use Parameter which 'true' value indicates that client should
  425. /// request prefix assignment.
  426. /// @param iaid IAID to be used in the IA_NA.
  427. void usePD(const bool use = true, const uint32_t iaid = 5678) {
  428. use_pd_ = use;
  429. pd_iaid_ = iaid;
  430. }
  431. /// @brief Simulate sending messages through a relay.
  432. ///
  433. /// @param use Parameter which 'true' value indicates that client should
  434. /// simulate sending messages via relay.
  435. /// @param link_addr Relay link-addr.
  436. void useRelay(const bool use = true,
  437. const asiolink::IOAddress& link_addr = asiolink::IOAddress("3000:1::1")) {
  438. use_relay_ = use;
  439. relay_link_addr_ = link_addr;
  440. }
  441. /// @brief Controls whether the client should send a client-id or not
  442. /// @param send should the client-id be sent?
  443. void useClientId(const bool send) {
  444. use_client_id_ = send;
  445. }
  446. /// @brief Controls whether the client should send an addres in IA_NA
  447. ///
  448. /// @todo: For now, this flag is only used in Decline
  449. /// @param send should the address be included?
  450. void includeAddress(const bool send) {
  451. include_address_ = send;
  452. }
  453. /// @brief Specifies if the Rapid Commit option should be included in
  454. /// the Solicit message.
  455. ///
  456. /// @param rapid_commit Boolean parameter controlling if the Rapid Commit
  457. /// option must be included in the Solicit (if true), or not (if false).
  458. void useRapidCommit(const bool rapid_commit) {
  459. use_rapid_commit_ = rapid_commit;
  460. }
  461. /// @brief Specifies server-id to be used in send messages
  462. ///
  463. /// Overrides the server-id to be sent when server-id is expected to be
  464. /// sent. May be NULL, which means use proper server-id sent in Advertise
  465. /// (which is a normal client behavior).
  466. ///
  467. /// @param server_id server-id to be sent
  468. void useServerId(const OptionPtr& server_id) {
  469. forced_server_id_ = server_id;
  470. }
  471. /// @brief Creates an instance of the Client FQDN option to be included
  472. /// in the client's message.
  473. ///
  474. /// @param flags Flags.
  475. /// @param fqdn_name Name in the textual format.
  476. /// @param fqdn_type Type of the name (fully qualified or partial).
  477. void useFQDN(const uint8_t flags, const std::string& fqdn_name,
  478. Option6ClientFqdn::DomainNameType fqdn_type);
  479. /// @brief Lease configuration obtained by the client.
  480. Configuration config_;
  481. /// @brief Link address of the relay to be used for relayed messages.
  482. asiolink::IOAddress relay_link_addr_;
  483. /// @brief RelayInfo (information about relays)
  484. ///
  485. /// Dhcp6Client will typically construct this info itself, but if
  486. /// it is provided here by the test, this data will be used as is.
  487. std::vector<Pkt6::RelayInfo> relay_info_;
  488. /// @brief Controls whether the client will send ORO
  489. ///
  490. /// The actual content of the ORO is specified in oro_.
  491. /// It is useful to split the actual content and the ORO sending
  492. /// decision, so we could test cases of sending empty ORO.
  493. /// @param send controls whether ORO will be sent or not.
  494. void useORO(bool send) {
  495. use_oro_ = send;
  496. }
  497. /// @brief Instructs client to request specified option in ORO
  498. ///
  499. /// @param option_code client will request this option code
  500. void requestOption(uint16_t option_code) {
  501. use_oro_ = true;
  502. oro_.push_back(option_code);
  503. }
  504. /// @brief returns client-id
  505. /// @return client-id
  506. DuidPtr getDuid() const {
  507. return (duid_);
  508. }
  509. /// @brief Generates IA_NA based on lease information
  510. ///
  511. /// @param query generated IA_NA options will be added here
  512. void
  513. generateIAFromLeases(const Pkt6Ptr& query);
  514. private:
  515. /// @brief Applies the new leases for the client.
  516. ///
  517. /// This method is called when the client obtains a new configuration
  518. /// from the server in the Reply message. This function adds new leases
  519. /// or replaces existing ones, on the client's side. Client uses these
  520. /// leases in any later communication with the server when doing Renew
  521. /// or Rebind.
  522. ///
  523. /// @param reply Server response.
  524. /// @param state specifies lease state (see Lease::STATE_* for details).
  525. ///
  526. /// The default for state is 0. We could have included dhcpsrv/lease.h
  527. /// and used Lease::STATE_DEFAULT, but that would complicate the header
  528. /// inclusion dependencies. It's easier to simply use 0 as the default.
  529. ///
  530. /// @todo Currently this function supports one IAAddr or IAPrefix option
  531. /// within IA. We will need to extend it to support multiple options
  532. /// within a single IA once server supports that.
  533. void applyRcvdConfiguration(const Pkt6Ptr& reply, uint32_t state = 0);
  534. /// @brief Applies configuration for the single lease.
  535. ///
  536. /// This method is called by the @c Dhcp6Client::applyRcvdConfiguration for
  537. /// each individual lease.
  538. ///
  539. /// @param lease_info Structure holding new lease information.
  540. void applyLease(const Lease6& lease);
  541. /// @brief Includes Client FQDN in the client's message.
  542. ///
  543. /// This method checks if @c fqdn_ is specified and includes it in
  544. /// the client's message.
  545. void appendFQDN();
  546. /// @brief Includes IAs to be requested.
  547. ///
  548. /// This method checks if @c use_na_ and/or @c use_pd_ are specified and
  549. /// includes appropriate IA types, if they are not already included.
  550. ///
  551. /// @param query Pointer to the client's message to which IAs should be
  552. /// added.
  553. void appendRequestedIAs(const Pkt6Ptr& query) const;
  554. /// @brief Include IA of the specified type if it doesn't exist yet.
  555. ///
  556. /// This methods includes an IA option of the specific type, and
  557. /// having a given IAID to the query message, if this IA hasn't
  558. /// been added yet.
  559. ///
  560. /// @param query Pointer to the client's message to which IA should be
  561. /// added.
  562. /// @param ia_type One of the D6O_IA_NA or D6O_IA_PD
  563. /// @param iaid IAID of the IA.
  564. void conditionallyAppendRequestedIA(const Pkt6Ptr& query,
  565. const uint8_t ia_type,
  566. const uint32_t iaid) const;
  567. /// @brief Copy IA options from one message to another.
  568. ///
  569. /// This method copies IA_NA and IA_PD options from one message to another.
  570. /// It is useful when the client needs to construct the Request message
  571. /// using addresses and prefixes returned by the client in Advertise.
  572. ///
  573. /// @param source Message from which IA options will be copied.
  574. /// @param dest Message to which IA options will be copied.
  575. ///
  576. /// @todo Add support for IA_TA.
  577. void copyIAs(const Pkt6Ptr& source, const Pkt6Ptr& dest);
  578. /// @brief Creates IA options from existing configuration.
  579. ///
  580. /// This method iterates over existing leases that client acquired and
  581. /// places corresponding IA_NA or IA_PD options into a specified message.
  582. /// This is useful to construct Renew, Rebind or Confirm message from the
  583. /// existing configuration that client has obtained using 4-way exchange.
  584. ///
  585. /// If there are no leases no IA options will be added. If the lease exists
  586. /// but any of the lifetime values is set to 0, the IA option will be added
  587. /// but the IAAddr (or IAPrefix) option will not be added.
  588. ///
  589. /// @param dest Message to which the IA options will be added.
  590. void copyIAsFromLeases(const Pkt6Ptr& dest) const;
  591. /// @brief Creates client's side DHCP message.
  592. ///
  593. /// @param msg_type Type of the message to be created.
  594. /// @return An instance of the message created.
  595. Pkt6Ptr createMsg(const uint8_t msg_type);
  596. /// @brief Generates DUID for the client.
  597. ///
  598. /// @param duid_type Type of the DUID. Currently, only LLT is accepted.
  599. /// @return Object encapsulating a DUID.
  600. DuidPtr generateDUID(DUID::DUIDType duid_type) const;
  601. /// @brief Returns client's leases which match the specified condition.
  602. ///
  603. /// @param property A value of the lease property used to search the lease.
  604. /// @param equals A flag which indicates if the operator should search
  605. /// for the leases which property is equal to the value of @c property
  606. /// parameter (if true), or unequal (if false).
  607. /// @param [out] leases A vector in which the operator will store leases
  608. /// found.
  609. ///
  610. /// @tparam BaseType Base type to which the property belongs: @c Lease or
  611. /// @c Lease6.
  612. /// @tparam PropertyType A type of the property, e.g. @c uint32_t for IAID.
  613. /// @tparam MemberPointer A pointer to the member, e.g. @c &Lease6::iaid_.
  614. template<typename BaseType, typename PropertyType,
  615. PropertyType BaseType::*MemberPointer>
  616. void getLeasesByProperty(const PropertyType& property, const bool equals,
  617. std::vector<Lease6>& leases) const;
  618. /// @brief Simulates reception of the message from the server.
  619. ///
  620. /// @return Received message.
  621. Pkt6Ptr receiveOneMsg();
  622. /// @brief Simulates sending a message to the server.
  623. ///
  624. /// This function instantly triggers processing of the message by the
  625. /// server. The server's response can be gathered by invoking the
  626. /// @c receiveOneMsg function.
  627. ///
  628. /// @param msg Message to be sent.
  629. void sendMsg(const Pkt6Ptr& msg);
  630. /// @brief Current context (sent and received message).
  631. Context context_;
  632. /// @brief Current transaction id (altered on each send).
  633. uint32_t curr_transid_;
  634. /// @brief Currently used destination address.
  635. asiolink::IOAddress dest_addr_;
  636. /// @brief Currently used DUID.
  637. DuidPtr duid_;
  638. /// @brief Currently used link local address.
  639. asiolink::IOAddress link_local_;
  640. /// @brief Currently used interface.
  641. std::string iface_name_;
  642. /// @brief Pointer to the server that the client is communicating with.
  643. boost::shared_ptr<isc::dhcp::test::NakedDhcpv6Srv> srv_;
  644. bool use_na_; ///< Enable address assignment.
  645. bool use_pd_; ///< Enable prefix delegation.
  646. bool use_relay_; ///< Enable relaying messages to the server.
  647. bool use_oro_; ///< Conth
  648. bool use_client_id_;
  649. bool use_rapid_commit_;
  650. /// @brief Pointer to the option holding an address hint.
  651. Option6IAAddrPtr address_hint_;
  652. /// @brief Pointer to the option holding a prefix hint.
  653. Option6IAPrefixPtr prefix_hint_;
  654. /// @brief List of options to be requested
  655. ///
  656. /// Content of this vector will be sent as ORO if use_oro_ is set
  657. /// to true. See @ref sendORO for details.
  658. std::vector<uint16_t> oro_;
  659. /// @brief forced (Overridden) value of the server-id option (may be NULL)
  660. OptionPtr forced_server_id_;
  661. /// @brief FQDN requested by the client.
  662. Option6ClientFqdnPtr fqdn_;
  663. /// @bref IAID used by the client when requesting address assignment.
  664. uint32_t na_iaid_;
  665. /// @brief IAID used by the client when requesting prefix delegation.
  666. uint32_t pd_iaid_;
  667. /// @brief Determines if the client will include address in the messages
  668. /// it sends.
  669. ///
  670. /// @todo this flag is currently supported in Decline only.
  671. bool include_address_;
  672. };
  673. } // end of namespace isc::dhcp::test
  674. } // end of namespace isc::dhcp
  675. } // end of namespace isc
  676. #endif // DHCP6_CLIENT