Kea: radius_accounting.cc Source File

| Kea 3.0.0

radius_accounting.cc
Go to the documentation of this file.
1// Copyright (C) 2020-2025 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 <asiolink/addr_utilities.h>
10#include <cc/simple_parser.h>
11#include <dhcpsrv/cfgmgr.h>
12#include <dhcpsrv/host_mgr.h>
13#include <dhcpsrv/subnet.h>
14#include <radius_accounting.h>
15#include <radius_log.h>
16#include <radius_utils.h>
17#include <util/multi_threading_mgr.h>
18#include <stdio.h>
19
20using namespace std;
21using namespace isc;
22using namespace isc::asiolink;
23using namespace isc::data;
24using namespace isc::dhcp;
25using namespace isc::util;
26using namespace boost::gregorian;
27using namespace boost::posix_time;
28namespace ph = std::placeholders;
29
30namespace isc {
31namespace radius {
32
33string
34eventToText(Event event) {
35 switch (event) {
36 case EVENT_CREATE:
37 return ("create");
38 case EVENT_RENEW:
39 return ("renew");
40 case EVENT_REBIND:
41 return ("rebind");
42 case EVENT_EXPIRE:
43 return ("expire");
44 case EVENT_RELEASE:
45 return ("release");
46 case EVENT_DECLINE:
47 return ("decline");
48 case EVENT_ADD:
49 return ("add");
50 case EVENT_UPDATE:
51 return ("update");
52 case EVENT_DEL:
53 return ("delete");
54 default:
55 return ("unknown");
56 }
57}
58
59RadiusAcctEnv::RadiusAcctEnv(std::string session_id, Event event,
60 uint32_t subnet_id,
61 AttributesPtr send_attrs)
62 : session_id_(session_id), event_(event), subnet_id_(subnet_id),
63 send_attrs_(send_attrs), finished_(false) {
64}
65
66RadiusAcctHandler::RadiusAcctHandler(RadiusAcctEnv env,
67 const CallbackAcct& callback)
68 : env_(env), acct_() {
69 acct_.reset(new RadiusAsyncAcct(env_.subnet_id_, env_.send_attrs_, callback));
70 RadiusImpl::instance().registerExchange(acct_->getExchange());
71 MultiThreadingLock lock(mutex_);
72 ++counter_;
73}
74
75RadiusAcctHandler::~RadiusAcctHandler() {
76 MultiThreadingLock lock(mutex_);
77 if (counter_ > 0) {
78 --counter_;
79 }
80}
81
82void
83RadiusAcctHandler::start() {
84 acct_->start();
85}
86
87size_t
88RadiusAcctHandler::getCounter() {
89 MultiThreadingLock lock(mutex_);
90 return (counter_);
91}
92
93size_t RadiusAcctHandler::counter_ = 0;
94
95mutex RadiusAcctHandler::mutex_;
96
97RadiusAccounting::RadiusAccounting()
98 : RadiusService("accounting"), epoch_(date(2018, 3, 7), hours(11)), record_count_(0) {
99}
100
101void
102RadiusAccounting::init(const std::string& filename) {
103 filename_ = filename;
104 if (!filename_.empty()) {
105 file_.reset(new CSVFile(filename_));
106
107 file_->addColumn("address");
108 file_->addColumn("seconds");
109 file_->addColumn("milliseconds");
110
111 if (file_->exists()) {
112 if (loadFromFile() && (container_.size() > 0)) {
113 storeToFile();
114 }
115 }
116 try {
117 file_->open(true);
118 LOG_INFO(radius_logger, RADIUS_SESSION_HISTORY_OPENED)
119 .arg(filename_);
120 } catch (const std::exception& ex) {
121 LOG_ERROR(radius_logger, RADIUS_SESSION_HISTORY_OPEN_FAILED)
122 .arg(filename_)
123 .arg(ex.what());
124 file_.reset();
125 }
126 }
127}
128
129 RadiusAcctHandlerPtr
130RadiusAccounting::buildAcct(const dhcp::Lease4Ptr& lease, Event event) {
131 AttributesPtr send(new Attributes());
132
133 // Add client-id and hardware address.
134 string hwaddr = lease->hwaddr_->toText(false);
135 if (RadiusImpl::instance().canonical_mac_address_) {
136 hwaddr = canonize(hwaddr);
137 }
138 if (lease->client_id_) {
139 vector<uint8_t> vec;
140 bool extracted = false;
141 if (RadiusImpl::instance().extract_duid_) {
142 vec = extractDuid(lease->client_id_, extracted);
143 }
144 // If case the DUID was not extracted, we will try to get the
145 // identifier using client-id.
146 if (!extracted) {
147 if (RadiusImpl::instance().clientid_pop0_) {
148 vec = pop0(lease->client_id_);
149 } else {
150 vec = lease->client_id_->getClientId();
151 }
152 }
153 string text;
154 if (RadiusImpl::instance().clientid_printable_) {
155 text = toPrintable(vec);
156 } else {
157 text = toHex(vec);
158 }
159
160 send->add(Attribute::fromString(PW_USER_NAME, text));
161 send->add(Attribute::fromString(PW_CALLING_STATION_ID, hwaddr));
162 } else {
163 send->add(Attribute::fromString(PW_USER_NAME, hwaddr));
164 }
165
166 // Add address.
167 send->add(Attribute::fromIpAddr(PW_FRAMED_IP_ADDRESS, lease->addr_));
168
169 // Get the create timestamp.
170 bool generate = false;
171 if ((event == EVENT_CREATE) || (event == EVENT_ADD)) {
172 generate = true;
173 }
174 ptime tm = getCreateTimestamp(lease->addr_, generate);
175
176 // Build the session Id.
177 ostringstream stream;
178 stream << lease->addr_.toText() << '@';
179 time_duration rtm(tm - epoch_);
180 stream << rtm.total_seconds() << ".";
181 rtm -= seconds(rtm.total_seconds());
182 stream << rtm.total_milliseconds();
183 send->add(Attribute::fromString(PW_ACCT_SESSION_ID, stream.str()));
184
185 // Accounting status type.
186 uint32_t status = PW_STATUS_ALIVE;
187 if (generate) {
188 status = PW_STATUS_START;
189 } else if ((event == EVENT_EXPIRE) ||
190 (event == EVENT_RELEASE) ||
191 (event == EVENT_DECLINE) ||
192 (event == EVENT_DEL)) {
193 status = PW_STATUS_STOP;
194 }
195 send->add(Attribute::fromInt(PW_ACCT_STATUS_TYPE, status));
196
197 // Add class: get host identifier.
198 Host::IdentifierType id_type = RadiusImpl::instance().id_type4_;
199 vector<uint8_t> host_id;
200 switch (id_type) {
201 case Host::IDENT_HWADDR:
202 host_id = lease->hwaddr_->hwaddr_;
203 break;
204 case Host::IDENT_DUID:
205 if (lease->client_id_) {
206 host_id = lease->client_id_->getClientId();
207 if ((host_id.size() <= 5) ||
208 (host_id[0] != CLIENT_ID_OPTION_TYPE_DUID)) {
209 host_id.clear();
210 } else {
211 host_id = vector<uint8_t>(host_id.begin() + 5, host_id.end());
212 }
213 }
214 break;
215 case Host::IDENT_CLIENT_ID:
216 if (lease->client_id_) {
217 host_id = lease->client_id_->getClientId();
218 }
219 break;
220 case Host::IDENT_FLEX:
221 if (lease->client_id_) {
222 host_id = lease->client_id_->getClientId();
223 if ((host_id.size() <= 1) || (host_id[0] != 0)) {
224 host_id.clear();
225 } else {
226 host_id = vector<uint8_t>(host_id.begin() + 1, host_id.end());
227 }
228 }
229 break;
230 default:
231 // not supported.
232 break;
233 }
234
235 // Add class: get host entry.
236 ConstHostPtr host;
237 if (!host_id.empty()) {
238 uint32_t subnet_id = lease->subnet_id_;
239 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
240 getCfgSubnets4()->getBySubnetId(subnet_id);
241 if (subnet && subnet->getReservationsGlobal()) {
242 subnet_id = SUBNET_ID_GLOBAL;
243 }
244 host = HostMgr::instance().get4Any(subnet_id, id_type,
245 &host_id[0], host_id.size());
246 }
247 // Add class: get cached Class attribute.
248 // @todo: extend and make configurable with a list of attributes.
249 if (host && host->getContext() &&
250 (host->getContext()->getType() == Element::map)) {
251 Attributes cached_attrs =
252 Attributes::fromElement(host->getContext()->get("radius"));
253 send->add(cached_attrs.get(PW_CLASS));
254 }
255
256 // Add attributes from configuration.
257 send->append(RadiusImpl::instance().acct_->attributes_.getAll());
258
259 // Return the handler.
260 RadiusAcctEnv env(stream.str(), event, lease->subnet_id_, send);
261 RadiusAcctHandlerPtr handler;
262 handler.reset(new RadiusAcctHandler(
263 env, std::bind(&RadiusAccounting::terminate, env, ph::_1)));
264
265 // Erase create timestamp on stop.
266 if (status == PW_STATUS_STOP) {
267 eraseCreateTimestamp(lease->addr_);
268 }
269
270 return (handler);
271}
272
273 RadiusAcctHandlerPtr
274 RadiusAccounting::buildAcct(const dhcp::Lease6Ptr& lease, Event event) {
275 AttributesPtr send(new Attributes());
276
277 // Add duid.
278 vector<uint8_t> vec;
279 if (RadiusImpl::instance().clientid_pop0_) {
280 vec = pop0(lease->duid_);
281 } else {
282 vec = lease->duid_->getDuid();
283 }
284 string text;
285 if (RadiusImpl::instance().clientid_printable_) {
286 text = toPrintable(vec);
287 } else {
288 text = toHex(vec);
289 }
290 send->add(Attribute::fromString(PW_USER_NAME, text));
291
292 // Add hardware address.
293 if (lease->hwaddr_) {
294 string hwaddr = lease->hwaddr_->toText(false);
295 if (RadiusImpl::instance().canonical_mac_address_) {
296 hwaddr = canonize(hwaddr);
297 }
298 send->add(Attribute::fromString(PW_CALLING_STATION_ID, hwaddr));
299 }
300
301 // Add address or prefix.
302 if (lease->type_ != Lease::TYPE_PD) {
303 send->add(Attribute::fromIpv6Addr(PW_FRAMED_IPV6_ADDRESS, lease->addr_));
304 } else {
305 send->add(Attribute::fromIpv6Prefix(PW_DELEGATED_IPV6_PREFIX,
306 lease->prefixlen_, lease->addr_));
307 }
308
309 // Get the create timestamp.
310 bool generate = false;
311 if ((event == EVENT_CREATE) || (event == EVENT_ADD)) {
312 generate = true;
313 }
314 ptime tm = getCreateTimestamp(lease->addr_, generate);
315
316 // Build the session Id.
317 ostringstream stream;
318 stream << lease->addr_.toText() << '@';
319 time_duration rtm(tm - epoch_);
320 stream << rtm.total_seconds() << ".";
321 rtm -= seconds(rtm.total_seconds());
322 stream << rtm.total_milliseconds();
323 send->add(Attribute::fromString(PW_ACCT_SESSION_ID, stream.str()));
324
325 // Accounting status type.
326 uint32_t status = PW_STATUS_ALIVE;
327 if (generate) {
328 status = PW_STATUS_START;
329 } else if ((event == EVENT_EXPIRE) ||
330 (event == EVENT_RELEASE) ||
331 (event == EVENT_DECLINE) ||
332 (event == EVENT_DEL)) {
333 status = PW_STATUS_STOP;
334 }
335 send->add(Attribute::fromInt(PW_ACCT_STATUS_TYPE, status));
336
337 // Add class: get host identifier.
338 Host::IdentifierType id_type = RadiusImpl::instance().id_type6_;
339 vector<uint8_t> host_id;
340 switch (id_type) {
341 case Host::IDENT_DUID:
342 host_id = lease->duid_->getDuid();
343 break;
344 case Host::IDENT_HWADDR:
345 if (lease->hwaddr_) {
346 host_id = lease->hwaddr_->hwaddr_;
347 }
348 break;
349 case Host::IDENT_FLEX:
350 host_id = lease->duid_->getDuid();
351 if ((host_id.size() <= 2) ||
352 (host_id[0] != 0) || (host_id[1] != 0)) {
353 host_id.clear();
354 } else {
355 host_id = vector<uint8_t>(host_id.begin() + 2, host_id.end());
356 }
357 break;
358 default:
359 // not supported.
360 break;
361 }
362
363 // Add class: get host entry.
364 ConstHostPtr host;
365 if (!host_id.empty()) {
366 uint32_t subnet_id = lease->subnet_id_;
367 ConstSubnet6Ptr subnet = CfgMgr::instance().getCurrentCfg()->
368 getCfgSubnets6()->getBySubnetId(subnet_id);
369 if (subnet && subnet->getReservationsGlobal()) {
370 subnet_id = SUBNET_ID_GLOBAL;
371 }
372 host = HostMgr::instance().get6Any(subnet_id, id_type,
373 &host_id[0], host_id.size());
374 }
375 // Add class: get cached Class attribute.
376 // @todo: extend and make configurable with a list of attributes.
377 if (host && host->getContext() &&
378 (host->getContext()->getType() == Element::map)) {
379 Attributes cached_attrs =
380 Attributes::fromElement(host->getContext()->get("radius"));
381 send->add(cached_attrs.get(PW_CLASS));
382 }
383
384 // Add attributes from configuration.
385 send->append(RadiusImpl::instance().acct_->attributes_.getAll());
386
387 // Return the handler.
388 RadiusAcctEnv env(stream.str(), event, lease->subnet_id_, send);
389 RadiusAcctHandlerPtr handler;
390 handler.reset(new RadiusAcctHandler(
391 env, std::bind(&RadiusAccounting::terminate, env, ph::_1)));
392
393 // Erase create timestamp on stop.
394 if (status == PW_STATUS_STOP) {
395 eraseCreateTimestamp(lease->addr_);
396 }
397
398 return (handler);
399}
400
401 RadiusAcctHandlerPtr
402RadiusAccounting::buildAcct4(const ConstElementPtr& arguments, Event event) {
403 IOAddress addr(0);
404 uint32_t subnet_id = SUBNET_ID_UNUSED;
405 HWAddrPtr hwaddr;
406 ClientIdPtr client_id;
407 bool force = false;
408 try {
409 // Parse arguments.
410 addr = SimpleParser::getAddress(arguments, "ip-address");
411 subnet_id = SimpleParser::getInteger(arguments, "subnet-id");
412 string hwaddr_txt = SimpleParser::getString(arguments, "hw-address");
413 hwaddr.reset(new HWAddr(HWAddr::fromText(hwaddr_txt)));
414
415 if (arguments->contains("client-id")) {
416 string txt = SimpleParser::getString(arguments, "client-id");
417 client_id = ClientId::fromText(txt);
418 }
419
420 if (arguments->contains("force-create")) {
421 force = SimpleParser::getBoolean(arguments, "force-create");
422 }
423 } catch (const std::exception&) {
424 return (RadiusAcctHandlerPtr());
425 }
426 if (!addr.isV4()) {
427 return (RadiusAcctHandlerPtr());
428 }
429
430 // Fill attributes.
431 AttributesPtr send(new Attributes());
432
433 // Add client-id and hardware address.
434 string mac = hwaddr->toText(false);
435 if (RadiusImpl::instance().canonical_mac_address_) {
436 mac = canonize(mac);
437 }
438 if (client_id) {
439 vector<uint8_t> vec;
440 bool extracted = false;
441 if (RadiusImpl::instance().extract_duid_) {
442 vec = extractDuid(client_id, extracted);
443 }
444 // If case the DUID was not extracted, we will try to get the
445 // identifier using client-id.
446 if (!extracted) {
447 if (RadiusImpl::instance().clientid_pop0_) {
448 vec = pop0(client_id);
449 } else {
450 vec = client_id->getClientId();
451 }
452 }
453 string text;
454 if (RadiusImpl::instance().clientid_printable_) {
455 text = toPrintable(vec);
456 } else {
457 text = toHex(vec);
458 }
459
460 send->add(Attribute::fromString(PW_USER_NAME, text));
461 send->add(Attribute::fromString(PW_CALLING_STATION_ID, mac));
462 } else {
463 send->add(Attribute::fromString(PW_USER_NAME, mac));
464 }
465
466 // Add address.
467 send->add(Attribute::fromIpAddr(PW_FRAMED_IP_ADDRESS, addr));
468
469 // Get the create timestamp.
470 bool generate = false;
471 if ((event == EVENT_ADD) && force) {
472 generate = true;
473 }
474 ptime tm = getCreateTimestamp(addr, generate);
475
476 // Build the session Id.
477 ostringstream stream;
478 stream << addr << '@';
479 time_duration rtm(tm - epoch_);
480 stream << rtm.total_seconds() << ".";
481 rtm -= seconds(rtm.total_seconds());
482 stream << rtm.total_milliseconds();
483 send->add(Attribute::fromString(PW_ACCT_SESSION_ID, stream.str()));
484
485 // Accounting status type.
486 uint32_t status = PW_STATUS_ALIVE;
487 if (generate) {
488 status = PW_STATUS_START;
489 } else if (event == EVENT_DEL) {
490 status = PW_STATUS_STOP;
491 }
492 send->add(Attribute::fromInt(PW_ACCT_STATUS_TYPE, status));
493
494 // Add class: get host identifier.
495 Host::IdentifierType id_type = RadiusImpl::instance().id_type4_;
496 vector<uint8_t> host_id;
497 switch (id_type) {
498 case Host::IDENT_HWADDR:
499 host_id = hwaddr->hwaddr_;
500 break;
501 case Host::IDENT_DUID:
502 if (client_id) {
503 host_id = client_id->getClientId();
504 if ((host_id.size() <= 5) ||
505 (host_id[0] != CLIENT_ID_OPTION_TYPE_DUID)) {
506 host_id.clear();
507 } else {
508 host_id = vector<uint8_t>(host_id.begin() + 5, host_id.end());
509 }
510 }
511 break;
512 case Host::IDENT_CLIENT_ID:
513 if (client_id) {
514 host_id = client_id->getClientId();
515 }
516 break;
517 case Host::IDENT_FLEX:
518 if (client_id) {
519 host_id = client_id->getClientId();
520 if ((host_id.size() <= 1) || (host_id[0] != 0)) {
521 host_id.clear();
522 } else {
523 host_id = vector<uint8_t>(host_id.begin() + 1, host_id.end());
524 }
525 }
526 break;
527 default:
528 // not supported.
529 break;
530 }
531
532 // Add class: get host entry.
533 ConstHostPtr host;
534 if (!host_id.empty()) {
535 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
536 getCfgSubnets4()->getBySubnetId(subnet_id);
537 uint32_t host_subnet_id =
538 ((subnet && subnet->getReservationsGlobal()) ?
539 SUBNET_ID_GLOBAL : subnet_id);
540 host = HostMgr::instance().get4Any(host_subnet_id, id_type,
541 &host_id[0], host_id.size());
542 }
543 // Add class: get cached Class attribute.
544 // @todo: extend and make configurable with a list of attributes.
545 if (host && host->getContext() &&
546 (host->getContext()->getType() == Element::map)) {
547 Attributes cached_attrs =
548 Attributes::fromElement(host->getContext()->get("radius"));
549 send->add(cached_attrs.get(PW_CLASS));
550 }
551
552 // Add attributes from configuration.
553 send->append(RadiusImpl::instance().acct_->attributes_.getAll());
554
555 // Return the handler.
556 RadiusAcctEnv env(stream.str(), event, subnet_id, send);
557 RadiusAcctHandlerPtr handler;
558 handler.reset(new RadiusAcctHandler(
559 env, std::bind(&RadiusAccounting::terminate, env, ph::_1)));
560
561 // Erase create timestamp on stop.
562 if (status == PW_STATUS_STOP) {
563 eraseCreateTimestamp(addr);
564 }
565
566 return (handler);
567}
568
569 RadiusAcctHandlerPtr
570RadiusAccounting::buildAcct6(const ConstElementPtr& arguments, Event event) {
571 IOAddress addr("::");
572 uint32_t subnet_id = SUBNET_ID_UNUSED;
573 DuidPtr duid;
574 HWAddrPtr hwaddr;
575 Lease::Type type = Lease::TYPE_NA;
576 uint8_t prefix_len = 128;
577 bool force = false;
578 try {
579 // Parse arguments.
580 addr = SimpleParser::getAddress(arguments, "ip-address");
581 subnet_id = SimpleParser::getInteger(arguments, "subnet-id");
582 string txt = SimpleParser::getString(arguments, "duid");
583 duid.reset(new DUID(DUID::fromText(txt)));
584
585 if (arguments->contains("hw-address")) {
586 string hwaddr_txt = SimpleParser::getString(arguments, "hw-address");
587 hwaddr.reset(new HWAddr(HWAddr::fromText(hwaddr_txt)));
588 }
589
590 if (arguments->contains("type")) {
591 txt = SimpleParser::getString(arguments, "type");
592 if (txt == "IA_NA") {
593 type = Lease::TYPE_NA;
594 } else if (txt == "IA_TA") {
595 type = Lease::TYPE_TA;
596 } else if (txt == "IA_PD") {
597 type = Lease::TYPE_PD;
598
599 prefix_len = SimpleParser::getInteger(arguments, "prefix-len");
600
601 if ((prefix_len <= 0) || (prefix_len > 128)) {
602 isc_throw(OutOfRange,
603 "'prefix-len' value must be in range of [1..128]");
604 }
605
606 if (prefix_len != 128) {
607 IOAddress first_address = firstAddrInPrefix(addr, prefix_len);
608 if (first_address != addr) {
609 isc_throw(BadValue, "Prefix address: " << addr
610 << " exceeds prefix/prefix-len pair: " << first_address
611 << "/" << static_cast<uint32_t>(prefix_len));
612 }
613 }
614 } else {
615 isc_throw(BadValue, "bad type" << txt);
616 }
617 }
618
619 if (arguments->contains("force-create")) {
620 force = SimpleParser::getBoolean(arguments, "force-create");
621 }
622 } catch (const std::exception&) {
623 return (RadiusAcctHandlerPtr());
624 }
625 if (!addr.isV6()) {
626 return (RadiusAcctHandlerPtr());
627 }
628
629 // Fill attributes.
630 AttributesPtr send(new Attributes());
631
632 // Add duid.
633 vector<uint8_t> vec;
634 if (RadiusImpl::instance().clientid_pop0_) {
635 vec = pop0(duid);
636 } else {
637 vec = duid->getDuid();
638 }
639 string text;
640 if (RadiusImpl::instance().clientid_printable_) {
641 text = toPrintable(vec);
642 } else {
643 text = toHex(vec);
644 }
645 send->add(Attribute::fromString(PW_USER_NAME, text));
646
647 // Add hardware address.
648 if (hwaddr) {
649 string mac = hwaddr->toText(false);
650 if (RadiusImpl::instance().canonical_mac_address_) {
651 mac = canonize(mac);
652 }
653 send->add(Attribute::fromString(PW_CALLING_STATION_ID, mac));
654 }
655
656 // Add address or prefix.
657 if (type != Lease::TYPE_PD) {
658 send->add(Attribute::fromIpv6Addr(PW_FRAMED_IPV6_ADDRESS, addr));
659 } else {
660 send->add(Attribute::fromIpv6Prefix(PW_DELEGATED_IPV6_PREFIX,
661 prefix_len, addr));
662 }
663
664 // Get the create timestamp.
665 bool generate = false;
666 if ((event == EVENT_ADD) && force) {
667 generate = true;
668 }
669 ptime tm = getCreateTimestamp(addr, generate);
670
671 // Build the session Id.
672 ostringstream stream;
673 stream << addr << '@';
674 time_duration rtm(tm - epoch_);
675 stream << rtm.total_seconds() << ".";
676 rtm -= seconds(rtm.total_seconds());
677 stream << rtm.total_milliseconds();
678 send->add(Attribute::fromString(PW_ACCT_SESSION_ID, stream.str()));
679
680 // Accounting status type.
681 uint32_t status = PW_STATUS_ALIVE;
682 if (generate) {
683 status = PW_STATUS_START;
684 } else if (event == EVENT_DEL) {
685 status = PW_STATUS_STOP;
686 }
687 send->add(Attribute::fromInt(PW_ACCT_STATUS_TYPE, status));
688
689 // Add class: get host identifier.
690 Host::IdentifierType id_type = RadiusImpl::instance().id_type6_;
691 vector<uint8_t> host_id;
692 switch (id_type) {
693 case Host::IDENT_DUID:
694 host_id = duid->getDuid();
695 break;
696 case Host::IDENT_HWADDR:
697 if (hwaddr) {
698 host_id = hwaddr->hwaddr_;
699 }
700 break;
701 case Host::IDENT_FLEX:
702 host_id = duid->getDuid();
703 if ((host_id.size() <= 2) ||
704 (host_id[0] != 0) || (host_id[1] != 0)) {
705 host_id.clear();
706 } else {
707 host_id = vector<uint8_t>(host_id.begin() + 2, host_id.end());
708 }
709 break;
710 default:
711 // not supported.
712 break;
713 }
714
715 // Add class: get host entry.
716 ConstHostPtr host;
717 if (!host_id.empty()) {
718 ConstSubnet6Ptr subnet = CfgMgr::instance().getCurrentCfg()->
719 getCfgSubnets6()->getBySubnetId(subnet_id);
720 uint32_t host_subnet_id =
721 ((subnet && subnet->getReservationsGlobal()) ?
722 SUBNET_ID_GLOBAL : subnet_id);
723 host = HostMgr::instance().get6Any(host_subnet_id, id_type,
724 &host_id[0], host_id.size());
725 }
726 // Add class: get cached Class attribute.
727 // @todo: extend and make configurable with a list of attributes.
728 if (host && host->getContext() &&
729 (host->getContext()->getType() == Element::map)) {
730 Attributes cached_attrs =
731 Attributes::fromElement(host->getContext()->get("radius"));
732 send->add(cached_attrs.get(PW_CLASS));
733 }
734
735 // Add attributes from configuration.
736 send->append(RadiusImpl::instance().acct_->attributes_.getAll());
737
738 // Return the handler.
739 RadiusAcctEnv env(stream.str(), event, subnet_id, send);
740 RadiusAcctHandlerPtr handler;
741 handler.reset(new RadiusAcctHandler(
742 env, std::bind(&RadiusAccounting::terminate, env, ph::_1)));
743
744 // Erase create timestamp on stop.
745 if (status == PW_STATUS_STOP) {
746 eraseCreateTimestamp(addr);
747 }
748
749 return (handler);
750}
751
752void
753RadiusAccounting::runAsync(RadiusAcctHandlerPtr handler) {
754 handler->start();
755}
756
757void
758RadiusAccounting::terminate(RadiusAcctEnv env, int result) {
759 env.finished_ = true;
760 if (result != OK_RC) {
761 LOG_ERROR(radius_logger, RADIUS_ACCOUNTING_ERROR)
762 .arg(env.session_id_)
763 .arg(env.event_)
764 .arg(eventToText(env.event_))
765 .arg(result)
766 .arg(exchangeRCtoText(result));
767 }
768}
769
770ptime
771RadiusAccounting::getCreateTimestamp(const IOAddress& addr, bool generate) {
772 MultiThreadingLock lock(mutex_);
773 TMContainerAddressIndex& idx = container_.get<TMAddressIndexTag>();
774 TMContainerAddressIndex::iterator it = idx.find(addr);
775 if (!generate) {
776 if (it == idx.end()) {
777 LOG_DEBUG(radius_logger, RADIUS_DBG_TRACE,
778 RADIUS_ACCOUNTING_NO_HISTORY)
779 .arg(addr.toText());
780 } else {
781 return (it->timestamp_);
782 }
783 }
784
785 // generate is true or no address was found.
786 while (it != idx.end()) {
787 idx.erase(it);
788 // One round should be enough as the address is unique.
789 it = idx.find(addr);
790 }
791 ptime tm = microsec_clock::universal_time();
792 auto ret = container_.insert(LeaseTS(addr, tm));
793 if (!ret.second) {
794 LOG_ERROR(radius_logger, RADIUS_ACCOUNTING_HISTORY_UPDATE_FAILED)
795 .arg(addr.toText());
796 }
797
798 // Append to create timestamp file.
799 if (file_) {
800 try {
801 CSVRow row(file_->getColumnCount());
802
803 row.writeAt(file_->getColumnIndex("address"), addr);
804 time_duration rtm(tm - epoch_);
805 row.writeAt(file_->getColumnIndex("seconds"), rtm.total_seconds());
806 rtm -= seconds(rtm.total_seconds());
807 row.writeAt(file_->getColumnIndex("milliseconds"),
808 rtm.total_milliseconds());
809
810 file_->append(row);
811 ++record_count_;
812 } catch (const std::exception& ex) {
813 LOG_WARN(radius_logger, RADIUS_SESSION_HISTORY_APPEND_FAILED)
814 .arg(addr.toText())
815 .arg(ex.what());
816 file_.reset();
817 }
818 }
819
820 return (tm);
821}
822
823void
824RadiusAccounting::eraseCreateTimestamp(const IOAddress& addr) {
825 MultiThreadingLock lock(mutex_);
826 TMContainerAddressIndex& idx = container_.get<TMAddressIndexTag>();
827 TMContainerAddressIndex::iterator it = idx.find(addr);
828 while (it != idx.end()) {
829 idx.erase(it);
830 // One round should be enough as the address is unique.
831 it = idx.find(addr);
832 }
833 // Append delete marker to create timestamp file.
834 if (file_) {
835 try {
836 CSVRow row(file_->getColumnCount());
837
838 row.writeAt(file_->getColumnIndex("address"), addr);
839 row.writeAt(file_->getColumnIndex("seconds"), 0L);
840 row.writeAt(file_->getColumnIndex("milliseconds"), 0L);
841
842 file_->append(row);
843 ++record_count_;
844 } catch (const std::exception& ex) {
845 LOG_WARN(radius_logger, RADIUS_SESSION_HISTORY_APPEND_FAILED)
846 .arg(addr.toText())
847 .arg(ex.what());
848 file_.reset();
849 }
850 }
851}
852
853bool
854RadiusAccounting::loadFromFile() {
855 TMContainerAddressIndex& idx = container_.get<TMAddressIndexTag>();
856 bool ok = true;
857 size_t adds = 0;
858 size_t fails = 0;
859 try {
860 file_->open(false);
861
862 for (;;) {
863 CSVRow row;
864 file_->next(row, true);
865 // Check if done.
866 if (row == CSVFile::EMPTY_ROW()) {
867 if (ok) {
868 LOG_INFO(radius_logger, RADIUS_SESSION_HISTORY_LOADED)
869 .arg(adds)
870 .arg(container_.size());
871 break;
872 } else {
873 isc_throw(CSVFileError, "partial load");
874 }
875 }
876
877 // Get fields.
878 string addr_txt = row.readAt(file_->getColumnIndex("address"));
879 IOAddress addr(addr_txt);
880 long secs =
881 row.readAndConvertAt<long>(file_->getColumnIndex("seconds"));
882 long msecs =
883 row.readAndConvertAt<long>(file_->getColumnIndex("milliseconds"));
884
885 // Get an iterator to a possible entry.
886 TMContainerAddressIndex::iterator it = idx.find(addr);
887 while (it != idx.end()) {
888 idx.erase(it);
889 // One round should be enough as the address is unique.
890 it = idx.find(addr);
891 }
892
893 // Zero seconds means deleted record.
894 if (secs == 0) {
895 continue;
896 }
897
898 time_duration rtm (seconds(secs) + milliseconds(msecs));
899 ptime tm(epoch_ + rtm);
900 auto ret = container_.insert(LeaseTS(addr, tm));
901 if (!ret.second) {
902 ok = false;
903 ++fails;
904 } else {
905 ++adds;
906 }
907 }
908
909 } catch (const std::exception& ex) {
910 LOG_ERROR(radius_logger, RADIUS_SESSION_HISTORY_LOAD_FAILED)
911 .arg(adds)
912 .arg(fails)
913 .arg(container_.size());
914 ok = false;
915 }
916
917 file_->close();
918
919 return (ok);
920}
921
922void
923RadiusAccounting::storeToFile() {
924 TMContainerTimestampIndex& idx = container_.get<TMTimestampIndexTag>();
925 string newfilename = filename_ + ".new";
926 CSVFile newfile(newfilename);
927 size_t stored = 0;
928 if (container_.empty()) {
929 return;
930 }
931 try {
932 // Add columns
933 newfile.addColumn("address");
934 newfile.addColumn("seconds");
935 newfile.addColumn("milliseconds");
936
937 // Rename file if it exists.
938 if (newfile.exists()) {
939 string backfilename = filename_ + ".new~";
940 rename(newfilename.c_str(), backfilename.c_str());
941 }
942
943 // Open file (seed to end in case the rename failed).
944 newfile.open(true);
945
946 // Dump container content.
947 for (auto const& it : idx) {
948 CSVRow row(newfile.getColumnCount());
949
950 row.writeAt(newfile.getColumnIndex("address"), it.addr_);
951 time_duration rtm(it.timestamp_ - epoch_);
952 row.writeAt(newfile.getColumnIndex("seconds"),
953 rtm.total_seconds());
954 rtm -= seconds(rtm.total_seconds());
955 row.writeAt(newfile.getColumnIndex("milliseconds"),
956 rtm.total_milliseconds());
957
958 newfile.append(row);
959 ++stored;
960 }
961
962 // Close file.
963 newfile.close();
964
965 // Rename files.
966 string backfilename = filename_ + ".bak";
967 bool moved = true;
968 if (rename(filename_.c_str(), backfilename.c_str()) != 0) {
969 moved = false;
970 }
971 if (rename(newfilename.c_str(), filename_.c_str()) != 0) {
972 if (moved) {
973 // Try to restore current file.
974 rename(backfilename.c_str(), filename_.c_str());
975 }
976 }
977
978 LOG_INFO(radius_logger, RADIUS_SESSION_HISTORY_STORED)
979 .arg(stored);
980
981 } catch (const std::exception& ex) {
982 LOG_ERROR(radius_logger, RADIUS_SESSION_HISTORY_STORE_FAILED)
983 .arg(newfilename)
984 .arg(ex.what())
985 .arg(stored)
986 .arg(container_.size());
987 }
988 record_count_ = 0;
989}
990
991} // end of namespace isc::radius
992} // end of namespace isc
addr_utilities.h
cfgmgr.h
DUID::fromText
static DUID fromText(const std::string &text)
Create DUID from the textual format.
Definition duid.cc:50
Element::map
@ map
Definition data.h:147
isc::BadValue
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition exceptions/exceptions.h:132
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
isc::asiolink::IOAddress
The IOAddress class represents an IP addresses (version agnostic)
Definition io_address.h:45
isc::asiolink::IOAddress::toText
std::string toText() const
Convert the address to a string.
Definition io_address.cc:61
isc::asiolink::IOAddress::isV6
bool isV6() const
Convenience function to check for an IPv6 address.
Definition io_address.h:136
isc::asiolink::IOAddress::isV4
bool isV4() const
Convenience function to check for an IPv4 address.
Definition io_address.h:114
isc::data::SimpleParser::getAddress
static isc::asiolink::IOAddress getAddress(const ConstElementPtr &scope, const std::string &name)
Returns a IOAddress parameter from a scope.
Definition lib/cc/simple_parser.cc:125
isc::data::SimpleParser::getString
static std::string getString(isc::data::ConstElementPtr scope, const std::string &name)
Returns a string parameter from a scope.
Definition lib/cc/simple_parser.cc:60
isc::data::SimpleParser::getBoolean
static bool getBoolean(isc::data::ConstElementPtr scope, const std::string &name)
Returns a boolean parameter from a scope.
Definition lib/cc/simple_parser.cc:108
isc::data::SimpleParser::getInteger
static int64_t getInteger(isc::data::ConstElementPtr scope, const std::string &name)
Returns an integer parameter from a scope.
Definition lib/cc/simple_parser.cc:77
isc::dhcp::CfgMgr::instance
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
isc::dhcp::CfgMgr::getCurrentCfg
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition cfgmgr.cc:116
isc::dhcp::ClientId::fromText
static ClientIdPtr fromText(const std::string &text)
Create client identifier from the textual format.
Definition duid.cc:73
isc::dhcp::DUID
Holds DUID (DHCPv6 Unique Identifier)
Definition duid.h:142
isc::dhcp::HostMgr::get6Any
ConstHostPtr get6Any(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns any host connected to the IPv6 subnet.
Definition host_mgr.cc:590
isc::dhcp::HostMgr::get4Any
ConstHostPtr get4Any(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns any host connected to the IPv4 subnet.
Definition host_mgr.cc:401
isc::dhcp::HostMgr::instance
static HostMgr & instance()
Returns a sole instance of the HostMgr.
Definition host_mgr.cc:114
isc::dhcp::Host::IdentifierType
IdentifierType
Type of the host identifier.
Definition host.h:337
isc::dhcp::Host::IDENT_HWADDR
@ IDENT_HWADDR
Definition host.h:338
isc::dhcp::Host::IDENT_FLEX
@ IDENT_FLEX
Flexible host identifier.
Definition host.h:342
isc::dhcp::Host::IDENT_DUID
@ IDENT_DUID
Definition host.h:339
isc::dhcp::Host::IDENT_CLIENT_ID
@ IDENT_CLIENT_ID
Definition host.h:341
isc::radius::Attribute::fromInt
static AttributePtr fromInt(const uint8_t type, const uint32_t value)
From integer with type.
Definition client_attribute.cc:158
isc::radius::Attribute::fromIpAddr
static AttributePtr fromIpAddr(const uint8_t type, const asiolink::IOAddress &value)
From IPv4 address with type.
Definition client_attribute.cc:163
isc::radius::Attribute::fromString
static AttributePtr fromString(const uint8_t type, const std::string &value)
From type specific factories.
Definition client_attribute.cc:142
isc::radius::Attribute::fromIpv6Prefix
static AttributePtr fromIpv6Prefix(const uint8_t type, const uint8_t len, const asiolink::IOAddress &value)
From IPv6 prefix with type.
Definition client_attribute.cc:173
isc::radius::Attribute::fromIpv6Addr
static AttributePtr fromIpv6Addr(const uint8_t type, const asiolink::IOAddress &value)
From IPv6 address with type.
Definition client_attribute.cc:168
isc::radius::Attributes
Collection of attributes.
Definition client_attribute.h:652
isc::radius::Attributes::get
ConstAttributePtr get(const uint8_t type) const
Get instance of the attribute in the collection.
Definition client_attribute.cc:648
isc::radius::Attributes::fromElement
static Attributes fromElement(const data::ConstElementPtr &attr_list)
Parse collection.
Definition client_attribute.cc:683
isc::radius::LeaseTS
Create timestamp entry.
Definition radius_accounting.h:48
isc::radius::RadiusAccounting::buildAcct6
RadiusAcctHandlerPtr buildAcct6(const data::ConstElementPtr &arguments, Event event)
Build RadiusAcct handler for Accounting-Request.
Definition radius_accounting.cc:570
isc::radius::RadiusAccounting::container_
TMContainer container_
The Create timestamp container which holds session history.
Definition radius_accounting.h:295
isc::radius::RadiusAccounting::buildAcct4
RadiusAcctHandlerPtr buildAcct4(const data::ConstElementPtr &arguments, Event event)
Build RadiusAcct handler for Accounting-Request.
Definition radius_accounting.cc:402
isc::radius::RadiusAccounting::eraseCreateTimestamp
void eraseCreateTimestamp(const asiolink::IOAddress &addr)
Erase create-timestamp entry to session history.
Definition radius_accounting.cc:824
isc::radius::RadiusAccounting::file_
CSVFilePtr file_
Pointer to the CSVFile.
Definition radius_accounting.h:303
isc::radius::RadiusAccounting::init
void init(const std::string &filename)
Initialize.
Definition radius_accounting.cc:102
isc::radius::RadiusAccounting::loadFromFile
bool loadFromFile()
Load create-timestamp entries from file.
Definition radius_accounting.cc:854
isc::radius::RadiusAccounting::runAsync
static void runAsync(RadiusAcctHandlerPtr handler)
Run asynchronously.
Definition radius_accounting.cc:753
isc::radius::RadiusAccounting::mutex_
std::mutex mutex_
Mutex to protect access to container_ and file_.
Definition radius_accounting.h:312
isc::radius::RadiusAccounting::RadiusAccounting
RadiusAccounting()
Constructor.
Definition radius_accounting.cc:97
isc::radius::RadiusAccounting::storeToFile
void storeToFile()
Store create-timestamp entries to a file.
Definition radius_accounting.cc:923
isc::radius::RadiusAccounting::record_count_
size_t record_count_
New record counter.
Definition radius_accounting.h:309
isc::radius::RadiusAccounting::buildAcct
RadiusAcctHandlerPtr buildAcct(const dhcp::Lease4Ptr &lease, Event event)
Build RadiusAcct handler for Accounting-Request - IPv4.
Definition radius_accounting.cc:130
isc::radius::RadiusAccounting::terminate
static void terminate(RadiusAcctEnv env, int result)
Termination callback.
Definition radius_accounting.cc:758
isc::radius::RadiusAccounting::epoch_
const boost::posix_time::ptime epoch_
Epoch to avoid too long values.
Definition radius_accounting.h:300
isc::radius::RadiusAccounting::getCreateTimestamp
boost::posix_time::ptime getCreateTimestamp(const asiolink::IOAddress &addr, bool generate)
Get lease create-timestamp entry from session history.
Definition radius_accounting.cc:771
isc::radius::RadiusAccounting::filename_
std::string filename_
Create timestamps file name.
Definition radius_accounting.h:292
isc::radius::RadiusAcctEnv
Class of Radius accounting environments.
Definition radius_accounting.h:109
isc::radius::RadiusAcctEnv::RadiusAcctEnv
RadiusAcctEnv(std::string session_id, Event event, uint32_t subnet_id, AttributesPtr send_attrs)
Constructor.
Definition radius_accounting.cc:59
isc::radius::RadiusAcctEnv::session_id_
std::string session_id_
Session Id.
Definition radius_accounting.h:122
isc::radius::RadiusAcctEnv::finished_
bool finished_
Termination flag.
Definition radius_accounting.h:134
isc::radius::RadiusAcctEnv::send_attrs_
AttributesPtr send_attrs_
Attributes to send.
Definition radius_accounting.h:131
isc::radius::RadiusAcctEnv::subnet_id_
uint32_t subnet_id_
Subnet Id (aka client/NAS port).
Definition radius_accounting.h:128
isc::radius::RadiusAcctEnv::event_
Event event_
Event.
Definition radius_accounting.h:125
isc::radius::RadiusAcctHandler
Class of Radius accounting communication handler.
Definition radius_accounting.h:138
isc::radius::RadiusAcctHandler::RadiusAcctHandler
RadiusAcctHandler(RadiusAcctEnv env, const CallbackAcct &callback)
Constructor.
Definition radius_accounting.cc:66
isc::radius::RadiusAcctHandler::getCounter
static size_t getCounter()
Get instance counter.
Definition radius_accounting.cc:88
isc::radius::RadiusAcctHandler::env_
RadiusAcctEnv env_
Environment.
Definition radius_accounting.h:157
isc::radius::RadiusAcctHandler::start
void start()
Start communication.
Definition radius_accounting.cc:83
isc::radius::RadiusAcctHandler::~RadiusAcctHandler
virtual ~RadiusAcctHandler()
Destructor.
Definition radius_accounting.cc:75
isc::radius::RadiusAcctHandler::acct_
RadiusAsyncAcctPtr acct_
Pointer to the communication class.
Definition radius_accounting.h:162
isc::radius::RadiusAsyncAcct
class for asynchronous accounting communication with servers.
Definition radius_request.h:246
isc::radius::RadiusImpl::id_type4_
dhcp::Host::IdentifierType id_type4_
Identifier type for IPv4.
Definition radius.h:202
isc::radius::RadiusImpl::id_type6_
dhcp::Host::IdentifierType id_type6_
Identifier type for IPv6.
Definition radius.h:205
isc::radius::RadiusImpl::instance
static RadiusImpl & instance()
RadiusImpl is a singleton class.
Definition radius.cc:37
isc::radius::RadiusService::RadiusService
RadiusService(const std::string &name)
Constructor.
Definition radius_service.cc:18
isc::util::CSVFileError
Exception thrown when an error occurs during CSV file processing.
Definition csv_file.h:22
isc::util::CSVFile
Provides input/output access to CSV files.
Definition csv_file.h:358
isc::util::CSVFile::close
void close()
Closes the CSV file.
Definition csv_file.cc:123
isc::util::CSVFile::getColumnCount
size_t getColumnCount() const
Returns the number of columns in the file.
Definition csv_file.h:403
isc::util::CSVFile::exists
bool exists() const
Checks if the CSV file exists and can be opened for reading.
Definition csv_file.cc:133
isc::util::CSVFile::EMPTY_ROW
static CSVRow EMPTY_ROW()
Represents empty row.
Definition csv_file.h:491
isc::util::CSVFile::append
void append(const CSVRow &row) const
Writes the CSV row into the file.
Definition csv_file.cc:167
isc::util::CSVFile::addColumn
void addColumn(const std::string &col_name)
Adds new column name.
Definition csv_file.cc:147
isc::util::CSVFile::getColumnIndex
size_t getColumnIndex(const std::string &col_name) const
Returns the index of the column having specified name.
Definition csv_file.cc:237
isc::util::CSVFile::open
virtual void open(const bool seek_to_end=false)
Opens existing file or creates a new one.
Definition csv_file.cc:302
isc::util::CSVRow
Represents a single row of the CSV file.
Definition csv_file.h:51
isc::util::CSVRow::readAndConvertAt
T readAndConvertAt(const size_t at) const
Retrieves a value from the internal container.
Definition csv_file.h:156
isc::util::CSVRow::writeAt
void writeAt(const size_t at, const char *value)
Replaces the value at specified index.
Definition csv_file.cc:84
isc::util::CSVRow::readAt
std::string readAt(const size_t at) const
Retrieves a value from the internal container.
Definition csv_file.cc:60
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
host_mgr.h
simple_parser.h
LOG_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
LOG_INFO
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
LOG_WARN
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition macros.h:26
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
multi_threading_mgr.h
isc::asiolink
Definition addr_utilities.cc:170
isc::asiolink::firstAddrInPrefix
IOAddress firstAddrInPrefix(const IOAddress &prefix, uint8_t len)
This code is based on similar code from the Dibbler project.
Definition addr_utilities.cc:172
isc::data
Definition base_stamped_element.cc:12
isc::data::ConstElementPtr
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::ConstSubnet6Ptr
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
Definition subnet.h:623
isc::dhcp::ConstSubnet4Ptr
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
Definition subnet.h:458
isc::dhcp::DuidPtr
boost::shared_ptr< DUID > DuidPtr
Definition duid.h:136
isc::dhcp::Lease6Ptr
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition lease.h:528
isc::dhcp::HWAddrPtr
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition hwaddr.h:154
isc::dhcp::ClientIdPtr
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
Definition duid.h:216
isc::dhcp::ConstHostPtr
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
Definition host.h:840
isc::dhcp::Lease4Ptr
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition lease.h:315
isc::radius
Definition cfg_attribute.cc:21
isc::radius::RadiusAcctHandlerPtr
boost::shared_ptr< RadiusAcctHandler > RadiusAcctHandlerPtr
Type of pointers to Radius accounting communication handler.
Definition radius_accounting.h:174
isc::radius::PW_DELEGATED_IPV6_PREFIX
@ PW_DELEGATED_IPV6_PREFIX
ipv6prefix.
Definition hooks/dhcp/radius/client.h:118
isc::radius::PW_USER_NAME
@ PW_USER_NAME
string.
Definition hooks/dhcp/radius/client.h:18
isc::radius::PW_FRAMED_IP_ADDRESS
@ PW_FRAMED_IP_ADDRESS
ipaddr.
Definition hooks/dhcp/radius/client.h:25
isc::radius::PW_CALLING_STATION_ID
@ PW_CALLING_STATION_ID
string.
Definition hooks/dhcp/radius/client.h:48
isc::radius::PW_ACCT_STATUS_TYPE
@ PW_ACCT_STATUS_TYPE
integer.
Definition hooks/dhcp/radius/client.h:57
isc::radius::PW_ACCT_SESSION_ID
@ PW_ACCT_SESSION_ID
string.
Definition hooks/dhcp/radius/client.h:61
isc::radius::PW_CLASS
@ PW_CLASS
string.
Definition hooks/dhcp/radius/client.h:42
isc::radius::PW_FRAMED_IPV6_ADDRESS
@ PW_FRAMED_IPV6_ADDRESS
ipv6addr.
Definition hooks/dhcp/radius/client.h:119
isc::radius::PW_STATUS_ALIVE
@ PW_STATUS_ALIVE
Definition hooks/dhcp/radius/client.h:132
isc::radius::PW_STATUS_START
@ PW_STATUS_START
Definition hooks/dhcp/radius/client.h:130
isc::radius::PW_STATUS_STOP
@ PW_STATUS_STOP
Definition hooks/dhcp/radius/client.h:131
isc::radius::extractDuid
vector< uint8_t > extractDuid(const ClientIdPtr &client_id, bool &extracted)
Extract the duid from a RFC 4361 compliant DHCPv4 client ID.
Definition radius_utils.cc:98
isc::radius::RADIUS_ACCOUNTING_ERROR
const isc::log::MessageID RADIUS_ACCOUNTING_ERROR
Definition radius_messages.h:29
isc::radius::canonize
string canonize(const string &hexdump)
Canonize hardware address textual representation.
Definition radius_utils.cc:25
isc::radius::RADIUS_SESSION_HISTORY_STORE_FAILED
const isc::log::MessageID RADIUS_SESSION_HISTORY_STORE_FAILED
Definition radius_messages.h:91
isc::radius::TMContainerAddressIndex
TMContainer::index< TMAddressIndexTag >::type TMContainerAddressIndex
First index type in the TMContainer.
Definition radius_accounting.h:101
isc::radius::AttributesPtr
boost::shared_ptr< Attributes > AttributesPtr
Shared pointers to attribute collection.
Definition client_attribute.h:799
isc::radius::RADIUS_SESSION_HISTORY_OPEN_FAILED
const isc::log::MessageID RADIUS_SESSION_HISTORY_OPEN_FAILED
Definition radius_messages.h:89
isc::radius::CallbackAcct
std::function< void(int)> CallbackAcct
Type of callback for accounting termination.
Definition radius_request.h:29
isc::radius::TMContainerTimestampIndex
TMContainer::index< TMTimestampIndexTag >::type TMContainerTimestampIndex
Second index type in the TMContainer.
Definition radius_accounting.h:104
isc::radius::RADIUS_SESSION_HISTORY_LOADED
const isc::log::MessageID RADIUS_SESSION_HISTORY_LOADED
Definition radius_messages.h:86
isc::radius::Event
Event
Type of accounting events.
Definition radius_accounting.h:25
isc::radius::EVENT_DECLINE
@ EVENT_DECLINE
Definition radius_accounting.h:31
isc::radius::EVENT_UPDATE
@ EVENT_UPDATE
Definition radius_accounting.h:33
isc::radius::EVENT_EXPIRE
@ EVENT_EXPIRE
Definition radius_accounting.h:29
isc::radius::EVENT_ADD
@ EVENT_ADD
Definition radius_accounting.h:32
isc::radius::EVENT_RELEASE
@ EVENT_RELEASE
Definition radius_accounting.h:30
isc::radius::EVENT_CREATE
@ EVENT_CREATE
Definition radius_accounting.h:26
isc::radius::EVENT_DEL
@ EVENT_DEL
Definition radius_accounting.h:34
isc::radius::EVENT_RENEW
@ EVENT_RENEW
Definition radius_accounting.h:27
isc::radius::EVENT_REBIND
@ EVENT_REBIND
Definition radius_accounting.h:28
isc::radius::exchangeRCtoText
string exchangeRCtoText(const int rc)
ExchangeRC value -> name function.
Definition client_exchange.cc:37
isc::radius::RADIUS_DBG_TRACE
const int RADIUS_DBG_TRACE
Radius logging levels.
Definition radius_log.h:26
isc::radius::RADIUS_ACCOUNTING_HISTORY_UPDATE_FAILED
const isc::log::MessageID RADIUS_ACCOUNTING_HISTORY_UPDATE_FAILED
Definition radius_messages.h:30
isc::radius::RADIUS_SESSION_HISTORY_APPEND_FAILED
const isc::log::MessageID RADIUS_SESSION_HISTORY_APPEND_FAILED
Definition radius_messages.h:85
isc::radius::OK_RC
@ OK_RC
Definition client_exchange.h:40
isc::radius::toPrintable
string toPrintable(const vector< uint8_t > &content)
Return printable textual representation of a vector.
Definition radius_utils.cc:68
isc::radius::toHex
string toHex(const vector< uint8_t > &content)
Return hexadecimal textual representation of a vector.
Definition radius_utils.cc:83
isc::radius::RADIUS_SESSION_HISTORY_STORED
const isc::log::MessageID RADIUS_SESSION_HISTORY_STORED
Definition radius_messages.h:90
isc::radius::radius_logger
isc::log::Logger radius_logger("radius-hooks")
Radius Logger.
Definition radius_log.h:35
isc::radius::RADIUS_SESSION_HISTORY_OPENED
const isc::log::MessageID RADIUS_SESSION_HISTORY_OPENED
Definition radius_messages.h:88
isc::radius::pop0
vector< uint8_t > pop0(const ClientIdPtr &client_id)
Pop leading zero in a DHCPv4 client-id.
Definition radius_utils.cc:50
isc::radius::RADIUS_SESSION_HISTORY_LOAD_FAILED
const isc::log::MessageID RADIUS_SESSION_HISTORY_LOAD_FAILED
Definition radius_messages.h:87
isc::radius::RADIUS_ACCOUNTING_NO_HISTORY
const isc::log::MessageID RADIUS_ACCOUNTING_NO_HISTORY
Definition radius_messages.h:31
isc::radius::eventToText
string eventToText(Event event)
Translate an event to text.
Definition radius_accounting.cc:34
isc::util
Definition time_utils.cc:43
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
radius_accounting.h
radius_log.h
radius_utils.h
isc::dhcp::HWAddr
Hardware type that represents information from DHCPv4 packet.
Definition hwaddr.h:20
isc::dhcp::HWAddr::fromText
static HWAddr fromText(const std::string &text, const uint16_t htype=HTYPE_ETHER)
Creates instance of the hardware address from textual format.
Definition hwaddr.cc:69
isc::dhcp::Lease::Type
Type
Type of lease or pool.
Definition lease.h:46
isc::dhcp::Lease::TYPE_TA
@ TYPE_TA
the lease contains temporary IPv6 address
Definition lease.h:48
isc::dhcp::Lease::TYPE_PD
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition lease.h:49
isc::dhcp::Lease::TYPE_NA
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition lease.h:47
isc::radius::TMAddressIndexTag
Tag for the index for searching by address.
Definition radius_accounting.h:68
isc::radius::TMTimestampIndexTag
Tag for the index for searching by timestamp.
Definition radius_accounting.h:71
isc::util::MultiThreadingLock
RAII lock object to protect the code in the same scope with a mutex.
Definition multi_threading_mgr.h:349
subnet.h