dhcp4_srv.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. // Copyright (C) 2011-2013 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 DHCPV4_SRV_H
  15. #define DHCPV4_SRV_H
  16. #include <dhcp/dhcp4.h>
  17. #include <dhcp/pkt4.h>
  18. #include <dhcp/option.h>
  19. #include <dhcp/option4_client_fqdn.h>
  20. #include <dhcp/option_custom.h>
  21. #include <dhcp_ddns/ncr_msg.h>
  22. #include <dhcpsrv/subnet.h>
  23. #include <dhcpsrv/alloc_engine.h>
  24. #include <hooks/callout_handle.h>
  25. #include <boost/noncopyable.hpp>
  26. #include <iostream>
  27. #include <queue>
  28. namespace isc {
  29. namespace dhcp {
  30. /// @brief Exception thrown when DHCID computation failed.
  31. class DhcidComputeError : public isc::Exception {
  32. public:
  33. DhcidComputeError(const char* file, size_t line, const char* what) :
  34. isc::Exception(file, line, what) { };
  35. };
  36. /// @brief DHCPv4 server service.
  37. ///
  38. /// This singleton class represents DHCPv4 server. It contains all
  39. /// top-level methods and routines necessary for server operation.
  40. /// In particular, it instantiates IfaceMgr, loads or generates DUID
  41. /// that is going to be used as server-identifier, receives incoming
  42. /// packets, processes them, manages leases assignment and generates
  43. /// appropriate responses.
  44. ///
  45. /// This class does not support any controlling mechanisms directly.
  46. /// See the derived \ref ControlledDhcpv4Srv class for support for
  47. /// command and configuration updates over msgq.
  48. ///
  49. /// For detailed explanation or relations between main(), ControlledDhcpv4Srv,
  50. /// Dhcpv4Srv and other classes, see \ref dhcpv4Session.
  51. class Dhcpv4Srv : public boost::noncopyable {
  52. public:
  53. /// @brief defines if certain option may, must or must not appear
  54. typedef enum {
  55. FORBIDDEN,
  56. MANDATORY,
  57. OPTIONAL
  58. } RequirementLevel;
  59. /// @brief Default constructor.
  60. ///
  61. /// Instantiates necessary services, required to run DHCPv4 server.
  62. /// In particular, creates IfaceMgr that will be responsible for
  63. /// network interaction. Will instantiate lease manager, and load
  64. /// old or create new DUID. It is possible to specify alternate
  65. /// port on which DHCPv4 server will listen on. That is mostly useful
  66. /// for testing purposes. The Last two arguments of the constructor
  67. /// should be left at default values for normal server operation.
  68. /// They should be set to 'false' when creating an instance of this
  69. /// class for unit testing because features they enable require
  70. /// root privileges.
  71. ///
  72. /// @param port specifies port number to listen on
  73. /// @param dbconfig Lease manager configuration string. The default
  74. /// of the "memfile" manager is used for testing.
  75. /// @param use_bcast configure sockets to support broadcast messages.
  76. /// @param direct_response_desired specifies if it is desired to
  77. /// use direct V4 traffic.
  78. Dhcpv4Srv(uint16_t port = DHCP4_SERVER_PORT,
  79. const char* dbconfig = "type=memfile",
  80. const bool use_bcast = true,
  81. const bool direct_response_desired = true);
  82. /// @brief Destructor. Used during DHCPv4 service shutdown.
  83. virtual ~Dhcpv4Srv();
  84. /// @brief Main server processing loop.
  85. ///
  86. /// Main server processing loop. Receives incoming packets, verifies
  87. /// their correctness, generates appropriate answer (if needed) and
  88. /// transmits respones.
  89. ///
  90. /// @return true, if being shut down gracefully, fail if experienced
  91. /// critical error.
  92. bool run();
  93. /// @brief Instructs the server to shut down.
  94. void shutdown();
  95. /// @brief Return textual type of packet received by server
  96. ///
  97. /// Returns the name of valid packet received by the server (e.g. DISCOVER).
  98. /// If the packet is unknown - or if it is a valid DHCP packet but not one
  99. /// expected to be received by the server (such as an OFFER), the string
  100. /// "UNKNOWN" is returned. This method is used in debug messages.
  101. ///
  102. /// As the operation of the method does not depend on any server state, it
  103. /// is declared static.
  104. ///
  105. /// @todo: This should be named static Pkt4::getName()
  106. ///
  107. /// @param type DHCPv4 packet type
  108. ///
  109. /// @return Pointer to "const" string containing the packet name.
  110. /// Note that this string is statically allocated and MUST NOT
  111. /// be freed by the caller.
  112. static const char* serverReceivedPacketName(uint8_t type);
  113. ///
  114. /// @name Public accessors returning values required to (re)open sockets.
  115. ///
  116. /// These accessors must be public because sockets are reopened from the
  117. /// static configuration callback handler. This callback handler invokes
  118. /// @c ControlledDhcpv4Srv::openActiveSockets which requires parameters
  119. /// which has to be retrieved from the @c ControlledDhcpv4Srv object.
  120. /// They are retrieved using these public functions
  121. //@{
  122. ///
  123. /// @brief Get UDP port on which server should listen.
  124. ///
  125. /// Typically, server listens on UDP port number 67. Other ports are used
  126. /// for testing purposes only.
  127. ///
  128. /// @return UDP port on which server should listen.
  129. uint16_t getPort() const {
  130. return (port_);
  131. }
  132. /// @brief Return bool value indicating that broadcast flags should be set
  133. /// on sockets.
  134. ///
  135. /// @return A bool value indicating that broadcast should be used (if true).
  136. bool useBroadcast() const {
  137. return (use_bcast_);
  138. }
  139. //@}
  140. /// @brief Open sockets which are marked as active in @c CfgMgr.
  141. ///
  142. /// This function reopens sockets according to the current settings in the
  143. /// Configuration Manager. It holds the list of the interfaces which server
  144. /// should listen on. This function will open sockets on these interfaces
  145. /// only. This function is not exception safe.
  146. ///
  147. /// @param port UDP port on which server should listen.
  148. /// @param use_bcast should broadcast flags be set on the sockets.
  149. static void openActiveSockets(const uint16_t port, const bool use_bcast);
  150. protected:
  151. /// @brief Verifies if the server id belongs to our server.
  152. ///
  153. /// This function checks if the server identifier carried in the specified
  154. /// DHCPv4 message belongs to this server. If the server identifier option
  155. /// is absent or the value carried by this option is equal to one of the
  156. /// server identifiers used by the server, the true is returned. If the
  157. /// server identifier option is present, but it doesn't match any server
  158. /// identifier used by this server, the false value is returned.
  159. ///
  160. /// @param pkt DHCPv4 message which server identifier is to be checked.
  161. ///
  162. /// @return true, if the server identifier is absent or matches one of the
  163. /// server identifiers that the server is using; false otherwise.
  164. bool acceptServerId(const Pkt4Ptr& pkt) const;
  165. /// @brief verifies if specified packet meets RFC requirements
  166. ///
  167. /// Checks if mandatory option is really there, that forbidden option
  168. /// is not there, and that client-id or server-id appears only once.
  169. ///
  170. /// @param pkt packet to be checked
  171. /// @param serverid expectation regarding server-id option
  172. /// @throw RFCViolation if any issues are detected
  173. static void sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid);
  174. /// @brief Processes incoming DISCOVER and returns response.
  175. ///
  176. /// Processes received DISCOVER message and verifies that its sender
  177. /// should be served. In particular, a lease is selected and sent
  178. /// as an offer to a client if it should be served.
  179. ///
  180. /// @param discover DISCOVER message received from client
  181. ///
  182. /// @return OFFER message or NULL
  183. Pkt4Ptr processDiscover(Pkt4Ptr& discover);
  184. /// @brief Processes incoming REQUEST and returns REPLY response.
  185. ///
  186. /// Processes incoming REQUEST message and verifies that its sender
  187. /// should be served. In particular, verifies that requested lease
  188. /// is valid, not expired, not reserved, not used by other client and
  189. /// that requesting client is allowed to use it.
  190. ///
  191. /// Returns ACK message, NAK message, or NULL
  192. ///
  193. /// @param request a message received from client
  194. ///
  195. /// @return ACK or NAK message
  196. Pkt4Ptr processRequest(Pkt4Ptr& request);
  197. /// @brief Stub function that will handle incoming RELEASE messages.
  198. ///
  199. /// In DHCPv4, server does not respond to RELEASE messages, therefore
  200. /// this function does not return anything.
  201. ///
  202. /// @param release message received from client
  203. void processRelease(Pkt4Ptr& release);
  204. /// @brief Stub function that will handle incoming DHCPDECLINE messages.
  205. ///
  206. /// @param decline message received from client
  207. void processDecline(Pkt4Ptr& decline);
  208. /// @brief Stub function that will handle incoming INFORM messages.
  209. ///
  210. /// @param inform message received from client
  211. Pkt4Ptr processInform(Pkt4Ptr& inform);
  212. /// @brief Copies default parameters from client's to server's message
  213. ///
  214. /// Some fields are copied from client's message into server's response,
  215. /// e.g. client HW address, number of hops, transaction-id etc.
  216. ///
  217. /// @param question any message sent by client
  218. /// @param answer any message server is going to send as response
  219. void copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer);
  220. /// @brief Appends options requested by client.
  221. ///
  222. /// This method assigns options that were requested by client
  223. /// (sent in PRL) or are enforced by server.
  224. ///
  225. /// @param question DISCOVER or REQUEST message from a client.
  226. /// @param msg outgoing message (options will be added here)
  227. void appendRequestedOptions(const Pkt4Ptr& question, Pkt4Ptr& msg);
  228. /// @brief Appends requested vendor options as requested by client.
  229. ///
  230. /// This method is similar to \ref appendRequestedOptions(), but uses
  231. /// vendor options. The major difference is that vendor-options use
  232. /// its own option spaces (there may be more than one distinct set of vendor
  233. /// options, each with unique vendor-id). Vendor options are requested
  234. /// using separate options within their respective vendor-option spaces.
  235. ///
  236. /// @param question DISCOVER or REQUEST message from a client.
  237. /// @param answer outgoing message (options will be added here)
  238. void appendRequestedVendorOptions(const Pkt4Ptr& question, Pkt4Ptr& answer);
  239. /// @brief Assigns a lease and appends corresponding options
  240. ///
  241. /// This method chooses the most appropriate lease for reqesting
  242. /// client and assigning it. Options corresponding to the lease
  243. /// are added to specific message.
  244. ///
  245. /// @param question DISCOVER or REQUEST message from client
  246. /// @param answer OFFER or ACK/NAK message (lease options will be added here)
  247. void assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer);
  248. /// @brief Append basic options if they are not present.
  249. ///
  250. /// This function adds the following basic options if they
  251. /// are not yet added to the message:
  252. /// - Subnet Mask,
  253. /// - Router,
  254. /// - Name Server,
  255. /// - Domain Name.
  256. ///
  257. /// @param question DISCOVER or REQUEST message from a client.
  258. /// @param msg the message to add options to.
  259. void appendBasicOptions(const Pkt4Ptr& question, Pkt4Ptr& msg);
  260. /// @brief Processes Client FQDN and Hostname Options sent by a client.
  261. ///
  262. /// Client may send Client FQDN or Hostname option to communicate its name
  263. /// to the server. Server may use this name to perform DNS update for the
  264. /// lease being assigned to a client. If server takes responsibility for
  265. /// updating DNS for a client it may communicate it by sending the Client
  266. /// FQDN or Hostname %Option back to the client. Server select a different
  267. /// name than requested by a client to update DNS. In such case, the server
  268. /// stores this different name in its response.
  269. ///
  270. /// Client should not send both Client FQDN and Hostname options. However,
  271. /// if client sends both options, server should prefer Client FQDN option
  272. /// and ignore the Hostname option. If Client FQDN option is not present,
  273. /// the Hostname option is processed.
  274. ///
  275. /// The Client FQDN %Option is processed by this function as described in
  276. /// RFC4702.
  277. ///
  278. /// In response to a Hostname %Option sent by a client, the server may send
  279. /// Hostname option with the same or different hostname. If different
  280. /// hostname is sent, it is an indication to the client that server has
  281. /// overridden the client's preferred name and will rather use this
  282. /// different name to update DNS. However, since Hostname option doesn't
  283. /// carry an information whether DNS update will be carried by the server
  284. /// or not, the client is responsible for checking whether DNS update
  285. /// has been performed.
  286. ///
  287. /// After successful processing options stored in the first parameter,
  288. /// this function may add Client FQDN or Hostname option to the response
  289. /// message. In some cases, server may cease to add any options to the
  290. /// response, i.e. when server doesn't support DNS updates.
  291. ///
  292. /// This function does not throw. It simply logs the debug message if the
  293. /// processing of the FQDN or Hostname failed.
  294. ///
  295. /// @param query A DISCOVER or REQUEST message from a cient.
  296. /// @param [out] answer A response message to be sent to a client.
  297. void processClientName(const Pkt4Ptr& query, Pkt4Ptr& answer);
  298. private:
  299. /// @brief Process Client FQDN %Option sent by a client.
  300. ///
  301. /// This function is called by the @c Dhcpv4Srv::processClientName when
  302. /// the client has sent the FQDN option in its message to the server.
  303. /// It comprises the actual logic to parse the FQDN option and prepare
  304. /// the FQDN option to be sent back to the client in the server's
  305. /// response.
  306. ///
  307. /// @param fqdn An DHCPv4 Client FQDN %Option sent by a client.
  308. /// @param [out] answer A response message to be sent to a client.
  309. void processClientFqdnOption(const Option4ClientFqdnPtr& fqdn,
  310. Pkt4Ptr& answer);
  311. /// @brief Process Hostname %Option sent by a client.
  312. ///
  313. /// This function is called by the @c DHcpv4Srv::processClientName when
  314. /// the client has sent the Hostname option in its message to the server.
  315. /// It comprises the actual logic to parse the Hostname option and
  316. /// prepare the Hostname option to be sent back to the client in the
  317. /// server's response.
  318. ///
  319. /// @param opt_hostname An @c OptionCustom object encapsulating the Hostname
  320. /// %Option.
  321. /// @param [out] answer A response message to be sent to a client.
  322. void processHostnameOption(const OptionCustomPtr& opt_hostname,
  323. Pkt4Ptr& answer);
  324. protected:
  325. /// @brief Creates NameChangeRequests which correspond to the lease
  326. /// which has been acquired.
  327. ///
  328. /// If this function is called whe an existing lease is renewed, it
  329. /// may generate NameChangeRequest to remove existing DNS entries which
  330. /// correspond to the old lease instance. This function may cease to
  331. /// generate NameChangeRequests if the notion of the client's FQDN hasn't
  332. /// changed between an old and new lease.
  333. ///
  334. /// @param lease A pointer to the new lease which has been acquired.
  335. /// @param old_lease A pointer to the instance of the old lease which has
  336. /// been replaced by the new lease passed in the first argument. The NULL
  337. /// value indicates that the new lease has been allocated, rather than
  338. /// lease being renewed.
  339. void createNameChangeRequests(const Lease4Ptr& lease,
  340. const Lease4Ptr& old_lease);
  341. /// @brief Creates the NameChangeRequest and adds to the queue for
  342. /// processing.
  343. ///
  344. /// This function adds the @c isc::dhcp_ddns::NameChangeRequest to the
  345. /// queue and emits the debug message which indicates whether the request
  346. /// being added is to remove DNS entry or add a new entry. This function
  347. /// is exception free.
  348. ///
  349. /// @param chg_type A type of the NameChangeRequest (ADD or REMOVE).
  350. /// @param lease A lease for which the NameChangeRequest is created and
  351. /// queued.
  352. void queueNameChangeRequest(const isc::dhcp_ddns::NameChangeType chg_type,
  353. const Lease4Ptr& lease);
  354. /// @brief Sends all outstanding NameChangeRequests to b10-dhcp-ddns module.
  355. ///
  356. /// The purpose of this function is to pick all outstanding
  357. /// NameChangeRequests from the FIFO queue and send them to b10-dhcp-ddns
  358. /// module.
  359. ///
  360. /// @todo Currently this function simply removes all requests from the
  361. /// queue but doesn't send them anywhere. In the future, the
  362. /// NameChangeSender will be used to deliver requests to the other module.
  363. void sendNameChangeRequests();
  364. /// @brief Attempts to renew received addresses
  365. ///
  366. /// Attempts to renew existing lease. This typically includes finding a lease that
  367. /// corresponds to the received address. If no such lease is found, a status code
  368. /// response is generated.
  369. ///
  370. /// @param renew client's message asking for renew
  371. /// @param reply server's response (ACK or NAK)
  372. void renewLease(const Pkt4Ptr& renew, Pkt4Ptr& reply);
  373. /// @brief Appends default options to a message
  374. ///
  375. /// Currently it is only a Message Type option. This function does not add
  376. /// the Server Identifier option as this option must be added using
  377. /// @c Dhcpv4Srv::appendServerID.
  378. ///
  379. ///
  380. /// @param msg message object (options will be added to it)
  381. /// @param msg_type specifies message type
  382. void appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type);
  383. /// @brief Adds server identifier option to the server's response.
  384. ///
  385. /// This method adds a server identifier to the DHCPv4 message. It epxects
  386. /// that the local (source) address is set for this message. If address is
  387. /// not set, it will throw an exception. This method also expects that the
  388. /// server identifier option is not present in the specified message.
  389. /// Otherwise, it will throw an exception on attempt to add a duplicate
  390. /// server identifier option.
  391. ///
  392. /// @note This method doesn't throw exceptions by itself but the underlying
  393. /// classes being used my throw. The reason for this method to not sanity
  394. /// check the specified message is that it is meant to be called internally
  395. /// by the @c Dhcpv4Srv class.
  396. ///
  397. /// @note This method is static because it is not dependent on the class
  398. /// state.
  399. ///
  400. /// @param [out] response DHCPv4 message to which the server identifier
  401. /// option should be added.
  402. static void appendServerID(const Pkt4Ptr& response);
  403. /// @brief Set IP/UDP and interface parameters for the DHCPv4 response.
  404. ///
  405. /// This method sets the following parameters for the DHCPv4 message being
  406. /// sent to a client:
  407. /// - client unicast or a broadcast address,
  408. /// - client or relay port,
  409. /// - server address,
  410. /// - server port,
  411. /// - name and index of the interface which is to be used to send the
  412. /// message.
  413. ///
  414. /// Internally it calls the @c Dhcpv4Srv::adjustRemoteAddr to figure
  415. /// out the destination address (client unicast address or broadcast
  416. /// address).
  417. ///
  418. /// The destination port is always DHCPv4 client (68) or relay (67) port,
  419. /// depending if the response will be sent directly to a client.
  420. ///
  421. /// The source port is always set to DHCPv4 server port (67).
  422. ///
  423. /// The interface selected for the response is always the same as the
  424. /// one through which the query has been received.
  425. ///
  426. /// The source address for the response is the IPv4 address assigned to
  427. /// the interface being used to send the response. This function uses
  428. /// @c IfaceMgr to get the socket bound to the IPv4 address on the
  429. /// particular interface.
  430. ///
  431. /// @note This method is static because it is not dependent on the class
  432. /// state.
  433. static void adjustIfaceData(const Pkt4Ptr& query, const Pkt4Ptr& response);
  434. /// @brief Sets remote addresses for outgoing packet.
  435. ///
  436. /// This method sets the local and remote addresses on outgoing packet.
  437. /// The addresses being set depend on the following conditions:
  438. /// - has incoming packet been relayed,
  439. /// - is direct response to a client without address supported,
  440. /// - type of the outgoing packet,
  441. /// - broadcast flag set in the incoming packet.
  442. ///
  443. /// @warning This method does not check whether provided packet pointers
  444. /// are valid. Make sure that pointers are correct before calling this
  445. /// function.
  446. ///
  447. /// @note This method is static because it is not dependent on the class
  448. /// state.
  449. ///
  450. /// @param question instance of a packet received by a server.
  451. /// @param [out] response response packet which addresses are to be
  452. /// adjusted.
  453. static void adjustRemoteAddr(const Pkt4Ptr& question,
  454. const Pkt4Ptr& response);
  455. /// @brief converts server-id to text
  456. /// Converts content of server-id option to a text representation, e.g.
  457. /// "192.0.2.1"
  458. ///
  459. /// @param opt option that contains server-id
  460. /// @return string representation
  461. static std::string srvidToString(const OptionPtr& opt);
  462. /// @brief Computes DHCID from a lease.
  463. ///
  464. /// This method creates an object which represents DHCID. The DHCID value
  465. /// is computed as described in RFC4701. The section 3.3. of RFC4701
  466. /// specifies the DHCID RR Identifier Type codes:
  467. /// - 0x0000 The 1 octet htype followed by glen octets of chaddr
  468. /// - 0x0001 The data octets from the DHCPv4 client's Client Identifier
  469. /// option.
  470. /// - 0x0002 The client's DUID.
  471. ///
  472. /// Currently this function supports first two of these identifiers.
  473. /// The 0x0001 is preferred over the 0x0000 - if the client identifier
  474. /// option is present, the former is used. If the client identifier
  475. /// is absent, the latter is used.
  476. ///
  477. /// @todo Implement support for 0x0002 DHCID identifier type.
  478. ///
  479. /// @param lease A pointer to the structure describing a lease.
  480. /// @return An object encapsulating DHCID to be used for DNS updates.
  481. /// @throw DhcidComputeError If the computation of the DHCID failed.
  482. static isc::dhcp_ddns::D2Dhcid computeDhcid(const Lease4Ptr& lease);
  483. /// @brief Selects a subnet for a given client's packet.
  484. ///
  485. /// @param question client's message
  486. /// @return selected subnet (or NULL if no suitable subnet was found)
  487. isc::dhcp::Subnet4Ptr selectSubnet(const Pkt4Ptr& question);
  488. /// indicates if shutdown is in progress. Setting it to true will
  489. /// initiate server shutdown procedure.
  490. volatile bool shutdown_;
  491. /// @brief dummy wrapper around IfaceMgr::receive4
  492. ///
  493. /// This method is useful for testing purposes, where its replacement
  494. /// simulates reception of a packet. For that purpose it is protected.
  495. virtual Pkt4Ptr receivePacket(int timeout);
  496. /// @brief dummy wrapper around IfaceMgr::send()
  497. ///
  498. /// This method is useful for testing purposes, where its replacement
  499. /// simulates transmission of a packet. For that purpose it is protected.
  500. virtual void sendPacket(const Pkt4Ptr& pkt);
  501. /// @brief Implements a callback function to parse options in the message.
  502. ///
  503. /// @param buf a A buffer holding options in on-wire format.
  504. /// @param option_space A name of the option space which holds definitions
  505. /// of to be used to parse options in the packets.
  506. /// @param [out] options A reference to the collection where parsed options
  507. /// will be stored.
  508. /// @return An offset to the first byte after last parsed option.
  509. size_t unpackOptions(const OptionBuffer& buf,
  510. const std::string& option_space,
  511. isc::dhcp::OptionCollection& options);
  512. /// @brief Assigns incoming packet to zero or more classes.
  513. ///
  514. /// @note For now, the client classification is very simple. It just uses
  515. /// content of the vendor-class-identifier option as a class. The resulting
  516. /// class will be stored in packet (see @ref isc::dhcp::Pkt4::classes_ and
  517. /// @ref isc::dhcp::Pkt4::inClass).
  518. ///
  519. /// @param pkt packet to be classified
  520. void classifyPacket(const Pkt4Ptr& pkt);
  521. /// @brief Performs packet processing specific to a class
  522. ///
  523. /// This processing is a likely candidate to be pushed into hooks.
  524. ///
  525. /// @param query incoming client's packet
  526. /// @param rsp server's response
  527. /// @return true if successful, false otherwise (will prevent sending response)
  528. bool classSpecificProcessing(const Pkt4Ptr& query, const Pkt4Ptr& rsp);
  529. private:
  530. /// @brief Constructs netmask option based on subnet4
  531. /// @param subnet subnet for which the netmask will be calculated
  532. ///
  533. /// @return Option that contains netmask information
  534. static OptionPtr getNetmaskOption(const Subnet4Ptr& subnet);
  535. /// @brief Implements the error handler for socket open failure.
  536. ///
  537. /// This callback function is installed on the @c isc::dhcp::IfaceMgr
  538. /// when IPv4 sockets are being open. When socket fails to open for
  539. /// any reason, this function is called. It simply logs the error message.
  540. ///
  541. /// @param errmsg An error message containing a cause of the failure.
  542. static void ifaceMgrSocket4ErrorHandler(const std::string& errmsg);
  543. /// @brief Allocation Engine.
  544. /// Pointer to the allocation engine that we are currently using
  545. /// It must be a pointer, because we will support changing engines
  546. /// during normal operation (e.g. to use different allocators)
  547. boost::shared_ptr<AllocEngine> alloc_engine_;
  548. uint16_t port_; ///< UDP port number on which server listens.
  549. bool use_bcast_; ///< Should broadcast be enabled on sockets (if true).
  550. /// Indexes for registered hook points
  551. int hook_index_pkt4_receive_;
  552. int hook_index_subnet4_select_;
  553. int hook_index_pkt4_send_;
  554. protected:
  555. /// Holds a list of @c isc::dhcp_ddns::NameChangeRequest objects which
  556. /// are waiting for sending to b10-dhcp-ddns module.
  557. std::queue<isc::dhcp_ddns::NameChangeRequest> name_change_reqs_;
  558. };
  559. }; // namespace isc::dhcp
  560. }; // namespace isc
  561. #endif // DHCP4_SRV_H