static ConstElementPtr
lease6DelHandler(const string& command, ConstElementPtr args);
+ /// @brief lease4-update handler
+ ///
+ /// This command attempts to update existing IPv4 lease. The parameters
+ /// specified will replace existing lease. The only condition is that
+ /// the IP address must not change. If you want to change the IP address,
+ /// please use lease4-del and lease4-add instead.
+ ///
+ /// Example command:
+ /// {
+ /// "command": "lease4-update",
+ /// "arguments": {
+ /// "subnet-id": 44,
+ /// "ip-address": "192.0.2.1",
+ /// "hw-address": "1a:1b:1c:1d:1e:1f",
+ /// "hostname": "newhostname.example.org"
+ /// }
+ /// };
+ ///
+ /// @param command - should be "lease4-update", but it is ignored
+ /// @param args arguments that describe the lease being updated.
static ConstElementPtr
lease4UpdateHandler(const string& command, ConstElementPtr args);
- /// @brief Not implemented yet.
+ /// @brief lease6-update handler
+ ///
+ /// This command attempts to update existing IPv6 lease. The parameters
+ /// specified will replace existing lease. The only condition is that
+ /// the IP address must not change. If you want to change the IP address,
+ /// please use lease6-del and lease6-add instead.
+ ///
+ /// Example command:
+ /// {
+ /// "command": "lease6-update",
+ /// "arguments": {
+ /// "subnet-id": 66,
+ /// "ip-address": "2001:db8::1",
+ /// "iaid": 7654321,
+ /// "duid": "88:88:88:88:88:88:88:88",
+ /// "hostname": "newhostname.example.org"
+ /// }
+ /// }";
+ ///
+ /// @param command - should be "lease6-update" (but it is ignored)
+ /// @param args arguments that describe the lease being updated.
static ConstElementPtr
lease6UpdateHandler(const string& command, ConstElementPtr args);
+ /// @brief lease4-wipe handler
+ ///
+ /// This commands attempts to remove all IPv4 leases from a specific
+ /// subnet. Currently the leases are removed from the database,
+ /// without any processing (like calling hooks or doing DDNS
+ /// cleanups).
+ ///
+ /// Example command:
+ /// {\n"
+ /// "command": "lease4-wipe",\n"
+ /// "arguments": {"
+ /// "subnet-id": 44
+ /// }\n"
+ /// }";
+ /// @param command - should be "lease4-wipe" (but is ignored)
+ /// @param args arguments that describe the lease being updated.
static ConstElementPtr
lease4WipeHandler(const string& command, ConstElementPtr args);
+ /// @brief lease6-wipe handler
+ ///
+ /// This commands attempts to remove all IPv4 leases from a specific
+ /// subnet. Currently the leases are removed from the database,
+ /// without any processing (like calling hooks or doing DDNS
+ /// cleanups).
+ ///
+ /// Example command:
+ /// {\n"
+ /// "command": "lease4-wipe",\n"
+ /// "arguments": {"
+ /// "subnet-id": 44
+ /// }\n"
+ /// }";
+ /// @param command - should be "lease4-wipe" (but is ignored)
+ /// @param args arguments that describe the lease being updated.
static ConstElementPtr
lease6WipeHandler(const string& command, ConstElementPtr args);
/// See @ref Parameters class for detailed description of what is expected
/// in the args structure.
///
- /// @param args - arguments passed to command
+ /// @param v6 whether addresses allowed are v4 (false) or v6 (true)
+ /// @param args arguments passed to command
/// @return parsed parameters
/// @throw BadValue if input arguments don't make sense.
- static Parameters getParameters(const ConstElementPtr& args);
+ static Parameters getParameters(bool v6, const ConstElementPtr& args);
};
LeaseCmdsImpl::LeaseCmdsImpl() {
}
LeaseCmdsImpl::Parameters
-LeaseCmdsImpl::getParameters(const ConstElementPtr& params) {
+LeaseCmdsImpl::getParameters(bool v6, const ConstElementPtr& params) {
Parameters x;
if (!params || params->getType() != Element::map) {
}
x.addr = IOAddress(tmp->stringValue());
+
+ if ((v6 && !x.addr.isV6()) || (!v6 && !x.addr.isV4())) {
+ stringstream txt;
+ txt << "Invalid " << (v6 ? "IPv6" : "IPv4")
+ << " address specified: " << tmp->stringValue();
+ isc_throw(BadValue, txt.str());
+ }
+
x.query_type = Parameters::TYPE_ADDR;
return (x);
}
Lease6Ptr lease6;
bool v4 = (name == "lease4-get");
try {
- p = getParameters(params);
+ p = getParameters(!v4, params);
switch (p.query_type) {
case Parameters::TYPE_ADDR: {
Lease4Ptr lease4;
IOAddress addr(IOAddress::IPV4_ZERO_ADDRESS());
try {
- p = getParameters(params);
+ p = getParameters(false, params);
switch (p.query_type) {
case Parameters::TYPE_ADDR: {
Lease6Ptr lease6;
IOAddress addr(IOAddress::IPV6_ZERO_ADDRESS());
try {
- p = getParameters(params);
+ p = getParameters(true, params);
switch (p.query_type) {
case Parameters::TYPE_ADDR: {
// subnet-id is valid, etc)
lease4 = parser.parse(config, params);
- // Ok, now check if there is a lease to be updated.
- Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(lease4->addr_);
- if (!existing) {
- stringstream tmp;
- tmp << "There is no lease for address " << lease4->addr_ << ", can't update.";
- return (createAnswer(CONTROL_RESULT_EMPTY, tmp.str()));
- }
-
LeaseMgrFactory::instance().updateLease4(lease4);
return (createAnswer(CONTROL_RESULT_SUCCESS, "IPv4 lease updated."));
// subnet-id is valid, etc)
lease6 = parser.parse(config, params);
- // Ok, now check if there is a lease to be updated.
- Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(lease6->type_,
- lease6->addr_);
- if (!existing) {
- stringstream tmp;
- tmp << "There is no lease for address " << lease6->addr_ << ", can't update.";
- return (createAnswer(CONTROL_RESULT_EMPTY, tmp.str()));
- }
-
LeaseMgrFactory::instance().updateLease6(lease6);
return (createAnswer(CONTROL_RESULT_SUCCESS, "IPv6 lease updated."));
LeaseCmdsImpl::lease4WipeHandler(const string& /*cmd*/, ConstElementPtr params) {
try {
- // We need the lease to be specified.
+ // The subnet-id is a mandatory parameter.
if (!params) {
isc_throw(isc::BadValue, "no parameters specified for lease4-wipe command");
}
-
SimpleParser parser;
SubnetID id = parser.getUint32(params, "subnet-id");
LeaseCmdsImpl::lease6WipeHandler(const string& /*cmd*/, ConstElementPtr params) {
try {
- // We need the lease to be specified.
+ // The subnet-id is a mandatory parameter.
if (!params) {
isc_throw(isc::BadValue, "no parameters specified for lease6-wipe command");
}
-
SimpleParser parser;
SubnetID id = parser.getUint32(params, "subnet-id");
"}";
exp_rsp = "Non-IPv4 address specified: 2001:db8::1";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+
+ // currently defined states are 0,1 and 2. 123 is junk.
+ txt =
+ "{\n"
+ " \"command\": \"lease4-add\",\n"
+ " \"arguments\": {"
+ " \"subnet-id\": 44,\n"
+ " \"ip-address\": \"192.0.2.1\",\n"
+ " \"hw-address\": \"1a:1b:1c:1d:1e:1f\",\n"
+ " \"state\": 123\n"
+ " }\n"
+ "}";
+ exp_rsp = "Invalid state value: 123, supported values are: 0 (default), 1 "
+ "(declined) and 2 (expired-reclaimed)";
+ testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
}
// Check that a simple, well formed lease4 can be added.
"}";
exp_rsp = "Non-IPv6 address specified: 192.0.2.1";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+
+ // Invalid state: the only supported values are 0,1,2.
+ txt =
+ "{\n"
+ " \"command\": \"lease6-add\",\n"
+ " \"arguments\": {"
+ " \"subnet-id\": 66,\n"
+ " \"ip-address\": \"2001:db8::1\",\n"
+ " \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
+ " \"iaid\": 1234\n,"
+ " \"state\": 123\n"
+ " }\n"
+ "}";
+ exp_rsp = "Invalid state value: 123, supported values are: 0 (default), 1 "
+ "(declined) and 2 (expired-reclaimed)";
+ testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
}
// Check that a simple, well formed lease6 can be added.
testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
}
+// Checks that lease4-get sanitizes its input.
+TEST_F(LeaseCmdsTest, Lease4GetByAddrBadParam) {
+
+ // Initialize lease manager (false = v4, true = add a lease)
+ initLeaseMgr(false, true);
+
+ // Invalid family
+ string cmd =
+ "{\n"
+ " \"command\": \"lease4-get\",\n"
+ " \"arguments\": {"
+ " \"ip-address\": \"2001:db8::1\""
+ " }\n"
+ "}";
+ string exp_rsp = "Invalid IPv4 address specified: 2001:db8::1";
+ testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+ // This is way off
+ cmd =
+ "{\n"
+ " \"command\": \"lease4-get\",\n"
+ " \"arguments\": {"
+ " \"ip-address\": \"221B Baker St.\""
+ " }\n"
+ "}";
+ exp_rsp = "Failed to convert string to address '221B Baker St.': Invalid argument";
+ testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
// Checks that lease4-get can handle a situation when the query is
// valid, but the lease is not there.
TEST_F(LeaseCmdsTest, Lease4GetByAddrNotFound) {
checkLease6(lease, "2001:db8::1", 0, 66, "77:77:77:77:77:77:77:77", false);
}
+// Checks that lease6-get sanitizes its input.
+TEST_F(LeaseCmdsTest, Lease6GetByAddrBadParam) {
+
+ // Initialize lease manager (true = v6, true = add a lease)
+ initLeaseMgr(true, true);
+
+ // Invalid family
+ string cmd =
+ "{\n"
+ " \"command\": \"lease6-get\",\n"
+ " \"arguments\": {"
+ " \"ip-address\": \"192.0.2.1\""
+ " }\n"
+ "}";
+ string exp_rsp = "Invalid IPv6 address specified: 192.0.2.1";
+ testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+ // This is way off
+ cmd =
+ "{\n"
+ " \"command\": \"lease6-get\",\n"
+ " \"arguments\": {"
+ " \"ip-address\": \"221B Baker St.\""
+ " }\n"
+ "}";
+ exp_rsp = "Failed to convert string to address '221B Baker St.': Invalid argument";
+ testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
// Checks that lease6-get(subnet-id, type, addr6) can handle a situation when
// the query is correctly formed and the lease is returned.
TEST_F(LeaseCmdsTest, Lease6GetByAddrPrefix) {
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
}
+// Check that lease4-update correctly handles case when there is
+// no lease to be updated.
+TEST_F(LeaseCmdsTest, Lease4UpdateNoLease) {
+
+ // Initialize lease manager (false = v4, false = don't add any lease)
+ initLeaseMgr(false, false);
+
+ // Check that the lease manager pointer is there.
+ ASSERT_TRUE(lmptr_);
+
+ // Now send the command.
+ string txt =
+ "{\n"
+ " \"command\": \"lease4-update\",\n"
+ " \"arguments\": {"
+ " \"subnet-id\": 44,\n"
+ " \"ip-address\": \"192.0.2.1\",\n"
+ " \"hw-address\": \"1a:1b:1c:1d:1e:1f\",\n"
+ " \"hostname\": \"newhostname.example.org\""
+ " }\n"
+ "}";
+ string exp_rsp = "failed to update the lease with address 192.0.2.1 - no such lease";
+ testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
// Check that a lease4 can be updated. We're changing hw-address
// and a hostname.
TEST_F(LeaseCmdsTest, Lease4Update) {
EXPECT_EQ(7654321, l->iaid_);
}
+
+// Check that lease6-update correctly handles case when there is
+// no lease to be updated.
+TEST_F(LeaseCmdsTest, Lease6UpdateNoLease) {
+
+ // Initialize lease manager (true = v6, false = don't add any lease)
+ initLeaseMgr(true, false);
+
+ // Check that the lease manager pointer is there.
+ ASSERT_TRUE(lmptr_);
+
+ // Now send the command.
+ string txt =
+ "{\n"
+ " \"command\": \"lease6-update\",\n"
+ " \"arguments\": {"
+ " \"subnet-id\": 66,\n"
+ " \"ip-address\": \"2001:db8::1\",\n"
+ " \"iaid\": 7654321,\n"
+ " \"duid\": \"88:88:88:88:88:88:88:88\",\n"
+ " \"hostname\": \"newhostname.example.org\""
+ " }\n"
+ "}";
+ string exp_rsp = "failed to update the lease with address 2001:db8::1 - no such lease";
+ testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
// Checks that lease6-del can handle a situation when the query is
// broken (some required parameters are missing).
TEST_F(LeaseCmdsTest, Lease4DelMissingParams) {
EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.2.1")));
}
+
+// Checks that lease4-del sanitizes its input.
+TEST_F(LeaseCmdsTest, Lease4DelByAddrBadParam) {
+
+ // Initialize lease manager (false = v4, true = add a lease)
+ initLeaseMgr(false, true);
+
+ // Invalid family
+ string cmd =
+ "{\n"
+ " \"command\": \"lease4-del\",\n"
+ " \"arguments\": {"
+ " \"ip-address\": \"2001:db8::1\""
+ " }\n"
+ "}";
+ string exp_rsp = "Invalid IPv4 address specified: 2001:db8::1";
+ testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+ // This is way off
+ cmd =
+ "{\n"
+ " \"command\": \"lease6-del\",\n"
+ " \"arguments\": {"
+ " \"ip-address\": \"221B Baker St.\""
+ " }\n"
+ "}";
+ exp_rsp = "Failed to convert string to address '221B Baker St.': Invalid argument";
+ testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
// Checks that lease4-del can handle a situation when the query is
// well formed, but the lease is not there.
TEST_F(LeaseCmdsTest, Lease4DelByHWAddrNotFound) {
EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8::1")));
}
+// Checks that lease6-del sanitizes its input.
+TEST_F(LeaseCmdsTest, Lease6DelByAddrBadParam) {
+
+ // Initialize lease manager (true = v6, true = add a lease)
+ initLeaseMgr(true, true);
+
+ // Invalid family
+ string cmd =
+ "{\n"
+ " \"command\": \"lease6-del\",\n"
+ " \"arguments\": {"
+ " \"ip-address\": \"192.0.2.1\""
+ " }\n"
+ "}";
+ string exp_rsp = "Invalid IPv6 address specified: 192.0.2.1";
+ testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+ // This is way off
+ cmd =
+ "{\n"
+ " \"command\": \"lease6-del\",\n"
+ " \"arguments\": {"
+ " \"ip-address\": \"221B Baker St.\""
+ " }\n"
+ "}";
+ exp_rsp = "Failed to convert string to address '221B Baker St.': Invalid argument";
+ testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
// Checks that lease6-del(subnet-id, type, addr6) can handle a situation when
// the query is correctly formed and the lease is deleted.
TEST_F(LeaseCmdsTest, Lease6DelByAddrPrefix) {