Browse Source

[1959] Set packet v4 defaults correctly

Marcin Siodelski 12 years ago
parent
commit
2e6923cefc
2 changed files with 80 additions and 67 deletions
  1. 37 29
      tests/tools/perfdhcp/test_control.cc
  2. 43 38
      tests/tools/perfdhcp/test_control.h

+ 37 - 29
tests/tools/perfdhcp/test_control.cc

@@ -38,8 +38,9 @@ namespace isc {
 namespace perfdhcp {
 
 TestControl::TestControlSocket::TestControlSocket(int socket) :
-    socket_(socket) {
-    initInterface();
+    socket_(socket),
+    addr_("127.0.0.1") {
+    initSocketData();
 }
 
 TestControl::TestControlSocket::~TestControlSocket() {
@@ -47,7 +48,7 @@ TestControl::TestControlSocket::~TestControlSocket() {
 }
 
 void
-TestControl::TestControlSocket::initInterface() {
+TestControl::TestControlSocket::initSocketData() {
     const IfaceMgr::IfaceCollection& ifaces =
         IfaceMgr::instance().getIfaces();
     for (IfaceMgr::IfaceCollection::const_iterator it = ifaces.begin();
@@ -61,6 +62,7 @@ TestControl::TestControlSocket::initInterface() {
              ++s) {
             if (s->sockfd_ == socket_) {
                 iface_ = it->getName();
+                addr_ = s->addr_;
                 return;
             }
         }
@@ -93,26 +95,6 @@ TestControl::checkExitConditions() const {
     return(false);
 }
 
-boost::shared_ptr<Pkt4>
-TestControl::createDiscoverPkt4(const std::vector<uint8_t>& mac_addr) const {
-    const uint32_t transid = static_cast<uint32_t>(random());
-    boost::shared_ptr<Pkt4> pkt4(new Pkt4(DHCPDISCOVER, transid));
-    if (!pkt4) {
-        isc_throw(isc::Unexpected, "failed to create DISCOVER packet");
-    }
-
-    if (HW_ETHER_LEN != mac_addr.size()) {
-        isc_throw(BadValue, "invalid MAC address size");
-    }
-    pkt4->setHWAddr(HTYPE_ETHER, HW_ETHER_LEN, mac_addr);
-
-    OptionBuffer buf_msg_type;
-    buf_msg_type.push_back(DHCPDISCOVER);
-    pkt4->addOption(Option::factory(Option::V4, DHO_DHCP_MESSAGE_TYPE, buf_msg_type));
-    pkt4->addOption(Option::factory(Option::V4, DHO_DHCP_PARAMETER_REQUEST_LIST));
-    return pkt4;
-}
-
 OptionPtr
 TestControl::factoryGeneric4(Option::Universe u,
                                  uint16_t type,
@@ -149,8 +131,11 @@ TestControl::generateMacAddress() const {
         return options.getMacPrefix();
     }
     std::vector<uint8_t> mac_addr(options.getMacPrefix());
+    if (mac_addr.size() != HW_ETHER_LEN) {
+        isc_throw(BadValue, "invalid MAC address prefix specified");
+    }
     uint32_t r = random();
-    r %= clients_num + 1;
+    r %= clients_num;
     for (std::vector<uint8_t>::iterator it = mac_addr.end() - 1;
          it >= mac_addr.begin();
          --it) {
@@ -333,7 +318,7 @@ TestControl::run() {
         receivePackets();
 
         for (uint64_t i = packets_due; i > 0; --i) {
-            startExchange(socket);
+            sendDiscover4(socket);
             ++packets_sent;
             cout << "Packets sent " << packets_sent << endl;
         }
@@ -341,20 +326,43 @@ TestControl::run() {
 }
 
 void
-TestControl::startExchange(const TestControlSocket& socket) {
+TestControl::sendDiscover4(const TestControlSocket& socket) {
     ++sent_packets_0_;
     last_sent_ = microsec_clock::universal_time();
     std::vector<uint8_t> mac_address = generateMacAddress();
-    boost::shared_ptr<Pkt4> pkt4 = createDiscoverPkt4(mac_address);
-    pkt4->setIface(socket.getIface());
+    const uint32_t transid = static_cast<uint32_t>(random());
+    boost::shared_ptr<Pkt4> pkt4(new Pkt4(DHCPDISCOVER, transid));
+    if (!pkt4) {
+        isc_throw(Unexpected, "failed to create DISCOVER packet");
+    }
+    OptionBuffer buf_msg_type;
+    buf_msg_type.push_back(DHCPDISCOVER);
+    pkt4->addOption(Option::factory(Option::V4, DHO_DHCP_MESSAGE_TYPE,
+                                    buf_msg_type));
+    pkt4->addOption(Option::factory(Option::V4,
+                                    DHO_DHCP_PARAMETER_REQUEST_LIST));
+
+    setDefaults4(socket, pkt4);
     pkt4->pack();
     IfaceMgr::instance().send(pkt4);
 }
 
 void
+TestControl::setDefaults4(const TestControlSocket &socket,
+                          const boost::shared_ptr<Pkt4>& pkt) {
+    CommandOptions& options = CommandOptions::instance();
+    pkt->setIface(socket.getIface());
+    pkt->setLocalPort(DHCP4_CLIENT_PORT);
+    pkt->setRemotePort(DHCP4_SERVER_PORT);
+    pkt->setRemoteAddr(IOAddress(options.getServerName()));
+    pkt->setGiaddr(IOAddress(socket.getAddress()));
+    pkt->setHops(1);
+}
+
+void
 TestControl::updateSendDue() {
     // If default constructor was called, this should not happen but
-    // if somebody has changed default constructor it is better to
+    // if somebody has cw/e August 3, 2012hanged default constructor it is better to
     // keep this check.
     if (last_sent_.is_not_a_date_time()) {
         isc_throw(Unexpected, "time of last sent packet not initialized");

+ 43 - 38
tests/tools/perfdhcp/test_control.h

@@ -67,6 +67,11 @@ public:
         /// \return name of the interface where socket is bound to.
         const std::string& getIface() const { return(iface_); }
 
+        /// \brief Return address where socket is bound to.
+        ///
+        /// \return address where socket is bound to.
+        const asiolink::IOAddress& getAddress() const { return(addr_); }
+
     private:
         /// \brief Private default constructor.
         ///
@@ -74,18 +79,18 @@ public:
         /// socket descriptor is passed to create object.
         TestControlSocket();
 
-        /// \brief Initialize name of the interface.
+        /// \brief Initialize socket data.
         ///
-        /// This method intializes the name of the interface where
-        /// socket is bound to. This name can be later retreived by
-        /// client class to set interface name in DHCP packet objects.
+        /// This method initializes members of the class that Interface
+        /// Manager holds: interface name, local address.
         ///
         /// \throw isc::BadValue if interface for specified socket
         /// descriptor does not exist.
-        void initInterface();
+        void initSocketData();
 
-        int socket_;          ///< Socket descirptor.
-        std::string iface_;   ///< Name of the interface.
+        int socket_;               ///< Socket descirptor.
+        std::string iface_;        ///< Name of the interface.
+        asiolink::IOAddress addr_; ///< Address bound.
     };
 
     /// \brief Length of the Ethernet HW address (MAC) in bytes.
@@ -127,30 +132,6 @@ private:
     /// \return true if any of the exit conditions is fulfiled.
     bool checkExitConditions() const;
 
-    /// \brief Create DHCPv4 DISCOVER packet.
-    ///
-    /// Create instance of DHCPv4 DISCOVER packet with ethernet
-    /// HW type and MAC address specified as parameter. The following
-    /// DHCP options are added to the packet:
-    /// - DHO_DHCP_MESSAGE_TYPE with DHCPDISCOVER message type value
-    /// - DHO_DHCP_PARAMETER_REQUEST_LIST with the following options
-    /// being requested from the server:
-    ///    - DHO_SUBNET_MASK,
-    ///    - DHO_BROADCAST_ADDRESS,
-    ///    - DHO_TIME_OFFSET,
-    ///    - DHO_ROUTERS,
-    ///    - DHO_DOMAIN_NAME,
-    ///    - DHO_DOMAIN_NAME_SERVERS,
-    ///    - DHO_HOST_NAME.
-    ///
-    /// \param mac_addr MAC address to be set for the packet. MAC address
-    /// has to be exactly 6 octets long.
-    /// \throw isc::Unexpected if failed to create new packet instance.
-    /// \throw isc::BadValue if MAC address has invalid length.
-    /// \return insance of the DHCPv4 DISCOVER packet.
-    boost::shared_ptr<dhcp::Pkt4>
-    createDiscoverPkt4(const std::vector<uint8_t>& mac_addr) const;
-
     /// \brief Factory function to create generic option.
     ///
     /// Factory function is registered using \ref LibDHCP::OptionFactoryRegister.
@@ -205,6 +186,8 @@ private:
     /// Based on this the random value is generated and added to
     /// the MAC address prefix (default MAC address).
     ///
+    /// \throw isc::BadValue if MAC address prefix (default or specified
+    /// from the command line) has invalid size (expected 6 octets).
     /// \return generated MAC address.
     std::vector<uint8_t> generateMacAddress() const;
 
@@ -254,16 +237,38 @@ private:
     ///
     /// Method registers option factory functions for DHCPv4 or DHCPv6,
     /// depending in whch mode test is currently running.
-     void registerOptionFactories() const;
+    void registerOptionFactories() const;
+
+    /// \brief Send DHCPv4 DISCOVER message.
+    ///
+    /// Method creates and sends DHCPv4 DISCOVER message to the server
+    /// with the following options:
+    /// - MESSAGE_TYPE set to DHCPDISCOVER
+    /// - PARAMETER_REQUEST_LIST with the same list of requested options
+    /// as described in \ref factoryRequestList.
+    /// The transaction id and MAC address are randomly generated for
+    /// the message. Range of unique MAC addresses generated depends
+    /// on the number of clients specified from the command line.
+    ///
+    /// \param socket socket to be used to send the message.
+    /// \throw isc::Unexpected if failed to create new packet instance.
+    /// \throw isc::BadValue if MAC address has invalid length.
+    void sendDiscover4(const TestControlSocket &socket);
 
-    /// \brief Start new exchange of DHCP messages.
+    /// \brief Set default DHCPv4 packet data.
     ///
-    /// Method starts new DHCP exchange by sending new DHCPv4 DISCOVER
-    /// or DHCPv6 SOLICIT packet to the server.
+    /// This method sets default data on the DHCPv4 packet:
+    /// - interface name,
+    /// - local port = 68 (DHCP client port),
+    /// - remote port = 67 (DHCP server port),
+    /// - server's address,
+    /// - GIADDR = local address where socket is bound to,
+    /// - hops = 1 (pretending that we are a relay)
     ///
-    /// \param socket socket used to send DHCP message.
-    /// \throw isc::Unexpected if failed to create or send packet
-    void startExchange(const TestControlSocket& socket);
+    /// \param socket socket used to send the packet.
+    /// \param pkt packet to be configured.
+    void setDefaults4(const TestControlSocket& socket,
+                      const boost::shared_ptr<dhcp::Pkt4>& pkt);
 
     /// \brief Update due time to initiate next chunk of exchanges.
     ///