Browse Source

[1238] Assorted IfaceMgr and Dhcpv6_srv improvments.
- sockets are now closed in destructor
- IfaceMgr now deletes all SocketInfo
- Throwing proper exception type
- Dhcpv6_srv constructor takes one parameter (port number)

Tomek Mrugalski 13 years ago
parent
commit
4d97ef5cdb
2 changed files with 31 additions and 17 deletions
  1. 27 13
      src/bin/dhcp6/iface_mgr.cc
  2. 4 4
      src/bin/dhcp6/tests/dhcp6_srv_unittest.cc

+ 27 - 13
src/bin/dhcp6/iface_mgr.cc

@@ -80,14 +80,18 @@ IfaceMgr::Iface::getPlainMac() const {
 }
 
 bool IfaceMgr::Iface::delAddress(const isc::asiolink::IOAddress& addr) {
-    for (AddressCollection::iterator a = addrs_.begin();
-         a!=addrs_.end(); ++a) {
-        if (*a==addr) {
-            addrs_.erase(a);
-            return (true);
-        }
+
+    // Let's delete all addresses that match. It really shouldn't matter
+    // if we delete first or all, as the OS should allow to add a single
+    // address to an interface only once. If OS allows multiple instances
+    // of the same address added, we are in deep problems anyway.
+    size_t size = addrs_.size();
+    addrs_.erase(remove(addrs_.begin(), addrs_.end(), addr), addrs_.end());
+    if (addrs_.size() < size) {
+        return (true);
+    } else {
+        return (false);
     }
-    return (false);
 }
 
 bool IfaceMgr::Iface::delSocket(uint16_t sockfd) {
@@ -131,6 +135,18 @@ IfaceMgr::IfaceMgr()
 }
 
 IfaceMgr::~IfaceMgr() {
+
+    for (IfaceCollection::iterator iface = ifaces_.begin();
+         iface != ifaces_.end(); ++iface) {
+
+        for (SocketCollection::iterator sock = iface->sockets_.begin();
+             sock != iface->sockets_.end(); ++sock) {
+            cout << "Closing socket " << sock->sockfd_ << endl;
+            close(sock->sockfd_);
+        }
+        iface->sockets_.clear();
+    }
+
     // control_buf_ is deleted automatically (scoped_ptr)
     control_buf_len_ = 0;
 }
@@ -310,8 +326,7 @@ IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, int port) {
     cout << "Created socket " << sock << " on " << iface.getName() << "/" <<
         addr.toText() << "/port=" << port << endl;
 
-    SocketInfo info(sock, addr, port);
-    iface.addSocket(info);
+    iface.addSocket(SocketInfo(sock, addr, port));
 
     return (sock);
 }
@@ -390,8 +405,7 @@ IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, int port) {
     cout << "Created socket " << sock << " on " << iface.getName() << "/" <<
         addr.toText() << "/port=" << port << endl;
 
-    SocketInfo info(sock, addr, port);
-    iface.addSocket(info);
+    iface.addSocket(SocketInfo(sock, addr, port));
 
     return (sock);
 }
@@ -495,13 +509,13 @@ bool
 IfaceMgr::send(boost::shared_ptr<Pkt4>& )
 {
     /// TODO: Implement this (ticket #1240)
-    isc_throw(Unexpected, "Pkt4 send not implemented yet.");
+    isc_throw(NotImplemented, "Pkt4 send not implemented yet.");
 }
 
 
 boost::shared_ptr<Pkt4>
 IfaceMgr::receive4() {
-    isc_throw(Unexpected, "Pkt4 reception not implemented yet.");
+    isc_throw(NotImplemented, "Pkt4 reception not implemented yet.");
 
     // TODO: To be implemented (ticket #1239)
     return (boost::shared_ptr<Pkt4>()); // NULL

+ 4 - 4
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc

@@ -34,7 +34,7 @@ namespace test {
 class NakedDhcpv6Srv: public Dhcpv6Srv {
     // "naked" Interface Manager, exposes internal fields
 public:
-    NakedDhcpv6Srv() { }
+    NakedDhcpv6Srv():Dhcpv6Srv(DHCP6_SERVER_PORT + 10000) { }
 
     boost::shared_ptr<Pkt6>
     processSolicit(boost::shared_ptr<Pkt6>& request) {
@@ -58,7 +58,7 @@ TEST_F(Dhcpv6SrvTest, basic) {
     // fe80::1234 link-local address on eth0 interface. Obviously
     // an attempt to bind this socket will fail.
     Dhcpv6Srv * srv = 0;
-    EXPECT_NO_THROW( {
+    ASSERT_NO_THROW( {
         // open an unpriviledged port
         srv = new Dhcpv6Srv(DHCP6_SERVER_PORT + 10000);
     });
@@ -70,7 +70,7 @@ TEST_F(Dhcpv6SrvTest, basic) {
 
 TEST_F(Dhcpv6SrvTest, Solicit_basic) {
     NakedDhcpv6Srv * srv = 0;
-    EXPECT_NO_THROW( srv = new NakedDhcpv6Srv(); );
+    ASSERT_NO_THROW( srv = new NakedDhcpv6Srv(); );
 
     // a dummy content for client-id
     boost::shared_array<uint8_t> clntDuid(new uint8_t[32]);
@@ -137,7 +137,7 @@ TEST_F(Dhcpv6SrvTest, Solicit_basic) {
     EXPECT_EQ(tmp->getType(), srv->getServerID()->getType() );
     ASSERT_EQ(tmp->len(),  srv->getServerID()->len() );
 
-    EXPECT_EQ(tmp->getData(), srv->getServerID()->getData());
+    EXPECT_TRUE(tmp->getData() == srv->getServerID()->getData());
 
     // more checks to be implemented
     delete srv;