Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
4e225668
Commit
4e225668
authored
Nov 25, 2013
by
Marcin Siodelski
Browse files
[2765] Added fallback socket descriptor to SocketInfo structure.
parent
0119b50f
Changes
11
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/tests/dhcp4_test_utils.h
View file @
4e225668
...
...
@@ -20,6 +20,7 @@
#define DHCP4_TEST_UTILS_H
#include
<gtest/gtest.h>
#include
<dhcp/iface_mgr.h>
#include
<dhcp/pkt4.h>
#include
<dhcp/pkt_filter.h>
#include
<dhcp/pkt_filter_inet.h>
...
...
@@ -52,9 +53,10 @@ public:
}
/// Does nothing.
virtual
int
openSocket
(
const
Iface
&
,
const
isc
::
asiolink
::
IOAddress
&
,
const
uint16_t
,
const
bool
,
const
bool
)
{
return
(
0
);
virtual
SocketInfo
openSocket
(
const
Iface
&
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
bool
,
const
bool
)
{
return
(
SocketInfo
(
addr
,
port
,
0
));
}
/// Does nothing.
...
...
src/lib/dhcp/iface_mgr.cc
View file @
4e225668
...
...
@@ -741,7 +741,7 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
}
}
SocketInfo
info
(
sock
,
addr
,
port
);
SocketInfo
info
(
addr
,
port
,
sock
);
iface
.
addSocket
(
info
);
return
(
sock
);
...
...
@@ -754,13 +754,11 @@ int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr,
// Skip checking if the packet_filter_ is non-NULL because this check
// has been already done when packet filter object was set.
int
sock
=
packet_filter_
->
openSocket
(
iface
,
addr
,
port
,
receive_bcast
,
send_bcast
);
SocketInfo
info
(
sock
,
addr
,
port
);
SocketInfo
info
=
packet_filter_
->
openSocket
(
iface
,
addr
,
port
,
receive_bcast
,
send_bcast
);
iface
.
addSocket
(
info
);
return
(
sock
);
return
(
info
.
sock
fd_
);
}
bool
...
...
src/lib/dhcp/iface_mgr.h
View file @
4e225668
...
...
@@ -72,19 +72,49 @@ public:
/// Holds information about socket.
struct
SocketInfo
{
uint16_t
sockfd_
;
/// socket descriptor
isc
::
asiolink
::
IOAddress
addr_
;
/// bound address
uint16_t
port_
;
/// socket port
uint16_t
family_
;
/// IPv4 or IPv6
/// @brief Socket descriptor (a.k.a. primary socket).
int
sockfd_
;
/// @brief Fallback socket descriptor.
///
/// This socket descriptor holds the handle to the fallback socket.
/// The fallback socket is created when there is a need for the regular
/// datagram socket to be bound to an IP address and port, besides
/// primary socket (sockfd_) which is actually used to receive and process
/// the DHCP messages. The fallback socket (if exists) is always associated
/// with the primary socket. In particular, the need for the fallback socket
/// arises when raw socket is a primary one. When primary socket is open,
/// it is bound to an interface not the address and port. The implications
/// include the possibility that the other process (e.g. the other instance
/// of DHCP server) will bind to the same address and port through which the
/// raw socket receives the DHCP messages.Another implication is that the
/// kernel, being unaware of the DHCP server operating through the raw
/// socket, will respond with the ICMP "Destination port unreachable"
/// messages when DHCP messages are only received through the raw socket.
/// In order to workaround the issues mentioned here, the fallback socket
/// should be opened so as/ the kernel is aware that the certain address
/// and port is in use.
///
/// The fallback description is supposed to be set to a negative value if
/// the fallback socket is closed (not open).
int
fallbackfd_
;
/// @brief SocketInfo constructor.
///
/// @param sockfd socket descriptor
/// @param addr an address the socket is bound to
/// @param port a port the socket is bound to
SocketInfo
(
uint16_t
sockfd
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
uint16_t
port
)
:
sockfd_
(
sockfd
),
addr_
(
addr
),
port_
(
port
),
family_
(
addr
.
getFamily
())
{
}
/// @param addr An address the socket is bound to.
/// @param port A port the socket is bound to.
/// @param sockfd Socket descriptor.
/// @param fallbackfd A descriptor of the fallback socket.
SocketInfo
(
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
int
sockfd
,
const
int
fallbackfd
=
-
1
)
:
addr_
(
addr
),
port_
(
port
),
family_
(
addr
.
getFamily
()),
sockfd_
(
sockfd
),
fallbackfd_
(
fallbackfd
)
{
}
};
...
...
src/lib/dhcp/pkt_filter.h
View file @
4e225668
...
...
@@ -67,20 +67,30 @@ public:
/// @return true of the direct response is supported.
virtual
bool
isDirectResponseSupported
()
const
=
0
;
/// @brief Open socket.
/// @brief Open
primary and fallback
socket.
///
/// @param iface interface descriptor
/// @param addr address on the interface to be used to send packets.
/// @param port port number.
/// @param receive_bcast configure socket to receive broadcast messages
/// A method implementation in the derived class may open one or two
/// sockets:
/// - a primary socket - used for communication with clients. DHCP messages
/// received using this socket are processed and the same socket is used
/// to send a response to the client.
/// - a fallback socket which is optionally opened if there is a need for
/// the presence of the socket which can be bound to a specific IP address
/// and UDP port (e.g. raw primary socket can't be). For the details, see
/// the documentation of @c isc::dhcp::SocketInfo.
///
/// @param iface Interface descriptor.
/// @param addr Address on the interface to be used to send packets.
/// @param port Port number.
/// @param receive_bcast Configure socket to receive broadcast messages
/// @param send_bcast configure socket to send broadcast messages.
///
/// @return
created socket's descriptor
virtual
int
openSocket
(
const
Iface
&
iface
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
bool
receive_bcast
,
const
bool
send_bcast
)
=
0
;
/// @return
A structure describing a primary and fallback socket.
virtual
SocketInfo
openSocket
(
const
Iface
&
iface
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
bool
receive_bcast
,
const
bool
send_bcast
)
=
0
;
/// @brief Receive packet over specified socket.
///
...
...
src/lib/dhcp/pkt_filter_inet.cc
View file @
4e225668
...
...
@@ -28,11 +28,12 @@ PktFilterInet::PktFilterInet()
{
}
int
PktFilterInet
::
openSocket
(
const
Iface
&
iface
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
bool
receive_bcast
,
const
bool
send_bcast
)
{
SocketInfo
PktFilterInet
::
openSocket
(
const
Iface
&
iface
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
bool
receive_bcast
,
const
bool
send_bcast
)
{
struct
sockaddr_in
addr4
;
memset
(
&
addr4
,
0
,
sizeof
(
sockaddr
));
...
...
@@ -90,7 +91,8 @@ int PktFilterInet::openSocket(const Iface& iface,
}
#endif
return
(
sock
);
SocketInfo
sock_desc
(
addr
,
port
,
sock
);
return
(
sock_desc
);
}
...
...
src/lib/dhcp/pkt_filter_inet.h
View file @
4e225668
...
...
@@ -44,20 +44,20 @@ public:
return
(
false
);
}
/// @brief Open socket.
/// @brief Open
primary and fallback
socket.
///
/// @param iface
i
nterface descriptor
/// @param addr
a
ddress on the interface to be used to send packets.
/// @param port
p
ort number.
/// @param receive_bcast
c
onfigure socket to receive broadcast messages
/// @param send_bcast
c
onfigure socket to send broadcast messages.
/// @param iface
I
nterface descriptor
.
/// @param addr
A
ddress on the interface to be used to send packets.
/// @param port
P
ort number.
/// @param receive_bcast
C
onfigure socket to receive broadcast messages
/// @param send_bcast
C
onfigure socket to send broadcast messages.
///
/// @return
created socket's descriptor
virtual
int
openSocket
(
const
Iface
&
iface
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
bool
receive_bcast
,
const
bool
send_bcast
);
/// @return
A structure describing a primary and fallback socket.
virtual
SocketInfo
openSocket
(
const
Iface
&
iface
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
bool
receive_bcast
,
const
bool
send_bcast
);
/// @brief Receive packet over specified socket.
///
...
...
src/lib/dhcp/pkt_filter_lpf.cc
View file @
4e225668
...
...
@@ -102,7 +102,7 @@ using namespace isc::util;
namespace
isc
{
namespace
dhcp
{
int
SocketInfo
PktFilterLPF
::
openSocket
(
const
Iface
&
iface
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
bool
,
...
...
@@ -123,7 +123,7 @@ PktFilterLPF::openSocket(const Iface& iface,
// We return negative, the proper error message will be displayed
// by the IfaceMgr ...
close
(
sock_check
);
return
(
-
1
);
return
(
SocketInfo
(
addr
,
port
,
-
1
)
)
;
}
close
(
sock_check
);
...
...
@@ -166,7 +166,8 @@ PktFilterLPF::openSocket(const Iface& iface,
<<
"' to interface '"
<<
iface
.
getName
()
<<
"'"
);
}
return
(
sock
);
SocketInfo
sock_desc
(
addr
,
port
,
sock
);
return
(
sock_desc
);
}
...
...
src/lib/dhcp/pkt_filter_lpf.h
View file @
4e225668
...
...
@@ -41,21 +41,20 @@ public:
return
(
true
);
}
/// @brief Open socket.
/// @brief Open
primary and fallback
socket.
///
/// @param iface
i
nterface descriptor
/// @param addr
a
ddress on the interface to be used to send packets.
/// @param port
p
ort number.
/// @param receive_bcast
c
onfigure socket to receive broadcast messages
/// @param send_bcast
c
onfigure socket to send broadcast messages.
/// @param iface
I
nterface descriptor
.
/// @param addr
A
ddress on the interface to be used to send packets.
/// @param port
P
ort number.
/// @param receive_bcast
C
onfigure socket to receive broadcast messages
/// @param send_bcast
C
onfigure socket to send broadcast messages.
///
/// @throw isc::NotImplemented always
/// @return created socket's descriptor
virtual
int
openSocket
(
const
Iface
&
iface
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
bool
receive_bcast
,
const
bool
send_bcast
);
/// @return A structure describing a primary and fallback socket.
virtual
SocketInfo
openSocket
(
const
Iface
&
iface
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
bool
receive_bcast
,
const
bool
send_bcast
);
/// @brief Receive packet over specified socket.
///
...
...
src/lib/dhcp/tests/iface_mgr_unittest.cc
View file @
4e225668
...
...
@@ -84,13 +84,13 @@ public:
/// (because real values are rather less than 255). Values greater
/// than 255 are not recommended because they cause warnings to be
/// reported by Valgrind when invoking close() on them.
virtual
int
openSocket
(
const
Iface
&
,
const
isc
::
asiolink
::
IOAddress
&
,
const
uint16_t
,
const
bool
,
const
bool
)
{
virtual
SocketInfo
openSocket
(
const
Iface
&
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint16_t
port
,
const
bool
,
const
bool
)
{
open_socket_called_
=
true
;
return
(
255
);
return
(
SocketInfo
(
addr
,
port
,
255
)
)
;
}
/// Does nothing
...
...
@@ -1152,18 +1152,28 @@ TEST_F(IfaceMgrTest, iface_methods) {
TEST_F
(
IfaceMgrTest
,
socketInfo
)
{
// Check that socketinfo for IPv4 socket is functional
SocketInfo
sock1
(
7
,
IOAddress
(
"192.0.2.56"
),
DHCP4_SERVER_PORT
+
7
);
SocketInfo
sock1
(
IOAddress
(
"192.0.2.56"
),
DHCP4_SERVER_PORT
+
7
,
7
);
EXPECT_EQ
(
7
,
sock1
.
sockfd_
);
EXPECT_EQ
(
-
1
,
sock1
.
fallbackfd_
);
EXPECT_EQ
(
"192.0.2.56"
,
sock1
.
addr_
.
toText
());
EXPECT_EQ
(
AF_INET
,
sock1
.
family_
);
EXPECT_EQ
(
DHCP4_SERVER_PORT
+
7
,
sock1
.
port_
);
// Check that non-default value of the fallback socket descriptor is set
SocketInfo
sock2
(
IOAddress
(
"192.0.2.53"
),
DHCP4_SERVER_PORT
+
8
,
8
,
10
);
EXPECT_EQ
(
8
,
sock2
.
sockfd_
);
EXPECT_EQ
(
10
,
sock2
.
fallbackfd_
);
EXPECT_EQ
(
"192.0.2.53"
,
sock2
.
addr_
.
toText
());
EXPECT_EQ
(
AF_INET
,
sock2
.
family_
);
EXPECT_EQ
(
DHCP4_SERVER_PORT
+
8
,
sock2
.
port_
);
// Check that socketinfo for IPv6 socket is functional
SocketInfo
sock2
(
9
,
IOAddress
(
"2001:db8:1::56"
),
DHCP4_SERVER_PORT
+
9
);
EXPECT_EQ
(
9
,
sock2
.
sockfd_
);
EXPECT_EQ
(
"2001:db8:1::56"
,
sock2
.
addr_
.
toText
());
EXPECT_EQ
(
AF_INET6
,
sock2
.
family_
);
EXPECT_EQ
(
DHCP4_SERVER_PORT
+
9
,
sock2
.
port_
);
SocketInfo
sock3
(
IOAddress
(
"2001:db8:1::56"
),
DHCP4_SERVER_PORT
+
9
,
9
);
EXPECT_EQ
(
9
,
sock3
.
sockfd_
);
EXPECT_EQ
(
-
1
,
sock3
.
fallbackfd_
);
EXPECT_EQ
(
"2001:db8:1::56"
,
sock3
.
addr_
.
toText
());
EXPECT_EQ
(
AF_INET6
,
sock3
.
family_
);
EXPECT_EQ
(
DHCP4_SERVER_PORT
+
9
,
sock3
.
port_
);
// Now let's test if IfaceMgr handles socket info properly
scoped_ptr
<
NakedIfaceMgr
>
ifacemgr
(
new
NakedIfaceMgr
());
...
...
@@ -1171,6 +1181,7 @@ TEST_F(IfaceMgrTest, socketInfo) {
ASSERT_TRUE
(
loopback
);
loopback
->
addSocket
(
sock1
);
loopback
->
addSocket
(
sock2
);
loopback
->
addSocket
(
sock3
);
Pkt6
pkt6
(
DHCPV6_REPLY
,
123456
);
...
...
@@ -1225,6 +1236,7 @@ TEST_F(IfaceMgrTest, socketInfo) {
EXPECT_NO_THROW
(
ifacemgr
->
getIface
(
LOOPBACK
)
->
delSocket
(
7
);
ifacemgr
->
getIface
(
LOOPBACK
)
->
delSocket
(
8
);
);
// It should throw again, there's no usable socket anymore.
...
...
src/lib/dhcp/tests/pkt_filter_inet_unittest.cc
View file @
4e225668
...
...
@@ -112,7 +112,7 @@ TEST_F(PktFilterInetTest, openSocket) {
// Try to open socket.
PktFilterInet
pkt_filter
;
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
);
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
)
.
sockfd_
;
// Check that socket has been opened.
ASSERT_GE
(
socket_
,
0
);
...
...
@@ -170,7 +170,7 @@ TEST_F(PktFilterInetTest, send) {
// Open socket. We don't check that the socket has appropriate
// options and family set because we have checked that in the
// openSocket test already.
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
);
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
)
.
sockfd_
;
ASSERT_GE
(
socket_
,
0
);
// Send the packet over the socket.
...
...
@@ -249,14 +249,14 @@ TEST_F(PktFilterInetTest, receive) {
// Open socket. We don't check that the socket has appropriate
// options and family set because we have checked that in the
// openSocket test already.
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
);
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
)
.
sockfd_
;
ASSERT_GE
(
socket_
,
0
);
// Send the packet over the socket.
ASSERT_NO_THROW
(
pkt_filter
.
send
(
iface
,
socket_
,
pkt
));
// Receive the packet.
SocketInfo
socket_info
(
socket_
,
IOAddress
(
"127.0.0.1"
),
PORT
);
SocketInfo
socket_info
(
IOAddress
(
"127.0.0.1"
),
PORT
,
socket_
);
Pkt4Ptr
rcvd_pkt
=
pkt_filter
.
receive
(
iface
,
socket_info
);
// Check that the packet has been correctly received.
ASSERT_TRUE
(
rcvd_pkt
);
...
...
src/lib/dhcp/tests/pkt_filter_lpf_unittest.cc
View file @
4e225668
...
...
@@ -124,7 +124,7 @@ TEST_F(PktFilterLPFTest, DISABLED_openSocket) {
// Try to open socket.
PktFilterLPF
pkt_filter
;
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
);
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
)
.
sockfd_
;
// Check that socket has been opened.
ASSERT_GE
(
socket_
,
0
);
...
...
@@ -183,7 +183,7 @@ TEST_F(PktFilterLPFTest, DISABLED_send) {
// Open socket. We don't check that the socket has appropriate
// options and family set because we have checked that in the
// openSocket test already.
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
);
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
)
.
sockfd_
;
ASSERT_GE
(
socket_
,
0
);
// Send the packet over the socket.
...
...
@@ -273,7 +273,7 @@ TEST_F(PktFilterLPFTest, DISABLED_receive) {
// Open socket. We don't check that the socket has appropriate
// options and family set because we have checked that in the
// openSocket test already.
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
);
socket_
=
pkt_filter
.
openSocket
(
iface
,
addr
,
PORT
,
false
,
false
)
.
sockfd_
;
ASSERT_GE
(
socket_
,
0
);
// Send the packet over the socket.
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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