]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Include the raw data from a fully encapsualted option in the cache
authorShawn Routhier <sar@isc.org>
Thu, 11 Aug 2016 03:28:28 +0000 (20:28 -0700)
committerShawn Routhier <sar@isc.org>
Thu, 11 Aug 2016 03:28:28 +0000 (20:28 -0700)
RELNOTES
common/options.c

index 730a62561b54d8477d736c08eb88b681574b983d..3927402d6c39b5b4d5fd367cb4df3a8f0ace81ea 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -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.
index b41ec4d49e96023003ac7ecc37ff0d80b0d1306c..223726ca0c01fbb611a3063c785133b4c54d858b 100644 (file)
@@ -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,