2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-02 23:15:20 +00:00

[#1672] class fixed field order now matches class option order in kea-dhc4

src/bin/dhcp4/dhcp4_srv.cc
    Dhcpv4Srv::setFixedFields - modified to use the value for a field
    from the first class in query's list of classes that specifies
    the field.

src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
    TEST_F(Dhcpv4SrvTest, fixedFieldsInClassOrder) - new unit test
This commit is contained in:
Thomas Markwalder
2021-02-14 13:16:34 -05:00
parent d43f44fb05
commit 730888d98d
2 changed files with 198 additions and 22 deletions

View File

@@ -1678,10 +1678,12 @@ Dhcpv4Srv::buildCfgOptionList(Dhcpv4Exchange& ex) {
// Skip it
continue;
}
if (ccdef->getCfgOption()->empty()) {
// Skip classes which don't configure options
continue;
}
co_list.push_back(ccdef->getCfgOption());
}
@@ -2916,8 +2918,13 @@ Dhcpv4Srv::setFixedFields(Dhcpv4Exchange& ex) {
// Now we need to iterate over the classes assigned to the
// query packet and find corresponding class definitions for it.
// We want the first value found for each field.
IOAddress next_server("0.0.0.0");
string sname;
string filename;
size_t found_cnt = 0;
for (ClientClasses::const_iterator name = classes.cbegin();
name != classes.cend(); ++name) {
name != classes.cend() && found_cnt < 3; ++name) {
ClientClassDefPtr cl = dict->findClass(*name);
if (!cl) {
@@ -2928,31 +2935,40 @@ Dhcpv4Srv::setFixedFields(Dhcpv4Exchange& ex) {
continue;
}
IOAddress next_server = cl->getNextServer();
if (!next_server.isV4Zero()) {
response->setSiaddr(next_server);
if (next_server == IOAddress::IPV4_ZERO_ADDRESS()) {
next_server = cl->getNextServer();
if (!next_server.isV4Zero()) {
response->setSiaddr(next_server);
found_cnt++;
}
}
const string& sname = cl->getSname();
if (!sname.empty()) {
// Converting string to (const uint8_t*, size_t len) format is
// tricky. reinterpret_cast is not the most elegant solution,
// but it does avoid us making unnecessary copy. We will convert
// sname and file fields in Pkt4 to string one day and life
// will be easier.
response->setSname(reinterpret_cast<const uint8_t*>(sname.c_str()),
sname.size());
if (sname.empty()) {
sname = cl->getSname();
if (!sname.empty()) {
// Converting string to (const uint8_t*, size_t len) format is
// tricky. reinterpret_cast is not the most elegant solution,
// but it does avoid us making unnecessary copy. We will convert
// sname and file fields in Pkt4 to string one day and life
// will be easier.
response->setSname(reinterpret_cast<const uint8_t*>(sname.c_str()),
sname.size());
found_cnt++;
}
}
const string& filename = cl->getFilename();
if (!filename.empty()) {
// Converting string to (const uint8_t*, size_t len) format is
// tricky. reinterpret_cast is not the most elegant solution,
// but it does avoid us making unnecessary copy. We will convert
// sname and file fields in Pkt4 to string one day and life
// will be easier.
response->setFile(reinterpret_cast<const uint8_t*>(filename.c_str()),
filename.size());
if (filename.empty()) {
filename = cl->getFilename();
if (!filename.empty()) {
// Converting string to (const uint8_t*, size_t len) format is
// tricky. reinterpret_cast is not the most elegant solution,
// but it does avoid us making unnecessary copy. We will convert
// sname and file fields in Pkt4 to string one day and life
// will be easier.
response->setFile(reinterpret_cast<const uint8_t*>(filename.c_str()),
filename.size());
found_cnt++;
}
}
}
}