Kea 3.1.8
radius_request.cc
Go to the documentation of this file.
1// Copyright (C) 2020-2026 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 <radius_request.h>
10#include <radius_access.h>
11#include <radius_accounting.h>
12#include <radius_log.h>
13#include <sstream>
14
15using namespace isc::asiolink;
16using namespace isc::dhcp;
17using namespace isc::radius;
18using namespace std;
19namespace ph = std::placeholders;
20
21namespace isc {
22namespace radius {
23
24uint32_t getNASPort(uint32_t subnet_id) {
25 const map<uint32_t, uint32_t>& remap = RadiusImpl::instance().remap_;
26 auto const by_id = remap.find(subnet_id);
27 if (by_id != remap.end()) {
28 return (by_id->second);
29 }
30 auto const by_id0 = remap.find(SUBNET_ID_DEFAULT);
31 if (by_id0 != remap.end()) {
32 return (by_id0->second);
33 }
34 return (subnet_id);
35}
36
38 uint32_t subnet_id,
39 const AttributesPtr& send_attrs,
40 bool sync,
41 const Exchange::Handler& handler) {
42 AttributesPtr attrs;
43 if (send_attrs) {
44 attrs.reset(new Attributes(*send_attrs));
45 } else {
46 attrs.reset(new Attributes());
47 }
48 nas_port_ = getNASPort(subnet_id);
49 if (!attrs->get(PW_NAS_PORT)) {
51 }
52 MessagePtr request(new Message(code, 0, vector<uint8_t>(),
53 "to-be-set", attrs));
54 unsigned maxretries = RadiusImpl::instance().retries_;
55 Servers servers;
56 if (code == PW_ACCESS_REQUEST) {
58 } else {
60 }
61 if (sync) {
62 exchange_ = Exchange::create(request, maxretries, servers);
63 } else {
65 request, maxretries, servers, handler,
66 RadiusImpl::instance().proto_);
67 }
68}
69
70void
72 AttributesPtr send_attrs;
73 MessagePtr request = exchange_->getRequest();
74 if (request) {
75 send_attrs = request->getAttributes();
76 }
78 .arg(nas_port_)
79 .arg(send_attrs ? send_attrs->toText() : "no attributes");
80
82
83 int result = getRC();
84 AttributesPtr recv_attrs = getRespAttrs();
85 if (result == OK_RC) {
88 .arg(recv_attrs ? recv_attrs->toText() : "no attributes");
90 } else if (result == REJECT_RC) {
93 .arg(recv_attrs ? recv_attrs->toText() : "no attributes");
95 } else {
98 .arg(result)
99 .arg(exchangeRCtoText(result));
100 }
101
102 if (callback_) {
103 try {
104 callback_(result, recv_attrs);
105 } catch (...) {
106 }
107 }
108 exchange_->shutdown();
109}
110
112 const AttributesPtr& send_attrs,
113 const CallbackAuth& callback)
114 : RadiusAuth(subnet_id, send_attrs, false,
116 callback, ph::_1)) {
117}
118
119void
121 AttributesPtr send_attrs;
122 MessagePtr request = exchange_->getRequest();
123 if (request) {
124 send_attrs = request->getAttributes();
125 }
127 .arg(nas_port_)
128 .arg(send_attrs ? send_attrs->toText() : "no attributes");
129
131}
132
133void
135 const ExchangePtr exchange) {
136 // Should no happen...
137 if (!exchange) {
138 return;
139 }
140 int result = exchange->getRC();
141 AttributesPtr recv_attrs;
142 MessagePtr response = exchange->getResponse();
143 if (response) {
144 recv_attrs = response->getAttributes();
145 }
146 if (result == OK_RC) {
149 .arg(recv_attrs ? recv_attrs->toText() : "no attributes");
151 } else if (result == REJECT_RC) {
154 .arg(recv_attrs ? recv_attrs->toText() : "no attributes");
156 } else {
159 .arg(result)
160 .arg(exchangeRCtoText(result));
161 }
162
163 if (callback) {
164 try {
165 callback(result, recv_attrs);
166 } catch (...) {
167 }
168 }
169 exchange->shutdown();
171}
172
173void
175 AttributesPtr send_attrs;
176 MessagePtr request = exchange_->getRequest();
177 if (request) {
178 send_attrs = request->getAttributes();
179 }
181 .arg(nas_port_)
182 .arg(send_attrs ? send_attrs->toText() : "no attributes");
183
185
186 int result = getRC();
187 if (result == OK_RC) {
191 } else {
194 .arg(result)
195 .arg(exchangeRCtoText(result));
196 }
197
198 if (callback_) {
199 try {
200 callback_(result);
201 } catch (...) {
202 }
203 }
204 exchange_->shutdown();
205}
206
208 const AttributesPtr& send_attrs,
209 const CallbackAcct& callback)
210 : RadiusAcct(subnet_id, send_attrs, false,
212 callback, ph::_1)) {
213}
214
215void
217 AttributesPtr send_attrs;
218 MessagePtr request = exchange_->getRequest();
219 if (request) {
220 send_attrs = request->getAttributes();
221 }
223 .arg(nas_port_)
224 .arg(send_attrs ? send_attrs->toText() : "no attributes");
225
227}
228
229void
231 const ExchangePtr exchange) {
232 // Should not happen...
233 if (!exchange) {
234 return;
235 }
236 int result = exchange->getRC();
237 if (result == OK_RC) {
241 } else {
244 .arg(result)
245 .arg(exchangeRCtoText(result));
246 }
247
248 if (callback) {
249 try {
250 callback(result);
251 } catch (...) {
252 }
253 }
254 exchange->shutdown();
256}
257
258} // end of namespace radius
259} // end of namespace isc
static AttributePtr fromInt(const uint8_t type, const uint32_t value)
From integer with type.
Collection of attributes.
std::function< void(const ExchangePtr ex)> Handler
Termination handler.
static ExchangePtr create(const asiolink::IOServicePtr io_service, const MessagePtr &request, unsigned maxretries, const Servers &servers, Handler handler, RadiusProtocol protocol=PW_PROTO_UDP)
Factory.
RADIUS Message.
RadiusAcct(uint32_t subnet_id, const AttributesPtr &send_attrs, bool sync, const Exchange::Handler &handler)
Constructor.
static void invokeCallback(const CallbackAcct &callback, const ExchangePtr exchange)
Invoke accounting communication callback.
virtual void start() override
Start communication.
RadiusAsyncAcct(uint32_t subnet_id, const AttributesPtr &send_attrs, const CallbackAcct &callback)
Constructor.
static void invokeCallback(const CallbackAuth &callback, const ExchangePtr exchange)
Invoke authentication communication callback.
virtual void start() override
Start communication.
RadiusAsyncAuth(uint32_t subnet_id, const AttributesPtr &send_attrs, const CallbackAuth &callback)
Constructor.
RadiusAuth(uint32_t subnet_id, const AttributesPtr &send_attrs, bool sync, const Exchange::Handler &handler)
Constructor.
void setAccountingIdleTimer()
Set the accounting idle timer.
Definition radius.cc:420
const Servers & getAccessServers() const
Get servers for access.
Definition radius.cc:390
void unregisterExchange(ExchangePtr exchange)
Unregister Exchange.
Definition radius.cc:202
unsigned retries_
Retries.
Definition radius.h:320
std::map< uint32_t, uint32_t > remap_
Subnet ID to NAS port map.
Definition radius.h:278
const Servers & getAccountingServers() const
Get servers for accounting.
Definition radius.cc:399
void setAccessIdleTimer()
Set the access idle timer.
Definition radius.cc:408
static RadiusImpl & instance()
RadiusImpl is a singleton class.
Definition radius.cc:163
int getRC() const
Get the error code.
RadiusRequest(const MsgCode code, uint32_t subnet_id, const AttributesPtr &send_attrs, bool sync, const Exchange::Handler &handler)
Constructor.
AttributesPtr getRespAttrs() const
Get response attributes.
virtual void start()
Start communication.
uint32_t nas_port_
Client/NAS port (from Subnet Id).
ExchangePtr exchange_
Exchange.
virtual void start() override
Start communication.
CallbackAcct callback_
Accounting termination callback.
CallbackAuth callback_
Authentication termination callback.
virtual void start() override
Start communication.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
const isc::log::MessageID RADIUS_AUTHENTICATION_SYNC_FAILED
const isc::log::MessageID RADIUS_AUTHENTICATION_ASYNC_FAILED
const isc::log::MessageID RADIUS_ACCOUNTING_ASYNC_SUCCEED
const isc::log::MessageID RADIUS_ACCOUNTING_SYNC_SUCCEED
const isc::log::MessageID RADIUS_AUTHENTICATION_ASYNC
const isc::log::MessageID RADIUS_AUTHENTICATION_SYNC
boost::shared_ptr< Attributes > AttributesPtr
Shared pointers to attribute collection.
std::function< void(int)> CallbackAcct
Type of callback for accounting termination.
const isc::log::MessageID RADIUS_ACCOUNTING_SYNC
string exchangeRCtoText(const int rc)
ExchangeRC value -> name function.
const isc::log::MessageID RADIUS_AUTHENTICATION_SYNC_REJECTED
std::vector< ServerPtr > Servers
Type of RADIUS server collection.
boost::shared_ptr< Exchange > ExchangePtr
Type of shared pointers to RADIUS exchange object.
const isc::log::MessageID RADIUS_ACCOUNTING_SYNC_FAILED
const int RADIUS_DBG_TRACE
Radius logging levels.
Definition radius_log.h:26
const isc::log::MessageID RADIUS_ACCOUNTING_ASYNC_FAILED
const isc::log::MessageID RADIUS_ACCOUNTING_ASYNC
const isc::log::MessageID RADIUS_AUTHENTICATION_SYNC_ACCEPTED
std::function< void(int, AttributesPtr)> CallbackAuth
Type of callback for authentication termination.
isc::log::Logger radius_logger("radius-hooks")
Radius Logger.
Definition radius_log.h:35
boost::shared_ptr< Message > MessagePtr
Shared pointers to message.
MsgCode
Standard RADIUS message code.
uint32_t getNASPort(uint32_t subnet_id)
Remap a subnet ID to a NAS port.
const isc::log::MessageID RADIUS_AUTHENTICATION_ASYNC_ACCEPTED
const isc::log::MessageID RADIUS_AUTHENTICATION_ASYNC_REJECTED
Defines the logger used by the top-level component of kea-lfc.