Browse Source

[4206b] Pkt{4,6}::getLabel() methods are now exception safe.

Tomek Mrugalski 9 years ago
parent
commit
97b5297868
4 changed files with 35 additions and 6 deletions
  1. 19 5
      src/lib/dhcp/pkt4.cc
  2. 2 0
      src/lib/dhcp/pkt4.h
  3. 12 1
      src/lib/dhcp/pkt6.cc
  4. 2 0
      src/lib/dhcp/pkt6.h

+ 19 - 5
src/lib/dhcp/pkt4.cc

@@ -343,15 +343,29 @@ std::string
 Pkt4::getLabel() const {
 
     /// @todo If and when client id is extracted into Pkt4, this method should
-    /// the instance member rather than fetch it every time.
+    /// use the instance member rather than fetch it every time.
+    std::string suffix;
     ClientIdPtr client_id;
     OptionPtr client_opt = getOption(DHO_DHCP_CLIENT_IDENTIFIER);
-    if (client_opt ) {
-        client_id = ClientIdPtr(new ClientId(client_opt->getData()));
+    if (client_opt) {
+        try {
+            client_id = ClientIdPtr(new ClientId(client_opt->getData()));
+        } catch (...) {
+            // ClientId may throw if the client-id is too short.
+            suffix = "(malformed client-id)";
+        }
     }
 
-    return makeLabel(hwaddr_, client_id, transid_);
-
+    std::string txt;
+    try {
+        txt = makeLabel(hwaddr_, client_id, transid_);
+    } catch (...) {
+        // This should not happen with the current code, but we may add extra
+        // sanity checks in the future that would possibly throw if
+        // the hwaddr lenght is 0.
+        txt = "(malformed hw address)";
+    }
+    return (txt + suffix);
 }
 
 std::string

+ 2 - 0
src/lib/dhcp/pkt4.h

@@ -103,6 +103,8 @@ public:
     /// wrapper around static makeLabel(). See this method for string
     /// content.
     ///
+    /// This method is exception safe.
+    ///
     /// @return string with text representation
     std::string getLabel() const;
 

+ 12 - 1
src/lib/dhcp/pkt6.cc

@@ -555,7 +555,18 @@ Pkt6::toText() const {
 DuidPtr
 Pkt6::getClientId() const {
     OptionPtr opt_duid = getOption(D6O_CLIENTID);
-    return (opt_duid ? DuidPtr(new DUID(opt_duid->getData())) : DuidPtr());
+    try {
+        // This will throw if the DUID length is larger than 128 bytes
+        // or is too short.
+        return (opt_duid ? DuidPtr(new DUID(opt_duid->getData())) : DuidPtr());
+    } catch (...) {
+        // Do nothing. This method is used only by getLabel(), which is
+        // used for logging purposes. We should not throw, but rather
+        // report no DUID. We should not log anything, as we're in the
+        // process of logging something for this packet. So the only
+        // choice left is to return an empty pointer.
+    }
+    return DuidPtr();
 }
 
 isc::dhcp::OptionCollection

+ 2 - 0
src/lib/dhcp/pkt6.h

@@ -227,6 +227,8 @@ public:
 
     /// @brief Retrieves the DUID from the Client Identifier option.
     ///
+    /// This method is exception safe.
+    ///
     /// @return Pointer to the DUID or NULL if the option doesn't exist.
     DuidPtr getClientId() const;