33 switch (exchange_type) {
46 "unrecognized exchange type '" << exchange_type <<
"'");
54 return(os <<
"DISCOVER-OFFER");
56 return(os <<
"REQUEST-ACK");
58 return(os <<
"REQUEST-ACK (renewal)");
60 return(os <<
"RELEASE");
62 return(os <<
"SOLICIT-ADVERTISE");
64 return(os <<
"REQUEST-REPLY");
66 return(os <<
"RENEW-REPLY");
68 return(os <<
"RELEASE-REPLY");
70 return(os <<
"Unknown exchange type");
76 const double drop_time,
77 const bool archive_enabled,
78 const boost::posix_time::ptime boot_time)
79 : xchg_type_(xchg_type),
83 archive_enabled_(archive_enabled),
84 drop_time_(drop_time),
85 min_delay_(std::numeric_limits<double>::max()),
88 sum_delay_squared_(0.),
91 unordered_lookup_size_sum_(0),
92 unordered_lookups_(0),
96 non_unique_addr_num_(0),
97 rejected_leases_num_(0),
100 next_sent_ = sent_packets_.begin();
105 const PktPtr& rcvd_packet) {
113 boost::posix_time::ptime sent_time = sent_packet->getTimestamp();
114 boost::posix_time::ptime rcvd_time = rcvd_packet->getTimestamp();
116 if (sent_time.is_not_a_date_time() ||
117 rcvd_time.is_not_a_date_time()) {
119 "Timestamp must be set for sent and "
120 "received packet to measure RTT,"
121 <<
" sent: " << sent_time
122 <<
" recv: " << rcvd_time);
124 boost::posix_time::time_period period(sent_time, rcvd_time);
129 static_cast<double>(period.length().total_nanoseconds()) / 1e9;
133 "greater than received packet's timestamp in "
134 << xchg_type_ <<
".\nTime difference: "
135 << delta <<
", sent: " << sent_time <<
", rcvd: "
136 << rcvd_time <<
".\nTrans ID: " << sent_packet->getTransid()
141 if (delta < min_delay_) {
145 if (delta > max_delay_) {
151 sum_delay_squared_ += delta * delta;
156 using namespace boost::posix_time;
162 if (sent_packets_.size() == 0) {
169 }
else if (next_sent_ == sent_packets_.end()) {
173 next_sent_ = sent_packets_.begin();
178 bool packet_found =
false;
185 if ((*next_sent_)->getTransid() == rcvd_packet->getTransid()) {
200 std::pair<PktListTransidHashIterator,PktListTransidHashIterator> p =
207 ++unordered_lookups_;
211 unordered_lookup_size_sum_ += std::distance(p.first, p.second);
212 bool non_expired_found =
false;
223 if (!packet_found && ((*it)->getTransid() == rcvd_packet->getTransid())) {
225 next_sent_ = sent_packets_.template project<0>(it);
228 if (!non_expired_found) {
231 ptime now = microsec_clock::universal_time();
232 ptime packet_time = (*it)->getTimestamp();
233 time_period packet_period(packet_time, now);
234 if (!packet_period.is_null()) {
235 double period_fractional =
236 packet_period.length().total_seconds() +
237 (
static_cast<double>(packet_period.length().fractional_seconds())
238 / packet_period.length().ticks_per_second());
239 if (drop_time_ > 0 && (period_fractional > drop_time_)) {
248 non_expired_found =
true;
255 if (non_expired_found && packet_found) {
261 while (!to_remove.empty()) {
270 if (sent_packets_.template project<0>(it) != next_sent_) {
271 eraseSent(sent_packets_.template project<0>(it));
273 next_sent_ = eraseSent(sent_packets_.template project<0>(it));
276 packet_found =
false;
292 PktPtr sent_packet(*next_sent_);
296 next_sent_ = eraseSent(next_sent_);
305 if (!archive_enabled_) {
307 "packets archive mode is disabled");
309 if (rcvd_packets_num_ == 0) {
310 std::cout <<
"Unavailable! No packets received." << std::endl;
313 using namespace boost::posix_time;
317 it != rcvd_packets_.end();
321 archived_packets_.template get<1>();
326 it_archived != p.second;
328 if ((*it_archived)->getTransid() ==
329 rcvd_packet->getTransid()) {
330 PktPtr sent_packet = *it_archived;
332 ptime sent_time = sent_packet->getTimestamp();
333 ptime rcvd_time = rcvd_packet->getTimestamp();
337 if (sent_time.is_not_a_date_time() ||
338 rcvd_time.is_not_a_date_time()) {
340 "packet time is not set");
343 time_period sent_period(boot_time_, sent_time);
344 time_period rcvd_period(boot_time_, rcvd_time);
346 std::cout <<
"sent / received: "
347 << to_iso_string(sent_period.length())
349 << to_iso_string(rcvd_period.length())
359 boot_time_(
boost::posix_time::microsec_clock::universal_time())
399 std::stringstream result;
401 for (
PktPtr const& packet : rcvd_packets_) {
407 if (client_id_option) {
412 if (client_id_option) {
413 result <<
DUID(client_id_option->getData()).
toText();
422 Pkt4Ptr const& packet4(boost::dynamic_pointer_cast<Pkt4>(packet));
424 result << packet4->getYiaddr().toText();
430 boost::dynamic_pointer_cast<Option6IAAddr>(
433 result << iaaddr->getAddress().toText();
443 boost::dynamic_pointer_cast<Option6IAPrefix>(
446 result << iaprefix->getAddress().toText();
462 for (
auto const& exchange : exchanges_) {
463 std::cout <<
"***Leases for " << exchange.first <<
"***" << std::endl;
464 std::cout <<
"client_id,adrress,prefix" << std::endl;
465 exchange.second->printLeases();
466 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.
bool testDiags(const char diag)
Find if diagnostic flag has been set.
int getRenewRate() const
Returns a rate at which DHCPv6 Renew messages are sent.
uint8_t getIpVersion() const
Returns IP version.
std::vector< double > getDropTime() const
Returns drop time.
int getReleaseRate() const
Returns a rate at which DHCPv6 Release messages are sent.
ExchangeMode getExchangeMode() const
Returns packet exchange mode.
PktList::iterator PktListIterator
Packet list iterator for sequential access to elements.
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.