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_) {
 
  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())
 
  363        addExchangeStats(ExchangeType::DO, options.getDropTime()[0]);
 
  364        if (options.getExchangeMode() == CommandOptions::DORA_SARR) {
 
  365            addExchangeStats(ExchangeType::RA, options.getDropTime()[1]);
 
  368            addExchangeStats(ExchangeType::RNA);
 
  371            addExchangeStats(ExchangeType::RLA);
 
  373    } 
else if (options.getIpVersion() == 6) {
 
  374        addExchangeStats(ExchangeType::SA, options.getDropTime()[0]);
 
  375        if (options.getExchangeMode() == CommandOptions::DORA_SARR) {
 
  376            addExchangeStats(ExchangeType::RR, options.getDropTime()[1]);
 
  378        if (options.getRenewRate() != 0) {
 
  379            addExchangeStats(ExchangeType::RN);
 
  381        if (options.getReleaseRate() != 0) {
 
  382            addExchangeStats(ExchangeType::RL);
 
  385    if (options.testDiags(
'i')) {
 
  386        addCustomCounter(
"shortwait", 
"Short waits for packets");
 
 
  395    std::stringstream result;
 
  397    for (
PktPtr const& packet : rcvd_packets_) {
 
  403            if (client_id_option) {
 
  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();
 
  426                    boost::dynamic_pointer_cast<Option6IAAddr>(
 
  429                    result << iaaddr->getAddress().toText();
 
  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;
 
 
@ DHO_DHCP_CLIENT_IDENTIFIER
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.
int getReleaseRate() const
Returns a rate at which DHCPv6 Release messages are sent.
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.
ExchangeStats(const ExchangeType xchg_type, const double drop_time, const bool archive_enabled, const boost::posix_time::ptime boot_time)
Constructor.
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 printLeases() const
Delegate to all exchanges to print their leases.
StatsMgr(CommandOptions &options)
Constructor.
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.
int get(CalloutHandle &handle)
The gss-tsig-get command.
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.