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>
17#include <dhcp6/dhcp6_srv.h>
20#include <hooks/hooks_log.h>
21#include <hooks/hooks_manager.h>
22#include <stats/stats_mgr.h>
23
24using namespace std;
25using namespace isc::hooks;
26
27namespace isc {
28namespace dhcp {
29
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
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
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.
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
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
Definition: cfgmgr.cc:160
This class implements the communication between the DHCPv4 and DHCPv6 servers to allow for transmissi...
Definition: dhcp4o6_ipc.h:61
Pkt6Ptr receive()
Receive message over IPC.
Definition: dhcp4o6_ipc.cc:127
void close()
Close communication socket.
Definition: dhcp4o6_ipc.cc:118
virtual void open()=0
Open communication socket (for derived classes).
int socket_fd_
Socket descriptor.
Definition: dhcp4o6_ipc.h:125
Handles DHCPv4-over-DHCPv6 IPC on the DHCPv6 server side.
Definition: dhcp6to4_ipc.h:21
Dhcp6to4Ipc()
Constructor.
Definition: dhcp6to4_ipc.cc:30
virtual void open()
Open communication socket.
Definition: dhcp6to4_ipc.cc:37
static Dhcp6to4Ipc & instance()
Returns pointer to the sole instance of Dhcp6to4Ipc.
Definition: dhcp6to4_ipc.cc:32
static void handler()
On receive handler.
Definition: dhcp6to4_ipc.cc:55
static void processStatsSent(const Pkt6Ptr &response)
Updates statistics for transmitted packets.
Definition: dhcp6_srv.cc:3786
static uint16_t checkRelaySourcePort(const Pkt6Ptr &query)
Used for DHCPv4-over-DHCPv6 too.
Definition: dhcp6_srv.cc:3715
static int getHookIndexBuffer6Send()
Returns the index of the buffer6_send hook.
Definition: dhcp6_srv.cc:3810
static IfaceMgr & instance()
IfaceMgr is a singleton class.
Definition: iface_mgr.cc:53
void addExternalSocket(int socketfd, SocketCallback callback)
Adds external socket and a callback.
Definition: iface_mgr.cc:317
bool send(const Pkt6Ptr &pkt)
Sends an IPv6 packet.
Definition: iface_mgr.cc:953
RAII object enabling copying options retrieved from the packet.
Definition: pkt.h:40
@ NEXT_STEP_DROP
drop the packet
@ NEXT_STEP_SKIP
skip the next processing step
static bool calloutsPresent(int index)
Are callouts present?
static void callCallouts(int index, CalloutHandle &handle)
Calls the callouts for a given hook.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
void clear()
Clear buffer content.
Definition: buffer.h:448
@ DHCPV6_RELAY_REPL
Definition: dhcp6.h:225
@ DHCPV6_RELAY_FORW
Definition: dhcp6.h:224
Defines the Dhcp6to4Ipc class.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
const int DBG_DHCP6_HOOKS
Debug level used to trace hook related operations.
Definition: dhcp6_log.h:33
isc::log::Logger packet6_logger(DHCP6_PACKET_LOGGER_NAME)
Logger for processed packets.
Definition: dhcp6_log.h:99
isc::hooks::CalloutHandlePtr getCalloutHandle(const T &pktptr)
CalloutHandle Store.
const int DBG_DHCP6_DETAIL_DATA
This level is used to log the contents of packets received and sent.
Definition: dhcp6_log.h:53
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Definition: pkt6.h:31
const int DBG_DHCP6_BASIC
Debug level used to trace basic operations within the code.
Definition: dhcp6_log.h:30
const int DBG_DHCP6_DETAIL
Debug level used to trace detailed errors.
Definition: dhcp6_log.h:50
isc::log::Logger hooks_logger("hooks")
Hooks Logger.
Definition: hooks_log.h:37
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
Defines the logger used by the top-level component of kea-dhcp-ddns.