Kea  2.3.3-git
dhcp6to4_ipc.cc
Go to the documentation of this file.
1 // Copyright (C) 2015-2022 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 uint16_t Dhcp6to4Ipc::client_port = 0;
31 
32 Dhcp6to4Ipc::Dhcp6to4Ipc() : Dhcp4o6IpcBase() {}
33 
35  static Dhcp6to4Ipc dhcp6to4_ipc;
36  return (dhcp6to4_ipc);
37 }
38 
40  uint16_t port = CfgMgr::instance().getStagingCfg()->getDhcp4o6Port();
41  if (port == 0) {
43  return;
44  }
45  if (port > 65534) {
46  isc_throw(OutOfRange, "DHCP4o6 port " << port);
47  }
48 
49  int old_fd = socket_fd_;
51  if ((old_fd == -1) && (socket_fd_ != old_fd)) {
54  }
55 }
56 
57 void Dhcp6to4Ipc::handler(int /* fd */) {
59  Pkt6Ptr pkt;
60 
61  try {
63  // Receive message from IPC.
64  pkt = ipc.receive();
65 
66  if (pkt) {
68  .arg(static_cast<int>(pkt->getType()))
69  .arg(pkt->getRemoteAddr().toText())
70  .arg(pkt->getRemotePort())
71  .arg(pkt->getIface());
72  }
73  } catch (const std::exception& e) {
75  .arg(e.what());
76  }
77 
78  if (!pkt) {
79  return;
80  }
81 
82  // Should we check it is a DHCPV6_DHCPV4_RESPONSE?
83 
84  // Handle relay port
85  uint16_t relay_port = Dhcpv6Srv::checkRelaySourcePort(pkt);
86 
87  // The received message has been unpacked by the receive() function. This
88  // method could have modified the message so it's better to pack() it
89  // again because we'll be forwarding it to a client.
90  isc::util::OutputBuffer& buf = pkt->getBuffer();
91  buf.clear();
92  pkt->pack();
93 
94  // Don't use getType(): get the message type from the buffer as we
95  // want to know if it is a relayed message (vs. internal message type).
96  // getType() always returns the type of internal message.
97  uint8_t msg_type = buf[0];
98  if (client_port) {
99  pkt->setRemotePort(client_port);
100  } else if ((msg_type == DHCPV6_RELAY_FORW) ||
101  (msg_type == DHCPV6_RELAY_REPL)) {
102  pkt->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
103  } else {
104  pkt->setRemotePort(DHCP6_CLIENT_PORT);
105  }
106 
107  // Can't call the pkt6_send callout because we don't have the query
108  // From Dhcpv6Srv::processPacketBufferSend
109 
110  try {
111  // Let's execute all callouts registered for buffer6_send
112  if (HooksManager::calloutsPresent(Dhcpv6Srv::getHookIndexBuffer6Send())) {
113  CalloutHandlePtr callout_handle = getCalloutHandle(pkt);
114 
115  // Delete previously set arguments
116  callout_handle->deleteAllArguments();
117 
118  // Use the RAII wrapper to make sure that the callout handle state is
119  // reset when this object goes out of scope. All hook points must do
120  // it to prevent possible circular dependency between the callout
121  // handle and its arguments.
122  ScopedCalloutHandleState callout_handle_state(callout_handle);
123 
124  // Enable copying options from the packet within hook library.
125  ScopedEnableOptionsCopy<Pkt6> response6_options_copy(pkt);
126 
127  // Pass incoming packet as argument
128  callout_handle->setArgument("response6", pkt);
129 
130  // Call callouts
131  HooksManager::callCallouts(Dhcpv6Srv::getHookIndexBuffer6Send(),
132  *callout_handle);
133 
134  // Callouts decided to skip the next processing step. The next
135  // processing step would be to parse the packet, so skip at this
136  // stage means drop.
137  if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
138  (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
141  .arg(pkt->getLabel());
142  return;
143  }
144 
145  callout_handle->getArgument("response6", pkt);
146  }
147 
149  .arg(static_cast<int>(pkt->getType())).arg(pkt->toText());
150 
151  // Forward packet to the client.
152  IfaceMgr::instance().send(pkt);
153 
154  // Update statistics accordingly for sent packet.
156 
157  } catch (const std::exception& e) {
159  }
160 }
161 
162 } // namespace dhcp
163 
164 } // namespace isc
165 
static uint16_t client_port
Definition: dhcp6to4_ipc.h:51
const isc::log::MessageID DHCP6_DHCP4O6_RECEIVE_FAIL
isc::log::Logger packet6_logger(DHCP6_PACKET_LOGGER_NAME)
Logger for processed packets.
Definition: dhcp6_log.h:100
void addExternalSocket(int socketfd, SocketCallback callback)
Adds external socket and a callback.
Definition: iface_mgr.cc:325
static Dhcp6to4Ipc & instance()
Returns pointer to the sole instance of Dhcp6to4Ipc.
Definition: dhcp6to4_ipc.cc:34
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
const int DBG_DHCP6_HOOKS
Debug level used to trace hook related operations.
Definition: dhcp6_log.h:34
virtual void open()=0
Open communication socket (for derived classes).
const int DBG_DHCP6_BASIC
Debug level used to trace basic operations within the code.
Definition: dhcp6_log.h:31
static void processStatsSent(const Pkt6Ptr &response)
Updates statistics for transmitted packets.
Definition: dhcp6_srv.cc:4521
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
STL namespace.
This class implements the communication between the DHCPv4 and DHCPv6 servers to allow for transmissi...
Definition: dhcp4o6_ipc.h:61
virtual void open()
Open communication socket.
Definition: dhcp6to4_ipc.cc:39
RAII object enabling copying options retrieved from the packet.
Definition: pkt.h:40
Handles DHCPv4-over-DHCPv6 IPC on the DHCPv6 server side.
Definition: dhcp6to4_ipc.h:21
bool send(const Pkt6Ptr &pkt)
Sends an IPv6 packet.
Definition: iface_mgr.cc:1126
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Definition: pkt6.h:28
const isc::log::MessageID DHCP6_DHCP4O6_SEND_FAIL
const isc::log::MessageID DHCP6_DHCP4O6_RECEIVING
int socket_fd_
Socket descriptor.
Definition: dhcp4o6_ipc.h:125
const isc::log::MessageID DHCP6_HOOK_BUFFER_SEND_SKIP
Wrapper class around callout handle which automatically resets handle&#39;s state.
static int getHookIndexBuffer6Send()
Returns the index of the buffer6_send hook.
Definition: dhcp6_srv.cc:4545
Defines the Dhcp6to4Ipc class.
void clear()
Clear buffer content.
Definition: buffer.h:451
const int DBG_DHCP6_DETAIL
Debug level used to trace detailed errors.
Definition: dhcp6_log.h:51
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
Defines the logger used by the top-level component of kea-lfc.
const isc::log::MessageID DHCP6_RESPONSE_DATA
const int DBG_DHCP6_DETAIL_DATA
This level is used to log the contents of packets received and sent.
Definition: dhcp6_log.h:54
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
isc::log::Logger hooks_logger("hooks")
Hooks Logger.
Definition: hooks_log.h:37
const isc::log::MessageID DHCP6_DHCP4O6_PACKET_RECEIVED
static IfaceMgr & instance()
IfaceMgr is a singleton class.
Definition: iface_mgr.cc:53
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
Pkt6Ptr receive()
Receive message over IPC.
Definition: dhcp4o6_ipc.cc:127
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
void close()
Close communication socket.
Definition: dhcp4o6_ipc.cc:118
isc::hooks::CalloutHandlePtr getCalloutHandle(const T &pktptr)
CalloutHandle Store.
static void handler(int)
On receive handler.
Definition: dhcp6to4_ipc.cc:57
static uint16_t checkRelaySourcePort(const Pkt6Ptr &query)
Used for DHCPv4-over-DHCPv6 too.
Definition: dhcp6_srv.cc:4450
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
Definition: cfgmgr.cc:167