Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
43ad3049
Commit
43ad3049
authored
Apr 04, 2013
by
Marcin Siodelski
Browse files
[991] Broadcast options are enabled on sockets conditionally.
parent
63df2f7c
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/dhcp4_srv.cc
View file @
43ad3049
...
...
@@ -57,7 +57,7 @@ static const char* SERVER_ID_FILE = "b10-dhcp4-serverid";
// These are hardcoded parameters. Currently this is a skeleton server that only
// grants those options and a single, fixed, hardcoded lease.
Dhcpv4Srv
::
Dhcpv4Srv
(
uint16_t
port
,
const
char
*
dbconfig
)
{
Dhcpv4Srv
::
Dhcpv4Srv
(
uint16_t
port
,
const
char
*
dbconfig
,
const
bool
use_bcast
)
{
LOG_DEBUG
(
dhcp4_logger
,
DBG_DHCP4_START
,
DHCP4_OPEN_SOCKET
).
arg
(
port
);
try
{
// First call to instance() will create IfaceMgr (it's a singleton)
...
...
@@ -67,7 +67,7 @@ Dhcpv4Srv::Dhcpv4Srv(uint16_t port, const char* dbconfig) {
if
(
port
)
{
// open sockets only if port is non-zero. Port 0 is used
// for non-socket related testing.
IfaceMgr
::
instance
().
openSockets4
(
port
);
IfaceMgr
::
instance
().
openSockets4
(
port
,
use_bcast
);
}
string
srvid_file
=
CfgMgr
::
instance
().
getDataDir
()
+
"/"
+
string
(
SERVER_ID_FILE
);
...
...
src/bin/dhcp4/dhcp4_srv.h
View file @
43ad3049
...
...
@@ -66,8 +66,10 @@ class Dhcpv4Srv : public boost::noncopyable {
/// @param port specifies port number to listen on
/// @param dbconfig Lease manager configuration string. The default
/// of the "memfile" manager is used for testing.
/// @param use_bcast configure sockets to support broadcast messages.
Dhcpv4Srv
(
uint16_t
port
=
DHCP4_SERVER_PORT
,
const
char
*
dbconfig
=
"type=memfile"
);
const
char
*
dbconfig
=
"type=memfile"
,
const
bool
use_bcast
=
true
);
/// @brief Destructor. Used during DHCPv4 service shutdown.
~
Dhcpv4Srv
();
...
...
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
View file @
43ad3049
...
...
@@ -45,7 +45,16 @@ namespace {
class
NakedDhcpv4Srv
:
public
Dhcpv4Srv
{
// "Naked" DHCPv4 server, exposes internal fields
public:
NakedDhcpv4Srv
(
uint16_t
port
=
0
)
:
Dhcpv4Srv
(
port
)
{
}
/// @brief Constructor.
///
/// It disables configuration of broadcast options on
/// sockets that are opened by the Dhcpv4Srv constructor.
/// Setting broadcast options requires root privileges
/// which is not the case when running unit tests.
NakedDhcpv4Srv
(
uint16_t
port
=
0
)
:
Dhcpv4Srv
(
port
,
"type=memfile"
,
false
)
{
}
using
Dhcpv4Srv
::
processDiscover
;
using
Dhcpv4Srv
::
processRequest
;
...
...
src/lib/dhcp/iface_mgr.cc
View file @
43ad3049
...
...
@@ -195,10 +195,23 @@ void IfaceMgr::stubDetectIfaces() {
addInterface
(
iface
);
}
bool
IfaceMgr
::
openSockets4
(
const
uint16_t
port
)
{
bool
IfaceMgr
::
openSockets4
(
const
uint16_t
port
,
const
bool
use_bcast
)
{
int
sock
;
int
count
=
0
;
// This option is used to bind sockets to particular interfaces.
// This is currently the only way to discover on which interface
// the broadcast packet has been received. If this option is
// not supported then only one interface should be confugured
// to listen for broadcast traffic.
#ifdef SO_BINDTODEVICE
const
bool
bind_to_device
=
true
;
#else
const
bool
bind_to_device
=
false
;
#endif
int
bcast_num
=
0
;
for
(
IfaceCollection
::
iterator
iface
=
ifaces_
.
begin
();
iface
!=
ifaces_
.
end
();
++
iface
)
{
...
...
@@ -219,9 +232,37 @@ bool IfaceMgr::openSockets4(const uint16_t port) {
continue
;
}
// Open socket and enable broadcast traffic
// (two last arguments enable broadcast).
sock
=
openSocket
(
iface
->
getName
(),
*
addr
,
port
,
true
,
true
);
// If selected interface is broadcast capable set appropriate
// options on the socket so as it can receive and send broadcast
// messages.
if
(
iface
->
flag_broadcast_
&&
use_bcast
)
{
// If our OS supports binding socket to a device we can listen
// for broadcast messages on multiple interfaces. Otherwise we
// bind to INADDR_ANY address but we can do it only once. Thus,
// if one socket has been bound we can't do it any further.
if
(
!
bind_to_device
&&
bcast_num
>
0
)
{
isc_throw
(
SocketConfigError
,
"SO_BINDTODEVICE socket option is"
<<
" not supported on this OS; therefore, DHCP"
<<
" server can only listen broadcast traffic on"
<<
" a single interface"
);
}
else
{
// We haven't open any broadcast sockets yet, so we can
// open at least one more.
sock
=
openSocket
(
iface
->
getName
(),
*
addr
,
port
,
true
,
true
);
// Binding socket to an interface is not supported so we can't
// open any more broadcast sockets. Increase the number of
// opened broadcast sockets.
if
(
!
bind_to_device
)
{
++
bcast_num
;
}
}
}
else
{
// Not broadcast capable, do not set broadcast flags.
sock
=
openSocket
(
iface
->
getName
(),
*
addr
,
port
,
false
,
false
);
}
if
(
sock
<
0
)
{
isc_throw
(
SocketConfigError
,
"failed to open IPv4 socket"
<<
" supporting broadcast traffic"
);
...
...
src/lib/dhcp/iface_mgr.h
View file @
43ad3049
...
...
@@ -534,10 +534,12 @@ public:
/// Will throw exception if socket creation fails.
///
/// @param port specifies port number (usually DHCP4_SERVER_PORT)
/// @param use_bcast configure sockets to support broadcast messages.
///
/// @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
);
bool
openSockets4
(
const
uint16_t
port
=
DHCP4_SERVER_PORT
,
const
bool
use_bcast
=
true
);
/// @brief Closes all open sockets.
/// Is used in destructor, but also from Dhcpv4_srv and Dhcpv6_srv classes.
...
...
src/lib/dhcp/pkt_filter_inet.cc
View file @
43ad3049
...
...
@@ -49,6 +49,7 @@ PktFilterInet::openSocket(const Iface& iface,
isc_throw
(
SocketConfigError
,
"Failed to create UDP6 socket."
);
}
#ifdef SO_BINDTODEVICE
if
(
receive_bcast
)
{
// Bind to device so as we receive traffic on a specific interface.
if
(
setsockopt
(
sock
,
SOL_SOCKET
,
SO_BINDTODEVICE
,
iface
.
getName
().
c_str
(),
...
...
@@ -58,6 +59,7 @@ PktFilterInet::openSocket(const Iface& iface,
<<
"on socket "
<<
sock
);
}
}
#endif
if
(
send_bcast
)
{
// Enable sending to broadcast address.
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment