17#include <boost/foreach.hpp>
34 switch (exchange_type) {
47 "unrecognized exchange type '" << exchange_type <<
"'");
55 return(os <<
"DISCOVER-OFFER");
57 return(os <<
"REQUEST-ACK");
59 return(os <<
"REQUEST-ACK (renewal)");
61 return(os <<
"RELEASE");
63 return(os <<
"SOLICIT-ADVERTISE");
65 return(os <<
"REQUEST-REPLY");
67 return(os <<
"RENEW-REPLY");
69 return(os <<
"RELEASE-REPLY");
71 return(os <<
"Unknown exchange type");
77 const double drop_time,
78 const bool archive_enabled,
79 const boost::posix_time::ptime boot_time)
80 : xchg_type_(xchg_type),
84 archive_enabled_(archive_enabled),
85 drop_time_(drop_time),
86 min_delay_(std::numeric_limits<double>::max()),
89 sum_delay_squared_(0.),
92 unordered_lookup_size_sum_(0),
93 unordered_lookups_(0),
97 non_unique_addr_num_(0),
98 rejected_leases_num_(0),
101 next_sent_ = sent_packets_.begin();
106 const PktPtr& rcvd_packet) {
114 boost::posix_time::ptime sent_time = sent_packet->getTimestamp();
115 boost::posix_time::ptime rcvd_time = rcvd_packet->getTimestamp();
117 if (sent_time.is_not_a_date_time() ||
118 rcvd_time.is_not_a_date_time()) {
120 "Timestamp must be set for sent and "
121 "received packet to measure RTT,"
122 <<
" sent: " << sent_time
123 <<
" recv: " << rcvd_time);
125 boost::posix_time::time_period period(sent_time, rcvd_time);
130 static_cast<double>(period.length().total_nanoseconds()) / 1e9;
134 "greater than received packet's timestamp in "
135 << xchg_type_ <<
".\nTime difference: "
136 << delta <<
", sent: " << sent_time <<
", rcvd: "
137 << rcvd_time <<
".\nTrans ID: " << sent_packet->getTransid()
142 if (delta < min_delay_) {
146 if (delta > max_delay_) {
152 sum_delay_squared_ += delta * delta;
157 using namespace boost::posix_time;
163 if (sent_packets_.size() == 0) {
170 }
else if (next_sent_ == sent_packets_.end()) {
174 next_sent_ = sent_packets_.begin();
179 bool packet_found =
false;
186 if ((*next_sent_)->getTransid() == rcvd_packet->getTransid()) {
201 std::pair<PktListTransidHashIterator,PktListTransidHashIterator> p =
208 ++unordered_lookups_;
212 unordered_lookup_size_sum_ += std::distance(p.first, p.second);
213 bool non_expired_found =
false;
224 if (!packet_found && ((*it)->getTransid() == rcvd_packet->getTransid())) {
226 next_sent_ = sent_packets_.template project<0>(it);
229 if (!non_expired_found) {
232 ptime now = microsec_clock::universal_time();
233 ptime packet_time = (*it)->getTimestamp();
234 time_period packet_period(packet_time, now);
235 if (!packet_period.is_null()) {
236 double period_fractional =
237 packet_period.length().total_seconds() +
238 (
static_cast<double>(packet_period.length().fractional_seconds())
239 / packet_period.length().ticks_per_second());
240 if (drop_time_ > 0 && (period_fractional > drop_time_)) {
249 non_expired_found =
true;
256 if (non_expired_found && packet_found) {
262 while (!to_remove.empty()) {
271 if (sent_packets_.template project<0>(it) != next_sent_) {
272 eraseSent(sent_packets_.template project<0>(it));
274 next_sent_ = eraseSent(sent_packets_.template project<0>(it));
277 packet_found =
false;
293 PktPtr sent_packet(*next_sent_);
297 next_sent_ = eraseSent(next_sent_);
306 if (!archive_enabled_) {
308 "packets archive mode is disabled");
310 if (rcvd_packets_num_ == 0) {
311 std::cout <<
"Unavailable! No packets received." << std::endl;
314 using namespace boost::posix_time;
317 for (
auto const& it : rcvd_packets_) {
318 PktPtr rcvd_packet = it;
320 archived_packets_.template get<1>();
324 BOOST_FOREACH(
auto const& it_archived, p) {
325 if (it_archived->getTransid() == rcvd_packet->getTransid()) {
326 PktPtr sent_packet = it_archived;
328 ptime sent_time = sent_packet->getTimestamp();
329 ptime rcvd_time = rcvd_packet->getTimestamp();
333 if (sent_time.is_not_a_date_time() ||
334 rcvd_time.is_not_a_date_time()) {
336 "packet time is not set");
339 time_period sent_period(boot_time_, sent_time);
340 time_period rcvd_period(boot_time_, rcvd_time);
342 std::cout <<
"sent / received: "
343 << to_iso_string(sent_period.length())
345 << to_iso_string(rcvd_period.length())
355 boot_time_(
boost::posix_time::microsec_clock::universal_time())
360 archive_enabled_ = options.testDiags(
'l') || options.testDiags(
't');
362 if (options.getIpVersion() == 4) {
367 if (options.getRenewRate() != 0) {
370 if (options.getReleaseRate() != 0) {
373 }
else if (options.getIpVersion() == 6) {
378 if (options.getRenewRate() != 0) {
381 if (options.getReleaseRate() != 0) {
385 if (options.testDiags(
'i')) {
395 std::stringstream result;
397 for (PktPtr
const& packet : rcvd_packets_) {
401 OptionPtr
const& client_id_option(
402 packet->getOption(DHO_DHCP_CLIENT_IDENTIFIER));
403 if (client_id_option) {
407 OptionPtr
const& client_id_option(packet->getOption(
D6O_CLIENTID));
408 if (client_id_option) {
409 result <<
DUID(client_id_option->getData()).
toText();
418 Pkt4Ptr
const& packet4(boost::dynamic_pointer_cast<Pkt4>(packet));
420 result << packet4->getYiaddr().toText();
423 OptionPtr
const& option(packet->getOption(
D6O_IA_NA));
425 Option6IAAddrPtr
const& iaaddr(
426 boost::dynamic_pointer_cast<Option6IAAddr>(
429 result << iaaddr->getAddress().toText();
436 OptionPtr
const& option(packet->getOption(
D6O_IA_PD));
438 Option6IAPrefixPtr
const& iaprefix(
439 boost::dynamic_pointer_cast<Option6IAPrefix>(
442 result << iaprefix->getAddress().toText();
458 for (
auto const& exchange : exchanges_) {
459 std::cout <<
"***Leases for " << exchange.first <<
"***" << std::endl;
460 std::cout <<
"client_id,adrress,prefix" << std::endl;
461 exchange.second->printLeases();
462 std::cout << std::endl;
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when an unexpected error condition occurs.
Holds DUID (DHCPv6 Unique Identifier)
std::string toText() const
Returns textual representation of the identifier (e.g.
Class that represents IAPREFIX option in DHCPv6.
Represents DHCPv4 packet.
static int malformed_pkts_
static uint32_t hashTransid(const dhcp::PktPtr &packet)
Hash transaction id of the packet.
PktListTransidHashIndex::const_iterator PktListTransidHashIterator
Packet list iterator to access packets using transaction id hash.
std::queue< PktListTransidHashIterator > PktListRemovalQueue
Packet list iterator queue for removal.
std::string receivedLeases() const
Return the list of received leases in CSV format as string.
PktList::template nth_index< 1 >::type PktListTransidHashIndex
Packet list index to search packets using transaction id hash.
void printLeases() const
Print the list of received leases.
void printTimestamps()
Print timestamps for sent and received packets.
dhcp::PktPtr matchPackets(const dhcp::PktPtr &rcvd_packet)
Match received packet with the corresponding sent packet.
void updateDelays(const dhcp::PktPtr &sent_packet, const dhcp::PktPtr &rcvd_packet)
Update delay counters.
void addCustomCounter(const std::string &short_name, const std::string &long_name)
Add named custom uint64 counter.
void printLeases() const
Delegate to all exchanges to print their leases.
StatsMgr(CommandOptions &options)
Constructor.
void addExchangeStats(const ExchangeType xchg_type, const double drop_time=-1)
Specify new exchange type.
static std::string vector2Hex(const std::vector< uint8_t > &vec, const std::string &separator="")
Convert vector in hexadecimal string.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
@ DHO_DHCP_CLIENT_IDENTIFIER
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
boost::shared_ptr< Option6IAPrefix > Option6IAPrefixPtr
Pointer to the Option6IAPrefix object.
boost::shared_ptr< Option6IAAddr > Option6IAAddrPtr
A pointer to the isc::dhcp::Option6IAAddr object.
boost::shared_ptr< Option > OptionPtr
int dhcpVersion(ExchangeType const exchange_type)
Get the DHCP version that fits the exchange type.
ExchangeType
DHCP packet exchange types.
@ SA
DHCPv6 SOLICIT-ADVERTISE.
@ RNA
DHCPv4 REQUEST-ACK (renewal)
@ RL
DHCPv6 RELEASE-REPLY.
@ DO
DHCPv4 DISCOVER-OFFER.
@ RR
DHCPv6 REQUEST-REPLY.
std::ostream & operator<<(std::ostream &os, ExchangeType xchg_type)
Return name of the exchange.
Defines the logger used by the top-level component of kea-lfc.