Browse Source

[3768] Implemented the test which checks overlapping client ids.

Marcin Siodelski 10 years ago
parent
commit
ba89c257a3

+ 25 - 0
src/bin/dhcp4/tests/dhcp4_client.cc

@@ -49,6 +49,7 @@ Dhcp4Client::Dhcp4Client(const Dhcp4Client::State& state) :
     curr_transid_(0),
     curr_transid_(0),
     dest_addr_("255.255.255.255"),
     dest_addr_("255.255.255.255"),
     hwaddr_(generateHWAddr()),
     hwaddr_(generateHWAddr()),
+    clientid_(),
     iface_name_("eth0"),
     iface_name_("eth0"),
     relay_addr_("192.0.2.2"),
     relay_addr_("192.0.2.2"),
     requested_options_(),
     requested_options_(),
@@ -66,6 +67,7 @@ Dhcp4Client::Dhcp4Client(boost::shared_ptr<NakedDhcpv4Srv> srv,
     dest_addr_("255.255.255.255"),
     dest_addr_("255.255.255.255"),
     fqdn_(),
     fqdn_(),
     hwaddr_(generateHWAddr()),
     hwaddr_(generateHWAddr()),
+    clientid_(),
     iface_name_("eth0"),
     iface_name_("eth0"),
     relay_addr_("192.0.2.2"),
     relay_addr_("192.0.2.2"),
     requested_options_(),
     requested_options_(),
@@ -153,6 +155,8 @@ Dhcp4Client::doDiscover(const boost::shared_ptr<IOAddress>& requested_addr) {
     includePRL();
     includePRL();
     // Include FQDN or Hostname.
     // Include FQDN or Hostname.
     includeName();
     includeName();
+    // Include Client Identifier
+    includeClientId();
     if (requested_addr) {
     if (requested_addr) {
         addRequestedAddress(*requested_addr);
         addRequestedAddress(*requested_addr);
     }
     }
@@ -244,6 +248,8 @@ Dhcp4Client::doRequest() {
     includePRL();
     includePRL();
     // Include FQDN or Hostname.
     // Include FQDN or Hostname.
     includeName();
     includeName();
+    // Include Client Identifier
+    includeClientId();
     // Send the message to the server.
     // Send the message to the server.
     sendMsg(context_.query_);
     sendMsg(context_.query_);
     // Expect response.
     // Expect response.
@@ -255,6 +261,25 @@ Dhcp4Client::doRequest() {
 }
 }
 
 
 void
 void
+Dhcp4Client::includeClientId(const std::string& clientid) {
+    clientid_ = ClientId::fromText(clientid);
+}
+
+void
+Dhcp4Client::includeClientId() {
+    if (!context_.query_) {
+        isc_throw(Dhcp4ClientError, "pointer to the query must not be NULL"
+                  " when adding Client Identifier option");
+    }
+
+    if (clientid_) {
+        OptionPtr opt(new Option(Option::V4, DHO_DHCP_CLIENT_IDENTIFIER,
+                                 clientid_->getClientId()));
+        context_.query_->addOption(opt);
+    }
+}
+
+void
 Dhcp4Client::includeFQDN(const uint8_t flags, const std::string& fqdn_name,
 Dhcp4Client::includeFQDN(const uint8_t flags, const std::string& fqdn_name,
                          Option4ClientFqdn::DomainNameType fqdn_type) {
                          Option4ClientFqdn::DomainNameType fqdn_type) {
     fqdn_.reset(new Option4ClientFqdn(flags, Option4ClientFqdn::RCODE_CLIENT(),
     fqdn_.reset(new Option4ClientFqdn(flags, Option4ClientFqdn::RCODE_CLIENT(),

+ 18 - 0
src/bin/dhcp4/tests/dhcp4_client.h

@@ -217,6 +217,14 @@ public:
         return (srv_);
         return (srv_);
     }
     }
 
 
+    /// @brief Creates the client id from the client id in the textual format.
+    ///
+    /// The generated client id will be added to the client's messages to the
+    /// server.
+    ///
+    /// @param clientid Client id in the textual format.
+    void includeClientId(const std::string& clientid);
+
     /// @brief Creates an instance of the Client FQDN option to be included
     /// @brief Creates an instance of the Client FQDN option to be included
     /// in the client's message.
     /// in the client's message.
     ///
     ///
@@ -360,6 +368,13 @@ private:
     /// @return An instance of the message created.
     /// @return An instance of the message created.
     Pkt4Ptr createMsg(const uint8_t msg_type);
     Pkt4Ptr createMsg(const uint8_t msg_type);
 
 
+    /// @brief Includes the Client Identifier option in the client's message.
+    ///
+    /// This function creates an instance of the Client Identifier option
+    /// if the client identifier has been specified and includes this
+    /// option in the client's message to the server.
+    void includeClientId();
+
     /// @brief Includes FQDN or Hostname option in the client's message.
     /// @brief Includes FQDN or Hostname option in the client's message.
     ///
     ///
     /// This method checks if @c fqdn_ or @c hostname_ is specified and
     /// This method checks if @c fqdn_ or @c hostname_ is specified and
@@ -407,6 +422,9 @@ private:
     /// @brief Current hardware address of the client.
     /// @brief Current hardware address of the client.
     HWAddrPtr hwaddr_;
     HWAddrPtr hwaddr_;
 
 
+    /// @brief Current client identifier.
+    ClientIdPtr clientid_;
+
     /// @brief Interface to be used to send the messages.
     /// @brief Interface to be used to send the messages.
     std::string iface_name_;
     std::string iface_name_;
 
 

+ 22 - 0
src/bin/dhcp4/tests/dora_unittest.cc

@@ -441,6 +441,28 @@ TEST_F(DORATest, ciaddr) {
     EXPECT_EQ("0.0.0.0", resp->getCiaddr().toText());
     EXPECT_EQ("0.0.0.0", resp->getCiaddr().toText());
 }
 }
 
 
+TEST_F(DORATest, overlappingClientId) {
+    Dhcp4Client clientA(Dhcp4Client::SELECTING);
+    clientA.includeClientId("12:34");
+    configure(DORA_CONFIGS[0], *clientA.getServer());
+    ASSERT_NO_THROW(clientA.doDORA());
+    // Make sure that the server responded.
+    ASSERT_TRUE(clientA.getContext().response_);
+    Pkt4Ptr respA = clientA.getContext().response_;
+    // Make sure that the server has responded with DHCPACK.
+    ASSERT_EQ(DHCPACK, static_cast<int>(respA->getType()));
+
+    Dhcp4Client clientB(clientA.getServer(), Dhcp4Client::SELECTING);
+    clientB.includeClientId("12:34");
+    ASSERT_NO_THROW(clientB.doDiscover());
+
+    Pkt4Ptr respB = clientB.getContext().response_;
+    // Make sure that the server has responded with DHCPOFFER.
+    ASSERT_EQ(DHCPOFFER, static_cast<int>(respB->getType()));
+
+    EXPECT_NE(clientA.config_.lease_.addr_, respB->getYiaddr());
+}
+
 // This is a simple test for the host reservation. It creates a reservation
 // This is a simple test for the host reservation. It creates a reservation
 // for an address for a single client, identified by the HW address. The
 // for an address for a single client, identified by the HW address. The
 // test verifies that the client using this HW address will obtain a
 // test verifies that the client using this HW address will obtain a