core: use ndn::dns from ndn-cxx
refs #2207
Change-Id: Ice97c9203283b5b89982049cb29c0ccfed0ef422
diff --git a/core/resolver.hpp b/core/resolver.hpp
deleted file mode 100644
index d144645..0000000
--- a/core/resolver.hpp
+++ /dev/null
@@ -1,215 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_CORE_RESOLVER_H
-#define NFD_CORE_RESOLVER_H
-
-#include "common.hpp"
-#include "core/global-io.hpp"
-#include "core/scheduler.hpp"
-
-namespace nfd {
-namespace resolver {
-
-typedef function<bool (const boost::asio::ip::address& address)> AddressSelector;
-
-struct AnyAddress {
- bool
- operator()(const boost::asio::ip::address& address)
- {
- return true;
- }
-};
-
-struct Ipv4Address {
- bool
- operator()(const boost::asio::ip::address& address)
- {
- return address.is_v4();
- }
-};
-
-struct Ipv6Address {
- bool
- operator()(const boost::asio::ip::address& address)
- {
- return address.is_v6();
- }
-};
-
-} // namespace resolver
-
-template<class Protocol>
-class Resolver
-{
-public:
- struct Error : public std::runtime_error
- {
- Error(const std::string& what) : std::runtime_error(what) {}
- };
-
- typedef function<void (const typename Protocol::endpoint& endpoint)> SuccessCallback;
- typedef function<void (const std::string& reason)> ErrorCallback;
-
- typedef boost::asio::ip::basic_resolver< Protocol > resolver;
-
- /** \brief Asynchronously resolve host and port
- *
- * If an address selector predicate is specified, then each resolved IP address
- * is checked against the predicate.
- *
- * Available address selector predicates:
- *
- * - resolver::AnyAddress()
- * - resolver::Ipv4Address()
- * - resolver::Ipv6Address()
- */
- static void
- asyncResolve(const std::string& host, const std::string& port,
- const SuccessCallback& onSuccess,
- const ErrorCallback& onError,
- const nfd::resolver::AddressSelector& addressSelector = nfd::resolver::AnyAddress(),
- const time::seconds& timeout = time::seconds(4))
- {
- shared_ptr<Resolver> resolver =
- shared_ptr<Resolver>(new Resolver(onSuccess, onError,
- addressSelector));
-
- resolver->asyncResolve(host, port, timeout, resolver);
- // resolver will be destroyed when async operation finishes or global IO service stops
- }
-
- /** \brief Synchronously resolve host and port
- *
- * If an address selector predicate is specified, then each resolved IP address
- * is checked against the predicate.
- *
- * Available address selector predicates:
- *
- * - resolver::AnyAddress()
- * - resolver::Ipv4Address()
- * - resolver::Ipv6Address()
- */
- static typename Protocol::endpoint
- syncResolve(const std::string& host, const std::string& port,
- const nfd::resolver::AddressSelector& addressSelector = nfd::resolver::AnyAddress())
- {
- Resolver resolver(SuccessCallback(), ErrorCallback(), addressSelector);
-
- typename resolver::query query(host, port
-#if not defined(__FreeBSD__)
- , resolver::query::all_matching
-#endif
- );
-
- typename resolver::iterator remoteEndpoint = resolver.m_resolver.resolve(query);
- typename resolver::iterator end;
- for (; remoteEndpoint != end; ++remoteEndpoint)
- {
- if (addressSelector(typename Protocol::endpoint(*remoteEndpoint).address()))
- return *remoteEndpoint;
- }
- throw Error("No endpoint matching the specified address selector found");
- }
-
-private:
- Resolver(const SuccessCallback& onSuccess,
- const ErrorCallback& onError,
- const nfd::resolver::AddressSelector& addressSelector)
- : m_resolver(getGlobalIoService())
- , m_addressSelector(addressSelector)
- , m_onSuccess(onSuccess)
- , m_onError(onError)
- {
- }
-
- void
- asyncResolve(const std::string& host, const std::string& port,
- const time::seconds& timeout,
- const shared_ptr<Resolver>& self)
- {
- typename resolver::query query(host, port
-#if not defined(__FreeBSD__)
- , resolver::query::all_matching
-#endif
- );
-
- m_resolver.async_resolve(query,
- bind(&Resolver::onResolveSuccess, this, _1, _2, self));
-
- m_resolveTimeout = scheduler::schedule(timeout,
- bind(&Resolver::onResolveError, this,
- "Timeout", self));
- }
-
- void
- onResolveSuccess(const boost::system::error_code& error,
- typename resolver::iterator remoteEndpoint,
- const shared_ptr<Resolver>& self)
- {
- scheduler::cancel(m_resolveTimeout);
-
- if (error)
- {
- if (error == boost::system::errc::operation_canceled)
- return;
-
- return m_onError("Remote endpoint hostname or port cannot be resolved: " +
- error.category().message(error.value()));
- }
-
- typename resolver::iterator end;
- for (; remoteEndpoint != end; ++remoteEndpoint)
- {
- if (m_addressSelector(typename Protocol::endpoint(*remoteEndpoint).address()))
- return m_onSuccess(*remoteEndpoint);
- }
-
- m_onError("No endpoint matching the specified address selector found");
- }
-
- void
- onResolveError(const std::string& errorInfo,
- const shared_ptr<Resolver>& self)
- {
- m_resolver.cancel();
- m_onError(errorInfo);
- }
-
-private:
- resolver m_resolver;
- scheduler::EventId m_resolveTimeout;
-
- nfd::resolver::AddressSelector m_addressSelector;
- SuccessCallback m_onSuccess;
- ErrorCallback m_onError;
-};
-
-typedef Resolver<boost::asio::ip::tcp> TcpResolver;
-typedef Resolver<boost::asio::ip::udp> UdpResolver;
-
-} // namespace nfd
-
-#endif // NFD_CORE_RESOLVER_H
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index 598a2c4..0a152b1 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis
+ * Copyright (c) 2014-2015, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -24,9 +24,10 @@
*/
#include "tcp-factory.hpp"
-#include "core/resolver.hpp"
#include "core/logger.hpp"
#include "core/network-interface.hpp"
+#include "core/global-io.hpp"
+#include <ndn-cxx/util/dns.hpp>
NFD_LOG_INIT("TcpFactory");
@@ -110,7 +111,9 @@
shared_ptr<TcpChannel>
TcpFactory::createChannel(const std::string& localHost, const std::string& localPort)
{
- return createChannel(TcpResolver::syncResolve(localHost, localPort));
+ tcp::Endpoint endpoint(ndn::dns::syncResolve(localHost, getGlobalIoService()),
+ boost::lexical_cast<uint16_t>(localPort));
+ return createChannel(endpoint);
}
shared_ptr<TcpChannel>
@@ -128,30 +131,10 @@
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed)
{
- resolver::AddressSelector addressSelector = resolver::AnyAddress();
- if (uri.getScheme() == "tcp4")
- addressSelector = resolver::Ipv4Address();
- else if (uri.getScheme() == "tcp6")
- addressSelector = resolver::Ipv6Address();
+ BOOST_ASSERT(uri.isCanonical());
+ boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(uri.getHost());
+ tcp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(uri.getPort()));
- if (!uri.getPath().empty() && uri.getPath() != "/")
- {
- onConnectFailed("Invalid URI");
- }
-
- TcpResolver::asyncResolve(uri.getHost(),
- uri.getPort().empty() ? m_defaultPort : uri.getPort(),
- bind(&TcpFactory::continueCreateFaceAfterResolve, this, _1,
- onCreated, onConnectFailed),
- onConnectFailed,
- addressSelector);
-}
-
-void
-TcpFactory::continueCreateFaceAfterResolve(const tcp::Endpoint& endpoint,
- const FaceCreatedCallback& onCreated,
- const FaceConnectFailedCallback& onConnectFailed)
-{
if (m_prohibitedEndpoints.find(endpoint) != m_prohibitedEndpoints.end())
{
onConnectFailed("Requested endpoint is prohibited "
@@ -160,7 +143,6 @@
}
// very simple logic for now
-
for (ChannelMap::iterator channel = m_channels.begin();
channel != m_channels.end();
++channel)
diff --git a/daemon/face/tcp-factory.hpp b/daemon/face/tcp-factory.hpp
index e2ebda5..e50bf66 100644
--- a/daemon/face/tcp-factory.hpp
+++ b/daemon/face/tcp-factory.hpp
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis
+ * Copyright (c) 2014-2015, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -29,6 +29,7 @@
#include "protocol-factory.hpp"
#include "tcp-channel.hpp"
+
namespace nfd {
class TcpFactory : public ProtocolFactory
@@ -110,11 +111,6 @@
shared_ptr<TcpChannel>
findChannel(const tcp::Endpoint& localEndpoint);
- void
- continueCreateFaceAfterResolve(const tcp::Endpoint& endpoint,
- const FaceCreatedCallback& onCreated,
- const FaceConnectFailedCallback& onConnectFailed);
-
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
typedef std::map< tcp::Endpoint, shared_ptr<TcpChannel> > ChannelMap;
ChannelMap m_channels;
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 74064c3..4ef4e17 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -25,8 +25,8 @@
#include "udp-factory.hpp"
#include "core/global-io.hpp"
-#include "core/resolver.hpp"
#include "core/network-interface.hpp"
+#include <ndn-cxx/util/dns.hpp>
#if defined(__linux__)
#include <sys/socket.h>
@@ -140,7 +140,9 @@
const std::string& localPort,
const time::seconds& timeout)
{
- return createChannel(UdpResolver::syncResolve(localHost, localPort), timeout);
+ udp::Endpoint endPoint(ndn::dns::syncResolve(localHost, getGlobalIoService()),
+ boost::lexical_cast<uint16_t>(localPort));
+ return createChannel(endPoint, timeout);
}
shared_ptr<MulticastUdpFace>
@@ -251,12 +253,13 @@
const std::string& multicastPort,
const std::string& networkInterfaceName /* "" */)
{
+ udp::Endpoint localEndpoint(ndn::dns::syncResolve(localIp, getGlobalIoService()),
+ boost::lexical_cast<uint16_t>(multicastPort));
- return createMulticastFace(UdpResolver::syncResolve(localIp,
- multicastPort),
- UdpResolver::syncResolve(multicastIp,
- multicastPort),
- networkInterfaceName);
+ udp::Endpoint multicastEndpoint(ndn::dns::syncResolve(multicastIp, getGlobalIoService()),
+ boost::lexical_cast<uint16_t>(multicastPort));
+
+ return createMulticastFace(localEndpoint, multicastEndpoint, networkInterfaceName);
}
void
@@ -264,31 +267,10 @@
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed)
{
- resolver::AddressSelector addressSelector = resolver::AnyAddress();
- if (uri.getScheme() == "udp4")
- addressSelector = resolver::Ipv4Address();
- else if (uri.getScheme() == "udp6")
- addressSelector = resolver::Ipv6Address();
+ BOOST_ASSERT(uri.isCanonical());
+ boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(uri.getHost());
+ udp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(uri.getPort()));
- if (!uri.getPath().empty() && uri.getPath() != "/")
- {
- onConnectFailed("Invalid URI");
- }
-
- UdpResolver::asyncResolve(uri.getHost(),
- uri.getPort().empty() ? m_defaultPort : uri.getPort(),
- bind(&UdpFactory::continueCreateFaceAfterResolve, this, _1,
- onCreated, onConnectFailed),
- onConnectFailed,
- addressSelector);
-
-}
-
-void
-UdpFactory::continueCreateFaceAfterResolve(const udp::Endpoint& endpoint,
- const FaceCreatedCallback& onCreated,
- const FaceConnectFailedCallback& onConnectFailed)
-{
if (endpoint.address().is_multicast()) {
onConnectFailed("The provided address is multicast. Please use createMulticastFace method");
return;
diff --git a/daemon/face/udp-factory.hpp b/daemon/face/udp-factory.hpp
index 1f7f7de..db4760b 100644
--- a/daemon/face/udp-factory.hpp
+++ b/daemon/face/udp-factory.hpp
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis
+ * Copyright (c) 2014-2015, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -197,11 +197,6 @@
shared_ptr<MulticastUdpFace>
findMulticastFace(const udp::Endpoint& localEndpoint);
- void
- continueCreateFaceAfterResolve(const udp::Endpoint& endpoint,
- const FaceCreatedCallback& onCreated,
- const FaceConnectFailedCallback& onConnectFailed);
-
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
typedef std::map< udp::Endpoint, shared_ptr<UdpChannel> > ChannelMap;
diff --git a/daemon/face/websocket-factory.cpp b/daemon/face/websocket-factory.cpp
index 30f3afd..49f28b0 100644
--- a/daemon/face/websocket-factory.cpp
+++ b/daemon/face/websocket-factory.cpp
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis
+ * Copyright (c) 2014-2015, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -24,7 +24,7 @@
*/
#include "websocket-factory.hpp"
-#include "core/resolver.hpp"
+#include <ndn-cxx/util/dns.hpp>
namespace nfd {
@@ -53,7 +53,8 @@
shared_ptr<WebSocketChannel>
WebSocketFactory::createChannel(const std::string& host, const std::string& port)
{
- ip::tcp::endpoint tcpEndpoint = TcpResolver::syncResolve(host, port);
+ ip::tcp::endpoint tcpEndpoint(ndn::dns::syncResolve(host, getGlobalIoService()),
+ boost::lexical_cast<uint16_t>(port));
websocket::Endpoint endpoint(tcpEndpoint.address(), tcpEndpoint.port());
return createChannel(endpoint);
}
diff --git a/tests/core/resolver.cpp b/tests/core/resolver.cpp
deleted file mode 100644
index 18d35b7..0000000
--- a/tests/core/resolver.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014 Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "core/resolver.hpp"
-#include "core/logger.hpp"
-
-#include "tests/test-common.hpp"
-
-namespace nfd {
-namespace tests {
-
-NFD_LOG_INIT("tests.CoreResolver");
-
-using boost::asio::ip::address_v4;
-using boost::asio::ip::address_v6;
-using boost::asio::ip::tcp;
-using boost::asio::ip::udp;
-
-BOOST_FIXTURE_TEST_SUITE(CoreResolver, BaseFixture)
-
-template<class Protocol>
-class ResolverFixture : protected BaseFixture
-{
-public:
- ResolverFixture()
- : m_nFailures(0)
- , m_nSuccesses(0)
- {
- }
-
- void
- onSuccess(const typename Protocol::endpoint& resolvedEndpoint,
- const typename Protocol::endpoint& expectedEndpoint,
- bool isValid, bool wantCheckAddress = false)
- {
- NFD_LOG_DEBUG("Resolved to: " << resolvedEndpoint);
- ++m_nSuccesses;
-
- if (!isValid)
- {
- BOOST_FAIL("Resolved to " + boost::lexical_cast<std::string>(resolvedEndpoint)
- + ", but it should have failed");
- }
-
- BOOST_CHECK_EQUAL(resolvedEndpoint.port(), expectedEndpoint.port());
-
- BOOST_CHECK_EQUAL(resolvedEndpoint.address().is_v4(), expectedEndpoint.address().is_v4());
-
- // checking address is not deterministic and should be enabled only
- // if only one IP address will be returned by resolution
- if (wantCheckAddress)
- {
- BOOST_CHECK_EQUAL(resolvedEndpoint.address(), expectedEndpoint.address());
- }
- }
-
- void
- onFailure(bool isValid)
- {
- ++m_nFailures;
-
- if (!isValid)
- BOOST_FAIL("Resolution should not have failed");
-
- BOOST_CHECK_MESSAGE(true, "Resolution failed as expected");
- }
-
-
- uint32_t m_nFailures;
- uint32_t m_nSuccesses;
-};
-
-BOOST_FIXTURE_TEST_CASE(Tcp, ResolverFixture<tcp>)
-{
- TcpResolver::asyncResolve("www.named-data.net", "6363",
- bind(&ResolverFixture<tcp>::onSuccess, this, _1,
- tcp::endpoint(address_v4(), 6363), true, false),
- bind(&ResolverFixture<tcp>::onFailure, this, false));
-
- TcpResolver::asyncResolve("www.named-data.net", "notport",
- bind(&ResolverFixture<tcp>::onSuccess, this, _1,
- tcp::endpoint(address_v4(), 0), false, false),
- bind(&ResolverFixture<tcp>::onFailure, this, true)); // should fail
-
-
- TcpResolver::asyncResolve("nothost.nothost.nothost.arpa", "6363",
- bind(&ResolverFixture<tcp>::onSuccess, this, _1,
- tcp::endpoint(address_v4(), 6363), false, false),
- bind(&ResolverFixture<tcp>::onFailure, this, true)); // should fail
-
- TcpResolver::asyncResolve("www.google.com", "80",
- bind(&ResolverFixture<tcp>::onSuccess, this, _1,
- tcp::endpoint(address_v4(), 80), true, false),
- bind(&ResolverFixture<tcp>::onFailure, this, false),
- resolver::Ipv4Address()); // request IPv4 address
-
- TcpResolver::asyncResolve("www.google.com", "80",
- bind(&ResolverFixture<tcp>::onSuccess, this, _1,
- tcp::endpoint(address_v6(), 80), true, false),
- bind(&ResolverFixture<tcp>::onFailure, this, false),
- resolver::Ipv6Address()); // request IPv6 address
-
- TcpResolver::asyncResolve("ipv6.google.com", "80", // only IPv6 address should be available
- bind(&ResolverFixture<tcp>::onSuccess, this, _1,
- tcp::endpoint(address_v6(), 80), true, false),
- bind(&ResolverFixture<tcp>::onFailure, this, false));
-
- TcpResolver::asyncResolve("ipv6.google.com", "80", // only IPv6 address should be available
- bind(&ResolverFixture<tcp>::onSuccess, this, _1,
- tcp::endpoint(address_v6(), 80), true, false),
- bind(&ResolverFixture<tcp>::onFailure, this, false),
- resolver::Ipv6Address());
-
- TcpResolver::asyncResolve("ipv6.google.com", "80", // only IPv6 address should be available
- bind(&ResolverFixture<tcp>::onSuccess, this, _1,
- tcp::endpoint(address_v6(), 80), false, false),
- bind(&ResolverFixture<tcp>::onFailure, this, true), // should fail
- resolver::Ipv4Address());
-
- TcpResolver::asyncResolve("192.0.2.1", "80",
- bind(&ResolverFixture<tcp>::onSuccess, this, _1,
- tcp::endpoint(address_v4::from_string("192.0.2.1"), 80), true, true),
- bind(&ResolverFixture<tcp>::onFailure, this, false));
-
- TcpResolver::asyncResolve("2001:db8:3f9:0:3025:ccc5:eeeb:86d3", "80",
- bind(&ResolverFixture<tcp>::onSuccess, this, _1,
- tcp::endpoint(address_v6::
- from_string("2001:db8:3f9:0:3025:ccc5:eeeb:86d3"),
- 80), true, true),
- bind(&ResolverFixture<tcp>::onFailure, this, false));
-
- g_io.run();
-
- BOOST_CHECK_EQUAL(m_nFailures, 3);
- BOOST_CHECK_EQUAL(m_nSuccesses, 7);
-}
-
-BOOST_AUTO_TEST_CASE(SyncTcp)
-{
- tcp::endpoint endpoint;
- BOOST_CHECK_NO_THROW(endpoint = TcpResolver::syncResolve("www.named-data.net", "6363"));
- NFD_LOG_DEBUG("Resolved to: " << endpoint);
- BOOST_CHECK_EQUAL(endpoint.address().is_v4(), true);
- BOOST_CHECK_EQUAL(endpoint.port(), 6363);
-}
-
-BOOST_FIXTURE_TEST_CASE(Udp, ResolverFixture<udp>)
-{
- UdpResolver::asyncResolve("www.named-data.net", "6363",
- bind(&ResolverFixture<udp>::onSuccess, this, _1,
- udp::endpoint(address_v4(), 6363), true, false),
- bind(&ResolverFixture<udp>::onFailure, this, false));
-
- UdpResolver::asyncResolve("www.named-data.net", "notport",
- bind(&ResolverFixture<udp>::onSuccess, this, _1,
- udp::endpoint(address_v4(), 0), false, false),
- bind(&ResolverFixture<udp>::onFailure, this, true)); // should fail
-
-
- UdpResolver::asyncResolve("nothost.nothost.nothost.arpa", "6363",
- bind(&ResolverFixture<udp>::onSuccess, this, _1,
- udp::endpoint(address_v4(), 6363), false, false),
- bind(&ResolverFixture<udp>::onFailure, this, true)); // should fail
-
- UdpResolver::asyncResolve("www.google.com", "80",
- bind(&ResolverFixture<udp>::onSuccess, this, _1,
- udp::endpoint(address_v4(), 80), true, false),
- bind(&ResolverFixture<udp>::onFailure, this, false),
- resolver::Ipv4Address()); // request IPv4 address
-
- UdpResolver::asyncResolve("www.google.com", "80",
- bind(&ResolverFixture<udp>::onSuccess, this, _1,
- udp::endpoint(address_v6(), 80), true, false),
- bind(&ResolverFixture<udp>::onFailure, this, false),
- resolver::Ipv6Address()); // request IPv6 address
-
- UdpResolver::asyncResolve("ipv6.google.com", "80", // only IPv6 address should be available
- bind(&ResolverFixture<udp>::onSuccess, this, _1,
- udp::endpoint(address_v6(), 80), true, false),
- bind(&ResolverFixture<udp>::onFailure, this, false));
-
- UdpResolver::asyncResolve("ipv6.google.com", "80", // only IPv6 address should be available
- bind(&ResolverFixture<udp>::onSuccess, this, _1,
- udp::endpoint(address_v6(), 80), true, false),
- bind(&ResolverFixture<udp>::onFailure, this, false),
- resolver::Ipv6Address());
-
- UdpResolver::asyncResolve("ipv6.google.com", "80", // only IPv6 address should be available
- bind(&ResolverFixture<udp>::onSuccess, this, _1,
- udp::endpoint(address_v6(), 80), false, false),
- bind(&ResolverFixture<udp>::onFailure, this, true), // should fail
- resolver::Ipv4Address());
-
- UdpResolver::asyncResolve("192.0.2.1", "80",
- bind(&ResolverFixture<udp>::onSuccess, this, _1,
- udp::endpoint(address_v4::from_string("192.0.2.1"), 80), true, true),
- bind(&ResolverFixture<udp>::onFailure, this, false));
-
- UdpResolver::asyncResolve("2001:db8:3f9:0:3025:ccc5:eeeb:86d3", "80",
- bind(&ResolverFixture<udp>::onSuccess, this, _1,
- udp::endpoint(address_v6::
- from_string("2001:db8:3f9:0:3025:ccc5:eeeb:86d3"),
- 80), true, true),
- bind(&ResolverFixture<udp>::onFailure, this, false));
-
- g_io.run();
-
- BOOST_CHECK_EQUAL(m_nFailures, 3);
- BOOST_CHECK_EQUAL(m_nSuccesses, 7);
-}
-
-BOOST_AUTO_TEST_CASE(SyncUdp)
-{
- udp::endpoint endpoint;
- BOOST_CHECK_NO_THROW(endpoint = UdpResolver::syncResolve("www.named-data.net", "6363"));
- NFD_LOG_DEBUG("Resolved to: " << endpoint);
- BOOST_CHECK_EQUAL(endpoint.address().is_v4(), true);
- BOOST_CHECK_EQUAL(endpoint.port(), 6363);
-}
-
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-} // namespace nfd
diff --git a/tests/daemon/face/face-history.hpp b/tests/daemon/face/face-history.hpp
new file mode 100644
index 0000000..263a23a
--- /dev/null
+++ b/tests/daemon/face/face-history.hpp
@@ -0,0 +1,93 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TESTS_DAEMON_FACE_FACE_HISTORY_HPP
+#define NFD_TESTS_DAEMON_FACE_FACE_HISTORY_HPP
+
+#include "face/face.hpp"
+
+namespace nfd {
+namespace tests {
+
+/** \brief captures signals from Face
+ */
+class FaceHistory : noncopyable
+{
+public:
+ explicit
+ FaceHistory(Face& face)
+ : m_limitedIo(nullptr)
+ {
+ this->construct(face);
+ }
+
+ FaceHistory(Face& face, LimitedIo& limitedIo)
+ : m_limitedIo(&limitedIo)
+ {
+ this->construct(face);
+ }
+
+private:
+ void
+ construct(Face& face)
+ {
+ m_receiveInterestConn = face.onReceiveInterest.connect([this] (const Interest& interest) {
+ this->receivedInterests.push_back(interest);
+ this->afterOp();
+ });
+ m_receiveDataConn = face.onReceiveData.connect([this] (const Data& data) {
+ this->receivedData.push_back(data);
+ this->afterOp();
+ });
+ m_failConn = face.onFail.connect([this] (const std::string& reason) {
+ this->failures.push_back(reason);
+ this->afterOp();
+ });
+ }
+
+ void
+ afterOp()
+ {
+ if (m_limitedIo != nullptr) {
+ m_limitedIo->afterOp();
+ }
+ }
+
+public:
+ std::vector<Interest> receivedInterests;
+ std::vector<Data> receivedData;
+ std::vector<std::string> failures;
+
+private:
+ LimitedIo* m_limitedIo;
+ signal::ScopedConnection m_receiveInterestConn;
+ signal::ScopedConnection m_receiveDataConn;
+ signal::ScopedConnection m_failConn;
+};
+
+} // namespace tests
+} // namespace nfd
+
+#endif // NFD_TESTS_DAEMON_FACE_FACE_HISTORY_HPP
diff --git a/tests/daemon/face/tcp.cpp b/tests/daemon/face/tcp.cpp
index 51c4ae1..23899e6 100644
--- a/tests/daemon/face/tcp.cpp
+++ b/tests/daemon/face/tcp.cpp
@@ -24,7 +24,7 @@
*/
#include "face/tcp-factory.hpp"
-#include "core/resolver.hpp"
+#include <ndn-cxx/util/dns.hpp>
#include "core/network-interface.hpp"
#include <ndn-cxx/security/key-chain.hpp>
@@ -98,17 +98,16 @@
{
TcpFactory factory = TcpFactory();
- factory.createFace(FaceUri("tcp4://127.0.0.1"),
+ factory.createFace(FaceUri("tcp4://127.0.0.1:6363"),
+ bind(&FaceCreateFixture::ignore, this),
+ bind(&FaceCreateFixture::checkError, this, _1,
+ "No channels available to connect to 127.0.0.1:6363"));
+
+ factory.createChannel("127.0.0.1", "20071");
+
+ factory.createFace(FaceUri("tcp4://127.0.0.1:20070"),
bind(&FaceCreateFixture::ignore, this),
bind(&FaceCreateFixture::failIfError, this, _1));
-
- factory.createFace(FaceUri("tcp4://127.0.0.1/"),
- bind(&FaceCreateFixture::ignore, this),
- bind(&FaceCreateFixture::failIfError, this, _1));
-
- factory.createFace(FaceUri("tcp4://127.0.0.1/path"),
- bind(&FaceCreateFixture::ignore, this),
- bind(&FaceCreateFixture::checkError, this, _1, "Invalid URI"));
}
class EndToEndFixture : protected BaseFixture
@@ -263,7 +262,7 @@
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"),
+ factory2.createFace(FaceUri("tcp4://127.0.0.1:20070"),
bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
@@ -348,7 +347,7 @@
factory2.createChannel("::2", "20070");
- factory2.createFace(FaceUri("tcp://[::1]:20070"),
+ factory2.createFace(FaceUri("tcp6://[::1]:20070"),
bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
@@ -550,7 +549,8 @@
BOOST_REQUIRE_EQUAL(channel->isListening(), true);
DummyStreamSender<boost::asio::ip::tcp, Dataset> sender;
- sender.start(Resolver<boost::asio::ip::tcp>::syncResolve("127.0.0.1", "20070"));
+ tcp::Endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 20070);
+ sender.start(endpoint);
BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS,
time::seconds(1)) == LimitedIo::EXCEED_TIME,
@@ -582,7 +582,8 @@
BOOST_REQUIRE_EQUAL(channel->isListening(), true);
DummyStreamSender<boost::asio::ip::tcp, Dataset> sender;
- sender.start(Resolver<boost::asio::ip::tcp>::syncResolve(someIpv4Address, "20070"));
+ tcp::Endpoint endpoint(ndn::dns::syncResolve(someIpv4Address, getGlobalIoService()), 20070);
+ sender.start(endpoint);
BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS,
time::seconds(1)) == LimitedIo::EXCEED_TIME,
@@ -621,7 +622,7 @@
TcpFactory factory;
shared_ptr<TcpChannel> channel = factory.createChannel("0.0.0.0", "20070");
- factory.createFace(FaceUri("tcp://192.0.2.1:20070"),
+ factory.createFace(FaceUri("tcp4://192.0.2.1:20070"),
bind(&FaceCreateTimeoutFixture::onFaceCreated, this, _1),
bind(&FaceCreateTimeoutFixture::onConnectFailed, this, _1));
@@ -650,7 +651,7 @@
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"),
+ factory2.createFace(FaceUri("tcp4://127.0.0.1:20070"),
bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
diff --git a/tests/daemon/face/udp.cpp b/tests/daemon/face/udp.cpp
index 7109808..4d29e7d 100644
--- a/tests/daemon/face/udp.cpp
+++ b/tests/daemon/face/udp.cpp
@@ -28,6 +28,7 @@
#include "tests/test-common.hpp"
#include "tests/limited-io.hpp"
+#include "face-history.hpp"
namespace nfd {
namespace tests {
@@ -231,756 +232,373 @@
{
UdpFactory factory = UdpFactory();
- factory.createFace(FaceUri("udp4://127.0.0.1"),
+ factory.createFace(FaceUri("udp4://127.0.0.1:6363"),
bind(&FaceCreateFixture::ignore, this),
- bind(&FaceCreateFixture::failIfError, this, _1));
-
- factory.createFace(FaceUri("udp4://127.0.0.1/"),
- bind(&FaceCreateFixture::ignore, this),
- bind(&FaceCreateFixture::failIfError, this, _1));
-
- factory.createFace(FaceUri("udp4://127.0.0.1/path"),
- bind(&FaceCreateFixture::ignore, this),
- bind(&FaceCreateFixture::checkError, this, _1, "Invalid URI"));
-
-}
-
-class EndToEndFixture : protected BaseFixture
-{
-public:
- void
- channel1_onFaceCreated(const shared_ptr<Face>& newFace)
- {
- BOOST_CHECK(!static_cast<bool>(face1));
- channel1_onFaceCreatedNoCheck(newFace);
- }
-
- void
- channel1_onFaceCreatedNoCheck(const shared_ptr<Face>& newFace)
- {
- face1 = newFace;
- face1->onReceiveInterest.connect(bind(&EndToEndFixture::face1_onReceiveInterest, this, _1));
- face1->onReceiveData.connect(bind(&EndToEndFixture::face1_onReceiveData, this, _1));
- face1->onFail.connect(bind(&EndToEndFixture::face1_onFail, this));
- BOOST_CHECK_MESSAGE(true, "channel 1 face created");
-
- faces.push_back(face1);
-
- limitedIo.afterOp();
- }
-
- void
- channel1_onConnectFailed(const std::string& reason)
- {
- BOOST_CHECK_MESSAGE(false, reason);
-
- limitedIo.afterOp();
- }
-
- void
- face1_onReceiveInterest(const Interest& interest)
- {
- face1_receivedInterests.push_back(interest);
-
- limitedIo.afterOp();
- }
-
- void
- face1_onReceiveData(const Data& data)
- {
- face1_receivedDatas.push_back(data);
-
- limitedIo.afterOp();
- }
-
- void
- face1_onFail()
- {
- face1.reset();
- limitedIo.afterOp();
- }
-
- void
- channel2_onFaceCreated(const shared_ptr<Face>& newFace)
- {
- BOOST_CHECK(!static_cast<bool>(face2));
- face2 = newFace;
- face2->onReceiveInterest.connect(bind(&EndToEndFixture::face2_onReceiveInterest, this, _1));
- face2->onReceiveData.connect(bind(&EndToEndFixture::face2_onReceiveData, this, _1));
- face2->onFail.connect(bind(&EndToEndFixture::face2_onFail, this));
-
- faces.push_back(face2);
-
- BOOST_CHECK_MESSAGE(true, "channel 2 face created");
- limitedIo.afterOp();
- }
-
- void
- channel2_onConnectFailed(const std::string& reason)
- {
- BOOST_CHECK_MESSAGE(false, reason);
-
- limitedIo.afterOp();
- }
-
- void
- face2_onReceiveInterest(const Interest& interest)
- {
- face2_receivedInterests.push_back(interest);
-
- limitedIo.afterOp();
- }
-
- void
- face2_onReceiveData(const Data& data)
- {
- face2_receivedDatas.push_back(data);
-
- limitedIo.afterOp();
- }
-
- void
- face2_onFail()
- {
- face2.reset();
- limitedIo.afterOp();
- }
-
- void
- channel3_onFaceCreated(const shared_ptr<Face>& newFace)
- {
- BOOST_CHECK(!static_cast<bool>(face1));
- face3 = newFace;
- faces.push_back(newFace);
-
- limitedIo.afterOp();
- }
-
- void
- channel_onFaceCreated(const shared_ptr<Face>& newFace)
- {
- faces.push_back(newFace);
- limitedIo.afterOp();
- }
-
- void
- channel_onConnectFailed(const std::string& reason)
- {
- BOOST_CHECK_MESSAGE(false, reason);
-
- limitedIo.afterOp();
- }
-
- void
- channel_onConnectFailedOk(const std::string& reason)
- {
- // it's ok, it was supposed to fail
- limitedIo.afterOp();
- }
-
- void
- checkFaceList(size_t shouldBe)
- {
- BOOST_CHECK_EQUAL(faces.size(), shouldBe);
- }
-
- void
- connect(const shared_ptr<UdpChannel>& channel,
- const std::string& remoteHost,
- const std::string& remotePort)
- {
- channel->connect(remoteHost, remotePort,
- bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
- }
-
-public:
- LimitedIo limitedIo;
-
- shared_ptr<Face> face1;
- std::vector<Interest> face1_receivedInterests;
- std::vector<Data> face1_receivedDatas;
- shared_ptr<Face> face2;
- std::vector<Interest> face2_receivedInterests;
- std::vector<Data> face2_receivedDatas;
- shared_ptr<Face> face3;
-
- std::list< shared_ptr<Face> > faces;
-};
-
-
-BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
-{
- UdpFactory factory;
+ bind(&FaceCreateFixture::checkError, this, _1,
+ "No channels available to connect to 127.0.0.1:6363"));
factory.createChannel("127.0.0.1", "20071");
factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
- bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+ bind(&FaceCreateFixture::ignore, this),
+ bind(&FaceCreateFixture::failIfError, this, _1));
+}
+class EndToEndIpv4
+{
+public:
+ static const std::string
+ getScheme()
+ {
+ return "udp4";
+ }
- BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot connect or cannot accept connection");
+ static const std::string
+ getLocalIp()
+ {
+ return "127.0.0.1";
+ }
- BOOST_REQUIRE(static_cast<bool>(face2));
- BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "udp4://127.0.0.1:20070");
- BOOST_CHECK_EQUAL(face2->getLocalUri().toString(), "udp4://127.0.0.1:20071");
- BOOST_CHECK_EQUAL(face2->isLocal(), false);
+ static const std::string
+ getPort1()
+ {
+ return "20071";
+ }
+
+ static const std::string
+ getPort2()
+ {
+ return "20072";
+ }
+
+ static const std::string
+ getPort3()
+ {
+ return "20073";
+ }
+
+ static const FaceUri
+ getFaceUri1()
+ {
+ return FaceUri("udp4://127.0.0.1:20071");
+ }
+
+ static const FaceUri
+ getFaceUri2()
+ {
+ return FaceUri("udp4://127.0.0.1:20072");
+ }
+
+ static const FaceUri
+ getFaceUri3()
+ {
+ return FaceUri("udp4://127.0.0.1:20073");
+ }
+};
+
+class EndToEndIpv6
+{
+public:
+ static const std::string
+ getScheme()
+ {
+ return "udp6";
+ }
+
+ static const std::string
+ getLocalIp()
+ {
+ return "::1";
+ }
+
+ static const std::string
+ getPort1()
+ {
+ return "20071";
+ }
+
+ static const std::string
+ getPort2()
+ {
+ return "20072";
+ }
+
+ static const std::string
+ getPort3()
+ {
+ return "20073";
+ }
+
+ static const FaceUri
+ getFaceUri1()
+ {
+ return FaceUri("udp6://[::1]:20071");
+ }
+
+ static const FaceUri
+ getFaceUri2()
+ {
+ return FaceUri("udp6://[::1]:20072");
+ }
+
+ static const FaceUri
+ getFaceUri3()
+ {
+ return FaceUri("udp6://[::1]:20073");
+ }
+};
+
+typedef boost::mpl::list<EndToEndIpv4, EndToEndIpv6> EndToEndAddresses;
+
+// end to end communication
+BOOST_AUTO_TEST_CASE_TEMPLATE(EndToEnd, A, EndToEndAddresses)
+{
+ LimitedIo limitedIo;
+ UdpFactory factory;
+
+ shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1());
+
+ // face1 (on channel1) connects to face2 (on channel2, to be created)
+ shared_ptr<Face> face1;
+ unique_ptr<FaceHistory> history1;
+ factory.createFace(A::getFaceUri2(),
+ [&] (shared_ptr<Face> newFace) {
+ face1 = newFace;
+ history1.reset(new FaceHistory(*face1, limitedIo));
+ limitedIo.afterOp();
+ },
+ [] (const std::string& reason) { BOOST_ERROR(reason); });
+
+ limitedIo.run(1, time::seconds(1));
+ BOOST_REQUIRE(face1 != nullptr);
+ BOOST_CHECK_EQUAL(face1->getRemoteUri(), A::getFaceUri2());
+ BOOST_CHECK_EQUAL(face1->getLocalUri(), A::getFaceUri1());
+ BOOST_CHECK_EQUAL(face1->isLocal(), false); // UdpFace is never local
+ BOOST_CHECK_EQUAL(face1->getCounters().getNInBytes(), 0);
+ BOOST_CHECK_EQUAL(face1->getCounters().getNOutBytes(), 0);
+
+ // channel2 creation must be after face1 creation,
+ // otherwise channel2's endpoint would be prohibited
+ shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2());
+ shared_ptr<Face> face2;
+ unique_ptr<FaceHistory> history2;
+ channel2->listen([&] (shared_ptr<Face> newFace) {
+ BOOST_CHECK(face2 == nullptr);
+ face2 = newFace;
+ history2.reset(new FaceHistory(*face2, limitedIo));
+ limitedIo.afterOp();
+ },
+ [] (const std::string& reason) { BOOST_ERROR(reason); });
+
+ limitedIo.run(1, time::seconds(1));
+ BOOST_CHECK(face2 == nullptr); // face2 shouldn't be created until face1 sends something
+
+ shared_ptr<Interest> interest1 = makeInterest("/I1");
+ shared_ptr<Interest> interest2 = makeInterest("/I2");
+ shared_ptr<Data> data1 = makeData("/D1");
+ shared_ptr<Data> data2 = makeData("/D2");
+
+ // face1 sends to channel2, creates face2
+ face1->sendInterest(*interest1);
+ face1->sendData(*data1);
+ face1->sendData(*data1);
+ face1->sendData(*data1);
+ size_t nBytesSent1 = interest1->wireEncode().size() + 3 * data1->wireEncode().size();
+
+ limitedIo.run(5, time::seconds(1)); // 1 accept, 4 receives
+
+ BOOST_REQUIRE(face2 != nullptr);
+ BOOST_CHECK_EQUAL(face2->getRemoteUri(), A::getFaceUri1());
+ BOOST_CHECK_EQUAL(face2->getLocalUri(), A::getFaceUri2());
+ BOOST_CHECK_EQUAL(face2->isLocal(), false); // UdpFace is never local
+ BOOST_CHECK_EQUAL(face2->getCounters().getNInBytes(), nBytesSent1);
BOOST_CHECK_EQUAL(face2->getCounters().getNOutBytes(), 0);
- BOOST_CHECK_EQUAL(face2->getCounters().getNInBytes(), 0);
- // face1 is not created yet
- shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
- channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+ BOOST_REQUIRE_EQUAL(history2->receivedInterests.size(), 1);
+ BOOST_CHECK_EQUAL(history2->receivedInterests.front().getName(), interest1->getName());
+ BOOST_REQUIRE_EQUAL(history2->receivedData.size(), 3);
+ BOOST_CHECK_EQUAL(history2->receivedData.front().getName(), data1->getName());
- Interest interest1("ndn:/TpnzGvW9R");
- Data data1 ("ndn:/KfczhUqVix");
- data1.setContent(0, 0);
- Interest interest2("ndn:/QWiIMfj5sL");
- Data data2 ("ndn:/XNBV796f");
- data2.setContent(0, 0);
- Interest interest3("ndn:/QWiIhjgkj5sL");
- Data data3 ("ndn:/XNBV794f");
- data3.setContent(0, 0);
+ // face2 sends to face1
+ face2->sendInterest(*interest2);
+ face2->sendInterest(*interest2);
+ face2->sendInterest(*interest2);
+ face2->sendData(*data2);
+ size_t nBytesSent2 = 3 * interest2->wireEncode().size() + data2->wireEncode().size();
+ limitedIo.run(4, time::seconds(1)); // 4 receives
- ndn::SignatureSha256WithRsa fakeSignature;
- fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue,
- reinterpret_cast<const uint8_t*>(0),
- 0));
+ BOOST_REQUIRE_EQUAL(history1->receivedInterests.size(), 3);
+ BOOST_CHECK_EQUAL(history1->receivedInterests.front().getName(), interest2->getName());
+ BOOST_REQUIRE_EQUAL(history1->receivedData.size(), 1);
+ BOOST_CHECK_EQUAL(history1->receivedData.front().getName(), data2->getName());
- // set fake signature on data1 and data2
- data1.setSignature(fakeSignature);
- data2.setSignature(fakeSignature);
- data3.setSignature(fakeSignature);
-
- face2->sendInterest(interest2);
- face2->sendData (data2 );
- face2->sendData (data2 );
- face2->sendData (data2 );
- size_t nBytesSent2 = interest2.wireEncode().size() + data2.wireEncode().size() * 3;
-
- BOOST_CHECK_MESSAGE(limitedIo.run(5,//4 send + 1 listen return
- time::seconds(4)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot send or receive Interest/Data packets");
-
- BOOST_REQUIRE(static_cast<bool>(face1));
- BOOST_CHECK_EQUAL(face1->getRemoteUri().toString(), "udp4://127.0.0.1:20071");
- BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "udp4://127.0.0.1:20070");
- BOOST_CHECK_EQUAL(face1->isLocal(), false);
-
- face1->sendInterest(interest1);
- face1->sendInterest(interest1);
- face1->sendInterest(interest1);
- face1->sendData (data1 );
-
- BOOST_CHECK_MESSAGE(limitedIo.run(4, time::seconds(4)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot send or receive Interest/Data packets");
-
- BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
- BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 3);
- BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 3);
- BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
-
- BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2.getName());
- BOOST_CHECK_EQUAL(face1_receivedDatas [0].getName(), data2.getName());
- BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1.getName());
- BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1.getName());
-
-
-
- //checking if the connection accepting mechanism works properly.
-
- face2->sendData (data3 );
- face2->sendInterest(interest3);
- nBytesSent2 += data3.wireEncode().size() + interest3.wireEncode().size();
-
- BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot send or receive Interest/Data packets");
-
- BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 2);
- BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 4);
-
- BOOST_CHECK_EQUAL(face1_receivedInterests[1].getName(), interest3.getName());
- BOOST_CHECK_EQUAL(face1_receivedDatas [3].getName(), data3.getName());
-
+ // counters
const FaceCounters& counters1 = face1->getCounters();
- BOOST_CHECK_EQUAL(counters1.getNInInterests() , 2);
- BOOST_CHECK_EQUAL(counters1.getNInDatas() , 4);
- BOOST_CHECK_EQUAL(counters1.getNOutInterests(), 3);
- BOOST_CHECK_EQUAL(counters1.getNOutDatas() , 1);
+ BOOST_CHECK_EQUAL(counters1.getNInInterests(), 3);
+ BOOST_CHECK_EQUAL(counters1.getNInDatas(), 1);
+ BOOST_CHECK_EQUAL(counters1.getNOutInterests(), 1);
+ BOOST_CHECK_EQUAL(counters1.getNOutDatas(), 3);
BOOST_CHECK_EQUAL(counters1.getNInBytes(), nBytesSent2);
+ BOOST_CHECK_EQUAL(counters1.getNOutBytes(), nBytesSent1);
const FaceCounters& counters2 = face2->getCounters();
- BOOST_CHECK_EQUAL(counters2.getNInInterests() , 3);
- BOOST_CHECK_EQUAL(counters2.getNInDatas() , 1);
- BOOST_CHECK_EQUAL(counters2.getNOutInterests(), 2);
- BOOST_CHECK_EQUAL(counters2.getNOutDatas() , 4);
+ BOOST_CHECK_EQUAL(counters2.getNInInterests(), 1);
+ BOOST_CHECK_EQUAL(counters2.getNInDatas(), 3);
+ BOOST_CHECK_EQUAL(counters2.getNOutInterests(), 3);
+ BOOST_CHECK_EQUAL(counters2.getNOutDatas(), 1);
+ BOOST_CHECK_EQUAL(counters2.getNInBytes(), nBytesSent1);
BOOST_CHECK_EQUAL(counters2.getNOutBytes(), nBytesSent2);
}
-BOOST_FIXTURE_TEST_CASE(EndToEnd6, EndToEndFixture)
+// channel accepting multiple incoming connections
+BOOST_AUTO_TEST_CASE_TEMPLATE(MultipleAccepts, A, EndToEndAddresses)
{
+ LimitedIo limitedIo;
UdpFactory factory;
- factory.createChannel("::1", "20071");
+ // channel1 is listening
+ shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1());
+ std::vector<shared_ptr<Face>> faces1;
+ channel1->listen([&] (shared_ptr<Face> newFace) {
+ faces1.push_back(newFace);
+ limitedIo.afterOp();
+ },
+ [] (const std::string& reason) { BOOST_ERROR(reason); });
- factory.createFace(FaceUri("udp://[::1]:20070"),
- bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+ // face2 (on channel2) connects to channel1
+ shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2());
+ BOOST_CHECK_NE(channel1, channel2);
+ shared_ptr<Face> face2;
+ boost::asio::ip::address ipAddress2 = boost::asio::ip::address::from_string(A::getLocalIp());
+ udp::Endpoint endpoint2(ipAddress2, boost::lexical_cast<uint16_t>(A::getPort1()));
+ channel2->connect(endpoint2,
+ [&] (shared_ptr<Face> newFace) {
+ face2 = newFace;
+ limitedIo.afterOp();
+ },
+ [] (const std::string& reason) { BOOST_ERROR(reason); });
+ limitedIo.run(1, time::seconds(1)); // 1 create (on channel2)
+ BOOST_REQUIRE(face2 != nullptr);
+ BOOST_CHECK_EQUAL(faces1.size(), 0); // channel1 won't create face until face2 sends something
- BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot connect or cannot accept connection");
+ // face3 (on channel3) connects to channel1
+ shared_ptr<UdpChannel> channel3 = factory.createChannel(A::getLocalIp(), A::getPort3());
+ BOOST_CHECK_NE(channel1, channel3);
+ shared_ptr<Face> face3;
+ boost::asio::ip::address ipAddress3 = boost::asio::ip::address::from_string(A::getLocalIp());
+ udp::Endpoint endpoint3(ipAddress3, boost::lexical_cast<uint16_t>(A::getPort1()));
+ channel3->connect(endpoint3,
+ [&] (shared_ptr<Face> newFace) {
+ face3 = newFace;
+ limitedIo.afterOp();
+ },
+ [] (const std::string& reason) { BOOST_ERROR(reason); });
- BOOST_REQUIRE(static_cast<bool>(face2));
- BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "udp6://[::1]:20070");
- BOOST_CHECK_EQUAL(face2->getLocalUri().toString(), "udp6://[::1]:20071");
- BOOST_CHECK_EQUAL(face2->isLocal(), false);
- // face1 is not created yet
+ limitedIo.run(1, time::seconds(1)); // 1 create (on channel3)
+ BOOST_REQUIRE(face3 != nullptr);
+ BOOST_CHECK_EQUAL(faces1.size(), 0); // channel1 won't create face until face3 sends something
- shared_ptr<UdpChannel> channel1 = factory.createChannel("::1", "20070");
- channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+ // face2 sends to channel1
+ shared_ptr<Interest> interest2 = makeInterest("/I2");
+ face2->sendInterest(*interest2);
+ limitedIo.run(1, time::milliseconds(100)); // 1 accept (on channel1)
+ BOOST_REQUIRE_EQUAL(faces1.size(), 1);
+ BOOST_CHECK_EQUAL(channel1->size(), 1);
+ BOOST_CHECK_EQUAL(faces1.at(0)->getRemoteUri(), A::getFaceUri2());
- Interest interest1("ndn:/TpnzGvW9R");
- Data data1 ("ndn:/KfczhUqVix");
- data1.setContent(0, 0);
- Interest interest2("ndn:/QWiIMfj5sL");
- Data data2 ("ndn:/XNBV796f");
- data2.setContent(0, 0);
- Interest interest3("ndn:/QWiIhjgkj5sL");
- Data data3 ("ndn:/XNBV794f");
- data3.setContent(0, 0);
-
-
- ndn::SignatureSha256WithRsa fakeSignature;
- fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue,
- reinterpret_cast<const uint8_t*>(0),
- 0));
-
- // set fake signature on data1 and data2
- data1.setSignature(fakeSignature);
- data2.setSignature(fakeSignature);
- data3.setSignature(fakeSignature);
-
- face2->sendInterest(interest2);
- face2->sendData (data2 );
-
- BOOST_CHECK_MESSAGE(limitedIo.run(3,//2 send + 1 listen return
- time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot send or receive Interest/Data packets");
-
- BOOST_REQUIRE(static_cast<bool>(face1));
- BOOST_CHECK_EQUAL(face1->getRemoteUri().toString(), "udp6://[::1]:20071");
- BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "udp6://[::1]:20070");
- BOOST_CHECK_EQUAL(face1->isLocal(), false);
-
- face1->sendInterest(interest1);
- face1->sendData (data1 );
-
- BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot send or receive Interest/Data packets");
-
-
- BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
- BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 1);
- BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
- BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
-
- BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2.getName());
- BOOST_CHECK_EQUAL(face1_receivedDatas [0].getName(), data2.getName());
- BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1.getName());
- BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1.getName());
-
-
-
- //checking if the connection accepting mechanism works properly.
-
- face2->sendData (data3 );
- face2->sendInterest(interest3);
-
- BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot send or receive Interest/Data packets");
-
- BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 2);
- BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 2);
-
- BOOST_CHECK_EQUAL(face1_receivedInterests[1].getName(), interest3.getName());
- BOOST_CHECK_EQUAL(face1_receivedDatas [1].getName(), data3.getName());
+ // face3 sends to channel1
+ shared_ptr<Data> data3 = makeData("/D3");
+ face3->sendData(*data3);
+ limitedIo.run(1, time::milliseconds(100)); // 1 accept (on channel1)
+ BOOST_REQUIRE_EQUAL(faces1.size(), 2);
+ BOOST_CHECK_EQUAL(channel1->size(), 2);
+ BOOST_CHECK_EQUAL(faces1.at(1)->getRemoteUri(), A::getFaceUri3());
}
-BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
+// manually close a face
+BOOST_AUTO_TEST_CASE_TEMPLATE(ManualClose, A, EndToEndAddresses)
{
- Interest interest1("ndn:/TpnzGvW9R");
- Interest interest2("ndn:/QWiIMfj5sL");
-
+ LimitedIo limitedIo;
UdpFactory factory;
- shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
- shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+ shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1());
+ shared_ptr<Face> face1;
+ unique_ptr<FaceHistory> history1;
+ factory.createFace(A::getFaceUri2(),
+ [&] (shared_ptr<Face> newFace) {
+ face1 = newFace;
+ history1.reset(new FaceHistory(*face1, limitedIo));
+ limitedIo.afterOp();
+ },
+ [] (const std::string& reason) { BOOST_ERROR(reason); });
- channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+ limitedIo.run(1, time::milliseconds(100));
+ BOOST_REQUIRE(face1 != nullptr);
+ BOOST_CHECK_EQUAL(channel1->size(), 1);
- channel2->connect("127.0.0.1", "20070",
- bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
-
-
- BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot connect or cannot accept connection");
-
- BOOST_CHECK_EQUAL(faces.size(), 1);
-
- shared_ptr<UdpChannel> channel3 = factory.createChannel("127.0.0.1", "20072");
- channel3->connect("127.0.0.1", "20070",
- bind(&EndToEndFixture::channel3_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
-
- shared_ptr<UdpChannel> channel4 = factory.createChannel("127.0.0.1", "20073");
-
- BOOST_CHECK_NE(channel3, channel4);
-
- scheduler::schedule(time::milliseconds(500),
- bind(&EndToEndFixture::connect, this, channel4, "127.0.0.1", "20070"));
-
- scheduler::schedule(time::milliseconds(400), bind(&EndToEndFixture::checkFaceList, this, 2));
-
- BOOST_CHECK_MESSAGE(limitedIo.run(2,// 2 connects
- time::seconds(4)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot connect or cannot accept multiple connections");
-
- BOOST_CHECK_EQUAL(faces.size(), 3);
-
-
- face2->sendInterest(interest1);
- BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot send or receive Interest/Data packets");
-
- BOOST_CHECK_EQUAL(faces.size(), 4);
-
- face3->sendInterest(interest2);
- BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot send or receive Interest/Data packets");
-
- //channel1 should have created 2 faces, one when face2 sent an interest, one when face3 sent an interest
- BOOST_CHECK_EQUAL(faces.size(), 5);
- BOOST_CHECK_THROW(channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel_onConnectFailedOk, this, _1)),
- UdpChannel::Error);
-}
-
-//Test commented because it required to be run in a machine that can resolve ipv6 query
-//BOOST_FIXTURE_TEST_CASE(EndToEndIpv6, EndToEndFixture)
-//{
-// UdpFactory factory = UdpFactory();
-// Scheduler scheduler(g_io); // to limit the amount of time the test may take
-//
-// EventId abortEvent =
-// scheduler.scheduleEvent(time::seconds(1),
-// bind(&EndToEndFixture::abortTestCase, this,
-// "UdpChannel error: cannot connect or cannot accept connection"));
-//
-// limitedIoRemaining = 1;
-//
-// shared_ptr<UdpChannel> channel1 = factory.createChannel("::1", "20070");
-// shared_ptr<UdpChannel> channel2 = factory.createChannel("::1", "20071");
-//
-// channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
-// bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
-//
-// channel2->connect("::1", "20070",
-// bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
-// bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
-// g_io.run();
-// g_io.reset();
-// scheduler.cancelEvent(abortEvent);
-//
-// BOOST_REQUIRE(static_cast<bool>(face2));
-//
-// abortEvent =
-// scheduler.scheduleEvent(time::seconds(1),
-// bind(&EndToEndFixture::abortTestCase, this,
-// "UdpChannel error: cannot send or receive Interest/Data packets"));
-//
-// Interest interest1("ndn:/TpnzGvW9R");
-// Data data1 ("ndn:/KfczhUqVix");
-// data1.setContent(0, 0);
-// Interest interest2("ndn:/QWiIMfj5sL");
-// Data data2 ("ndn:/XNBV796f");
-// data2.setContent(0, 0);
-// Interest interest3("ndn:/QWiIhjgkj5sL");
-// Data data3 ("ndn:/XNBV794f");
-// data3.setContent(0, 0);
-//
-// ndn::SignatureSha256WithRsa fakeSignature;
-// fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
-//
-// // set fake signature on data1 and data2
-// data1.setSignature(fakeSignature);
-// data2.setSignature(fakeSignature);
-// data3.setSignature(fakeSignature);
-//
-// face2->sendInterest(interest2);
-// face2->sendData (data2 );
-//
-// limitedIoRemaining = 3; //2 send + 1 listen return
-// g_io.run();
-// g_io.reset();
-// scheduler.cancelEvent(abortEvent);
-//
-// BOOST_REQUIRE(static_cast<bool>(face1));
-//
-// face1->sendInterest(interest1);
-// face1->sendData (data1 );
-//
-// abortEvent =
-// scheduler.scheduleEvent(time::seconds(1),
-// bind(&EndToEndFixture::abortTestCase, this,
-// "UdpChannel error: cannot send or receive Interest/Data packets"));
-// limitedIoRemaining = 2;
-// g_io.run();
-// g_io.reset();
-// scheduler.cancelEvent(abortEvent);
-//
-// BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
-// BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 1);
-// BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
-// BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
-//
-// BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2.getName());
-// BOOST_CHECK_EQUAL(face1_receivedDatas [0].getName(), data2.getName());
-// BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1.getName());
-// BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1.getName());
-//
-// //checking if the connection accepting mechanism works properly.
-//
-// face2->sendData (data3 );
-// face2->sendInterest(interest3);
-//
-// abortEvent =
-// scheduler.scheduleEvent(time::seconds(1),
-// bind(&EndToEndFixture::abortTestCase, this,
-// "UdpChannel error: cannot send or receive Interest/Data packets"));
-// limitedIoRemaining = 2;
-// g_io.run();
-// g_io.reset();
-// scheduler.cancelEvent(abortEvent);
-//
-// BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 2);
-// BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 2);
-//
-// BOOST_CHECK_EQUAL(face1_receivedInterests[1].getName(), interest3.getName());
-// BOOST_CHECK_EQUAL(face1_receivedDatas [1].getName(), data3.getName());
-//
-//}
-
-
-//Test commented because it required to be run in a machine that can resolve ipv6 query
-//BOOST_FIXTURE_TEST_CASE(MultipleAcceptsIpv6, EndToEndFixture)
-//{
-// Interest interest1("ndn:/TpnzGvW9R");
-// Interest interest2("ndn:/QWiIMfj5sL");
-// Interest interest3("ndn:/QWiIhjgkj5sL");
-//
-// UdpFactory factory = UdpFactory();
-// Scheduler scheduler(g_io); // to limit the amount of time the test may take
-//
-// EventId abortEvent =
-// scheduler.scheduleEvent(time::seconds(4),
-// bind(&EndToEndFixture::abortTestCase, this,
-// "UdpChannel error: cannot connect or cannot accept connection"));
-//
-// shared_ptr<UdpChannel> channel1 = factory.createChannel("::1", "20070");
-// shared_ptr<UdpChannel> channel2 = factory.createChannel("::1", "20071");
-//
-// channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
-// bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
-//
-// channel2->connect("::1", "20070",
-// bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
-// bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
-//
-// limitedIoRemaining = 1;
-// g_io.run();
-// g_io.reset();
-// scheduler.cancelEvent(abortEvent);
-//
-// BOOST_CHECK_EQUAL(faces.size(), 1);
-//
-// shared_ptr<UdpChannel> channel3 = factory.createChannel("::1", "20072");
-// channel3->connect("::1", "20070",
-// bind(&EndToEndFixture::channel3_onFaceCreated, this, _1),
-// bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
-//
-// shared_ptr<UdpChannel> channel4 = factory.createChannel("::1", "20073");
-//
-// BOOST_CHECK_NE(channel3, channel4);
-//
-// scheduler
-// .scheduleEvent(time::milliseconds(500),
-// bind(&UdpChannel::connect, channel4,
-// "::1", "20070",
-// static_cast<UdpChannel::FaceCreatedCallback>(bind(&EndToEndFixture::
-// channel_onFaceCreated, this, _1)),
-// static_cast<UdpChannel::ConnectFailedCallback>(bind(&EndToEndFixture::
-// channel_onConnectFailed, this, _1))));
-//
-// limitedIoRemaining = 2; // 2 connects
-// abortEvent =
-// scheduler.scheduleEvent(time::seconds(4),
-// bind(&EndToEndFixture::abortTestCase, this,
-// "UdpChannel error: cannot connect or cannot accept multiple connections"));
-//
-// scheduler.scheduleEvent(time::seconds(0.4),
-// bind(&EndToEndFixture::checkFaceList, this, 2));
-//
-// g_io.run();
-// g_io.reset();
-//
-// BOOST_CHECK_EQUAL(faces.size(), 3);
-//
-//
-// face2->sendInterest(interest1);
-// abortEvent =
-// scheduler.scheduleEvent(time::seconds(1),
-// bind(&EndToEndFixture::abortTestCase, this,
-// "UdpChannel error: cannot send or receive Interest/Data packets"));
-// limitedIoRemaining = 1;
-// g_io.run();
-// g_io.reset();
-// scheduler.cancelEvent(abortEvent);
-//
-// BOOST_CHECK_EQUAL(faces.size(), 4);
-//
-// face3->sendInterest(interest2);
-// abortEvent =
-// scheduler.scheduleEvent(time::seconds(1),
-// bind(&EndToEndFixture::abortTestCase, this,
-// "UdpChannel error: cannot send or receive Interest/Data packets"));
-// limitedIoRemaining = 1;
-// g_io.run();
-// g_io.reset();
-// scheduler.cancelEvent(abortEvent);
-//
-// //channel1 should have created 2 faces, one when face2 sent an interest, one when face3 sent an interest
-// BOOST_CHECK_EQUAL(faces.size(), 5);
-// BOOST_CHECK_THROW(channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,
-// this,
-// _1),
-// bind(&EndToEndFixture::channel_onConnectFailedOk,
-// this,
-// _1)),
-// UdpChannel::Error);
-//}
-
-
-BOOST_FIXTURE_TEST_CASE(FaceClosing, EndToEndFixture)
-{
- UdpFactory factory = UdpFactory();
-
- shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
- shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
-
- channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
-
- channel2->connect("127.0.0.1", "20070",
- bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
-
- BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot connect or cannot accept connection");
-
- BOOST_CHECK_EQUAL(channel2->size(), 1);
-
- BOOST_CHECK(static_cast<bool>(face2));
-
- // Face::close must be invoked during io run to be counted as an op
- scheduler::schedule(time::milliseconds(100), bind(&Face::close, face2));
-
- BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_OPS,
- "FaceClosing error: cannot properly close faces");
-
- BOOST_CHECK(!static_cast<bool>(face2));
-
- BOOST_CHECK_EQUAL(channel2->size(), 0);
-}
-
-BOOST_FIXTURE_TEST_CASE(ClosingIdleFace, EndToEndFixture)
-{
- Interest interest1("ndn:/TpnzGvW9R");
- Interest interest2("ndn:/QWiIMfj5sL");
-
- UdpFactory factory;
-
- shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070",
- time::seconds(2));
- shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071",
- time::seconds(2));
-
- channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
-
- channel2->connect("127.0.0.1", "20070",
- bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
- bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
-
- BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot connect or cannot accept connection");
-
- face2->sendInterest(interest1);
- BOOST_CHECK(!face2->isOnDemand());
-
- BOOST_CHECK_MESSAGE(limitedIo.run(2,//1 send + 1 listen return
- time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot send or receive Interest/Data packets");
-
- BOOST_CHECK_EQUAL(faces.size(), 2);
- BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(2)) == LimitedIo::EXCEED_TIME,
- "Idle face should be still open because has been used recently");
- BOOST_CHECK_EQUAL(faces.size(), 2);
- BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_OPS,
- "Closing idle face error: face should be closed by now");
-
- //the face on listen should be closed now
+ face1->close();
+ getGlobalIoService().poll();
+ BOOST_CHECK_EQUAL(history1->failures.size(), 1);
BOOST_CHECK_EQUAL(channel1->size(), 0);
- //checking that face2 has not been closed
- BOOST_CHECK_EQUAL(channel2->size(), 1);
- BOOST_REQUIRE(static_cast<bool>(face2));
+}
- face2->sendInterest(interest2);
- BOOST_CHECK_MESSAGE(limitedIo.run(2,//1 send + 1 listen return
- time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot send or receive Interest/Data packets");
- //channel1 should have created a new face by now
+// automatically close an idle incoming face
+BOOST_AUTO_TEST_CASE_TEMPLATE(IdleClose, A, EndToEndAddresses)
+{
+ LimitedIo limitedIo;
+ UdpFactory factory;
+
+ // channel1 is listening
+ shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1(),
+ time::seconds(2));
+ shared_ptr<Face> face1;
+ unique_ptr<FaceHistory> history1;
+ channel1->listen([&] (shared_ptr<Face> newFace) {
+ BOOST_CHECK(face1 == nullptr);
+ face1 = newFace;
+ history1.reset(new FaceHistory(*face1, limitedIo));
+ limitedIo.afterOp();
+ },
+ [] (const std::string& reason) { BOOST_ERROR(reason); });
+
+ // face2 (on channel2) connects to channel1
+ shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2(),
+ time::seconds(2));
+ shared_ptr<Face> face2;
+ unique_ptr<FaceHistory> history2;
+ boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(A::getLocalIp());
+ udp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(A::getPort1()));
+ channel2->connect(endpoint,
+ [&] (shared_ptr<Face> newFace) {
+ face2 = newFace;
+ history2.reset(new FaceHistory(*face2, limitedIo));
+ limitedIo.afterOp();
+ },
+ [] (const std::string& reason) { BOOST_ERROR(reason); });
+
+ limitedIo.run(1, time::milliseconds(100)); // 1 create (on channel2)
+ BOOST_REQUIRE(face2 != nullptr);
+ BOOST_CHECK_EQUAL(face2->isOnDemand(), false);
+
+ // face2 sends to channel1, creates face1
+ shared_ptr<Interest> interest2 = makeInterest("/I2");
+ face2->sendInterest(*interest2);
+
+ limitedIo.run(2, time::seconds(1)); // 1 accept (on channel1), 1 receive (on face1)
BOOST_CHECK_EQUAL(channel1->size(), 1);
- BOOST_CHECK_EQUAL(channel2->size(), 1);
- BOOST_REQUIRE(static_cast<bool>(face1));
- BOOST_CHECK(face1->isOnDemand());
+ BOOST_REQUIRE(face1 != nullptr);
+ BOOST_CHECK_EQUAL(face1->isOnDemand(), true);
- channel1->connect("127.0.0.1", "20071",
- bind(&EndToEndFixture::channel1_onFaceCreatedNoCheck, this, _1),
- bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+ limitedIo.defer(time::seconds(1));
+ BOOST_CHECK_EQUAL(history1->failures.size(), 0); // face1 is not idle
+ BOOST_CHECK_EQUAL(history2->failures.size(), 0); // face2 is outgoing face and never closed
- BOOST_CHECK_MESSAGE(limitedIo.run(1,//1 connect
- time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UdpChannel error: cannot connect");
-
- BOOST_CHECK(!face1->isOnDemand());
-
- //the connect should have set face1 as permanent face,
- //but it shouln't have created any additional faces
- BOOST_CHECK_EQUAL(channel1->size(), 1);
- BOOST_CHECK_EQUAL(channel2->size(), 1);
- BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_TIME,
- "Idle face should be still open because it's permanent now");
- //both faces are permanent, nothing should have changed
- BOOST_CHECK_EQUAL(channel1->size(), 1);
- BOOST_CHECK_EQUAL(channel2->size(), 1);
+ limitedIo.defer(time::seconds(4));
+ BOOST_CHECK_EQUAL(history1->failures.size(), 1); // face1 is idle and automatically closed
+ BOOST_CHECK_EQUAL(channel1->size(), 0);
+ BOOST_CHECK_EQUAL(history2->failures.size(), 0); // face2 is outgoing face and never closed
}
class FakeNetworkInterfaceFixture : public BaseFixture