Commit 66d99226 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[trac1957] Throwing exception if unable to find address to create socket.

parent 61667bcc
......@@ -397,7 +397,6 @@ int IfaceMgr::openSocket(const std::string& ifname, const IOAddress& addr,
int IfaceMgr::openSocketFromIface(const std::string& ifname,
const uint16_t port,
const uint8_t family) {
int sock = 0;
// Search for specified interface among detected interfaces.
for (IfaceCollection::iterator iface = ifaces_.begin();
iface != ifaces_.end();
......@@ -411,28 +410,36 @@ int IfaceMgr::openSocketFromIface(const std::string& ifname,
// Interface is now detected. Search for address on interface
// that matches address family (v6 or v4).
AddressCollection addrs = iface->getAddresses();
for (AddressCollection::iterator addr_it = addrs.begin();
addr_it != addrs.end();
++addr_it) {
if (addr_it->getFamily() != family) {
continue;
AddressCollection::iterator addr_it = addrs.begin();
while (addr_it != addrs.end()) {
if (addr_it->getFamily() == family) {
// We have interface and address so let's open socket.
// This may cause isc::Unexpected exception.
return (openSocket(iface->getName(), *addr_it, port));
}
// We have interface and address so let's open socket.
sock = openSocket(iface->getName(), *addr_it, port);
if (sock < 0) {
isc_throw(Unexpected, "Failed to open socket.");
++addr_it;
}
// If we are at the end of address collection it means that we found
// interface but there is no address for family specified.
if (addr_it == addrs.end()) {
// Stringify the family value to append it to exception string.
std::string family_name("AF_INET");
if (family == AF_INET6) {
family_name = "AF_INET6";
}
return (sock);
// We did not find address on the interface.
isc_throw(BadValue, "There is no address for interface: "
<< ifname << ", port: " << port << ", address "
" family: " << family_name);
}
}
return (sock);
// If we got here it means that we had not found the specified interface.
// Otherwise we would have returned from previous exist points.
isc_throw(BadValue, "There is no " << ifname << " interface present.");
}
int IfaceMgr::openSocketFromAddress(const IOAddress& addr,
const uint16_t port) {
int sock = 0;
// Search through detected interfaces and addresses to match
// local address we got.
for (IfaceCollection::iterator iface = ifaces_.begin();
......@@ -449,19 +456,16 @@ int IfaceMgr::openSocketFromAddress(const IOAddress& addr,
// on detected interfaces. If it does, we have
// address and interface detected so we can open
// socket.
if (*addr_it != addr) {
continue;
if (*addr_it == addr) {
// Open socket using local interface, address and port.
// This may cause isc::Unexpected exception.
return (openSocket(iface->getName(), *addr_it, port));
}
// Open socket using local interface, address and port.
sock = openSocket(iface->getName(), *addr_it, port);
if (sock < 0) {
isc_throw(Unexpected, "Failed to open unicast socket.");
}
return (sock);
}
}
return (sock);
// If we got here it means that we did not find specified address
// on any available interface.
isc_throw(BadValue, "There is no such address " << addr.toText());
}
int IfaceMgr::openSocketFromRemoteAddress(const IOAddress& remote_addr,
......@@ -474,7 +478,7 @@ int IfaceMgr::openSocketFromRemoteAddress(const IOAddress& remote_addr,
isc::asiolink::IOAddress
IfaceMgr::getLocalAddress(const IOAddress& remote_addr, const uint16_t port) {
// Create remote endpoint, we will be connecting to it.
boost::shared_ptr<const UDPEndpoint>
boost::scoped_ptr<const UDPEndpoint>
remote_endpoint(static_cast<const UDPEndpoint*>
(UDPEndpoint::create(IPPROTO_UDP, remote_addr, port)));
if (!remote_endpoint) {
......
......@@ -389,6 +389,8 @@ public:
/// @return socket descriptor, if socket creation, binding and multicast
/// group join were all successful.
/// @throw isc::Unexpected if failed to create and bind socket.
/// @throw isc::BadValue if there is no address on specified interface
/// that belongs to given family.
int openSocketFromIface(const std::string& ifname,
const uint16_t port,
const uint8_t family);
......@@ -403,6 +405,8 @@ public:
/// @return socket descriptor, if socket creation, binding and multicast
/// group join were all successful.
/// @throw isc::Unexpected if failed to create and bind socket
/// @throw isc::BadValue if specified address is not available on
/// any interface
int openSocketFromAddress(const isc::asiolink::IOAddress& addr,
const uint16_t port);
......
......@@ -18,6 +18,7 @@
#include <sstream>
#include <arpa/inet.h>
#include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h>
#include <asiolink/io_address.h>
......@@ -241,12 +242,13 @@ TEST_F(IfaceMgrTest, sockets6) {
}
TEST_F(IfaceMgrTest, socketsFromIface) {
NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
boost::scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
// open v6 socket on loopback interface and bind to 10547 port
int socket1 = 0;
const uint16_t port1 = 10547;
EXPECT_NO_THROW(
socket1 = ifacemgr->openSocketFromIface(LOOPBACK, 10547, AF_INET6);
socket1 = ifacemgr->openSocketFromIface(LOOPBACK, port1, AF_INET6);
);
// socket descriptor must be positive integer
EXPECT_GT(socket1, 0);
......@@ -254,25 +256,26 @@ TEST_F(IfaceMgrTest, socketsFromIface) {
// open v4 sicket on loopback interface and bind to 10548 port
int socket2 = 0;
const uint16_t port2 = 10548;
EXPECT_NO_THROW(
socket2 = ifacemgr->openSocketFromIface(LOOPBACK, 10547, AF_INET);
socket2 = ifacemgr->openSocketFromIface(LOOPBACK, port2, AF_INET);
);
// socket descriptor must be positive integer
EXPECT_GT(socket2, 0);
close(socket2);
delete ifacemgr;
}
TEST_F(IfaceMgrTest, socketsFromAddress) {
NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
boost::scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
// open v6 socket on loopback address and bind to 10547 port
int socket1 = 0;
const uint16_t port1 = 10547;
IOAddress loAddr6("::1");
EXPECT_NO_THROW(
socket1 = ifacemgr->openSocketFromAddress(loAddr6, 10547);
socket1 = ifacemgr->openSocketFromAddress(loAddr6, port1);
);
// socket descriptor must be positive integer
EXPECT_GT(socket1, 0);
......@@ -280,41 +283,40 @@ TEST_F(IfaceMgrTest, socketsFromAddress) {
// open v4 socket on loopback address and bind to 10548 port
int socket2 = 0;
const uint16_t port2 = 10548;
IOAddress loAddr("127.0.0.1");
EXPECT_NO_THROW(
socket2 = ifacemgr->openSocketFromAddress(loAddr, 10548);
socket2 = ifacemgr->openSocketFromAddress(loAddr, port2);
);
// socket descriptor must be positive integer
EXPECT_GT(socket2, 0);
close(socket2);
delete ifacemgr;
}
TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
boost::scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
// Open v6 socket to connect to remote address.
// Loopback address is the only one that we know
// so let's treat it as remote address.
int socket1 = 0;
const uint16_t port1 = 10547;
IOAddress loAddr6("::1");
EXPECT_NO_THROW(
socket1 = ifacemgr->openSocketFromRemoteAddress(loAddr6, 10547);
socket1 = ifacemgr->openSocketFromRemoteAddress(loAddr6, port1);
);
EXPECT_GT(socket1, 0);
close(socket1);
// Open v4 socket to connect to remote address.
int socket2 = 0;
const uint16_t port2 = 10548;
IOAddress loAddr("127.0.0.1");
EXPECT_NO_THROW(
socket2 = ifacemgr->openSocketFromRemoteAddress(loAddr, 10548);
socket2 = ifacemgr->openSocketFromRemoteAddress(loAddr, port2);
);
EXPECT_GT(socket2, 0);
close(socket2);
delete ifacemgr;
}
// TODO: disabled due to other naming on various systems
......
Supports Markdown
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