mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-02 23:15:20 +00:00
[master] Merge branch 'trac4254'
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
|
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -691,8 +691,6 @@ CommandOptions::validate() const {
|
|||||||
"-B is not compatible with IPv6 (-6)");
|
"-B is not compatible with IPv6 (-6)");
|
||||||
check((getIpVersion() != 6) && (isRapidCommit() != 0),
|
check((getIpVersion() != 6) && (isRapidCommit() != 0),
|
||||||
"-6 (IPv6) must be set to use -c");
|
"-6 (IPv6) must be set to use -c");
|
||||||
check((getIpVersion() != 6) && (getRenewRate() !=0),
|
|
||||||
"-f<renew-rate> may be used with -6 (IPv6) only");
|
|
||||||
check((getIpVersion() != 6) && (getReleaseRate() != 0),
|
check((getIpVersion() != 6) && (getReleaseRate() != 0),
|
||||||
"-F<release-rate> may be used with -6 (IPv6) only");
|
"-F<release-rate> may be used with -6 (IPv6) only");
|
||||||
check((getExchangeMode() == DO_SA) && (getNumRequests().size() > 1),
|
check((getExchangeMode() == DO_SA) && (getNumRequests().size() > 1),
|
||||||
@@ -963,6 +961,11 @@ CommandOptions::usage() const {
|
|||||||
"-E<time-offset>: Offset of the (DHCPv4) secs field / (DHCPv6)\n"
|
"-E<time-offset>: Offset of the (DHCPv4) secs field / (DHCPv6)\n"
|
||||||
" elapsed-time option in the (second/request) template.\n"
|
" elapsed-time option in the (second/request) template.\n"
|
||||||
" The value 0 disables it.\n"
|
" The value 0 disables it.\n"
|
||||||
|
"-f<renew-rate>: Rate at which DHCPv4 or DHCPv6 renew requests are sent\n"
|
||||||
|
" to a server. This value is only valid when used in conjunction\n"
|
||||||
|
" with the exchange rate (given by -r<rate>). Furthermore the sum of\n"
|
||||||
|
" this value and the release-rate (given by -F<rate) must be equal\n"
|
||||||
|
" to or less than the exchange rate.\n"
|
||||||
"-h: Print this help.\n"
|
"-h: Print this help.\n"
|
||||||
"-i: Do only the initial part of an exchange: DO or SA, depending on\n"
|
"-i: Do only the initial part of an exchange: DO or SA, depending on\n"
|
||||||
" whether -6 is given.\n"
|
" whether -6 is given.\n"
|
||||||
@@ -1010,11 +1013,6 @@ CommandOptions::usage() const {
|
|||||||
"\n"
|
"\n"
|
||||||
"DHCPv6 only options:\n"
|
"DHCPv6 only options:\n"
|
||||||
"-c: Add a rapid commit option (exchanges will be SA).\n"
|
"-c: Add a rapid commit option (exchanges will be SA).\n"
|
||||||
"-f<renew-rate>: Rate at which IPv6 Renew requests are sent to\n"
|
|
||||||
" a server. This value is only valid when used in conjunction with\n"
|
|
||||||
" the exchange rate (given by -r<rate>). Furthermore the sum of\n"
|
|
||||||
" this value and the release-rate (given by -F<rate) must be equal\n"
|
|
||||||
" to or less than the exchange rate.\n"
|
|
||||||
"-F<release-rate>: Rate at which IPv6 Release requests are sent to\n"
|
"-F<release-rate>: Rate at which IPv6 Release requests are sent to\n"
|
||||||
" a server. This value is only valid when used in conjunction with\n"
|
" a server. This value is only valid when used in conjunction with\n"
|
||||||
" the exchange rate (given by -r<rate>). Furthermore the sum of\n"
|
" the exchange rate (given by -r<rate>). Furthermore the sum of\n"
|
||||||
|
@@ -318,6 +318,23 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-f <replaceable class="parameter">renew-rate</replaceable></option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Rate at which DHCPv4 or DHCPv6 renew requests are sent
|
||||||
|
to a server. This value is only valid when used in conjunction
|
||||||
|
with the exchange rate (given by <option>-r <replaceable
|
||||||
|
class="parameter">rate</replaceable></option>).
|
||||||
|
Furthermore the sum of this value and the release-rate
|
||||||
|
(given by <option>-F <replaceable class="parameter">
|
||||||
|
rate</replaceable></option>) must be equal to or less than
|
||||||
|
the exchange rate.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-h</option></term>
|
<term><option>-h</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@@ -560,23 +577,6 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><option>-f <replaceable class="parameter">renew-rate</replaceable></option></term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Rate at which IPv6 RENEW requests are sent
|
|
||||||
to a server. This value is only valid when
|
|
||||||
used in conjunction with the exchange
|
|
||||||
rate (given by <option>-r <replaceable
|
|
||||||
class="parameter">rate</replaceable></option>).
|
|
||||||
Furthermore the sum of this value and the
|
|
||||||
release-rate (given by <option>-F <replaceable
|
|
||||||
class="parameter">rate</replaceable></option>)
|
|
||||||
must be equal to or less than the exchange rate.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-F <replaceable class="parameter">release-rate</replaceable></option></term>
|
<term><option>-F <replaceable class="parameter">release-rate</replaceable></option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
|
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
|
||||||
namespace isc {
|
namespace isc {
|
||||||
@@ -114,6 +115,7 @@ public:
|
|||||||
enum ExchangeType {
|
enum ExchangeType {
|
||||||
XCHG_DO, ///< DHCPv4 DISCOVER-OFFER
|
XCHG_DO, ///< DHCPv4 DISCOVER-OFFER
|
||||||
XCHG_RA, ///< DHCPv4 REQUEST-ACK
|
XCHG_RA, ///< DHCPv4 REQUEST-ACK
|
||||||
|
XCHG_RNA, ///< DHCPv4 REQUEST-ACK (renewal)
|
||||||
XCHG_SA, ///< DHCPv6 SOLICIT-ADVERTISE
|
XCHG_SA, ///< DHCPv6 SOLICIT-ADVERTISE
|
||||||
XCHG_RR, ///< DHCPv6 REQUEST-REPLY
|
XCHG_RR, ///< DHCPv6 REQUEST-REPLY
|
||||||
XCHG_RN, ///< DHCPv6 RENEW-REPLY
|
XCHG_RN, ///< DHCPv6 RENEW-REPLY
|
||||||
@@ -172,7 +174,7 @@ public:
|
|||||||
/// 1023 values maximum. Search operation on this index generally
|
/// 1023 values maximum. Search operation on this index generally
|
||||||
/// returns the range of packets that have the same transaction id
|
/// returns the range of packets that have the same transaction id
|
||||||
/// hash assigned but most often these ranges will be short so further
|
/// hash assigned but most often these ranges will be short so further
|
||||||
/// search within a range to find a packet with pacrticular transaction
|
/// search within a range to find a packet with particular transaction
|
||||||
/// id will not be intensive.
|
/// id will not be intensive.
|
||||||
///
|
///
|
||||||
/// Example 1: Add elements to the list
|
/// Example 1: Add elements to the list
|
||||||
@@ -188,7 +190,7 @@ public:
|
|||||||
/// packets_collection.template get<0>().push_back(pkt2);
|
/// packets_collection.template get<0>().push_back(pkt2);
|
||||||
/// \endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
/// Example 2: Access elements through sequencial index
|
/// Example 2: Access elements through sequential index
|
||||||
/// \code
|
/// \code
|
||||||
/// PktList packets_collection();
|
/// PktList packets_collection();
|
||||||
/// ... # Add elements to the container
|
/// ... # Add elements to the container
|
||||||
@@ -241,7 +243,7 @@ public:
|
|||||||
>
|
>
|
||||||
> PktList;
|
> PktList;
|
||||||
|
|
||||||
/// Packet list iterator for sequencial access to elements.
|
/// Packet list iterator for sequential access to elements.
|
||||||
typedef typename PktList::iterator PktListIterator;
|
typedef typename PktList::iterator PktListIterator;
|
||||||
/// Packet list index to search packets using transaction id hash.
|
/// Packet list index to search packets using transaction id hash.
|
||||||
typedef typename PktList::template nth_index<1>::type
|
typedef typename PktList::template nth_index<1>::type
|
||||||
@@ -249,6 +251,9 @@ public:
|
|||||||
/// Packet list iterator to access packets using transaction id hash.
|
/// Packet list iterator to access packets using transaction id hash.
|
||||||
typedef typename PktListTransidHashIndex::const_iterator
|
typedef typename PktListTransidHashIndex::const_iterator
|
||||||
PktListTransidHashIterator;
|
PktListTransidHashIterator;
|
||||||
|
/// Packet list iterator queue for removal.
|
||||||
|
typedef typename std::queue<PktListTransidHashIterator>
|
||||||
|
PktListRemovalQueue;
|
||||||
|
|
||||||
/// \brief Constructor
|
/// \brief Constructor
|
||||||
///
|
///
|
||||||
@@ -419,7 +424,7 @@ public:
|
|||||||
// take a little more expensive approach to look packets using
|
// take a little more expensive approach to look packets using
|
||||||
// alternative index (transaction id & 1023).
|
// alternative index (transaction id & 1023).
|
||||||
PktListTransidHashIndex& idx = sent_packets_.template get<1>();
|
PktListTransidHashIndex& idx = sent_packets_.template get<1>();
|
||||||
// Packets are grouped using trasaction id masked with value
|
// Packets are grouped using transaction id masked with value
|
||||||
// of 1023. For instance, packets with transaction id equal to
|
// of 1023. For instance, packets with transaction id equal to
|
||||||
// 1, 1024 ... will belong to the same group (a.k.a. bucket).
|
// 1, 1024 ... will belong to the same group (a.k.a. bucket).
|
||||||
// When using alternative index we don't find the packet but
|
// When using alternative index we don't find the packet but
|
||||||
@@ -437,6 +442,8 @@ public:
|
|||||||
// bucket size the better. If bucket sizes appear to big we
|
// bucket size the better. If bucket sizes appear to big we
|
||||||
// might want to increase number of buckets.
|
// might want to increase number of buckets.
|
||||||
unordered_lookup_size_sum_ += std::distance(p.first, p.second);
|
unordered_lookup_size_sum_ += std::distance(p.first, p.second);
|
||||||
|
// Removal can be done only after the loop
|
||||||
|
PktListRemovalQueue to_remove;
|
||||||
for (PktListTransidHashIterator it = p.first; it != p.second;
|
for (PktListTransidHashIterator it = p.first; it != p.second;
|
||||||
++it) {
|
++it) {
|
||||||
if ((*it)->getTransid() == rcvd_packet->getTransid()) {
|
if ((*it)->getTransid() == rcvd_packet->getTransid()) {
|
||||||
@@ -454,20 +461,31 @@ public:
|
|||||||
(static_cast<double>(packet_period.length().fractional_seconds())
|
(static_cast<double>(packet_period.length().fractional_seconds())
|
||||||
/ packet_period.length().ticks_per_second());
|
/ packet_period.length().ticks_per_second());
|
||||||
if (drop_time_ > 0 && (period_fractional > drop_time_)) {
|
if (drop_time_ > 0 && (period_fractional > drop_time_)) {
|
||||||
// The packet pointed to by 'it' is timed out so we
|
// Push the iterator on the removal queue.
|
||||||
// have to remove it. Removal may invalidate the
|
to_remove.push(it);
|
||||||
// next_sent_ pointer if it points to the packet
|
|
||||||
// being removed. So, we set the next_sent_ to point
|
}
|
||||||
// to the next packet after removed one. This
|
}
|
||||||
// pointer will be further updated in the following
|
}
|
||||||
// iterations, if the subsequent packets are also
|
|
||||||
// timed out.
|
// Deal with the removal queue
|
||||||
|
while (!to_remove.empty()) {
|
||||||
|
PktListTransidHashIterator it = to_remove.front();
|
||||||
|
to_remove.pop();
|
||||||
|
// The packet pointed to by 'it' is timed out so
|
||||||
|
// we have to remove it.
|
||||||
|
if (packet_found || !to_remove.empty()) {
|
||||||
|
eraseSent(sent_packets_.template project<0>(it));
|
||||||
|
} else {
|
||||||
|
// Removal may invalidate the next_sent_
|
||||||
|
// pointer if it points to the packet being
|
||||||
|
// removed. So, we set the next_sent_ to point
|
||||||
|
// to the next packet after removed one.
|
||||||
next_sent_ = eraseSent(sent_packets_.template project<0>(it));
|
next_sent_ = eraseSent(sent_packets_.template project<0>(it));
|
||||||
|
}
|
||||||
++collected_;
|
++collected_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!packet_found) {
|
if (!packet_found) {
|
||||||
// If we are here, it means that both ordered lookup and
|
// If we are here, it means that both ordered lookup and
|
||||||
@@ -487,14 +505,14 @@ public:
|
|||||||
return(sent_packet);
|
return(sent_packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Return minumum delay between sent and received packet.
|
/// \brief Return minimum delay between sent and received packet.
|
||||||
///
|
///
|
||||||
/// Method returns minimum delay between sent and received packet.
|
/// Method returns minimum delay between sent and received packet.
|
||||||
///
|
///
|
||||||
/// \return minimum delay between packets.
|
/// \return minimum delay between packets.
|
||||||
double getMinDelay() const { return(min_delay_); }
|
double getMinDelay() const { return(min_delay_); }
|
||||||
|
|
||||||
/// \brief Return maxmimum delay between sent and received packet.
|
/// \brief Return maximum delay between sent and received packet.
|
||||||
///
|
///
|
||||||
/// Method returns maximum delay between sent and received packet.
|
/// Method returns maximum delay between sent and received packet.
|
||||||
///
|
///
|
||||||
@@ -535,13 +553,13 @@ public:
|
|||||||
getAvgDelay() * getAvgDelay()));
|
getAvgDelay() * getAvgDelay()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Return number of orphant packets.
|
/// \brief Return number of orphan packets.
|
||||||
///
|
///
|
||||||
/// Method returns number of received packets that had no matching
|
/// Method returns number of received packets that had no matching
|
||||||
/// sent packet. It is possible that such packet was late or not
|
/// sent packet. It is possible that such packet was late or not
|
||||||
/// for us.
|
/// for us.
|
||||||
///
|
///
|
||||||
/// \return number of orphant received packets.
|
/// \return number of orphan received packets.
|
||||||
uint64_t getOrphans() const { return(orphans_); }
|
uint64_t getOrphans() const { return(orphans_); }
|
||||||
|
|
||||||
/// \brief Return number of garbage collected packets.
|
/// \brief Return number of garbage collected packets.
|
||||||
@@ -631,7 +649,8 @@ public:
|
|||||||
/// orphans for the 4-way exchanges, which is wrong. We will need to
|
/// orphans for the 4-way exchanges, which is wrong. We will need to
|
||||||
/// move the orphans counting out of the Statistics Manager so as
|
/// move the orphans counting out of the Statistics Manager so as
|
||||||
/// orphans counter is increased only if the particular message is
|
/// orphans counter is increased only if the particular message is
|
||||||
/// not identified as a reponse to any of the messages sent by perfdhcp.
|
/// not identified as a response to any of the messages sent by
|
||||||
|
/// perfdhcp.
|
||||||
void printMainStats() const {
|
void printMainStats() const {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
cout << "sent packets: " << getSentPacketsNum() << endl
|
cout << "sent packets: " << getSentPacketsNum() << endl
|
||||||
@@ -752,7 +771,7 @@ public:
|
|||||||
// when test is completed.
|
// when test is completed.
|
||||||
archived_packets_.push_back(*it);
|
archived_packets_.push_back(*it);
|
||||||
}
|
}
|
||||||
// get<0>() template returns sequencial index to
|
// get<0>() template returns sequential index to
|
||||||
// container.
|
// container.
|
||||||
return(sent_packets_.template get<0>().erase(it));
|
return(sent_packets_.template get<0>().erase(it));
|
||||||
}
|
}
|
||||||
@@ -785,7 +804,7 @@ public:
|
|||||||
/// to keep all packets archived throughout the test.
|
/// to keep all packets archived throughout the test.
|
||||||
bool archive_enabled_;
|
bool archive_enabled_;
|
||||||
|
|
||||||
/// Maxmimum time elapsed between sending and receiving packet
|
/// Maximum time elapsed between sending and receiving packet
|
||||||
/// before packet is assumed dropped.
|
/// before packet is assumed dropped.
|
||||||
double drop_time_;
|
double drop_time_;
|
||||||
|
|
||||||
@@ -796,16 +815,16 @@ public:
|
|||||||
double sum_delay_; ///< Sum of delays between sent
|
double sum_delay_; ///< Sum of delays between sent
|
||||||
///< and received packets.
|
///< and received packets.
|
||||||
double sum_delay_squared_; ///< Squared sum of delays between
|
double sum_delay_squared_; ///< Squared sum of delays between
|
||||||
///< sent and recived packets.
|
///< sent and received packets.
|
||||||
|
|
||||||
uint64_t orphans_; ///< Number of orphant received packets.
|
uint64_t orphans_; ///< Number of orphan received packets.
|
||||||
|
|
||||||
uint64_t collected_; ///< Number of garbage collected packets.
|
uint64_t collected_; ///< Number of garbage collected packets.
|
||||||
|
|
||||||
/// Sum of unordered lookup sets. Needed to calculate mean size of
|
/// Sum of unordered lookup sets. Needed to calculate mean size of
|
||||||
/// lookup set. It is desired that number of unordered lookups is
|
/// lookup set. It is desired that number of unordered lookups is
|
||||||
/// minimal for performance reasons. Tracking number of lookups and
|
/// minimal for performance reasons. Tracking number of lookups and
|
||||||
/// mean size of the lookup set should give idea of packets serach
|
/// mean size of the lookup set should give idea of packets search
|
||||||
/// complexity.
|
/// complexity.
|
||||||
uint64_t unordered_lookup_size_sum_;
|
uint64_t unordered_lookup_size_sum_;
|
||||||
|
|
||||||
@@ -823,7 +842,7 @@ public:
|
|||||||
typedef boost::shared_ptr<ExchangeStats> ExchangeStatsPtr;
|
typedef boost::shared_ptr<ExchangeStats> ExchangeStatsPtr;
|
||||||
/// Map containing all specified exchange types.
|
/// Map containing all specified exchange types.
|
||||||
typedef typename std::map<ExchangeType, ExchangeStatsPtr> ExchangesMap;
|
typedef typename std::map<ExchangeType, ExchangeStatsPtr> ExchangesMap;
|
||||||
/// Iterator poiting to \ref ExchangesMap
|
/// Iterator pointing to \ref ExchangesMap
|
||||||
typedef typename ExchangesMap::const_iterator ExchangesMapIterator;
|
typedef typename ExchangesMap::const_iterator ExchangesMapIterator;
|
||||||
/// Map containing custom counters.
|
/// Map containing custom counters.
|
||||||
typedef typename std::map<std::string, CustomCounterPtr> CustomCountersMap;
|
typedef typename std::map<std::string, CustomCounterPtr> CustomCountersMap;
|
||||||
@@ -876,7 +895,7 @@ public:
|
|||||||
/// This method checks if the \ref ExchangeStats object of a particular type
|
/// This method checks if the \ref ExchangeStats object of a particular type
|
||||||
/// exists (has been added using \ref addExchangeStats function).
|
/// exists (has been added using \ref addExchangeStats function).
|
||||||
///
|
///
|
||||||
/// \param xchg_type A type of the exchange being repersented by the
|
/// \param xchg_type A type of the exchange being represented by the
|
||||||
/// \ref ExchangeStats object.
|
/// \ref ExchangeStats object.
|
||||||
///
|
///
|
||||||
/// \return true if the \ref ExchangeStats object has been added for a
|
/// \return true if the \ref ExchangeStats object has been added for a
|
||||||
@@ -902,9 +921,9 @@ public:
|
|||||||
CustomCounterPtr(new CustomCounter(long_name));
|
CustomCounterPtr(new CustomCounter(long_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Check if any packet drops occured.
|
/// \brief Check if any packet drops occurred.
|
||||||
///
|
///
|
||||||
// \return true, if packet drops occured.
|
// \return true, if packet drops occurred.
|
||||||
bool droppedPackets() const {
|
bool droppedPackets() const {
|
||||||
for (ExchangesMapIterator it = exchanges_.begin();
|
for (ExchangesMapIterator it = exchanges_.begin();
|
||||||
it != exchanges_.end();
|
it != exchanges_.end();
|
||||||
@@ -920,7 +939,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// Method returns specified counter.
|
/// Method returns specified counter.
|
||||||
///
|
///
|
||||||
/// \param counter_key key poiting to the counter in the counters map.
|
/// \param counter_key key pointing to the counter in the counters map.
|
||||||
/// The short counter name has to be used to access counter.
|
/// The short counter name has to be used to access counter.
|
||||||
/// \return pointer to specified counter object.
|
/// \return pointer to specified counter object.
|
||||||
CustomCounterPtr getCounter(const std::string& counter_key) {
|
CustomCounterPtr getCounter(const std::string& counter_key) {
|
||||||
@@ -936,7 +955,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// Increment counter value by one.
|
/// Increment counter value by one.
|
||||||
///
|
///
|
||||||
/// \param counter_key key poiting to the counter in the counters map.
|
/// \param counter_key key pointing to the counter in the counters map.
|
||||||
/// \param value value to increment counter by.
|
/// \param value value to increment counter by.
|
||||||
/// \return pointer to specified counter after incrementation.
|
/// \return pointer to specified counter after incrementation.
|
||||||
const CustomCounter& incrementCounter(const std::string& counter_key,
|
const CustomCounter& incrementCounter(const std::string& counter_key,
|
||||||
@@ -991,7 +1010,7 @@ public:
|
|||||||
return(sent_packet);
|
return(sent_packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Return minumum delay between sent and received packet.
|
/// \brief Return minimum delay between sent and received packet.
|
||||||
///
|
///
|
||||||
/// Method returns minimum delay between sent and received packet
|
/// Method returns minimum delay between sent and received packet
|
||||||
/// for specified exchange type.
|
/// for specified exchange type.
|
||||||
@@ -1004,7 +1023,7 @@ public:
|
|||||||
return(xchg_stats->getMinDelay());
|
return(xchg_stats->getMinDelay());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Return maxmimum delay between sent and received packet.
|
/// \brief Return maximum delay between sent and received packet.
|
||||||
///
|
///
|
||||||
/// Method returns maximum delay between sent and received packet
|
/// Method returns maximum delay between sent and received packet
|
||||||
/// for specified exchange type.
|
/// for specified exchange type.
|
||||||
@@ -1039,14 +1058,14 @@ public:
|
|||||||
return(xchg_stats->getStdDevDelay());
|
return(xchg_stats->getStdDevDelay());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Return number of orphant packets.
|
/// \brief Return number of orphan packets.
|
||||||
///
|
///
|
||||||
/// Method returns number of orphant packets for specified
|
/// Method returns number of orphan packets for specified
|
||||||
/// exchange type.
|
/// exchange type.
|
||||||
///
|
///
|
||||||
/// \param xchg_type exchange type.
|
/// \param xchg_type exchange type.
|
||||||
/// \throw isc::BadValue if invalid exchange type specified.
|
/// \throw isc::BadValue if invalid exchange type specified.
|
||||||
/// \return number of orphant packets so far.
|
/// \return number of orphan packets so far.
|
||||||
uint64_t getOrphans(const ExchangeType xchg_type) const {
|
uint64_t getOrphans(const ExchangeType xchg_type) const {
|
||||||
ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
|
ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
|
||||||
return(xchg_stats->getOrphans());
|
return(xchg_stats->getOrphans());
|
||||||
@@ -1179,6 +1198,8 @@ public:
|
|||||||
return("DISCOVER-OFFER");
|
return("DISCOVER-OFFER");
|
||||||
case XCHG_RA:
|
case XCHG_RA:
|
||||||
return("REQUEST-ACK");
|
return("REQUEST-ACK");
|
||||||
|
case XCHG_RNA:
|
||||||
|
return("REQUEST-ACK (renewal)");
|
||||||
case XCHG_SA:
|
case XCHG_SA:
|
||||||
return("SOLICIT-ADVERTISE");
|
return("SOLICIT-ADVERTISE");
|
||||||
case XCHG_RR:
|
case XCHG_RR:
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
|
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -315,6 +315,22 @@ TestControl::checkExitConditions() const {
|
|||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pkt4Ptr
|
||||||
|
TestControl::createRequestFromAck(const dhcp::Pkt4Ptr& ack) {
|
||||||
|
if (!ack) {
|
||||||
|
isc_throw(isc::BadValue, "Unable to create DHCPREQUEST from a"
|
||||||
|
" null DHCPACK message");
|
||||||
|
} else if (ack->getYiaddr().isV4Zero()) {
|
||||||
|
isc_throw(isc::BadValue, "Unable to create DHCPREQUEST from a"
|
||||||
|
" DHCPACK message containing yiaddr of 0");
|
||||||
|
}
|
||||||
|
Pkt4Ptr msg(new Pkt4(DHCPREQUEST, generateTransid()));
|
||||||
|
msg->setCiaddr(ack->getYiaddr());
|
||||||
|
msg->setHWAddr(ack->getHWAddr());
|
||||||
|
msg->addOption(generateClientId(msg->getHWAddr()));
|
||||||
|
return (msg);
|
||||||
|
}
|
||||||
|
|
||||||
Pkt6Ptr
|
Pkt6Ptr
|
||||||
TestControl::createMessageFromReply(const uint16_t msg_type,
|
TestControl::createMessageFromReply(const uint16_t msg_type,
|
||||||
const dhcp::Pkt6Ptr& reply) {
|
const dhcp::Pkt6Ptr& reply) {
|
||||||
@@ -481,6 +497,15 @@ TestControl::generateMacAddress(uint8_t& randomized) const {
|
|||||||
return (mac_addr);
|
return (mac_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OptionPtr
|
||||||
|
TestControl::generateClientId(const dhcp::HWAddrPtr& hwaddr) const {
|
||||||
|
std::vector<uint8_t> client_id(1, static_cast<uint8_t>(hwaddr->htype_));
|
||||||
|
client_id.insert(client_id.end(), hwaddr->hwaddr_.begin(),
|
||||||
|
hwaddr->hwaddr_.end());
|
||||||
|
return (OptionPtr(new Option(Option::V4, DHO_DHCP_CLIENT_IDENTIFIER,
|
||||||
|
client_id)));
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<uint8_t>
|
std::vector<uint8_t>
|
||||||
TestControl::generateDuid(uint8_t& randomized) const {
|
TestControl::generateDuid(uint8_t& randomized) const {
|
||||||
CommandOptions& options = CommandOptions::instance();
|
CommandOptions& options = CommandOptions::instance();
|
||||||
@@ -663,6 +688,9 @@ TestControl::initializeStatsMgr() {
|
|||||||
stats_mgr4_->addExchangeStats(StatsMgr4::XCHG_RA,
|
stats_mgr4_->addExchangeStats(StatsMgr4::XCHG_RA,
|
||||||
options.getDropTime()[1]);
|
options.getDropTime()[1]);
|
||||||
}
|
}
|
||||||
|
if (options.getRenewRate() != 0) {
|
||||||
|
stats_mgr4_->addExchangeStats(StatsMgr4::XCHG_RNA);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (options.getIpVersion() == 6) {
|
} else if (options.getIpVersion() == 6) {
|
||||||
stats_mgr6_.reset();
|
stats_mgr6_.reset();
|
||||||
@@ -725,7 +753,7 @@ TestControl::openSocket() const {
|
|||||||
// Local name is specified along with '-l' option.
|
// Local name is specified along with '-l' option.
|
||||||
// It may point to interface name or local address.
|
// It may point to interface name or local address.
|
||||||
if (!localname.empty()) {
|
if (!localname.empty()) {
|
||||||
// CommandOptions should be already aware wether local name
|
// CommandOptions should be already aware whether local name
|
||||||
// is interface name or address because it uses IfaceMgr to
|
// is interface name or address because it uses IfaceMgr to
|
||||||
// scan interfaces and get's their names.
|
// scan interfaces and get's their names.
|
||||||
if (options.isInterface()) {
|
if (options.isInterface()) {
|
||||||
@@ -798,7 +826,7 @@ TestControl::sendPackets(const TestControlSocket& socket,
|
|||||||
for (uint64_t i = packets_num; i > 0; --i) {
|
for (uint64_t i = packets_num; i > 0; --i) {
|
||||||
if (options.getIpVersion() == 4) {
|
if (options.getIpVersion() == 4) {
|
||||||
// No template packets means that no -T option was specified.
|
// No template packets means that no -T option was specified.
|
||||||
// We have to build packets ourselfs.
|
// We have to build packets ourselves.
|
||||||
if (template_buffers_.empty()) {
|
if (template_buffers_.empty()) {
|
||||||
sendDiscover4(socket, preload);
|
sendDiscover4(socket, preload);
|
||||||
} else {
|
} else {
|
||||||
@@ -808,7 +836,7 @@ TestControl::sendPackets(const TestControlSocket& socket,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No template packets means that no -T option was specified.
|
// No template packets means that no -T option was specified.
|
||||||
// We have to build packets ourselfs.
|
// We have to build packets ourselves.
|
||||||
if (template_buffers_.empty()) {
|
if (template_buffers_.empty()) {
|
||||||
sendSolicit6(socket, preload);
|
sendSolicit6(socket, preload);
|
||||||
} else {
|
} else {
|
||||||
@@ -831,6 +859,17 @@ TestControl::sendPackets(const TestControlSocket& socket,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
TestControl::sendMultipleRequests(const TestControlSocket& socket,
|
||||||
|
const uint64_t msg_num) {
|
||||||
|
for (uint64_t i = 0; i < msg_num; ++i) {
|
||||||
|
if (!sendRequestFromAck(socket)) {
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (msg_num);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
TestControl::sendMultipleMessages6(const TestControlSocket& socket,
|
TestControl::sendMultipleMessages6(const TestControlSocket& socket,
|
||||||
const uint32_t msg_type,
|
const uint32_t msg_type,
|
||||||
@@ -1072,7 +1111,28 @@ TestControl::processReceivedPacket4(const TestControlSocket& socket,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (pkt4->getType() == DHCPACK) {
|
} else if (pkt4->getType() == DHCPACK) {
|
||||||
stats_mgr4_->passRcvdPacket(StatsMgr4::XCHG_RA, pkt4);
|
// If received message is DHCPACK, we have to check if this is
|
||||||
|
// a response to 4-way exchange. We'll match this packet with
|
||||||
|
// a DHCPREQUEST sent as part of the 4-way exchanges.
|
||||||
|
if (stats_mgr4_->passRcvdPacket(StatsMgr4::XCHG_RA, pkt4)) {
|
||||||
|
// The DHCPACK belongs to DHCPREQUEST-DHCPACK exchange type.
|
||||||
|
// So, we may need to keep this DHCPACK in the storage if renews.
|
||||||
|
// Note that, DHCPACK messages hold the information about
|
||||||
|
// leases assigned. We use this information to renew.
|
||||||
|
if (stats_mgr4_->hasExchangeStats(StatsMgr4::XCHG_RNA)) {
|
||||||
|
// Renew messages are sent, because StatsMgr has the
|
||||||
|
// specific exchange type specified. Let's append the DHCPACK.
|
||||||
|
// message to a storage
|
||||||
|
ack_storage_.append(pkt4);
|
||||||
|
}
|
||||||
|
// The DHCPACK message is not a server's response to the DHCPREQUEST
|
||||||
|
// message sent within the 4-way exchange. It may be a response to a
|
||||||
|
// renewal. In this case we first check if StatsMgr has exchange type
|
||||||
|
// for renew specified, and if it has, if there is a corresponding
|
||||||
|
// renew message for the received DHCPACK.
|
||||||
|
} else if (stats_mgr4_->hasExchangeStats(StatsMgr4::XCHG_RNA)) {
|
||||||
|
stats_mgr4_->passRcvdPacket(StatsMgr4::XCHG_RNA, pkt4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1364,13 +1424,18 @@ TestControl::run() {
|
|||||||
|
|
||||||
// If -f<renew-rate> option was specified we have to check how many
|
// If -f<renew-rate> option was specified we have to check how many
|
||||||
// Renew packets should be sent to catch up with a desired rate.
|
// Renew packets should be sent to catch up with a desired rate.
|
||||||
if ((options.getIpVersion() == 6) && (options.getRenewRate() != 0)) {
|
if (options.getRenewRate() != 0) {
|
||||||
uint64_t renew_packets_due =
|
uint64_t renew_packets_due =
|
||||||
renew_rate_control_.getOutboundMessageCount();
|
renew_rate_control_.getOutboundMessageCount();
|
||||||
checkLateMessages(renew_rate_control_);
|
checkLateMessages(renew_rate_control_);
|
||||||
// Send Renew messages.
|
|
||||||
|
// Send multiple renews to satisfy the desired rate.
|
||||||
|
if (options.getIpVersion() == 4) {
|
||||||
|
sendMultipleRequests(socket, renew_packets_due);
|
||||||
|
} else {
|
||||||
sendMultipleMessages6(socket, DHCPV6_RENEW, renew_packets_due);
|
sendMultipleMessages6(socket, DHCPV6_RENEW, renew_packets_due);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If -F<release-rate> option was specified we have to check how many
|
// If -F<release-rate> option was specified we have to check how many
|
||||||
// Release messages should be sent to catch up with a desired rate.
|
// Release messages should be sent to catch up with a desired rate.
|
||||||
@@ -1389,7 +1454,7 @@ TestControl::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we are sending Renews to the server, the Reply packets are cached
|
// If we are sending Renews to the server, the Reply packets are cached
|
||||||
// so as leases for which we send Renews can be idenitfied. The major
|
// so as leases for which we send Renews can be identified. The major
|
||||||
// issue with this approach is that most of the time we are caching
|
// issue with this approach is that most of the time we are caching
|
||||||
// more packets than we actually need. This function removes excessive
|
// more packets than we actually need. This function removes excessive
|
||||||
// Reply messages to reduce the memory and CPU utilization. Note that
|
// Reply messages to reduce the memory and CPU utilization. Note that
|
||||||
@@ -1428,7 +1493,7 @@ TestControl::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ret_code = 0;
|
int ret_code = 0;
|
||||||
// Check if any packet drops occured.
|
// Check if any packet drops occurred.
|
||||||
if (options.getIpVersion() == 4) {
|
if (options.getIpVersion() == 4) {
|
||||||
ret_code = stats_mgr4_->droppedPackets() ? 3 : 0;
|
ret_code = stats_mgr4_->droppedPackets() ? 3 : 0;
|
||||||
} else if (options.getIpVersion() == 6) {
|
} else if (options.getIpVersion() == 6) {
|
||||||
@@ -1479,7 +1544,7 @@ TestControl::sendDiscover4(const TestControlSocket& socket,
|
|||||||
// Generate the MAC address to be passed in the packet.
|
// Generate the MAC address to be passed in the packet.
|
||||||
uint8_t randomized = 0;
|
uint8_t randomized = 0;
|
||||||
std::vector<uint8_t> mac_address = generateMacAddress(randomized);
|
std::vector<uint8_t> mac_address = generateMacAddress(randomized);
|
||||||
// Generate trasnaction id to be set for the new exchange.
|
// Generate transaction id to be set for the new exchange.
|
||||||
const uint32_t transid = generateTransid();
|
const uint32_t transid = generateTransid();
|
||||||
Pkt4Ptr pkt4(new Pkt4(DHCPDISCOVER, transid));
|
Pkt4Ptr pkt4(new Pkt4(DHCPDISCOVER, transid));
|
||||||
if (!pkt4) {
|
if (!pkt4) {
|
||||||
@@ -1504,6 +1569,9 @@ TestControl::sendDiscover4(const TestControlSocket& socket,
|
|||||||
// Set hardware address
|
// Set hardware address
|
||||||
pkt4->setHWAddr(HTYPE_ETHER, mac_address.size(), mac_address);
|
pkt4->setHWAddr(HTYPE_ETHER, mac_address.size(), mac_address);
|
||||||
|
|
||||||
|
// Set client identifier
|
||||||
|
pkt4->addOption(generateClientId(pkt4->getHWAddr()));
|
||||||
|
|
||||||
pkt4->pack();
|
pkt4->pack();
|
||||||
IfaceMgr::instance().send(pkt4);
|
IfaceMgr::instance().send(pkt4);
|
||||||
if (!preload) {
|
if (!preload) {
|
||||||
@@ -1521,13 +1589,13 @@ TestControl::sendDiscover4(const TestControlSocket& socket,
|
|||||||
const std::vector<uint8_t>& template_buf,
|
const std::vector<uint8_t>& template_buf,
|
||||||
const bool preload /* = false */) {
|
const bool preload /* = false */) {
|
||||||
basic_rate_control_.updateSendTime();
|
basic_rate_control_.updateSendTime();
|
||||||
// Get the first argument if mulitple the same arguments specified
|
// Get the first argument if multiple the same arguments specified
|
||||||
// in the command line. First one refers to DISCOVER packets.
|
// in the command line. First one refers to DISCOVER packets.
|
||||||
const uint8_t arg_idx = 0;
|
const uint8_t arg_idx = 0;
|
||||||
// Generate the MAC address to be passed in the packet.
|
// Generate the MAC address to be passed in the packet.
|
||||||
uint8_t randomized = 0;
|
uint8_t randomized = 0;
|
||||||
std::vector<uint8_t> mac_address = generateMacAddress(randomized);
|
std::vector<uint8_t> mac_address = generateMacAddress(randomized);
|
||||||
// Generate trasnaction id to be set for the new exchange.
|
// Generate transaction id to be set for the new exchange.
|
||||||
const uint32_t transid = generateTransid();
|
const uint32_t transid = generateTransid();
|
||||||
// Get transaction id offset.
|
// Get transaction id offset.
|
||||||
size_t transid_offset = getTransactionIdOffset(arg_idx);
|
size_t transid_offset = getTransactionIdOffset(arg_idx);
|
||||||
@@ -1568,6 +1636,32 @@ TestControl::sendDiscover4(const TestControlSocket& socket,
|
|||||||
saveFirstPacket(pkt4);
|
saveFirstPacket(pkt4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TestControl::sendRequestFromAck(const TestControlSocket& socket) {
|
||||||
|
// Update timestamp of last sent renewal.
|
||||||
|
renew_rate_control_.updateSendTime();
|
||||||
|
|
||||||
|
// Get one of the recorded DHCPACK messages.
|
||||||
|
Pkt4Ptr ack = ack_storage_.getRandom();
|
||||||
|
if (!ack) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create message of the specified type.
|
||||||
|
Pkt4Ptr msg = createRequestFromAck(ack);
|
||||||
|
setDefaults4(socket, msg);
|
||||||
|
msg->pack();
|
||||||
|
// And send it.
|
||||||
|
IfaceMgr::instance().send(msg);
|
||||||
|
if (!stats_mgr4_) {
|
||||||
|
isc_throw(Unexpected, "Statistics Manager for DHCPv4 "
|
||||||
|
"hasn't been initialized");
|
||||||
|
}
|
||||||
|
stats_mgr4_->passSentPacket(StatsMgr4::XCHG_RNA, msg);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TestControl::sendMessageFromReply(const uint16_t msg_type,
|
TestControl::sendMessageFromReply(const uint16_t msg_type,
|
||||||
const TestControlSocket& socket) {
|
const TestControlSocket& socket) {
|
||||||
@@ -1647,6 +1741,8 @@ TestControl::sendRequest4(const TestControlSocket& socket,
|
|||||||
|
|
||||||
// Set hardware address
|
// Set hardware address
|
||||||
pkt4->setHWAddr(offer_pkt4->getHWAddr());
|
pkt4->setHWAddr(offer_pkt4->getHWAddr());
|
||||||
|
// Set client id.
|
||||||
|
pkt4->addOption(generateClientId(pkt4->getHWAddr()));
|
||||||
// Set elapsed time.
|
// Set elapsed time.
|
||||||
uint32_t elapsed_time = getElapsedTime<Pkt4Ptr>(discover_pkt4, offer_pkt4);
|
uint32_t elapsed_time = getElapsedTime<Pkt4Ptr>(discover_pkt4, offer_pkt4);
|
||||||
pkt4->setSecs(static_cast<uint16_t>(elapsed_time / 1000));
|
pkt4->setSecs(static_cast<uint16_t>(elapsed_time / 1000));
|
||||||
@@ -1677,7 +1773,7 @@ TestControl::sendRequest4(const TestControlSocket& socket,
|
|||||||
// We need to go back by HW_ETHER_LEN (MAC address length)
|
// We need to go back by HW_ETHER_LEN (MAC address length)
|
||||||
// because this offset points to last octet of MAC address.
|
// because this offset points to last octet of MAC address.
|
||||||
size_t rand_offset = getRandomOffset(arg_idx) - HW_ETHER_LEN + 1;
|
size_t rand_offset = getRandomOffset(arg_idx) - HW_ETHER_LEN + 1;
|
||||||
// Create temporaru buffer from the template.
|
// Create temporary buffer from the template.
|
||||||
std::vector<uint8_t> in_buf(template_buf.begin(),
|
std::vector<uint8_t> in_buf(template_buf.begin(),
|
||||||
template_buf.end());
|
template_buf.end());
|
||||||
// Check if given randomization offset is not out of bounds.
|
// Check if given randomization offset is not out of bounds.
|
||||||
@@ -1946,7 +2042,7 @@ TestControl::sendSolicit6(const TestControlSocket& socket,
|
|||||||
// Generate DUID to be passed to the packet
|
// Generate DUID to be passed to the packet
|
||||||
uint8_t randomized = 0;
|
uint8_t randomized = 0;
|
||||||
std::vector<uint8_t> duid = generateDuid(randomized);
|
std::vector<uint8_t> duid = generateDuid(randomized);
|
||||||
// Generate trasnaction id to be set for the new exchange.
|
// Generate transaction id to be set for the new exchange.
|
||||||
const uint32_t transid = generateTransid();
|
const uint32_t transid = generateTransid();
|
||||||
Pkt6Ptr pkt6(new Pkt6(DHCPV6_SOLICIT, transid));
|
Pkt6Ptr pkt6(new Pkt6(DHCPV6_SOLICIT, transid));
|
||||||
if (!pkt6) {
|
if (!pkt6) {
|
||||||
@@ -1995,7 +2091,7 @@ TestControl::sendSolicit6(const TestControlSocket& socket,
|
|||||||
const int arg_idx = 0;
|
const int arg_idx = 0;
|
||||||
// Get transaction id offset.
|
// Get transaction id offset.
|
||||||
size_t transid_offset = getTransactionIdOffset(arg_idx);
|
size_t transid_offset = getTransactionIdOffset(arg_idx);
|
||||||
// Generate trasnaction id to be set for the new exchange.
|
// Generate transaction id to be set for the new exchange.
|
||||||
const uint32_t transid = generateTransid();
|
const uint32_t transid = generateTransid();
|
||||||
// Create packet.
|
// Create packet.
|
||||||
PerfPkt6Ptr pkt6(new PerfPkt6(&template_buf[0], template_buf.size(),
|
PerfPkt6Ptr pkt6(new PerfPkt6(&template_buf[0], template_buf.size(),
|
||||||
@@ -2005,7 +2101,7 @@ TestControl::sendSolicit6(const TestControlSocket& socket,
|
|||||||
}
|
}
|
||||||
size_t rand_offset = getRandomOffset(arg_idx);
|
size_t rand_offset = getRandomOffset(arg_idx);
|
||||||
// randomized will pick number of bytes randomized so we can
|
// randomized will pick number of bytes randomized so we can
|
||||||
// just use part of the generated duid and substitude a few bytes
|
// just use part of the generated duid and substitute a few bytes
|
||||||
/// in template.
|
/// in template.
|
||||||
uint8_t randomized = 0;
|
uint8_t randomized = 0;
|
||||||
std::vector<uint8_t> duid = generateDuid(randomized);
|
std::vector<uint8_t> duid = generateDuid(randomized);
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
|
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -124,7 +124,7 @@ public:
|
|||||||
typedef StatsMgr<dhcp::Pkt4> StatsMgr4;
|
typedef StatsMgr<dhcp::Pkt4> StatsMgr4;
|
||||||
/// Pointer to Statistics Manager for DHCPv4;
|
/// Pointer to Statistics Manager for DHCPv4;
|
||||||
typedef boost::shared_ptr<StatsMgr4> StatsMgr4Ptr;
|
typedef boost::shared_ptr<StatsMgr4> StatsMgr4Ptr;
|
||||||
/// Statictics Manager for DHCPv6.
|
/// Statistics Manager for DHCPv6.
|
||||||
typedef StatsMgr<dhcp::Pkt6> StatsMgr6;
|
typedef StatsMgr<dhcp::Pkt6> StatsMgr6;
|
||||||
/// Pointer to Statistics Manager for DHCPv6.
|
/// Pointer to Statistics Manager for DHCPv6.
|
||||||
typedef boost::shared_ptr<StatsMgr6> StatsMgr6Ptr;
|
typedef boost::shared_ptr<StatsMgr6> StatsMgr6Ptr;
|
||||||
@@ -246,7 +246,7 @@ public:
|
|||||||
/// throw exception.
|
/// throw exception.
|
||||||
///
|
///
|
||||||
/// \throw isc::InvalidOperation if command line options are not parsed.
|
/// \throw isc::InvalidOperation if command line options are not parsed.
|
||||||
/// \throw isc::Unexpected if internal Test Controller error occured.
|
/// \throw isc::Unexpected if internal Test Controller error occurred.
|
||||||
/// \return error_code, 3 if number of received packets is not equal
|
/// \return error_code, 3 if number of received packets is not equal
|
||||||
/// to number of sent packets, 0 if everything is ok.
|
/// to number of sent packets, 0 if everything is ok.
|
||||||
int run();
|
int run();
|
||||||
@@ -306,13 +306,21 @@ protected:
|
|||||||
/// has been reached.
|
/// has been reached.
|
||||||
void cleanCachedPackets();
|
void cleanCachedPackets();
|
||||||
|
|
||||||
|
/// \brief Creates DHCPREQUEST from a DHCPACK message.
|
||||||
|
///
|
||||||
|
/// \param ack An instance of the DHCPACK message to be used to
|
||||||
|
/// create a new message.
|
||||||
|
///
|
||||||
|
/// \return Pointer to the created message.
|
||||||
|
dhcp::Pkt4Ptr createRequestFromAck(const dhcp::Pkt4Ptr& ack);
|
||||||
|
|
||||||
/// \brief Creates DHCPv6 message from the Reply packet.
|
/// \brief Creates DHCPv6 message from the Reply packet.
|
||||||
///
|
///
|
||||||
/// This function creates DHCPv6 Renew or Release message using the
|
/// This function creates DHCPv6 Renew or Release message using the
|
||||||
/// data from the Reply message by copying options from the Reply
|
/// data from the Reply message by copying options from the Reply
|
||||||
/// message.
|
/// message.
|
||||||
///
|
///
|
||||||
/// \param msg_type A type of the message to be createad.
|
/// \param msg_type A type of the message to be created.
|
||||||
/// \param reply An instance of the Reply packet which contents should
|
/// \param reply An instance of the Reply packet which contents should
|
||||||
/// be used to create an instance of the new message.
|
/// be used to create an instance of the new message.
|
||||||
///
|
///
|
||||||
@@ -432,6 +440,16 @@ protected:
|
|||||||
uint16_t type,
|
uint16_t type,
|
||||||
const dhcp::OptionBuffer& buf);
|
const dhcp::OptionBuffer& buf);
|
||||||
|
|
||||||
|
/// \brief Generate DHCPv4 client identifier from HW address.
|
||||||
|
///
|
||||||
|
/// This method generates DHCPv4 client identifier option from a
|
||||||
|
/// HW address.
|
||||||
|
///
|
||||||
|
/// \param hwaddr HW address.
|
||||||
|
///
|
||||||
|
/// \return Pointer to an instance of the generated option.
|
||||||
|
dhcp::OptionPtr generateClientId(const dhcp::HWAddrPtr& hwaddr) const;
|
||||||
|
|
||||||
/// \brief Generate DUID.
|
/// \brief Generate DUID.
|
||||||
///
|
///
|
||||||
/// Method generates unique DUID. The number of DUIDs it can generate
|
/// Method generates unique DUID. The number of DUIDs it can generate
|
||||||
@@ -527,7 +545,7 @@ protected:
|
|||||||
/// \throw isc::InvalidOperation if broadcast option can't be
|
/// \throw isc::InvalidOperation if broadcast option can't be
|
||||||
/// set for the v4 socket or if multicast option can't be set
|
/// set for the v4 socket or if multicast option can't be set
|
||||||
/// for the v6 socket.
|
/// for the v6 socket.
|
||||||
/// \throw isc::Unexpected if interal unexpected error occured.
|
/// \throw isc::Unexpected if internal unexpected error occurred.
|
||||||
/// \return socket descriptor.
|
/// \return socket descriptor.
|
||||||
int openSocket() const;
|
int openSocket() const;
|
||||||
|
|
||||||
@@ -562,7 +580,7 @@ protected:
|
|||||||
/// \param [in] socket socket to be used.
|
/// \param [in] socket socket to be used.
|
||||||
/// \param [in] pkt4 object representing DHCPv4 packet received.
|
/// \param [in] pkt4 object representing DHCPv4 packet received.
|
||||||
/// \throw isc::BadValue if unknown message type received.
|
/// \throw isc::BadValue if unknown message type received.
|
||||||
/// \throw isc::Unexpected if unexpected error occured.
|
/// \throw isc::Unexpected if unexpected error occurred.
|
||||||
void processReceivedPacket4(const TestControlSocket& socket,
|
void processReceivedPacket4(const TestControlSocket& socket,
|
||||||
const dhcp::Pkt4Ptr& pkt4);
|
const dhcp::Pkt4Ptr& pkt4);
|
||||||
|
|
||||||
@@ -579,7 +597,7 @@ protected:
|
|||||||
/// \param [in] socket socket to be used.
|
/// \param [in] socket socket to be used.
|
||||||
/// \param [in] pkt6 object representing DHCPv6 packet received.
|
/// \param [in] pkt6 object representing DHCPv6 packet received.
|
||||||
/// \throw isc::BadValue if unknown message type received.
|
/// \throw isc::BadValue if unknown message type received.
|
||||||
/// \throw isc::Unexpected if unexpected error occured.
|
/// \throw isc::Unexpected if unexpected error occurred.
|
||||||
void processReceivedPacket6(const TestControlSocket& socket,
|
void processReceivedPacket6(const TestControlSocket& socket,
|
||||||
const dhcp::Pkt6Ptr& pkt6);
|
const dhcp::Pkt6Ptr& pkt6);
|
||||||
|
|
||||||
@@ -595,7 +613,7 @@ protected:
|
|||||||
///
|
///
|
||||||
/// \param socket socket to be used.
|
/// \param socket socket to be used.
|
||||||
/// \throw isc::BadValue if unknown message type received.
|
/// \throw isc::BadValue if unknown message type received.
|
||||||
/// \throw isc::Unexpected if unexpected error occured.
|
/// \throw isc::Unexpected if unexpected error occurred.
|
||||||
/// \return number of received packets.
|
/// \return number of received packets.
|
||||||
uint64_t receivePackets(const TestControlSocket& socket);
|
uint64_t receivePackets(const TestControlSocket& socket);
|
||||||
|
|
||||||
@@ -726,6 +744,15 @@ protected:
|
|||||||
const uint64_t packets_num,
|
const uint64_t packets_num,
|
||||||
const bool preload = false);
|
const bool preload = false);
|
||||||
|
|
||||||
|
/// \brief Send number of DHCPREQUEST (renew) messages to a server.
|
||||||
|
///
|
||||||
|
/// \param socket An object representing socket to be used to send packets.
|
||||||
|
/// \param msg_num A number of messages to be sent.
|
||||||
|
///
|
||||||
|
/// \return A number of messages actually sent.
|
||||||
|
uint64_t sendMultipleRequests(const TestControlSocket& socket,
|
||||||
|
const uint64_t msg_num);
|
||||||
|
|
||||||
/// \brief Send number of DHCPv6 Renew or Release messages to the server.
|
/// \brief Send number of DHCPv6 Renew or Release messages to the server.
|
||||||
///
|
///
|
||||||
/// \param socket An object representing socket to be used to send packets.
|
/// \param socket An object representing socket to be used to send packets.
|
||||||
@@ -738,6 +765,14 @@ protected:
|
|||||||
const uint32_t msg_type,
|
const uint32_t msg_type,
|
||||||
const uint64_t msg_num);
|
const uint64_t msg_num);
|
||||||
|
|
||||||
|
/// \brief Send DHCPv4 renew (DHCPREQUEST) using specified socket.
|
||||||
|
///
|
||||||
|
/// \param socket An object encapsulating socket to be used to send
|
||||||
|
/// a packet.
|
||||||
|
///
|
||||||
|
/// \return true if the message has been sent, false otherwise.
|
||||||
|
bool sendRequestFromAck(const TestControlSocket& socket);
|
||||||
|
|
||||||
/// \brief Send DHCPv6 Renew or Release message using specified socket.
|
/// \brief Send DHCPv6 Renew or Release message using specified socket.
|
||||||
///
|
///
|
||||||
/// This method will select an existing lease from the Reply packet cache
|
/// This method will select an existing lease from the Reply packet cache
|
||||||
@@ -763,7 +798,7 @@ protected:
|
|||||||
/// \param discover_pkt4 DISCOVER packet sent.
|
/// \param discover_pkt4 DISCOVER packet sent.
|
||||||
/// \param offer_pkt4 OFFER packet object.
|
/// \param offer_pkt4 OFFER packet object.
|
||||||
///
|
///
|
||||||
/// \throw isc::Unexpected if unexpected error occured.
|
/// \throw isc::Unexpected if unexpected error occurred.
|
||||||
/// \throw isc::InvalidOperation if Statistics Manager has not been
|
/// \throw isc::InvalidOperation if Statistics Manager has not been
|
||||||
/// initialized.
|
/// initialized.
|
||||||
/// \throw isc::dhcp::SocketWriteError if failed to send the packet.
|
/// \throw isc::dhcp::SocketWriteError if failed to send the packet.
|
||||||
@@ -800,7 +835,7 @@ protected:
|
|||||||
///
|
///
|
||||||
/// \param socket socket to be used to send message.
|
/// \param socket socket to be used to send message.
|
||||||
/// \param advertise_pkt6 ADVERTISE packet object.
|
/// \param advertise_pkt6 ADVERTISE packet object.
|
||||||
/// \throw isc::Unexpected if unexpected error occured.
|
/// \throw isc::Unexpected if unexpected error occurred.
|
||||||
/// \throw isc::InvalidOperation if Statistics Manager has not been
|
/// \throw isc::InvalidOperation if Statistics Manager has not been
|
||||||
/// initialized.
|
/// initialized.
|
||||||
///
|
///
|
||||||
@@ -971,7 +1006,7 @@ protected:
|
|||||||
/// \brief Return transaction id offset in a packet.
|
/// \brief Return transaction id offset in a packet.
|
||||||
///
|
///
|
||||||
/// \param arg_idx command line argument index to be used.
|
/// \param arg_idx command line argument index to be used.
|
||||||
/// If multiple -X parameters specifed it points to the
|
/// If multiple -X parameters specified it points to the
|
||||||
/// one to be used.
|
/// one to be used.
|
||||||
/// \return transaction id offset in packet.
|
/// \return transaction id offset in packet.
|
||||||
int getTransactionIdOffset(const int arg_idx) const;
|
int getTransactionIdOffset(const int arg_idx) const;
|
||||||
@@ -1077,6 +1112,7 @@ protected:
|
|||||||
StatsMgr4Ptr stats_mgr4_; ///< Statistics Manager 4.
|
StatsMgr4Ptr stats_mgr4_; ///< Statistics Manager 4.
|
||||||
StatsMgr6Ptr stats_mgr6_; ///< Statistics Manager 6.
|
StatsMgr6Ptr stats_mgr6_; ///< Statistics Manager 6.
|
||||||
|
|
||||||
|
PacketStorage<dhcp::Pkt4> ack_storage_; ///< A storage for DHCPACK messages.
|
||||||
PacketStorage<dhcp::Pkt6> reply_storage_; ///< A storage for reply messages.
|
PacketStorage<dhcp::Pkt6> reply_storage_; ///< A storage for reply messages.
|
||||||
|
|
||||||
NumberGeneratorPtr transid_gen_; ///< Transaction id generator.
|
NumberGeneratorPtr transid_gen_; ///< Transaction id generator.
|
||||||
@@ -1089,7 +1125,7 @@ protected:
|
|||||||
TemplateBufferCollection template_buffers_;
|
TemplateBufferCollection template_buffers_;
|
||||||
|
|
||||||
/// First packets send. They are used at the end of the test
|
/// First packets send. They are used at the end of the test
|
||||||
/// to print packet templates when diagnostics flag T is specifed.
|
/// to print packet templates when diagnostics flag T is specified.
|
||||||
std::map<uint8_t, dhcp::Pkt4Ptr> template_packets_v4_;
|
std::map<uint8_t, dhcp::Pkt4Ptr> template_packets_v4_;
|
||||||
std::map<uint8_t, dhcp::Pkt6Ptr> template_packets_v6_;
|
std::map<uint8_t, dhcp::Pkt6Ptr> template_packets_v6_;
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
|
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -341,6 +341,9 @@ TEST_F(CommandOptionsTest, RenewRate) {
|
|||||||
// that order doesn't matter.
|
// that order doesn't matter.
|
||||||
EXPECT_NO_THROW(process("perfdhcp -6 -f 5 -r 10 -l ethx all"));
|
EXPECT_NO_THROW(process("perfdhcp -6 -f 5 -r 10 -l ethx all"));
|
||||||
EXPECT_EQ(5, opt.getRenewRate());
|
EXPECT_EQ(5, opt.getRenewRate());
|
||||||
|
// Renew rate should also be accepted for DHCPv4 case.
|
||||||
|
EXPECT_NO_THROW(process("perfdhcp -4 -f 5 -r 10 -l ethx all"));
|
||||||
|
EXPECT_EQ(5, opt.getRenewRate());
|
||||||
// The renew rate should not be greater than the rate.
|
// The renew rate should not be greater than the rate.
|
||||||
EXPECT_THROW(process("perfdhcp -6 -r 10 -f 11 -l ethx all"),
|
EXPECT_THROW(process("perfdhcp -6 -r 10 -f 11 -l ethx all"),
|
||||||
isc::InvalidParameter);
|
isc::InvalidParameter);
|
||||||
@@ -354,10 +357,6 @@ TEST_F(CommandOptionsTest, RenewRate) {
|
|||||||
// be accepted.
|
// be accepted.
|
||||||
EXPECT_THROW(process("perfdhcp -6 -f 10 -l ethx all"),
|
EXPECT_THROW(process("perfdhcp -6 -f 10 -l ethx all"),
|
||||||
isc::InvalidParameter);
|
isc::InvalidParameter);
|
||||||
// Currently the -f<renew-rate> can be specified for IPv6 mode
|
|
||||||
// only.
|
|
||||||
EXPECT_THROW(process("perfdhcp -4 -r 10 -f 10 -l ethx all"),
|
|
||||||
isc::InvalidParameter);
|
|
||||||
// Renew rate should be specified.
|
// Renew rate should be specified.
|
||||||
EXPECT_THROW(process("perfdhcp -6 -r 10 -f -l ethx all"),
|
EXPECT_THROW(process("perfdhcp -6 -r 10 -f -l ethx all"),
|
||||||
isc::InvalidParameter);
|
isc::InvalidParameter);
|
||||||
@@ -384,7 +383,7 @@ TEST_F(CommandOptionsTest, ReleaseRate) {
|
|||||||
// The release-rate of 0 is invalid.
|
// The release-rate of 0 is invalid.
|
||||||
EXPECT_THROW(process("perfdhcp -6 -r 10 -F 0 -l ethx all"),
|
EXPECT_THROW(process("perfdhcp -6 -r 10 -F 0 -l ethx all"),
|
||||||
isc::InvalidParameter);
|
isc::InvalidParameter);
|
||||||
// The negative rlease-rate is invalid.
|
// The negative release-rate is invalid.
|
||||||
EXPECT_THROW(process("perfdhcp -6 -r 10 -F -5 -l ethx all"),
|
EXPECT_THROW(process("perfdhcp -6 -r 10 -F -5 -l ethx all"),
|
||||||
isc::InvalidParameter);
|
isc::InvalidParameter);
|
||||||
// If -r<rate> is not specified the -F<release-rate> should not
|
// If -r<rate> is not specified the -F<release-rate> should not
|
||||||
@@ -634,7 +633,7 @@ TEST_F(CommandOptionsTest, Seed) {
|
|||||||
EXPECT_EQ(0, opt.getSeed());
|
EXPECT_EQ(0, opt.getSeed());
|
||||||
EXPECT_FALSE(opt.isSeeded());
|
EXPECT_FALSE(opt.isSeeded());
|
||||||
|
|
||||||
// Negtaive test cases
|
// Negative test cases
|
||||||
// Seed must be non-negative integer
|
// Seed must be non-negative integer
|
||||||
EXPECT_THROW(process("perfdhcp -6 -P 2 -s -5 -l ethx all"),
|
EXPECT_THROW(process("perfdhcp -6 -P 2 -s -5 -l ethx all"),
|
||||||
isc::InvalidParameter);
|
isc::InvalidParameter);
|
||||||
@@ -768,7 +767,7 @@ TEST_F(CommandOptionsTest, Interface) {
|
|||||||
// at least one interface name on OS where test is run.
|
// at least one interface name on OS where test is run.
|
||||||
// Interface Manager has ability to detect interfaces.
|
// Interface Manager has ability to detect interfaces.
|
||||||
// Although we don't call initIsInterface explicitly
|
// Although we don't call initIsInterface explicitly
|
||||||
// here it is called by CommandOptions object interally
|
// here it is called by CommandOptions object internally
|
||||||
// so this function is covered by the test.
|
// so this function is covered by the test.
|
||||||
dhcp::IfaceMgr& iface_mgr = dhcp::IfaceMgr::instance();
|
dhcp::IfaceMgr& iface_mgr = dhcp::IfaceMgr::instance();
|
||||||
const dhcp::IfaceMgr::IfaceCollection& ifaces = iface_mgr.getIfaces();
|
const dhcp::IfaceMgr::IfaceCollection& ifaces = iface_mgr.getIfaces();
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
|
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
// Packet timestamp is normally updated by interface
|
// Packet timestamp is normally updated by interface
|
||||||
// manager on packets reception or send. Unit tests
|
// manager on packets reception or send. Unit tests
|
||||||
// do not use interface manager so we need to do it
|
// do not use interface manager so we need to do it
|
||||||
// ourselfs.
|
// ourselves.
|
||||||
pkt->updateTimestamp();
|
pkt->updateTimestamp();
|
||||||
return pkt;
|
return pkt;
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ public:
|
|||||||
// Packet timestamp is normally updated by interface
|
// Packet timestamp is normally updated by interface
|
||||||
// manager on packets reception or send. Unit tests
|
// manager on packets reception or send. Unit tests
|
||||||
// do not use interface manager so we need to do it
|
// do not use interface manager so we need to do it
|
||||||
// ourselfs.
|
// ourselves.
|
||||||
pkt->updateTimestamp();
|
pkt->updateTimestamp();
|
||||||
return pkt;
|
return pkt;
|
||||||
}
|
}
|
||||||
@@ -238,7 +238,7 @@ TEST_F(StatsMgrTest, MultipleExchanges) {
|
|||||||
passMultiplePackets6(stats_mgr, StatsMgr6::XCHG_RR, DHCPV6_REQUEST,
|
passMultiplePackets6(stats_mgr, StatsMgr6::XCHG_RR, DHCPV6_REQUEST,
|
||||||
request_packets_num);
|
request_packets_num);
|
||||||
|
|
||||||
// Check if all packets are successfuly passed to packet lists.
|
// Check if all packets are successfully passed to packet lists.
|
||||||
EXPECT_EQ(solicit_packets_num,
|
EXPECT_EQ(solicit_packets_num,
|
||||||
stats_mgr->getSentPacketsNum(StatsMgr6::XCHG_SA));
|
stats_mgr->getSentPacketsNum(StatsMgr6::XCHG_SA));
|
||||||
EXPECT_EQ(request_packets_num,
|
EXPECT_EQ(request_packets_num,
|
||||||
@@ -265,6 +265,9 @@ TEST_F(StatsMgrTest, ExchangeToString) {
|
|||||||
EXPECT_EQ("DISCOVER-OFFER",
|
EXPECT_EQ("DISCOVER-OFFER",
|
||||||
StatsMgr4::exchangeToString(StatsMgr4::XCHG_DO));
|
StatsMgr4::exchangeToString(StatsMgr4::XCHG_DO));
|
||||||
EXPECT_EQ("REQUEST-ACK", StatsMgr4::exchangeToString(StatsMgr4::XCHG_RA));
|
EXPECT_EQ("REQUEST-ACK", StatsMgr4::exchangeToString(StatsMgr4::XCHG_RA));
|
||||||
|
EXPECT_EQ("REQUEST-ACK (renewal)",
|
||||||
|
StatsMgr4::exchangeToString(StatsMgr4::XCHG_RNA));
|
||||||
|
|
||||||
|
|
||||||
// Test DHCPv6 specific exchange names.
|
// Test DHCPv6 specific exchange names.
|
||||||
EXPECT_EQ("SOLICIT-ADVERTISE",
|
EXPECT_EQ("SOLICIT-ADVERTISE",
|
||||||
@@ -375,7 +378,7 @@ TEST_F(StatsMgrTest, Delays) {
|
|||||||
std::numeric_limits<double>::max());
|
std::numeric_limits<double>::max());
|
||||||
EXPECT_GT(stats_mgr->getMinDelay(StatsMgr4::XCHG_DO), 1);
|
EXPECT_GT(stats_mgr->getMinDelay(StatsMgr4::XCHG_DO), 1);
|
||||||
|
|
||||||
// Max delay is supposed to the same value as mininimum
|
// Max delay is supposed to the same value as minimum
|
||||||
// or maximum delay.
|
// or maximum delay.
|
||||||
EXPECT_GT(stats_mgr->getMaxDelay(StatsMgr4::XCHG_DO), 1);
|
EXPECT_GT(stats_mgr->getMaxDelay(StatsMgr4::XCHG_DO), 1);
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
|
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -69,7 +69,7 @@ public:
|
|||||||
uint32_t transid_; ///< Last generated transaction id.
|
uint32_t transid_; ///< Last generated transaction id.
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Sets the due times for sedning Solicit, Renew and Release.
|
/// \brief Sets the due times for sending Solicit, Renew and Release.
|
||||||
///
|
///
|
||||||
/// There are three class members that hold the due time for sending DHCP
|
/// There are three class members that hold the due time for sending DHCP
|
||||||
/// messages:
|
/// messages:
|
||||||
@@ -95,12 +95,14 @@ public:
|
|||||||
|
|
||||||
using TestControl::checkExitConditions;
|
using TestControl::checkExitConditions;
|
||||||
using TestControl::createMessageFromReply;
|
using TestControl::createMessageFromReply;
|
||||||
|
using TestControl::createRequestFromAck;
|
||||||
using TestControl::factoryElapsedTime6;
|
using TestControl::factoryElapsedTime6;
|
||||||
using TestControl::factoryGeneric;
|
using TestControl::factoryGeneric;
|
||||||
using TestControl::factoryIana6;
|
using TestControl::factoryIana6;
|
||||||
using TestControl::factoryOptionRequestOption6;
|
using TestControl::factoryOptionRequestOption6;
|
||||||
using TestControl::factoryRapidCommit6;
|
using TestControl::factoryRapidCommit6;
|
||||||
using TestControl::factoryRequestList4;
|
using TestControl::factoryRequestList4;
|
||||||
|
using TestControl::generateClientId;
|
||||||
using TestControl::generateDuid;
|
using TestControl::generateDuid;
|
||||||
using TestControl::generateMacAddress;
|
using TestControl::generateMacAddress;
|
||||||
using TestControl::getCurrentTimeout;
|
using TestControl::getCurrentTimeout;
|
||||||
@@ -114,6 +116,7 @@ public:
|
|||||||
using TestControl::reset;
|
using TestControl::reset;
|
||||||
using TestControl::sendDiscover4;
|
using TestControl::sendDiscover4;
|
||||||
using TestControl::sendPackets;
|
using TestControl::sendPackets;
|
||||||
|
using TestControl::sendMultipleRequests;
|
||||||
using TestControl::sendMultipleMessages6;
|
using TestControl::sendMultipleMessages6;
|
||||||
using TestControl::sendRequest6;
|
using TestControl::sendRequest6;
|
||||||
using TestControl::sendSolicit6;
|
using TestControl::sendSolicit6;
|
||||||
@@ -265,7 +268,7 @@ public:
|
|||||||
/// \param requested_options reference buffer with options.
|
/// \param requested_options reference buffer with options.
|
||||||
/// \param buf test buffer with options that will be matched.
|
/// \param buf test buffer with options that will be matched.
|
||||||
/// \return number of options from the buffer matched with options in
|
/// \return number of options from the buffer matched with options in
|
||||||
/// the reference buffer or -1 if error occured.
|
/// the reference buffer or -1 if error occurred.
|
||||||
int matchRequestedOptions6(const dhcp::OptionBuffer& requested_options,
|
int matchRequestedOptions6(const dhcp::OptionBuffer& requested_options,
|
||||||
const dhcp::OptionBuffer& buf) const {
|
const dhcp::OptionBuffer& buf) const {
|
||||||
// Sanity check.
|
// Sanity check.
|
||||||
@@ -316,7 +319,7 @@ public:
|
|||||||
return (cnt);
|
return (cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Test generation of mulitple DUIDs
|
/// \brief Test generation of multiple DUIDs
|
||||||
///
|
///
|
||||||
/// This method checks the generation of multiple DUIDs. Number
|
/// This method checks the generation of multiple DUIDs. Number
|
||||||
/// of iterations depends on the number of simulated clients.
|
/// of iterations depends on the number of simulated clients.
|
||||||
@@ -403,7 +406,7 @@ public:
|
|||||||
// if randomization algorithm generates the same values but
|
// if randomization algorithm generates the same values but
|
||||||
// this would be an error in randomization algorithm.
|
// this would be an error in randomization algorithm.
|
||||||
total_dist += mismatch_dist;
|
total_dist += mismatch_dist;
|
||||||
// Mismatch may have occured on the DUID octet position
|
// Mismatch may have occurred on the DUID octet position
|
||||||
// up to calculated earlier unequal_pos.
|
// up to calculated earlier unequal_pos.
|
||||||
ASSERT_LE(mismatch_dist, unequal_pos);
|
ASSERT_LE(mismatch_dist, unequal_pos);
|
||||||
// unique will inform if tested DUID is unique.
|
// unique will inform if tested DUID is unique.
|
||||||
@@ -433,7 +436,7 @@ public:
|
|||||||
// Remember generated DUID.
|
// Remember generated DUID.
|
||||||
duids.push_back(new_duid);
|
duids.push_back(new_duid);
|
||||||
}
|
}
|
||||||
// If we have more than one client at least one mismatch occured.
|
// If we have more than one client at least one mismatch occurred.
|
||||||
if (clients_num < 2) {
|
if (clients_num < 2) {
|
||||||
EXPECT_EQ(0, total_dist);
|
EXPECT_EQ(0, total_dist);
|
||||||
}
|
}
|
||||||
@@ -580,7 +583,7 @@ public:
|
|||||||
int clients_num = CommandOptions::instance().getClientsNum();
|
int clients_num = CommandOptions::instance().getClientsNum();
|
||||||
// The old_mac will be holding the value of previously generated
|
// The old_mac will be holding the value of previously generated
|
||||||
// MAC address. We will be comparing the newly generated one with it
|
// MAC address. We will be comparing the newly generated one with it
|
||||||
// to see if it changes when mulitple clients are simulated or if it
|
// to see if it changes when multiple clients are simulated or if it
|
||||||
// does not change when single client is simulated.
|
// does not change when single client is simulated.
|
||||||
MacAddress old_mac(CommandOptions::instance().getMacTemplate());
|
MacAddress old_mac(CommandOptions::instance().getMacTemplate());
|
||||||
// Holds the position if the octet on which two MAC addresses can
|
// Holds the position if the octet on which two MAC addresses can
|
||||||
@@ -614,7 +617,7 @@ public:
|
|||||||
// the case if randomization algorithm generates the same
|
// the case if randomization algorithm generates the same
|
||||||
// values but this would be an error in randomization algorithm.
|
// values but this would be an error in randomization algorithm.
|
||||||
total_dist += mismatch_dist;
|
total_dist += mismatch_dist;
|
||||||
// Mismatch may have occured on the MAC address'es octet position
|
// Mismatch may have occurred on the MAC address'es octet position
|
||||||
// up to calculated earlier unequal_pos.
|
// up to calculated earlier unequal_pos.
|
||||||
ASSERT_LE(mismatch_dist, unequal_pos);
|
ASSERT_LE(mismatch_dist, unequal_pos);
|
||||||
// unique will inform if tested DUID is unique.
|
// unique will inform if tested DUID is unique.
|
||||||
@@ -650,7 +653,143 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Test that the DHCPv4 Release or Renew message is created
|
/// \brief Test sending DHCPv4 renews.
|
||||||
|
///
|
||||||
|
/// This function simulates acquiring 10 leases from the server. Returned
|
||||||
|
/// DHCPACK messages are cached and used to send renew messages.
|
||||||
|
/// The maximal number of messages which can be sent is equal to the
|
||||||
|
/// number of leases acquired (10). This function also checks that an
|
||||||
|
/// attempt to send more renew messages than the number of leases acquired
|
||||||
|
/// will fail.
|
||||||
|
void testSendRenew4() {
|
||||||
|
std::string loopback_iface(getLocalLoopback());
|
||||||
|
if (loopback_iface.empty()) {
|
||||||
|
std::cout << "Skipping the test because loopback interface could"
|
||||||
|
" not be detected" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Build a command line. Depending on the message type, we will use
|
||||||
|
// -f<renew-rate> or -F<release-rate> parameter.
|
||||||
|
std::ostringstream s;
|
||||||
|
s << "perfdhcp -4 -l " << loopback_iface << " -r 10 -f";
|
||||||
|
s << " 10 -R 10 -L 10067 -n 10 127.0.0.1";
|
||||||
|
ASSERT_NO_THROW(processCmdLine(s.str()));
|
||||||
|
// Create a test controller class.
|
||||||
|
NakedTestControl tc;
|
||||||
|
tc.initializeStatsMgr();
|
||||||
|
// Set the transaction id generator to sequential to control to
|
||||||
|
// guarantee that transaction ids are predictable.
|
||||||
|
boost::shared_ptr<NakedTestControl::IncrementalGenerator>
|
||||||
|
generator(new NakedTestControl::IncrementalGenerator());
|
||||||
|
tc.setTransidGenerator(generator);
|
||||||
|
// Socket has to be created so as we can actually send packets.
|
||||||
|
int sock_handle = 0;
|
||||||
|
ASSERT_NO_THROW(sock_handle = tc.openSocket());
|
||||||
|
TestControl::TestControlSocket sock(sock_handle);
|
||||||
|
|
||||||
|
// Send a number of DHCPDISCOVER messages. Each generated message will
|
||||||
|
// be assigned a different transaction id, starting from 1 to 10.
|
||||||
|
tc.sendPackets(sock, 10);
|
||||||
|
|
||||||
|
// Simulate DHCPOFFER responses from the server. Each DHCPOFFER is
|
||||||
|
// assigned a transaction id from the range of 1 to 10, so as they
|
||||||
|
// match the transaction ids from the DHCPDISCOVER messages.
|
||||||
|
for (unsigned i = generator->getNext() - 10;
|
||||||
|
i < generator->getNext(); ++i) {
|
||||||
|
Pkt4Ptr offer(createOfferPkt4(i));
|
||||||
|
// If DHCPOFFER is matched with the DHCPDISCOVER the call below
|
||||||
|
// will trigger a corresponding DHCPREQUEST. They will be assigned
|
||||||
|
// transaction ids from the range from 11 to 20 (the range of
|
||||||
|
// 1 to 10 has been used by DHCPDISCOVER-DHCPOFFER).
|
||||||
|
ASSERT_NO_THROW(tc.processReceivedPacket4(sock, offer));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Requests have been sent, so now let's simulate responses from the
|
||||||
|
// server. Generate corresponding DHCPACK messages with the transaction
|
||||||
|
// ids from the range from 11 to 20.
|
||||||
|
for (unsigned i = generator->getNext() - 10;
|
||||||
|
i < generator->getNext(); ++i) {
|
||||||
|
Pkt4Ptr ack(createAckPkt4(i));
|
||||||
|
// Each DHCPACK packet corresponds to the new lease acquired. Since
|
||||||
|
// -f<renew-rate> option has been specified, received Reply
|
||||||
|
// messages are held so as renew messages can be sent for
|
||||||
|
// existing leases.
|
||||||
|
ASSERT_NO_THROW(tc.processReceivedPacket4(sock, ack));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t msg_num;
|
||||||
|
// Try to send 5 messages. It should be successful because 10
|
||||||
|
// DHCPREQUEST messages has been received. For each of them we
|
||||||
|
// should be able to send renewal.
|
||||||
|
ASSERT_NO_THROW(
|
||||||
|
msg_num = tc.sendMultipleRequests(sock, 5)
|
||||||
|
);
|
||||||
|
// Make sure that we have sent 5 messages.
|
||||||
|
EXPECT_EQ(5, msg_num);
|
||||||
|
|
||||||
|
// Try to do it again. We should still have 5 Reply packets for
|
||||||
|
// which renews haven't been sent yet.
|
||||||
|
ASSERT_NO_THROW(
|
||||||
|
msg_num = tc.sendMultipleRequests(sock, 5)
|
||||||
|
);
|
||||||
|
EXPECT_EQ(5, msg_num);
|
||||||
|
|
||||||
|
// We used all the DHCPACK packets (we sent renew or release for each of
|
||||||
|
// them already). Therefore, no further renew messages should be sent
|
||||||
|
// before we acquire new leases.
|
||||||
|
ASSERT_NO_THROW(
|
||||||
|
msg_num = tc.sendMultipleRequests(sock, 5)
|
||||||
|
);
|
||||||
|
// Make sure that no message has been sent.
|
||||||
|
EXPECT_EQ(0, msg_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Test that the DHCPREQUEST message is created correctly and
|
||||||
|
/// comprises expected values.
|
||||||
|
void testCreateRequest() {
|
||||||
|
// This command line specifies that the Release/Renew messages should
|
||||||
|
// be sent with the same rate as the Solicit messages.
|
||||||
|
std::ostringstream s;
|
||||||
|
s << "perfdhcp -4 -l lo -r 10 -f 10";
|
||||||
|
s << " -R 10 -L 10067 -n 10 127.0.0.1";
|
||||||
|
ASSERT_NO_THROW(processCmdLine(s.str()));
|
||||||
|
// Create a test controller class.
|
||||||
|
NakedTestControl tc;
|
||||||
|
// Set the transaction id generator which will be used by the
|
||||||
|
// createRenew or createRelease function to generate transaction id.
|
||||||
|
boost::shared_ptr<NakedTestControl::IncrementalGenerator>
|
||||||
|
generator(new NakedTestControl::IncrementalGenerator());
|
||||||
|
tc.setTransidGenerator(generator);
|
||||||
|
|
||||||
|
Pkt4Ptr ack = createAckPkt4(1);
|
||||||
|
|
||||||
|
// Create DHCPREQUST from DHCPACK.
|
||||||
|
Pkt4Ptr request;
|
||||||
|
ASSERT_NO_THROW(request = tc.createRequestFromAck(ack));
|
||||||
|
|
||||||
|
// Make sure that the DHCPACK has been successfully created and that
|
||||||
|
// it holds expected data.
|
||||||
|
ASSERT_TRUE(request);
|
||||||
|
EXPECT_EQ("127.0.0.1", request->getCiaddr().toText());
|
||||||
|
|
||||||
|
// HW address.
|
||||||
|
HWAddrPtr hwaddr_ack = ack->getHWAddr();
|
||||||
|
ASSERT_TRUE(hwaddr_ack);
|
||||||
|
HWAddrPtr hwaddr_req = request->getHWAddr();
|
||||||
|
ASSERT_TRUE(hwaddr_req);
|
||||||
|
EXPECT_TRUE(hwaddr_ack->hwaddr_ == hwaddr_req->hwaddr_);
|
||||||
|
|
||||||
|
// Creating message from null DHCPACK should fail.
|
||||||
|
EXPECT_THROW(tc.createRequestFromAck(Pkt4Ptr()), isc::BadValue);
|
||||||
|
|
||||||
|
// Creating message from DHCPACK holding zero yiaddr should fail.
|
||||||
|
asiolink::IOAddress yiaddr = ack->getYiaddr();
|
||||||
|
ack->setYiaddr(asiolink::IOAddress::IPV4_ZERO_ADDRESS());
|
||||||
|
EXPECT_THROW(tc.createRequestFromAck(ack), isc::BadValue);
|
||||||
|
ack->setYiaddr(yiaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Test that the DHCPv6 Release or Renew message is created
|
||||||
/// correctly and comprises expected options.
|
/// correctly and comprises expected options.
|
||||||
///
|
///
|
||||||
/// \param msg_type A type of the message to be tested: DHCPV6_RELEASE
|
/// \param msg_type A type of the message to be tested: DHCPV6_RELEASE
|
||||||
@@ -721,7 +860,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// This function simulates acquiring 10 leases from the server. Returned
|
/// This function simulates acquiring 10 leases from the server. Returned
|
||||||
/// Reply messages are cached and used to send Renew or Release messages.
|
/// Reply messages are cached and used to send Renew or Release messages.
|
||||||
/// The maxmimal number of Renew or Release messages which can be sent is
|
/// The maximal number of Renew or Release messages which can be sent is
|
||||||
/// equal to the number of leases acquired (10). This function also checks
|
/// equal to the number of leases acquired (10). This function also checks
|
||||||
/// that an attempt to send more Renew or Release messages than the number
|
/// that an attempt to send more Renew or Release messages than the number
|
||||||
/// of leases acquired will fail.
|
/// of leases acquired will fail.
|
||||||
@@ -816,26 +955,47 @@ public:
|
|||||||
/// \brief Parse command line string with CommandOptions.
|
/// \brief Parse command line string with CommandOptions.
|
||||||
///
|
///
|
||||||
/// \param cmdline command line string to be parsed.
|
/// \param cmdline command line string to be parsed.
|
||||||
/// \throw isc::Unexpected if unexpected error occured.
|
/// \throw isc::Unexpected if unexpected error occurred.
|
||||||
/// \throw isc::InvalidParameter if command line is invalid.
|
/// \throw isc::InvalidParameter if command line is invalid.
|
||||||
void processCmdLine(const std::string& cmdline) const {
|
void processCmdLine(const std::string& cmdline) const {
|
||||||
CommandOptionsHelper::process(cmdline);
|
CommandOptionsHelper::process(cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Create DHCPOFFER or DHCPACK packet.
|
||||||
|
///
|
||||||
|
/// \param pkt_type DHCPOFFER or DHCPACK.
|
||||||
|
/// \param transid Transaction id.
|
||||||
|
///
|
||||||
|
/// \return Instance of the packet.
|
||||||
|
Pkt4Ptr
|
||||||
|
createResponsePkt4(const uint8_t pkt_type,
|
||||||
|
const uint32_t transid) const {
|
||||||
|
Pkt4Ptr pkt(new Pkt4(pkt_type, transid));
|
||||||
|
OptionPtr opt_serverid = Option::factory(Option::V4,
|
||||||
|
DHO_DHCP_SERVER_IDENTIFIER,
|
||||||
|
OptionBuffer(4, 1));
|
||||||
|
pkt->setYiaddr(asiolink::IOAddress("127.0.0.1"));
|
||||||
|
pkt->addOption(opt_serverid);
|
||||||
|
pkt->updateTimestamp();
|
||||||
|
return (pkt);
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Create DHCPv4 OFFER packet.
|
/// \brief Create DHCPv4 OFFER packet.
|
||||||
///
|
///
|
||||||
/// \param transid transaction id.
|
/// \param transid transaction id.
|
||||||
/// \return instance of the packet.
|
/// \return instance of the packet.
|
||||||
boost::shared_ptr<Pkt4>
|
Pkt4Ptr
|
||||||
createOfferPkt4(uint32_t transid) const {
|
createOfferPkt4(uint32_t transid) const {
|
||||||
boost::shared_ptr<Pkt4> offer(new Pkt4(DHCPOFFER, transid));
|
return (createResponsePkt4(DHCPOFFER, transid));
|
||||||
OptionPtr opt_serverid = Option::factory(Option::V4,
|
}
|
||||||
DHO_DHCP_SERVER_IDENTIFIER,
|
|
||||||
OptionBuffer(4, 1));
|
/// \brief Create DHCPACK packet.
|
||||||
offer->setYiaddr(asiolink::IOAddress("127.0.0.1"));
|
///
|
||||||
offer->addOption(opt_serverid);
|
/// \param transid transaction id.
|
||||||
offer->updateTimestamp();
|
/// \return instance of the packet.
|
||||||
return (offer);
|
Pkt4Ptr
|
||||||
|
createAckPkt4(const uint32_t transid) const {
|
||||||
|
return (createResponsePkt4(DHCPACK, transid));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Create DHCPv6 ADVERTISE packet.
|
/// \brief Create DHCPv6 ADVERTISE packet.
|
||||||
@@ -916,6 +1076,34 @@ TEST_F(TestControlTest, reset) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test verifies that the client id is generated from the HW address.
|
||||||
|
TEST_F(TestControlTest, generateClientId) {
|
||||||
|
// Generate HW address.
|
||||||
|
std::vector<uint8_t> hwaddr;
|
||||||
|
for (unsigned int i = 0; i < 6; ++i) {
|
||||||
|
hwaddr.push_back(i);
|
||||||
|
}
|
||||||
|
HWAddrPtr hwaddr_ptr(new HWAddr(hwaddr, 5));
|
||||||
|
|
||||||
|
// Use generated HW address to generate client id.
|
||||||
|
NakedTestControl tc;
|
||||||
|
OptionPtr opt_client_id;
|
||||||
|
ASSERT_NO_THROW(opt_client_id = tc.generateClientId(hwaddr_ptr));
|
||||||
|
ASSERT_TRUE(opt_client_id);
|
||||||
|
|
||||||
|
// Extract the client id data.
|
||||||
|
const OptionBuffer& client_id = opt_client_id->getData();
|
||||||
|
ASSERT_EQ(7, client_id.size());
|
||||||
|
|
||||||
|
// Verify that the client identifier is generated correctly.
|
||||||
|
|
||||||
|
// First byte is the HW type.
|
||||||
|
EXPECT_EQ(5, client_id[0]);
|
||||||
|
// The rest of the client identifier should be equal to the HW address.
|
||||||
|
std::vector<uint8_t> sub(client_id.begin() + 1, client_id.end());
|
||||||
|
EXPECT_TRUE(hwaddr == sub);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(TestControlTest, GenerateDuid) {
|
TEST_F(TestControlTest, GenerateDuid) {
|
||||||
// Simple command line that simulates one client only. Always the
|
// Simple command line that simulates one client only. Always the
|
||||||
// same DUID will be generated.
|
// same DUID will be generated.
|
||||||
@@ -1252,7 +1440,7 @@ TEST_F(TestControlTest, Packet6ExchangeFromTemplate) {
|
|||||||
// then test should be interrupted and actual number of iterations will
|
// then test should be interrupted and actual number of iterations will
|
||||||
// be 6.
|
// be 6.
|
||||||
const int received_num = 3;
|
const int received_num = 3;
|
||||||
// Simulate the number of Solicit-Advertise-Request-Reply (SARR) echanges.
|
// Simulate the number of Solicit-Advertise-Request-Reply (SARR) exchanges.
|
||||||
// The test function generates server's responses and passes it to the
|
// The test function generates server's responses and passes it to the
|
||||||
// TestControl class methods for processing. The number of exchanges
|
// TestControl class methods for processing. The number of exchanges
|
||||||
// actually performed is returned in 'iterations_performed' argument. If
|
// actually performed is returned in 'iterations_performed' argument. If
|
||||||
@@ -1287,14 +1475,14 @@ TEST_F(TestControlTest, Packet6Exchange) {
|
|||||||
// This simulates no packet drops.
|
// This simulates no packet drops.
|
||||||
bool use_templates = false;
|
bool use_templates = false;
|
||||||
|
|
||||||
// Simulate the number of Solicit-Advertise-Request-Reply (SARR) echanges.
|
// Simulate the number of Solicit-Advertise-Request-Reply (SARR) exchanges.
|
||||||
// The test function generates server's responses and passes it to the
|
// The test function generates server's responses and passes it to the
|
||||||
// TestControl class methods for processing. The number of exchanges
|
// TestControl class methods for processing. The number of exchanges
|
||||||
// actually performed is returned in 'iterations_performed' argument. If
|
// actually performed is returned in 'iterations_performed' argument. If
|
||||||
// processing is successful, the number of performed iterations should be
|
// processing is successful, the number of performed iterations should be
|
||||||
// equal to the number of exchanges specified with the '-n' command line
|
// equal to the number of exchanges specified with the '-n' command line
|
||||||
// parameter (10 in this case). All exchanged packets carry the IA_NA option
|
// parameter (10 in this case). All exchanged packets carry the IA_NA option
|
||||||
// to simulate the IPv6 address acqusition and to verify that the IA_NA
|
// to simulate the IPv6 address acquisition and to verify that the IA_NA
|
||||||
// options returned by the server are processed correctly.
|
// options returned by the server are processed correctly.
|
||||||
testPkt6Exchange(iterations_num, iterations_num, use_templates,
|
testPkt6Exchange(iterations_num, iterations_num, use_templates,
|
||||||
iterations_performed);
|
iterations_performed);
|
||||||
@@ -1323,7 +1511,7 @@ TEST_F(TestControlTest, Packet6ExchangePrefixDelegation) {
|
|||||||
// This simulates no packet drops.
|
// This simulates no packet drops.
|
||||||
bool use_templates = false;
|
bool use_templates = false;
|
||||||
|
|
||||||
// Simulate the number of Solicit-Advertise-Request-Reply (SARR) echanges.
|
// Simulate the number of Solicit-Advertise-Request-Reply (SARR) exchanges.
|
||||||
// The test function generates server's responses and passes it to the
|
// The test function generates server's responses and passes it to the
|
||||||
// TestControl class methods for processing. The number of exchanges
|
// TestControl class methods for processing. The number of exchanges
|
||||||
// actually performed is returned in 'iterations_performed' argument. If
|
// actually performed is returned in 'iterations_performed' argument. If
|
||||||
@@ -1358,7 +1546,7 @@ TEST_F(TestControlTest, Packet6ExchangeAddressAndPrefix) {
|
|||||||
// Set number of received packets equal to number of iterations.
|
// Set number of received packets equal to number of iterations.
|
||||||
// This simulates no packet drops.
|
// This simulates no packet drops.
|
||||||
bool use_templates = false;
|
bool use_templates = false;
|
||||||
// Simulate the number of Solicit-Advertise-Request-Reply (SARR) echanges.
|
// Simulate the number of Solicit-Advertise-Request-Reply (SARR) exchanges.
|
||||||
// The test function generates server's responses and passes it to the
|
// The test function generates server's responses and passes it to the
|
||||||
// TestControl class methods for processing. The number of exchanges
|
// TestControl class methods for processing. The number of exchanges
|
||||||
// actually performed is returned in 'iterations_performed' argument. If
|
// actually performed is returned in 'iterations_performed' argument. If
|
||||||
@@ -1432,14 +1620,30 @@ TEST_F(TestControlTest, PacketTemplates) {
|
|||||||
EXPECT_THROW(tc.initPacketTemplates(), isc::BadValue);
|
EXPECT_THROW(tc.initPacketTemplates(), isc::BadValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestControlTest, processRenew) {
|
// This test verifies that DHCPv4 renew (DHCPREQUEST) messages can be
|
||||||
|
// sent for acquired leases.
|
||||||
|
TEST_F(TestControlTest, processRenew4) {
|
||||||
|
testSendRenew4();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test verifies that DHCPv6 Renew messages can be sent for acquired
|
||||||
|
// leases.
|
||||||
|
TEST_F(TestControlTest, processRenew6) {
|
||||||
testSendRenewRelease(DHCPV6_RENEW);
|
testSendRenewRelease(DHCPV6_RENEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestControlTest, processRelease) {
|
// This test verifies that DHCPv6 Release messages can be sent for acquired
|
||||||
|
// leases.
|
||||||
|
TEST_F(TestControlTest, processRelease6) {
|
||||||
testSendRenewRelease(DHCPV6_RELEASE);
|
testSendRenewRelease(DHCPV6_RELEASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test verifies that DHCPREQUEST is created correctly from the
|
||||||
|
// DHCPACK message.
|
||||||
|
TEST_F(TestControlTest, createRequest) {
|
||||||
|
testCreateRequest();
|
||||||
|
}
|
||||||
|
|
||||||
// This test verifies that the DHCPV6 Renew message is created correctly
|
// This test verifies that the DHCPV6 Renew message is created correctly
|
||||||
// and that it comprises all required options.
|
// and that it comprises all required options.
|
||||||
TEST_F(TestControlTest, createRenew) {
|
TEST_F(TestControlTest, createRenew) {
|
||||||
@@ -1485,8 +1689,8 @@ TEST_F(TestControlTest, getCurrentTimeout) {
|
|||||||
// server's responses is valid. In this case, we are simulating that perfdhcp
|
// server's responses is valid. In this case, we are simulating that perfdhcp
|
||||||
// sends Renew requests to the server, apart from the regular 4-way exchanges.
|
// sends Renew requests to the server, apart from the regular 4-way exchanges.
|
||||||
// The timeout value depends on both the due time to send next Solicit and the
|
// The timeout value depends on both the due time to send next Solicit and the
|
||||||
// due time to send Renew - the timeout should be ajusted to the due time that
|
// due time to send Renew - the timeout should be adjusted to the due time
|
||||||
// occurs sooner.
|
// that occurs sooner.
|
||||||
TEST_F(TestControlTest, getCurrentTimeoutRenew) {
|
TEST_F(TestControlTest, getCurrentTimeoutRenew) {
|
||||||
// Set the Solicit rate to 10 and the Renew rate 5.
|
// Set the Solicit rate to 10 and the Renew rate 5.
|
||||||
ASSERT_NO_THROW(processCmdLine("perfdhcp -6 -l lo -r 10 -f 5 ::1"));
|
ASSERT_NO_THROW(processCmdLine("perfdhcp -6 -l lo -r 10 -f 5 ::1"));
|
||||||
|
Reference in New Issue
Block a user