Commit 6fc0bdf0 authored by Marcin Siodelski's avatar Marcin Siodelski

[1955] Using OutputBuffer::writeUint8At to avoid OutputBuffer::clear().

parent 5496d551
...@@ -44,7 +44,7 @@ PktTransform::pack(const Option::Universe universe, ...@@ -44,7 +44,7 @@ PktTransform::pack(const Option::Universe universe,
uint8_t transid_len = (universe == Option::V6) ? 3 : 4; uint8_t transid_len = (universe == Option::V6) ? 3 : 4;
if ((transid_offset + transid_len + 1 > in_buffer.size()) || if ((transid_offset + transid_len >= in_buffer.size()) ||
(transid_offset == 0)) { (transid_offset == 0)) {
cout << "Failed to build packet: provided transaction id offset: " cout << "Failed to build packet: provided transaction id offset: "
<< transid_offset << " is out of bounds (expected 1.." << transid_offset << " is out of bounds (expected 1.."
...@@ -52,22 +52,14 @@ PktTransform::pack(const Option::Universe universe, ...@@ -52,22 +52,14 @@ PktTransform::pack(const Option::Universe universe,
return (false); return (false);
} }
// Seek to the transaction id position in output buffer.
out_buffer.clear();
out_buffer.skip(transid_offset);
try { try {
size_t offset_ptr = transid_offset;
if (universe == Option::V4) { if (universe == Option::V4) {
out_buffer.writeUint8(transid >> 24 & 0xFF); out_buffer.writeUint8At(transid >> 24 & 0xFF, offset_ptr++);
} }
out_buffer.writeUint8(transid >> 16 & 0xFF); out_buffer.writeUint8At(transid >> 16 & 0xFF, offset_ptr++);
out_buffer.writeUint8(transid >> 8 & 0xFF); out_buffer.writeUint8At(transid >> 8 & 0xFF, offset_ptr++);
out_buffer.writeUint8(transid & 0xFF); out_buffer.writeUint8At(transid & 0xFF, offset_ptr++);
// Buffer pointer is at the end of transaction id.
// We have to seek to the end of buffer so as data don't
// get truncated.
out_buffer.skip(in_buffer.size() - out_buffer.getLength());
// We already have packet template stored in output buffer // We already have packet template stored in output buffer
// but still some options have to be updated if client // but still some options have to be updated if client
...@@ -98,16 +90,15 @@ PktTransform::unpack(const Option::Universe universe, ...@@ -98,16 +90,15 @@ PktTransform::unpack(const Option::Universe universe,
return (false); return (false);
} }
if (universe == Option::V6) { // Read transaction id from the buffer.
transid = ((in_buffer[transid_offset] << 16) + // For DHCPv6 we transaction id is 3 bytes long so the high byte
(in_buffer[transid_offset + 1] << 8) + // of transid will be zero.
(in_buffer[transid_offset + 2])) OptionBufferConstIter it = in_buffer.begin() + transid_offset;
& 0xFFFFFF; transid = 0;
} else { for (int i = 0; i < transid_len; ++i, ++it) {
transid = ((in_buffer[transid_offset] << 24) + // Read next byte and shift it left to its position in
(in_buffer[transid_offset + 1] << 16) + // transid (shift by the number of bytes read so far.
(in_buffer[transid_offset + 2] << 8) + transid += *it << (transid_len - i - 1) * 8;
(in_buffer[transid_offset + 3]));
} }
try { try {
...@@ -141,14 +132,20 @@ PktTransform::packOptions(const OptionBuffer& in_buffer, ...@@ -141,14 +132,20 @@ PktTransform::packOptions(const OptionBuffer& in_buffer,
<< " is out of bounds (expected 1.." << " is out of bounds (expected 1.."
<< in_buffer.size() - option->len() << ")"); << in_buffer.size() - option->len() << ")");
} }
out_buffer.clear();
out_buffer.skip(offset);
// Replace existing option with new value. // Create temporary buffer to store option contents.
option->pack(out_buffer); util::OutputBuffer buf(option->len());
// Pack option contents into temporary buffer.
option->pack(buf);
// OutputBuffer class has nice functions that write
// data at the specified position so we can use it to
// inject contents of temporary buffer to output buffer.
const uint8_t *buf_data =
static_cast<const uint8_t*>(buf.getData());
for (int i = 0; i < buf.getLength(); ++i) {
out_buffer.writeUint8At(buf_data[i], offset + i);
}
} }
// Seek to the end of the buffer to make sure its size is correct.
out_buffer.skip(in_buffer.size() - out_buffer.getLength());
} }
catch (const Exception&) { catch (const Exception&) {
isc_throw(isc::BadValue, "failed to pack options into buffer."); isc_throw(isc::BadValue, "failed to pack options into buffer.");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment