Kea: radius_accounting.cc Source File

| Kea 3.2.0-git

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