Browse Source

[2414] Changes after review.

Tomek Mrugalski 12 years ago
parent
commit
cad4fb56e8
3 changed files with 122 additions and 47 deletions
  1. 31 15
      src/bin/dhcp6/dhcp6_messages.mes
  2. 82 24
      src/bin/dhcp6/dhcp6_srv.cc
  3. 9 8
      src/bin/dhcp6/dhcp6_srv.h

+ 31 - 15
src/bin/dhcp6/dhcp6_messages.mes

@@ -32,8 +32,8 @@ updated configuration from the BIND 10 configuration system.
 
 
 % DHCP6_DB_BACKEND_STARTED Lease database started (backend type: %1)
 % DHCP6_DB_BACKEND_STARTED Lease database started (backend type: %1)
 This informational message is printed every time DHCPv6 is started.
 This informational message is printed every time DHCPv6 is started.
-It indicates which backend type will be used throughout the server
-operation.
+It indicates what database backend type is being to store lease and
+other information.
 
 
 % DHCP6_NOT_RUNNING IPv6 DHCP server is not running
 % DHCP6_NOT_RUNNING IPv6 DHCP server is not running
 A warning message is issued when an attempt is made to shut down the
 A warning message is issued when an attempt is made to shut down the
@@ -47,16 +47,26 @@ interfaces and is therefore shutting down.
 A debug message issued during startup, this indicates that the IPv6 DHCP
 A debug message issued during startup, this indicates that the IPv6 DHCP
 server is about to open sockets on the specified port.
 server is about to open sockets on the specified port.
 
 
-% DHCP6_LEASE_ALLOC Lease %1 %2 allocated (client duid=%3, iaid=%4)
-This debug message indicates that the server successfully advertised (i.e.
-responded to SOLICIT) or granted (i.e. responded to REQUEST) a lease.
-This is a normal behavior and incicates successful operation.
+% DHCP6_LEASE_ADVERT Lease %1 advertised (client duid=%2, iaid=%3)
+This debug message indicates that the server successfully advertised
+a lease. It is up to the client to choose one server out of othe advertised
+and continue allocation with that server. This is a normal behavior and
+incicates successful operation.
 
 
-% DHCP6_LEASE_ALLOC_FAIL Failed to %1 a lease for client duid=%2, iaid=%3
-This message indicates that the server failed to advertise (i.e. respond
-to SOLICIT) or grant (i.e. respond to REQUEST) a lease for a given client.
-There may be many reasons for such failure. Each specific failure is logged
-in a separate log entry.
+% DHCP6_LEASE_ALLOC lease %1 has been allocated (client duid=%2, iaid=%3)
+This debug message indicates that the server successfully granted (in
+response to client's REQUEST message) a lease. This is a normal behavior
+and incicates successful operation.
+
+% DHCP6_LEASE_ADVERT_FAIL failed to advertise a lease for client duid=%1, iaid=%2
+This message indicates that the server failed to advertise (in response to
+received SOLICIT) a lease for a given client. There may be many reasons for
+such failure. Each specific failure is logged in a separate log entry.
+
+% DHCP6_LEASE_ALLOC_FAIL failed to grant a lease for client duid=%1, iaid=%2
+This message indicates that the server failed to grant (in response to
+received REQUEST) a lease for a given client. There may be many reasons for
+such failure. Each specific failure is logged in a separate log entry.
 
 
 % DHCP6_PACKET_PARSE_FAIL failed to parse incoming packet
 % DHCP6_PACKET_PARSE_FAIL failed to parse incoming packet
 The IPv6 DHCP server has received a packet that it is unable to interpret.
 The IPv6 DHCP server has received a packet that it is unable to interpret.
@@ -82,7 +92,7 @@ This error is output if the server failed to assemble the data to be
 returned to the client into a valid packet.  The reason is most likely
 returned to the client into a valid packet.  The reason is most likely
 to be to a programming error: please raise a bug report.
 to be to a programming error: please raise a bug report.
 
 
-% DHCP6_PROCESS_IA_NA_REQUEST Server is processing IA_NA option (duid=%1, iaid=%2, hint=%3)
+% DHCP6_PROCESS_IA_NA_REQUEST server is processing IA_NA option (duid=%1, iaid=%2, hint=%3)
 This is a debug message that indicates a processing of received IA_NA
 This is a debug message that indicates a processing of received IA_NA
 option. It may optionally contain an address that may be used by the server
 option. It may optionally contain an address that may be used by the server
 as a hint for possible requested address.
 as a hint for possible requested address.
@@ -131,12 +141,18 @@ This is a debug message issued during the IPv6 DHCP server startup.
 It lists some information about the parameters with which the server
 It lists some information about the parameters with which the server
 is running.
 is running.
 
 
-% DHCP6_SUBNET_SELECTED The %1 subnet was selected for client assignment
+% DHCP6_SUBNET_SELECTED the %1 subnet was selected for client assignment
 This is a debug message informing that a given subnet was selected. It will
 This is a debug message informing that a given subnet was selected. It will
 be used for address and option assignment. This is one of the early steps
 be used for address and option assignment. This is one of the early steps
 in the processing of incoming client message.
 in the processing of incoming client message.
 
 
-% DHCP6_SUBNET_SELECTION_FAILED Failed to select a subnet for incoming packet, src=%1 type=%2
+% DHCP6_SUBNET_SELECTION_FAILED failed to select a subnet for incoming packet, src=%1 type=%2
+This warning message is output when a packet was received from a subnet for
+which the DHCPv6 server has not been configured. The cause is most likely due
+to a misconfiguration of the server. The packet processing will continue, but
+the response will only contain generic configuration parameters and no
+addresses or prefixes.
+
 This is a warning message that a packet was received, but the server is
 This is a warning message that a packet was received, but the server is
 not configured to support the subnet the packet originated from. This
 not configured to support the subnet the packet originated from. This
 message means that the received traffic does not match server configuration
 message means that the received traffic does not match server configuration
@@ -152,7 +168,7 @@ This is a debug message that is issued every time the server receives a
 configuration. That happens start up and also when a server configuration
 configuration. That happens start up and also when a server configuration
 change is committed by the administrator.
 change is committed by the administrator.
 
 
-% DHCP6_CONFIG_NEW_SUBNET A new subnet has been added to configuration: %1
+% DHCP6_CONFIG_NEW_SUBNET a new subnet has been added to configuration: %1
 This is an informational message reporting that the configuration has
 This is an informational message reporting that the configuration has
 been extended to include the specified subnet.
 been extended to include the specified subnet.
 
 

+ 82 - 24
src/bin/dhcp6/dhcp6_srv.cc

@@ -52,10 +52,11 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port) {
     // it may throw something if things go wrong
     // it may throw something if things go wrong
     try {
     try {
 
 
-        // used for testing purposes. Some tests, e.g. configuration parser,
+        // Port 0 is used for testing purposes. It means that the server should
+        // not open any sockets at all. Some tests, e.g. configuration parser,
         // require Dhcpv6Srv object, but they don't really need it to do
         // require Dhcpv6Srv object, but they don't really need it to do
         // anything. This speed up and simplifies the tests.
         // anything. This speed up and simplifies the tests.
-        if (port) {
+        if (port > 0) {
             if (IfaceMgr::instance().countIfaces() == 0) {
             if (IfaceMgr::instance().countIfaces() == 0) {
                 LOG_ERROR(dhcp6_logger, DHCP6_NO_INTERFACES);
                 LOG_ERROR(dhcp6_logger, DHCP6_NO_INTERFACES);
                 shutdown_ = true;
                 shutdown_ = true;
@@ -67,8 +68,6 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port) {
 
 
         setServerID();
         setServerID();
 
 
-        /// @todo: instantiate LeaseMgr here once it is imlpemented.
-
     } catch (const std::exception &e) {
     } catch (const std::exception &e) {
         LOG_ERROR(dhcp6_logger, DHCP6_SRV_CONSTRUCT_ERROR).arg(e.what());
         LOG_ERROR(dhcp6_logger, DHCP6_SRV_CONSTRUCT_ERROR).arg(e.what());
         shutdown_ = true;
         shutdown_ = true;
@@ -101,7 +100,12 @@ void Dhcpv6Srv::shutdown() {
 
 
 bool Dhcpv6Srv::run() {
 bool Dhcpv6Srv::run() {
     while (!shutdown_) {
     while (!shutdown_) {
-        /// @todo: calculate actual timeout once we have lease database
+        /// @todo: calculate actual timeout to the next event (e.g. lease
+        /// expiration) once we have lease database. The idea here is that
+        /// it is possible to do everything in a single process/thread.
+        /// For now, we are just calling select for 1000 seconds. There
+        /// were some issues reported on some systems when calling select()
+        /// with too large values. Unfortunately, I don't recall the details.
         int timeout = 1000;
         int timeout = 1000;
 
 
         // client's message and server's response
         // client's message and server's response
@@ -209,7 +213,7 @@ void Dhcpv6Srv::setServerID() {
 
 
     const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
     const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
 
 
-    // let's find suitable interface
+    // Let's find suitable interface.
     for (IfaceMgr::IfaceCollection::const_iterator iface = ifaces.begin();
     for (IfaceMgr::IfaceCollection::const_iterator iface = ifaces.begin();
          iface != ifaces.end(); ++iface) {
          iface != ifaces.end(); ++iface) {
         // All the following checks could be merged into one multi-condition
         // All the following checks could be merged into one multi-condition
@@ -230,17 +234,17 @@ void Dhcpv6Srv::setServerID() {
             continue;
             continue;
         }
         }
 
 
-        // let's don't use loopback
+        // Let's don't use loopback.
         if (iface->flag_loopback_) {
         if (iface->flag_loopback_) {
             continue;
             continue;
         }
         }
 
 
-        // let's skip downed interfaces. It is better to use working ones.
+        // Let's skip downed interfaces. It is better to use working ones.
         if (!iface->flag_up_) {
         if (!iface->flag_up_) {
             continue;
             continue;
         }
         }
 
 
-        // some interfaces (like lo on Linux) report 6-bytes long
+        // Some interfaces (like lo on Linux) report 6-bytes long
         // MAC adress 00:00:00:00:00:00. Let's not use such weird interfaces
         // MAC adress 00:00:00:00:00:00. Let's not use such weird interfaces
         // to generate DUID.
         // to generate DUID.
         if (isRangeZero(iface->getMac(), iface->getMac() + iface->getMacLen())) {
         if (isRangeZero(iface->getMac(), iface->getMac() + iface->getMacLen())) {
@@ -259,14 +263,14 @@ void Dhcpv6Srv::setServerID() {
         writeUint16(DUID::DUID_LLT, &srvid[0]);
         writeUint16(DUID::DUID_LLT, &srvid[0]);
         writeUint16(HWTYPE_ETHERNET, &srvid[2]);
         writeUint16(HWTYPE_ETHERNET, &srvid[2]);
         writeUint32(static_cast<uint32_t>(seconds), &srvid[4]);
         writeUint32(static_cast<uint32_t>(seconds), &srvid[4]);
-        memcpy(&srvid[0]+8, iface->getMac(), iface->getMacLen());
+        memcpy(&srvid[0] + 8, iface->getMac(), iface->getMacLen());
 
 
         serverid_ = OptionPtr(new Option(Option::V6, D6O_SERVERID,
         serverid_ = OptionPtr(new Option(Option::V6, D6O_SERVERID,
                                          srvid.begin(), srvid.end()));
                                          srvid.begin(), srvid.end()));
         return;
         return;
     }
     }
 
 
-    // if we reached here, there are no suitable interfaces found.
+    // If we reached here, there are no suitable interfaces found.
     // Either interface detection is not supported on this platform or
     // Either interface detection is not supported on this platform or
     // this is really weird box. Let's use DUID-EN instead.
     // this is really weird box. Let's use DUID-EN instead.
     // See Section 9.3 of RFC3315 for details.
     // See Section 9.3 of RFC3315 for details.
@@ -278,15 +282,15 @@ void Dhcpv6Srv::setServerID() {
     // Length of the identifier is company specific. I hereby declare
     // Length of the identifier is company specific. I hereby declare
     // ISC "standard" of 6 bytes long pseudo-random numbers.
     // ISC "standard" of 6 bytes long pseudo-random numbers.
     srandom(time(NULL));
     srandom(time(NULL));
-    fillRandom(&srvid[6],&srvid[12]);
+    fillRandom(&srvid[6], &srvid[12]);
 
 
     serverid_ = OptionPtr(new Option(Option::V6, D6O_SERVERID,
     serverid_ = OptionPtr(new Option(Option::V6, D6O_SERVERID,
                                      srvid.begin(), srvid.end()));
                                      srvid.begin(), srvid.end()));
 }
 }
 
 
 void Dhcpv6Srv::copyDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
 void Dhcpv6Srv::copyDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
-    // add client-id
-    boost::shared_ptr<Option> clientid = question->getOption(D6O_CLIENTID);
+    // Add client-id.
+    OptionPtr clientid = question->getOption(D6O_CLIENTID);
     if (clientid) {
     if (clientid) {
         answer->addOption(clientid);
         answer->addOption(clientid);
     }
     }
@@ -298,7 +302,7 @@ void Dhcpv6Srv::appendDefaultOptions(const Pkt6Ptr& /*question*/, Pkt6Ptr& answe
     // TODO: question is currently unused, but we need it at least to know
     // TODO: question is currently unused, but we need it at least to know
     // message type we are answering
     // message type we are answering
 
 
-    // add server-id
+    // Add server-id.
     answer->addOption(getServerID());
     answer->addOption(getServerID());
 }
 }
 
 
@@ -307,9 +311,9 @@ void Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& /*question*/, Pkt6Ptr& ans
     // TODO: question is currently unused, but we need to extract ORO from it
     // TODO: question is currently unused, but we need to extract ORO from it
     // and act on its content. Now we just send DNS-SERVERS option.
     // and act on its content. Now we just send DNS-SERVERS option.
 
 
-    // add dns-servers option
-    boost::shared_ptr<Option> dnsservers(new Option6AddrLst(D6O_NAME_SERVERS,
-                                         IOAddress(HARDCODED_DNS_SERVER)));
+    // Add dns-servers option.
+    OptionPtr dnsservers(new Option6AddrLst(D6O_NAME_SERVERS,
+                                            IOAddress(HARDCODED_DNS_SERVER)));
     answer->addOption(dnsservers);
     answer->addOption(dnsservers);
 }
 }
 
 
@@ -331,8 +335,19 @@ Subnet6Ptr Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
 
 
 void Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
 void Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
 
 
+    // We need to allocate addresses for all IA_NA options in the client's
+    // question (i.e. SOLICIT or REQUEST) message.
+
+    // We need to select a subnet the client is connected in.
     Subnet6Ptr subnet = selectSubnet(question);
     Subnet6Ptr subnet = selectSubnet(question);
     if (subnet) {
     if (subnet) {
+        // This particular client is out of luck today. We do not have
+        // information about the subnet he is connected to. This likely means
+        // misconfiguration of the server (or some relays). We will continue to
+        // process this message, but our response will be almost useless: no
+        // addresses or prefixes, no subnet specific configuration etc. The only
+        // thing this client can get is some global information (like DNS
+        // servers).
         LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_SUBNET_SELECTED)
         LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_SUBNET_SELECTED)
             .arg(subnet->toText());
             .arg(subnet->toText());
     } else {
     } else {
@@ -343,12 +358,23 @@ void Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
 
 
     // @todo: We should implement Option6Duid some day, but we can do without it
     // @todo: We should implement Option6Duid some day, but we can do without it
     // just fine for now
     // just fine for now
+
+    // Let's find client's DUID. Client is supposed to include its client-id
+    // option almost all the time (the only exception is an anonymous inf-request,
+    // but that is mostly a theoretical case). Our allocation engine needs DUID
+    // and will refuse to allocate anything to anonymous clients.
     DuidPtr duid;
     DuidPtr duid;
     OptionPtr opt_duid = question->getOption(D6O_CLIENTID);
     OptionPtr opt_duid = question->getOption(D6O_CLIENTID);
     if (opt_duid) {
     if (opt_duid) {
         duid = DuidPtr(new DUID(opt_duid->getData()));
         duid = DuidPtr(new DUID(opt_duid->getData()));
     }
     }
 
 
+    // Now that we have all information about the client, let's iterate over all
+    // received options and handle IA_NA options one by one and store our
+    // responses in answer message (ADVERTISE or REPLY).
+    //
+    // @todo: expand this to cover IA_PD and IA_TA once we implement support for
+    // prefix delegation and temporary addresses.
     for (Option::OptionCollection::iterator opt = question->options_.begin();
     for (Option::OptionCollection::iterator opt = question->options_.begin();
          opt != question->options_.end(); ++opt) {
          opt != question->options_.end(); ++opt) {
         switch (opt->second->getType()) {
         switch (opt->second->getType()) {
@@ -368,14 +394,24 @@ void Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
 
 
 OptionPtr Dhcpv6Srv::handleIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid, Pkt6Ptr question,
 OptionPtr Dhcpv6Srv::handleIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid, Pkt6Ptr question,
                                  boost::shared_ptr<Option6IA> ia) {
                                  boost::shared_ptr<Option6IA> ia) {
+    // If there is no subnet selected for handling this IA_NA, the only thing to do left is
+    // to say that we are sorry, but the user won't get an address. As a convenience, we
+    // use a different status text to indicate that (compare to the same status code,
+    // but different wording below)
     if (!subnet) {
     if (!subnet) {
+        // Create empty IA_NA option with IAID matching the request.
         boost::shared_ptr<Option6IA> ia_rsp(new Option6IA(D6O_IA_NA, ia->getIAID()));
         boost::shared_ptr<Option6IA> ia_rsp(new Option6IA(D6O_IA_NA, ia->getIAID()));
 
 
+        // Insert status code NoAddrsAvail.
         ia_rsp->addOption(createStatusCode(STATUS_NoAddrsAvail, "Sorry, no subnet available."));
         ia_rsp->addOption(createStatusCode(STATUS_NoAddrsAvail, "Sorry, no subnet available."));
         return (ia_rsp);
         return (ia_rsp);
     }
     }
 
 
-    shared_ptr<Option6IAAddr> hintOpt = dynamic_pointer_cast<Option6IAAddr>(ia->getOption(D6O_IAADDR));
+    // Check if the client sent us a hint in his IA_NA. Clients may send an
+    // address in their IA_NA options as a suggestion (e.g. the last address
+    // they used before).
+    shared_ptr<Option6IAAddr> hintOpt = dynamic_pointer_cast<Option6IAAddr>
+                                        (ia->getOption(D6O_IAADDR));
     IOAddress hint("::");
     IOAddress hint("::");
     if (hintOpt) {
     if (hintOpt) {
         hint = hintOpt->getAddress();
         hint = hintOpt->getAddress();
@@ -385,21 +421,34 @@ OptionPtr Dhcpv6Srv::handleIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
         .arg(duid?duid->toText():"(no-duid)").arg(ia->getIAID())
         .arg(duid?duid->toText():"(no-duid)").arg(ia->getIAID())
         .arg(hintOpt?hint.toText():"(no hint)");
         .arg(hintOpt?hint.toText():"(no hint)");
 
 
+    // "Fake" allocation is processing of SOLICIT message. We pretend to do an
+    // allocation, but we do not put the lease in the database. That is ok,
+    // because we do not guarantee that the user will get that exact lease. If
+    // the user selects this server to do actual allocation (i.e. sends REQUEST)
+    // it should include this hint. That will help us during the actual lease
+    // allocation.
     bool fake_allocation = false;
     bool fake_allocation = false;
     if (question->getType() == DHCPV6_SOLICIT) {
     if (question->getType() == DHCPV6_SOLICIT) {
         /// @todo: Check if we support rapid commit
         /// @todo: Check if we support rapid commit
         fake_allocation = true;
         fake_allocation = true;
     }
     }
 
 
+    // Use allocation engine to pick a lease for this client. Allocation engine
+    // will try to honour the hint, but it is just a hint - some other address
+    // may be used instead. If fake_allocation is set to false, the lease will
+    // be inserted into the LeaseMgr as well.
     Lease6Ptr lease = alloc_engine_->allocateAddress6(subnet, duid, ia->getIAID(),
     Lease6Ptr lease = alloc_engine_->allocateAddress6(subnet, duid, ia->getIAID(),
                                                       hint, fake_allocation);
                                                       hint, fake_allocation);
 
 
+    // Create IA_NA that we will put in the response.
     boost::shared_ptr<Option6IA> ia_rsp(new Option6IA(D6O_IA_NA, ia->getIAID()));
     boost::shared_ptr<Option6IA> ia_rsp(new Option6IA(D6O_IA_NA, ia->getIAID()));
 
 
     if (lease) {
     if (lease) {
-        LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_LEASE_ALLOC)
+        // We have a lease! Let's wrap its content into IA_NA option
+        // with IAADDR suboption.
+        LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, fake_allocation?
+                  DHCP6_LEASE_ADVERT:DHCP6_LEASE_ALLOC)
             .arg(lease->addr_.toText())
             .arg(lease->addr_.toText())
-            .arg(fake_allocation?"would be":"has been")
             .arg(duid?duid->toText():"(no-duid)")
             .arg(duid?duid->toText():"(no-duid)")
             .arg(ia->getIAID());
             .arg(ia->getIAID());
 
 
@@ -412,14 +461,23 @@ OptionPtr Dhcpv6Srv::handleIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
                                    lease->preferred_lft_,
                                    lease->preferred_lft_,
                                    lease->valid_lft_));
                                    lease->valid_lft_));
         ia_rsp->addOption(addr);
         ia_rsp->addOption(addr);
+
+        // It would be possible to insert status code=0(success) as well,
+        // but this is considered waste of bandwidth as absence of status
+        // code is considered a success.
     } else {
     } else {
-        LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_LEASE_ALLOC_FAIL)
-            .arg(fake_allocation?"advertise":"grant")
+        // Allocation engine did not allocate a lease. The engine logged
+        // cause of that failure. The only thing left is to insert
+        // status code to pass the sad news to the client.
+
+        LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, fake_allocation?
+                  DHCP6_LEASE_ADVERT_FAIL:DHCP6_LEASE_ALLOC_FAIL)
             .arg(duid?duid->toText():"(no-duid)")
             .arg(duid?duid->toText():"(no-duid)")
             .arg(ia->getIAID())
             .arg(ia->getIAID())
             .arg(subnet->toText());
             .arg(subnet->toText());
 
 
-        ia_rsp->addOption(createStatusCode(STATUS_NoAddrsAvail, "Sorry, no address could be allocated."));
+        ia_rsp->addOption(createStatusCode(STATUS_NoAddrsAvail,
+                          "Sorry, no address could be allocated."));
     }
     }
     return (ia_rsp);
     return (ia_rsp);
 }
 }

+ 9 - 8
src/bin/dhcp6/dhcp6_srv.h

@@ -56,7 +56,7 @@ public:
     /// @brief Destructor. Used during DHCPv6 service shutdown.
     /// @brief Destructor. Used during DHCPv6 service shutdown.
     virtual ~Dhcpv6Srv();
     virtual ~Dhcpv6Srv();
 
 
-    /// @brief Returns server-intentifier option
+    /// @brief Returns server-intentifier option.
     ///
     ///
     /// @return server-id option
     /// @return server-id option
     OptionPtr getServerID() { return serverid_; }
     OptionPtr getServerID() { return serverid_; }
@@ -74,7 +74,7 @@ public:
     /// @brief Instructs the server to shut down.
     /// @brief Instructs the server to shut down.
     void shutdown();
     void shutdown();
 
 
-    /// @brief Return textual type of packet received by server
+    /// @brief Return textual type of packet received by server.
     ///
     ///
     /// Returns the name of valid packet received by the server (e.g. SOLICIT).
     /// Returns the name of valid packet received by the server (e.g. SOLICIT).
     /// If the packet is unknown - or if it is a valid DHCP packet but not one
     /// If the packet is unknown - or if it is a valid DHCP packet but not one
@@ -151,19 +151,20 @@ protected:
     /// @param infRequest message received from client
     /// @param infRequest message received from client
     Pkt6Ptr processInfRequest(const Pkt6Ptr& infRequest);
     Pkt6Ptr processInfRequest(const Pkt6Ptr& infRequest);
 
 
-    /// @brief creates status-code option
+    /// @brief Creates status-code option.
     ///
     ///
     /// @param code status code value (see RFC3315)
     /// @param code status code value (see RFC3315)
     /// @param text textual explanation (will be sent in status code option)
     /// @param text textual explanation (will be sent in status code option)
     /// @return status-code option
     /// @return status-code option
     OptionPtr createStatusCode(uint16_t code, const std::string& text);
     OptionPtr createStatusCode(uint16_t code, const std::string& text);
 
 
-    /// @brief selects a subnet for a given client's packet
+    /// @brief Selects a subnet for a given client's packet.
     ///
     ///
+    /// @param question client's message
     /// @return selected subnet (or NULL if no suitable subnet was found)
     /// @return selected subnet (or NULL if no suitable subnet was found)
     isc::dhcp::Subnet6Ptr selectSubnet(const Pkt6Ptr& question);
     isc::dhcp::Subnet6Ptr selectSubnet(const Pkt6Ptr& question);
 
 
-    /// @brief processes IA_NA option (and assigns addresses if necessary)
+    /// @brief Processes IA_NA option (and assigns addresses if necessary).
     ///
     ///
     /// Generates response to IA_NA. This typically includes selecting (and
     /// Generates response to IA_NA. This typically includes selecting (and
     /// allocating a lease in case of REQUEST) a lease and creating
     /// allocating a lease in case of REQUEST) a lease and creating
@@ -181,7 +182,7 @@ protected:
                           isc::dhcp::Pkt6Ptr question,
                           isc::dhcp::Pkt6Ptr question,
                           boost::shared_ptr<Option6IA> ia);
                           boost::shared_ptr<Option6IA> ia);
 
 
-    /// @brief Copies required options from client message to server answer
+    /// @brief Copies required options from client message to server answer.
     ///
     ///
     /// Copies options that must appear in any server response (ADVERTISE, REPLY)
     /// Copies options that must appear in any server response (ADVERTISE, REPLY)
     /// to client's messages (SOLICIT, REQUEST, RENEW, REBIND, DECLINE, RELEASE).
     /// to client's messages (SOLICIT, REQUEST, RENEW, REBIND, DECLINE, RELEASE).
@@ -236,13 +237,13 @@ protected:
     /// server DUID (to be sent in server-identifier option)
     /// server DUID (to be sent in server-identifier option)
     boost::shared_ptr<isc::dhcp::Option> serverid_;
     boost::shared_ptr<isc::dhcp::Option> serverid_;
 
 
-    /// @brief Allocation Engine
+    /// @brief Allocation Engine.
     /// Pointer to the allocation engine that we are currently using
     /// Pointer to the allocation engine that we are currently using
     /// It must be a pointer, because we will support changing engines
     /// It must be a pointer, because we will support changing engines
     /// during normal operation (e.g. to use different allocators)
     /// during normal operation (e.g. to use different allocators)
     AllocEngine* alloc_engine_;
     AllocEngine* alloc_engine_;
 
 
-    /// indicates if shutdown is in progress. Setting it to true will
+    /// Indicates if shutdown is in progress. Setting it to true will
     /// initiate server shutdown procedure.
     /// initiate server shutdown procedure.
     volatile bool shutdown_;
     volatile bool shutdown_;
 };
 };