face, mgmt: improve face creation failure and bad URI handling
Prevent creation of faces to endpoints owned by NFD instance
Prevent creation of UDP broadcast faces (255.255.255.255 and
those belonging to machine's interfaces) in response to
face creation command
Sanity check configuration file port numbers in face manager
refs: #1414, #1427
Change-Id: Ia3f0a9337f3d97c34388773eab05bc39ad6dd804
diff --git a/daemon/core/network-interface.cpp b/daemon/core/network-interface.cpp
index ef55e7b..c1cfaa6 100644
--- a/daemon/core/network-interface.cpp
+++ b/daemon/core/network-interface.cpp
@@ -95,6 +95,17 @@
break;
#endif
}
+
+ if (netif->isBroadcastCapable() && ifa->ifa_broadaddr != 0)
+ {
+ const sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(ifa->ifa_broadaddr);
+
+ char address[INET_ADDRSTRLEN];
+ if (::inet_ntop(AF_INET, &sin->sin_addr, address, sizeof(address)))
+ netif->broadcastAddress = boost::asio::ip::address_v4::from_string(address);
+ else
+ NFD_LOG_WARN("inet_ntop() failed on " << ifname);
+ }
}
::freeifaddrs(ifa_list);
diff --git a/daemon/core/network-interface.hpp b/daemon/core/network-interface.hpp
index d02171a..0265461 100644
--- a/daemon/core/network-interface.hpp
+++ b/daemon/core/network-interface.hpp
@@ -17,11 +17,13 @@
class NetworkInterfaceInfo
{
public:
+
int index;
std::string name;
ethernet::Address etherAddress;
std::vector<boost::asio::ip::address_v4> ipv4Addresses;
std::vector<boost::asio::ip::address_v6> ipv6Addresses;
+ boost::asio::ip::address_v4 broadcastAddress;
unsigned int flags;
bool
@@ -31,7 +33,11 @@
isMulticastCapable() const;
bool
+ isBroadcastCapable() const;
+
+ bool
isUp() const;
+
};
inline bool
@@ -47,6 +53,12 @@
}
inline bool
+NetworkInterfaceInfo::isBroadcastCapable() const
+{
+ return (flags & IFF_BROADCAST) != 0;
+}
+
+inline bool
NetworkInterfaceInfo::isUp() const
{
return (flags & IFF_UP) != 0;
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index d301350..cd3119e 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -7,6 +7,7 @@
#include "tcp-factory.hpp"
#include "core/resolver.hpp"
#include "core/logger.hpp"
+#include "core/network-interface.hpp"
NFD_LOG_INIT("TcpFactory");
@@ -15,6 +16,78 @@
TcpFactory::TcpFactory(const std::string& defaultPort/* = "6363"*/)
: m_defaultPort(defaultPort)
{
+
+}
+
+void
+TcpFactory::prohibitEndpoint(const tcp::Endpoint& endpoint)
+{
+ using namespace boost::asio::ip;
+
+ static const address_v4 ALL_V4_ENDPOINT(address_v4::from_string("0.0.0.0"));
+ static const address_v6 ALL_V6_ENDPOINT(address_v6::from_string("::"));
+
+ const address& address = endpoint.address();
+
+ if (address.is_v4() && address == ALL_V4_ENDPOINT)
+ {
+ prohibitAllIpv4Endpoints(endpoint.port());
+ }
+ else if (endpoint.address().is_v6() && address == ALL_V6_ENDPOINT)
+ {
+ prohibitAllIpv6Endpoints(endpoint.port());
+ }
+
+ NFD_LOG_TRACE("prohibiting TCP " <<
+ endpoint.address().to_string() << ":" << endpoint.port());
+
+ m_prohibitedEndpoints.insert(endpoint);
+}
+
+void
+TcpFactory::prohibitAllIpv4Endpoints(const uint16_t port)
+{
+ using namespace boost::asio::ip;
+
+ const std::list<shared_ptr<NetworkInterfaceInfo> > nicList(listNetworkInterfaces());
+
+ for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i = nicList.begin();
+ i != nicList.end();
+ ++i)
+ {
+ const shared_ptr<NetworkInterfaceInfo>& nic = *i;
+ const std::vector<address_v4>& ipv4Addresses = nic->ipv4Addresses;
+
+ for (std::vector<address_v4>::const_iterator j = ipv4Addresses.begin();
+ j != ipv4Addresses.end();
+ ++j)
+ {
+ prohibitEndpoint(tcp::Endpoint(*j, port));
+ }
+ }
+}
+
+void
+TcpFactory::prohibitAllIpv6Endpoints(const uint16_t port)
+{
+ using namespace boost::asio::ip;
+
+ const std::list<shared_ptr<NetworkInterfaceInfo> > nicList(listNetworkInterfaces());
+
+ for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i = nicList.begin();
+ i != nicList.end();
+ ++i)
+ {
+ const shared_ptr<NetworkInterfaceInfo>& nic = *i;
+ const std::vector<address_v6>& ipv6Addresses = nic->ipv6Addresses;
+
+ for (std::vector<address_v6>::const_iterator j = ipv6Addresses.begin();
+ j != ipv6Addresses.end();
+ ++j)
+ {
+ prohibitEndpoint(tcp::Endpoint(*j, port));
+ }
+ }
}
shared_ptr<TcpChannel>
@@ -26,6 +99,8 @@
channel = make_shared<TcpChannel>(boost::cref(endpoint));
m_channels[endpoint] = channel;
+ prohibitEndpoint(endpoint);
+
NFD_LOG_DEBUG("Channel [" << endpoint << "] created");
return channel;
}
@@ -57,6 +132,11 @@
else if (uri.getScheme() == "tcp6")
addressSelector = resolver::Ipv6Address();
+ if (!uri.getPath().empty())
+ {
+ onConnectFailed("Invalid URI");
+ }
+
TcpResolver::asyncResolve(uri.getHost(),
uri.getPort().empty() ? m_defaultPort : uri.getPort(),
bind(&TcpFactory::continueCreateFaceAfterResolve, this, _1,
@@ -70,6 +150,13 @@
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed)
{
+ if (m_prohibitedEndpoints.find(endpoint) != m_prohibitedEndpoints.end())
+ {
+ onConnectFailed("Requested endpoint is prohibited "
+ "(reserved by this NFD or disallowed by face management protocol)");
+ return;
+ }
+
// very simple logic for now
for (ChannelMap::iterator channel = m_channels.begin();
diff --git a/daemon/face/tcp-factory.hpp b/daemon/face/tcp-factory.hpp
index 6ba2e37..d4b6618 100644
--- a/daemon/face/tcp-factory.hpp
+++ b/daemon/face/tcp-factory.hpp
@@ -67,6 +67,16 @@
const FaceConnectFailedCallback& onConnectFailed);
private:
+
+ void
+ prohibitEndpoint(const tcp::Endpoint& endpoint);
+
+ void
+ prohibitAllIpv4Endpoints(const uint16_t port);
+
+ void
+ prohibitAllIpv6Endpoints(const uint16_t port);
+
/**
* \brief Look up TcpChannel using specified local endpoint
*
@@ -88,6 +98,8 @@
ChannelMap m_channels;
std::string m_defaultPort;
+
+ std::set<tcp::Endpoint> m_prohibitedEndpoints;
};
} // namespace nfd
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index 390b412..49c22b7 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -31,7 +31,7 @@
{
m_socket->set_option(ip::v6_only(true));
}
-
+
try {
m_socket->bind(m_localEndpoint);
}
@@ -41,9 +41,9 @@
throw Error("Failed to properly configure the socket. "
"UdpChannel creation aborted, check the address (" + std::string(e.what()) + ")");
}
-
+
this->setUri(FaceUri(localEndpoint));
-
+
//setting the timeout to close the idle faces
m_closeIdleFaceEvent = scheduler::schedule(m_idleFaceTimeout,
bind(&UdpChannel::closeIdleFaces, this));
@@ -62,7 +62,7 @@
throw Error("Listen already called on this channel");
}
m_isListening = true;
-
+
onFaceCreatedNewPeerCallback = onFaceCreated;
onConnectFailedNewPeerCallback = onListenFailed;
@@ -76,7 +76,8 @@
void
UdpChannel::connect(const udp::Endpoint& remoteEndpoint,
- const FaceCreatedCallback& onFaceCreated)
+ const FaceCreatedCallback& onFaceCreated,
+ const ConnectFailedCallback& onConnectFailed)
{
ChannelFaceMap::iterator i = m_channelFaces.find(remoteEndpoint);
if (i != m_channelFaces.end()) {
@@ -88,10 +89,10 @@
//creating a new socket for the face that will be created soon
shared_ptr<ip::udp::socket> clientSocket =
make_shared<ip::udp::socket>(boost::ref(getGlobalIoService()));
-
+
clientSocket->open(m_localEndpoint.protocol());
clientSocket->set_option(ip::udp::socket::reuse_address(true));
-
+
try {
clientSocket->bind(m_localEndpoint);
clientSocket->connect(remoteEndpoint); //@todo connect or async_connect
@@ -101,8 +102,8 @@
}
catch (boost::system::system_error& e) {
clientSocket->close();
- throw Error("Failed to properly configure the socket. Check the address ("
- + std::string(e.what()) + ")");
+ onConnectFailed("Failed to configure socket (" + std::string(e.what()) + ")");
+ return;
}
createFace(clientSocket, onFaceCreated, false);
}
@@ -144,7 +145,7 @@
return;
}
- connect(*remoteEndpoint, onFaceCreated);
+ connect(*remoteEndpoint, onFaceCreated, onConnectFailed);
}
size_t
@@ -229,7 +230,7 @@
UdpChannel::closeIdleFaces()
{
ChannelFaceMap::iterator next = m_channelFaces.begin();
-
+
while (next != m_channelFaces.end()) {
ChannelFaceMap::iterator it = next;
next++;
diff --git a/daemon/face/udp-channel.hpp b/daemon/face/udp-channel.hpp
index 0243dd6..f5dd16e 100644
--- a/daemon/face/udp-channel.hpp
+++ b/daemon/face/udp-channel.hpp
@@ -69,7 +69,8 @@
*/
void
connect(const udp::Endpoint& remoteEndpoint,
- const FaceCreatedCallback& onFaceCreated);
+ const FaceCreatedCallback& onFaceCreated,
+ const ConnectFailedCallback& onConnectFailed);
/**
* \brief Create a face by establishing connection to the specified
* remote host and remote port
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 36b1fcd..e99961a 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -7,6 +7,7 @@
#include "udp-factory.hpp"
#include "core/global-io.hpp"
#include "core/resolver.hpp"
+#include "core/network-interface.hpp"
namespace nfd {
@@ -19,6 +20,89 @@
{
}
+
+
+void
+UdpFactory::prohibitEndpoint(const udp::Endpoint& endpoint)
+{
+ using namespace boost::asio::ip;
+
+ static const address_v4 ALL_V4_ENDPOINT(address_v4::from_string("0.0.0.0"));
+ static const address_v6 ALL_V6_ENDPOINT(address_v6::from_string("::"));
+
+ const address& address = endpoint.address();
+
+ if (address.is_v4() && address == ALL_V4_ENDPOINT)
+ {
+ prohibitAllIpv4Endpoints(endpoint.port());
+ }
+ else if (endpoint.address().is_v6() && address == ALL_V6_ENDPOINT)
+ {
+ prohibitAllIpv6Endpoints(endpoint.port());
+ }
+
+ NFD_LOG_TRACE("prohibiting UDP " <<
+ endpoint.address().to_string() << ":" << endpoint.port());
+
+ m_prohibitedEndpoints.insert(endpoint);
+}
+
+void
+UdpFactory::prohibitAllIpv4Endpoints(const uint16_t port)
+{
+ using namespace boost::asio::ip;
+
+ static const address_v4 INVALID_BROADCAST(address_v4::from_string("0.0.0.0"));
+
+ const std::list<shared_ptr<NetworkInterfaceInfo> > nicList(listNetworkInterfaces());
+
+ for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i = nicList.begin();
+ i != nicList.end();
+ ++i)
+ {
+ const shared_ptr<NetworkInterfaceInfo>& nic = *i;
+ const std::vector<address_v4>& ipv4Addresses = nic->ipv4Addresses;
+
+ for (std::vector<address_v4>::const_iterator j = ipv4Addresses.begin();
+ j != ipv4Addresses.end();
+ ++j)
+ {
+ prohibitEndpoint(udp::Endpoint(*j, port));
+ }
+
+ if (nic->isBroadcastCapable() && nic->broadcastAddress != INVALID_BROADCAST)
+ {
+ NFD_LOG_TRACE("prohibiting broadcast address: " << nic->broadcastAddress.to_string());
+ prohibitEndpoint(udp::Endpoint(nic->broadcastAddress, port));
+ }
+ }
+
+ prohibitEndpoint(udp::Endpoint(address::from_string("255.255.255.255"), port));
+}
+
+void
+UdpFactory::prohibitAllIpv6Endpoints(const uint16_t port)
+{
+ using namespace boost::asio::ip;
+
+ const std::list<shared_ptr<NetworkInterfaceInfo> > nicList(listNetworkInterfaces());
+
+ for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i = nicList.begin();
+ i != nicList.end();
+ ++i)
+ {
+ const shared_ptr<NetworkInterfaceInfo>& nic = *i;
+ const std::vector<address_v6>& ipv6Addresses = nic->ipv6Addresses;
+
+ for (std::vector<address_v6>::const_iterator j = ipv6Addresses.begin();
+ j != ipv6Addresses.end();
+ ++j)
+ {
+ prohibitEndpoint(udp::Endpoint(*j, port));
+ }
+ }
+}
+
shared_ptr<UdpChannel>
UdpFactory::createChannel(const udp::Endpoint& endpoint,
const time::seconds& timeout)
@@ -45,6 +129,7 @@
channel = make_shared<UdpChannel>(boost::cref(endpoint),
timeout);
m_channels[endpoint] = channel;
+ prohibitEndpoint(endpoint);
return channel;
}
@@ -80,6 +165,11 @@
"endpoint is already allocated for a UDP unicast channel");
}
+ if (m_prohibitedEndpoints.find(multicastEndpoint) != m_prohibitedEndpoints.end()) {
+ throw Error("Cannot create the requested UDP multicast face, "
+ "remote endpoint is owned by this NFD instance");
+ }
+
if (localEndpoint.address().is_v6() || multicastEndpoint.address().is_v6()) {
throw Error("IPv6 multicast is not supported yet. Please provide an IPv4 address");
}
@@ -149,6 +239,11 @@
else if (uri.getScheme() == "udp6")
addressSelector = resolver::Ipv6Address();
+ if (!uri.getPath().empty())
+ {
+ onConnectFailed("Invalid URI");
+ }
+
UdpResolver::asyncResolve(uri.getHost(),
uri.getPort().empty() ? m_defaultPort : uri.getPort(),
bind(&UdpFactory::continueCreateFaceAfterResolve, this, _1,
@@ -168,6 +263,13 @@
return;
}
+ if (m_prohibitedEndpoints.find(endpoint) != m_prohibitedEndpoints.end())
+ {
+ onConnectFailed("Requested endpoint is prohibited "
+ "(reserved by this NFD or disallowed by face management protocol)");
+ return;
+ }
+
// very simple logic for now
for (ChannelMap::iterator channel = m_channels.begin();
@@ -177,7 +279,7 @@
if ((channel->first.address().is_v4() && endpoint.address().is_v4()) ||
(channel->first.address().is_v6() && endpoint.address().is_v6()))
{
- channel->second->connect(endpoint, onCreated);
+ channel->second->connect(endpoint, onCreated, onConnectFailed);
return;
}
}
diff --git a/daemon/face/udp-factory.hpp b/daemon/face/udp-factory.hpp
index 969ef8c..fe69794 100644
--- a/daemon/face/udp-factory.hpp
+++ b/daemon/face/udp-factory.hpp
@@ -26,7 +26,7 @@
{
Error(const std::string& what) : ProtocolFactory::Error(what) {}
};
-
+
explicit
UdpFactory(const std::string& defaultPort = "6363");
@@ -66,10 +66,10 @@
*
* Note that this call will **BLOCK** until resolution is done or failed.
*
- * If localHost is a IPv6 address of a specific device, it must be in the form:
+ * If localHost is a IPv6 address of a specific device, it must be in the form:
* ip address%interface name
* Example: fe80::5e96:9dff:fe7d:9c8d%en1
- * Otherwise, you can use ::
+ * Otherwise, you can use ::
*
* Once a face is created, if it doesn't send/receive anything for
* a period of time equal to timeout, it will be destroyed
@@ -98,7 +98,7 @@
* creation fails and an exception is thrown
*
* \returns always a valid pointer to a MulticastUdpFace object, an exception
- * is thrown if it cannot be created.
+ * is thrown if it cannot be created.
*
* \throws UdpFactory::Error
*
@@ -108,12 +108,12 @@
shared_ptr<MulticastUdpFace>
createMulticastFace(const udp::Endpoint& localEndpoint,
const udp::Endpoint& multicastEndpoint);
-
+
shared_ptr<MulticastUdpFace>
createMulticastFace(const std::string& localIp,
const std::string& multicastIp,
const std::string& multicastPort);
-
+
// from Factory
virtual void
createFace(const FaceUri& uri,
@@ -129,9 +129,19 @@
MulticastFaceMap m_multicastFaces;
private:
+
+ void
+ prohibitEndpoint(const udp::Endpoint& endpoint);
+
+ void
+ prohibitAllIpv4Endpoints(const uint16_t port);
+
+ void
+ prohibitAllIpv6Endpoints(const uint16_t port);
+
void
afterFaceFailed(udp::Endpoint& endpoint);
-
+
/**
* \brief Look up UdpChannel using specified local endpoint
*
@@ -142,8 +152,8 @@
*/
shared_ptr<UdpChannel>
findChannel(const udp::Endpoint& localEndpoint);
-
-
+
+
/**
* \brief Look up multicast UdpFace using specified local endpoint
*
@@ -154,16 +164,18 @@
*/
shared_ptr<MulticastUdpFace>
findMulticastFace(const udp::Endpoint& localEndpoint);
-
+
void
continueCreateFaceAfterResolve(const udp::Endpoint& endpoint,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed);
-
+
typedef std::map< udp::Endpoint, shared_ptr<UdpChannel> > ChannelMap;
ChannelMap m_channels;
-
+
std::string m_defaultPort;
+
+ std::set<udp::Endpoint> m_prohibitedEndpoints;
};
} // namespace nfd
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index 183af17..406d524 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -242,6 +242,16 @@
if (i->first == "port")
{
port = i->second.get_value<std::string>();
+ try
+ {
+ uint16_t portNo = boost::lexical_cast<uint16_t>(port);
+ NFD_LOG_TRACE("TCP port set to " << portNo);
+ }
+ catch (const std::bad_cast& error)
+ {
+ throw ConfigFile::Error("Invalid value for option " +
+ i->first + "\" in \"udp\" section");
+ }
}
else if (i->first == "listen")
{
@@ -311,6 +321,16 @@
if (i->first == "port")
{
port = i->second.get_value<std::string>();
+ try
+ {
+ uint16_t portNo = boost::lexical_cast<uint16_t>(port);
+ NFD_LOG_TRACE("UDP port set to " << portNo);
+ }
+ catch (const std::bad_cast& error)
+ {
+ throw ConfigFile::Error("Invalid value for option " +
+ i->first + "\" in \"udp\" section");
+ }
}
else if (i->first == "idle_timeout")
{
@@ -346,6 +366,16 @@
else if (i->first == "mcast_port")
{
mcastPort = i->second.get_value<std::string>();
+ try
+ {
+ uint16_t portNo = boost::lexical_cast<uint16_t>(mcastPort);
+ NFD_LOG_TRACE("UDP multicast port set to " << portNo);
+ }
+ catch (const std::bad_cast& error)
+ {
+ throw ConfigFile::Error("Invalid value for option " +
+ i->first + "\" in \"udp\" section");
+ }
}
else if (i->first == "mcast_group")
{
@@ -581,7 +611,7 @@
FaceManager::onConnectFailed(const Name& requestName, const std::string& reason)
{
NFD_LOG_DEBUG("Failed to create face: " << reason);
- sendResponse(requestName, 400, "Failed to create face");
+ sendResponse(requestName, 408, reason);
}
void
@@ -594,6 +624,7 @@
if (!validateParameters(command, parameters))
{
sendResponse(requestName, 400, "Malformed command");
+ NFD_LOG_TRACE("invalid control parameters URI");
return;
}
@@ -601,6 +632,7 @@
if (!uri.parse(parameters.getUri()))
{
sendResponse(requestName, 400, "Malformed command");
+ NFD_LOG_TRACE("failed to parse URI");
return;
}
@@ -611,9 +643,30 @@
return;
}
- factory->second->createFace(uri,
- bind(&FaceManager::onCreated, this, requestName, parameters, _1),
- bind(&FaceManager::onConnectFailed, this, requestName, _1));
+ try
+ {
+ factory->second->createFace(uri,
+ bind(&FaceManager::onCreated,
+ this, requestName, parameters, _1),
+ bind(&FaceManager::onConnectFailed,
+ this, requestName, _1));
+ }
+ catch (const std::runtime_error& error)
+ {
+ std::string errorMessage = "NFD error: ";
+ errorMessage += error.what();
+
+ NFD_LOG_ERROR(errorMessage);
+ sendResponse(requestName, 500, errorMessage);
+ }
+ catch (const std::logic_error& error)
+ {
+ std::string errorMessage = "NFD error: ";
+ errorMessage += error.what();
+
+ NFD_LOG_ERROR(errorMessage);
+ sendResponse(requestName, 500, errorMessage);
+ }
}
diff --git a/tests/face/tcp.cpp b/tests/face/tcp.cpp
index 6bbe4ba..b71de48 100644
--- a/tests/face/tcp.cpp
+++ b/tests/face/tcp.cpp
@@ -161,13 +161,12 @@
std::list< shared_ptr<Face> > faces;
};
-
BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
{
- TcpFactory factory;
+ TcpFactory factory1;
- shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
- factory.createChannel("127.0.0.1", "20071");
+ shared_ptr<TcpChannel> channel1 = factory1.createChannel("127.0.0.1", "20070");
+ factory1.createChannel("127.0.0.1", "20071");
BOOST_CHECK_EQUAL(channel1->isListening(), false);
@@ -176,9 +175,14 @@
BOOST_CHECK_EQUAL(channel1->isListening(), true);
- factory.createFace(FaceUri("tcp://127.0.0.1:20070"),
- bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+ TcpFactory factory2;
+
+ shared_ptr<TcpChannel> channel2 = factory2.createChannel("127.0.0.2", "20070");
+ factory2.createChannel("127.0.0.2", "20071");
+
+ factory2.createFace(FaceUri("tcp://127.0.0.1:20070"),
+ bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+ bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
"TcpChannel error: cannot connect or cannot accept connection");
@@ -253,17 +257,21 @@
BOOST_FIXTURE_TEST_CASE(EndToEnd6, EndToEndFixture)
{
- TcpFactory factory;
+ TcpFactory factory1;
- shared_ptr<TcpChannel> channel1 = factory.createChannel("::1", "20070");
- shared_ptr<TcpChannel> channel2 = factory.createChannel("::1", "20071");
+ shared_ptr<TcpChannel> channel1 = factory1.createChannel("::1", "20070");
+ shared_ptr<TcpChannel> channel2 = factory1.createChannel("::1", "20071");
channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
- factory.createFace(FaceUri("tcp://[::1]:20070"),
- bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+ TcpFactory factory2;
+
+ factory2.createChannel("::2", "20070");
+
+ factory2.createFace(FaceUri("tcp://[::1]:20070"),
+ bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+ bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
"TcpChannel error: cannot connect or cannot accept connection");
diff --git a/tests/mgmt/face-manager.cpp b/tests/mgmt/face-manager.cpp
index 4d6830c..ebae6f7 100644
--- a/tests/mgmt/face-manager.cpp
+++ b/tests/mgmt/face-manager.cpp
@@ -1465,7 +1465,7 @@
getFace()->onReceiveData +=
bind(&FaceFixture::validateControlResponse, this, _1,
- command->getName(), 400, "Failed to create face");
+ command->getName(), 408, "unit-test-reason");
onConnectFailed(command->getName(), "unit-test-reason");