BIND 10 master, updated. f142802acfd65bb9cd993a254a99ff34ef731573 [master] Merge branch 'trac2187'
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Sep 26 15:16:45 UTC 2012
The branch, master has been updated
via f142802acfd65bb9cd993a254a99ff34ef731573 (commit)
via dfc79b64ed8fdf77c46ebea1e025e229b7497a60 (commit)
via 64e40094a730e99da4b24bbe97cb346af7b8fbcd (commit)
via 02dd6ed0dd458e7627e06bcab6a5168354e929d6 (commit)
via bbf34f3ba16d91fabcfa53a5b989e999d9c19875 (commit)
via 237def8395cbe9f2d1193e804443c403294b8c6f (commit)
via 1a7e6f8b2d18a98bfac5f4a47f55f8f288e4d0ab (commit)
via 79848f3dcca94147df133b8969c5c1aa0fddc299 (commit)
via 26f07019946b185e191ce7490f4c398b830f8420 (commit)
via 5633225648b2a4a5582327131f9ca7a7d83b340f (commit)
via 8a1be35939e817930570e4afc76af240e78c2602 (commit)
via 1f486ccd690d8267b0a4410d8163298c5f5cf1ef (commit)
via d863d2f26c9e2fb9a866d56de15723cfd5a9e58b (commit)
from 2adcf03734b609514a665ce58315e71ddb110eb5 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit f142802acfd65bb9cd993a254a99ff34ef731573
Merge: 2adcf03 dfc79b6
Author: Marcin Siodelski <marcin at isc.org>
Date: Wed Sep 26 17:14:53 2012 +0200
[master] Merge branch 'trac2187'
-----------------------------------------------------------------------
Summary of changes:
src/bin/dhcp4/dhcp4_messages.mes | 10 ++
src/bin/dhcp4/dhcp4_srv.cc | 14 +-
src/bin/dhcp6/dhcp6_messages.mes | 10 ++
src/bin/dhcp6/dhcp6_srv.cc | 14 +-
src/lib/dhcp/iface_mgr.cc | 234 ++++++++----------------------
src/lib/dhcp/iface_mgr.h | 40 +++++
src/lib/dhcp/iface_mgr_linux.cc | 9 +-
src/lib/dhcp/libdhcp++.cc | 17 +--
src/lib/dhcp/pkt4.cc | 2 -
src/lib/dhcp/pkt6.cc | 10 +-
src/lib/dhcp/tests/iface_mgr_unittest.cc | 85 ++++++++---
tests/tools/perfdhcp/test_control.cc | 16 +-
tests/tools/perfdhcp/test_control.h | 16 ++
13 files changed, 253 insertions(+), 224 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/dhcp4/dhcp4_messages.mes b/src/bin/dhcp4/dhcp4_messages.mes
index 98e402d..63ddbfc 100644
--- a/src/bin/dhcp4/dhcp4_messages.mes
+++ b/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
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
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
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).
+% 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
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
diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc
index 2bbc075..67943c5 100644
--- a/src/bin/dhcp4/dhcp4_srv.cc
+++ b/src/bin/dhcp4/dhcp4_srv.cc
@@ -73,9 +73,15 @@ Dhcpv4Srv::run() {
int timeout = 1000;
// client's message and server's response
- Pkt4Ptr query = IfaceMgr::instance().receive4(timeout);
+ Pkt4Ptr query;
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) {
try {
query->unpack();
@@ -141,7 +147,11 @@ Dhcpv4Srv::run() {
.arg(rsp->getType()).arg(rsp->toText());
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 {
LOG_ERROR(dhcp4_logger, DHCP4_PACK_FAIL);
}
diff --git a/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes
index a361531..1564940 100644
--- a/src/bin/dhcp6/dhcp6_messages.mes
+++ b/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
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
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
DHCP packet, just a type not expected by the server (e.g. it will report
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
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
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index 7c21941..54fa2b5 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -84,9 +84,15 @@ bool Dhcpv6Srv::run() {
int timeout = 1000;
// client's message and server's response
- Pkt6Ptr query = IfaceMgr::instance().receive6(timeout);
+ Pkt6Ptr query;
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->unpack()) {
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL,
@@ -154,7 +160,11 @@ bool Dhcpv6Srv::run() {
.arg(rsp->getType()).arg(rsp->toText());
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 {
LOG_ERROR(dhcp6_logger, DHCP6_PACK_FAIL);
}
diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc
index 1ff2fc6..ecaa652 100644
--- a/src/lib/dhcp/iface_mgr.cc
+++ b/src/lib/dhcp/iface_mgr.cc
@@ -122,8 +122,6 @@ IfaceMgr::IfaceMgr()
session_socket_(INVALID_SOCKET), session_callback_(NULL)
{
- cout << "IfaceMgr initialization." << endl;
-
try {
// required for sending/receiving packets
// let's keep it in front, just in case someone
@@ -134,13 +132,7 @@ IfaceMgr::IfaceMgr()
detectIfaces();
} 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
// 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) {
@@ -221,13 +196,9 @@ bool IfaceMgr::openSockets4(const uint16_t port) {
iface != ifaces_.end();
++iface) {
- cout << "Trying opening socket on interface " << iface->getFullName() << endl;
-
if (iface->flag_loopback_ ||
!iface->flag_up_ ||
!iface->flag_running_) {
- cout << "Interface " << iface->getFullName()
- << " not suitable: is loopback, is down or not running" << endl;
continue;
}
@@ -243,15 +214,13 @@ bool IfaceMgr::openSockets4(const uint16_t port) {
sock = openSocket(iface->getName(), *addr, port);
if (sock < 0) {
- cout << "Failed to open unicast socket." << endl;
- return (false);
+ isc_throw(SocketConfigError, "failed to open unicast socket");
}
count++;
}
}
return (count > 0);
-
}
bool IfaceMgr::openSockets6(const uint16_t port) {
@@ -280,8 +249,7 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
sock = openSocket(iface->getName(), *addr, port);
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
@@ -290,7 +258,8 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
if ( !joinMulticast(sock, iface->getName(),
string(ALL_DHCP_RELAY_AGENTS_AND_SERVERS))) {
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.");
}
@@ -305,7 +274,7 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
IOAddress(ALL_DHCP_RELAY_AGENTS_AND_SERVERS),
port);
if (sock2 < 0) {
- isc_throw(Unexpected, "Failed to open multicast socket on "
+ isc_throw(SocketConfigError, "Failed to open multicast socket on "
<< " interface " << iface->getFullName());
iface->delSocket(sock); // delete previously opened socket
}
@@ -418,7 +387,7 @@ int IfaceMgr::openSocketFromIface(const std::string& ifname,
family_name = "AF_INET6";
}
// 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 "
" family: " << family_name);
}
@@ -460,9 +429,13 @@ int IfaceMgr::openSocketFromAddress(const IOAddress& addr,
int IfaceMgr::openSocketFromRemoteAddress(const IOAddress& remote_addr,
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
@@ -506,7 +479,7 @@ IfaceMgr::getLocalAddress(const IOAddress& remote_addr, const uint16_t port) {
sock.connect(remote_endpoint->getASIOEndpoint(), err_code);
if (err_code) {
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.
@@ -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) {
- cout << "Creating UDP4 socket on " << iface.getFullName()
- << " " << addr.toText() << "/port=" << port << endl;
-
struct sockaddr_in addr4;
memset(&addr4, 0, sizeof(sockaddr));
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);
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) {
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);
}
@@ -552,13 +522,10 @@ int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port) {
int flag = 1;
if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &flag, sizeof(flag)) != 0) {
close(sock);
- isc_throw(Unexpected, "setsockopt: IP_PKTINFO: failed.");
+ isc_throw(SocketConfigError, "setsockopt: IP_PKTINFO: failed.");
}
#endif
- cout << "Created socket " << sock << " on " << iface.getName() << "/" <<
- addr.toText() << "/port=" << port << endl;
-
SocketInfo info(sock, addr, port);
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) {
- cout << "Creating UDP6 socket on " << iface.getFullName()
- << " " << addr.toText() << "/port=" << port << endl;
-
struct sockaddr_in6 addr6;
memset(&addr6, 0, sizeof(addr6));
addr6.sin6_family = AF_INET6;
@@ -590,7 +554,7 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
// make a socket
int sock = socket(AF_INET6, SOCK_DGRAM, 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
@@ -599,12 +563,12 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char *)&flag, sizeof(flag)) < 0) {
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) {
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);
}
#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,
&flag, sizeof(flag)) != 0) {
close(sock);
- isc_throw(Unexpected, "setsockopt: IPV6_RECVPKTINFO failed.");
+ isc_throw(SocketConfigError, "setsockopt: IPV6_RECVPKTINFO failed.");
}
#else
// RFC2292 - an old way
if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO,
&flag, sizeof(flag)) != 0) {
close(sock);
- isc_throw(Unexpected, "setsockopt: IPV6_PKTINFO: failed.");
+ isc_throw(SocketConfigError, "setsockopt: IPV6_PKTINFO: failed.");
}
#endif
@@ -632,14 +596,11 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
if ( !joinMulticast( sock, iface.getName(),
string(ALL_DHCP_RELAY_AGENTS_AND_SERVERS) ) ) {
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.");
}
}
- cout << "Created socket " << sock << " on " << iface.getName() << "/" <<
- addr.toText() << "/port=" << port << endl;
-
SocketInfo info(sock, addr, port);
iface.addSocket(info);
@@ -654,20 +615,15 @@ const std::string & mcast) {
if (inet_pton(AF_INET6, mcast.c_str(),
&mreq.ipv6mr_multiaddr) <= 0) {
- cout << "Failed to convert " << ifname
- << " to IPv6 multicast address." << endl;
return (false);
}
mreq.ipv6mr_interface = if_nametoindex(ifname.c_str());
if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
&mreq, sizeof(mreq)) < 0) {
- cout << "Failed to join " << mcast << " multicast group." << endl;
return (false);
}
- cout << "Joined multicast " << mcast << " group." << endl;
-
return (true);
}
@@ -746,13 +702,8 @@ IfaceMgr::send(const Pkt6Ptr& pkt) {
result = sendmsg(getSocket(*pkt), &m, 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);
}
@@ -797,24 +748,13 @@ IfaceMgr::send(const Pkt4Ptr& pkt)
// call OS-specific routines (like setting interface index)
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();
int result = sendmsg(getSocket(*pkt), &m, 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);
}
@@ -869,27 +809,18 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
select_timeout.tv_sec = timeout_sec;
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);
- cout << "select returned " << result << endl;
if (result == 0) {
// nothing received and timeout has been reached
return (Pkt4Ptr()); // NULL
} 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
if ((session_socket_ != INVALID_SOCKET) && (FD_ISSET(session_socket_, &sockets))) {
// something received over session socket
- cout << "BIND10 command or config available over session socket." << endl;
-
if (session_callback_) {
// in theory we could call io_service.run_one() here, instead of
// implementing callback mechanism, but that would introduce
@@ -918,14 +849,9 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
}
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!
struct sockaddr_in from_addr;
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);
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.
@@ -982,15 +907,9 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
pkt->setLocalPort(candidate->port_);
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);
}
@@ -1039,10 +958,6 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
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;
select_timeout.tv_sec = timeout_sec;
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
return (Pkt6Ptr()); // NULL
} 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
if ((session_socket_ != INVALID_SOCKET) && (FD_ISSET(session_socket_, &sockets))) {
// something received over session socket
- cout << "BIND10 command or config available over session socket." << endl;
-
if (session_callback_) {
// in theory we could call io_service.run_one() here, instead of
// 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) {
- 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!
uint8_t buf[RCVBUFSIZE];
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);
}
if (!found_pktinfo) {
- cout << "Unable to find pktinfo" << endl;
- return (Pkt6Ptr()); // NULL
+ isc_throw(SocketReadError, "unable to find pktinfo");
}
} else {
- cout << "Failed to receive data." << endl;
- return (Pkt6Ptr()); // NULL
+ isc_throw(SocketReadError, "failed to receive data");
}
// Let's create a packet.
@@ -1176,8 +1079,7 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
try {
pkt = Pkt6Ptr(new Pkt6(buf, result));
} 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();
@@ -1193,18 +1095,10 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
if (received) {
pkt->setIface(received->getName());
} 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);
}
diff --git a/src/lib/dhcp/iface_mgr.h b/src/lib/dhcp/iface_mgr.h
index 98ce672..a7b9a78 100644
--- a/src/lib/dhcp/iface_mgr.h
+++ b/src/lib/dhcp/iface_mgr.h
@@ -28,6 +28,38 @@
namespace isc {
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
///
/// IfaceMgr is an interface manager class that detects available network
@@ -340,6 +372,8 @@ public:
///
/// @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
bool send(const Pkt6Ptr& pkt);
@@ -351,6 +385,8 @@ public:
///
/// @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
bool send(const Pkt4Ptr& pkt);
@@ -369,6 +405,7 @@ public:
/// (in microseconds)
///
/// @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)
Pkt6Ptr receive6(uint32_t timeout_sec, uint32_t timeout_usec = 0);
@@ -383,6 +420,7 @@ public:
/// (in microseconds)
///
/// @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)
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)
///
+ /// @throw SocketOpenFailure if tried and failed to open socket.
/// @return true if any sockets were open
bool openSockets6(const uint16_t port = DHCP6_SERVER_PORT);
@@ -472,6 +511,7 @@ public:
///
/// @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
bool openSockets4(const uint16_t port = DHCP4_SERVER_PORT);
diff --git a/src/lib/dhcp/iface_mgr_linux.cc b/src/lib/dhcp/iface_mgr_linux.cc
index 3c62d72..189fe90 100644
--- a/src/lib/dhcp/iface_mgr_linux.cc
+++ b/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
/// from the Linux kernel.
void IfaceMgr::detectIfaces() {
- cout << "Linux: detecting interfaces." << endl;
-
// Copies of netlink messages about links will be stored here.
Netlink::NetlinkMessages link_info;
@@ -495,8 +493,6 @@ void IfaceMgr::detectIfaces() {
nl.release_list(link_info);
nl.release_list(addr_info);
-
- printIfaces();
}
/// @brief sets flag_*_ fields.
@@ -558,10 +554,7 @@ bool IfaceMgr::os_receive4(struct msghdr& m, Pkt4Ptr& pkt) {
// broadcast. This will return broadcast address, not
// 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;
}
cmsg = CMSG_NXTHDR(&m, cmsg);
diff --git a/src/lib/dhcp/libdhcp++.cc b/src/lib/dhcp/libdhcp++.cc
index 22cd47b..12e1bbd 100644
--- a/src/lib/dhcp/libdhcp++.cc
+++ b/src/lib/dhcp/libdhcp++.cc
@@ -72,26 +72,23 @@ size_t LibDHCP::unpackOptions6(const OptionBuffer& buf,
offset += 2;
if (offset + opt_len > end) {
- cout << "Option " << opt_type << " truncated." << endl;
+ // @todo: consider throwing exception here.
return (offset);
}
OptionPtr opt;
switch (opt_type) {
case D6O_IA_NA:
case D6O_IA_PD:
- // cout << "Creating Option6IA" << endl;
opt = OptionPtr(new Option6IA(opt_type,
buf.begin() + offset,
buf.begin() + offset + opt_len));
break;
case D6O_IAADDR:
- // cout << "Creating Option6IAAddr" << endl;
opt = OptionPtr(new Option6IAAddr(opt_type,
buf.begin() + offset,
buf.begin() + offset + opt_len));
break;
default:
- // cout << "Creating Option" << endl;
opt = OptionPtr(new Option(Option::V6,
opt_type,
buf.begin() + offset,
@@ -151,15 +148,9 @@ size_t LibDHCP::unpackOptions4(const OptionBuffer& buf,
void LibDHCP::packOptions6(isc::util::OutputBuffer &buf,
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);
}
}
diff --git a/src/lib/dhcp/pkt4.cc b/src/lib/dhcp/pkt4.cc
index 2c3f1eb..405277d 100644
--- a/src/lib/dhcp/pkt4.cc
+++ b/src/lib/dhcp/pkt4.cc
@@ -197,8 +197,6 @@ void Pkt4::check() {
}
void Pkt4::repack() {
- cout << "Convering RX packet to TX packet: " << data_.size() << " bytes." << endl;
-
bufferOut_.writeData(&data_[0], data_.size());
}
diff --git a/src/lib/dhcp/pkt6.cc b/src/lib/dhcp/pkt6.cc
index e869c7b..330c97f 100644
--- a/src/lib/dhcp/pkt6.cc
+++ b/src/lib/dhcp/pkt6.cc
@@ -100,7 +100,7 @@ Pkt6::packUDP() {
LibDHCP::packOptions6(bufferOut_, options_);
}
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 (true);
@@ -129,8 +129,8 @@ Pkt6::unpack() {
bool
Pkt6::unpackUDP() {
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);
}
msg_type_ = data_[0];
@@ -143,7 +143,7 @@ Pkt6::unpackUDP() {
LibDHCP::unpackOptions6(opt_buffer, options_);
} 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 (true);
@@ -197,8 +197,6 @@ Pkt6::delOption(uint16_t type) {
}
void Pkt6::repack() {
- cout << "Convering RX packet to TX packet: " << data_.size() << " bytes." << endl;
-
bufferOut_.writeData(&data_[0], data_.size());
}
diff --git a/src/lib/dhcp/tests/iface_mgr_unittest.cc b/src/lib/dhcp/tests/iface_mgr_unittest.cc
index 4fe7e23..2c7b86b 100644
--- a/src/lib/dhcp/tests/iface_mgr_unittest.cc
+++ b/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
// is implemented
if (if_nametoindex("lo") > 0) {
- cout << "This is Linux, using lo as loopback." << endl;
snprintf(LOOPBACK, BUF_SIZE - 1, "lo");
} else if (if_nametoindex("lo0") > 0) {
- cout << "This is BSD, using lo0 as loopback." << endl;
snprintf(LOOPBACK, BUF_SIZE - 1, "lo0");
} else {
cout << "Failed to detect loopback interface. Neither "
@@ -421,7 +419,7 @@ TEST_F(IfaceMgrTest, sockets6) {
// testing socket operation in a portable way is tricky
// without interface detection implemented
- NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
+ boost::scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
IOAddress loAddr("::1");
@@ -441,10 +439,25 @@ TEST_F(IfaceMgrTest, sockets6) {
// removed code for binding socket twice to the same address/port
// 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) {
@@ -468,6 +481,18 @@ TEST_F(IfaceMgrTest, socketsFromIface) {
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 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
EXPECT_GT(socket1, 0);
- close(socket1);
// Open v4 socket on loopback interface and bind to different port
int socket2 = 0;
@@ -492,7 +516,19 @@ TEST_F(IfaceMgrTest, socketsFromAddress) {
);
// socket descriptor must be positive integer
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) {
@@ -507,7 +543,6 @@ TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
socket1 = ifacemgr->openSocketFromRemoteAddress(loAddr6, PORT1);
);
EXPECT_GT(socket1, 0);
- close(socket1);
// Open v4 socket to connect to remote address.
int socket2 = 0;
@@ -516,7 +551,10 @@ TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
socket2 = ifacemgr->openSocketFromRemoteAddress(loAddr, PORT2);
);
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
// Linux because interface detection is not implemented on them.
@@ -530,8 +568,10 @@ TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
socket3 = ifacemgr->openSocketFromRemoteAddress(bcastAddr, PORT2);
);
EXPECT_GT(socket3, 0);
- close(socket3);
#endif
+
+ // Do not call closeSockets() because it is called by IfaceMgr's
+ // virtual destructor.
}
// 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
// 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
IOAddress loAddr("::1");
@@ -619,7 +659,11 @@ TEST_F(IfaceMgrTest, sendReceive6) {
// we should accept both values as source ports.
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) {
@@ -627,7 +671,7 @@ TEST_F(IfaceMgrTest, sendReceive4) {
// testing socket operation in a portable way is tricky
// 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
IOAddress loAddr("127.0.0.1");
@@ -675,8 +719,7 @@ TEST_F(IfaceMgrTest, sendReceive4) {
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_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
// 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));
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)
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));
// ... and repeat
- pkt4 = ifacemgr->receive4(1);
+ ASSERT_NO_THROW(pkt4 = ifacemgr->receive4(1));
// IfaceMgr should not process control socket data as incoming packets
EXPECT_FALSE(pkt4);
diff --git a/tests/tools/perfdhcp/test_control.cc b/tests/tools/perfdhcp/test_control.cc
index b7c3cd6..9376972 100644
--- a/tests/tools/perfdhcp/test_control.cc
+++ b/tests/tools/perfdhcp/test_control.cc
@@ -980,7 +980,13 @@ TestControl::receivePackets(const TestControlSocket& socket) {
uint64_t received = 0;
while (receiving) {
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) {
receiving = false;
} else {
@@ -992,7 +998,13 @@ TestControl::receivePackets(const TestControlSocket& socket) {
processReceivedPacket4(socket, pkt4);
}
} 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) {
receiving = false;
} else {
diff --git a/tests/tools/perfdhcp/test_control.h b/tests/tools/perfdhcp/test_control.h
index 26c0c0b..2bd7871 100644
--- a/tests/tools/perfdhcp/test_control.h
+++ b/tests/tools/perfdhcp/test_control.h
@@ -633,8 +633,10 @@ protected:
///
/// \param socket socket to be used to send the message.
/// \param preload preload mode, packets not included in statistics.
+ ///
/// \throw isc::Unexpected if failed to create new packet instance.
/// \throw isc::BadValue if MAC address has invalid length.
+ /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
void sendDiscover4(const TestControlSocket& socket,
const bool preload = false);
@@ -650,7 +652,9 @@ protected:
/// \param socket socket to be used to send the message.
/// \param template_buf buffer holding template packet.
/// \param preload preload mode, packets not included in statistics.
+ ///
/// \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,
const std::vector<uint8_t>& template_buf,
const bool preload = false);
@@ -689,9 +693,11 @@ protected:
/// \param socket socket to be used to send message.
/// \param discover_pkt4 DISCOVER packet sent.
/// \param offer_pkt4 OFFER packet object.
+ ///
/// \throw isc::Unexpected if unexpected error occured.
/// \throw isc::InvalidOperation if Statistics Manager has not been
/// initialized.
+ /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
void sendRequest4(const TestControlSocket& socket,
const dhcp::Pkt4Ptr& discover_pkt4,
const dhcp::Pkt4Ptr& offer_pkt4);
@@ -706,6 +712,8 @@ protected:
/// \param template_buf buffer holding template packet.
/// \param discover_pkt4 DISCOVER packet sent.
/// \param offer_pkt4 OFFER packet received.
+ ///
+ /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
void sendRequest4(const TestControlSocket& socket,
const std::vector<uint8_t>& template_buf,
const dhcp::Pkt4Ptr& discover_pkt4,
@@ -726,6 +734,8 @@ protected:
/// \throw isc::Unexpected if unexpected error occured.
/// \throw isc::InvalidOperation if Statistics Manager has not been
/// initialized.
+ ///
+ /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
void sendRequest6(const TestControlSocket& socket,
const dhcp::Pkt6Ptr& advertise_pkt6);
@@ -738,6 +748,8 @@ protected:
/// \param socket socket to be used to send message.
/// \param template_buf packet template buffer.
/// \param advertise_pkt6 ADVERTISE packet object.
+ ///
+ /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
void sendRequest6(const TestControlSocket& socket,
const std::vector<uint8_t>& template_buf,
const dhcp::Pkt6Ptr& advertise_pkt6);
@@ -756,7 +768,9 @@ protected:
///
/// \param socket socket to be used to send the message.
/// \param preload mode, packets not included in statistics.
+ ///
/// \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,
const bool preload = false);
@@ -769,6 +783,8 @@ protected:
/// \param socket socket to be used to send the message.
/// \param template_buf packet template buffer.
/// \param preload mode, packets not included in statistics.
+ ///
+ /// \throw isc::dhcp::SocketWriteError if failed to send the packet.
void sendSolicit6(const TestControlSocket& socket,
const std::vector<uint8_t>& template_buf,
const bool preload = false);
More information about the bind10-changes
mailing list