Commit 87e43d5d authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[3036] Generate NameChangeRequests for Solicit, Request, Renew and Release.

parent b74b04e1
......@@ -54,6 +54,11 @@ b10_dhcp6_SOURCES += config_parser.cc config_parser.h
b10_dhcp6_SOURCES += dhcp6_log.cc dhcp6_log.h
b10_dhcp6_SOURCES += dhcp6_srv.cc dhcp6_srv.h
# Temporarily compile this file here. It will be removed once libdhcp-ddns
# is implemented which will include this file and other files required
# by DHCPv6.
b10_dhcp6_SOURCES += ../d2/ncr_msg.cc ../d2/ncr_msg.h
nodist_b10_dhcp6_SOURCES = dhcp6_messages.h dhcp6_messages.cc
EXTRA_DIST += dhcp6_messages.mes
......
......@@ -65,6 +65,18 @@ This informational message is printed every time the IPv6 DHCP server
is started. It indicates what database backend type is being to store
lease and other information.
% DHCP6_DDNS_REMOVE_EMPTY_HOSTNAME FQDN for the lease being deleted is empty: %1
This error message is issued when a lease being deleted contains an indication
that the DNS Update has been performed for it, but the FQDN is missing for this
lease. This is an indication that someone may have messed up in the lease
database.
% DHCP6_DDNS_REMOVE_INVALID_HOSTNAME FQDN for the lease being deleted has invalid format: %1
This error message is issued when a lease being deleted contains an indication
that the DNS Update has been performed for it, but the FQDN held in the lease
database has invalid format and can't be transformed to the canonical on-wire
format.
% 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 the
......
This diff is collapsed.
......@@ -29,6 +29,7 @@
#include <boost/noncopyable.hpp>
#include <iostream>
#include <queue>
namespace isc {
namespace dhcp {
......@@ -130,20 +131,17 @@ protected:
/// @param request a message received from client
///
/// @return REPLY message or NULL
Pkt6Ptr processRequest(const Pkt6Ptr& request,
isc::d2::NameChangeRequestPtr& ncr);
Pkt6Ptr processRequest(const Pkt6Ptr& request);
/// @brief Stub function that will handle incoming RENEW messages.
///
/// @param renew message received from client
Pkt6Ptr processRenew(const Pkt6Ptr& renew,
isc::d2::NameChangeRequestPtr& ncr);
Pkt6Ptr processRenew(const Pkt6Ptr& renew);
/// @brief Stub function that will handle incoming REBIND messages.
///
/// @param rebind message received from client
Pkt6Ptr processRebind(const Pkt6Ptr& rebind,
isc::d2::NameChangeRequestPtr& ncr);
Pkt6Ptr processRebind(const Pkt6Ptr& rebind);
/// @brief Stub function that will handle incoming CONFIRM messages.
///
......@@ -153,8 +151,7 @@ protected:
/// @brief Stub function that will handle incoming RELEASE messages.
///
/// @param release message received from client
Pkt6Ptr processRelease(const Pkt6Ptr& release,
isc::d2::NameChangeRequestPtr& ncr);
Pkt6Ptr processRelease(const Pkt6Ptr& release);
/// @brief Stub function that will handle incoming DECLINE messages.
///
......@@ -191,11 +188,14 @@ protected:
/// @param duid client's duid
/// @param question client's message (typically SOLICIT or REQUEST)
/// @param ia pointer to client's IA_NA option (client's request)
/// @param fqdn A DHCPv6 Client FQDN %Option generated in a response to the
/// FQDN option sent by a client.
/// @return IA_NA option (server's response)
OptionPtr assignIA_NA(const isc::dhcp::Subnet6Ptr& subnet,
const isc::dhcp::DuidPtr& duid,
isc::dhcp::Pkt6Ptr question,
boost::shared_ptr<Option6IA> ia);
Option6IAPtr ia,
const Option6ClientFqdnPtr& fqdn);
/// @brief Renews specific IA_NA option
///
......@@ -207,9 +207,11 @@ protected:
/// @param duid client's duid
/// @param question client's message
/// @param ia IA_NA option that is being renewed
/// @param fqdn DHCPv6 Client FQDN Option included in the server's response
/// @return IA_NA option (server's response)
OptionPtr renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
Pkt6Ptr question, boost::shared_ptr<Option6IA> ia);
Pkt6Ptr question, boost::shared_ptr<Option6IA> ia,
const Option6ClientFqdnPtr& fqdn);
/// @brief Releases specific IA_NA option
///
......@@ -268,7 +270,10 @@ protected:
///
/// @param question client's message (with requested IA_NA)
/// @param answer server's message (IA_NA options will be added here)
void assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer);
/// @param fqdn an FQDN option generated in a response to the client's
/// FQDN option.
void assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer,
const Option6ClientFqdnPtr& fqdn);
/// @brief Processes Client FQDN Option.
///
......@@ -288,24 +293,56 @@ protected:
/// held in this function.
///
/// @param question Client's message.
/// @param answer Server's response to the client.
void processClientFqdn(const Pkt6Ptr& question, Pkt6Ptr& answer,
d2::NameChangeRequestPtr& ncr);
/// @brief Creates a @c isc::d2::NameChangeRequest based on the DHCPv6
/// Client FQDN %Option stored in the response to the client.
///
/// The @c isc:d2::NameChangeRequest class encapsulates the request from
/// the DHCPv6 server to the DHCP-DDNS module to perform DNS Update.
///
/// @param answer A response being sent to a client.
/// @return FQDN option produced in the response to the client's message.
Option6ClientFqdnPtr processClientFqdn(const Pkt6Ptr& question);
/// @brief Adds DHCPv6 Client FQDN %Option to the server response.
///
/// This function will add the specified FQDN option into the server's
/// response when FQDN is not NULL and server is either configured to
/// always include the FQDN in the response or client requested it using
/// %Option Request %Option.
/// This function is exception safe.
///
/// @param question A message received from the client.
/// @param [out] answer A server's response where FQDN option will be added.
/// @param fqdn A DHCPv6 Client FQDN %Option to be added.
void appendClientFqdn(const Pkt6Ptr& question,
Pkt6Ptr& answer,
const Option6ClientFqdnPtr& fqdn);
/// @brief Creates a number of @c isc::d2::NameChangeRequest objects based
/// on the DHCPv6 Client FQDN %Option.
///
/// The @c isc::d2::NameChangeRequest class encapsulates the request from
/// the DHCPv6 server to the DHCP-DDNS module to perform DNS Update. The
/// FQDN option carries response to the client about DNS updates that
/// server intents to perform for the DNS client. Based on this, the
/// function will create zero or more @c isc::d2::NameChangeRequest objects
/// and store them in the internal queue. Requests created by this function
/// are only adding or updating DNS records. In order to generate requests
/// for DNS records removal, use @c createRemovalNameChangeRequest.
///
/// @param answer A message beging sent to the Client.
/// @param fqdn_answer A DHCPv6 Client FQDN %Option which is included in the
/// response message sent to a client.
/// @param [out] ncr A @c isc::d2::NameChangeRequest object to be sent to
/// the DHCP-DDNS module as a result of the Client FQDN %Option processing.
void createNameChangeRequest(const Pkt6Ptr& answer,
const Option6ClientFqdnPtr& fqdn_answer,
isc::d2::NameChangeRequestPtr& ncr);
void createNameChangeRequests(const Pkt6Ptr& answer,
const Option6ClientFqdnPtr& fqdn_answer);
/// @brief Creates a @c isc::d2::NameChangeRequest which requests removal
/// of DNS entries for a particular lease.
///
/// This function should be called upon removal of the lease from the lease
/// database, i.e, when client sent Release or Decline message. It will
/// create a single @isc::d2::NameChangeRequest which removes the existing
/// DNS records for the lease, which server is responsible for. Note that
/// this function will not remove the entries which server hadn't added.
/// This is the case, when client performs forward DNS update on its own.
///
/// @param lease A lease for which the the removal of correponding DNS
/// records will be performed.
void createRemovalNameChangeRequest(const Lease6Ptr& lease);
/// @brief Attempts to renew received addresses
///
......@@ -315,7 +352,10 @@ protected:
/// as IA_NA/IAADDR to reply packet.
/// @param renew client's message asking for renew
/// @param reply server's response
void renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply);
/// @param fqdn A DHCPv6 Client FQDN %Option generated in the response to the
/// client's FQDN option.
void renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply,
const Option6ClientFqdnPtr& fqdn);
/// @brief Attempts to release received addresses
///
......@@ -377,6 +417,12 @@ private:
/// Indicates if shutdown is in progress. Setting it to true will
/// initiate server shutdown procedure.
volatile bool shutdown_;
protected:
/// Holds a list of @c isc::d2::NameChangeRequest objects, which
/// are waiting for sending to D2 module.
std::queue<isc::d2::NameChangeRequest> name_change_reqs_;
};
}; // namespace isc::dhcp
......
......@@ -55,6 +55,11 @@ dhcp6_unittests_SOURCES += ../dhcp6_srv.h ../dhcp6_srv.cc
dhcp6_unittests_SOURCES += ../dhcp6_log.h ../dhcp6_log.cc
dhcp6_unittests_SOURCES += ../ctrl_dhcp6_srv.cc
dhcp6_unittests_SOURCES += ../config_parser.cc ../config_parser.h
# Temporarily compile this file here. It will be removed once libdhcp-ddns
# is implemented which will include this file and other files required
# by DHCPv6.
dhcp6_unittests_SOURCES += ../../d2/ncr_msg.cc ../../d2/ncr_msg.h
nodist_dhcp6_unittests_SOURCES = ../dhcp6_messages.h ../dhcp6_messages.cc
dhcp6_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
......
This diff is collapsed.
// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
......@@ -16,12 +16,17 @@
#define OPTION_IA_H
#include <dhcp/option.h>
#include <boost/shared_ptr.hpp>
#include <stdint.h>
namespace isc {
namespace dhcp {
class Option6IA;
/// A pointer to the @c Option6IA object.
typedef boost::shared_ptr<Option6IA> Option6IAPtr;
class Option6IA: public Option {
public:
......
......@@ -17,10 +17,16 @@
#include <asiolink/io_address.h>
#include <dhcp/option.h>
#include <boost/shared_ptr.hpp>
namespace isc {
namespace dhcp {
class Option6IAAddr;
/// A pointer to the @c isc::dhcp::Option6IAAddr object.
typedef boost::shared_ptr<Option6IAAddr> Option6IAAddrPtr;
class Option6IAAddr: public Option {
public:
......
......@@ -168,6 +168,9 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
const DuidPtr& duid,
uint32_t iaid,
const IOAddress& hint,
const bool fwd_dns_update,
const bool rev_dns_update,
const std::string& hostname,
bool fake_allocation /* = false */ ) {
try {
......@@ -201,7 +204,10 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
/// implemented
// the hint is valid and not currently used, let's create a lease for it
Lease6Ptr lease = createLease6(subnet, duid, iaid, hint, fake_allocation);
Lease6Ptr lease = createLease6(subnet, duid, iaid,
hint, fwd_dns_update,
rev_dns_update, hostname,
fake_allocation);
// It can happen that the lease allocation failed (we could have lost
// the race condition. That means that the hint is lo longer usable and
......@@ -212,7 +218,8 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
} else {
if (existing->expired()) {
return (reuseExpiredLease(existing, subnet, duid, iaid,
fake_allocation));
fwd_dns_update, rev_dns_update,
hostname, fake_allocation));
}
}
......@@ -246,7 +253,8 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
// there's no existing lease for selected candidate, so it is
// free. Let's allocate it.
Lease6Ptr lease = createLease6(subnet, duid, iaid, candidate,
fake_allocation);
fwd_dns_update, rev_dns_update,
hostname, fake_allocation);
if (lease) {
return (lease);
}
......@@ -257,7 +265,8 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
} else {
if (existing->expired()) {
return (reuseExpiredLease(existing, subnet, duid, iaid,
fake_allocation));
fwd_dns_update, rev_dns_update,
hostname, fake_allocation));
}
}
......@@ -438,6 +447,9 @@ Lease6Ptr AllocEngine::reuseExpiredLease(Lease6Ptr& expired,
const Subnet6Ptr& subnet,
const DuidPtr& duid,
uint32_t iaid,
const bool fwd_dns_update,
const bool rev_dns_update,
const std::string& hostname,
bool fake_allocation /*= false */ ) {
if (!expired->expired()) {
......@@ -454,9 +466,9 @@ Lease6Ptr AllocEngine::reuseExpiredLease(Lease6Ptr& expired,
expired->cltt_ = time(NULL);
expired->subnet_id_ = subnet->getID();
expired->fixed_ = false;
expired->hostname_ = std::string("");
expired->fqdn_fwd_ = false;
expired->fqdn_rev_ = false;
expired->hostname_ = hostname;
expired->fqdn_fwd_ = fwd_dns_update;
expired->fqdn_rev_ = rev_dns_update;
/// @todo: log here that the lease was reused (there's ticket #2524 for
/// logging in libdhcpsrv)
......@@ -517,12 +529,19 @@ Lease6Ptr AllocEngine::createLease6(const Subnet6Ptr& subnet,
const DuidPtr& duid,
uint32_t iaid,
const IOAddress& addr,
const bool fwd_dns_update,
const bool rev_dns_update,
const std::string& hostname,
bool fake_allocation /*= false */ ) {
Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr, duid, iaid,
subnet->getPreferred(), subnet->getValid(),
subnet->getT1(), subnet->getT2(), subnet->getID()));
lease->fqdn_fwd_ = fwd_dns_update;
lease->fqdn_rev_ = rev_dns_update;
lease->hostname_ = hostname;
if (!fake_allocation) {
// That is a real (REQUEST) allocation
bool status = LeaseMgrFactory::instance().addLease(lease);
......
......@@ -233,6 +233,11 @@ protected:
/// @param duid Client's DUID
/// @param iaid iaid field from the IA_NA container that client sent
/// @param hint a hint that the client provided
/// @param fwd_dns_update A boolean value which indicates that server takes
/// responisibility for the forward DNS Update for this lease (if true).
/// @param rev_dns_update A boolean value which indicates that server takes
/// responibility for the reverse DNS Update for this lease (if true).
/// @param hostname A fully qualified domain-name of the client.
/// @param fake_allocation is this real i.e. REQUEST (false) or just picking
/// an address for SOLICIT that is not really allocated (true)
/// @return Allocated IPv6 lease (or NULL if allocation failed)
......@@ -241,6 +246,9 @@ protected:
const DuidPtr& duid,
uint32_t iaid,
const isc::asiolink::IOAddress& hint,
const bool fwd_dns_update,
const bool rev_dns_update,
const std::string& hostname,
bool fake_allocation);
/// @brief Destructor. Used during DHCPv6 service shutdown.
......@@ -275,13 +283,21 @@ private:
/// @param subnet subnet the lease is allocated from
/// @param duid client's DUID
/// @param iaid IAID from the IA_NA container the client sent to us
/// @param addr an address that was selected and is confirmed to be available
/// @param addr an address that was selected and is confirmed to be
/// available
/// @param fwd_dns_update A boolean value which indicates that server takes
/// responisibility for the forward DNS Update for this lease (if true).
/// @param rev_dns_update A boolean value which indicates that server takes
/// responibility for the reverse DNS Update for this lease (if true).
/// @param hostname A fully qualified domain-name of the client.
/// @param fake_allocation is this real i.e. REQUEST (false) or just picking
/// an address for SOLICIT that is not really allocated (true)
/// @return allocated lease (or NULL in the unlikely case of the lease just
/// becomed unavailable)
Lease6Ptr createLease6(const Subnet6Ptr& subnet, const DuidPtr& duid,
uint32_t iaid, const isc::asiolink::IOAddress& addr,
const bool fwd_dns_update, const bool rev_dns_update,
const std::string& hostname,
bool fake_allocation = false);
/// @brief Reuses expired IPv4 lease
......@@ -313,12 +329,20 @@ private:
/// @param subnet subnet the lease is allocated from
/// @param duid client's DUID
/// @param iaid IAID from the IA_NA container the client sent to us
/// @param fwd_dns_update A boolean value which indicates that server takes
/// responisibility for the forward DNS Update for this lease (if true).
/// @param rev_dns_update A boolean value which indicates that server takes
/// responibility for the reverse DNS Update for this lease (if true).
/// @param hostname A fully qualified domain-name of the client.
/// @param fake_allocation is this real i.e. REQUEST (false) or just picking
/// an address for SOLICIT that is not really allocated (true)
/// @return refreshed lease
/// @throw BadValue if trying to recycle lease that is still valid
Lease6Ptr reuseExpiredLease(Lease6Ptr& expired, const Subnet6Ptr& subnet,
const DuidPtr& duid, uint32_t iaid,
const bool fwd_dns_update,
const bool rev_dns_update,
const std::string& hostname,
bool fake_allocation = false);
/// @brief a pointer to currently used allocator
......
......@@ -202,7 +202,9 @@ TEST_F(AllocEngine6Test, simpleAlloc6) {
ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
ASSERT_TRUE(engine);
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress("::"), false,
false, "",
false);
// Check that we got a lease
......@@ -225,8 +227,9 @@ TEST_F(AllocEngine6Test, fakeAlloc6) {
ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
ASSERT_TRUE(engine);
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
true);
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress("::"), false,
false, "", true);
// Check that we got a lease
ASSERT_TRUE(lease);
......@@ -248,6 +251,7 @@ TEST_F(AllocEngine6Test, allocWithValidHint6) {
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress("2001:db8:1::15"),
false, false, "",
false);
// Check that we got a lease
......@@ -286,6 +290,7 @@ TEST_F(AllocEngine6Test, allocWithUsedHint6) {
// twice.
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress("2001:db8:1::1f"),
false, false, "",
false);
// Check that we got a lease
ASSERT_TRUE(lease);
......@@ -319,6 +324,7 @@ TEST_F(AllocEngine6Test, allocBogusHint6) {
// with the normal allocation
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress("3000::abc"),
false, false, "",
false);
// Check that we got a lease
ASSERT_TRUE(lease);
......@@ -345,12 +351,14 @@ TEST_F(AllocEngine6Test, allocateAddress6Nulls) {
// Allocations without subnet are not allowed
Lease6Ptr lease = engine->allocateAddress6(Subnet6Ptr(), duid_, iaid_,
IOAddress("::"), false);
IOAddress("::"),
false, false, "", false);
ASSERT_FALSE(lease);
// Allocations without DUID are not allowed either
lease = engine->allocateAddress6(subnet_, DuidPtr(), iaid_,
IOAddress("::"), false);
IOAddress("::"),
false, false, "", false);
ASSERT_FALSE(lease);
}
......@@ -438,7 +446,9 @@ TEST_F(AllocEngine6Test, smallPool6) {
subnet_->addPool(pool_);
cfg_mgr.addSubnet6(subnet_);
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress("::"),
false, false, "",
false);
// Check that we got that single lease
......@@ -485,7 +495,8 @@ TEST_F(AllocEngine6Test, outOfAddresses6) {
// There is just a single address in the pool and allocated it to someone
// else, so the allocation should fail
Lease6Ptr lease2 = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress("::"), false);
IOAddress("::"),
false, false, "", false);
EXPECT_FALSE(lease2);
}
......@@ -519,6 +530,7 @@ TEST_F(AllocEngine6Test, solicitReuseExpiredLease6) {
// CASE 1: Asking for any address
lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
false, false, "",
true);
// Check that we got that single lease
ASSERT_TRUE(lease);
......@@ -528,7 +540,9 @@ TEST_F(AllocEngine6Test, solicitReuseExpiredLease6) {
checkLease6(lease);
// CASE 2: Asking specifically for this address
lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress(addr.toText()),
lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress(addr.toText()),
false, false, "",
true);
// Check that we got that single lease
ASSERT_TRUE(lease);
......@@ -563,7 +577,8 @@ TEST_F(AllocEngine6Test, requestReuseExpiredLease6) {
// A client comes along, asking specifically for this address
lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress(addr.toText()), false);
IOAddress(addr.toText()),
false, false, "", false);
// Check that he got that single lease
ASSERT_TRUE(lease);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment