Skip to content

Commit 799a4cb

Browse files
committed
[#3440] Moved to a single vector
1 parent fdbcd4e commit 799a4cb

File tree

2 files changed

+13
-31
lines changed

2 files changed

+13
-31
lines changed

src/lib/dhcp/libdhcp++.cc

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -485,16 +485,8 @@ LibDHCP::unpackOptions4(const OptionBuffer& buf, const string& option_space,
485485
// The buffer being read comprises a set of options, each starting with
486486
// a one-byte type code and a one-byte length field.
487487

488-
// Track seen options in a first pass. We use 2 different data structures
489-
// (seen and counts) because this code is in the critical path and
490-
// having more than one instance of an option is a very rare case.
491-
492-
// Record if an option was already seen using the most efficient
493-
// data structure for this goal.
494-
vector<bool> seen(256, false);
495-
// Handle the very rare case where an option is more than once in the
496-
// input buffer, in other / common case it stays empty.
497-
unordered_map<uint8_t, size_t> counts;
488+
// Track seen options in a first pass.
489+
vector<uint32_t> count(256, 0);
498490
while (offset < buf.size()) {
499491
// Get the option type
500492
uint8_t opt_type = buf[offset++];
@@ -533,24 +525,13 @@ LibDHCP::unpackOptions4(const OptionBuffer& buf, const string& option_space,
533525

534526
offset += opt_len;
535527

536-
// Mark as seen.
537-
if (!seen[opt_type]) {
538-
seen[opt_type] = true;
539-
continue;
540-
}
541-
542-
// Already seen.
543-
size_t& count = counts[opt_type];
544-
if (count == 0) {
545-
// Default value for size_t is 0 but this option was already seen.
546-
count = 2;
547-
} else {
548-
++count;
549-
}
528+
// Increment count.
529+
count[opt_type] += 1;
550530
}
551531

552532
// Fusing option buffers.
553533
unordered_map<uint8_t, OptionBuffer> fused;
534+
unordered_map<uint8_t, uint32_t> seen;
554535

555536
// Second pass.
556537
offset = 0;
@@ -612,16 +593,17 @@ LibDHCP::unpackOptions4(const OptionBuffer& buf, const string& option_space,
612593
offset += opt_len;
613594

614595
// Concatenate multiple instance of an option.
615-
if (!counts.empty() && (counts.count(opt_type) > 0)) {
616-
size_t count = counts[opt_type];
596+
uint32_t opt_count = count[opt_type];
597+
if (opt_count > 1) {
617598
OptionBuffer& previous = fused[opt_type];
618599
previous.insert(previous.end(), obuf.begin(), obuf.end());
619-
if (count <= 1) {
600+
uint32_t& already_seen = seen[opt_type];
601+
++already_seen;
602+
if (already_seen != opt_count) {
603+
continue;
604+
} else {
620605
// last occurrence: build the option.
621606
obuf = previous;
622-
} else {
623-
counts[opt_type] = count - 1;
624-
continue;
625607
}
626608
}
627609

src/lib/dhcp/tests/libdhcp++_unittest.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,7 @@ TEST_F(LibDhcpTest, splitOptionWithSuboptionWhichOverflow) {
13581358
RAI_OPTION_SUBSCRIBER_ID,
13591359
buf_in.begin(),
13601360
buf_in.end()));
1361-
ASSERT_TRUE(subscriber_id_opt);
1361+
ASSERT_TRUE(subscriber_id_opt);
13621362
rai->addOption(subscriber_id_opt);
13631363

13641364
splitOptionWithSuboptionWhichOverflow(rai, circuit_id_opt, remote_id_opt, subscriber_id_opt);

0 commit comments

Comments
 (0)