Browse Source

Merge branch 'master' of git+ssh://git.bind10.isc.org/var/bind10/git/bind10

Michal 'vorner' Vaner 12 years ago
parent
commit
77b10c7082

+ 10 - 0
src/bin/dhcp4/dhcp4_messages.mes

@@ -42,12 +42,22 @@ server is about to open sockets on the specified port.
 The IPv4 DHCP server has received a packet that it is unable to
 The IPv4 DHCP server has received a packet that it is unable to
 interpret. The reason why the packet is invalid is included in the message.
 interpret. The reason why the packet is invalid is included in the message.
 
 
+% DHCP4_PACKET_RECEIVE_FAIL error on attempt to receive packet: %1
+The IPv4 DHCP server tried to receive a packet but an error
+occured during this attempt. The reason for the error is included in
+the message.
+
 % DHCP4_PACKET_RECEIVED %1 (type %2) packet received on interface %3
 % DHCP4_PACKET_RECEIVED %1 (type %2) packet received on interface %3
 A debug message noting that the server has received the specified type of
 A debug message noting that the server has received the specified type of
 packet on the specified interface.  Note that a packet marked as UNKNOWN
 packet on the specified interface.  Note that a packet marked as UNKNOWN
 may well be a valid DHCP packet, just a type not expected by the server
 may well be a valid DHCP packet, just a type not expected by the server
 (e.g. it will report a received OFFER packet as UNKNOWN).
 (e.g. it will report a received OFFER packet as UNKNOWN).
 
 
+% DHCP4_PACKET_SEND_FAIL failed to send DHCPv4 packet: %1
+This error is output if the IPv4 DHCP server fails to send an assembled
+DHCP message to a client. The reason for the error is included in the
+message.
+
 % DHCP4_PACK_FAIL failed to assemble response correctly
 % DHCP4_PACK_FAIL failed to assemble response correctly
 This error is output if the server failed to assemble the data to be
 This error is output if the server failed to assemble the data to be
 returned to the client into a valid packet.  The cause is most likely
 returned to the client into a valid packet.  The cause is most likely

+ 12 - 2
src/bin/dhcp4/dhcp4_srv.cc

@@ -73,9 +73,15 @@ Dhcpv4Srv::run() {
         int timeout = 1000;
         int timeout = 1000;
 
 
         // client's message and server's response
         // client's message and server's response
-        Pkt4Ptr query = IfaceMgr::instance().receive4(timeout);
+        Pkt4Ptr query;
         Pkt4Ptr rsp;
         Pkt4Ptr rsp;
 
 
+        try {
+            query = IfaceMgr::instance().receive4(timeout);
+        } catch (const std::exception& e) {
+            LOG_ERROR(dhcp4_logger, DHCP4_PACKET_RECEIVE_FAIL).arg(e.what());
+        }
+
         if (query) {
         if (query) {
             try {
             try {
                 query->unpack();
                 query->unpack();
@@ -141,7 +147,11 @@ Dhcpv4Srv::run() {
                           .arg(rsp->getType()).arg(rsp->toText());
                           .arg(rsp->getType()).arg(rsp->toText());
 
 
                 if (rsp->pack()) {
                 if (rsp->pack()) {
-                    IfaceMgr::instance().send(rsp);
+                    try {
+                        IfaceMgr::instance().send(rsp);
+                    } catch (const std::exception& e) {
+                        LOG_ERROR(dhcp4_logger, DHCP4_PACKET_SEND_FAIL).arg(e.what());
+                    }
                 } else {
                 } else {
                     LOG_ERROR(dhcp4_logger, DHCP4_PACK_FAIL);
                     LOG_ERROR(dhcp4_logger, DHCP4_PACK_FAIL);
                 }
                 }

+ 10 - 0
src/bin/dhcp6/dhcp6_messages.mes

@@ -45,12 +45,22 @@ server is about to open sockets on the specified port.
 % DHCP6_PACKET_PARSE_FAIL failed to parse incoming packet
 % DHCP6_PACKET_PARSE_FAIL failed to parse incoming packet
 The IPv6 DHCP server has received a packet that it is unable to interpret.
 The IPv6 DHCP server has received a packet that it is unable to interpret.
 
 
+% DHCP6_PACKET_RECEIVE_FAIL error on attempt to receive packet: %1
+The IPv6 DHCP server tried to receive a packet but an error
+occured during this attempt. The reason for the error is included in
+the message.
+
 % DHCP6_PACKET_RECEIVED %1 (type %2) packet received
 % DHCP6_PACKET_RECEIVED %1 (type %2) packet received
 A debug message noting that the server has received the specified type
 A debug message noting that the server has received the specified type
 of packet.  Note that a packet marked as UNKNOWN may well be a valid
 of packet.  Note that a packet marked as UNKNOWN may well be a valid
 DHCP packet, just a type not expected by the server (e.g. it will report
 DHCP packet, just a type not expected by the server (e.g. it will report
 a received OFFER packet as UNKNOWN).
 a received OFFER packet as UNKNOWN).
 
 
+% DHCP6_PACKET_SEND_FAIL failed to send DHCPv6 packet: %1
+This error is output if the IPv6 DHCP server fails to send an assembled
+DHCP message to a client. The reason for the error is included in the
+message.
+
 % DHCP6_PACK_FAIL failed to assemble response correctly
 % DHCP6_PACK_FAIL failed to assemble response correctly
 This error is output if the server failed to assemble the data to be
 This error is output if the server failed to assemble the data to be
 returned to the client into a valid packet.  The reason is most likely
 returned to the client into a valid packet.  The reason is most likely

+ 12 - 2
src/bin/dhcp6/dhcp6_srv.cc

@@ -84,9 +84,15 @@ bool Dhcpv6Srv::run() {
         int timeout = 1000;
         int timeout = 1000;
 
 
         // client's message and server's response
         // client's message and server's response
-        Pkt6Ptr query = IfaceMgr::instance().receive6(timeout);
+        Pkt6Ptr query;
         Pkt6Ptr rsp;
         Pkt6Ptr rsp;
 
 
+        try {
+            query = IfaceMgr::instance().receive6(timeout);
+        } catch (const std::exception& e) {
+            LOG_ERROR(dhcp6_logger, DHCP6_PACKET_RECEIVE_FAIL).arg(e.what());
+        }
+
         if (query) {
         if (query) {
             if (!query->unpack()) {
             if (!query->unpack()) {
                 LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL,
                 LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL,
@@ -154,7 +160,11 @@ bool Dhcpv6Srv::run() {
                           .arg(rsp->getType()).arg(rsp->toText());
                           .arg(rsp->getType()).arg(rsp->toText());
 
 
                 if (rsp->pack()) {
                 if (rsp->pack()) {
-                    IfaceMgr::instance().send(rsp);
+                    try {
+                        IfaceMgr::instance().send(rsp);
+                    } catch (const std::exception& e) {
+                        LOG_ERROR(dhcp6_logger, DHCP6_PACKET_SEND_FAIL).arg(e.what());
+                    }
                 } else {
                 } else {
                     LOG_ERROR(dhcp6_logger, DHCP6_PACK_FAIL);
                     LOG_ERROR(dhcp6_logger, DHCP6_PACK_FAIL);
                 }
                 }

+ 64 - 170
src/lib/dhcp/iface_mgr.cc

@@ -122,8 +122,6 @@ IfaceMgr::IfaceMgr()
      session_socket_(INVALID_SOCKET), session_callback_(NULL)
      session_socket_(INVALID_SOCKET), session_callback_(NULL)
 {
 {
 
 
-    cout << "IfaceMgr initialization." << endl;
-
     try {
     try {
         // required for sending/receiving packets
         // required for sending/receiving packets
         // let's keep it in front, just in case someone
         // let's keep it in front, just in case someone
@@ -134,13 +132,7 @@ IfaceMgr::IfaceMgr()
         detectIfaces();
         detectIfaces();
 
 
     } catch (const std::exception& ex) {
     } catch (const std::exception& ex) {
-        cout << "IfaceMgr creation failed:" << ex.what() << endl;
-
-        // TODO Uncomment this (or call LOG_FATAL) once
-        // interface detection is implemented. Otherwise
-        // it is not possible to run tests in a portable
-        // way (see detectIfaces() method).
-        throw;
+        isc_throw(IfaceDetectError, ex.what());
     }
     }
 }
 }
 
 
@@ -166,51 +158,34 @@ void IfaceMgr::stubDetectIfaces() {
     // is faked by detecting loopback interface (lo or lo0). It will eventually
     // is faked by detecting loopback interface (lo or lo0). It will eventually
     // be removed once we have actual implementations for all supported systems.
     // be removed once we have actual implementations for all supported systems.
 
 
-    cout << "Interface detection is not implemented on this Operating System yet. "
-         << endl;
-
-    try {
-        if (if_nametoindex("lo") > 0) {
-            ifaceName = "lo";
-            // this is Linux-like OS
-        } else if (if_nametoindex("lo0") > 0) {
-            ifaceName = "lo0";
-            // this is BSD-like OS
-        } else {
-            // we give up. What OS is this, anyway? Solaris? Hurd?
-            isc_throw(NotImplemented,
-                      "Interface detection on this OS is not supported.");
-        }
-
-        Iface iface(ifaceName, if_nametoindex(ifaceName.c_str()));
-        iface.flag_up_ = true;
-        iface.flag_running_ = true;
-
-        // Note that we claim that this is not a loopback. iface_mgr tries to open a
-        // socket on all interaces that are up, running and not loopback. As this is
-        // the only interface we were able to detect, let's pretend this is a normal
-        // interface.
-        iface.flag_loopback_ = false;
-        iface.flag_multicast_ = true;
-        iface.flag_broadcast_ = true;
-        iface.setHWType(HWTYPE_ETHERNET);
-
-        iface.addAddress(IOAddress(v4addr));
-        iface.addAddress(IOAddress(v6addr));
-        addInterface(iface);
-
-        cout << "Detected interface " << ifaceName << "/" << v4addr << "/"
-             << v6addr << endl;
-    } catch (const std::exception& ex) {
-        // TODO: deallocate whatever memory we used
-        // not that important, since this function is going to be
-        // thrown away as soon as we get proper interface detection
-        // implemented
-
-        // TODO Do LOG_FATAL here
-        std::cerr << "Interface detection failed." << std::endl;
-        throw;
+    if (if_nametoindex("lo") > 0) {
+        ifaceName = "lo";
+        // this is Linux-like OS
+    } else if (if_nametoindex("lo0") > 0) {
+        ifaceName = "lo0";
+        // this is BSD-like OS
+    } else {
+        // we give up. What OS is this, anyway? Solaris? Hurd?
+        isc_throw(NotImplemented,
+                  "Interface detection on this OS is not supported.");
     }
     }
+
+    Iface iface(ifaceName, if_nametoindex(ifaceName.c_str()));
+    iface.flag_up_ = true;
+    iface.flag_running_ = true;
+
+    // Note that we claim that this is not a loopback. iface_mgr tries to open a
+    // socket on all interaces that are up, running and not loopback. As this is
+    // the only interface we were able to detect, let's pretend this is a normal
+    // interface.
+    iface.flag_loopback_ = false;
+    iface.flag_multicast_ = true;
+    iface.flag_broadcast_ = true;
+    iface.setHWType(HWTYPE_ETHERNET);
+
+    iface.addAddress(IOAddress(v4addr));
+    iface.addAddress(IOAddress(v6addr));
+    addInterface(iface);
 }
 }
 
 
 bool IfaceMgr::openSockets4(const uint16_t port) {
 bool IfaceMgr::openSockets4(const uint16_t port) {
@@ -221,13 +196,9 @@ bool IfaceMgr::openSockets4(const uint16_t port) {
          iface != ifaces_.end();
          iface != ifaces_.end();
          ++iface) {
          ++iface) {
 
 
-        cout << "Trying opening socket on interface " << iface->getFullName() << endl;
-
         if (iface->flag_loopback_ ||
         if (iface->flag_loopback_ ||
             !iface->flag_up_ ||
             !iface->flag_up_ ||
             !iface->flag_running_) {
             !iface->flag_running_) {
-            cout << "Interface " << iface->getFullName()
-                 << " not suitable: is loopback, is down or not running" << endl;
             continue;
             continue;
         }
         }
 
 
@@ -243,15 +214,13 @@ bool IfaceMgr::openSockets4(const uint16_t port) {
 
 
             sock = openSocket(iface->getName(), *addr, port);
             sock = openSocket(iface->getName(), *addr, port);
             if (sock < 0) {
             if (sock < 0) {
-                cout << "Failed to open unicast socket." << endl;
-                return (false);
+                isc_throw(SocketConfigError, "failed to open unicast socket");
             }
             }
 
 
             count++;
             count++;
         }
         }
     }
     }
     return (count > 0);
     return (count > 0);
-
 }
 }
 
 
 bool IfaceMgr::openSockets6(const uint16_t port) {
 bool IfaceMgr::openSockets6(const uint16_t port) {
@@ -280,8 +249,7 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
 
 
             sock = openSocket(iface->getName(), *addr, port);
             sock = openSocket(iface->getName(), *addr, port);
             if (sock < 0) {
             if (sock < 0) {
-                cout << "Failed to open unicast socket." << endl;
-                return (false);
+                isc_throw(SocketConfigError, "failed to open unicast socket");
             }
             }
 
 
             // Binding socket to unicast address and then joining multicast group
             // Binding socket to unicast address and then joining multicast group
@@ -290,7 +258,8 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
             if ( !joinMulticast(sock, iface->getName(),
             if ( !joinMulticast(sock, iface->getName(),
                                 string(ALL_DHCP_RELAY_AGENTS_AND_SERVERS))) {
                                 string(ALL_DHCP_RELAY_AGENTS_AND_SERVERS))) {
                 close(sock);
                 close(sock);
-                isc_throw(Unexpected, "Failed to join " << ALL_DHCP_RELAY_AGENTS_AND_SERVERS
+                isc_throw(SocketConfigError, "Failed to join "
+                          << ALL_DHCP_RELAY_AGENTS_AND_SERVERS
                           << " multicast group.");
                           << " multicast group.");
             }
             }
 
 
@@ -305,7 +274,7 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
                                    IOAddress(ALL_DHCP_RELAY_AGENTS_AND_SERVERS),
                                    IOAddress(ALL_DHCP_RELAY_AGENTS_AND_SERVERS),
                                    port);
                                    port);
             if (sock2 < 0) {
             if (sock2 < 0) {
-                isc_throw(Unexpected, "Failed to open multicast socket on "
+                isc_throw(SocketConfigError, "Failed to open multicast socket on "
                           << " interface " << iface->getFullName());
                           << " interface " << iface->getFullName());
                 iface->delSocket(sock); // delete previously opened socket
                 iface->delSocket(sock); // delete previously opened socket
             }
             }
@@ -418,7 +387,7 @@ int IfaceMgr::openSocketFromIface(const std::string& ifname,
                 family_name = "AF_INET6";
                 family_name = "AF_INET6";
             }
             }
             // We did not find address on the interface.
             // We did not find address on the interface.
-            isc_throw(BadValue, "There is no address for interface: "
+            isc_throw(SocketConfigError, "There is no address for interface: "
                       << ifname << ", port: " << port << ", address "
                       << ifname << ", port: " << port << ", address "
                       " family: " << family_name);
                       " family: " << family_name);
         }
         }
@@ -460,9 +429,13 @@ int IfaceMgr::openSocketFromAddress(const IOAddress& addr,
 
 
 int IfaceMgr::openSocketFromRemoteAddress(const IOAddress& remote_addr,
 int IfaceMgr::openSocketFromRemoteAddress(const IOAddress& remote_addr,
                                           const uint16_t port) {
                                           const uint16_t port) {
-    // Get local address to be used to connect to remote location.
-    IOAddress local_address(getLocalAddress(remote_addr, port).getAddress());
-    return openSocketFromAddress(local_address, port);
+    try {
+        // Get local address to be used to connect to remote location.
+        IOAddress local_address(getLocalAddress(remote_addr, port).getAddress());
+        return openSocketFromAddress(local_address, port);
+    } catch (const Exception& e) {
+        isc_throw(SocketConfigError, e.what());
+    }
 }
 }
 
 
 isc::asiolink::IOAddress
 isc::asiolink::IOAddress
@@ -506,7 +479,7 @@ IfaceMgr::getLocalAddress(const IOAddress& remote_addr, const uint16_t port) {
     sock.connect(remote_endpoint->getASIOEndpoint(), err_code);
     sock.connect(remote_endpoint->getASIOEndpoint(), err_code);
     if (err_code) {
     if (err_code) {
         sock.close();
         sock.close();
-        isc_throw(Unexpected,"failed to connect to remote endpoint.");
+        isc_throw(Unexpected, "failed to connect to remote endpoint.");
     }
     }
 
 
     // Once we are connected socket object holds local endpoint.
     // Once we are connected socket object holds local endpoint.
@@ -523,9 +496,6 @@ IfaceMgr::getLocalAddress(const IOAddress& remote_addr, const uint16_t port) {
 
 
 int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port) {
 int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port) {
 
 
-    cout << "Creating UDP4 socket on " << iface.getFullName()
-         << " " << addr.toText() << "/port=" << port << endl;
-
     struct sockaddr_in addr4;
     struct sockaddr_in addr4;
     memset(&addr4, 0, sizeof(sockaddr));
     memset(&addr4, 0, sizeof(sockaddr));
     addr4.sin_family = AF_INET;
     addr4.sin_family = AF_INET;
@@ -537,12 +507,12 @@ int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port) {
 
 
     int sock = socket(AF_INET, SOCK_DGRAM, 0);
     int sock = socket(AF_INET, SOCK_DGRAM, 0);
     if (sock < 0) {
     if (sock < 0) {
-        isc_throw(Unexpected, "Failed to create UDP6 socket.");
+        isc_throw(SocketConfigError, "Failed to create UDP6 socket.");
     }
     }
 
 
     if (bind(sock, (struct sockaddr *)&addr4, sizeof(addr4)) < 0) {
     if (bind(sock, (struct sockaddr *)&addr4, sizeof(addr4)) < 0) {
         close(sock);
         close(sock);
-        isc_throw(Unexpected, "Failed to bind socket " << sock << " to " << addr.toText()
+        isc_throw(SocketConfigError, "Failed to bind socket " << sock << " to " << addr.toText()
                   << "/port=" << port);
                   << "/port=" << port);
     }
     }
 
 
@@ -552,13 +522,10 @@ int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port) {
     int flag = 1;
     int flag = 1;
     if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &flag, sizeof(flag)) != 0) {
     if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &flag, sizeof(flag)) != 0) {
         close(sock);
         close(sock);
-        isc_throw(Unexpected, "setsockopt: IP_PKTINFO: failed.");
+        isc_throw(SocketConfigError, "setsockopt: IP_PKTINFO: failed.");
     }
     }
 #endif
 #endif
 
 
-    cout << "Created socket " << sock << " on " << iface.getName() << "/" <<
-        addr.toText() << "/port=" << port << endl;
-
     SocketInfo info(sock, addr, port);
     SocketInfo info(sock, addr, port);
     iface.addSocket(info);
     iface.addSocket(info);
 
 
@@ -567,9 +534,6 @@ int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port) {
 
 
 int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
 int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
 
 
-    cout << "Creating UDP6 socket on " << iface.getFullName()
-         << " " << addr.toText() << "/port=" << port << endl;
-
     struct sockaddr_in6 addr6;
     struct sockaddr_in6 addr6;
     memset(&addr6, 0, sizeof(addr6));
     memset(&addr6, 0, sizeof(addr6));
     addr6.sin6_family = AF_INET6;
     addr6.sin6_family = AF_INET6;
@@ -590,7 +554,7 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
     // make a socket
     // make a socket
     int sock = socket(AF_INET6, SOCK_DGRAM, 0);
     int sock = socket(AF_INET6, SOCK_DGRAM, 0);
     if (sock < 0) {
     if (sock < 0) {
-        isc_throw(Unexpected, "Failed to create UDP6 socket.");
+        isc_throw(SocketConfigError, "Failed to create UDP6 socket.");
     }
     }
 
 
     // Set the REUSEADDR option so that we don't fail to start if
     // Set the REUSEADDR option so that we don't fail to start if
@@ -599,12 +563,12 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
                    (char *)&flag, sizeof(flag)) < 0) {
                    (char *)&flag, sizeof(flag)) < 0) {
         close(sock);
         close(sock);
-        isc_throw(Unexpected, "Can't set SO_REUSEADDR option on dhcpv6 socket.");
+        isc_throw(SocketConfigError, "Can't set SO_REUSEADDR option on dhcpv6 socket.");
     }
     }
 
 
     if (bind(sock, (struct sockaddr *)&addr6, sizeof(addr6)) < 0) {
     if (bind(sock, (struct sockaddr *)&addr6, sizeof(addr6)) < 0) {
         close(sock);
         close(sock);
-        isc_throw(Unexpected, "Failed to bind socket " << sock << " to " << addr.toText()
+        isc_throw(SocketConfigError, "Failed to bind socket " << sock << " to " << addr.toText()
                   << "/port=" << port);
                   << "/port=" << port);
     }
     }
 #ifdef IPV6_RECVPKTINFO
 #ifdef IPV6_RECVPKTINFO
@@ -612,14 +576,14 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
     if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO,
     if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO,
                    &flag, sizeof(flag)) != 0) {
                    &flag, sizeof(flag)) != 0) {
         close(sock);
         close(sock);
-        isc_throw(Unexpected, "setsockopt: IPV6_RECVPKTINFO failed.");
+        isc_throw(SocketConfigError, "setsockopt: IPV6_RECVPKTINFO failed.");
     }
     }
 #else
 #else
     // RFC2292 - an old way
     // RFC2292 - an old way
     if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO,
     if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO,
                    &flag, sizeof(flag)) != 0) {
                    &flag, sizeof(flag)) != 0) {
         close(sock);
         close(sock);
-        isc_throw(Unexpected, "setsockopt: IPV6_PKTINFO: failed.");
+        isc_throw(SocketConfigError, "setsockopt: IPV6_PKTINFO: failed.");
     }
     }
 #endif
 #endif
 
 
@@ -632,14 +596,11 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
         if ( !joinMulticast( sock, iface.getName(),
         if ( !joinMulticast( sock, iface.getName(),
                          string(ALL_DHCP_RELAY_AGENTS_AND_SERVERS) ) ) {
                          string(ALL_DHCP_RELAY_AGENTS_AND_SERVERS) ) ) {
             close(sock);
             close(sock);
-            isc_throw(Unexpected, "Failed to join " << ALL_DHCP_RELAY_AGENTS_AND_SERVERS
+            isc_throw(SocketConfigError, "Failed to join " << ALL_DHCP_RELAY_AGENTS_AND_SERVERS
                       << " multicast group.");
                       << " multicast group.");
         }
         }
     }
     }
 
 
-    cout << "Created socket " << sock << " on " << iface.getName() << "/" <<
-        addr.toText() << "/port=" << port << endl;
-
     SocketInfo info(sock, addr, port);
     SocketInfo info(sock, addr, port);
     iface.addSocket(info);
     iface.addSocket(info);
 
 
@@ -654,20 +615,15 @@ const std::string & mcast) {
 
 
     if (inet_pton(AF_INET6, mcast.c_str(),
     if (inet_pton(AF_INET6, mcast.c_str(),
                   &mreq.ipv6mr_multiaddr) <= 0) {
                   &mreq.ipv6mr_multiaddr) <= 0) {
-        cout << "Failed to convert " << ifname
-             << " to IPv6 multicast address." << endl;
         return (false);
         return (false);
     }
     }
 
 
     mreq.ipv6mr_interface = if_nametoindex(ifname.c_str());
     mreq.ipv6mr_interface = if_nametoindex(ifname.c_str());
     if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
     if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
                    &mreq, sizeof(mreq)) < 0) {
                    &mreq, sizeof(mreq)) < 0) {
-        cout << "Failed to join " << mcast << " multicast group." << endl;
         return (false);
         return (false);
     }
     }
 
 
-    cout << "Joined multicast " << mcast << " group." << endl;
-
     return (true);
     return (true);
 }
 }
 
 
@@ -746,13 +702,8 @@ IfaceMgr::send(const Pkt6Ptr& pkt) {
 
 
     result = sendmsg(getSocket(*pkt), &m, 0);
     result = sendmsg(getSocket(*pkt), &m, 0);
     if (result < 0) {
     if (result < 0) {
-        isc_throw(Unexpected, "Pkt6 send failed: sendmsg() returned " << result);
+        isc_throw(SocketWriteError, "Pkt6 send failed: sendmsg() returned " << result);
     }
     }
-    cout << "Sent " << pkt->getBuffer().getLength() << " bytes over socket " << getSocket(*pkt)
-         << " on " << iface->getFullName() << " interface: "
-         << " dst=[" << pkt->getRemoteAddr().toText() << "]:" << pkt->getRemotePort()
-         << ", src=" << pkt->getLocalAddr().toText() << "]:" << pkt->getLocalPort()
-         << endl;
 
 
     return (result);
     return (result);
 }
 }
@@ -797,24 +748,13 @@ IfaceMgr::send(const Pkt4Ptr& pkt)
     // call OS-specific routines (like setting interface index)
     // call OS-specific routines (like setting interface index)
     os_send4(m, control_buf_, control_buf_len_, pkt);
     os_send4(m, control_buf_, control_buf_len_, pkt);
 
 
-    cout << "Trying to send " << pkt->getBuffer().getLength() << " bytes to "
-         << pkt->getRemoteAddr().toText() << ":" << pkt->getRemotePort()
-         << " over socket " << getSocket(*pkt) << " on interface "
-         << getIface(pkt->getIface())->getFullName() << endl;
-
     pkt->updateTimestamp();
     pkt->updateTimestamp();
 
 
     int result = sendmsg(getSocket(*pkt), &m, 0);
     int result = sendmsg(getSocket(*pkt), &m, 0);
     if (result < 0) {
     if (result < 0) {
-        isc_throw(Unexpected, "Pkt4 send failed.");
+        isc_throw(SocketWriteError, "pkt4 send failed");
     }
     }
 
 
-    cout << "Sent " << pkt->getBuffer().getLength() << " bytes over socket " << getSocket(*pkt)
-         << " on " << iface->getFullName() << " interface: "
-         << " dst=" << pkt->getRemoteAddr().toText() << ":" << pkt->getRemotePort()
-         << ", src=" << pkt->getLocalAddr().toText() << ":" << pkt->getLocalPort()
-         << endl;
-
     return (result);
     return (result);
 }
 }
 
 
@@ -869,27 +809,18 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
     select_timeout.tv_sec = timeout_sec;
     select_timeout.tv_sec = timeout_sec;
     select_timeout.tv_usec = timeout_usec;
     select_timeout.tv_usec = timeout_usec;
 
 
-    cout << "Trying to receive data on sockets: " << names.str()
-         << ". Timeout is " << timeout_sec << "." << setw(6) << setfill('0')
-         << timeout_usec << " seconds." << endl;
     int result = select(maxfd + 1, &sockets, NULL, NULL, &select_timeout);
     int result = select(maxfd + 1, &sockets, NULL, NULL, &select_timeout);
-    cout << "select returned " << result << endl;
 
 
     if (result == 0) {
     if (result == 0) {
         // nothing received and timeout has been reached
         // nothing received and timeout has been reached
         return (Pkt4Ptr()); // NULL
         return (Pkt4Ptr()); // NULL
     } else if (result < 0) {
     } else if (result < 0) {
-        cout << "Socket read error: " << strerror(errno) << endl;
-
-        /// @todo: perhaps throw here?
-        return (Pkt4Ptr()); // NULL
+        isc_throw(SocketReadError, strerror(errno));
     }
     }
 
 
     // Let's find out which socket has the data
     // Let's find out which socket has the data
     if ((session_socket_ != INVALID_SOCKET) && (FD_ISSET(session_socket_, &sockets))) {
     if ((session_socket_ != INVALID_SOCKET) && (FD_ISSET(session_socket_, &sockets))) {
         // something received over session socket
         // something received over session socket
-        cout << "BIND10 command or config available over session socket." << endl;
-
         if (session_callback_) {
         if (session_callback_) {
             // in theory we could call io_service.run_one() here, instead of
             // in theory we could call io_service.run_one() here, instead of
             // implementing callback mechanism, but that would introduce
             // implementing callback mechanism, but that would introduce
@@ -918,14 +849,9 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
     }
     }
 
 
     if (!candidate) {
     if (!candidate) {
-        cout << "Received data over unknown socket." << endl;
-        return (Pkt4Ptr()); // NULL
+        isc_throw(SocketReadError, "received data over unknown socket");
     }
     }
 
 
-    cout << "Trying to receive over UDP4 socket " << candidate->sockfd_ << " bound to "
-         << candidate->addr_.toText() << "/port=" << candidate->port_ << " on "
-         << iface->getFullName() << endl;
-
     // Now we have a socket, let's get some data from it!
     // Now we have a socket, let's get some data from it!
     struct sockaddr_in from_addr;
     struct sockaddr_in from_addr;
     uint8_t buf[RCVBUFSIZE];
     uint8_t buf[RCVBUFSIZE];
@@ -958,8 +884,7 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
 
 
     result = recvmsg(candidate->sockfd_, &m, 0);
     result = recvmsg(candidate->sockfd_, &m, 0);
     if (result < 0) {
     if (result < 0) {
-        cout << "Failed to receive UDP4 data." << endl;
-        return (Pkt4Ptr()); // NULL
+        isc_throw(SocketReadError, "failed to receive UDP4 data");
     }
     }
 
 
     // We have all data let's create Pkt4 object.
     // We have all data let's create Pkt4 object.
@@ -982,15 +907,9 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
     pkt->setLocalPort(candidate->port_);
     pkt->setLocalPort(candidate->port_);
 
 
     if (!os_receive4(m, pkt)) {
     if (!os_receive4(m, pkt)) {
-        cout << "Unable to find pktinfo" << endl;
-        return (boost::shared_ptr<Pkt4>()); // NULL
+        isc_throw(SocketReadError, "unable to find pktinfo");
     }
     }
 
 
-    cout << "Received " << result << " bytes from " << from.toText()
-         << "/port=" << from_port
-         << " sent to " << pkt->getLocalAddr().toText() << " over interface "
-         << iface->getFullName() << endl;
-
     return (pkt);
     return (pkt);
 }
 }
 
 
@@ -1039,10 +958,6 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
         names << session_socket_ << "(session)";
         names << session_socket_ << "(session)";
     }
     }
 
 
-    cout << "Trying to receive data on sockets: " << names.str()
-         << ". Timeout is " << timeout_sec << "." << setw(6) << setfill('0')
-         << timeout_usec << " seconds." << endl;
-
     struct timeval select_timeout;
     struct timeval select_timeout;
     select_timeout.tv_sec = timeout_sec;
     select_timeout.tv_sec = timeout_sec;
     select_timeout.tv_usec = timeout_usec;
     select_timeout.tv_usec = timeout_usec;
@@ -1053,17 +968,12 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
         // nothing received and timeout has been reached
         // nothing received and timeout has been reached
         return (Pkt6Ptr()); // NULL
         return (Pkt6Ptr()); // NULL
     } else if (result < 0) {
     } else if (result < 0) {
-        cout << "Socket read error: " << strerror(errno) << endl;
-
-        /// @todo: perhaps throw here?
-        return (Pkt6Ptr()); // NULL
+        isc_throw(SocketReadError, strerror(errno));
     }
     }
 
 
     // Let's find out which socket has the data
     // Let's find out which socket has the data
     if ((session_socket_ != INVALID_SOCKET) && (FD_ISSET(session_socket_, &sockets))) {
     if ((session_socket_ != INVALID_SOCKET) && (FD_ISSET(session_socket_, &sockets))) {
         // something received over session socket
         // something received over session socket
-        cout << "BIND10 command or config available over session socket." << endl;
-
         if (session_callback_) {
         if (session_callback_) {
             // in theory we could call io_service.run_one() here, instead of
             // in theory we could call io_service.run_one() here, instead of
             // implementing callback mechanism, but that would introduce
             // implementing callback mechanism, but that would introduce
@@ -1092,14 +1002,9 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
     }
     }
 
 
     if (!candidate) {
     if (!candidate) {
-        cout << "Received data over unknown socket." << endl;
-        return (Pkt6Ptr()); // NULL
+        isc_throw(SocketReadError, "received data over unknown socket");
     }
     }
 
 
-    cout << "Trying to receive over UDP6 socket " << candidate->sockfd_ << " bound to "
-         << candidate->addr_.toText() << "/port=" << candidate->port_ << " on "
-         << iface->getFullName() << endl;
-
     // Now we have a socket, let's get some data from it!
     // Now we have a socket, let's get some data from it!
     uint8_t buf[RCVBUFSIZE];
     uint8_t buf[RCVBUFSIZE];
     memset(&control_buf_[0], 0, control_buf_len_);
     memset(&control_buf_[0], 0, control_buf_len_);
@@ -1163,12 +1068,10 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
             cmsg = CMSG_NXTHDR(&m, cmsg);
             cmsg = CMSG_NXTHDR(&m, cmsg);
         }
         }
         if (!found_pktinfo) {
         if (!found_pktinfo) {
-            cout << "Unable to find pktinfo" << endl;
-            return (Pkt6Ptr()); // NULL
+            isc_throw(SocketReadError, "unable to find pktinfo");
         }
         }
     } else {
     } else {
-        cout << "Failed to receive data." << endl;
-        return (Pkt6Ptr()); // NULL
+        isc_throw(SocketReadError, "failed to receive data");
     }
     }
 
 
     // Let's create a packet.
     // Let's create a packet.
@@ -1176,8 +1079,7 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
     try {
     try {
         pkt = Pkt6Ptr(new Pkt6(buf, result));
         pkt = Pkt6Ptr(new Pkt6(buf, result));
     } catch (const std::exception& ex) {
     } catch (const std::exception& ex) {
-        cout << "Failed to create new packet." << endl;
-        return (Pkt6Ptr()); // NULL
+        isc_throw(SocketReadError, "failed to create new packet");
     }
     }
 
 
     pkt->updateTimestamp();
     pkt->updateTimestamp();
@@ -1193,18 +1095,10 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
     if (received) {
     if (received) {
         pkt->setIface(received->getName());
         pkt->setIface(received->getName());
     } else {
     } else {
-        cout << "Received packet over unknown interface (ifindex="
-             << pkt->getIndex() << ")." << endl;
-        return (boost::shared_ptr<Pkt6>()); // NULL
+        isc_throw(SocketReadError, "received packet over unknown interface"
+                  << "(ifindex=" << pkt->getIndex() << ")");
     }
     }
 
 
-    /// @todo: Move this to LOG_DEBUG
-    cout << "Received " << pkt->getBuffer().getLength() << " bytes over "
-         << pkt->getIface() << "/" << pkt->getIndex() << " interface: "
-         << " src=" << pkt->getRemoteAddr().toText()
-         << ", dst=" << pkt->getLocalAddr().toText()
-         << endl;
-
     return (pkt);
     return (pkt);
 }
 }
 
 

+ 40 - 0
src/lib/dhcp/iface_mgr.h

@@ -28,6 +28,38 @@
 namespace isc {
 namespace isc {
 
 
 namespace dhcp {
 namespace dhcp {
+
+/// @brief IfaceMgr exception thrown thrown when interface detection fails.
+class IfaceDetectError : public Exception {
+public:
+    IfaceDetectError(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) { };
+};
+
+/// @brief IfaceMgr exception thrown thrown when socket opening
+/// or configuration failed.
+class SocketConfigError : public Exception {
+public:
+    SocketConfigError(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) { };
+};
+
+/// @brief IfaceMgr exception thrown thrown when error occured during
+/// reading data from socket.
+class SocketReadError : public Exception {
+public:
+    SocketReadError(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) { };
+};
+
+/// @brief IfaceMgr exception thrown thrown when error occured during
+/// sedning data through socket.
+class SocketWriteError : public Exception {
+public:
+    SocketWriteError(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) { };
+};
+
 /// @brief handles network interfaces, transmission and reception
 /// @brief handles network interfaces, transmission and reception
 ///
 ///
 /// IfaceMgr is an interface manager class that detects available network
 /// IfaceMgr is an interface manager class that detects available network
@@ -340,6 +372,8 @@ public:
     ///
     ///
     /// @param pkt packet to be sent
     /// @param pkt packet to be sent
     ///
     ///
+    /// @throw isc::BadValue if invalid interface specified in the packet.
+    /// @throw isc::dhcp::SocketWriteError if sendmsg() failed to send packet.
     /// @return true if sending was successful
     /// @return true if sending was successful
     bool send(const Pkt6Ptr& pkt);
     bool send(const Pkt6Ptr& pkt);
 
 
@@ -351,6 +385,8 @@ public:
     ///
     ///
     /// @param pkt a packet to be sent
     /// @param pkt a packet to be sent
     ///
     ///
+    /// @throw isc::BadValue if invalid interface specified in the packet.
+    /// @throw isc::dhcp::SocketWriteError if sendmsg() failed to send packet.
     /// @return true if sending was successful
     /// @return true if sending was successful
     bool send(const Pkt4Ptr& pkt);
     bool send(const Pkt4Ptr& pkt);
 
 
@@ -369,6 +405,7 @@ public:
     /// (in microseconds)
     /// (in microseconds)
     ///
     ///
     /// @throw isc::BadValue if timeout_usec is greater than one million
     /// @throw isc::BadValue if timeout_usec is greater than one million
+    /// @throw isc::dhcp::SocketReadError if error occured when receiving a packet.
     /// @return Pkt6 object representing received packet (or NULL)
     /// @return Pkt6 object representing received packet (or NULL)
     Pkt6Ptr receive6(uint32_t timeout_sec, uint32_t timeout_usec = 0);
     Pkt6Ptr receive6(uint32_t timeout_sec, uint32_t timeout_usec = 0);
 
 
@@ -383,6 +420,7 @@ public:
     /// (in microseconds)
     /// (in microseconds)
     ///
     ///
     /// @throw isc::BadValue if timeout_usec is greater than one million
     /// @throw isc::BadValue if timeout_usec is greater than one million
+    /// @throw isc::dhcp::SocketReadError if error occured when receiving a packet.
     /// @return Pkt4 object representing received packet (or NULL)
     /// @return Pkt4 object representing received packet (or NULL)
     Pkt4Ptr receive4(uint32_t timeout_sec, uint32_t timeout_usec = 0);
     Pkt4Ptr receive4(uint32_t timeout_sec, uint32_t timeout_usec = 0);
 
 
@@ -460,6 +498,7 @@ public:
     ///
     ///
     /// @param port specifies port number (usually DHCP6_SERVER_PORT)
     /// @param port specifies port number (usually DHCP6_SERVER_PORT)
     ///
     ///
+    /// @throw SocketOpenFailure if tried and failed to open socket.
     /// @return true if any sockets were open
     /// @return true if any sockets were open
     bool openSockets6(const uint16_t port = DHCP6_SERVER_PORT);
     bool openSockets6(const uint16_t port = DHCP6_SERVER_PORT);
 
 
@@ -472,6 +511,7 @@ public:
     ///
     ///
     /// @param port specifies port number (usually DHCP4_SERVER_PORT)
     /// @param port specifies port number (usually DHCP4_SERVER_PORT)
     ///
     ///
+    /// @throw SocketOpenFailure if tried and failed to open socket.
     /// @return true if any sockets were open
     /// @return true if any sockets were open
     bool openSockets4(const uint16_t port = DHCP4_SERVER_PORT);
     bool openSockets4(const uint16_t port = DHCP4_SERVER_PORT);
 
 

+ 1 - 8
src/lib/dhcp/iface_mgr_linux.cc

@@ -417,8 +417,6 @@ namespace dhcp {
 /// Uses the socket-based netlink protocol to retrieve the list of interfaces
 /// Uses the socket-based netlink protocol to retrieve the list of interfaces
 /// from the Linux kernel.
 /// from the Linux kernel.
 void IfaceMgr::detectIfaces() {
 void IfaceMgr::detectIfaces() {
-    cout << "Linux: detecting interfaces." << endl;
-
     // Copies of netlink messages about links will be stored here.
     // Copies of netlink messages about links will be stored here.
     Netlink::NetlinkMessages link_info;
     Netlink::NetlinkMessages link_info;
 
 
@@ -495,8 +493,6 @@ void IfaceMgr::detectIfaces() {
 
 
     nl.release_list(link_info);
     nl.release_list(link_info);
     nl.release_list(addr_info);
     nl.release_list(addr_info);
-
-    printIfaces();
 }
 }
 
 
 /// @brief sets flag_*_ fields.
 /// @brief sets flag_*_ fields.
@@ -558,10 +554,7 @@ bool IfaceMgr::os_receive4(struct msghdr& m, Pkt4Ptr& pkt) {
             // broadcast. This will return broadcast address, not
             // broadcast. This will return broadcast address, not
             // the address we are bound to.
             // the address we are bound to.
 
 
-            // IOAddress tmp(htonl(pktinfo->ipi_spec_dst.s_addr));
-            // cout << "The other addr is: " << tmp.toText() << endl;
-
-            // Perhaps we should uncomment this:
+            // XXX: Perhaps we should uncomment this:
             // to_addr = pktinfo->ipi_spec_dst;
             // to_addr = pktinfo->ipi_spec_dst;
         }
         }
         cmsg = CMSG_NXTHDR(&m, cmsg);
         cmsg = CMSG_NXTHDR(&m, cmsg);

+ 4 - 13
src/lib/dhcp/libdhcp++.cc

@@ -72,26 +72,23 @@ size_t LibDHCP::unpackOptions6(const OptionBuffer& buf,
         offset += 2;
         offset += 2;
 
 
         if (offset + opt_len > end) {
         if (offset + opt_len > end) {
-            cout << "Option " << opt_type << " truncated." << endl;
+            // @todo: consider throwing exception here.
             return (offset);
             return (offset);
         }
         }
         OptionPtr opt;
         OptionPtr opt;
         switch (opt_type) {
         switch (opt_type) {
         case D6O_IA_NA:
         case D6O_IA_NA:
         case D6O_IA_PD:
         case D6O_IA_PD:
-            // cout << "Creating Option6IA" << endl;
             opt = OptionPtr(new Option6IA(opt_type,
             opt = OptionPtr(new Option6IA(opt_type,
                                           buf.begin() + offset,
                                           buf.begin() + offset,
                                           buf.begin() + offset + opt_len));
                                           buf.begin() + offset + opt_len));
             break;
             break;
         case D6O_IAADDR:
         case D6O_IAADDR:
-            // cout << "Creating Option6IAAddr" << endl;
             opt = OptionPtr(new Option6IAAddr(opt_type,
             opt = OptionPtr(new Option6IAAddr(opt_type,
                                               buf.begin() + offset,
                                               buf.begin() + offset,
                                               buf.begin() + offset + opt_len));
                                               buf.begin() + offset + opt_len));
             break;
             break;
         default:
         default:
-            // cout << "Creating Option" << endl;
             opt = OptionPtr(new Option(Option::V6,
             opt = OptionPtr(new Option(Option::V6,
                                        opt_type,
                                        opt_type,
                                        buf.begin() + offset,
                                        buf.begin() + offset,
@@ -151,15 +148,9 @@ size_t LibDHCP::unpackOptions4(const OptionBuffer& buf,
 
 
 void LibDHCP::packOptions6(isc::util::OutputBuffer &buf,
 void LibDHCP::packOptions6(isc::util::OutputBuffer &buf,
                            const isc::dhcp::Option::OptionCollection& options) {
                            const isc::dhcp::Option::OptionCollection& options) {
-    try {
-        for (Option::OptionCollection::const_iterator it = options.begin();
-             it != options.end(); ++it) {
-            it->second->pack(buf);
-        }
-    }
-    catch (const Exception&) {
-        cout << "Packet build failed (Option build failed)." << endl;
-        throw;
+    for (Option::OptionCollection::const_iterator it = options.begin();
+         it != options.end(); ++it) {
+        it->second->pack(buf);
     }
     }
 }
 }
 
 

+ 0 - 2
src/lib/dhcp/pkt4.cc

@@ -197,8 +197,6 @@ void Pkt4::check() {
 }
 }
 
 
 void Pkt4::repack() {
 void Pkt4::repack() {
-    cout << "Convering RX packet to TX packet: " << data_.size() << " bytes." << endl;
-
     bufferOut_.writeData(&data_[0], data_.size());
     bufferOut_.writeData(&data_[0], data_.size());
 }
 }
 
 

+ 4 - 6
src/lib/dhcp/pkt6.cc

@@ -100,7 +100,7 @@ Pkt6::packUDP() {
         LibDHCP::packOptions6(bufferOut_, options_);
         LibDHCP::packOptions6(bufferOut_, options_);
     }
     }
     catch (const Exception& e) {
     catch (const Exception& e) {
-        cout << "Packet build failed:" << e.what() << endl;
+        /// @todo: throw exception here once we turn this function to void.
         return (false);
         return (false);
     }
     }
     return (true);
     return (true);
@@ -129,8 +129,8 @@ Pkt6::unpack() {
 bool
 bool
 Pkt6::unpackUDP() {
 Pkt6::unpackUDP() {
     if (data_.size() < 4) {
     if (data_.size() < 4) {
-        std::cout << "DHCPv6 packet truncated. Only " << data_.size()
-                  << " bytes. Need at least 4." << std::endl;
+        // @todo: throw exception here informing that packet is truncated
+        // once we turn this function to void.
         return (false);
         return (false);
     }
     }
     msg_type_ = data_[0];
     msg_type_ = data_[0];
@@ -143,7 +143,7 @@ Pkt6::unpackUDP() {
 
 
         LibDHCP::unpackOptions6(opt_buffer, options_);
         LibDHCP::unpackOptions6(opt_buffer, options_);
     } catch (const Exception& e) {
     } catch (const Exception& e) {
-        cout << "Packet parsing failed:" << e.what() << endl;
+        // @todo: throw exception here once we turn this function to void.
         return (false);
         return (false);
     }
     }
     return (true);
     return (true);
@@ -197,8 +197,6 @@ Pkt6::delOption(uint16_t type) {
 }
 }
 
 
 void Pkt6::repack() {
 void Pkt6::repack() {
-    cout << "Convering RX packet to TX packet: " << data_.size() << " bytes." << endl;
-
     bufferOut_.writeData(&data_[0], data_.size());
     bufferOut_.writeData(&data_[0], data_.size());
 }
 }
 
 

+ 66 - 19
src/lib/dhcp/tests/iface_mgr_unittest.cc

@@ -82,10 +82,8 @@ TEST_F(IfaceMgrTest, loDetect) {
     // it will go away as soon as proper interface detection
     // it will go away as soon as proper interface detection
     // is implemented
     // is implemented
     if (if_nametoindex("lo") > 0) {
     if (if_nametoindex("lo") > 0) {
-        cout << "This is Linux, using lo as loopback." << endl;
         snprintf(LOOPBACK, BUF_SIZE - 1, "lo");
         snprintf(LOOPBACK, BUF_SIZE - 1, "lo");
     } else if (if_nametoindex("lo0") > 0) {
     } else if (if_nametoindex("lo0") > 0) {
-        cout << "This is BSD, using lo0 as loopback." << endl;
         snprintf(LOOPBACK, BUF_SIZE - 1, "lo0");
         snprintf(LOOPBACK, BUF_SIZE - 1, "lo0");
     } else {
     } else {
         cout << "Failed to detect loopback interface. Neither "
         cout << "Failed to detect loopback interface. Neither "
@@ -421,7 +419,7 @@ TEST_F(IfaceMgrTest, sockets6) {
     // testing socket operation in a portable way is tricky
     // testing socket operation in a portable way is tricky
     // without interface detection implemented
     // without interface detection implemented
 
 
-    NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
+    boost::scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
 
 
     IOAddress loAddr("::1");
     IOAddress loAddr("::1");
 
 
@@ -441,10 +439,25 @@ TEST_F(IfaceMgrTest, sockets6) {
     // removed code for binding socket twice to the same address/port
     // removed code for binding socket twice to the same address/port
     // as it caused problems on some platforms (e.g. Mac OS X)
     // as it caused problems on some platforms (e.g. Mac OS X)
 
 
-    close(socket1);
-    close(socket2);
+    // Close sockets here because the following tests will want to
+    // open sockets on the same ports.
+    ifacemgr->closeSockets();
 
 
-    delete ifacemgr;
+    // Use address that is not assigned to LOOPBACK iface.
+    IOAddress invalidAddr("::2");
+    EXPECT_THROW(
+        ifacemgr->openSocket(LOOPBACK, invalidAddr, 10547),
+        SocketConfigError
+    );
+
+    // Use non-existing interface name.
+    EXPECT_THROW(
+        ifacemgr->openSocket("non_existing_interface", loAddr, 10548),
+        BadValue
+    );
+
+    // Do not call closeSockets() because it is called by IfaceMgr's
+    // virtual destructor.
 }
 }
 
 
 TEST_F(IfaceMgrTest, socketsFromIface) {
 TEST_F(IfaceMgrTest, socketsFromIface) {
@@ -468,6 +481,18 @@ TEST_F(IfaceMgrTest, socketsFromIface) {
     EXPECT_GT(socket2, 0);
     EXPECT_GT(socket2, 0);
     close(socket2);
     close(socket2);
 
 
+    // Close sockets here because the following tests will want to
+    // open sockets on the same ports.
+    ifacemgr->closeSockets();
+
+    // Use invalid interface name.
+    EXPECT_THROW(
+        ifacemgr->openSocketFromIface("non_existing_interface", PORT1, AF_INET),
+        BadValue
+    );
+
+    // Do not call closeSockets() because it is called by IfaceMgr's
+    // virtual destructor.
 }
 }
 
 
 
 
@@ -482,7 +507,6 @@ TEST_F(IfaceMgrTest, socketsFromAddress) {
     );
     );
     // socket descriptor must be positive integer
     // socket descriptor must be positive integer
     EXPECT_GT(socket1, 0);
     EXPECT_GT(socket1, 0);
-    close(socket1);
 
 
     // Open v4 socket on loopback interface and bind to different port
     // Open v4 socket on loopback interface and bind to different port
     int socket2 = 0;
     int socket2 = 0;
@@ -492,7 +516,19 @@ TEST_F(IfaceMgrTest, socketsFromAddress) {
     );
     );
     // socket descriptor must be positive integer
     // socket descriptor must be positive integer
     EXPECT_GT(socket2, 0);
     EXPECT_GT(socket2, 0);
-    close(socket2);
+
+    // Close sockets here because the following tests will want to
+    // open sockets on the same ports.
+    ifacemgr->closeSockets();
+
+    // Use non-existing address.
+    IOAddress invalidAddr("1.2.3.4");
+    EXPECT_THROW(
+        ifacemgr->openSocketFromAddress(invalidAddr, PORT1), BadValue
+    );
+
+    // Do not call closeSockets() because it is called by IfaceMgr's
+    // virtual destructor.
 }
 }
 
 
 TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
 TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
@@ -507,7 +543,6 @@ TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
         socket1 = ifacemgr->openSocketFromRemoteAddress(loAddr6, PORT1);
         socket1 = ifacemgr->openSocketFromRemoteAddress(loAddr6, PORT1);
     );
     );
     EXPECT_GT(socket1, 0);
     EXPECT_GT(socket1, 0);
-    close(socket1);
 
 
     // Open v4 socket to connect to remote address.
     // Open v4 socket to connect to remote address.
     int socket2 = 0;
     int socket2 = 0;
@@ -516,7 +551,10 @@ TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
         socket2 = ifacemgr->openSocketFromRemoteAddress(loAddr, PORT2);
         socket2 = ifacemgr->openSocketFromRemoteAddress(loAddr, PORT2);
     );
     );
     EXPECT_GT(socket2, 0);
     EXPECT_GT(socket2, 0);
-    close(socket2);
+
+    // Close sockets here because the following tests will want to
+    // open sockets on the same ports.
+    ifacemgr->closeSockets();
 
 
     // The following test is currently disabled for OSes other than
     // The following test is currently disabled for OSes other than
     // Linux because interface detection is not implemented on them.
     // Linux because interface detection is not implemented on them.
@@ -530,8 +568,10 @@ TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
         socket3 = ifacemgr->openSocketFromRemoteAddress(bcastAddr, PORT2);
         socket3 = ifacemgr->openSocketFromRemoteAddress(bcastAddr, PORT2);
     );
     );
     EXPECT_GT(socket3, 0);
     EXPECT_GT(socket3, 0);
-    close(socket3);
 #endif
 #endif
+
+    // Do not call closeSockets() because it is called by IfaceMgr's
+    // virtual destructor.
 }
 }
 
 
 // TODO: disabled due to other naming on various systems
 // TODO: disabled due to other naming on various systems
@@ -570,7 +610,7 @@ TEST_F(IfaceMgrTest, sendReceive6) {
     // testing socket operation in a portable way is tricky
     // testing socket operation in a portable way is tricky
     // without interface detection implemented
     // without interface detection implemented
 
 
-    NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
+    boost::scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
 
 
     // let's assume that every supported OS have lo interface
     // let's assume that every supported OS have lo interface
     IOAddress loAddr("::1");
     IOAddress loAddr("::1");
@@ -619,7 +659,11 @@ TEST_F(IfaceMgrTest, sendReceive6) {
     // we should accept both values as source ports.
     // we should accept both values as source ports.
     EXPECT_TRUE((rcvPkt->getRemotePort() == 10546) || (rcvPkt->getRemotePort() == 10547));
     EXPECT_TRUE((rcvPkt->getRemotePort() == 10546) || (rcvPkt->getRemotePort() == 10547));
 
 
-    delete ifacemgr;
+    // try to send/receive data over the closed socket. Closed socket's descriptor is
+    // still being hold by IfaceMgr which will try to use it to receive data.
+    close(socket1);
+    EXPECT_THROW(ifacemgr->receive6(10), SocketReadError);
+    EXPECT_THROW(ifacemgr->send(sendPkt), SocketWriteError);
 }
 }
 
 
 TEST_F(IfaceMgrTest, sendReceive4) {
 TEST_F(IfaceMgrTest, sendReceive4) {
@@ -627,7 +671,7 @@ TEST_F(IfaceMgrTest, sendReceive4) {
     // testing socket operation in a portable way is tricky
     // testing socket operation in a portable way is tricky
     // without interface detection implemented
     // without interface detection implemented
 
 
-    NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
+    boost::scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
 
 
     // let's assume that every supported OS have lo interface
     // let's assume that every supported OS have lo interface
     IOAddress loAddr("127.0.0.1");
     IOAddress loAddr("127.0.0.1");
@@ -675,8 +719,7 @@ TEST_F(IfaceMgrTest, sendReceive4) {
 
 
     EXPECT_EQ(true, ifacemgr->send(sendPkt));
     EXPECT_EQ(true, ifacemgr->send(sendPkt));
 
 
-    rcvPkt = ifacemgr->receive4(10);
-
+    ASSERT_NO_THROW(rcvPkt = ifacemgr->receive4(10));
     ASSERT_TRUE(rcvPkt); // received our own packet
     ASSERT_TRUE(rcvPkt); // received our own packet
 
 
     ASSERT_NO_THROW(
     ASSERT_NO_THROW(
@@ -710,7 +753,11 @@ TEST_F(IfaceMgrTest, sendReceive4) {
     // assume the one or the other will always be choosen for sending data. We should
     // assume the one or the other will always be choosen for sending data. We should
     // skip checking source port of sent address.
     // skip checking source port of sent address.
 
 
-    delete ifacemgr;
+    // try to receive data over the closed socket. Closed socket's descriptor is
+    // still being hold by IfaceMgr which will try to use it to receive data.
+    close(socket1);
+    EXPECT_THROW(ifacemgr->receive4(10), SocketReadError);
+    EXPECT_THROW(ifacemgr->send(sendPkt), SocketWriteError);
 }
 }
 
 
 
 
@@ -1214,7 +1261,7 @@ TEST_F(IfaceMgrTest, controlSession) {
     EXPECT_NO_THROW(ifacemgr->set_session_socket(pipefd[0], my_callback));
     EXPECT_NO_THROW(ifacemgr->set_session_socket(pipefd[0], my_callback));
 
 
     Pkt4Ptr pkt4;
     Pkt4Ptr pkt4;
-    pkt4 = ifacemgr->receive4(1);
+    ASSERT_NO_THROW(pkt4 = ifacemgr->receive4(1));
 
 
     // Our callback should not be called this time (there was no data)
     // Our callback should not be called this time (there was no data)
     EXPECT_FALSE(callback_ok);
     EXPECT_FALSE(callback_ok);
@@ -1226,7 +1273,7 @@ TEST_F(IfaceMgrTest, controlSession) {
     EXPECT_EQ(38, write(pipefd[1], "Hi, this is a message sent over a pipe", 38));
     EXPECT_EQ(38, write(pipefd[1], "Hi, this is a message sent over a pipe", 38));
 
 
     // ... and repeat
     // ... and repeat
-    pkt4 = ifacemgr->receive4(1);
+    ASSERT_NO_THROW(pkt4 = ifacemgr->receive4(1));
 
 
     // IfaceMgr should not process control socket data as incoming packets
     // IfaceMgr should not process control socket data as incoming packets
     EXPECT_FALSE(pkt4);
     EXPECT_FALSE(pkt4);

+ 14 - 2
tests/tools/perfdhcp/test_control.cc

@@ -980,7 +980,13 @@ TestControl::receivePackets(const TestControlSocket& socket) {
     uint64_t received = 0;
     uint64_t received = 0;
     while (receiving) {
     while (receiving) {
         if (CommandOptions::instance().getIpVersion() == 4) {
         if (CommandOptions::instance().getIpVersion() == 4) {
-            Pkt4Ptr pkt4 = IfaceMgr::instance().receive4(timeout);
+            Pkt4Ptr pkt4;
+            try {
+                pkt4 = IfaceMgr::instance().receive4(timeout);
+            } catch (const Exception& e) {
+                std::cerr << "Failed to receive DHCPv4 packet: "
+                          << e.what() <<  std::endl;
+            }
             if (!pkt4) {
             if (!pkt4) {
                 receiving = false;
                 receiving = false;
             } else {
             } else {
@@ -992,7 +998,13 @@ TestControl::receivePackets(const TestControlSocket& socket) {
                 processReceivedPacket4(socket, pkt4);
                 processReceivedPacket4(socket, pkt4);
             }
             }
         } else if (CommandOptions::instance().getIpVersion() == 6) {
         } else if (CommandOptions::instance().getIpVersion() == 6) {
-            Pkt6Ptr pkt6 = IfaceMgr::instance().receive6(timeout);
+            Pkt6Ptr pkt6;
+            try {
+                pkt6 = IfaceMgr::instance().receive6(timeout);
+            } catch (const Exception& e) {
+                std::cerr << "Failed to receive DHCPv6 packet: "
+                          << e.what() << std::endl;
+            }
             if (!pkt6) {
             if (!pkt6) {
                 receiving  = false;
                 receiving  = false;
             } else {
             } else {

+ 16 - 0
tests/tools/perfdhcp/test_control.h

@@ -633,8 +633,10 @@ protected:
     ///
     ///
     /// \param socket socket to be used to send the message.
     /// \param socket socket to be used to send the message.
     /// \param preload preload mode, packets not included in statistics.
     /// \param preload preload mode, packets not included in statistics.
+    ///
     /// \throw isc::Unexpected if failed to create new packet instance.
     /// \throw isc::Unexpected if failed to create new packet instance.
     /// \throw isc::BadValue if MAC address has invalid length.
     /// \throw isc::BadValue if MAC address has invalid length.
+    /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
     void sendDiscover4(const TestControlSocket& socket,
     void sendDiscover4(const TestControlSocket& socket,
                        const bool preload = false);
                        const bool preload = false);
 
 
@@ -650,7 +652,9 @@ protected:
     /// \param socket socket to be used to send the message.
     /// \param socket socket to be used to send the message.
     /// \param template_buf buffer holding template packet.
     /// \param template_buf buffer holding template packet.
     /// \param preload preload mode, packets not included in statistics.
     /// \param preload preload mode, packets not included in statistics.
+    ///
     /// \throw isc::OutOfRange if randomization offset is out of bounds.
     /// \throw isc::OutOfRange if randomization offset is out of bounds.
+    /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
     void sendDiscover4(const TestControlSocket& socket,
     void 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);
@@ -689,9 +693,11 @@ protected:
     /// \param socket socket to be used to send message.
     /// \param socket socket to be used to send message.
     /// \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 occured.
     /// \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.
     void sendRequest4(const TestControlSocket& socket,
     void sendRequest4(const TestControlSocket& socket,
                       const dhcp::Pkt4Ptr& discover_pkt4,
                       const dhcp::Pkt4Ptr& discover_pkt4,
                       const dhcp::Pkt4Ptr& offer_pkt4);
                       const dhcp::Pkt4Ptr& offer_pkt4);
@@ -706,6 +712,8 @@ protected:
     /// \param template_buf buffer holding template packet.
     /// \param template_buf buffer holding template packet.
     /// \param discover_pkt4 DISCOVER packet sent.
     /// \param discover_pkt4 DISCOVER packet sent.
     /// \param offer_pkt4 OFFER packet received.
     /// \param offer_pkt4 OFFER packet received.
+    ///
+    /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
     void sendRequest4(const TestControlSocket& socket,
     void sendRequest4(const TestControlSocket& socket,
                       const std::vector<uint8_t>& template_buf,
                       const std::vector<uint8_t>& template_buf,
                       const dhcp::Pkt4Ptr& discover_pkt4,
                       const dhcp::Pkt4Ptr& discover_pkt4,
@@ -726,6 +734,8 @@ protected:
     /// \throw isc::Unexpected if unexpected error occured.
     /// \throw isc::Unexpected if unexpected error occured.
     /// \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.
     void sendRequest6(const TestControlSocket& socket,
     void sendRequest6(const TestControlSocket& socket,
                       const dhcp::Pkt6Ptr& advertise_pkt6);
                       const dhcp::Pkt6Ptr& advertise_pkt6);
 
 
@@ -738,6 +748,8 @@ protected:
     /// \param socket socket to be used to send message.
     /// \param socket socket to be used to send message.
     /// \param template_buf packet template buffer.
     /// \param template_buf packet template buffer.
     /// \param advertise_pkt6 ADVERTISE packet object.
     /// \param advertise_pkt6 ADVERTISE packet object.
+    ///
+    /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
     void sendRequest6(const TestControlSocket& socket,
     void sendRequest6(const TestControlSocket& socket,
                       const std::vector<uint8_t>& template_buf,
                       const std::vector<uint8_t>& template_buf,
                       const dhcp::Pkt6Ptr& advertise_pkt6);
                       const dhcp::Pkt6Ptr& advertise_pkt6);
@@ -756,7 +768,9 @@ protected:
     ///
     ///
     /// \param socket socket to be used to send the message.
     /// \param socket socket to be used to send the message.
     /// \param preload mode, packets not included in statistics.
     /// \param preload mode, packets not included in statistics.
+    ///
     /// \throw isc::Unexpected if failed to create new packet instance.
     /// \throw isc::Unexpected if failed to create new packet instance.
+    /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
     void sendSolicit6(const TestControlSocket& socket,
     void sendSolicit6(const TestControlSocket& socket,
                       const bool preload = false);
                       const bool preload = false);
 
 
@@ -769,6 +783,8 @@ protected:
     /// \param socket socket to be used to send the message.
     /// \param socket socket to be used to send the message.
     /// \param template_buf packet template buffer.
     /// \param template_buf packet template buffer.
     /// \param preload mode, packets not included in statistics.
     /// \param preload mode, packets not included in statistics.
+    ///
+    /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
     void sendSolicit6(const TestControlSocket& socket,
     void sendSolicit6(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);