Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
1d58f76d
Commit
1d58f76d
authored
Sep 09, 2013
by
Marcin Siodelski
Browse files
[3035] Basic implementation to process DHCP4 Hostname option.
parent
c8a1da13
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/dhcp4_srv.cc
View file @
1d58f76d
...
...
@@ -18,7 +18,6 @@
#include
<dhcp/hwaddr.h>
#include
<dhcp/iface_mgr.h>
#include
<dhcp/option4_addrlst.h>
#include
<dhcp/option_custom.h>
#include
<dhcp/option_int.h>
#include
<dhcp/option_int_array.h>
#include
<dhcp/pkt4.h>
...
...
@@ -752,7 +751,7 @@ Dhcpv4Srv::processClientName(const Pkt4Ptr& query, Pkt4Ptr& answer) {
OptionCustomPtr
hostname
=
boost
::
dynamic_pointer_cast
<
OptionCustom
>
(
query
->
getOption
(
DHO_HOST_NAME
));
if
(
hostname
)
{
processHostnameOption
(
query
,
answer
);
processHostnameOption
(
hostname
,
answer
);
}
}
...
...
@@ -842,7 +841,14 @@ Dhcpv4Srv::processClientFqdnOption(const Option4ClientFqdnPtr& fqdn,
}
void
Dhcpv4Srv
::
processHostnameOption
(
const
Pkt4Ptr
&
,
Pkt4Ptr
&
)
{
Dhcpv4Srv
::
processHostnameOption
(
const
OptionCustomPtr
&
opt_hostname
,
Pkt4Ptr
&
answer
)
{
if
(
!
FQDN_ENABLE_UPDATE
)
{
return
;
}
std
::
string
hostname
=
opt_hostname
->
readString
();
answer
->
addOption
(
OptionCustomPtr
(
new
OptionCustom
(
*
opt_hostname
)));
}
void
...
...
src/bin/dhcp4/dhcp4_srv.h
View file @
1d58f76d
...
...
@@ -19,6 +19,7 @@
#include
<dhcp/pkt4.h>
#include
<dhcp/option.h>
#include
<dhcp/option4_client_fqdn.h>
#include
<dhcp/option_custom.h>
#include
<dhcp_ddns/ncr_msg.h>
#include
<dhcpsrv/subnet.h>
#include
<dhcpsrv/alloc_engine.h>
...
...
@@ -306,9 +307,11 @@ private:
/// @brief Process Hostname %Option sent by a client.
///
/// @param query A DISCOVER or REQUEST message from a cient.
/// @param opt_hostname An @c OptionCustom object encapsulating the Hostname
/// %Option.
/// @param [out] answer A response message to be sent to a client.
void
processHostnameOption
(
const
Pkt4Ptr
&
query
,
Pkt4Ptr
&
answer
);
void
processHostnameOption
(
const
OptionCustomPtr
&
opt_hostname
,
Pkt4Ptr
&
answer
);
protected:
...
...
src/bin/dhcp4/tests/fqdn_unittest.cc
View file @
1d58f76d
...
...
@@ -28,12 +28,12 @@ using namespace isc::dhcp_ddns;
using
namespace
isc
::
test
;
namespace
{
class
Fqdn
Dhcpv4SrvTest
:
public
Dhcpv4SrvTest
{
class
Name
Dhcpv4SrvTest
:
public
Dhcpv4SrvTest
{
public:
Fqdn
Dhcpv4SrvTest
()
:
Dhcpv4SrvTest
()
{
Name
Dhcpv4SrvTest
()
:
Dhcpv4SrvTest
()
{
srv_
=
new
NakedDhcpv4Srv
(
0
);
}
virtual
~
Fqdn
Dhcpv4SrvTest
()
{
virtual
~
Name
Dhcpv4SrvTest
()
{
delete
srv_
;
}
...
...
@@ -65,13 +65,29 @@ public:
RCODE_CLIENT
(),
fqdn_name
,
fqdn_type
)));
}
// Create an instance of the Hostname option.
OptionCustomPtr
createHostname
(
const
std
::
string
&
hostname
)
{
OptionDefinition
def
(
"hostname"
,
DHO_HOST_NAME
,
"string"
);
OptionCustomPtr
opt_hostname
(
new
OptionCustom
(
def
,
Option
::
V4
));
opt_hostname
->
writeString
(
hostname
);
return
(
opt_hostname
);
}
// Get the Client FQDN Option from the given message.
Option4ClientFqdnPtr
getClientFqdnOption
(
const
Pkt4Ptr
&
pkt
)
{
return
(
boost
::
dynamic_pointer_cast
<
Option4ClientFqdn
>
(
pkt
->
getOption
(
DHO_FQDN
)));
}
// get the Hostname option from the given message.
OptionCustomPtr
getHostnameOption
(
const
Pkt4Ptr
&
pkt
)
{
return
(
boost
::
dynamic_pointer_cast
<
OptionCustom
>
(
pkt
->
getOption
(
DHO_HOST_NAME
)));
}
// Create a message holding DHCPv4 Client FQDN Option.
Pkt4Ptr
generatePktWithFqdn
(
const
uint8_t
msg_type
,
const
uint8_t
fqdn_flags
,
...
...
@@ -109,6 +125,30 @@ public:
return
(
pkt
);
}
// Create a message holding a Hostname option.
Pkt4Ptr
generatePktWithHostname
(
const
uint8_t
msg_type
,
const
std
::
string
&
hostname
)
{
Pkt4Ptr
pkt
=
Pkt4Ptr
(
new
Pkt4
(
msg_type
,
1234
));
pkt
->
setRemoteAddr
(
IOAddress
(
"192.0.2.3"
));
// For DISCOVER we don't include server id, because client broadcasts
// the message to all servers.
if
(
msg_type
!=
DHCPDISCOVER
)
{
pkt
->
addOption
(
srv_
->
getServerID
());
}
pkt
->
addOption
(
generateClientId
());
// Create Client FQDN Option with the specified flags and
// domain-name.
pkt
->
addOption
(
createHostname
(
hostname
));
return
(
pkt
);
}
// Test that server generates the appropriate FQDN option in response to
// client's FQDN option.
...
...
@@ -144,6 +184,30 @@ public:
}
// Test that the Hostname option is returned in the server's response
// to the message holding Hostname option sent by a client.
void
testProcessHostname
(
const
Pkt4Ptr
&
query
,
const
std
::
string
&
exp_hostname
)
{
ASSERT_TRUE
(
getHostnameOption
(
query
));
Pkt4Ptr
answer
;
if
(
query
->
getType
()
==
DHCPDISCOVER
)
{
answer
.
reset
(
new
Pkt4
(
DHCPOFFER
,
1234
));
}
else
{
answer
.
reset
(
new
Pkt4
(
DHCPACK
,
1234
));
}
ASSERT_NO_THROW
(
srv_
->
processClientName
(
query
,
answer
));
OptionCustomPtr
hostname
=
getHostnameOption
(
answer
);
ASSERT_TRUE
(
hostname
);
EXPECT_EQ
(
exp_hostname
,
hostname
->
readString
());
}
// Test that the client message holding an FQDN is processed and the
// NameChangeRequests are generated.
void
testProcessMessageWithFqdn
(
const
uint8_t
msg_type
,
...
...
@@ -202,7 +266,7 @@ public:
// Test that the exception is thrown if lease pointer specified as the argument
// of computeDhcid function is NULL.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
dhcidNullLease
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
dhcidNullLease
)
{
Lease4Ptr
lease
;
EXPECT_THROW
(
srv_
->
computeDhcid
(
lease
),
isc
::
dhcp
::
DhcidComputeError
);
...
...
@@ -210,7 +274,7 @@ TEST_F(FqdnDhcpv4SrvTest, dhcidNullLease) {
// Test that the appropriate exception is thrown if the lease object used
// to compute DHCID comprises wrong hostname.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
dhcidWrongHostname
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
dhcidWrongHostname
)
{
// First, make sure that the lease with the correct hostname is accepted.
Lease4Ptr
lease
=
createLease
(
IOAddress
(
"192.0.2.3"
),
"myhost.example.com."
,
true
,
true
);
...
...
@@ -227,7 +291,7 @@ TEST_F(FqdnDhcpv4SrvTest, dhcidWrongHostname) {
// Test that the DHCID is computed correctly, when the lease holds
// correct hostname and non-NULL client id.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
dhcidComputeFromClientId
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
dhcidComputeFromClientId
)
{
Lease4Ptr
lease
=
createLease
(
IOAddress
(
"192.0.2.3"
),
"myhost.example.com."
,
true
,
true
);
...
...
@@ -242,7 +306,7 @@ TEST_F(FqdnDhcpv4SrvTest, dhcidComputeFromClientId) {
// Test that the DHCID is computed correctly, when the lease holds correct
// hostname and NULL client id.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
dhcidComputeFromHWAddr
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
dhcidComputeFromHWAddr
)
{
Lease4Ptr
lease
=
createLease
(
IOAddress
(
"192.0.2.3"
),
"myhost.example.com."
,
true
,
true
);
...
...
@@ -260,7 +324,7 @@ TEST_F(FqdnDhcpv4SrvTest, dhcidComputeFromHWAddr) {
// Test that server confirms to perform the forward and reverse DNS update,
// when client asks for it.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
serverUpdateForward
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
serverUpdateForward
Fqdn
)
{
Pkt4Ptr
query
=
generatePktWithFqdn
(
DHCPREQUEST
,
Option4ClientFqdn
::
FLAG_E
|
Option4ClientFqdn
::
FLAG_S
,
...
...
@@ -274,9 +338,17 @@ TEST_F(FqdnDhcpv4SrvTest, serverUpdateForward) {
}
// Test that server processes the Hostname option sent by a client and
// responds with the Hostname option to confirm that the
TEST_F
(
NameDhcpv4SrvTest
,
serverUpdateHostname
)
{
Pkt4Ptr
query
=
generatePktWithHostname
(
DHCPREQUEST
,
"myhost.example.com."
);
testProcessHostname
(
query
,
"myhost.example.com."
);
}
// Test that server generates the fully qualified domain name for the client
// if client supplies the partial name.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
serverUpdateForwardPartialName
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
serverUpdateForwardPartialName
Fqdn
)
{
Pkt4Ptr
query
=
generatePktWithFqdn
(
DHCPREQUEST
,
Option4ClientFqdn
::
FLAG_E
|
Option4ClientFqdn
::
FLAG_S
,
...
...
@@ -292,7 +364,7 @@ TEST_F(FqdnDhcpv4SrvTest, serverUpdateForwardPartialName) {
// Test that server generates the fully qualified domain name for the client
// if clietn supplies empty domain name.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
serverUpdateForwardNoName
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
serverUpdateForwardNoName
Fqdn
)
{
Pkt4Ptr
query
=
generatePktWithFqdn
(
DHCPREQUEST
,
Option4ClientFqdn
::
FLAG_E
|
Option4ClientFqdn
::
FLAG_S
,
...
...
@@ -307,7 +379,7 @@ TEST_F(FqdnDhcpv4SrvTest, serverUpdateForwardNoName) {
}
// Test server's response when client requests no DNS update.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
noUpdate
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
noUpdate
Fqdn
)
{
Pkt4Ptr
query
=
generatePktWithFqdn
(
DHCPREQUEST
,
Option4ClientFqdn
::
FLAG_E
|
Option4ClientFqdn
::
FLAG_N
,
...
...
@@ -321,7 +393,7 @@ TEST_F(FqdnDhcpv4SrvTest, noUpdate) {
// Test that server does not accept delegation of the forward DNS update
// to a client.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
clientUpdateNotAllowed
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
clientUpdateNotAllowed
Fqdn
)
{
Pkt4Ptr
query
=
generatePktWithFqdn
(
DHCPREQUEST
,
Option4ClientFqdn
::
FLAG_E
,
"myhost.example.com."
,
...
...
@@ -336,7 +408,7 @@ TEST_F(FqdnDhcpv4SrvTest, clientUpdateNotAllowed) {
// Test that exactly one NameChangeRequest is generated when the new lease
// has been acquired (old lease is NULL).
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
createNameChangeRequestsNewLease
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
createNameChangeRequestsNewLease
)
{
Lease4Ptr
lease
=
createLease
(
IOAddress
(
"192.0.2.3"
),
"myhost.example.com."
,
true
,
true
);
Lease4Ptr
old_lease
;
...
...
@@ -353,7 +425,7 @@ TEST_F(FqdnDhcpv4SrvTest, createNameChangeRequestsNewLease) {
// Test that no NameChangeRequest is generated when a lease is renewed and
// the FQDN data hasn't changed.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
createNameChangeRequestsRenewNoChange
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
createNameChangeRequestsRenewNoChange
)
{
Lease4Ptr
lease
=
createLease
(
IOAddress
(
"192.0.2.3"
),
"myhost.example.com."
,
true
,
true
);
Lease4Ptr
old_lease
=
createLease
(
IOAddress
(
"192.0.2.3"
),
...
...
@@ -366,7 +438,7 @@ TEST_F(FqdnDhcpv4SrvTest, createNameChangeRequestsRenewNoChange) {
// Test that no NameChangeRequest is generated when forward and reverse
// DNS update flags are not set in the lease.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
createNameChangeRequestsNoUpdate
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
createNameChangeRequestsNoUpdate
)
{
Lease4Ptr
lease1
=
createLease
(
IOAddress
(
"192.0.2.3"
),
"lease1.example.com."
,
true
,
true
);
...
...
@@ -392,7 +464,7 @@ TEST_F(FqdnDhcpv4SrvTest, createNameChangeRequestsNoUpdate) {
// Test that two NameChangeRequests are generated when the lease is being
// renewed and the new lease has updated FQDN data.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
createNameChangeRequestsRenew
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
createNameChangeRequestsRenew
)
{
Lease4Ptr
lease1
=
createLease
(
IOAddress
(
"192.0.2.3"
),
"lease1.example.com."
,
true
,
true
);
...
...
@@ -419,7 +491,7 @@ TEST_F(FqdnDhcpv4SrvTest, createNameChangeRequestsRenew) {
// This test verifies that exception is thrown when leases passed to the
// createNameChangeRequests function do not match, i.e. they comprise
// different IP addresses, client ids etc.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
createNameChangeRequestsLeaseMismatch
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
createNameChangeRequestsLeaseMismatch
)
{
Lease4Ptr
lease1
=
createLease
(
IOAddress
(
"192.0.2.3"
),
"lease1.example.com."
,
true
,
true
);
...
...
@@ -432,7 +504,7 @@ TEST_F(FqdnDhcpv4SrvTest, createNameChangeRequestsLeaseMismatch) {
// Test that the OFFER message generated as a result of the DISCOVER message
// processing will not result in generation of the NameChangeRequests.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
processDiscover
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
processDiscover
)
{
Pkt4Ptr
req
=
generatePktWithFqdn
(
DHCPDISCOVER
,
Option4ClientFqdn
::
FLAG_S
|
Option4ClientFqdn
::
FLAG_E
,
"myhost.example.com."
,
...
...
@@ -450,7 +522,7 @@ TEST_F(FqdnDhcpv4SrvTest, processDiscover) {
// a different domain-name. Server should use existing lease for the second
// request but modify the DNS entries for the lease according to the contents
// of the FQDN sent in the second request.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
processTwoRequests
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
processTwoRequests
)
{
Pkt4Ptr
req1
=
generatePktWithFqdn
(
DHCPREQUEST
,
Option4ClientFqdn
::
FLAG_S
|
Option4ClientFqdn
::
FLAG_E
,
"myhost.example.com."
,
...
...
@@ -501,7 +573,7 @@ TEST_F(FqdnDhcpv4SrvTest, processTwoRequests) {
// Test that when the Release message is sent for the previously acquired
// lease, then server genenerates a NameChangeRequest to remove the entries
// corresponding to the lease being released.
TEST_F
(
Fqdn
Dhcpv4SrvTest
,
processRequestRelease
)
{
TEST_F
(
Name
Dhcpv4SrvTest
,
processRequestRelease
)
{
Pkt4Ptr
req
=
generatePktWithFqdn
(
DHCPREQUEST
,
Option4ClientFqdn
::
FLAG_S
|
Option4ClientFqdn
::
FLAG_E
,
"myhost.example.com."
,
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment