Kea  1.5.0
dhcp6to4_ipc.cc
Go to the documentation of this file.
1 // Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
9 #include <util/buffer.h>
10 #include <dhcp/iface_mgr.h>
11 #include <dhcp/pkt6.h>
13 #include <dhcpsrv/cfgmgr.h>
14 #include <dhcp6/dhcp6to4_ipc.h>
15 #include <dhcp6/dhcp6_log.h>
16 #include <dhcp6/ctrl_dhcp6_srv.h>
17 #include <dhcp6/dhcp6_srv.h>
18 #include <exceptions/exceptions.h>
19 #include <hooks/callout_handle.h>
20 #include <hooks/hooks_log.h>
21 #include <hooks/hooks_manager.h>
22 #include <stats/stats_mgr.h>
23 
24 using namespace std;
25 using namespace isc::hooks;
26 
27 namespace isc {
28 namespace dhcp {
29 
30 Dhcp6to4Ipc::Dhcp6to4Ipc() : Dhcp4o6IpcBase() {}
31 
33  static Dhcp6to4Ipc dhcp6to4_ipc;
34  return (dhcp6to4_ipc);
35 }
36 
38  uint16_t port = CfgMgr::instance().getStagingCfg()->getDhcp4o6Port();
39  if (port == 0) {
41  return;
42  }
43  if (port > 65534) {
44  isc_throw(OutOfRange, "DHCP4o6 port " << port);
45  }
46 
47  int old_fd = socket_fd_;
49  if ((old_fd == -1) && (socket_fd_ != old_fd)) {
52  }
53 }
54 
57  Pkt6Ptr pkt;
58 
59  try {
60  LOG_DEBUG(packet6_logger, DBG_DHCP6_DETAIL, DHCP6_DHCP4O6_RECEIVING);
61  // Receive message from IPC.
62  pkt = ipc.receive();
63 
64  if (pkt) {
65  LOG_DEBUG(packet6_logger, DBG_DHCP6_BASIC, DHCP6_DHCP4O6_PACKET_RECEIVED)
66  .arg(static_cast<int>(pkt->getType()))
67  .arg(pkt->getRemoteAddr().toText())
68  .arg(pkt->getRemotePort())
69  .arg(pkt->getIface());
70  }
71  } catch (const std::exception& e) {
72  LOG_DEBUG(packet6_logger,DBG_DHCP6_DETAIL, DHCP6_DHCP4O6_RECEIVE_FAIL)
73  .arg(e.what());
74  }
75 
76  if (!pkt) {
77  return;
78  }
79 
80  // Should we check it is a DHCPV6_DHCPV4_RESPONSE?
81 
82  // Handle relay port
83  uint16_t relay_port = Dhcpv6Srv::checkRelaySourcePort(pkt);
84 
85  // The received message has been unpacked by the receive() function. This
86  // method could have modified the message so it's better to pack() it
87  // again because we'll be forwarding it to a client.
88  isc::util::OutputBuffer& buf = pkt->getBuffer();
89  buf.clear();
90  pkt->pack();
91 
92  // Don't use getType(): get the message type from the buffer as we
93  // want to know if it is a relayed message (vs. internal message type).
94  // getType() always returns the type of internal message.
95  uint8_t msg_type = buf[0];
96  if ((msg_type == DHCPV6_RELAY_FORW) || (msg_type == DHCPV6_RELAY_REPL)) {
97  pkt->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
98  } else {
99  pkt->setRemotePort(DHCP6_CLIENT_PORT);
100  }
101 
102  // Can't call the pkt6_send callout because we don't have the query
103  // From Dhcpv6Srv::processPacketBufferSend
104 
105  try {
106  // Let's execute all callouts registered for buffer6_send
107  if (HooksManager::calloutsPresent(Dhcpv6Srv::getHookIndexBuffer6Send())) {
108  CalloutHandlePtr callout_handle = getCalloutHandle(pkt);
109 
110  // Delete previously set arguments
111  callout_handle->deleteAllArguments();
112 
113  // Enable copying options from the packet within hook library.
114  ScopedEnableOptionsCopy<Pkt6> response6_options_copy(pkt);
115 
116  // Pass incoming packet as argument
117  callout_handle->setArgument("response6", pkt);
118 
119  // Call callouts
120  HooksManager::callCallouts(Dhcpv6Srv::getHookIndexBuffer6Send(),
121  *callout_handle);
122 
123  // Callouts decided to skip the next processing step. The next
124  // processing step would to parse the packet, so skip at this
125  // stage means drop.
126  if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
127  (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
129  DHCP6_HOOK_BUFFER_SEND_SKIP)
130  .arg(pkt->getLabel());
131  return;
132  }
133 
134  callout_handle->getArgument("response6", pkt);
135  }
136 
137  LOG_DEBUG(packet6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_RESPONSE_DATA)
138  .arg(static_cast<int>(pkt->getType())).arg(pkt->toText());
139 
140  // Forward packet to the client.
141  IfaceMgr::instance().send(pkt);
142 
143  // Update statistics accordingly for sent packet.
145 
146  } catch (const std::exception& e) {
147  LOG_ERROR(packet6_logger, DHCP6_DHCP4O6_SEND_FAIL).arg(e.what());
148  }
149 }
150 
151 }; // namespace dhcp
152 
153 }; // namespace isc
isc::dhcp::IfaceMgr::send
bool send(const Pkt6Ptr &pkt)
Sends an IPv6 packet.
Definition: iface_mgr.cc:953
dhcp6to4_ipc.h
isc::dhcp::Dhcp6to4Ipc::instance
static Dhcp6to4Ipc & instance()
Returns pointer to the sole instance of Dhcp6to4Ipc.
Definition: dhcp6to4_ipc.cc:32
hooks_log.h
LOG_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
isc::dhcp::CfgMgr::instance
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
isc::dhcp::Dhcp6to4Ipc::open
virtual void open()
Open communication socket.
Definition: dhcp6to4_ipc.cc:37
isc::dhcp::Dhcp4o6IpcBase::open
virtual void open()=0
Open communication socket (for derived classes).
iface_mgr.h
isc::dhcp::DBG_DHCP6_HOOKS
const int DBG_DHCP6_HOOKS
Debug level used to trace hook related operations.
Definition: dhcp6_log.h:33
isc::dhcp::Dhcp4o6IpcBase::close
void close()
Close communication socket.
Definition: dhcp4o6_ipc.cc:118
isc::dhcp::Dhcp4o6IpcBase::ENDPOINT_TYPE_V6
@ ENDPOINT_TYPE_V6
Definition: dhcp4o6_ipc.h:67
isc::hooks::CalloutHandlePtr
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
Definition: callout_handle.h:416
isc::hooks::hooks_logger
isc::log::Logger hooks_logger("hooks")
Hooks Logger.
Definition: hooks_log.h:37
isc::dhcp::packet6_logger
isc::log::Logger packet6_logger(DHCP6_PACKET_LOGGER_NAME)
Logger for processed packets.
Definition: dhcp6_log.h:99
isc::dhcp::Dhcpv6Srv::getHookIndexBuffer6Send
static int getHookIndexBuffer6Send()
Returns the index of the buffer6_send hook.
Definition: dhcp6_srv.cc:3810
hooks_manager.h
pkt6.h
isc::dhcp::ScopedEnableOptionsCopy
RAII object enabling copying options retrieved from the packet.
Definition: pkt.h:40
isc::dhcp::Dhcp4o6IpcBase::socket_fd_
int socket_fd_
Socket descriptor.
Definition: dhcp4o6_ipc.h:125
isc::dhcp::Dhcp4o6IpcBase::receive
Pkt6Ptr receive()
Receive message over IPC.
Definition: dhcp4o6_ipc.cc:127
isc::dhcp::Dhcp6to4Ipc::handler
static void handler()
On receive handler.
Definition: dhcp6to4_ipc.cc:55
isc::dhcp::Dhcpv6Srv::checkRelaySourcePort
static uint16_t checkRelaySourcePort(const Pkt6Ptr &query)
Used for DHCPv4-over-DHCPv6 too.
Definition: dhcp6_srv.cc:3715
isc::dhcp::Dhcp4o6IpcBase
This class implements the communication between the DHCPv4 and DHCPv6 servers to allow for transmissi...
Definition: dhcp4o6_ipc.h:61
isc
Defines the logger used by the top-level component of kea-dhcp-ddns.
Definition: agent_parser.cc:144
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:192
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
isc::dhcp::Dhcp6to4Ipc
Handles DHCPv4-over-DHCPv6 IPC on the DHCPv6 server side.
Definition: dhcp6to4_ipc.h:21
isc::util::OutputBuffer::clear
void clear()
Clear buffer content.
Definition: buffer.h:448
isc::dhcp::IfaceMgr::instance
static IfaceMgr & instance()
IfaceMgr is a singleton class.
Definition: iface_mgr.cc:53
dhcp6_log.h
DHCPV6_RELAY_FORW
@ DHCPV6_RELAY_FORW
Definition: dhcp6.h:224
isc::util::OutputBuffer
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
isc::dhcp::Dhcpv6Srv::processStatsSent
static void processStatsSent(const Pkt6Ptr &response)
Updates statistics for transmitted packets.
Definition: dhcp6_srv.cc:3786
stats_mgr.h
buffer.h
dhcp6_srv.h
callout_handle_store.h
isc::dhcp::CfgMgr::getStagingCfg
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
Definition: cfgmgr.cc:160
isc::dhcp::IfaceMgr::addExternalSocket
void addExternalSocket(int socketfd, SocketCallback callback)
Adds external socket and a callback.
Definition: iface_mgr.cc:317
cfgmgr.h
isc::OutOfRange
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
Definition: exceptions/exceptions.h:115
exceptions.h
isc::dhcp::DBG_DHCP6_DETAIL_DATA
const int DBG_DHCP6_DETAIL_DATA
This level is used to log the contents of packets received and sent.
Definition: dhcp6_log.h:53
isc::hooks
Definition: callout_handle.cc:21
callout_handle.h
isc::dhcp::DBG_DHCP6_DETAIL
const int DBG_DHCP6_DETAIL
Debug level used to trace detailed errors.
Definition: dhcp6_log.h:50
DHCPV6_RELAY_REPL
@ DHCPV6_RELAY_REPL
Definition: dhcp6.h:225
ctrl_dhcp6_srv.h
isc::dhcp::Pkt6Ptr
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Definition: pkt6.h:28
isc::dhcp::DBG_DHCP6_BASIC
const int DBG_DHCP6_BASIC
Debug level used to trace basic operations within the code.
Definition: dhcp6_log.h:30
isc::dhcp::getCalloutHandle
isc::hooks::CalloutHandlePtr getCalloutHandle(const T &pktptr)
CalloutHandle Store.
Definition: callout_handle_store.h:47