Browse Source

[1186] IfaceMgr now uses boost::shared_ptr, skeleton functions added.
- IfaceMgr now uses shared_ptr.
- skeleton functions for specific message processing added.
- tests fixed.

Tomek Mrugalski 13 years ago
parent
commit
a690200253

+ 103 - 9
src/bin/dhcp6/dhcp6_srv.cc

@@ -12,6 +12,7 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include "dhcp/dhcp6.h"
 #include "dhcp/pkt6.h"
 #include "dhcp6/iface_mgr.h"
 #include "dhcp6/dhcp6_srv.h"
@@ -34,22 +35,115 @@ Dhcpv6Srv::~Dhcpv6Srv() {
 bool
 Dhcpv6Srv::run() {
     while (true) {
-        Pkt6* pkt;
+        boost::shared_ptr<Pkt6> query; // client's message
+        boost::shared_ptr<Pkt6> rsp;   // server's response
 
-        pkt = IfaceMgr::instance().receive();
+        query = IfaceMgr::instance().receive();
 
-        if (pkt) {
-            cout << "Received " << pkt->data_len_ << " bytes, echoing back."
-                 << endl;
-            IfaceMgr::instance().send(*pkt);
-            delete pkt;
+        if (query) {
+            if (!query->unpack()) {
+                cout << "Failed to parse incoming packet" << endl;
+                continue;
+            }
+            switch (query->getType()) {
+            case DHCPV6_SOLICIT:
+                rsp = processSolicit(query);
+                break;
+            case DHCPV6_REQUEST:
+                rsp = processRequest(query);
+                break;
+            case DHCPV6_RENEW:
+                rsp = processRenew(query);
+                break;
+            case DHCPV6_REBIND:
+                rsp = processRebind(query);
+                break;
+            case DHCPV6_CONFIRM:
+                rsp = processConfirm(query);
+                break;
+            case DHCPV6_RELEASE:
+                rsp = processRelease(query);
+                break;
+            case DHCPV6_DECLINE:
+                rsp = processDecline(query);
+                break;
+            default:
+                cout << "Unknown pkt type received:"
+                     << query->getType() << endl;
+            }
+
+            cout << "Received " << query->data_len_ << " bytes packet type="
+                 << query->getType() << endl;
+            if (rsp != boost::shared_ptr<Pkt6>()) {
+                cout << "Replying with " << rsp->getType() << endl;
+                IfaceMgr::instance().send(rsp);
+            }
         }
 
-	// TODO add support for config session (see src/bin/auth/main.cc)
-	//      so this daemon can be controlled from bob
+        // TODO add support for config session (see src/bin/auth/main.cc)
+        //      so this daemon can be controlled from bob
         sleep(1);
 
     }
 
     return (true);
 }
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processSolicit(boost::shared_ptr<Pkt6> solicit) {
+
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_ADVERTISE,
+                                           solicit->getTransid(),
+                                           Pkt6::UDP));
+
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processRequest(boost::shared_ptr<Pkt6> request) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           request->getTransid(),
+                                           Pkt6::UDP));
+
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processRenew(boost::shared_ptr<Pkt6> renew) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           renew->getTransid(),
+                                           Pkt6::UDP));
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processRebind(boost::shared_ptr<Pkt6> rebind) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           rebind->getTransid(),
+                                           Pkt6::UDP));
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processConfirm(boost::shared_ptr<Pkt6> confirm) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           confirm->getTransid(),
+                                           Pkt6::UDP));
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processRelease(boost::shared_ptr<Pkt6> release) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           release->getTransid(),
+                                           Pkt6::UDP));
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processDecline(boost::shared_ptr<Pkt6> decline) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           decline->getTransid(),
+                                           Pkt6::UDP));
+    return reply;
+}

+ 23 - 0
src/bin/dhcp6/dhcp6_srv.h

@@ -15,6 +15,8 @@
 #ifndef DHCPV6_SRV_H
 #define DHCPV6_SRV_H
 
+#include <boost/shared_ptr.hpp>
+#include "dhcp/pkt6.h"
 #include <iostream>
 
 namespace isc {
@@ -33,6 +35,27 @@ namespace isc {
         bool run();
 
     protected:
+        boost::shared_ptr<Pkt6>
+        processSolicit(boost::shared_ptr<Pkt6> solicit);
+
+        boost::shared_ptr<Pkt6>
+        processRequest(boost::shared_ptr<Pkt6> solicit);
+
+        boost::shared_ptr<Pkt6>
+        processRenew(boost::shared_ptr<Pkt6> solicit);
+
+        boost::shared_ptr<Pkt6>
+        processRebind(boost::shared_ptr<Pkt6> solicit);
+
+        boost::shared_ptr<Pkt6>
+        processConfirm(boost::shared_ptr<Pkt6> solicit);
+
+        boost::shared_ptr<Pkt6>
+        processRelease(boost::shared_ptr<Pkt6> solicit);
+
+        boost::shared_ptr<Pkt6>
+        processDecline(boost::shared_ptr<Pkt6> solicit);
+
         bool shutdown;
     };
 };

+ 18 - 21
src/bin/dhcp6/iface_mgr.cc

@@ -367,7 +367,7 @@ const std::string & mcast) {
  * @return True, if transmission was successful. False otherwise.
  */
 bool
-IfaceMgr::send(Pkt6 &pkt) {
+IfaceMgr::send(boost::shared_ptr<Pkt6> pkt) {
     struct msghdr m;
     struct iovec v;
     int result;
@@ -386,11 +386,11 @@ IfaceMgr::send(Pkt6 &pkt) {
     sockaddr_in6 to;
     memset(&to, 0, sizeof(to));
     to.sin6_family = AF_INET6;
-    to.sin6_port = htons(pkt.remote_port_);
+    to.sin6_port = htons(pkt->remote_port_);
     memcpy(&to.sin6_addr,
-           pkt.remote_addr_.getAddress().to_v6().to_bytes().data(),
+           pkt->remote_addr_.getAddress().to_v6().to_bytes().data(),
            16);
-    to.sin6_scope_id = pkt.ifindex_;
+    to.sin6_scope_id = pkt->ifindex_;
 
     m.msg_name = &to;
     m.msg_namelen = sizeof(to);
@@ -400,8 +400,8 @@ IfaceMgr::send(Pkt6 &pkt) {
      * "scatter-gather" stuff... we only have a single chunk
      * of data to send, so we declare a single vector entry.)
      */
-    v.iov_base = (char *) &pkt.data_[0];
-    v.iov_len = pkt.data_len_;
+    v.iov_base = (char *) &pkt->data_[0];
+    v.iov_len = pkt->data_len_;
     m.msg_iov = &v;
     m.msg_iovlen = 1;
 
@@ -421,7 +421,7 @@ IfaceMgr::send(Pkt6 &pkt) {
     cmsg->cmsg_len = CMSG_LEN(sizeof(*pktinfo));
     pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
     memset(pktinfo, 0, sizeof(*pktinfo));
-    pktinfo->ipi6_ifindex = pkt.ifindex_;
+    pktinfo->ipi6_ifindex = pkt->ifindex_;
     m.msg_controllen = cmsg->cmsg_len;
 
     result = sendmsg(sendsock_, &m, 0);
@@ -430,10 +430,10 @@ IfaceMgr::send(Pkt6 &pkt) {
     }
     cout << "Sent " << result << " bytes." << endl;
 
-    cout << "Sent " << pkt.data_len_ << " bytes over "
-         << pkt.iface_ << "/" << pkt.ifindex_ << " interface: "
-         << " dst=" << pkt.remote_addr_.toText()
-         << ", src=" << pkt.local_addr_.toText()
+    cout << "Sent " << pkt->data_len_ << " bytes over "
+         << pkt->iface_ << "/" << pkt->ifindex_ << " interface: "
+         << " dst=" << pkt->remote_addr_.toText()
+         << ", src=" << pkt->local_addr_.toText()
          << endl;
 
     return (result);
@@ -449,7 +449,7 @@ IfaceMgr::send(Pkt6 &pkt) {
  *
  * @return Object prepresenting received packet.
  */
-Pkt6*
+boost::shared_ptr<Pkt6>
 IfaceMgr::receive() {
     struct msghdr m;
     struct iovec v;
@@ -458,7 +458,7 @@ IfaceMgr::receive() {
     struct in6_pktinfo* pktinfo;
     struct sockaddr_in6 from;
     struct in6_addr to_addr;
-    Pkt6* pkt;
+    boost::shared_ptr<Pkt6> pkt;
     char addr_str[INET6_ADDRSTRLEN];
 
     try {
@@ -469,10 +469,10 @@ IfaceMgr::receive() {
         // we use larger buffer. This buffer limit is checked
         // during reception (see iov_len below), so we are
         // safe
-        pkt = new Pkt6(65536);
+        pkt = boost::shared_ptr<Pkt6>(new Pkt6(65536));
     } catch (const std::exception& ex) {
         cout << "Failed to create new packet." << endl;
-        return (0);
+        return (boost::shared_ptr<Pkt6>()); // NULL
     }
 
     memset(control_buf_, 0, control_buf_len_);
@@ -537,13 +537,11 @@ IfaceMgr::receive() {
         }
         if (!found_pktinfo) {
             cout << "Unable to find pktinfo" << endl;
-            delete pkt;
-            return (0);
+            return (boost::shared_ptr<Pkt6>()); // NULL
         }
     } else {
         cout << "Failed to receive data." << endl;
-        delete pkt;
-        return (0);
+        return (boost::shared_ptr<Pkt6>()); // NULL
     }
 
     // That's ugly.
@@ -562,8 +560,7 @@ IfaceMgr::receive() {
     } else {
         cout << "Received packet over unknown interface (ifindex="
              << pkt->ifindex_ << ")." << endl;
-        delete pkt;
-        return (0);
+        return (boost::shared_ptr<Pkt6>()); // NULL
     }
 
     pkt->data_len_ = result;

+ 3 - 2
src/bin/dhcp6/iface_mgr.h

@@ -16,6 +16,7 @@
 #define IFACE_MGR_H
 
 #include <list>
+#include <boost/shared_ptr.hpp>
 #include "io_address.h"
 #include "dhcp/pkt6.h"
 
@@ -60,8 +61,8 @@ namespace isc {
 
         void printIfaces(std::ostream& out = std::cout);
 
-        bool send(Pkt6& pkt);
-        Pkt6* receive();
+        bool send(boost::shared_ptr<Pkt6> pkt);
+        boost::shared_ptr<Pkt6> receive();
 
         // don't use private, we need derived classes in tests
     protected:

+ 10 - 12
src/bin/dhcp6/tests/iface_mgr_unittest.cc

@@ -282,19 +282,19 @@ TEST_F(IfaceMgrTest, DISABLED_sendReceive) {
     ifacemgr->setSendSock(socket2);
     ifacemgr->setRecvSock(socket1);
 
-    Pkt6 sendPkt(128);
+    boost::shared_ptr<Pkt6> sendPkt(new Pkt6(128) );
 
     // prepare dummy payload
     for (int i=0;i<128; i++) {
-        sendPkt.data_[i] = i;
+        sendPkt->data_[i] = i;
     }
 
-    sendPkt.remote_port_ = 10547;
-    sendPkt.remote_addr_ = IOAddress("::1");
-    sendPkt.ifindex_ = 1;
-    sendPkt.iface_ = "lo";
+    sendPkt->remote_port_ = 10547;
+    sendPkt->remote_addr_ = IOAddress("::1");
+    sendPkt->ifindex_ = 1;
+    sendPkt->iface_ = "lo";
 
-    Pkt6 * rcvPkt;
+    boost::shared_ptr<Pkt6> rcvPkt;
 
     EXPECT_EQ(true, ifacemgr->send(sendPkt));
 
@@ -303,15 +303,13 @@ TEST_F(IfaceMgrTest, DISABLED_sendReceive) {
     ASSERT_TRUE( rcvPkt != NULL ); // received our own packet
 
     // let's check that we received what was sent
-    EXPECT_EQ(sendPkt.data_len_, rcvPkt->data_len_);
-    EXPECT_EQ(0, memcmp(&sendPkt.data_[0], &rcvPkt->data_[0],
+    EXPECT_EQ(sendPkt->data_len_, rcvPkt->data_len_);
+    EXPECT_EQ(0, memcmp(&sendPkt->data_[0], &rcvPkt->data_[0],
                         rcvPkt->data_len_) );
 
-    EXPECT_EQ(sendPkt.remote_addr_.toText(), rcvPkt->remote_addr_.toText());
+    EXPECT_EQ(sendPkt->remote_addr_.toText(), rcvPkt->remote_addr_.toText());
     EXPECT_EQ(rcvPkt->remote_port_, 10546);
 
-    delete rcvPkt;
-
     delete ifacemgr;
 }
 

+ 12 - 0
src/lib/dhcp/pkt6.cc

@@ -49,6 +49,18 @@ Pkt6::Pkt6(unsigned int dataLen, DHCPv6Proto_ proto /* = UDP */)
 }
 
 
+Pkt6::Pkt6(unsigned char msg_type,
+           unsigned int transid,
+           DHCPv6Proto_ proto /*= UDP*/)
+    :local_addr_("::"),
+     remote_addr_("::"),
+     proto_(proto),
+     msg_type_(msg_type),
+     transid_(transid) {
+
+
+}
+
 /**
  * Returns calculated length of the packet.
  *

+ 1 - 1
src/lib/dhcp/pkt6.h

@@ -49,7 +49,7 @@ namespace isc {
         unsigned short len();
 
         unsigned char getType();
-        unsigned int getTransid();
+        unsigned int getTransid() { return transid_; };
 
         boost::shared_ptr<isc::dhcp::Option> getOption(unsigned short opt_type);