33 switch (exchange_type) {
45 "unrecognized exchange type '" << exchange_type <<
"'");
53 return(os <<
"DISCOVER-OFFER");
55 return(os <<
"REQUEST-ACK");
57 return(os <<
"REQUEST-ACK (renewal)");
59 return(os <<
"SOLICIT-ADVERTISE");
61 return(os <<
"REQUEST-REPLY");
63 return(os <<
"RENEW-REPLY");
65 return(os <<
"RELEASE-REPLY");
67 return(os <<
"Unknown exchange type");
73 const double drop_time,
74 const bool archive_enabled,
75 const boost::posix_time::ptime boot_time)
76 : xchg_type_(xchg_type),
80 archive_enabled_(archive_enabled),
81 drop_time_(drop_time),
82 min_delay_(
std::numeric_limits<double>::max()),
85 sum_delay_squared_(0.),
88 unordered_lookup_size_sum_(0),
89 unordered_lookups_(0),
93 non_unique_addr_num_(0),
94 rejected_leases_num_(0),
97 next_sent_ = sent_packets_.begin();
102 const PktPtr& rcvd_packet) {
110 boost::posix_time::ptime sent_time = sent_packet->getTimestamp();
111 boost::posix_time::ptime rcvd_time = rcvd_packet->getTimestamp();
113 if (sent_time.is_not_a_date_time() ||
114 rcvd_time.is_not_a_date_time()) {
116 "Timestamp must be set for sent and "
117 "received packet to measure RTT,"
118 <<
" sent: " << sent_time
119 <<
" recv: " << rcvd_time);
121 boost::posix_time::time_period period(sent_time, rcvd_time);
126 static_cast<double>(period.length().total_nanoseconds()) / 1e9;
130 "greater than received packet's timestamp in "
131 << xchg_type_ <<
".\nTime difference: "
132 << delta <<
", sent: " << sent_time <<
", rcvd: "
133 << rcvd_time <<
".\nTrans ID: " << sent_packet->getTransid()
138 if (delta < min_delay_) {
142 if (delta > max_delay_) {
148 sum_delay_squared_ += delta * delta;
159 if (sent_packets_.size() == 0) {
166 }
else if (next_sent_ == sent_packets_.end()) {
170 next_sent_ = sent_packets_.begin();
175 bool packet_found =
false;
182 if ((*next_sent_)->getTransid() == rcvd_packet->getTransid()) {
197 std::pair<PktListTransidHashIterator,PktListTransidHashIterator> p =
204 ++unordered_lookups_;
208 unordered_lookup_size_sum_ += std::distance(p.first, p.second);
209 bool non_expired_found =
false;
220 if (!packet_found && ((*it)->getTransid() == rcvd_packet->getTransid())) {
222 next_sent_ = sent_packets_.template project<0>(it);
225 if (!non_expired_found) {
228 ptime now = microsec_clock::universal_time();
229 ptime packet_time = (*it)->getTimestamp();
230 time_period packet_period(packet_time, now);
231 if (!packet_period.is_null()) {
232 double period_fractional =
233 packet_period.length().total_seconds() +
234 (
static_cast<double>(packet_period.length().fractional_seconds())
235 / packet_period.length().ticks_per_second());
236 if (drop_time_ > 0 && (period_fractional > drop_time_)) {
245 non_expired_found =
true;
252 if (non_expired_found && packet_found) {
258 while (!to_remove.empty()) {
267 if (sent_packets_.template project<0>(it) != next_sent_) {
268 eraseSent(sent_packets_.template project<0>(it));
270 next_sent_ = eraseSent(sent_packets_.template project<0>(it));
273 packet_found =
false;
289 PktPtr sent_packet(*next_sent_);
293 next_sent_ = eraseSent(next_sent_);
302 if (!archive_enabled_) {
304 "packets archive mode is disabled");
306 if (rcvd_packets_num_ == 0) {
307 std::cout <<
"Unavailable! No packets received." << std::endl;
314 it != rcvd_packets_.end();
318 archived_packets_.template get<1>();
320 PktListTransidHashIterator> p =
322 for (PktListTransidHashIterator it_archived = p.first;
323 it_archived != p.second;
325 if ((*it_archived)->getTransid() ==
326 rcvd_packet->getTransid()) {
327 PktPtr sent_packet = *it_archived;
329 ptime sent_time = sent_packet->getTimestamp();
330 ptime rcvd_time = rcvd_packet->getTimestamp();
334 if (sent_time.is_not_a_date_time() ||
335 rcvd_time.is_not_a_date_time()) {
337 "packet time is not set");
340 time_period sent_period(boot_time_, sent_time);
341 time_period rcvd_period(boot_time_, rcvd_time);
343 std::cout <<
"sent / received: "
344 << to_iso_string(sent_period.length())
346 << to_iso_string(rcvd_period.length())
356 boot_time_(
boost::posix_time::microsec_clock::universal_time())
394 std::stringstream result;
396 for (
PktPtr const& packet : rcvd_packets_) {
402 if (client_id_option) {
407 if (client_id_option) {
408 result <<
DUID(client_id_option->getData()).toText();
417 Pkt4Ptr const& packet4(boost::dynamic_pointer_cast<Pkt4>(packet));
419 result << packet4->getYiaddr().toText();
425 boost::dynamic_pointer_cast<Option6IAAddr>(
428 result << iaaddr->getAddress().toText();
438 boost::dynamic_pointer_cast<Option6IAPrefix>(
441 result << iaprefix->getAddress().toText();
457 for (
auto const& exchange : exchanges_) {
458 std::cout <<
"***Leases for " << exchange.first <<
"***" << std::endl;
459 std::cout <<
"client_id,adrress,prefix" << std::endl;
460 exchange.second->printLeases();
461 std::cout << std::endl;
DHCPv6 SOLICIT-ADVERTISE.
ExchangeType
DHCP packet exchange types.
static std::string vector2Hex(const std::vector< uint8_t > &vec, const std::string &separator="")
Convert vector in hexadecimal string.
static uint32_t hashTransid(const dhcp::PktPtr &packet)
Hash transaction id of the packet.
std::queue< PktListTransidHashIterator > PktListRemovalQueue
Packet list iterator queue for removal.
boost::shared_ptr< Option > OptionPtr
void updateDelays(const dhcp::PktPtr &sent_packet, const dhcp::PktPtr &rcvd_packet)
Update delay counters.
Holds DUID (DHCPv6 Unique Identifier)
std::vector< double > getDropTime() const
Returns drop time.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
StatsMgr(CommandOptions &options)
Constructor.
boost::shared_ptr< Option6IAPrefix > Option6IAPrefixPtr
Pointer to the Option6IAPrefix object.
DHCPv4 REQUEST-ACK (renewal)
A generic exception that is thrown when an unexpected error condition occurs.
void printLeases() const
Print the list of received leases.
int dhcpVersion(ExchangeType const exchange_type)
Get the DHCP version that fits the exchange type.
std::ostream & operator<<(std::ostream &os, ExchangeType xchg_type)
Return name of the exchange.
void printLeases() const
Delegate to all exchanges to print their leases.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
static int malformed_pkts_
uint8_t getIpVersion() const
Returns IP version.
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
dhcp::PktPtr matchPackets(const dhcp::PktPtr &rcvd_packet)
Match received packet with the corresponding sent packet.
Defines the logger used by the top-level component of kea-dhcp-ddns.
PktList::iterator PktListIterator
Packet list iterator for sequential access to elements.
PktList::template nth_index< 1 >::type PktListTransidHashIndex
Packet list index to search packets using transaction id hash.
Represents DHCPv4 packet.
void addExchangeStats(const ExchangeType xchg_type, const double drop_time=-1)
Specify new exchange type.
PktListTransidHashIndex::const_iterator PktListTransidHashIterator
Packet list iterator to access packets using transaction id hash.
ExchangeMode getExchangeMode() const
Returns packet exchange mode.
int getRenewRate() const
Returns a rate at which DHCPv6 Renew messages are sent.
A generic exception that is thrown if a function is called in a prohibited way.
bool testDiags(const char diag)
Find if diagnostic flag has been set.
int getReleaseRate() const
Returns a rate at which DHCPv6 Release messages are sent.
void addCustomCounter(const std::string &short_name, const std::string &long_name)
Add named custom uint64 counter.
Class that represents IAPREFIX option in DHCPv6.
void printTimestamps()
Print timestamps for sent and received packets.
boost::shared_ptr< Option6IAAddr > Option6IAAddrPtr
A pointer to the isc::dhcp::Option6IAAddr object.
std::string receivedLeases() const
Return the list of received leases in CSV format as string.