Commit 0ee00c5b authored by Shawn Routhier's avatar Shawn Routhier
Browse files

[master] Include the raw data from a fully encapsualted option in the cache

parent f2e70402
......@@ -54,6 +54,12 @@ by Eric Young (eay@cryptsoft.com).
Changes since 4.3.0 (new features)
- Insert the raw data from a fully encapsualted option into the option cache.
This allows "exists" to check for the option if any sub options exist. It
also adds the raw data to the environment variables supplied to the client
script.
[ISC-Bugs #39863]
Changes since 4.3.0 (bug fixes)
- Tidy up several small tickets.
......
......@@ -187,80 +187,84 @@ int parse_option_buffer (options, buffer, length, universe)
return 0;
}
/* If the option contains an encapsulation, parse it. If
the parse fails, or the option isn't an encapsulation (by
far the most common case), or the option isn't entirely
an encapsulation, keep the raw data as well. */
if (!(option &&
(option->format[0] == 'e' ||
option->format[0] == 'E') &&
(parse_encapsulated_suboptions(options, option,
bp->data + offset, len,
universe, NULL)))) {
op = lookup_option(universe, options, code);
if (op != NULL && universe->concat_duplicates) {
struct data_string new;
memset(&new, 0, sizeof new);
if (!buffer_allocate(&new.buffer,
op->data.len + len,
MDL)) {
log_error("parse_option_buffer: "
"No memory.");
buffer_dereference(&bp, MDL);
return 0;
}
/* Copy old option to new data object. */
memcpy(new.buffer->data, op->data.data,
op->data.len);
/* Concat new option behind old. */
memcpy(new.buffer->data + op->data.len,
bp->data + offset, len);
new.len = op->data.len + len;
new.data = new.buffer->data;
/* Save new concat'd object. */
data_string_forget(&op->data, MDL);
data_string_copy(&op->data, &new, MDL);
data_string_forget(&new, MDL);
} else if (op != NULL) {
/* We must append this statement onto the
* end of the list.
*/
while (op->next != NULL)
op = op->next;
if (!option_cache_allocate(&nop, MDL)) {
log_error("parse_option_buffer: "
"No memory.");
buffer_dereference(&bp, MDL);
return 0;
}
option_reference(&nop->option, op->option, MDL);
/* If the option contains an encapsulation, parse it. In
any case keep the raw data as well. (Previous to 4.4.0
we only kept the raw data if the parse failed, the option
wasn't an encapsulation (by far the most common case), or
the option wasn't entirely an encapsulation
*/
if (option &&
(option->format[0] == 'e' || option->format[0] == 'E')) {
(void) parse_encapsulated_suboptions(options, option,
bp->data + offset,
len,
universe, NULL);
}
nop->data.buffer = NULL;
buffer_reference(&nop->data.buffer, bp, MDL);
nop->data.data = bp->data + offset;
nop->data.len = len;
op = lookup_option(universe, options, code);
if (op == NULL) {
/* If we don't have an option create one */
if (save_option_buffer(universe, options, bp,
bp->data + offset, len,
code, 1) == 0) {
log_error("parse_option_buffer: "
"save_option_buffer failed");
buffer_dereference(&bp, MDL);
return (0);
}
} else if (universe->concat_duplicates) {
/* If we do have an option either concat with
what is there ...*/
struct data_string new;
memset(&new, 0, sizeof new);
if (!buffer_allocate(&new.buffer, op->data.len + len,
MDL)) {
log_error("parse_option_buffer: No memory.");
buffer_dereference(&bp, MDL);
return (0);
}
/* Copy old option to new data object. */
memcpy(new.buffer->data, op->data.data,
op->data.len);
/* Concat new option behind old. */
memcpy(new.buffer->data + op->data.len,
bp->data + offset, len);
new.len = op->data.len + len;
new.data = new.buffer->data;
/* Save new concat'd object. */
data_string_forget(&op->data, MDL);
data_string_copy(&op->data, &new, MDL);
data_string_forget(&new, MDL);
} else {
/* ... or we must append this statement onto the
* end of the list.
*/
while (op->next != NULL)
op = op->next;
option_cache_reference(&op->next, nop, MDL);
option_cache_dereference(&nop, MDL);
} else {
if (save_option_buffer(universe, options, bp,
bp->data + offset, len,
code, 1) == 0) {
log_error("parse_option_buffer: "
"save_option_buffer failed");
buffer_dereference(&bp, MDL);
return 0;
}
if (!option_cache_allocate(&nop, MDL)) {
log_error("parse_option_buffer: No memory.");
buffer_dereference(&bp, MDL);
return (0);
}
option_reference(&nop->option, op->option, MDL);
nop->data.buffer = NULL;
buffer_reference(&nop->data.buffer, bp, MDL);
nop->data.data = bp->data + offset;
nop->data.len = len;
option_cache_reference(&op->next, nop, MDL);
option_cache_dereference(&nop, MDL);
}
option_dereference(&option, MDL);
offset += len;
}
buffer_dereference (&bp, MDL);
return 1;
return (1);
}
/* If an option in an option buffer turns out to be an encapsulation,
......
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