Commit d20b1f2c authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[2902] Direct traffic is optional in the Dhcp4Srv to allow unit testing.

parent b9be6a95
...@@ -57,7 +57,8 @@ static const char* SERVER_ID_FILE = "b10-dhcp4-serverid"; ...@@ -57,7 +57,8 @@ static const char* SERVER_ID_FILE = "b10-dhcp4-serverid";
// These are hardcoded parameters. Currently this is a skeleton server that only // These are hardcoded parameters. Currently this is a skeleton server that only
// grants those options and a single, fixed, hardcoded lease. // grants those options and a single, fixed, hardcoded lease.
Dhcpv4Srv::Dhcpv4Srv(uint16_t port, const char* dbconfig, const bool use_bcast) { Dhcpv4Srv::Dhcpv4Srv(uint16_t port, const char* dbconfig, const bool use_bcast,
const bool direct_response_desired) {
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_START, DHCP4_OPEN_SOCKET).arg(port); LOG_DEBUG(dhcp4_logger, DBG_DHCP4_START, DHCP4_OPEN_SOCKET).arg(port);
try { try {
// First call to instance() will create IfaceMgr (it's a singleton) // First call to instance() will create IfaceMgr (it's a singleton)
...@@ -67,7 +68,7 @@ Dhcpv4Srv::Dhcpv4Srv(uint16_t port, const char* dbconfig, const bool use_bcast) ...@@ -67,7 +68,7 @@ Dhcpv4Srv::Dhcpv4Srv(uint16_t port, const char* dbconfig, const bool use_bcast)
// to the client which doesn't have address assigned. This capability // to the client which doesn't have address assigned. This capability
// may be lacking on some OSes, so there is no guarantee that server // may be lacking on some OSes, so there is no guarantee that server
// will be able to respond directly. // will be able to respond directly.
IfaceMgr::instance().setMatchingPacketFilter(true); IfaceMgr::instance().setMatchingPacketFilter(direct_response_desired);
if (port) { if (port) {
// open sockets only if port is non-zero. Port 0 is used // open sockets only if port is non-zero. Port 0 is used
......
...@@ -61,15 +61,20 @@ class Dhcpv4Srv : public boost::noncopyable { ...@@ -61,15 +61,20 @@ class Dhcpv4Srv : public boost::noncopyable {
/// network interaction. Will instantiate lease manager, and load /// network interaction. Will instantiate lease manager, and load
/// old or create new DUID. It is possible to specify alternate /// old or create new DUID. It is possible to specify alternate
/// port on which DHCPv4 server will listen on. That is mostly useful /// port on which DHCPv4 server will listen on. That is mostly useful
/// for testing purposes. /// for testing purposes. The Last two arguments of the constructor
/// should be left at default values for normal server operation.
/// They should be disabled when creating an instance of this class
/// for unit testing as enabling them requires root privilegs.
/// ///
/// @param port specifies port number to listen on /// @param port specifies port number to listen on
/// @param dbconfig Lease manager configuration string. The default /// @param dbconfig Lease manager configuration string. The default
/// of the "memfile" manager is used for testing. /// of the "memfile" manager is used for testing.
/// @param use_bcast configure sockets to support broadcast messages. /// @param use_bcast configure sockets to support broadcast messages.
/// @param specifies if it is desired to support direct V4 traffic.
Dhcpv4Srv(uint16_t port = DHCP4_SERVER_PORT, Dhcpv4Srv(uint16_t port = DHCP4_SERVER_PORT,
const char* dbconfig = "type=memfile", const char* dbconfig = "type=memfile",
const bool use_bcast = true); const bool use_bcast = true,
const bool direct_response_desired = true);
/// @brief Destructor. Used during DHCPv4 service shutdown. /// @brief Destructor. Used during DHCPv4 service shutdown.
~Dhcpv4Srv(); ~Dhcpv4Srv();
......
...@@ -50,10 +50,12 @@ public: ...@@ -50,10 +50,12 @@ public:
/// ///
/// It disables configuration of broadcast options on /// It disables configuration of broadcast options on
/// sockets that are opened by the Dhcpv4Srv constructor. /// sockets that are opened by the Dhcpv4Srv constructor.
/// Setting broadcast options requires root privileges /// Also, disables the Direct V4 traffic as it requires
/// which is not the case when running unit tests. /// use of raw sockets. Use of broadcast as well as raw
/// sockets require root privileges, thus can't be used
/// in unit testing.
NakedDhcpv4Srv(uint16_t port = 0) NakedDhcpv4Srv(uint16_t port = 0)
: Dhcpv4Srv(port, "type=memfile", false) { : Dhcpv4Srv(port, "type=memfile", false, false) {
} }
using Dhcpv4Srv::processDiscover; using Dhcpv4Srv::processDiscover;
......
...@@ -28,25 +28,12 @@ PktFilterInet::PktFilterInet() ...@@ -28,25 +28,12 @@ PktFilterInet::PktFilterInet()
{ {
} }
// iface is only used when SO_BINDTODEVICE is defined and thus
// the code section using this variable is compiled.
#ifdef SO_BINDTODEVICE
int PktFilterInet::openSocket(const Iface& iface, int PktFilterInet::openSocket(const Iface& iface,
const isc::asiolink::IOAddress& addr, const isc::asiolink::IOAddress& addr,
const uint16_t port, const uint16_t port,
const bool receive_bcast, const bool receive_bcast,
const bool send_bcast) { const bool send_bcast) {
#else
int PktFilterInet::openSocket(const Iface&,
const isc::asiolink::IOAddress& addr,
const uint16_t port,
const bool receive_bcast,
const bool send_bcast) {
#endif
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;
...@@ -54,7 +41,7 @@ int PktFilterInet::openSocket(const Iface&, ...@@ -54,7 +41,7 @@ int PktFilterInet::openSocket(const Iface&,
// If we are to receive broadcast messages we have to bind // If we are to receive broadcast messages we have to bind
// to "ANY" address. // to "ANY" address.
if (receive_bcast) { if (receive_bcast && iface.flag_broadcast_) {
addr4.sin_addr.s_addr = INADDR_ANY; addr4.sin_addr.s_addr = INADDR_ANY;
} else { } else {
addr4.sin_addr.s_addr = htonl(addr); addr4.sin_addr.s_addr = htonl(addr);
...@@ -77,7 +64,7 @@ int PktFilterInet::openSocket(const Iface&, ...@@ -77,7 +64,7 @@ int PktFilterInet::openSocket(const Iface&,
} }
#endif #endif
if (send_bcast) { if (send_bcast && iface.flag_broadcast_) {
// Enable sending to broadcast address. // Enable sending to broadcast address.
int flag = 1; int flag = 1;
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag)) < 0) { if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag)) < 0) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment