uint32_t used) {
bool result = false;
// We need to loop until all options have been split.
- for (;;) {
+ uint32_t tries = 0;
+ for (;; tries++) {
+ // Let's not do this forever if there is a bug hiding here somewhere...
+ // 65535 times should be enough for any packet load...
+ if (tries == std::numeric_limits<uint16_t>::max()) {
+ isc_throw(BadValue, "packet split failed after trying "
+ << tries << " times.");
+ }
bool found = false;
// Make a copy of the options so we can safely iterate over the
// old container.
OptionCollection copy = options;
// Iterate over all options in the container.
for (auto const& option : options) {
- OptionPtr candidate = option.second->clone();
+ OptionPtr candidate = option.second;
OptionCollection& sub_options = candidate->getMutableOptions();
// Split suboptions recursively, if any.
OptionCollection distinct_options;
size_t count = options.size();
ASSERT_NE(0, count);
ASSERT_EQ(option, pkt->getOption(DHO_BOOT_FILE_NAME));
+ std::string expected = pkt->toText();
+ pkt->pack();
+ auto buf = pkt->getBuffer();
{
ScopedPkt4OptionsCopy oc(*pkt);
- ASSERT_EQ(pkt->options_, options);
+ ASSERT_NE(pkt->options_, options);
+ ASSERT_NE(option, pkt->getOption(DHO_BOOT_FILE_NAME));
+ pkt->pack();
+ ASSERT_EQ(buf.getLength(), pkt->getBuffer().getLength());
+ for (size_t index = 0; index < buf.getLength(); ++index) {
+ ASSERT_EQ(buf[index], pkt->getBuffer()[index]);
+ }
+ ASSERT_EQ(expected, pkt->toText());
pkt->delOption(DHO_BOOT_FILE_NAME);
ASSERT_EQ(pkt->options_.size(), count - 1);
ASSERT_FALSE(pkt->getOption(DHO_BOOT_FILE_NAME));
{
try {
ScopedPkt4OptionsCopy oc(*pkt);
- ASSERT_EQ(pkt->options_, options);
+ ASSERT_NE(pkt->options_, options);
+ ASSERT_NE(option, pkt->getOption(DHO_BOOT_FILE_NAME));
+ pkt->pack();
+ ASSERT_EQ(buf.getLength(), pkt->getBuffer().getLength());
+ for (size_t index = 0; index < buf.getLength(); ++index) {
+ ASSERT_EQ(buf[index], pkt->getBuffer()[index]);
+ }
+ ASSERT_EQ(expected, pkt->toText());
pkt->delOption(DHO_BOOT_FILE_NAME);
ASSERT_EQ(pkt->options_.size(), count - 1);
ASSERT_FALSE(pkt->getOption(DHO_BOOT_FILE_NAME));
size_t count = options.size();
ASSERT_NE(0, count);
ASSERT_EQ(option, pkt->getOption(D6O_BOOTFILE_URL));
+ std::string expected = pkt->toText();
+ pkt->pack();
+ auto buf = pkt->getBuffer();
{
ScopedPkt6OptionsCopy oc(*pkt);
- ASSERT_EQ(pkt->options_, options);
+ ASSERT_NE(pkt->options_, options);
+ ASSERT_NE(option, pkt->getOption(D6O_BOOTFILE_URL));
+ pkt->pack();
+ ASSERT_EQ(buf.getLength(), pkt->getBuffer().getLength());
+ for (size_t index = 0; index < buf.getLength(); ++index) {
+ ASSERT_EQ(buf[index], pkt->getBuffer()[index]);
+ }
+ ASSERT_EQ(expected, pkt->toText());
pkt->delOption(D6O_BOOTFILE_URL);
ASSERT_EQ(pkt->options_.size(), count - 1);
ASSERT_FALSE(pkt->getOption(D6O_BOOTFILE_URL));
{
try {
ScopedPkt6OptionsCopy oc(*pkt);
- ASSERT_EQ(pkt->options_, options);
+ ASSERT_NE(pkt->options_, options);
+ ASSERT_NE(option, pkt->getOption(D6O_BOOTFILE_URL));
+ pkt->pack();
+ ASSERT_EQ(buf.getLength(), pkt->getBuffer().getLength());
+ for (size_t index = 0; index < buf.getLength(); ++index) {
+ ASSERT_EQ(buf[index], pkt->getBuffer()[index]);
+ }
+ ASSERT_EQ(expected, pkt->toText());
pkt->delOption(D6O_BOOTFILE_URL);
ASSERT_EQ(pkt->options_.size(), count - 1);
ASSERT_FALSE(pkt->getOption(D6O_BOOTFILE_URL));
{
ScopedSubOptionsCopy oc(initial);
ASSERT_EQ(initial->getOptions(), options);
+ ASSERT_EQ(option, initial->getOption(DHO_BOOT_FILE_NAME));
initial->delOption(DHO_BOOT_FILE_NAME);
ASSERT_EQ(initial->getOptions().size(), count - 1);
ASSERT_FALSE(initial->getOption(DHO_BOOT_FILE_NAME));
try {
ScopedSubOptionsCopy oc(initial);
ASSERT_EQ(initial->getOptions(), options);
+ ASSERT_EQ(option, initial->getOption(DHO_BOOT_FILE_NAME));
initial->delOption(DHO_BOOT_FILE_NAME);
ASSERT_EQ(initial->getOptions().size(), count - 1);
ASSERT_FALSE(initial->getOption(DHO_BOOT_FILE_NAME));