186 lines
7.1 KiB
Diff
186 lines
7.1 KiB
Diff
|
diff --git a/src/bin/dhcp4/dhcp4_messages.mes b/src/bin/dhcp4/dhcp4_messages.mes
|
||
|
index f8e471b..fc992a0 100644
|
||
|
--- a/src/bin/dhcp4/dhcp4_messages.mes
|
||
|
+++ b/src/bin/dhcp4/dhcp4_messages.mes
|
||
|
@@ -429,6 +429,11 @@ This error message is issued when preparing an on-wire format of the packet
|
||
|
has failed. The first argument identifies the client and the DHCP transaction.
|
||
|
The second argument includes the error string.
|
||
|
|
||
|
+% DHCP4_PACKET_PROCESS_EXCEPTION exception occurred during packet processing: %1
|
||
|
+This error message indicates that an exception was raised during packet processing
|
||
|
+that was not caught by other, more specific exception handlers. This packet will
|
||
|
+be dropped and the server will continue operation.
|
||
|
+
|
||
|
% DHCP4_PACKET_RECEIVED %1: %2 (type %3) received from %4 to %5 on interface %6
|
||
|
A debug message noting that the server has received the specified type of
|
||
|
packet on the specified interface. The first argument specifies the
|
||
|
diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc
|
||
|
index 6ade319..1bdfc9a 100644
|
||
|
--- a/src/bin/dhcp4/dhcp4_srv.cc
|
||
|
+++ b/src/bin/dhcp4/dhcp4_srv.cc
|
||
|
@@ -358,6 +358,8 @@ Dhcpv4Srv::run() {
|
||
|
Pkt4Ptr rsp;
|
||
|
|
||
|
try {
|
||
|
+
|
||
|
+ try {
|
||
|
// The lease database backend may install some timers for which
|
||
|
// the handlers need to be executed periodically. Retrieve the
|
||
|
// maximum interval at which the handlers must be executed from
|
||
|
@@ -716,6 +718,20 @@ Dhcpv4Srv::run() {
|
||
|
.arg(rsp->getLabel())
|
||
|
.arg(e.what());
|
||
|
}
|
||
|
+
|
||
|
+ } catch (const std::exception& e) {
|
||
|
+ // General catch-all exception that are not caught by more specific
|
||
|
+ // catches. This one is for exceptions derived from std::exception.
|
||
|
+ LOG_ERROR(packet4_logger, DHCP4_PACKET_PROCESS_EXCEPTION)
|
||
|
+ .arg(e.what());
|
||
|
+ } catch (...) {
|
||
|
+ // General catch-all exception that are not caught by more specific
|
||
|
+ // catches. This one is for other exceptions, not derived from
|
||
|
+ // std::exception.
|
||
|
+ LOG_ERROR(packet4_logger, DHCP4_PACKET_PROCESS_EXCEPTION)
|
||
|
+ .arg("an unknown exception not derived from std::exception");
|
||
|
+ }
|
||
|
+
|
||
|
}
|
||
|
|
||
|
return (true);
|
||
|
diff --git a/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes
|
||
|
index 5b62bb7..9b84797 100644
|
||
|
--- a/src/bin/dhcp6/dhcp6_messages.mes
|
||
|
+++ b/src/bin/dhcp6/dhcp6_messages.mes
|
||
|
@@ -413,6 +413,11 @@ This is a general catch-all message indicating that the processing of the
|
||
|
specified packet type from the indicated address failed. The reason is given in the
|
||
|
message. The server will not send a response but will instead ignore the packet.
|
||
|
|
||
|
+% DHCP6_PACKET_PROCESS_EXCEPTION exception occurred during packet processing: %1
|
||
|
+This error message indicates that an exception was raised during packet processing
|
||
|
+that was not caught by other, more specific exception handlers. This packet will
|
||
|
+be dropped and the server will continue operation.
|
||
|
+
|
||
|
% DHCP6_PACKET_RECEIVED %1: %2 (type %3) received from %4 to %5 on interface %6
|
||
|
A debug message noting that the server has received the specified type of
|
||
|
packet on the specified interface. The first argument specifies the
|
||
|
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
|
||
|
index 9f29e9d..33f54a0 100644
|
||
|
--- a/src/bin/dhcp6/dhcp6_srv.cc
|
||
|
+++ b/src/bin/dhcp6/dhcp6_srv.cc
|
||
|
@@ -315,6 +315,8 @@ bool Dhcpv6Srv::run() {
|
||
|
Pkt6Ptr rsp;
|
||
|
|
||
|
try {
|
||
|
+
|
||
|
+ try {
|
||
|
// The lease database backend may install some timers for which
|
||
|
// the handlers need to be executed periodically. Retrieve the
|
||
|
// maximum interval at which the handlers must be executed from
|
||
|
@@ -710,6 +712,13 @@ bool Dhcpv6Srv::run() {
|
||
|
.arg(e.what());
|
||
|
}
|
||
|
}
|
||
|
+
|
||
|
+ } catch (const std::exception& e) {
|
||
|
+ // General catch-all exception that are not caught by more specific
|
||
|
+ // catches.
|
||
|
+ LOG_ERROR(packet6_logger, DHCP6_PACKET_PROCESS_EXCEPTION)
|
||
|
+ .arg(e.what());
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
return (true);
|
||
|
diff --git a/src/lib/dhcp/pkt4.cc b/src/lib/dhcp/pkt4.cc
|
||
|
index 44a96ca..2a82969 100644
|
||
|
--- a/src/lib/dhcp/pkt4.cc
|
||
|
+++ b/src/lib/dhcp/pkt4.cc
|
||
|
@@ -343,15 +343,31 @@ 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::ostringstream label;
|
||
|
+ try {
|
||
|
+ label << 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 length is 0.
|
||
|
+ label << " (malformed hw address)";
|
||
|
+ }
|
||
|
+
|
||
|
+ label << suffix;
|
||
|
+ return (label.str());
|
||
|
}
|
||
|
|
||
|
std::string
|
||
|
diff --git a/src/lib/dhcp/pkt4.h b/src/lib/dhcp/pkt4.h
|
||
|
index 549be78..12af2cf 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 7881672..d0fd5e5 100644
|
||
|
--- a/src/lib/dhcp/pkt6.cc
|
||
|
+++ b/src/lib/dhcp/pkt6.cc
|
||
|
@@ -544,7 +544,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 febb92d..3228dad 100644
|
||
|
--- a/src/lib/dhcp/pkt6.h
|
||
|
+++ b/src/lib/dhcp/pkt6.h
|
||
|
@@ -217,6 +217,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;
|
||
|
|
||
|
|