From: Tomek Mrugalski Date: Fri, 11 Dec 2015 14:00:15 +0000 (+0100) Subject: [4206b] Pkt{4,6}::getLabel() methods are now exception safe. X-Git-Tag: trac4240_base~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=97b5297868c2a12afe3c7f23b02afabc7d804cde;p=thirdparty%2Fkea.git [4206b] Pkt{4,6}::getLabel() methods are now exception safe. --- diff --git a/src/lib/dhcp/pkt4.cc b/src/lib/dhcp/pkt4.cc index e1e6673499..309764220f 100644 --- a/src/lib/dhcp/pkt4.cc +++ b/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 diff --git a/src/lib/dhcp/pkt4.h b/src/lib/dhcp/pkt4.h index a4c0cc2db9..2989dcdb2d 100644 --- a/src/lib/dhcp/pkt4.h +++ b/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; diff --git a/src/lib/dhcp/pkt6.cc b/src/lib/dhcp/pkt6.cc index 6f95ef930a..59986f0d58 100644 --- a/src/lib/dhcp/pkt6.cc +++ b/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 diff --git a/src/lib/dhcp/pkt6.h b/src/lib/dhcp/pkt6.h index 87dab71a67..62014f6d62 100644 --- a/src/lib/dhcp/pkt6.h +++ b/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;