}
bool
-IfaceMgr::hasOpenSocket(const IOAddress& addr) const {
+IfaceMgr::hasOpenSocket(const IOAddress& addr, bool unicast) const {
// Fast track for IPv4 using bound addresses.
if (addr.isV4() && !bound_address_.empty()) {
return (bound_address_.count(addr.toUint32()) != 0);
// if address is unspecified (in6addr_any).
if (sock.addr_ == addr) {
return (true);
- } else if (sock.addr_.isV6Zero()) {
+ } else if (sock.addr_.isV6Zero() && !unicast) {
// Handle the case that the address is unspecified (any).
// This happens only with IPv6 so we do not check IPv4.
// In this case, we should check if the specified address
// address on BSD and Solaris on any interface, so we make sure that
// that interface actually has opened sockets by checking the number
// of sockets to be non zero.
- if (!skip_opened || !IfaceMgr::hasOpenSocket(addr) ||
+ if (!skip_opened || !IfaceMgr::hasOpenSocket(addr, true) ||
!iface->getSockets().size()) {
try {
IfaceMgr::openSocket(iface->getName(), addr, port, false, false);
/// specified link-local address and returns true.
///
/// @param addr Address of the socket being searched.
+ /// @param unicast Flag which indicates if the address is unicast.
///
/// @return true if there is a socket bound to the specified address.
- bool hasOpenSocket(const isc::asiolink::IOAddress& addr) const;
+ bool hasOpenSocket(const isc::asiolink::IOAddress& addr, bool unicast = false) const;
/// @brief Fetches the DHCPv4 packet queue manager
///
ASSERT_TRUE(filter);
ASSERT_NO_THROW(ifacemgr.setPacketFilter(filter));
+ ifacemgr.getIface("eth0")->addUnicast(IOAddress("2001:db8:1::1"));
+ ifacemgr.getIface("eth1")->addAddress(IOAddress("3001:db8:1::1"));
+
// Simulate opening sockets using the dummy packet filter.
bool success = false;
ASSERT_NO_THROW(success = ifacemgr.openSockets6(DHCP6_SERVER_PORT));
// for interfaces.
EXPECT_TRUE(ifacemgr.hasOpenSocket(IOAddress("fe80::3a60:77ff:fed5:cdef")));
EXPECT_TRUE(ifacemgr.hasOpenSocket(IOAddress("fe80::3a60:77ff:fed5:abcd")));
+ EXPECT_TRUE(ifacemgr.hasOpenSocket(IOAddress("2001:db8:1::1")));
+ EXPECT_TRUE(ifacemgr.hasOpenSocket(IOAddress("2001:db8:1::1"), true));
+ if (ifacemgr.hasOpenSocket(IOAddress("::"))) {
+ // On BSD binding is done using "::" when address is multicast which
+ // makes the address match interface address.
+ EXPECT_TRUE(ifacemgr.hasOpenSocket(IOAddress("3001:db8:1::1")));
+ } else {
+ // On Linux binding is done using link-local and all-servers address
+ // when address is multicast.
+ EXPECT_FALSE(ifacemgr.hasOpenSocket(IOAddress("3001:db8:1::1")));
+ }
+ EXPECT_FALSE(ifacemgr.hasOpenSocket(IOAddress("3001:db8:1::1"), true));
// Check that there is no socket bound to the address which hasn't been
// configured on any interface.
EXPECT_FALSE(ifacemgr.hasOpenSocket(IOAddress("fe80::3a60:77ff:feed:1")));
#if defined OS_LINUX
const uint32_t opened_by_eth0 = 3;
#else
- const uint32_t opened_by_eth0 = 1;
+ const uint32_t opened_by_eth0 = 2;
#endif
#if defined OS_LINUX