checkClientId(ack, clientid);
}
-// This test verifies that incoming REQUEST can be handled properly, that an
-// ACK is generated, that the response has an address and that address
-// really belongs to the configured pool.
-//
-// constructed 3 REQUEST messages with:
-// - client-id option (differs between messages)
-// - hwaddr information (differs between messages)
-//
-// expected returned ACK message:
-// - copy of client-id
-// - server-id
-// - assigned address (different for each client)
-TEST_F(Dhcpv4SrvTest, ManyRequests) {
- IfaceMgrTestConfig test_config(true);
- IfaceMgr::instance().openSockets4();
-
- boost::scoped_ptr<NakedDhcpv4Srv> srv;
- ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
-
- const IOAddress req_addr1("192.0.2.105");
- const IOAddress req_addr2("192.0.2.101");
- const IOAddress req_addr3("192.0.2.109");
- const IOAddress relay("192.0.2.1");
-
- Pkt4Ptr req1 = Pkt4Ptr(new Pkt4(DHCPOFFER, 1234));
- Pkt4Ptr req2 = Pkt4Ptr(new Pkt4(DHCPOFFER, 2345));
- Pkt4Ptr req3 = Pkt4Ptr(new Pkt4(DHCPOFFER, 3456));
-
- req1->setRemoteAddr(relay);
- req2->setRemoteAddr(relay);
- req3->setRemoteAddr(relay);
-
- // Assign interfaces
- req1->setIface("eth1");
- req2->setIface("eth1");
- req3->setIface("eth1");
-
- req1->setYiaddr(req_addr1);
- req2->setYiaddr(req_addr2);
- req3->setYiaddr(req_addr3);
-
- req1->setHWAddr(generateHWAddr(6));
- req2->setHWAddr(generateHWAddr(7));
- req3->setHWAddr(generateHWAddr(8));
-
- // Different client-id sizes
- OptionPtr clientid1 = generateClientId(4); // length 4
- OptionPtr clientid2 = generateClientId(5); // length 5
- OptionPtr clientid3 = generateClientId(6); // length 6
-
- req1->addOption(clientid1);
- req2->addOption(clientid2);
- req3->addOption(clientid3);
-
- // Pass it to the server and get an advertise
- Pkt4Ptr ack1 = srv->processRequest(req1);
- Pkt4Ptr ack2 = srv->processRequest(req2);
- Pkt4Ptr ack3 = srv->processRequest(req3);
-
- // Check if we get response at all
- checkResponse(ack1, DHCPACK, 1234);
- checkResponse(ack2, DHCPACK, 2345);
- checkResponse(ack3, DHCPACK, 3456);
-
- IOAddress addr1 = ack1->getYiaddr();
- IOAddress addr2 = ack2->getYiaddr();
- IOAddress addr3 = ack3->getYiaddr();
-
- // Check that every client received the address it requested
- EXPECT_EQ(req_addr1, addr1);
- EXPECT_EQ(req_addr2, addr2);
- EXPECT_EQ(req_addr3, addr3);
-
- // Check that the assigned address is indeed from the configured pool
- checkAddressParams(ack1, subnet_, true, true);
- checkAddressParams(ack2, subnet_, true, true);
- checkAddressParams(ack3, subnet_, true, true);
-
- // Check DUIDs
- checkServerId(ack1, srv->getServerID());
- checkServerId(ack2, srv->getServerID());
- checkServerId(ack3, srv->getServerID());
- checkClientId(ack1, clientid1);
- checkClientId(ack2, clientid2);
- checkClientId(ack3, clientid3);
-
- // Check that leases are in the database
- Lease4Ptr l = checkLease(ack1, clientid1, req1->getHWAddr(), addr1);
- EXPECT_TRUE(l);
- l = checkLease(ack2, clientid2, req2->getHWAddr(), addr2);
- l = checkLease(ack3, clientid3, req3->getHWAddr(), addr3);
-
- // Finally check that the addresses offered are different
- EXPECT_NE(addr1, addr2);
- EXPECT_NE(addr2, addr3);
- EXPECT_NE(addr3, addr1);
- cout << "Offered address to client1=" << addr1 << endl;
- cout << "Offered address to client2=" << addr2 << endl;
- cout << "Offered address to client3=" << addr3 << endl;
-}
-
// Checks whether echoing back client-id is controllable
TEST_F(Dhcpv4SrvTest, requestEchoClientId) {
IfaceMgrTestConfig test_config(true);
};
/// @brief Test fixture class for testing 4-way (DORA) exchanges.
+///
+/// @todo Currently there is a limit number of test cases covered here.
+/// In the future it is planned that the tests from the
+/// dhcp4_srv_unittest.cc will be migrated here and will use the
+/// @c Dhcp4Client class.
class DORATest : public Dhcpv4SrvTest {
public:
ASSERT_NE(client.config_.lease_.addr_.toText(), "0.0.0.0");
}
+/// This test verifies that multiple clients may use the DHCPv4 server
+/// and obtain unique leases.
+TEST_F(DORATest, selectingMultipleClients) {
+ Dhcp4Client client(Dhcp4Client::SELECTING);
+ // Configure DHCP server.
+ configure(DORA_CONFIGS[0], *client.getServer());
+
+ // Get the first lease.
+ ASSERT_NO_THROW(client.doDORA());
+
+ // Make sure that the server responded.
+ Pkt4Ptr resp = client.getContext().response_;
+ ASSERT_TRUE(resp);
+ ASSERT_EQ(DHCPACK, static_cast<int>(resp->getType()));
+ // Store the lease.
+ Lease4 lease1 = client.config_.lease_;
+
+ // Get the lease for a different client.
+ client.modifyHWAddr();
+ ASSERT_NO_THROW(client.doDORA());
+ // Make sure that the server responded.
+ resp = client.getContext().response_;
+ ASSERT_TRUE(resp);
+ ASSERT_EQ(DHCPACK, static_cast<int>(resp->getType()));
+ // Store the lease.
+ Lease4 lease2 = client.config_.lease_;
+
+ // Get the lease for a different client.
+ client.modifyHWAddr();
+ ASSERT_NO_THROW(client.doDORA());
+ // Make sure that the server responded.
+ resp = client.getContext().response_;
+ ASSERT_TRUE(resp);
+ ASSERT_EQ(DHCPACK, static_cast<int>(resp->getType()));
+ // Store the lease.
+ Lease4 lease3 = client.config_.lease_;
+
+ // Make sure that unique addresses have been assigned.
+ EXPECT_NE(lease1.addr_, lease2.addr_);
+ EXPECT_NE(lease2.addr_, lease3.addr_);
+ EXPECT_NE(lease1.addr_, lease3.addr_);
+}
+
// This test verifies that the client in a SELECTING state can request
// a specific address and that this address will be assigned when
// available. It also tests that if the client requests an address which
resp = client.getContext().response_;
// Make sure that the server responded.
ASSERT_TRUE(resp);
- // Make sure that the server has responded with DHCPACK.
+ // Make sure that the server has responded with DHCPACK.
ASSERT_EQ(DHCPACK, static_cast<int>(resp->getType()));
// Response must not be relayed.
EXPECT_FALSE(resp->isRelayed());
// to the INIT_REBOOT state so as the client can request the cached
// lease using the DHCPREQUEST message.
client.setState(Dhcp4Client::INIT_REBOOT);
- ASSERT_NO_THROW(client.doRequest(boost::shared_ptr<
- IOAddress>(new IOAddress("10.0.0.50"))));
+ ASSERT_NO_THROW(client.doRequest());
// Make sure that the server responded.
ASSERT_TRUE(client.getContext().response_);
// Try to request a different address than the client has. The server
// should respond with DHCPNAK.
client.config_.lease_.addr_ = IOAddress("10.0.0.30");
- ASSERT_NO_THROW(client.doRequest(boost::shared_ptr<
- IOAddress>(new IOAddress("10.0.0.50"))));
+ ASSERT_NO_THROW(client.doRequest());
// Make sure that the server responded.
ASSERT_TRUE(client.getContext().response_);
resp = client.getContext().response_;