From: Francis Dupont Date: Wed, 24 Feb 2016 13:00:14 +0000 (+0100) Subject: [4267] Finished merge of trac4266 (run_one server routine) X-Git-Tag: trac4267_base~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b06d0f707b17f45cece8f724216ef2cb7a6e5bd;p=thirdparty%2Fkea.git [4267] Finished merge of trac4266 (run_one server routine) --- 2b06d0f707b17f45cece8f724216ef2cb7a6e5bd diff --cc src/bin/dhcp4/dhcp4_srv.cc index a65b7c464a,c0ffcb9013..3aabadb8ad --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@@ -503,13 -433,78 +433,87 @@@ Dhcpv4Srv::run() return (true); } + void + Dhcpv4Srv::run_one() { + // client's message and server's response + Pkt4Ptr query; + Pkt4Ptr rsp; + + try { + uint32_t timeout = 1000; + LOG_DEBUG(packet4_logger, DBG_DHCP4_DETAIL, DHCP4_BUFFER_WAIT).arg(timeout); + query = receivePacket(timeout); + + // Log if packet has arrived. We can't log the detailed information + // about the DHCP message because it hasn't been unpacked/parsed + // yet, and it can't be parsed at this point because hooks will + // have to process it first. The only information available at this + // point are: the interface, source address and destination addresses + // and ports. + if (query) { + LOG_DEBUG(packet4_logger, DBG_DHCP4_BASIC, DHCP4_BUFFER_RECEIVED) + .arg(query->getRemoteAddr().toText()) + .arg(query->getRemotePort()) + .arg(query->getLocalAddr().toText()) + .arg(query->getLocalPort()) + .arg(query->getIface()); + + } else { + LOG_DEBUG(packet4_logger, DBG_DHCP4_DETAIL, DHCP4_BUFFER_WAIT_INTERRUPTED) + .arg(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, SIGHUP or SIGCHILD which are handled by the server. For + // signals that are not handled by the server we rely on the default + // behavior of the system. + LOG_DEBUG(packet4_logger, DBG_DHCP4_DETAIL, DHCP4_BUFFER_WAIT_SIGNAL) + .arg(signal_set_->getNext()); + } catch (const std::exception& e) { + // Log all other errors. + LOG_ERROR(packet4_logger, DHCP4_BUFFER_RECEIVE_FAIL).arg(e.what()); + } + + // Handle next signal received by the process. It must be called after + // an attempt to receive a packet to properly handle server shut down. + // The SIGTERM or SIGINT will be received prior to, or during execution + // of select() (select is invoked by receivePacket()). When that + // happens, select will be interrupted. The signal handler will be + // invoked immediately after select(). The handler will set the + // shutdown flag and cause the process to terminate before the next + // select() function is called. If the function was called before + // receivePacket the process could wait up to the duration of timeout + // of select() to terminate. + try { + handleSignal(); + } catch (const std::exception& e) { + // Standard exception occurred. Let's be on the safe side to + // catch std::exception. + LOG_ERROR(dhcp4_logger, DHCP4_HANDLE_SIGNAL_EXCEPTION) + .arg(e.what()); + } + + // Timeout may be reached or signal received, which breaks select() + // with no reception occurred. No need to log anything here because + // we have logged right after the call to receivePacket(). + if (!query) { + return; + } + ++ processPacket(query); ++ ++ } ++} ++ +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 statistoc further down the road. - // 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(1)); diff --cc src/bin/dhcp4/dhcp4_srv.h index bed9764df1,3400d9d6f2..d0a1cc4ed6 --- a/src/bin/dhcp4/dhcp4_srv.h +++ b/src/bin/dhcp4/dhcp4_srv.h @@@ -208,22 -208,19 +208,27 @@@ public /// @brief Main server processing loop. /// - /// Main server processing loop. Receives incoming packets, and calls - /// processPacket for each of them. + /// Main server processing loop. Call the processing one 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 one. + /// - /// Main server processing one. Receives one incoming packet, verifies - /// its correctness, generates appropriate answer (if needed) and - /// transmits response. ++ /// Main server processing one. Receives one incoming packet, calls ++ /// the processing packet routing, + 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 (if needed) and (if necessary) + /// transmits a response. + /// + /// @param query A pointer to the packet to be processed. + void processPacket(Pkt4Ptr& query); + /// @brief Instructs the server to shut down. void shutdown();