dhcp6_srv.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. // Copyright (C) 2011-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 DHCPV6_SRV_H
  15. #define DHCPV6_SRV_H
  16. #include <dhcp_ddns/ncr_msg.h>
  17. #include <dhcp/dhcp6.h>
  18. #include <dhcp/duid.h>
  19. #include <dhcp/option.h>
  20. #include <dhcp/option6_client_fqdn.h>
  21. #include <dhcp/option6_ia.h>
  22. #include <dhcp/option_definition.h>
  23. #include <dhcp/pkt6.h>
  24. #include <dhcpsrv/alloc_engine.h>
  25. #include <dhcpsrv/d2_client_mgr.h>
  26. #include <dhcpsrv/subnet.h>
  27. #include <hooks/callout_handle.h>
  28. #include <dhcpsrv/daemon.h>
  29. #include <iostream>
  30. #include <queue>
  31. namespace isc {
  32. namespace dhcp {
  33. /// @brief This exception is thrown when DHCP server hits the error which should
  34. /// result in discarding the message being processed.
  35. class DHCPv6DiscardMessageError : public Exception {
  36. public:
  37. DHCPv6DiscardMessageError(const char* file, size_t line, const char* what) :
  38. isc::Exception(file, line, what) { };
  39. };
  40. /// @brief DHCPv6 server service.
  41. ///
  42. /// This class represents DHCPv6 server. It contains all
  43. /// top-level methods and routines necessary for server operation.
  44. /// In particular, it instantiates IfaceMgr, loads or generates DUID
  45. /// that is going to be used as server-identifier, receives incoming
  46. /// packets, processes them, manages leases assignment and generates
  47. /// appropriate responses.
  48. class Dhcpv6Srv : public Daemon {
  49. public:
  50. /// @brief defines if certain option may, must or must not appear
  51. typedef enum {
  52. FORBIDDEN,
  53. MANDATORY,
  54. OPTIONAL
  55. } RequirementLevel;
  56. /// @brief Minimum length of a MAC address to be used in DUID generation.
  57. static const size_t MIN_MAC_LEN = 6;
  58. /// @brief Default constructor.
  59. ///
  60. /// Instantiates necessary services, required to run DHCPv6 server.
  61. /// In particular, creates IfaceMgr that will be responsible for
  62. /// network interaction. Will instantiate lease manager, and load
  63. /// old or create new DUID.
  64. ///
  65. /// @param port port on will all sockets will listen
  66. Dhcpv6Srv(uint16_t port = DHCP6_SERVER_PORT);
  67. /// @brief Destructor. Used during DHCPv6 service shutdown.
  68. virtual ~Dhcpv6Srv();
  69. /// @brief Returns server-indentifier option.
  70. ///
  71. /// @return server-id option
  72. OptionPtr getServerID() { return serverid_; }
  73. /// @brief Main server processing loop.
  74. ///
  75. /// Main server processing loop. Receives incoming packets, verifies
  76. /// their correctness, generates appropriate answer (if needed) and
  77. /// transmits responses.
  78. ///
  79. /// @return true, if being shut down gracefully, fail if experienced
  80. /// critical error.
  81. bool run();
  82. /// @brief Instructs the server to shut down.
  83. void shutdown();
  84. /// @brief Get UDP port on which server should listen.
  85. ///
  86. /// Typically, server listens on UDP port 547. Other ports are only
  87. /// used for testing purposes.
  88. ///
  89. /// @return UDP port on which server should listen.
  90. uint16_t getPort() const {
  91. return (port_);
  92. }
  93. /// @brief Starts DHCP_DDNS client IO if DDNS updates are enabled.
  94. ///
  95. /// If updates are enabled, it Instructs the D2ClientMgr singleton to
  96. /// enter send mode. If D2ClientMgr encounters errors it may throw
  97. /// D2ClientErrors. This method does not catch exceptions.
  98. void startD2();
  99. /// @brief Implements the error handler for DHCP_DDNS IO errors
  100. ///
  101. /// Invoked when a NameChangeRequest send to kea-dhcp-ddns completes with
  102. /// a failed status. These are communications errors, not data related
  103. /// failures.
  104. ///
  105. /// This method logs the failure and then suspends all further updates.
  106. /// Updating can only be restored by reconfiguration or restarting the
  107. /// server. There is currently no retry logic so the first IO error that
  108. /// occurs will suspend updates.
  109. /// @todo We may wish to make this more robust or sophisticated.
  110. ///
  111. /// @param result Result code of the send operation.
  112. /// @param ncr NameChangeRequest which failed to send.
  113. virtual void d2ClientErrorHandler(const dhcp_ddns::
  114. NameChangeSender::Result result,
  115. dhcp_ddns::NameChangeRequestPtr& ncr);
  116. protected:
  117. /// @brief Compare received server id with our server id
  118. ///
  119. /// Checks if the server id carried in a query from a client matches
  120. /// server identifier being used by the server.
  121. ///
  122. /// @param pkt DHCPv6 packet carrying server identifier to be checked.
  123. /// @return true if server id carried in the query matches server id
  124. /// used by the server; false otherwise.
  125. bool testServerID(const Pkt6Ptr& pkt);
  126. /// @brief Check if the message can be sent to unicast.
  127. ///
  128. /// This function checks if the received message conforms to the section 15
  129. /// of RFC3315 which says that: "A server MUST discard any Solicit, Confirm,
  130. /// Rebind or Information-request messages it receives with a unicast
  131. /// destination address.
  132. ///
  133. /// @param pkt DHCPv6 message to be checked.
  134. /// @return false if the message has been sent to unicast address but it is
  135. /// not allowed according to RFC3315, section 15; true otherwise.
  136. bool testUnicast(const Pkt6Ptr& pkt) const;
  137. /// @brief verifies if specified packet meets RFC requirements
  138. ///
  139. /// Checks if mandatory option is really there, that forbidden option
  140. /// is not there, and that client-id or server-id appears only once.
  141. ///
  142. /// @param pkt packet to be checked
  143. /// @param clientid expectation regarding client-id option
  144. /// @param serverid expectation regarding server-id option
  145. /// @throw RFCViolation if any issues are detected
  146. void sanityCheck(const Pkt6Ptr& pkt, RequirementLevel clientid,
  147. RequirementLevel serverid);
  148. /// @brief Processes incoming SOLICIT and returns response.
  149. ///
  150. /// Processes received SOLICIT message and verifies that its sender
  151. /// should be served. In particular IA, TA and PD options are populated
  152. /// with to-be assigned addresses, temporary addresses and delegated
  153. /// prefixes, respectively. In the usual 4 message exchange, server is
  154. /// expected to respond with ADVERTISE message. However, if client
  155. /// requests rapid-commit and server supports it, REPLY will be sent
  156. /// instead of ADVERTISE and requested leases will be assigned
  157. /// immediately.
  158. ///
  159. /// @param solicit SOLICIT message received from client
  160. ///
  161. /// @return ADVERTISE, REPLY message or NULL
  162. Pkt6Ptr processSolicit(const Pkt6Ptr& solicit);
  163. /// @brief Processes incoming REQUEST and returns REPLY response.
  164. ///
  165. /// Processes incoming REQUEST message and verifies that its sender
  166. /// should be served. In particular IA, TA and PD options are populated
  167. /// with assigned addresses, temporary addresses and delegated
  168. /// prefixes, respectively. Uses LeaseMgr to allocate or update existing
  169. /// leases.
  170. ///
  171. /// @param request a message received from client
  172. ///
  173. /// @return REPLY message or NULL
  174. Pkt6Ptr processRequest(const Pkt6Ptr& request);
  175. /// @brief Stub function that will handle incoming RENEW messages.
  176. ///
  177. /// @param renew message received from client
  178. Pkt6Ptr processRenew(const Pkt6Ptr& renew);
  179. /// @brief Stub function that will handle incoming REBIND messages.
  180. ///
  181. /// @param rebind message received from client
  182. Pkt6Ptr processRebind(const Pkt6Ptr& rebind);
  183. /// @brief Processes incoming Confirm message and returns Reply.
  184. ///
  185. /// This function processes Confirm message from the client according
  186. /// to section 18.2.2. of RFC3315. It discards the Confirm message if
  187. /// the message sent by the client contains no addresses, i.e. it has
  188. /// no IA_NA options or all IA_NA options contain no IAAddr options.
  189. ///
  190. /// If the Confirm message contains addresses this function will perform
  191. /// the following checks:
  192. /// - check if there is appropriate subnet configured for the client
  193. /// (e.g. subnet from which addresses are assigned for requests
  194. /// received on the particular interface).
  195. /// - check if all addresses sent in the Confirm message belong to the
  196. /// selected subnet.
  197. ///
  198. /// If any of the checks above fails, the Reply message with the status
  199. /// code NotOnLink is returned. Otherwise, the Reply message with the
  200. /// status code Success is returned.
  201. ///
  202. /// @param confirm Confirm message sent by a client.
  203. ///
  204. /// @return Reply message from the server al NULL pointer if Confirm
  205. /// message should be discarded by the server.
  206. Pkt6Ptr processConfirm(const Pkt6Ptr& confirm);
  207. /// @brief Stub function that will handle incoming RELEASE messages.
  208. ///
  209. /// @param release message received from client
  210. Pkt6Ptr processRelease(const Pkt6Ptr& release);
  211. /// @brief Stub function that will handle incoming DECLINE messages.
  212. ///
  213. /// @param decline message received from client
  214. Pkt6Ptr processDecline(const Pkt6Ptr& decline);
  215. /// @brief Stub function that will handle incoming INF-REQUEST messages.
  216. ///
  217. /// @param infRequest message received from client
  218. Pkt6Ptr processInfRequest(const Pkt6Ptr& infRequest);
  219. /// @brief Creates status-code option.
  220. ///
  221. /// @param code status code value (see RFC3315)
  222. /// @param text textual explanation (will be sent in status code option)
  223. /// @return status-code option
  224. OptionPtr createStatusCode(uint16_t code, const std::string& text);
  225. /// @brief Selects a subnet for a given client's packet.
  226. ///
  227. /// @param question client's message
  228. /// @return selected subnet (or NULL if no suitable subnet was found)
  229. isc::dhcp::Subnet6Ptr selectSubnet(const Pkt6Ptr& question);
  230. /// @brief Processes IA_NA option (and assigns addresses if necessary).
  231. ///
  232. /// Generates response to IA_NA. This typically includes selecting (and
  233. /// allocating a lease in case of REQUEST) an address lease and creating
  234. /// IAADDR option. In case of allocation failure, it may contain
  235. /// status code option with non-zero status, denoting cause of the
  236. /// allocation failure.
  237. ///
  238. /// @param subnet subnet the client is connected to
  239. /// @param duid client's duid
  240. /// @param query client's message (typically SOLICIT or REQUEST)
  241. /// @param answer server's response to the client's message. This
  242. /// message should contain Client FQDN option being sent by the server
  243. /// to the client (if the client sent this option to the server).
  244. /// @param ia pointer to client's IA_NA option (client's request)
  245. ///
  246. /// @return IA_NA option (server's response)
  247. OptionPtr assignIA_NA(const isc::dhcp::Subnet6Ptr& subnet,
  248. const isc::dhcp::DuidPtr& duid,
  249. const isc::dhcp::Pkt6Ptr& query,
  250. const isc::dhcp::Pkt6Ptr& answer,
  251. Option6IAPtr ia);
  252. /// @brief Processes IA_PD option (and assigns prefixes if necessary).
  253. ///
  254. /// Generates response to IA_PD. This typically includes selecting (and
  255. /// allocating in the case of REQUEST) a prefix lease and creating an
  256. /// IAPREFIX option. In case of an allocation failure, it may contain a
  257. /// status code option with non-zero status denoting the cause of the
  258. /// allocation failure.
  259. ///
  260. /// @param subnet subnet the client is connected to
  261. /// @param duid client's duid
  262. /// @param query client's message (typically SOLICIT or REQUEST)
  263. /// @param ia pointer to client's IA_PD option (client's request)
  264. /// @return IA_PD option (server's response)
  265. OptionPtr assignIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid,
  266. const Pkt6Ptr& query,
  267. boost::shared_ptr<Option6IA> ia);
  268. /// @brief Extends lifetime of the specific IA_NA option.
  269. ///
  270. /// Generates response to IA_NA in Renew or Rebind. This typically includes
  271. /// finding a lease that corresponds to the received address. If no such
  272. /// lease is found, an IA_NA response is generated with an appropriate
  273. /// status code.
  274. ///
  275. /// @todo The behavior of this function will need to be extended to support
  276. /// draft-ietf-dhc-dhcpv6-stateful-issues. This draft modifies the behavior
  277. /// described in RFC3315 with respect to Renew and Rebind processing. Key
  278. /// changes are (version -05):
  279. /// - Renewing and Rebinding client MAY request additional bindings by
  280. /// putting an IA for all bindings it desires but has been unable to obtain.
  281. /// Server MAY allocate addresses if it finds that they are appropriate for
  282. /// the link that client is attached to.
  283. /// - When receiving Rebind, if the server determines that the addresses are
  284. /// not appropriate for the link the client is attached to, the server MAY
  285. /// send the IA with address lifetimes set to 0 or discard the message.
  286. ///
  287. /// @param subnet subnet the sender belongs to
  288. /// @param duid client's duid
  289. /// @param query client's message (Renew or Rebind)
  290. /// @param answer server's response to the client's message. This
  291. /// message should contain Client FQDN option being sent by the server
  292. /// to the client (if the client sent this option to the server).
  293. /// @param ia IA_NA option which carries adress for which lease lifetime
  294. /// will be extended.
  295. /// @return IA_NA option (server's response)
  296. OptionPtr extendIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
  297. const Pkt6Ptr& query, const Pkt6Ptr& answer,
  298. Option6IAPtr ia);
  299. /// @brief Extends lifetime of the prefix.
  300. ///
  301. /// This function is called by the logic which processes Renew and Rebind
  302. /// messages to extend the lifetime of the existing prefix.
  303. ///
  304. /// The behavior of this function is different in that when there is no
  305. /// binding found in the lease database for the particular client the
  306. /// NoBinding status code is returned when processing Renew, the exception
  307. /// is thrown when there is no binding and the Rebind message is processed
  308. /// (see RFC3633, section 12.2. for details).
  309. ///
  310. /// @param subnet subnet the sender belongs to
  311. /// @param duid client's duid
  312. /// @param query client's message
  313. /// @param ia IA_PD option that is being renewed
  314. /// @return IA_PD option (server's response)
  315. /// @throw DHCPv6DiscardMessageError when the message being processed should
  316. /// be discarded by the server, i.e. there is no binding for the client doing
  317. /// Rebind.
  318. OptionPtr extendIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid,
  319. const Pkt6Ptr& query, Option6IAPtr ia);
  320. /// @brief Releases specific IA_NA option
  321. ///
  322. /// Generates response to IA_NA in Release message. This covers finding and
  323. /// removal of a lease that corresponds to the received address. If no such
  324. /// lease is found, an IA_NA response is generated with an appropriate
  325. /// status code.
  326. ///
  327. /// As RFC 3315 requires that a single status code be sent for the whole message,
  328. /// this method may update the passed general_status: it is set to SUCCESS when
  329. /// message processing begins, but may be updated to some error code if the
  330. /// release process fails.
  331. ///
  332. /// @param duid client's duid
  333. /// @param query client's message
  334. /// @param general_status a global status (it may be updated in case of errors)
  335. /// @param ia IA_NA option that is being released
  336. /// @return IA_NA option (server's response)
  337. OptionPtr releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
  338. int& general_status,
  339. boost::shared_ptr<Option6IA> ia);
  340. /// @brief Releases specific IA_PD option
  341. ///
  342. /// Generates response to IA_PD in Release message. This covers finding and
  343. /// removal of a lease that corresponds to the received prefix(es). If no such
  344. /// lease is found, an IA_PD response is generated with an appropriate
  345. /// status code.
  346. ///
  347. /// @param duid client's duid
  348. /// @param query client's message
  349. /// @param general_status a global status (it may be updated in case of errors)
  350. /// @param ia IA_PD option that is being released
  351. /// @return IA_PD option (server's response)
  352. OptionPtr releaseIA_PD(const DuidPtr& duid, const Pkt6Ptr& query,
  353. int& general_status,
  354. boost::shared_ptr<Option6IA> ia);
  355. /// @brief Copies required options from client message to server answer.
  356. ///
  357. /// Copies options that must appear in any server response (ADVERTISE, REPLY)
  358. /// to client's messages (SOLICIT, REQUEST, RENEW, REBIND, DECLINE, RELEASE).
  359. /// One notable example is client-id. Other options may be copied as required.
  360. /// Relay information details are also copied here.
  361. ///
  362. /// @param question client's message (options will be copied from here)
  363. /// @param answer server's message (options will be copied here)
  364. void copyClientOptions(const Pkt6Ptr& question, Pkt6Ptr& answer);
  365. /// @brief Appends default options to server's answer.
  366. ///
  367. /// Adds required options to server's answer. In particular, server-id
  368. /// is added. Possibly other mandatory options will be added, depending
  369. /// on type (or content) of client message.
  370. ///
  371. /// @param question client's message
  372. /// @param answer server's message (options will be added here)
  373. void appendDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer);
  374. /// @brief Appends requested options to server's answer.
  375. ///
  376. /// Appends options requested by client to the server's answer.
  377. ///
  378. /// @param question client's message
  379. /// @param answer server's message (options will be added here)
  380. void appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer);
  381. /// @brief Appends requested vendor options to server's answer.
  382. ///
  383. /// This is mostly useful for Cable Labs options for now, but the method
  384. /// is easily extensible to other vendors.
  385. ///
  386. /// @param question client's message
  387. /// @param answer server's message (vendor options will be added here)
  388. void appendRequestedVendorOptions(const Pkt6Ptr& question, Pkt6Ptr& answer);
  389. /// @brief Assigns leases.
  390. ///
  391. /// It supports addresses (IA_NA) only. It does NOT support temporary
  392. /// addresses (IA_TA) nor prefixes (IA_PD).
  393. /// @todo: Extend this method once TA and PD becomes supported
  394. ///
  395. /// @param question client's message (with requested IA_NA)
  396. /// @param answer server's message (IA_NA options will be added here).
  397. /// This message should contain Client FQDN option being sent by the server
  398. /// to the client (if the client sent this option to the server).
  399. void assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer);
  400. /// @brief Processes Client FQDN Option.
  401. ///
  402. /// This function retrieves DHCPv6 Client FQDN %Option (if any) from the
  403. /// packet sent by a client and takes necessary actions upon this option.
  404. /// Received option comprises flags field which controls what DNS updates
  405. /// server should do. Server may override client's preference based on
  406. /// the current configuration. Server indicates that it has overridden
  407. /// the preference by storing DHCPv6 Client FQDN option with the
  408. /// appropriate flags in the response to a client. This option is also
  409. /// used to communicate the client's domain-name which should be sent
  410. /// to the DNS in the update. Again, server may act upon the received
  411. /// domain-name, i.e. if the provided domain-name is partial it should
  412. /// generate the fully qualified domain-name.
  413. ///
  414. /// All the logic required to form appropriate answer to the client is
  415. /// held in this function.
  416. ///
  417. /// @param question Client's message.
  418. /// @param answer Server's response to a client. If server generated
  419. /// Client FQDN option for the client, this option is stored in this
  420. /// object.
  421. void processClientFqdn(const Pkt6Ptr& question, const Pkt6Ptr& answer);
  422. /// @brief Creates a number of @c isc::dhcp_ddns::NameChangeRequest objects
  423. /// based on the DHCPv6 Client FQDN %Option.
  424. ///
  425. /// The @c isc::dhcp_ddns::NameChangeRequest class encapsulates the request
  426. /// from the DHCPv6 server to the DHCP-DDNS module to perform DNS Update.
  427. /// The FQDN option carries response to the client about DNS updates that
  428. /// server intents to perform for the DNS client. Based on this, the
  429. /// function will create zero or more @c isc::dhcp_ddns::NameChangeRequest
  430. /// objects and store them in the internal queue. Requests created by this
  431. /// function are only adding or updating DNS records. In order to generate
  432. /// requests for DNS records removal, use @c createRemovalNameChangeRequest.
  433. /// If ddns updates are disabled, this method returns immediately.
  434. ///
  435. /// @todo Add support for multiple IAADDR options in the IA_NA.
  436. ///
  437. /// @param answer A message beging sent to the Client. If it holds the
  438. /// Client FQDN option, this option is used to create NameChangeRequests.
  439. void createNameChangeRequests(const Pkt6Ptr& answer);
  440. /// @brief Creates a @c isc::dhcp_ddns::NameChangeRequest which requests
  441. /// removal of DNS entries for a particular lease.
  442. ///
  443. /// This function should be called upon removal of the lease from the lease
  444. /// database, i.e, when client sent Release or Decline message. It will
  445. /// create a single @c isc::dhcp_ddns::NameChangeRequest which removes the
  446. /// existing DNS records for the lease, which server is responsible for.
  447. /// Note that this function will not remove the entries which server hadn't
  448. /// added. This is the case, when client performs forward DNS update on its
  449. /// own.
  450. /// If ddns updates are disabled, this method returns immediately.
  451. ///
  452. /// @param lease A lease for which the the removal of corresponding DNS
  453. /// records will be performed.
  454. void createRemovalNameChangeRequest(const Lease6Ptr& lease);
  455. /// @brief Attempts to extend the lifetime of IAs.
  456. ///
  457. /// This function is called when a client sends Renew or Rebind message.
  458. /// It iterates through received IA options and attempts to extend
  459. /// corresponding lease lifetimes. Internally, it calls
  460. /// @c Dhcpv6Srv::extendIA_NA and @c Dhcpv6Srv::extendIA_PD to extend
  461. /// the lifetime of IA_NA and IA_PD leases accordingly.
  462. ///
  463. /// @param query client's Renew or Rebind message
  464. /// @param reply server's response
  465. void extendLeases(const Pkt6Ptr& query, Pkt6Ptr& reply);
  466. /// @brief Attempts to release received addresses
  467. ///
  468. /// It iterates through received IA_NA options and attempts to release
  469. /// received addresses. If no such leases are found, or the lease fails
  470. /// proper checks (e.g. belongs to someone else), a proper status
  471. /// code is added to reply message. Released addresses are not added
  472. /// to REPLY packet, just its IA_NA containers.
  473. /// @param release client's message asking to release
  474. /// @param reply server's response
  475. void releaseLeases(const Pkt6Ptr& release, Pkt6Ptr& reply);
  476. /// @brief Sets server-identifier.
  477. ///
  478. /// This method attempts to generate server-identifier DUID. It generates a
  479. /// new DUID using interface link-layer addresses (EUI-64) + timestamp (DUID
  480. /// type duid-llt, see RFC3315, section 9.2). If there are no suitable
  481. /// interfaces present, exception it thrown
  482. ///
  483. /// @throws isc::Unexpected Failed to read DUID file and no suitable
  484. /// interfaces for new DUID generation are detected.
  485. void generateServerID();
  486. /// @brief attempts to load DUID from a file
  487. ///
  488. /// Tries to load duid from a text file. If the load is successful,
  489. /// it creates server-id option and stores it in serverid_ (to be used
  490. /// later by getServerID()).
  491. ///
  492. /// @param file_name name of the DUID file to load
  493. /// @return true if load was successful, false otherwise
  494. bool loadServerID(const std::string& file_name);
  495. /// @brief attempts to write DUID to a file
  496. /// Tries to write duid content (stored in serverid_) to a text file.
  497. ///
  498. /// @param file_name name of the DUID file to write
  499. /// @return true if write was successful, false otherwise
  500. bool writeServerID(const std::string& file_name);
  501. /// @brief converts DUID to text
  502. /// Converts content of DUID option to a text representation, e.g.
  503. /// 01:ff:02:03:06:80:90:ab:cd:ef
  504. ///
  505. /// @param opt option that contains DUID
  506. /// @return string representation
  507. static std::string duidToString(const OptionPtr& opt);
  508. /// @brief dummy wrapper around IfaceMgr::receive6
  509. ///
  510. /// This method is useful for testing purposes, where its replacement
  511. /// simulates reception of a packet. For that purpose it is protected.
  512. virtual Pkt6Ptr receivePacket(int timeout);
  513. /// @brief dummy wrapper around IfaceMgr::send()
  514. ///
  515. /// This method is useful for testing purposes, where its replacement
  516. /// simulates transmission of a packet. For that purpose it is protected.
  517. virtual void sendPacket(const Pkt6Ptr& pkt);
  518. /// @brief Implements a callback function to parse options in the message.
  519. ///
  520. /// @param buf a A buffer holding options in on-wire format.
  521. /// @param option_space A name of the option space which holds definitions
  522. /// of to be used to parse options in the packets.
  523. /// @param [out] options A reference to the collection where parsed options
  524. /// will be stored.
  525. /// @param relay_msg_offset Reference to a size_t structure. If specified,
  526. /// offset to beginning of relay_msg option will be stored in it.
  527. /// @param relay_msg_len reference to a size_t structure. If specified,
  528. /// length of the relay_msg option will be stored in it.
  529. /// @return An offset to the first byte after last parsed option.
  530. size_t unpackOptions(const OptionBuffer& buf,
  531. const std::string& option_space,
  532. isc::dhcp::OptionCollection& options,
  533. size_t* relay_msg_offset,
  534. size_t* relay_msg_len);
  535. /// @brief Assigns incoming packet to zero or more classes.
  536. ///
  537. /// @note For now, the client classification is very simple. It just uses
  538. /// content of the vendor-class-identifier option as a class. The resulting
  539. /// class will be stored in packet (see @ref isc::dhcp::Pkt6::classes_ and
  540. /// @ref isc::dhcp::Pkt6::inClass).
  541. ///
  542. /// @param pkt packet to be classified
  543. void classifyPacket(const Pkt6Ptr& pkt);
  544. /// @brief Attempts to get a MAC/hardware address using configred sources
  545. ///
  546. /// Tries to extract MAC/hardware address information from the packet
  547. /// using MAC sources configured in 'mac-sources' configuration parameter.
  548. ///
  549. /// @param pkt will try to exact MAC address from this packet
  550. /// @return HWaddr pointer (or NULL if configured methods fail)
  551. static HWAddrPtr getMAC(const Pkt6Ptr& pkt);
  552. /// @brief this is a prefix added to the contend of vendor-class option
  553. ///
  554. /// If incoming packet has a vendor class option, its content is
  555. /// prepended with this prefix and then interpreted as a class.
  556. /// For example, a packet that sends vendor class with value of "FOO"
  557. /// will cause the packet to be assigned to class VENDOR_CLASS_FOO.
  558. static const std::string VENDOR_CLASS_PREFIX;
  559. private:
  560. /// @brief Implements the error handler for socket open failure.
  561. ///
  562. /// This callback function is installed on the @c isc::dhcp::IfaceMgr
  563. /// when IPv6 sockets are being open. When socket fails to open for
  564. /// any reason, this function is called. It simply logs the error message.
  565. ///
  566. /// @param errmsg An error message containing a cause of the failure.
  567. static void ifaceMgrSocket6ErrorHandler(const std::string& errmsg);
  568. /// @brief Generate FQDN to be sent to a client if none exists.
  569. ///
  570. /// This function is meant to be called by the functions which process
  571. /// client's messages. The function should be called after a function
  572. /// which creates FQDN option for the client. This option must exist
  573. /// in the answer message specified as an argument. It must also be
  574. /// called after functions which assign leases for a client. The
  575. /// IA options being a result of lease acquisition must be appended
  576. /// to the message specified as a parameter.
  577. ///
  578. /// If the Client FQDN option being present in the message carries empty
  579. /// hostname, this function will attempt to generate hostname from the
  580. /// IPv6 address being acquired by the client. The IPv6 address is retrieved
  581. /// from the IA_NA option carried in the specified message. If multiple
  582. /// addresses are present in the particular IA_NA option or multiple IA_NA
  583. /// options exist, the first address found is selected.
  584. ///
  585. /// The IPv6 address is converted to the hostname using the following
  586. /// pattern:
  587. /// @code
  588. /// prefix-converted-ip-address.domain-name-suffix.
  589. /// @endcode
  590. /// where:
  591. /// - prefix is a configurable prefix string appended to all auto-generated
  592. /// hostnames.
  593. /// - converted-ip-address is created by replacing all colons from the IPv6
  594. /// address with hyphens.
  595. /// - domain-name-suffix is a suffix for a domain name that, together with
  596. /// the other parts, constitute the fully qualified domain name.
  597. ///
  598. /// When hostname is successfully generated, it is either used to update
  599. /// FQDN-related fields in a lease database or to update the Client FQDN
  600. /// option being sent back to the client. The lease database update is
  601. /// NOT performed if Advertise message is being processed.
  602. ///
  603. /// @param answer Message being sent to a client, which may hold IA_NA
  604. /// and Client FQDN options to be used to generate name for a client.
  605. ///
  606. /// @throw isc::Unexpected if specified message is NULL. This is treated
  607. /// as a programmatic error.
  608. void generateFqdn(const Pkt6Ptr& answer);
  609. /// @brief Triggers removal Name Change Request if FQDN data changes in leases
  610. ///
  611. /// If there are any differences (different fwd or rev flags, or different
  612. /// hostname) a DNS update for removing entry will be generated.
  613. ///
  614. /// @param old_lease old version of the lease
  615. /// @param new_lease new version of the lease (may be NULL)
  616. /// @param hostname specifies hostname (for printing purposes)
  617. /// @param do_fwd specifies if reverse updates are enabled (for printing purposes)
  618. /// @param do_rev specifies if reverse updates are enabled (for printing purposes)
  619. void conditionalNCRRemoval(Lease6Ptr& old_lease, Lease6Ptr& new_lease,
  620. const std::string& hostname,
  621. bool do_fwd, bool do_rev);
  622. /// @brief Allocation Engine.
  623. /// Pointer to the allocation engine that we are currently using
  624. /// It must be a pointer, because we will support changing engines
  625. /// during normal operation (e.g. to use different allocators)
  626. boost::shared_ptr<AllocEngine> alloc_engine_;
  627. /// Server DUID (to be sent in server-identifier option)
  628. OptionPtr serverid_;
  629. /// UDP port number on which server listens.
  630. uint16_t port_;
  631. protected:
  632. /// Indicates if shutdown is in progress. Setting it to true will
  633. /// initiate server shutdown procedure.
  634. volatile bool shutdown_;
  635. /// Holds a list of @c isc::dhcp_ddns::NameChangeRequest objects, which
  636. /// are waiting for sending to kea-dhcp-ddns module.
  637. std::queue<isc::dhcp_ddns::NameChangeRequest> name_change_reqs_;
  638. };
  639. }; // namespace isc::dhcp
  640. }; // namespace isc
  641. #endif // DHCP6_SRV_H