mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[master] Merge branch 'trac2187'
This commit is contained in:
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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());
|
||||
}
|
||||
|
||||
|
@@ -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());
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user