Skip to content
GitLab
Menu
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
985d66cb
Commit
985d66cb
authored
Feb 24, 2014
by
Thomas Markwalder
Browse files
[master] Merge branch 'trac3340'
Corrects DHO_HOST_OPTION bug in b10-dhcp4.
parents
78f1d79b
5d8fd663
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/dhcp4_srv.cc
View file @
985d66cb
...
...
@@ -703,12 +703,11 @@ Dhcpv4Srv::processClientName(const Pkt4Ptr& query, Pkt4Ptr& answer) {
processClientFqdnOption
(
fqdn
,
answer
);
}
else
{
Option
Custom
Ptr
hostname
=
boost
::
dynamic_pointer_cast
<
Option
Custom
>
Option
String
Ptr
hostname
=
boost
::
dynamic_pointer_cast
<
Option
String
>
(
query
->
getOption
(
DHO_HOST_NAME
));
if
(
hostname
)
{
processHostnameOption
(
hostname
,
answer
);
}
}
}
catch
(
const
Exception
&
ex
)
{
// In some rare cases it is possible that the client's name processing
...
...
@@ -761,7 +760,7 @@ Dhcpv4Srv::processClientFqdnOption(const Option4ClientFqdnPtr& fqdn,
}
void
Dhcpv4Srv
::
processHostnameOption
(
const
Option
Custom
Ptr
&
opt_hostname
,
Dhcpv4Srv
::
processHostnameOption
(
const
Option
String
Ptr
&
opt_hostname
,
Pkt4Ptr
&
answer
)
{
// Fetch D2 configuration.
D2ClientMgr
&
d2_mgr
=
CfgMgr
::
instance
().
getD2ClientMgr
();
...
...
@@ -771,7 +770,7 @@ Dhcpv4Srv::processHostnameOption(const OptionCustomPtr& opt_hostname,
return
;
}
std
::
string
hostname
=
isc
::
util
::
str
::
trim
(
opt_hostname
->
readString
());
std
::
string
hostname
=
isc
::
util
::
str
::
trim
(
opt_hostname
->
getValue
());
unsigned
int
label_count
=
OptionDataTypeUtil
::
getLabelCount
(
hostname
);
// The hostname option sent by the client should be at least 1 octet long.
// If it isn't we ignore this option. (Per RFC 2131, section 3.14)
...
...
@@ -785,7 +784,7 @@ Dhcpv4Srv::processHostnameOption(const OptionCustomPtr& opt_hostname,
// possible that we will use the hostname option provided by the client
// to perform the DNS update and we will send the same option to him to
// indicate that we accepted this hostname.
Option
Custom
Ptr
opt_hostname_resp
(
new
Option
Custom
(
*
opt_hostname
));
Option
String
Ptr
opt_hostname_resp
(
new
Option
String
(
*
opt_hostname
));
// The hostname option may be unqualified or fully qualified. The lab_count
// holds the number of labels for the name. The number of 1 means that
...
...
@@ -802,12 +801,14 @@ Dhcpv4Srv::processHostnameOption(const OptionCustomPtr& opt_hostname,
/// conversion if needed and possible.
if
((
d2_mgr
.
getD2ClientConfig
()
->
getReplaceClientName
())
||
(
label_count
<
2
))
{
opt_hostname_resp
->
writeString
(
""
);
// Set to root domain to signal later on that we should replace it.
// DHO_HOST_NAME is a string option which cannot be empty.
opt_hostname_resp
->
setValue
(
"."
);
}
else
if
(
label_count
==
2
)
{
// If there are two labels, it means that the client has specified
// the unqualified name. We have to concatenate the unqalified name
// with the domain name.
opt_hostname_resp
->
writeString
(
d2_mgr
.
qualifyName
(
hostname
));
opt_hostname_resp
->
setValue
(
d2_mgr
.
qualifyName
(
hostname
));
}
answer
->
addOption
(
opt_hostname_resp
);
...
...
@@ -958,7 +959,7 @@ Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
std
::
string
hostname
;
bool
fqdn_fwd
=
false
;
bool
fqdn_rev
=
false
;
Option
Custom
Ptr
opt_hostname
;
Option
String
Ptr
opt_hostname
;
Option4ClientFqdnPtr
fqdn
=
boost
::
dynamic_pointer_cast
<
Option4ClientFqdn
>
(
answer
->
getOption
(
DHO_FQDN
));
if
(
fqdn
)
{
...
...
@@ -966,10 +967,17 @@ Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
fqdn_fwd
=
fqdn
->
getFlag
(
Option4ClientFqdn
::
FLAG_S
);
fqdn_rev
=
!
fqdn
->
getFlag
(
Option4ClientFqdn
::
FLAG_N
);
}
else
{
opt_hostname
=
boost
::
dynamic_pointer_cast
<
Option
Custom
>
opt_hostname
=
boost
::
dynamic_pointer_cast
<
Option
String
>
(
answer
->
getOption
(
DHO_HOST_NAME
));
if
(
opt_hostname
)
{
hostname
=
opt_hostname
->
readString
();
hostname
=
opt_hostname
->
getValue
();
// DHO_HOST_NAME is string option which cannot be blank,
// we use "." to know we should replace it with a fully
// generated name. The local string variable needs to be
// blank in logic below.
if
(
hostname
==
"."
)
{
hostname
=
""
;
}
/// @todo It could be configurable what sort of updates the
/// server is doing when Hostname option was sent.
fqdn_fwd
=
true
;
...
...
@@ -1023,7 +1031,7 @@ Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
fqdn
->
setDomainName
(
lease
->
hostname_
,
Option4ClientFqdn
::
FULL
);
}
else
if
(
opt_hostname
)
{
opt_hostname
->
writeString
(
lease
->
hostname_
);
opt_hostname
->
setValue
(
lease
->
hostname_
);
}
}
catch
(
const
Exception
&
ex
)
{
...
...
src/bin/dhcp4/dhcp4_srv.h
View file @
985d66cb
...
...
@@ -18,6 +18,7 @@
#include <dhcp/dhcp4.h>
#include <dhcp/pkt4.h>
#include <dhcp/option.h>
#include <dhcp/option_string.h>
#include <dhcp/option4_client_fqdn.h>
#include <dhcp/option_custom.h>
#include <dhcp_ddns/ncr_msg.h>
...
...
@@ -460,10 +461,10 @@ private:
/// prepare the Hostname option to be sent back to the client in the
/// server's response.
///
/// @param opt_hostname An @c Option
Custom
object encapsulating the Hostname
/// @param opt_hostname An @c Option
String
object encapsulating the Hostname
/// %Option.
/// @param [out] answer A response message to be sent to a client.
void
processHostnameOption
(
const
Option
Custom
Ptr
&
opt_hostname
,
void
processHostnameOption
(
const
Option
String
Ptr
&
opt_hostname
,
Pkt4Ptr
&
answer
);
protected:
...
...
src/bin/dhcp4/tests/fqdn_unittest.cc
View file @
985d66cb
...
...
@@ -118,11 +118,11 @@ public:
}
// Create an instance of the Hostname option.
Option
Custom
Ptr
Option
String
Ptr
createHostname
(
const
std
::
string
&
hostname
)
{
Option
Definition
def
(
"hostname"
,
DHO_HOST_NAME
,
"string"
);
OptionCustomPtr
opt_hostname
(
new
OptionCustom
(
def
,
Option
::
V4
));
opt_hostname
->
writeString
(
hostname
);
Option
StringPtr
opt_hostname
(
new
OptionString
(
Option
::
V4
,
DHO_HOST_NAME
,
hostname
)
)
;
return
(
opt_hostname
);
}
...
...
@@ -147,9 +147,9 @@ public:
}
// get the Hostname option from the given message.
Option
Custom
Ptr
getHostnameOption
(
const
Pkt4Ptr
&
pkt
)
{
Option
String
Ptr
getHostnameOption
(
const
Pkt4Ptr
&
pkt
)
{
return
(
boost
::
dynamic_pointer_cast
<
Option
Custom
>
(
pkt
->
getOption
(
DHO_HOST_NAME
)));
Option
String
>
(
pkt
->
getOption
(
DHO_HOST_NAME
)));
}
// Create a message holding DHCPv4 Client FQDN Option.
...
...
@@ -264,7 +264,7 @@ public:
// the hostname option which would be sent to the client. It will
// throw NULL pointer if the hostname option is not to be included
// in the response.
Option
Custom
Ptr
processHostname
(
const
Pkt4Ptr
&
query
)
{
Option
String
Ptr
processHostname
(
const
Pkt4Ptr
&
query
)
{
if
(
!
getHostnameOption
(
query
))
{
ADD_FAILURE
()
<<
"Hostname option not carried in the query"
;
}
...
...
@@ -279,7 +279,7 @@ public:
}
srv_
->
processClientName
(
query
,
answer
);
Option
Custom
Ptr
hostname
=
getHostnameOption
(
answer
);
Option
String
Ptr
hostname
=
getHostnameOption
(
answer
);
return
(
hostname
);
}
...
...
@@ -571,29 +571,20 @@ TEST_F(NameDhcpv4SrvTest, serverUpdateHostname) {
Pkt4Ptr
query
;
ASSERT_NO_THROW
(
query
=
generatePktWithHostname
(
DHCPREQUEST
,
"myhost.example.com."
));
Option
Custom
Ptr
hostname
;
Option
String
Ptr
hostname
;
ASSERT_NO_THROW
(
hostname
=
processHostname
(
query
));
ASSERT_TRUE
(
hostname
);
EXPECT_EQ
(
"myhost.example.com."
,
hostname
->
readString
());
EXPECT_EQ
(
"myhost.example.com."
,
hostname
->
getValue
());
}
// Test that the server skips processing of the empty Hostname option.
TEST_F
(
NameDhcpv4SrvTest
,
serverUpdateEmptyHostname
)
{
Pkt4Ptr
query
;
ASSERT_NO_THROW
(
query
=
generatePktWithHostname
(
DHCPREQUEST
,
""
));
OptionCustomPtr
hostname
;
ASSERT_NO_THROW
(
hostname
=
processHostname
(
query
));
EXPECT_FALSE
(
hostname
);
}
// Test that the server skips processing of a wrong Hostname option.
TEST_F
(
NameDhcpv4SrvTest
,
serverUpdateWrongHostname
)
{
Pkt4Ptr
query
;
ASSERT_NO_THROW
(
query
=
generatePktWithHostname
(
DHCPREQUEST
,
"abc..example.com"
));
Option
Custom
Ptr
hostname
;
Option
String
Ptr
hostname
;
ASSERT_NO_THROW
(
hostname
=
processHostname
(
query
));
EXPECT_FALSE
(
hostname
);
}
...
...
@@ -620,11 +611,11 @@ TEST_F(NameDhcpv4SrvTest, serverUpdateForwardPartialNameFqdn) {
TEST_F
(
NameDhcpv4SrvTest
,
serverUpdateUnqualifiedHostname
)
{
Pkt4Ptr
query
;
ASSERT_NO_THROW
(
query
=
generatePktWithHostname
(
DHCPREQUEST
,
"myhost"
));
Option
Custom
Ptr
hostname
;
Option
String
Ptr
hostname
;
ASSERT_NO_THROW
(
hostname
=
processHostname
(
query
));
ASSERT_TRUE
(
hostname
);
EXPECT_EQ
(
"myhost.example.com."
,
hostname
->
readString
());
EXPECT_EQ
(
"myhost.example.com."
,
hostname
->
getValue
());
}
...
...
@@ -818,7 +809,7 @@ TEST_F(NameDhcpv4SrvTest, processRequestEmptyDomainNameDisabled) {
// Test that server generates client's hostname from the IP address assigned
// to it when Hostname option carries the top level domain-name.
TEST_F
(
NameDhcpv4SrvTest
,
processRequest
Empty
Hostname
)
{
TEST_F
(
NameDhcpv4SrvTest
,
processRequest
TopLevel
Hostname
)
{
IfaceMgrTestConfig
test_config
(
true
);
IfaceMgr
::
instance
().
openSockets4
();
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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