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
d5e189cf
Commit
d5e189cf
authored
Nov 09, 2011
by
Tomek Mrugalski
🛰
Browse files
[1238] Socket binding for IPv4 implemented.
parent
0b6937d0
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp6/iface_mgr.cc
View file @
d5e189cf
...
...
@@ -250,17 +250,75 @@ IfaceMgr::openSocket(const std::string& ifname,
uint16_t
IfaceMgr
::
openSocket4
(
Iface
&
iface
,
const
IOAddress
&
addr
,
int
port
)
{
isc_throw
(
NotImplemented
,
"Sorry. Try again in 2 weeks"
);
cout
<<
iface
.
getFullName
()
<<
addr
.
toText
()
<<
port
;
// just to disable unused warning
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
;
addr4
.
sin_port
=
htons
(
port
);
memcpy
(
&
addr4
.
sin_addr
,
addr
.
getAddress
().
to_v4
().
to_bytes
().
data
(),
sizeof
(
addr4
.
sin_addr
));
int
sock
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
if
(
sock
<
0
)
{
isc_throw
(
Unexpected
,
"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
()
<<
"/port="
<<
port
);
}
#if defined(SO_BINDTODEVICE)
#if 0
/// For some reason that doesn't work. It's not a big deal as this is
/// Linux only feature. We can use IP_PKTINFO to check that we received
/// packet over proper interface.
// Bind this socket to this interface.
const char* ifname = iface.getName().c_str();
int len = strlen(ifname);
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
ifname, len) < 0) {
isc_throw(Unexpected, "setsockopt: SO_BINDTODEVICE failed.");
}
#endif
#endif
int
flag
=
1
;
#ifdef IP_RECVPKTINFO
if
(
setsockopt
(
sock
,
IPPROTO_IP
,
IP_RECVPKTINFO
,
&
flag
,
sizeof
(
flag
))
!=
0
)
{
close
(
sock
);
isc_throw
(
Unexpected
,
"setsockopt: IP_RECVPKTINFO failed."
)
}
#else
/* RFC2292 - an old way */
if
(
setsockopt
(
sock
,
IPPROTO_IP
,
IP_PKTINFO
,
&
flag
,
sizeof
(
flag
))
!=
0
)
{
close
(
sock
);
isc_throw
(
Unexpected
,
"setsockopt: IP_PKTINFO: failed."
);
}
#endif
cout
<<
"Created socket "
<<
sock
<<
" on "
<<
iface
.
getName
()
<<
"/"
<<
addr
.
toText
()
<<
"/port="
<<
port
<<
endl
;
// TODO: Add socket to iface interface
return
(
sock
);
}
uint16_t
IfaceMgr
::
openSocket6
(
Iface
&
iface
,
const
IOAddress
&
addr
,
int
port
)
{
struct
sockaddr_in6
addr6
;
cout
<<
"Creating socket on "
<<
iface
.
getFullName
()
<<
"/port="
<<
port
<<
endl
;
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
;
addr6
.
sin6_port
=
htons
(
port
);
...
...
@@ -278,8 +336,7 @@ IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, int port) {
// make a socket
int
sock
=
socket
(
AF_INET6
,
SOCK_DGRAM
,
0
);
if
(
sock
<
0
)
{
cout
<<
"Failed to create UDP6 socket."
<<
endl
;
return
(
-
1
);
isc_throw
(
Unexpected
,
"Failed to create UDP6 socket."
);
}
/* Set the REUSEADDR option so that we don't fail to start if
...
...
@@ -287,32 +344,28 @@ IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, int port) {
int
flag
=
1
;
if
(
setsockopt
(
sock
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
char
*
)
&
flag
,
sizeof
(
flag
))
<
0
)
{
cout
<<
"Can't set SO_REUSEADDR option on dhcpv6 socket."
<<
endl
;
close
(
sock
);
return
(
-
1
);
isc_throw
(
Unexpected
,
"Can't set SO_REUSEADDR option on dhcpv6 socket."
);
}
if
(
bind
(
sock
,
(
struct
sockaddr
*
)
&
addr6
,
sizeof
(
addr6
))
<
0
)
{
cout
<<
"Failed to bind socket "
<<
sock
<<
" to "
<<
addr
.
toText
()
<<
"/port="
<<
port
<<
endl
;
close
(
sock
);
return
(
-
1
);
isc_throw
(
Unexpected
,
"Failed to bind socket "
<<
sock
<<
" to "
<<
addr
.
toText
()
<<
"/port="
<<
port
);
}
#ifdef IPV6_RECVPKTINFO
/* RFC3542 - a new way */
if
(
setsockopt
(
sock
,
IPPROTO_IPV6
,
IPV6_RECVPKTINFO
,
&
flag
,
sizeof
(
flag
))
!=
0
)
{
cout
<<
"setsockopt: IPV6_RECVPKTINFO failed."
<<
endl
;
close
(
sock
);
return
(
-
1
);
isc_throw
(
Unexpected
,
"setsockopt: IPV6_RECVPKTINFO failed."
);
}
#else
/* RFC2292 - an old way */
if
(
setsockopt
(
sock
,
IPPROTO_IPV6
,
IPV6_PKTINFO
,
&
flag
,
sizeof
(
flag
))
!=
0
)
{
cout
<<
"setsockopt: IPV6_PKTINFO: failed."
<<
endl
;
close
(
sock
);
return
(
-
1
);
isc_throw
(
Unexpected
,
"setsockopt: IPV6_PKTINFO: failed."
);
}
#endif
...
...
@@ -326,7 +379,8 @@ IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, int port) {
if
(
!
joinMcast
(
sock
,
iface
.
getName
(),
string
(
ALL_DHCP_RELAY_AGENTS_AND_SERVERS
)
)
)
{
close
(
sock
);
return
(
-
1
);
isc_throw
(
Unexpected
,
"Failed to join "
<<
ALL_DHCP_RELAY_AGENTS_AND_SERVERS
<<
" multicast group."
);
}
}
...
...
src/bin/dhcp6/tests/Makefile.am
View file @
d5e189cf
...
...
@@ -25,8 +25,6 @@ check-local:
AM_CPPFLAGS
=
-I
$(top_srcdir)
/src/lib
-I
$(top_builddir)
/src/lib
AM_CPPFLAGS
+=
-I
$(top_builddir)
/src/bin
# for generated spec_config.h header
AM_CPPFLAGS
+=
-I
$(top_srcdir)
/src/bin
AM_CPPFLAGS
+=
-I
$(top_builddir)
/src/lib/cc
AM_CPPFLAGS
+=
-I
$(top_srcdir)
/src/lib/asiolink
AM_CPPFLAGS
+=
$(BOOST_INCLUDES)
AM_CPPFLAGS
+=
-DTEST_DATA_DIR
=
\"
$(abs_top_srcdir)
/src/lib/testutils/testdata
\"
AM_CPPFLAGS
+=
-DTEST_DATA_BUILDDIR
=
\"
$(abs_top_builddir)
/src/bin/dhcp6/tests
\"
...
...
@@ -58,7 +56,6 @@ dhcp6_unittests_LDADD += $(SQLITE_LIBS)
dhcp6_unittests_LDADD
+=
$(top_builddir)
/src/lib/asiolink/libasiolink.la
dhcp6_unittests_LDADD
+=
$(top_builddir)
/src/lib/dhcp/libdhcp.la
dhcp6_unittests_LDADD
+=
$(top_builddir)
/src/lib/exceptions/libexceptions.la
dhcp6_unittests_LDADD
+=
$(top_builddir)
/src/lib/log/liblog.la
endif
noinst_PROGRAMS
=
$(TESTS)
src/bin/dhcp6/tests/iface_mgr_unittest.cc
View file @
d5e189cf
...
...
@@ -20,9 +20,10 @@
#include
<arpa/inet.h>
#include
<gtest/gtest.h>
#include
"io_address.h"
#include
"dhcp/pkt6.h"
#include
"dhcp6/iface_mgr.h"
#include
<asiolink/io_address.h>
#include
<dhcp/pkt6.h>
#include
<dhcp6/iface_mgr.h>
#include
<dhcp/dhcp4.h>
using
namespace
std
;
using
namespace
isc
;
...
...
@@ -242,10 +243,6 @@ TEST_F(IfaceMgrTest, detectIfaces) {
delete
ifacemgr
;
}
// TODO: disabled due to other naming on various systems
// (lo in Linux, lo0 in BSD systems)
// Fix for this is available on 1186 branch, will reenable
// this test once 1186 is merged
TEST_F
(
IfaceMgrTest
,
sockets6
)
{
// testing socket operation in a portable way is tricky
// without interface detection implemented
...
...
@@ -285,7 +282,7 @@ TEST_F(IfaceMgrTest, sockets6) {
// TODO: disabled due to other naming on various systems
// (lo in Linux, lo0 in BSD systems)
TEST_F
(
IfaceMgrTest
,
sockets6Mcast
)
{
TEST_F
(
IfaceMgrTest
,
DISABLED_
sockets6Mcast
)
{
// testing socket operation in a portable way is tricky
// without interface detection implemented
...
...
@@ -326,12 +323,15 @@ TEST_F(IfaceMgrTest, sendReceive6) {
fakeifaces
<<
LOOPBACK
<<
" ::1"
;
fakeifaces
.
close
();
NakedIfaceMgr
*
ifacemgr
=
new
NakedIfaceMgr
();
NakedIfaceMgr
*
ifacemgr
=
new
NakedIfaceMgr
();
// let's assume that every supported OS have lo interface
IOAddress
loAddr
(
"::1"
);
int
socket1
=
ifacemgr
->
openSocket
(
LOOPBACK
,
loAddr
,
10547
);
int
socket2
=
ifacemgr
->
openSocket
(
LOOPBACK
,
loAddr
,
10546
);
int
socket1
=
0
,
socket2
=
0
;
EXPECT_NO_THROW
(
socket1
=
ifacemgr
->
openSocket
(
LOOPBACK
,
loAddr
,
10547
);
socket2
=
ifacemgr
->
openSocket
(
LOOPBACK
,
loAddr
,
10546
);
);
ifacemgr
->
setSendSock
(
socket2
);
ifacemgr
->
setRecvSock
(
socket1
);
...
...
@@ -367,4 +367,25 @@ TEST_F(IfaceMgrTest, sendReceive6) {
delete
ifacemgr
;
}
TEST_F
(
IfaceMgrTest
,
socket4
)
{
createLoInterfacesTxt
();
NakedIfaceMgr
*
ifacemgr
=
new
NakedIfaceMgr
();
// let's assume that every supported OS have lo interface
IOAddress
loAddr
(
"127.0.0.1"
);
// use unprivileged port (it's convenient for running tests as non-root)
int
socket1
=
0
;
EXPECT_NO_THROW
(
socket1
=
ifacemgr
->
openSocket
(
LOOPBACK
,
loAddr
,
DHCP4_SERVER_PORT
+
10000
);
);
EXPECT_GT
(
socket1
,
0
);
close
(
socket1
);
delete
ifacemgr
;
}
}
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