2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-01 14:35:29 +00:00

[master] Merged trac4267 (final run_one())

This commit is contained in:
Francis Dupont
2016-03-23 16:42:21 +01:00
7 changed files with 857 additions and 793 deletions

View File

@@ -89,6 +89,7 @@ We have received the following contributions:
- Jinmei Tatuya
2015-10: Pkt4o6 class improvements
2015-11: split Dhcpv4Srv::run() into run() and processPacket()
- Sebastien Couture, Ubity Inc
2015-12: Fixes to MySQL schema creation

View File

@@ -449,10 +449,17 @@ 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_PROCESS_EXCEPTION exception occurred during packet processing
This error message indicates that a non-standard 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_PROCESS_STD_EXCEPTION exception occurred during packet processing: %1
This error message indicates that a standard 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

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -418,12 +418,30 @@ Dhcpv4Srv::sendPacket(const Pkt4Ptr& packet) {
bool
Dhcpv4Srv::run() {
while (!shutdown_) {
try {
run_one();
} 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_STD_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);
}
}
return (true);
}
void
Dhcpv4Srv::run_one() {
// client's message and server's response
Pkt4Ptr query;
Pkt4Ptr rsp;
try {
try {
uint32_t timeout = 1000;
LOG_DEBUG(packet4_logger, DBG_DHCP4_DETAIL, DHCP4_BUFFER_WAIT).arg(timeout);
@@ -484,12 +502,81 @@ Dhcpv4Srv::run() {
// with no reception occurred. No need to log anything here because
// we have logged right after the call to receivePacket().
if (!query) {
continue;
return;
}
processPacket(query, rsp);
if (!rsp) {
return;
}
try {
// Now all fields and options are constructed into output wire buffer.
// Option objects modification does not make sense anymore. Hooks
// can only manipulate wire buffer at this stage.
// Let's execute all callouts registered for buffer4_send
if (HooksManager::calloutsPresent(Hooks.hook_index_buffer4_send_)) {
CalloutHandlePtr callout_handle = getCalloutHandle(query);
// Delete previously set arguments
callout_handle->deleteAllArguments();
// Pass incoming packet as argument
callout_handle->setArgument("response4", rsp);
// Call callouts
HooksManager::callCallouts(Hooks.hook_index_buffer4_send_,
*callout_handle);
// Callouts decided to skip the next processing step. The next
// processing step would to parse the packet, so skip at this
// stage means drop.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
LOG_DEBUG(hooks_logger, DBG_DHCP4_HOOKS,
DHCP4_HOOK_BUFFER_SEND_SKIP)
.arg(rsp->getLabel());
return;
}
/// @todo: Add support for DROP status.
callout_handle->getArgument("response4", rsp);
}
LOG_DEBUG(packet4_logger, DBG_DHCP4_BASIC, DHCP4_PACKET_SEND)
.arg(rsp->getLabel())
.arg(rsp->getName())
.arg(static_cast<int>(rsp->getType()))
.arg(rsp->getLocalAddr())
.arg(rsp->getLocalPort())
.arg(rsp->getRemoteAddr())
.arg(rsp->getRemotePort())
.arg(rsp->getIface());
LOG_DEBUG(packet4_logger, DBG_DHCP4_DETAIL_DATA,
DHCP4_RESPONSE_DATA)
.arg(rsp->getLabel())
.arg(rsp->getName())
.arg(static_cast<int>(rsp->getType()))
.arg(rsp->toText());
sendPacket(rsp);
// Update statistics accordingly for sent packet.
processStatsSent(rsp);
} catch (const std::exception& e) {
LOG_ERROR(packet4_logger, DHCP4_PACKET_SEND_FAIL)
.arg(rsp->getLabel())
.arg(e.what());
}
}
void
Dhcpv4Srv::processPacket(Pkt4Ptr& query, Pkt4Ptr& rsp) {
// Log reception of the packet. We need to increase it early, as any
// failures in unpacking will cause the packet to be dropped. We
// will increase type specific packets further down the road.
// will increase type specific statistic further down the road.
// See processStatsReceived().
isc::stats::StatsMgr::instance().addValue("pkt4-received",
static_cast<int64_t>(1));
@@ -525,7 +612,8 @@ Dhcpv4Srv::run() {
// stage means that callouts did the parsing already, so server
// should skip parsing.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
LOG_DEBUG(hooks_logger, DBG_DHCP4_DETAIL, DHCP4_HOOK_BUFFER_RCVD_SKIP)
LOG_DEBUG(hooks_logger, DBG_DHCP4_DETAIL,
DHCP4_HOOK_BUFFER_RCVD_SKIP)
.arg(query->getRemoteAddr().toText())
.arg(query->getLocalAddr().toText())
.arg(query->getIface());
@@ -560,7 +648,7 @@ Dhcpv4Srv::run() {
static_cast<int64_t>(1));
isc::stats::StatsMgr::instance().addValue("pkt4-receive-drop",
static_cast<int64_t>(1));
continue;
return;
}
}
@@ -578,7 +666,7 @@ Dhcpv4Srv::run() {
// Increase the statistic of dropped packets.
isc::stats::StatsMgr::instance().addValue("pkt4-receive-drop",
static_cast<int64_t>(1));
continue;
return;
}
// We have sanity checked (in accept() that the Message Type option
@@ -613,9 +701,10 @@ Dhcpv4Srv::run() {
// processing step would to process the packet, so skip at this
// stage means drop.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
LOG_DEBUG(hooks_logger, DBG_DHCP4_HOOKS, DHCP4_HOOK_PACKET_RCVD_SKIP)
LOG_DEBUG(hooks_logger, DBG_DHCP4_HOOKS,
DHCP4_HOOK_PACKET_RCVD_SKIP)
.arg(query->getLabel());
continue;
return;
}
/// @todo: Add support for DROP status
@@ -674,10 +763,9 @@ Dhcpv4Srv::run() {
}
if (!rsp) {
continue;
return;
}
// Specifies if server should do the packing
bool skip_pack = false;
@@ -705,7 +793,8 @@ Dhcpv4Srv::run() {
// processing step would to send the packet, so skip at this
// stage means "drop response".
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
LOG_DEBUG(hooks_logger, DBG_DHCP4_HOOKS, DHCP4_HOOK_PACKET_SEND_SKIP)
LOG_DEBUG(hooks_logger, DBG_DHCP4_HOOKS,
DHCP4_HOOK_PACKET_SEND_SKIP)
.arg(query->getLabel());
skip_pack = true;
}
@@ -724,82 +813,6 @@ Dhcpv4Srv::run() {
.arg(e.what());
}
}
try {
// Now all fields and options are constructed into output wire buffer.
// Option objects modification does not make sense anymore. Hooks
// can only manipulate wire buffer at this stage.
// Let's execute all callouts registered for buffer4_send
if (HooksManager::calloutsPresent(Hooks.hook_index_buffer4_send_)) {
CalloutHandlePtr callout_handle = getCalloutHandle(query);
// Delete previously set arguments
callout_handle->deleteAllArguments();
// Pass incoming packet as argument
callout_handle->setArgument("response4", rsp);
// Call callouts
HooksManager::callCallouts(Hooks.hook_index_buffer4_send_,
*callout_handle);
// Callouts decided to skip the next processing step. The next
// processing step would to parse the packet, so skip at this
// stage means drop.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
LOG_DEBUG(hooks_logger, DBG_DHCP4_HOOKS,
DHCP4_HOOK_BUFFER_SEND_SKIP)
.arg(rsp->getLabel());
continue;
}
/// @todo: Add support for DROP status.
callout_handle->getArgument("response4", rsp);
}
LOG_DEBUG(packet4_logger, DBG_DHCP4_BASIC, DHCP4_PACKET_SEND)
.arg(rsp->getLabel())
.arg(rsp->getName())
.arg(static_cast<int>(rsp->getType()))
.arg(rsp->getLocalAddr())
.arg(rsp->getLocalPort())
.arg(rsp->getRemoteAddr())
.arg(rsp->getRemotePort())
.arg(rsp->getIface());
LOG_DEBUG(packet4_logger, DBG_DHCP4_DETAIL_DATA,
DHCP4_RESPONSE_DATA)
.arg(rsp->getLabel())
.arg(rsp->getName())
.arg(static_cast<int>(rsp->getType()))
.arg(rsp->toText());
sendPacket(rsp);
// Update statistics accordingly for sent packet.
processStatsSent(rsp);
} catch (const std::exception& e) {
LOG_ERROR(packet4_logger, DHCP4_PACKET_SEND_FAIL)
.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);
}
string

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -208,14 +208,28 @@ public:
/// @brief Main server processing loop.
///
/// Main server processing loop. Receives incoming packets, verifies
/// their correctness, generates appropriate answer (if needed) and
/// transmits responses.
/// Main server processing loop. Call the processing step routine
/// until shut down.
///
/// @return true, if being shut down gracefully, fail if experienced
/// critical error.
/// @return true, if being shut down gracefully, never fail.
bool run();
/// @brief Main server processing step.
///
/// Main server processing step. Receives one incoming packet, calls
/// the processing packet routing and (if necessary) transmits
/// a response.
void run_one();
/// @brief Process a single incoming DHCPv4 packet.
///
/// It verifies correctness of the passed packet, call per-type processXXX
/// methods, generates appropriate answer.
///
/// @param query A pointer to the packet to be processed.
/// @param rsp A pointer to the response
void processPacket(Pkt4Ptr& query, Pkt4Ptr& rsp);
/// @brief Instructs the server to shut down.
void shutdown();

View File

@@ -425,16 +425,23 @@ because packets of this type must be sent to multicast. The first argument
specifies the client and transaction identification information, the
second argument specifies packet type.
% 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_PROCESS_EXCEPTION exception occurred during packet processing
This error message indicates that a non-standard 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_PROCESS_FAIL processing of %1 message received from %2 failed: %3
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_STD_EXCEPTION exception occurred during packet processing: %1
This error message indicates that a standard 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

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -288,12 +288,28 @@ Dhcpv6Srv::createContext(const Pkt6Ptr& pkt) {
bool Dhcpv6Srv::run() {
while (!shutdown_) {
try {
run_one();
} catch (const std::exception& e) {
// General catch-all standard exceptions that are not caught by more
// specific catches.
LOG_ERROR(packet6_logger, DHCP6_PACKET_PROCESS_STD_EXCEPTION)
.arg(e.what());
} catch (...) {
// General catch-all non-standard exception that are not caught
// by more specific catches.
LOG_ERROR(packet6_logger, DHCP6_PACKET_PROCESS_EXCEPTION);
}
}
return (true);
}
void Dhcpv6Srv::run_one() {
// client's message and server's response
Pkt6Ptr query;
Pkt6Ptr rsp;
try {
try {
uint32_t timeout = 1000;
LOG_DEBUG(packet6_logger, DBG_DHCP6_DETAIL, DHCP6_BUFFER_WAIT).arg(timeout);
@@ -357,9 +373,62 @@ bool Dhcpv6Srv::run() {
// Timeout may be reached or signal received, which breaks select()
// with no packet received
if (!query) {
continue;
return;
}
processPacket(query, rsp);
if (!rsp) {
return;
}
try {
// Now all fields and options are constructed into output wire buffer.
// Option objects modification does not make sense anymore. Hooks
// can only manipulate wire buffer at this stage.
// Let's execute all callouts registered for buffer6_send
if (HooksManager::calloutsPresent(Hooks.hook_index_buffer6_send_)) {
CalloutHandlePtr callout_handle = getCalloutHandle(query);
// Delete previously set arguments
callout_handle->deleteAllArguments();
// Pass incoming packet as argument
callout_handle->setArgument("response6", rsp);
// Call callouts
HooksManager::callCallouts(Hooks.hook_index_buffer6_send_, *callout_handle);
// Callouts decided to skip the next processing step. The next
// processing step would to parse the packet, so skip at this
// stage means drop.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_BUFFER_SEND_SKIP)
.arg(rsp->getLabel());
return;
}
/// @todo: Add support for DROP status
callout_handle->getArgument("response6", rsp);
}
LOG_DEBUG(packet6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_RESPONSE_DATA)
.arg(static_cast<int>(rsp->getType())).arg(rsp->toText());
sendPacket(rsp);
// Update statistics accordingly for sent packet.
processStatsSent(rsp);
} catch (const std::exception& e) {
LOG_ERROR(packet6_logger, DHCP6_PACKET_SEND_FAIL).arg(e.what());
}
}
void
Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) {
// In order to parse the DHCP options, the server needs to use some
// configuration information such as: existing option spaces, option
// definitions etc. This is the kind of information which is not
@@ -425,7 +494,7 @@ bool Dhcpv6Srv::run() {
static_cast<int64_t>(1));
StatsMgr::instance().addValue("pkt6-receive-drop",
static_cast<int64_t>(1));
continue;
return;
}
}
@@ -438,7 +507,7 @@ bool Dhcpv6Srv::run() {
// Increase the statistic of dropped packets.
StatsMgr::instance().addValue("pkt6-receive-drop", static_cast<int64_t>(1));
continue;
return;
}
// Check if the received query has been sent to unicast or multicast.
@@ -448,7 +517,7 @@ bool Dhcpv6Srv::run() {
// Increase the statistic of dropped packets.
StatsMgr::instance().addValue("pkt6-receive-drop", static_cast<int64_t>(1));
continue;
return;
}
LOG_DEBUG(packet6_logger, DBG_DHCP6_BASIC_DATA, DHCP6_PACKET_RECEIVED)
@@ -483,7 +552,7 @@ bool Dhcpv6Srv::run() {
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_PACKET_RCVD_SKIP)
.arg(query->getLabel());
continue;
return;
}
/// @todo: Add support for DROP status.
@@ -568,7 +637,9 @@ bool Dhcpv6Srv::run() {
StatsMgr::instance().addValue("pkt6-receive-drop", static_cast<int64_t>(1));
}
if (rsp) {
if (!rsp) {
return;
}
// Process relay-supplied options. It is important to call this very
// late in the process, because we now have all the options the
@@ -634,74 +705,11 @@ bool Dhcpv6Srv::run() {
try {
rsp->pack();
} catch (const std::exception& e) {
LOG_ERROR(options6_logger, DHCP6_PACK_FAIL)
.arg(e.what());
continue;
LOG_ERROR(options6_logger, DHCP6_PACK_FAIL).arg(e.what());
return;
}
}
try {
// Now all fields and options are constructed into output wire buffer.
// Option objects modification does not make sense anymore. Hooks
// can only manipulate wire buffer at this stage.
// Let's execute all callouts registered for buffer6_send
if (HooksManager::calloutsPresent(Hooks.hook_index_buffer6_send_)) {
CalloutHandlePtr callout_handle = getCalloutHandle(query);
// Delete previously set arguments
callout_handle->deleteAllArguments();
// Pass incoming packet as argument
callout_handle->setArgument("response6", rsp);
// Call callouts
HooksManager::callCallouts(Hooks.hook_index_buffer6_send_, *callout_handle);
// Callouts decided to skip the next processing step. The next
// processing step would to parse the packet, so skip at this
// stage means drop.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_BUFFER_SEND_SKIP)
.arg(rsp->getLabel());
continue;
}
/// @todo: Add support for DROP status
callout_handle->getArgument("response6", rsp);
}
LOG_DEBUG(packet6_logger, DBG_DHCP6_DETAIL_DATA,
DHCP6_RESPONSE_DATA)
.arg(static_cast<int>(rsp->getType())).arg(rsp->toText());
sendPacket(rsp);
// Update statistics accordingly for sent packet.
processStatsSent(rsp);
} catch (const std::exception& e) {
LOG_ERROR(packet6_logger, DHCP6_PACKET_SEND_FAIL)
.arg(e.what());
}
}
} catch (const std::exception& e) {
// General catch-all standard exceptions that are not caught by more
// specific catches.
LOG_ERROR(packet6_logger, DHCP6_PACKET_PROCESS_EXCEPTION)
.arg(e.what());
} catch (...) {
// General catch-all non-standard exception that are not caught
// by more specific catches.
LOG_ERROR(packet6_logger, DHCP6_PACKET_PROCESS_EXCEPTION)
.arg("an unknown exception not derived from std::exception");
}
}
return (true);
}
std::string

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -89,14 +89,28 @@ public:
/// @brief Main server processing loop.
///
/// Main server processing loop. Receives incoming packets, verifies
/// their correctness, generates appropriate answer (if needed) and
/// transmits responses.
/// Main server processing loop. Call the processing step routine
/// until shut down.
///
/// @return true, if being shut down gracefully, fail if experienced
/// critical error.
/// @return true, if being shut down gracefully, never fail.
bool run();
/// @brief Main server processing step.
///
/// Main server processing step. Receives one incoming packet, calls
/// the processing packet routing and (if necessary) transmits
/// a response.
void run_one();
/// @brief Process a single incoming DHCPv6 packet.
///
/// It verifies correctness of the passed packet, call per-type processXXX
/// methods, generates appropriate answer.
///
/// @param query A pointer to the packet to be processed.
/// @param rsp A pointer to the response
void processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp);
/// @brief Instructs the server to shut down.
void shutdown();