From: Marcin Siodelski Date: Wed, 13 Aug 2014 11:27:02 +0000 (+0200) Subject: [3478] DHCPv6 server doesn't log an error of select() when signal received. X-Git-Tag: trac3482_base~35^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d78e33673367139527692eb86da830dc8457435c;p=thirdparty%2Fkea.git [3478] DHCPv6 server doesn't log an error of select() when signal received. --- diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 5c4db35c08..f7262d2c5f 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -242,6 +242,13 @@ bool Dhcpv6Srv::run() { try { query = receivePacket(timeout); + + } catch (const SignalInterruptOnSelect) { + // Packet reception interrupted because a signal has been received. + // This is not an error because we might have received a SIGTERM, + // SIGINT or SIGHUP which are handled by the server. For signals + // that are not handled by the server we rely on the default + // behavior of the system, but there is nothing we should log here. } catch (const std::exception& e) { LOG_ERROR(dhcp6_logger, DHCP6_PACKET_RECEIVE_FAIL).arg(e.what()); } diff --git a/src/bin/dhcp6/tests/dhcp6_process_tests.sh.in b/src/bin/dhcp6/tests/dhcp6_process_tests.sh.in index b972774352..2d1972fc03 100755 --- a/src/bin/dhcp6/tests/dhcp6_process_tests.sh.in +++ b/src/bin/dhcp6/tests/dhcp6_process_tests.sh.in @@ -193,6 +193,13 @@ dynamic_reconfiguration_test() { clean_exit 1 fi + # When the server receives a signal the call to select() function is + # interrupted. This should not be logged as an error. + get_log_messages "DHCP6_PACKET_RECEIVE_FAIL" + assert_eq 0 ${_GET_LOG_MESSAGES} \ + "Expected get_log_messages DHCP6_PACKET_RECEIVE_FAIL return %d, \ +returned %d." + # All ok. Shut down Kea and exit. test_finish 0 } @@ -255,6 +262,13 @@ shutdown_test() { assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \ "Expected wait_for_server_down return %d, returned %d" + # When the server receives a signal the call to select() function is + # interrupted. This should not be logged as an error. + get_log_messages "DHCP6_PACKET_RECEIVE_FAIL" + assert_eq 0 ${_GET_LOG_MESSAGES} \ + "Expected get_log_messages DHCP6_PACKET_RECEIVE_FAIL return %d, \ +returned %d." + test_finish 0 } diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc index ab7922633b..b466aa6dc6 100644 --- a/src/lib/dhcp/iface_mgr.cc +++ b/src/lib/dhcp/iface_mgr.cc @@ -1053,8 +1053,20 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */ if (result == 0) { // nothing received and timeout has been reached return (Pkt6Ptr()); // NULL + } else if (result < 0) { - isc_throw(SocketReadError, strerror(errno)); + // In most cases we would like to know whether select() returned + // an error because of a signal being received or for some other + // reasaon. This is because DHCP servers use signals to trigger + // certain actions, like reconfiguration or graceful shutdown. + // By cacthing a dedicated exception the caller will know if the + // error returned by the function is due to the reception of the + // signal or for some other reason. + if (errno == EINTR) { + isc_throw(SignalInterruptOnSelect, strerror(errno)); + } else { + isc_throw(SocketReadError, strerror(errno)); + } } // Let's find out which socket has the data