namespace isc {
- namespace dhcp {
- /// @brief DHCPv6 server service.
- ///
- /// This singleton class represents DHCPv6 server. It contains all
- /// top-level methods and routines necessary for server operation.
- /// In particular, it instantiates IfaceMgr, loads or generates DUID
- /// that is going to be used as server-identifier, receives incoming
- /// packets, processes them, manages leases assignment and generates
- /// appropriate responses.
- class Dhcpv6Srv : public boost::noncopyable {
- private:
-
- /// @brief A private copy constructor.
- ///
- /// Creates a single Dhcpv6Srv instance and all required objects,
- /// including interface manager (IfaceMgr). It is defined private on
- /// purpose. We don't want to have more than one copy of Dhcpv6Srv.
- ///
- /// It may throw exceptions if server creation failed, e.g. due to
- /// failures in IfaceMgr (e.g. socket creation) or unavailable
- /// interfaces when attempting to create new DUID.
- Dhcpv6Srv(const Dhcpv6Srv& src);
-
- /// @brief A private assignment operator.
- ///
- /// Note that there is no implementation of this assignment operator.
- /// Its definition is here to prevent creation of any copies.
- ///
- Dhcpv6Srv& operator=(const Dhcpv6Srv& src);
-
- /// @brief Sets server-identifier.
- ///
- /// This method attempts to set server-identifier DUID. It loads it
- /// from a file. If file load fails, it generates new DUID using
- /// interface link-layer addresses (EUI-64) + timestamp (DUID type
- /// duid-llt, see RFC3315, section 9.2). If there are no suitable
- /// interfaces present, exception it thrown
- ///
- /// @throws isc::Unexpected Failed to read DUID file and no suitable
- /// interfaces for new DUID generation are detected.
- void setServerID();
-
- /// server DUID (to be sent in server-identifier option)
- boost::shared_ptr<isc::dhcp::Option> serverid_;
-
- public:
- /// @brief Default constructor.
- ///
- /// Instantiates necessary services, required to run DHCPv6 server.
- /// In particular, creates IfaceMgr that will be responsible for
- /// network interaction. Will instantiate lease manager, and load
- /// old or create new DUID.
- Dhcpv6Srv();
-
- /// @brief Destructor. Shuts down DHCPv6 service.
- ~Dhcpv6Srv();
-
- /// @brief Returns server-intentifier option
- ///
- /// @return reference to server-id option
- ///
- boost::shared_ptr<isc::dhcp::Option>&
- getServerID() { return serverid_; }
-
- /// @brief Main server processing loop.
- ///
- /// Main server processing loop. Receives incoming packets, verifies
- /// their correctness, generates appropriate answer (if needed) and
- /// transmits respones.
- ///
- /// @return true, if being shut down gracefully, fail if experienced
- /// critical error.
- bool run();
-
- protected:
- /// @brief Processes incoming SOLICIT and returns response.
- ///
- /// Processes received SOLICIT message and verifies that its sender
- /// should be served. In particular IA, TA and PD options are populated
- /// with to-be assinged addresses, temporary addresses and delegated
- /// prefixes, respectively. In the usual 4 message exchange, server is
- /// expected to respond with ADVERTISE message. However, if client
- /// requests rapid-commit and server supports it, REPLY will be sent
- /// instead of ADVERTISE and requested leases will be assigned
- /// immediately.
- ///
- /// @param solicit SOLICIT message received from client
- ///
- /// @return ADVERTISE, REPLY message or NULL
- ///
- boost::shared_ptr<Pkt6>
- processSolicit(boost::shared_ptr<Pkt6> solicit);
-
- /// @brief Processes incoming REQUEST and returns REPLY response.
- ///
- /// Processes incoming REQUEST message and verifies that its sender
- /// should be served. In particular IA, TA and PD options are populated
- /// with assinged addresses, temporary addresses and delegated
- /// prefixes, respectively. Uses LeaseMgr to allocate or update existing
- /// leases.
- ///
- /// @param request REQUEST message received from client
- ///
- /// @return REPLY message or NULL
- boost::shared_ptr<Pkt6>
- processRequest(boost::shared_ptr<Pkt6> request);
-
- /// @brief Stub function that will handle incoming RENEW messages.
- boost::shared_ptr<Pkt6>
- processRenew(boost::shared_ptr<Pkt6> renew);
-
- /// @brief Stub function that will handle incoming REBIND messages.
- boost::shared_ptr<Pkt6>
- processRebind(boost::shared_ptr<Pkt6> rebind);
-
- /// @brief Stub function that will handle incoming CONFIRM messages.
- boost::shared_ptr<Pkt6>
- processConfirm(boost::shared_ptr<Pkt6> confirm);
-
- /// @brief Stub function that will handle incoming RELEASE messages.
- boost::shared_ptr<Pkt6>
- processRelease(boost::shared_ptr<Pkt6> release);
-
- /// @brief Stub function that will handle incoming DECLINE messages.
- boost::shared_ptr<Pkt6>
- processDecline(boost::shared_ptr<Pkt6> decline);
-
- /// @brief Stub function that will handle incoming INF-REQUEST messages.
- boost::shared_ptr<Pkt6>
- processInfRequest(boost::shared_ptr<Pkt6> infRequest);
-
- /// indicates if shutdown is in progress. Setting it to true will
- /// initiate server shutdown procedure.
- volatile bool shutdown;
- };
-
- }; // namespace isc::dhcp
+namespace dhcp {
+/// @brief DHCPv6 server service.
+///
+/// This singleton class represents DHCPv6 server. It contains all
+/// top-level methods and routines necessary for server operation.
+/// In particular, it instantiates IfaceMgr, loads or generates DUID
+/// that is going to be used as server-identifier, receives incoming
+/// packets, processes them, manages leases assignment and generates
+/// appropriate responses.
+class Dhcpv6Srv : public boost::noncopyable {
+
+public:
+ /// @brief Default constructor.
+ ///
+ /// Instantiates necessary services, required to run DHCPv6 server.
+ /// In particular, creates IfaceMgr that will be responsible for
+ /// network interaction. Will instantiate lease manager, and load
+ /// old or create new DUID.
+ Dhcpv6Srv();
+
+ /// @brief Destructor. Used during DHCPv6 service shutdown.
+ ~Dhcpv6Srv();
+
+ /// @brief Returns server-intentifier option
+ ///
+ /// @return server-id option
+ boost::shared_ptr<isc::dhcp::Option>
+ getServerID() { return serverid_; }
+
+ /// @brief Main server processing loop.
+ ///
+ /// Main server processing loop. Receives incoming packets, verifies
+ /// their correctness, generates appropriate answer (if needed) and
+ /// transmits respones.
+ ///
+ /// @return true, if being shut down gracefully, fail if experienced
+ /// critical error.
+ bool run();
+
+protected:
+ /// @brief Processes incoming SOLICIT and returns response.
+ ///
+ /// Processes received SOLICIT message and verifies that its sender
+ /// should be served. In particular IA, TA and PD options are populated
+ /// with to-be assinged addresses, temporary addresses and delegated
+ /// prefixes, respectively. In the usual 4 message exchange, server is
+ /// expected to respond with ADVERTISE message. However, if client
+ /// requests rapid-commit and server supports it, REPLY will be sent
+ /// instead of ADVERTISE and requested leases will be assigned
+ /// immediately.
+ ///
+ /// @param solicit SOLICIT message received from client
+ ///
+ /// @return ADVERTISE, REPLY message or NULL
+ boost::shared_ptr<Pkt6>
+ processSolicit(boost::shared_ptr<Pkt6> solicit);
+
+ /// @brief Processes incoming REQUEST and returns REPLY response.
+ ///
+ /// Processes incoming REQUEST message and verifies that its sender
+ /// should be served. In particular IA, TA and PD options are populated
+ /// with assinged addresses, temporary addresses and delegated
+ /// prefixes, respectively. Uses LeaseMgr to allocate or update existing
+ /// leases.
+ ///
+ /// @param request a message received from client
+ ///
+ /// @return REPLY message or NULL
+ boost::shared_ptr<Pkt6>
+ processRequest(boost::shared_ptr<Pkt6> request);
+
+ /// @brief Stub function that will handle incoming RENEW messages.
+ ///
+ /// @param renew message received from client
+ boost::shared_ptr<Pkt6>
+ processRenew(boost::shared_ptr<Pkt6> renew);
+
+ /// @brief Stub function that will handle incoming REBIND messages.
+ ///
+ /// @param rebind message received from client
+ boost::shared_ptr<Pkt6>
+ processRebind(boost::shared_ptr<Pkt6> rebind);
+
+ /// @brief Stub function that will handle incoming CONFIRM messages.
+ ///
+ /// @param confirm message received from client
+ boost::shared_ptr<Pkt6>
+ processConfirm(boost::shared_ptr<Pkt6> confirm);
+
+ /// @brief Stub function that will handle incoming RELEASE messages.
+ ///
+ /// @param release message received from client
+ boost::shared_ptr<Pkt6>
+ processRelease(boost::shared_ptr<Pkt6> release);
+
+ /// @brief Stub function that will handle incoming DECLINE messages.
+ ///
+ /// @param decline message received from client
+ boost::shared_ptr<Pkt6>
+ processDecline(boost::shared_ptr<Pkt6> decline);
+
+ /// @brief Stub function that will handle incoming INF-REQUEST messages.
+ ///
+ /// @param infRequest message received from client
+ boost::shared_ptr<Pkt6>
+ processInfRequest(boost::shared_ptr<Pkt6> infRequest);
+
+ /// @brief Sets server-identifier.
+ ///
+ /// This method attempts to set server-identifier DUID. It loads it
+ /// from a file. If file load fails, it generates new DUID using
+ /// interface link-layer addresses (EUI-64) + timestamp (DUID type
+ /// duid-llt, see RFC3315, section 9.2). If there are no suitable
+ /// interfaces present, exception it thrown
+ ///
+ /// @throws isc::Unexpected Failed to read DUID file and no suitable
+ /// interfaces for new DUID generation are detected.
+ void setServerID();
+
+ /// server DUID (to be sent in server-identifier option)
+ boost::shared_ptr<isc::dhcp::Option> serverid_;
+
+ /// indicates if shutdown is in progress. Setting it to true will
+ /// initiate server shutdown procedure.
+ volatile bool shutdown;
+};
+
+}; // namespace isc::dhcp
}; // namespace isc
#endif // DHCP6_SRV_H
namespace isc {
- namespace dhcp {
- /// @brief handles network interfaces, transmission and reception
+namespace dhcp {
+/// @brief handles network interfaces, transmission and reception
+///
+/// IfaceMgr is an interface manager class that detects available network
+/// interfaces, configured addresses, link-local addresses, and provides
+/// API for using sockets.
+///
+class IfaceMgr : public boost::noncopyable {
+public:
+ /// type that defines list of addresses
+ typedef std::list<isc::asiolink::IOAddress> Addr6Lst;
+
+ /// maximum MAC address length (Infiniband uses 20 bytes)
+ static const unsigned int MAX_MAC_LEN = 20;
+
+ /// @brief represents a single network interface
///
- /// IfaceMgr is an interface manager class that detects available network
- /// interfaces, configured addresses, link-local addresses, and provides
- /// API for using sockets.
- ///
- class IfaceMgr : public boost::noncopyable {
- public:
- /// type that defines list of addresses
- typedef std::list<isc::asiolink::IOAddress> Addr6Lst;
+ /// Iface structure represents network interface with all useful
+ /// information, like name, interface index, MAC address and
+ /// list of assigned addresses
+ struct Iface {
+ /// constructor
+ Iface(const std::string& name, int ifindex);
+
+ /// returns full interface name in format ifname/ifindex
+ std::string getFullName() const;
+
+ /// returns link-layer address a plain text
+ std::string getPlainMac() const;
- /// maximum MAC address length (Infiniband uses 20 bytes)
- static const unsigned int MAX_MAC_LEN = 20;
+ /// network interface name
+ std::string name_;
+
+ /// interface index (a value that uniquely indentifies an interface)
+ int ifindex_;
- /// @brief represents a single network interface
- ///
- /// Iface structure represents network interface with all useful
- /// information, like name, interface index, MAC address and
/// list of assigned addresses
- struct Iface {
- /// constructor
- Iface(const std::string& name, int ifindex);
-
- /// returns full interface name in format ifname/ifindex
- std::string getFullName() const;
-
- /// returns link-layer address a plain text
- std::string getPlainMac() const;
-
- std::string name_; /// network interface name
- int ifindex_; /// interface index (a value that uniquely
- /// indentifies an interface
- Addr6Lst addrs_; /// list of assigned addresses
- uint8_t mac_[MAX_MAC_LEN]; /// link-layer address
- int mac_len_; /// length of link-layer address (usually 6)
-
- int sendsock_; /// socket used to sending data
- int recvsock_; /// socket used for receiving data
-
- // next field is not needed, let's keep it in cointainers
- };
-
- // TODO performance improvement: we may change this into
- // 2 maps (ifindex-indexed and name-indexed) and
- // also hide it (make it public make tests easier for now)
- typedef std::list<Iface> IfaceLst;
-
- /// IfaceMgr is a singleton class. This method returns reference
- /// to its sole instance.
- ///
- /// @return the only existing instance of interface manager
- static IfaceMgr& instance();
-
- /// @brief Returns interface with specified interface index
- ///
- /// @param ifindex index of searched interface
- ///
- /// @return interface with requested index (or NULL if no such
- /// interface is present)
- ///
- Iface*
- getIface(int ifindex);
-
- /// @brief Returns interface with specified interface name
- ///
- /// @param ifname name of searched interface
- ///
- /// @return interface with requested name (or NULL if no such
- /// interface is present)
- ///
- Iface*
- getIface(const std::string& ifname);
-
- /// debugging method that prints out all available interfaces
- ///
- /// @param out specifies stream to print list of interfaces to
- void
- printIfaces(std::ostream& out = std::cout);
-
- /// @brief Sends a packet.
- ///
- /// Sends a packet. All parameters regarding interface, destination
- /// address are set in pkt object.
- ///
- /// @param pkt packet to be sent
- ///
- /// @return true if sending was successful
- ///
- bool
- send(boost::shared_ptr<Pkt6> pkt);
-
- /// @brief Tries to receive packet over open sockets.
- ///
- /// Attempts to receive a single packet of any of the open sockets.
- /// If reception is successful and all information about its sender
- /// are obtained, Pkt6 object is created and returned.
- ///
- /// @return Pkt6 object representing received packet (or NULL)
- ///
- boost::shared_ptr<Pkt6> receive();
-
- // don't use private, we need derived classes in tests
- protected:
-
- /// @brief Protected constructor.
- ///
- /// Protected constructor. This is a singleton class. We don't want
- /// anyone to create instances of IfaceMgr. Use instance() method
- IfaceMgr();
-
- ~IfaceMgr();
-
- /// @brief Detects network interfaces.
- ///
- /// This method will eventually detect available interfaces. For now
- /// it offers stub implementation. First interface name and link-local
- /// IPv6 address is read from intefaces.txt file.
- void
- detectIfaces();
-
- ///
- /// Opens UDP/IPv6 socket and binds it to address, interface nad port.
- ///
- /// @param ifname name of the interface
- /// @param addr address to be bound.
- /// @param port UDP port.
- ///
- /// @return socket descriptor, if socket creation, binding and multicast
- /// group join were all successful. -1 otherwise.
- int openSocket(const std::string& ifname,
- const isc::asiolink::IOAddress& addr,
- int port);
-
- // TODO: having 2 maps (ifindex->iface and ifname->iface would)
- // probably be better for performance reasons
-
- /// List of available interfaces
- IfaceLst ifaces_;
-
- /// a pointer to a sole instance of this class (a singleton)
- static IfaceMgr * instance_;
-
- // TODO: Also keep this interface on Iface once interface detection
- // is implemented. We may need it e.g. to close all sockets on
- // specific interface
- int recvsock_; // TODO: should be fd_set eventually, but we have only
- int sendsock_; // 2 sockets for now. Will do for until next release
- // we can't use the same socket, as receiving socket
- // is bound to multicast address. And we all know what happens
- // to people who try to use multicast as source address.
-
- /// control-buffer, used in transmission and reception
- char * control_buf_;
- int control_buf_len_;
-
- private:
- /// Opens sockets on detected interfaces.
- bool
- openSockets();
-
- /// creates a single instance of this class (a singleton implementation)
- static void
- instanceCreate();
-
- /// @brief Joins IPv6 multicast group on a socket.
- ///
- /// Socket must be created and bound to an address. Note that this
- /// address is different than the multicast address. For example DHCPv6
- /// server should bind its socket to link-local address (fe80::1234...)
- /// and later join ff02::1:2 multicast group.
- ///
- /// @param sock socket fd (socket must be bound)
- /// @param ifname interface name (for link-scoped multicast groups)
- /// @param mcast multicast address to join (e.g. "ff02::1:2")
- ///
- /// @return true if multicast join was successful
- ///
- bool
- joinMcast(int sock, const std::string& ifname,
- const std::string& mcast);
+ Addr6Lst addrs_;
+
+ /// link-layer address
+ uint8_t mac_[MAX_MAC_LEN];
+
+ /// length of link-layer address (usually 6)
+ int mac_len_;
+
+ /// socket used to sending data
+ int sendsock_;
+
+ /// socket used for receiving data
+ int recvsock_;
};
- }; // namespace isc::dhcp
+ // TODO performance improvement: we may change this into
+ // 2 maps (ifindex-indexed and name-indexed) and
+ // also hide it (make it public make tests easier for now)
+
+ /// type that holds a list of interfaces
+ typedef std::list<Iface> IfaceLst;
+
+ /// IfaceMgr is a singleton class. This method returns reference
+ /// to its sole instance.
+ ///
+ /// @return the only existing instance of interface manager
+ static IfaceMgr& instance();
+
+ /// @brief Returns interface with specified interface index
+ ///
+ /// @param ifindex index of searched interface
+ ///
+ /// @return interface with requested index (or NULL if no such
+ /// interface is present)
+ ///
+ Iface*
+ getIface(int ifindex);
+
+ /// @brief Returns interface with specified interface name
+ ///
+ /// @param ifname name of searched interface
+ ///
+ /// @return interface with requested name (or NULL if no such
+ /// interface is present)
+ ///
+ Iface*
+ getIface(const std::string& ifname);
+
+ /// debugging method that prints out all available interfaces
+ ///
+ /// @param out specifies stream to print list of interfaces to
+ void
+ printIfaces(std::ostream& out = std::cout);
+
+ /// @brief Sends a packet.
+ ///
+ /// Sends a packet. All parameters regarding interface, destination
+ /// address are set in pkt object.
+ ///
+ /// @param pkt packet to be sent
+ ///
+ /// @return true if sending was successful
+ ///
+ bool
+ send(boost::shared_ptr<Pkt6> pkt);
+
+ /// @brief Tries to receive packet over open sockets.
+ ///
+ /// Attempts to receive a single packet of any of the open sockets.
+ /// If reception is successful and all information about its sender
+ /// are obtained, Pkt6 object is created and returned.
+ ///
+ /// @return Pkt6 object representing received packet (or NULL)
+ ///
+ boost::shared_ptr<Pkt6> receive();
+
+ // don't use private, we need derived classes in tests
+protected:
+
+ /// @brief Protected constructor.
+ ///
+ /// Protected constructor. This is a singleton class. We don't want
+ /// anyone to create instances of IfaceMgr. Use instance() method
+ IfaceMgr();
+
+ ~IfaceMgr();
+
+ /// @brief Detects network interfaces.
+ ///
+ /// This method will eventually detect available interfaces. For now
+ /// it offers stub implementation. First interface name and link-local
+ /// IPv6 address is read from intefaces.txt file.
+ void
+ detectIfaces();
+
+ ///
+ /// Opens UDP/IPv6 socket and binds it to address, interface and port.
+ ///
+ /// @param ifname name of the interface
+ /// @param addr address to be bound.
+ /// @param port UDP port.
+ ///
+ /// @return socket descriptor, if socket creation, binding and multicast
+ /// group join were all successful. -1 otherwise.
+ int openSocket(const std::string& ifname,
+ const isc::asiolink::IOAddress& addr,
+ int port);
+
+ // TODO: having 2 maps (ifindex->iface and ifname->iface would)
+ // probably be better for performance reasons
+
+ /// List of available interfaces
+ IfaceLst ifaces_;
+
+ /// a pointer to a sole instance of this class (a singleton)
+ static IfaceMgr * instance_;
+
+ // TODO: Also keep this interface on Iface once interface detection
+ // is implemented. We may need it e.g. to close all sockets on
+ // specific interface
+ int recvsock_; // TODO: should be fd_set eventually, but we have only
+ int sendsock_; // 2 sockets for now. Will do for until next release
+ // we can't use the same socket, as receiving socket
+ // is bound to multicast address. And we all know what happens
+ // to people who try to use multicast as source address.
+
+ /// control-buffer, used in transmission and reception
+ char * control_buf_;
+ int control_buf_len_;
+
+private:
+ /// Opens sockets on detected interfaces.
+ bool
+ openSockets();
+
+ /// creates a single instance of this class (a singleton implementation)
+ static void
+ instanceCreate();
+
+ /// @brief Joins IPv6 multicast group on a socket.
+ ///
+ /// Socket must be created and bound to an address. Note that this
+ /// address is different than the multicast address. For example DHCPv6
+ /// server should bind its socket to link-local address (fe80::1234...)
+ /// and later join ff02::1:2 multicast group.
+ ///
+ /// @param sock socket fd (socket must be bound)
+ /// @param ifname interface name (for link-scoped multicast groups)
+ /// @param mcast multicast address to join (e.g. "ff02::1:2")
+ ///
+ /// @return true if multicast join was successful
+ ///
+ bool
+ joinMcast(int sock, const std::string& ifname,
+ const std::string& mcast);
+};
+
+}; // namespace isc::dhcp
}; // namespace isc
#endif