From: Francis Dupont Date: Thu, 16 Jun 2016 22:04:39 +0000 (+0200) Subject: [4109a] Copy the send part (logs and hook) from standard service to 4o6 handler X-Git-Tag: trac4273_base~5^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ab0eff8f663f2ffaee634893494c91c0e377a40;p=thirdparty%2Fkea.git [4109a] Copy the send part (logs and hook) from standard service to 4o6 handler --- diff --git a/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes index 3d8b2b8550..657ec4fa26 100644 --- a/src/bin/dhcp6/dhcp6_messages.mes +++ b/src/bin/dhcp6/dhcp6_messages.mes @@ -237,6 +237,24 @@ received in Decline message. It's expected that the option will contain an address that is being declined. Specific information will be printed in a separate message. +% DHCP6_DHCP4O6_PACKET_RECEIVED received DHCPv4o6 packet from DHCPv4 server (type %1) for %2 on interface %3 +This debug message is printed when the server is receiving a DHCPv4o6 +from the DHCPv4 server over inter-process communication. + +% DHCP6_DHCP4O6_RECEIVE_FAIL failed to receive DHCPv4o6: %1 +This debug message indicates the inter-process communication with the +DHCPv4 server failed. The reason for the error is included in +the message. + +% DHCP6_DHCP4O6_RECEIVING receiving DHCPv4o6 packet from DHCPv4 server +This debug message is printed when the server is receiving a DHCPv4o6 +from the DHCPv4 server over inter-process communication + +% DHCP6_DHCP4O6_SEND_FAIL failed to send DHCPv4o6 packet: %1 +This error is output if the IPv6 DHCP server fails to send an assembled +DHCPv4o6 message to a client. The reason for the error is included in the +message. + % DHCP6_DYNAMIC_RECONFIGURATION initiate server reconfiguration using file: %1, after receiving SIGHUP signal This is the info message logged when the DHCPv6 server starts reconfiguration as a result of receiving SIGHUP signal. diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 182cf3386b..aa65cd13bc 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -165,6 +165,8 @@ createStatusCode(const Pkt6& pkt, const Option6IA& ia, const uint16_t status_cod namespace isc { namespace dhcp { +int Dhcpv6Srv::hook_index_buffer6_send = Hooks.hook_index_buffer6_send_; + const std::string Dhcpv6Srv::VENDOR_CLASS_PREFIX("VENDOR_CLASS_"); Dhcpv6Srv::Dhcpv6Srv(uint16_t port) diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h index 0c9f6c2216..ec6233f4ad 100644 --- a/src/bin/dhcp6/dhcp6_srv.h +++ b/src/bin/dhcp6/dhcp6_srv.h @@ -787,12 +787,18 @@ private: /// @param query packet received static void processStatsReceived(const Pkt6Ptr& query); + /// UDP port number on which server listens. + uint16_t port_; + +public: + /// @note used by DHCPv4-over-DHCPv6 so must be public + /// @brief Updates statistics for transmitted packets /// @param query packet transmitted static void processStatsSent(const Pkt6Ptr& response); - /// UDP port number on which server listens. - uint16_t port_; + /// the index of the buffer6_send hook + static int hook_index_buffer6_send; protected: diff --git a/src/bin/dhcp6/dhcp6to4_ipc.cc b/src/bin/dhcp6/dhcp6to4_ipc.cc index f242f17a6c..95516e965d 100644 --- a/src/bin/dhcp6/dhcp6to4_ipc.cc +++ b/src/bin/dhcp6/dhcp6to4_ipc.cc @@ -8,10 +8,20 @@ #include #include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include using namespace std; +using namespace isc::hooks; namespace isc { namespace dhcp { @@ -44,13 +54,30 @@ void Dhcp6to4Ipc::open() { void Dhcp6to4Ipc::handler() { Dhcp6to4Ipc& ipc = Dhcp6to4Ipc::instance(); + Pkt6Ptr pkt; + + try { + LOG_DEBUG(packet6_logger, DBG_DHCP6_DETAIL, DHCP6_DHCP4O6_RECEIVING); + // Receive message from IPC. + pkt = ipc.receive(); + + if (pkt) { + LOG_DEBUG(packet6_logger, DBG_DHCP6_BASIC, DHCP6_DHCP4O6_PACKET_RECEIVED) + .arg(static_cast(pkt->getType())) + .arg(pkt->getRemoteAddr().toText()) + .arg(pkt->getIface()); + } + } catch (const std::exception& e) { + LOG_DEBUG(packet6_logger,DBG_DHCP6_DETAIL, DHCP6_DHCP4O6_RECEIVE_FAIL) + .arg(e.what()); + } - // Receive message from IPC. - Pkt6Ptr pkt = ipc.receive(); if (!pkt) { return; } + // Should we check it is a DHCPV6_DHCPV4_RESPONSE? + // The received message has been unpacked by the receive() function. This // method could have modified the message so it's better to pack() it // again because we'll be forwarding it to a client. @@ -58,16 +85,60 @@ void Dhcp6to4Ipc::handler() { buf.clear(); pkt->pack(); - uint8_t msg_type = pkt->getType(); + // Don't use getType(): get the message type from the buffer + uint8_t msg_type = buf[0]; if ((msg_type == DHCPV6_RELAY_FORW) || (msg_type == DHCPV6_RELAY_REPL)) { pkt->setRemotePort(DHCP6_SERVER_PORT); } else { pkt->setRemotePort(DHCP6_CLIENT_PORT); } - // Forward packet to the client. - IfaceMgr::instance().send(pkt); - // processStatsSent(pkt); + // Can't call the pkt6_send callout because we don't have the query + + // Copied from Dhcpv6Srv::run_one() sending part + + try { + // Let's execute all callouts registered for buffer6_send + if (HooksManager::calloutsPresent(Dhcpv6Srv::hook_index_buffer6_send)) { + CalloutHandlePtr callout_handle = getCalloutHandle(pkt); + + // Delete previously set arguments + callout_handle->deleteAllArguments(); + + // Pass incoming packet as argument + callout_handle->setArgument("response6", pkt); + + // Call callouts + HooksManager::callCallouts(Dhcpv6Srv::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(pkt->getLabel()); + return; + } + + /// @todo: Add support for DROP status + + callout_handle->getArgument("response6", pkt); + } + + LOG_DEBUG(packet6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_RESPONSE_DATA) + .arg(static_cast(pkt->getType())).arg(pkt->toText()); + + + // Forward packet to the client. + IfaceMgr::instance().send(pkt); + + // Update statistics accordingly for sent packet. + Dhcpv6Srv::processStatsSent(pkt); + + } catch (const std::exception& e) { + LOG_ERROR(packet6_logger, DHCP6_DHCP4O6_SEND_FAIL).arg(e.what()); + } } }; // namespace dhcp