face: use move semantics for sockets where possible
Change-Id: I2af595073f862c570c1ce0dcb3717f3d2b9cfd71
Refs: #2613
diff --git a/daemon/face/datagram-face.hpp b/daemon/face/datagram-face.hpp
index adbf9e6..82d0347 100644
--- a/daemon/face/datagram-face.hpp
+++ b/daemon/face/datagram-face.hpp
@@ -45,7 +45,7 @@
* \param socket Protocol-specific socket for the created face
*/
DatagramFace(const FaceUri& remoteUri, const FaceUri& localUri,
- const shared_ptr<typename protocol::socket>& socket);
+ typename protocol::socket socket);
// from Face
void
@@ -91,7 +91,7 @@
resetRecentUsage();
protected:
- shared_ptr<typename protocol::socket> m_socket;
+ typename protocol::socket m_socket;
NFD_LOG_INCLASS_DECLARE();
@@ -104,14 +104,16 @@
template<class T, class U>
inline
DatagramFace<T, U>::DatagramFace(const FaceUri& remoteUri, const FaceUri& localUri,
- const shared_ptr<typename DatagramFace::protocol::socket>& socket)
+ typename DatagramFace::protocol::socket socket)
: Face(remoteUri, localUri, false, std::is_same<U, Multicast>::value)
- , m_socket(socket)
+ , m_socket(std::move(socket))
{
NFD_LOG_FACE_INFO("Creating face");
- m_socket->async_receive(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE), 0,
- bind(&DatagramFace<T, U>::handleReceive, this, _1, _2));
+ m_socket.async_receive(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE),
+ bind(&DatagramFace<T, U>::handleReceive, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
}
template<class T, class U>
@@ -123,8 +125,11 @@
this->emitSignal(onSendInterest, interest);
const Block& payload = interest.wireEncode();
- m_socket->async_send(boost::asio::buffer(payload.wire(), payload.size()),
- bind(&DatagramFace<T, U>::handleSend, this, _1, _2, payload));
+ m_socket.async_send(boost::asio::buffer(payload.wire(), payload.size()),
+ bind(&DatagramFace<T, U>::handleSend, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ payload));
}
template<class T, class U>
@@ -136,15 +141,18 @@
this->emitSignal(onSendData, data);
const Block& payload = data.wireEncode();
- m_socket->async_send(boost::asio::buffer(payload.wire(), payload.size()),
- bind(&DatagramFace<T, U>::handleSend, this, _1, _2, payload));
+ m_socket.async_send(boost::asio::buffer(payload.wire(), payload.size()),
+ bind(&DatagramFace<T, U>::handleSend, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ payload));
}
template<class T, class U>
inline void
DatagramFace<T, U>::close()
{
- if (!m_socket->is_open())
+ if (!m_socket.is_open())
return;
NFD_LOG_FACE_INFO("Closing face");
@@ -161,7 +169,7 @@
return;
// this should be unnecessary, but just in case
- if (!m_socket->is_open()) {
+ if (!m_socket.is_open()) {
this->fail("Tunnel closed");
return;
}
@@ -198,9 +206,11 @@
{
receiveDatagram(m_inputBuffer, nBytesReceived, error);
- if (m_socket->is_open())
- m_socket->async_receive(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE), 0,
- bind(&DatagramFace<T, U>::handleReceive, this, _1, _2));
+ if (m_socket.is_open())
+ m_socket.async_receive(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE),
+ bind(&DatagramFace<T, U>::handleReceive, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
}
template<class T, class U>
@@ -209,7 +219,7 @@
size_t nBytesReceived,
const boost::system::error_code& error)
{
- if (error || nBytesReceived == 0)
+ if (error)
return processErrorCode(error);
NFD_LOG_FACE_TRACE("Received: " << nBytesReceived << " bytes");
@@ -257,8 +267,8 @@
// use the non-throwing variants and ignore errors, if any
boost::system::error_code error;
- m_socket->shutdown(protocol::socket::shutdown_both, error);
- m_socket->close(error);
+ m_socket.shutdown(protocol::socket::shutdown_both, error);
+ m_socket.close(error);
// after this, handlers will be called with an error code
// ensure that the Face object is alive at least until all pending
diff --git a/daemon/face/ethernet-face.cpp b/daemon/face/ethernet-face.cpp
index a2b10e3..05d1f71 100644
--- a/daemon/face/ethernet-face.cpp
+++ b/daemon/face/ethernet-face.cpp
@@ -62,12 +62,12 @@
const time::nanoseconds EthernetFace::REASSEMBLER_LIFETIME = time::seconds(60);
-EthernetFace::EthernetFace(const shared_ptr<boost::asio::posix::stream_descriptor>& socket,
+EthernetFace::EthernetFace(boost::asio::posix::stream_descriptor socket,
const NetworkInterfaceInfo& interface,
const ethernet::Address& address)
: Face(FaceUri(address), FaceUri::fromDev(interface.name), false, true)
, m_pcap(nullptr, pcap_close)
- , m_socket(socket)
+ , m_socket(std::move(socket))
#if defined(__linux__)
, m_interfaceIndex(interface.index)
#endif
@@ -88,7 +88,7 @@
// need to duplicate the fd, otherwise both pcap_close()
// and stream_descriptor::close() will try to close the
// same fd and one of them will fail
- m_socket->assign(::dup(fd));
+ m_socket.assign(::dup(fd));
m_interfaceMtu = getInterfaceMtu();
NFD_LOG_FACE_DEBUG("Interface MTU is: " << m_interfaceMtu);
@@ -109,14 +109,10 @@
pcap_set_promisc(m_pcap.get(), 1);
}
- m_socket->async_read_some(boost::asio::null_buffers(),
- bind(&EthernetFace::handleRead, this,
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred));
-}
-
-EthernetFace::~EthernetFace()
-{
+ m_socket.async_read_some(boost::asio::null_buffers(),
+ bind(&EthernetFace::handleRead, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
}
void
@@ -154,9 +150,9 @@
NFD_LOG_FACE_INFO("Closing face");
boost::system::error_code error;
- m_socket->cancel(error); // ignore errors
- m_socket->close(error); // ignore errors
- m_pcap.reset(nullptr);
+ m_socket.cancel(error); // ignore errors
+ m_socket.close(error); // ignore errors
+ m_pcap.reset();
fail("Face closed");
}
@@ -211,7 +207,7 @@
mr.mr_alen = m_destAddress.size();
std::copy(m_destAddress.begin(), m_destAddress.end(), mr.mr_address);
- if (::setsockopt(m_socket->native_handle(), SOL_PACKET,
+ if (::setsockopt(m_socket.native_handle(), SOL_PACKET,
PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == 0)
return true; // success
@@ -249,7 +245,7 @@
static_assert(sizeof(ifr.ifr_addr) >= offsetof(sockaddr_dl, sdl_data) + ethernet::ADDR_LEN,
"ifr_addr in struct ifreq is too small on this platform");
#else
- int fd = m_socket->native_handle();
+ int fd = m_socket.native_handle();
ifr.ifr_hwaddr.sa_family = AF_UNSPEC;
std::copy(m_destAddress.begin(), m_destAddress.end(), ifr.ifr_hwaddr.sa_data);
@@ -350,10 +346,10 @@
}
#endif
- m_socket->async_read_some(boost::asio::null_buffers(),
- bind(&EthernetFace::handleRead, this,
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred));
+ m_socket.async_read_some(boost::asio::null_buffers(),
+ bind(&EthernetFace::handleRead, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
}
void
@@ -415,8 +411,7 @@
ndnlp::NdnlpData fragment;
std::tie(isOk, fragment) = ndnlp::NdnlpData::fromBlock(fragmentBlock);
if (!isOk) {
- NFD_LOG_FACE_WARN("Received invalid NDNLP fragment from "
- << sourceAddress.toString());
+ NFD_LOG_FACE_WARN("Received invalid NDNLP fragment from " << sourceAddress.toString());
return;
}
@@ -444,7 +439,7 @@
}
size_t
-EthernetFace::getInterfaceMtu() const
+EthernetFace::getInterfaceMtu()
{
#ifdef SIOCGIFMTU
#if defined(__APPLE__) || defined(__FreeBSD__)
@@ -453,7 +448,7 @@
udp::socket sock(ref(getGlobalIoService()), udp::v4());
int fd = sock.native_handle();
#else
- int fd = m_socket->native_handle();
+ int fd = m_socket.native_handle();
#endif
ifreq ifr{};
diff --git a/daemon/face/ethernet-face.hpp b/daemon/face/ethernet-face.hpp
index e9f0e2a..2bbd781 100644
--- a/daemon/face/ethernet-face.hpp
+++ b/daemon/face/ethernet-face.hpp
@@ -60,12 +60,10 @@
Error(const std::string& what) : Face::Error(what) {}
};
- EthernetFace(const shared_ptr<boost::asio::posix::stream_descriptor>& socket,
+ EthernetFace(boost::asio::posix::stream_descriptor socket,
const NetworkInterfaceInfo& interface,
const ethernet::Address& address);
- ~EthernetFace() DECL_OVERRIDE;
-
/// send an Interest
void
sendInterest(const Interest& interest) DECL_OVERRIDE;
@@ -138,7 +136,7 @@
* @brief Returns the MTU of the underlying network interface
*/
size_t
- getInterfaceMtu() const;
+ getInterfaceMtu();
private:
struct Reassembler
@@ -148,7 +146,7 @@
};
unique_ptr<pcap_t, void(*)(pcap_t*)> m_pcap;
- shared_ptr<boost::asio::posix::stream_descriptor> m_socket;
+ boost::asio::posix::stream_descriptor m_socket;
#if defined(__linux__)
int m_interfaceIndex;
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index 0126b48..7c2d2f7 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -44,8 +44,8 @@
if (face)
return face;
- auto socket = make_shared<boost::asio::posix::stream_descriptor>(ref(getGlobalIoService()));
- face = make_shared<EthernetFace>(socket, interface, address);
+ face = make_shared<EthernetFace>(boost::asio::posix::stream_descriptor(getGlobalIoService()),
+ interface, address);
auto key = std::make_pair(interface.name, address);
face->onFail.connectSingleShot([this, key] (const std::string& reason) {
diff --git a/daemon/face/multicast-udp-face.cpp b/daemon/face/multicast-udp-face.cpp
index 910f1cb..8ac07af 100644
--- a/daemon/face/multicast-udp-face.cpp
+++ b/daemon/face/multicast-udp-face.cpp
@@ -31,13 +31,12 @@
MulticastUdpFace::protocol, Multicast,
"MulticastUdpFace");
-MulticastUdpFace::MulticastUdpFace(const shared_ptr<MulticastUdpFace::protocol::socket>& recvSocket,
- const shared_ptr<MulticastUdpFace::protocol::socket>& sendSocket,
- const MulticastUdpFace::protocol::endpoint& localEndpoint,
- const MulticastUdpFace::protocol::endpoint& multicastEndpoint)
- : DatagramFace(FaceUri(multicastEndpoint), FaceUri(localEndpoint), recvSocket)
- , m_multicastGroup(multicastEndpoint)
- , m_sendSocket(sendSocket)
+MulticastUdpFace::MulticastUdpFace(const protocol::endpoint& multicastGroup,
+ const FaceUri& localUri,
+ protocol::socket recvSocket, protocol::socket sendSocket)
+ : DatagramFace(FaceUri(multicastGroup), localUri, std::move(recvSocket))
+ , m_multicastGroup(multicastGroup)
+ , m_sendSocket(std::move(sendSocket))
{
}
@@ -48,20 +47,10 @@
}
void
-MulticastUdpFace::sendBlock(const Block& block)
-{
- m_sendSocket->async_send_to(boost::asio::buffer(block.wire(), block.size()),
- m_multicastGroup,
- bind(&MulticastUdpFace::handleSend, this, _1, _2, block));
-}
-
-void
MulticastUdpFace::sendInterest(const Interest& interest)
{
NFD_LOG_FACE_TRACE(__func__);
-
this->emitSignal(onSendInterest, interest);
-
sendBlock(interest.wireEncode());
}
@@ -69,12 +58,20 @@
MulticastUdpFace::sendData(const Data& data)
{
NFD_LOG_FACE_TRACE(__func__);
-
/// \todo After this face implements duplicate suppression, onSendData should
/// be emitted only when data is actually sent out. See also #2555
this->emitSignal(onSendData, data);
-
sendBlock(data.wireEncode());
}
+void
+MulticastUdpFace::sendBlock(const Block& block)
+{
+ m_sendSocket.async_send_to(boost::asio::buffer(block.wire(), block.size()), m_multicastGroup,
+ bind(&MulticastUdpFace::handleSend, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ block));
+}
+
} // namespace nfd
diff --git a/daemon/face/multicast-udp-face.hpp b/daemon/face/multicast-udp-face.hpp
index eff4394..7aab4a7 100644
--- a/daemon/face/multicast-udp-face.hpp
+++ b/daemon/face/multicast-udp-face.hpp
@@ -40,10 +40,8 @@
/**
* \brief Creates a UDP-based face for multicast communication
*/
- MulticastUdpFace(const shared_ptr<protocol::socket>& recvSocket,
- const shared_ptr<protocol::socket>& sendSocket,
- const protocol::endpoint& localEndpoint,
- const protocol::endpoint& multicastEndpoint);
+ MulticastUdpFace(const protocol::endpoint& multicastGroup, const FaceUri& localUri,
+ protocol::socket recvSocket, protocol::socket sendSocket);
const protocol::endpoint&
getMulticastGroup() const;
@@ -61,7 +59,7 @@
private:
protocol::endpoint m_multicastGroup;
- shared_ptr<protocol::socket> m_sendSocket;
+ protocol::socket m_sendSocket;
};
} // namespace nfd
diff --git a/daemon/face/stream-face.hpp b/daemon/face/stream-face.hpp
index fa743de..94c339a 100644
--- a/daemon/face/stream-face.hpp
+++ b/daemon/face/stream-face.hpp
@@ -41,12 +41,8 @@
public:
typedef Protocol protocol;
- /**
- * \brief Create instance of StreamFace
- */
StreamFace(const FaceUri& remoteUri, const FaceUri& localUri,
- const shared_ptr<typename protocol::socket>& socket,
- bool isOnDemand);
+ typename protocol::socket socket, bool isOnDemand);
// from FaceBase
void
@@ -80,7 +76,7 @@
deferredClose(const shared_ptr<Face>& face);
protected:
- shared_ptr<typename protocol::socket> m_socket;
+ typename protocol::socket m_socket;
NFD_LOG_INCLASS_DECLARE();
@@ -117,19 +113,20 @@
template<class T, class FaceBase>
inline
StreamFace<T, FaceBase>::StreamFace(const FaceUri& remoteUri, const FaceUri& localUri,
- const shared_ptr<typename StreamFace::protocol::socket>& socket,
- bool isOnDemand)
+ typename StreamFace::protocol::socket socket, bool isOnDemand)
: FaceBase(remoteUri, localUri)
- , m_socket(socket)
+ , m_socket(std::move(socket))
, m_inputBufferSize(0)
{
NFD_LOG_FACE_INFO("Creating face");
this->setOnDemand(isOnDemand);
- StreamFaceValidator<T, FaceBase>::validateSocket(*socket);
+ StreamFaceValidator<T, FaceBase>::validateSocket(m_socket);
- m_socket->async_receive(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE), 0,
- bind(&StreamFace<T, FaceBase>::handleReceive, this, _1, _2));
+ m_socket.async_receive(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE),
+ bind(&StreamFace<T, FaceBase>::handleReceive, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
}
@@ -190,7 +187,7 @@
inline void
StreamFace<T, U>::close()
{
- if (!m_socket->is_open())
+ if (!m_socket.is_open())
return;
NFD_LOG_FACE_INFO("Closing face");
@@ -207,7 +204,7 @@
error == boost::asio::error::shut_down) // after shutdown() is called
return;
- if (!m_socket->is_open())
+ if (!m_socket.is_open())
{
this->fail("Connection closed");
return;
@@ -228,9 +225,10 @@
inline void
StreamFace<T, U>::sendFromQueue()
{
- const Block& block = this->m_sendQueue.front();
- boost::asio::async_write(*this->m_socket, boost::asio::buffer(block),
- bind(&StreamFace<T, U>::handleSend, this, _1, _2));
+ boost::asio::async_write(m_socket, boost::asio::buffer(m_sendQueue.front()),
+ bind(&StreamFace<T, U>::handleSend, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
}
template<class T, class U>
@@ -305,9 +303,11 @@
}
}
- m_socket->async_receive(boost::asio::buffer(m_inputBuffer + m_inputBufferSize,
- ndn::MAX_NDN_PACKET_SIZE - m_inputBufferSize), 0,
- bind(&StreamFace<T, U>::handleReceive, this, _1, _2));
+ m_socket.async_receive(boost::asio::buffer(m_inputBuffer + m_inputBufferSize,
+ ndn::MAX_NDN_PACKET_SIZE - m_inputBufferSize),
+ bind(&StreamFace<T, U>::handleReceive, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
}
template<class T, class U>
@@ -320,8 +320,8 @@
// so that no further sends or receives are possible.
// Use the non-throwing variants and ignore errors, if any.
boost::system::error_code error;
- m_socket->cancel(error);
- m_socket->shutdown(protocol::socket::shutdown_both, error);
+ m_socket.cancel(error);
+ m_socket.shutdown(protocol::socket::shutdown_both, error);
// ensure that the Face object is alive at least until all pending
// handlers are dispatched
@@ -331,7 +331,7 @@
// Some bug or feature of Boost.Asio (see http://redmine.named-data.net/issues/1856):
//
// When shutdownSocket is called from within a socket event (e.g., from handleReceive),
- // m_socket->shutdown() does not trigger the cancellation of the handleSend callback.
+ // m_socket.shutdown() does not trigger the cancellation of the handleSend callback.
// Instead, handleSend is invoked as nothing bad happened.
//
// In order to prevent the assertion in handleSend from failing, we clear the queue
@@ -353,7 +353,7 @@
// use the non-throwing variant and ignore errors, if any
boost::system::error_code error;
- m_socket->close(error);
+ m_socket.close(error);
}
} // namespace nfd
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
index 637cfa3..b46e92c 100644
--- a/daemon/face/tcp-channel.cpp
+++ b/daemon/face/tcp-channel.cpp
@@ -34,8 +34,9 @@
using namespace boost::asio;
TcpChannel::TcpChannel(const tcp::Endpoint& localEndpoint)
- : m_acceptor(getGlobalIoService())
- , m_localEndpoint(localEndpoint)
+ : m_localEndpoint(localEndpoint)
+ , m_acceptor(getGlobalIoService())
+ , m_acceptSocket(getGlobalIoService())
{
setUri(FaceUri(m_localEndpoint));
}
@@ -74,11 +75,10 @@
return;
}
- shared_ptr<ip::tcp::socket> clientSocket =
- make_shared<ip::tcp::socket>(ref(getGlobalIoService()));
+ auto clientSocket = make_shared<ip::tcp::socket>(ref(getGlobalIoService()));
scheduler::EventId connectTimeoutEvent = scheduler::schedule(timeout,
- bind(&TcpChannel::handleConnectTimeout, this, clientSocket, onConnectFailed));
+ bind(&TcpChannel::handleConnectTimeout, this, clientSocket, onConnectFailed));
clientSocket->async_connect(remoteEndpoint,
bind(&TcpChannel::handleConnect, this,
@@ -94,38 +94,39 @@
}
void
-TcpChannel::createFace(const shared_ptr<ip::tcp::socket>& socket,
+TcpChannel::createFace(ip::tcp::socket socket,
const FaceCreatedCallback& onFaceCreated,
bool isOnDemand)
{
- tcp::Endpoint remoteEndpoint = socket->remote_endpoint();
-
shared_ptr<Face> face;
+ tcp::Endpoint remoteEndpoint = socket.remote_endpoint();
auto it = m_channelFaces.find(remoteEndpoint);
- if (it == m_channelFaces.end())
- {
- if (socket->local_endpoint().address().is_loopback())
- face = make_shared<TcpLocalFace>(socket, isOnDemand);
- else
- face = make_shared<TcpFace>(socket, isOnDemand);
+ if (it == m_channelFaces.end()) {
+ tcp::Endpoint localEndpoint = socket.local_endpoint();
- face->onFail.connectSingleShot([this, remoteEndpoint] (const std::string&) {
- NFD_LOG_TRACE("Erasing " << remoteEndpoint << " from channel face map");
- m_channelFaces.erase(remoteEndpoint);
- });
+ if (localEndpoint.address().is_loopback() &&
+ remoteEndpoint.address().is_loopback())
+ face = make_shared<TcpLocalFace>(FaceUri(remoteEndpoint), FaceUri(localEndpoint),
+ std::move(socket), isOnDemand);
+ else
+ face = make_shared<TcpFace>(FaceUri(remoteEndpoint), FaceUri(localEndpoint),
+ std::move(socket), isOnDemand);
- m_channelFaces[remoteEndpoint] = face;
- }
- else
- {
- // we've already created a a face for this endpoint, just reuse it
- face = it->second;
+ face->onFail.connectSingleShot([this, remoteEndpoint] (const std::string&) {
+ NFD_LOG_TRACE("Erasing " << remoteEndpoint << " from channel face map");
+ m_channelFaces.erase(remoteEndpoint);
+ });
+ m_channelFaces[remoteEndpoint] = face;
+ }
+ else {
+ // we already have a face for this endpoint, just reuse it
+ face = it->second;
- boost::system::error_code error;
- socket->shutdown(ip::tcp::socket::shutdown_both, error);
- socket->close(error);
- }
+ boost::system::error_code error;
+ socket.shutdown(ip::tcp::socket::shutdown_both, error);
+ socket.close(error);
+ }
// Need to invoke the callback regardless of whether or not we have already created
// the face so that control responses and such can be sent.
@@ -136,17 +137,13 @@
TcpChannel::accept(const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onAcceptFailed)
{
- auto socket = make_shared<ip::tcp::socket>(ref(getGlobalIoService()));
-
- m_acceptor.async_accept(*socket,
- bind(&TcpChannel::handleAccept, this,
- boost::asio::placeholders::error,
- socket, onFaceCreated, onAcceptFailed));
+ m_acceptor.async_accept(m_acceptSocket, bind(&TcpChannel::handleAccept, this,
+ boost::asio::placeholders::error,
+ onFaceCreated, onAcceptFailed));
}
void
TcpChannel::handleAccept(const boost::system::error_code& error,
- const shared_ptr<boost::asio::ip::tcp::socket>& socket,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onAcceptFailed)
{
@@ -160,12 +157,12 @@
return;
}
- NFD_LOG_DEBUG("[" << m_localEndpoint << "] Connection from " << socket->remote_endpoint());
+ NFD_LOG_DEBUG("[" << m_localEndpoint << "] Connection from " << m_acceptSocket.remote_endpoint());
+
+ createFace(std::move(m_acceptSocket), onFaceCreated, true);
// prepare accepting the next connection
accept(onFaceCreated, onAcceptFailed);
-
- createFace(socket, onFaceCreated, true);
}
void
@@ -189,9 +186,10 @@
if (error == boost::asio::error::operation_aborted) // when the socket is closed by someone
return;
+ NFD_LOG_WARN("[" << m_localEndpoint << "] Connect failed: " << error.message());
+
socket->close();
- NFD_LOG_DEBUG("[" << m_localEndpoint << "] Connect failed: " << error.message());
if (onConnectFailed)
onConnectFailed(error.message());
return;
@@ -199,7 +197,7 @@
NFD_LOG_DEBUG("[" << m_localEndpoint << "] Connected to " << socket->remote_endpoint());
- createFace(socket, onFaceCreated, false);
+ createFace(std::move(*socket), onFaceCreated, false);
}
void
diff --git a/daemon/face/tcp-channel.hpp b/daemon/face/tcp-channel.hpp
index ba59dbe..5b5505a 100644
--- a/daemon/face/tcp-channel.hpp
+++ b/daemon/face/tcp-channel.hpp
@@ -88,7 +88,7 @@
private:
void
- createFace(const shared_ptr<boost::asio::ip::tcp::socket>& socket,
+ createFace(boost::asio::ip::tcp::socket socket,
const FaceCreatedCallback& onFaceCreated,
bool isOnDemand);
@@ -98,7 +98,6 @@
void
handleAccept(const boost::system::error_code& error,
- const shared_ptr<boost::asio::ip::tcp::socket>& socket,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onConnectFailed);
@@ -116,8 +115,9 @@
private:
std::map<tcp::Endpoint, shared_ptr<Face>> m_channelFaces;
- boost::asio::ip::tcp::acceptor m_acceptor;
tcp::Endpoint m_localEndpoint;
+ boost::asio::ip::tcp::acceptor m_acceptor;
+ boost::asio::ip::tcp::socket m_acceptSocket;
};
inline bool
diff --git a/daemon/face/tcp-face.cpp b/daemon/face/tcp-face.cpp
index 6428b03..39ebe04 100644
--- a/daemon/face/tcp-face.cpp
+++ b/daemon/face/tcp-face.cpp
@@ -32,18 +32,15 @@
TcpLocalFace::protocol, LocalFace,
"TcpLocalFace");
-TcpFace::TcpFace(const shared_ptr<TcpFace::protocol::socket>& socket, bool isOnDemand)
- : StreamFace<protocol>(FaceUri(socket->remote_endpoint()),
- FaceUri(socket->local_endpoint()),
- socket, isOnDemand)
+TcpFace::TcpFace(const FaceUri& remoteUri, const FaceUri& localUri,
+ protocol::socket socket, bool isOnDemand)
+ : StreamFace<protocol>(remoteUri, localUri, std::move(socket), isOnDemand)
{
}
-TcpLocalFace::TcpLocalFace(const shared_ptr<TcpLocalFace::protocol::socket>& socket,
- bool isOnDemand)
- : StreamFace<protocol, LocalFace>(FaceUri(socket->remote_endpoint()),
- FaceUri(socket->local_endpoint()),
- socket, isOnDemand)
+TcpLocalFace::TcpLocalFace(const FaceUri& remoteUri, const FaceUri& localUri,
+ protocol::socket socket, bool isOnDemand)
+ : StreamFace<protocol, LocalFace>(remoteUri, localUri, std::move(socket), isOnDemand)
{
}
diff --git a/daemon/face/tcp-face.hpp b/daemon/face/tcp-face.hpp
index e4427de..f77b72d 100644
--- a/daemon/face/tcp-face.hpp
+++ b/daemon/face/tcp-face.hpp
@@ -36,8 +36,8 @@
class TcpFace : public StreamFace<boost::asio::ip::tcp>
{
public:
- TcpFace(const shared_ptr<protocol::socket>& socket,
- bool isOnDemand);
+ TcpFace(const FaceUri& remoteUri, const FaceUri& localUri,
+ protocol::socket socket, bool isOnDemand);
};
@@ -49,8 +49,8 @@
class TcpLocalFace : public StreamFace<boost::asio::ip::tcp, LocalFace>
{
public:
- TcpLocalFace(const shared_ptr<protocol::socket>& socket,
- bool isOnDemand);
+ TcpLocalFace(const FaceUri& remoteUri, const FaceUri& localUri,
+ protocol::socket socket, bool isOnDemand);
};
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index bd860cc..c0d0d3c 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -36,25 +36,10 @@
UdpChannel::UdpChannel(const udp::Endpoint& localEndpoint,
const time::seconds& timeout)
: m_localEndpoint(localEndpoint)
- , m_isListening(false)
+ , m_socket(getGlobalIoService())
, m_idleFaceTimeout(timeout)
{
setUri(FaceUri(m_localEndpoint));
-
- m_socket = make_shared<ip::udp::socket>(ref(getGlobalIoService()));
- m_socket->open(m_localEndpoint.protocol());
- m_socket->set_option(ip::udp::socket::reuse_address(true));
- if (m_localEndpoint.address().is_v6())
- m_socket->set_option(ip::v6_only(true));
-
- try {
- m_socket->bind(m_localEndpoint);
- }
- catch (const boost::system::system_error& e) {
- // bind failed, so the socket is useless now
- m_socket->close();
- throw Error("bind failed: " + std::string(e.what()));
- }
}
void
@@ -65,14 +50,19 @@
NFD_LOG_WARN("[" << m_localEndpoint << "] Already listening");
return;
}
- m_isListening = true;
- m_socket->async_receive_from(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE),
- m_newRemoteEndpoint,
- bind(&UdpChannel::handleNewPeer, this,
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred,
- onFaceCreated, onReceiveFailed));
+ m_socket.open(m_localEndpoint.protocol());
+ m_socket.set_option(ip::udp::socket::reuse_address(true));
+ if (m_localEndpoint.address().is_v6())
+ m_socket.set_option(ip::v6_only(true));
+
+ m_socket.bind(m_localEndpoint);
+ m_socket.async_receive_from(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE),
+ m_remoteEndpoint,
+ bind(&UdpChannel::handleNewPeer, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ onFaceCreated, onReceiveFailed));
}
void
@@ -80,34 +70,20 @@
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onConnectFailed)
{
- auto it = m_channelFaces.find(remoteEndpoint);
- if (it != m_channelFaces.end()) {
- it->second->setOnDemand(false);
- onFaceCreated(it->second);
- return;
- }
-
- // creating a new socket for the face that will be created soon
- shared_ptr<ip::udp::socket> clientSocket =
- make_shared<ip::udp::socket>(ref(getGlobalIoService()));
-
- clientSocket->open(m_localEndpoint.protocol());
- clientSocket->set_option(ip::udp::socket::reuse_address(true));
-
+ shared_ptr<UdpFace> face;
try {
- clientSocket->bind(m_localEndpoint);
- clientSocket->connect(remoteEndpoint); //@todo connect or async_connect
- //(since there is no handshake the connect shouldn't block). If we go for
- //async_connect, make sure that if in the meantime we receive a UDP pkt from
- //that endpoint nothing bad happen (it's difficult, but it could happen)
+ face = createFace(remoteEndpoint, false).second;
}
catch (const boost::system::system_error& e) {
- clientSocket->close();
- onConnectFailed("Failed to configure socket (" + std::string(e.what()) + ")");
+ NFD_LOG_WARN("[" << m_localEndpoint << "] Connect failed: " << e.what());
+ if (onConnectFailed)
+ onConnectFailed(e.what());
return;
}
- createFace(clientSocket, onFaceCreated, false);
+ // Need to invoke the callback regardless of whether or not we had already
+ // created the face so that control responses and such can be sent
+ onFaceCreated(face);
}
size_t
@@ -116,42 +92,34 @@
return m_channelFaces.size();
}
-shared_ptr<UdpFace>
-UdpChannel::createFace(const shared_ptr<ip::udp::socket>& socket,
- const FaceCreatedCallback& onFaceCreated,
- bool isOnDemand)
+std::pair<bool, shared_ptr<UdpFace>>
+UdpChannel::createFace(const udp::Endpoint& remoteEndpoint, bool isOnDemand)
{
- udp::Endpoint remoteEndpoint = socket->remote_endpoint();
-
- shared_ptr<UdpFace> face;
-
auto it = m_channelFaces.find(remoteEndpoint);
- if (it == m_channelFaces.end())
- {
- face = make_shared<UdpFace>(socket, isOnDemand, m_idleFaceTimeout);
+ if (it != m_channelFaces.end()) {
+ // we already have a face for this endpoint, just reuse it
+ if (!isOnDemand)
+ // only on-demand -> non-on-demand transition is allowed
+ it->second->setOnDemand(false);
+ return {false, it->second};
+ }
- face->onFail.connectSingleShot([this, remoteEndpoint] (const std::string&) {
- NFD_LOG_TRACE("Erasing " << remoteEndpoint << " from channel face map");
- m_channelFaces.erase(remoteEndpoint);
- });
+ // else, create a new face
+ ip::udp::socket socket(getGlobalIoService(), m_localEndpoint.protocol());
+ socket.set_option(ip::udp::socket::reuse_address(true));
+ socket.bind(m_localEndpoint);
+ socket.connect(remoteEndpoint);
- m_channelFaces[remoteEndpoint] = face;
- }
- else
- {
- // we've already created a a face for this endpoint, just reuse it
- face = it->second;
+ auto face = make_shared<UdpFace>(FaceUri(remoteEndpoint), FaceUri(m_localEndpoint),
+ std::move(socket), isOnDemand, m_idleFaceTimeout);
- boost::system::error_code error;
- socket->shutdown(ip::udp::socket::shutdown_both, error);
- socket->close(error);
- }
+ face->onFail.connectSingleShot([this, remoteEndpoint] (const std::string&) {
+ NFD_LOG_TRACE("Erasing " << remoteEndpoint << " from channel face map");
+ m_channelFaces.erase(remoteEndpoint);
+ });
+ m_channelFaces[remoteEndpoint] = face;
- // Need to invoke the callback regardless of whether or not we have already created
- // the face so that control responses and such can be sent.
- onFaceCreated(face);
-
- return face;
+ return {true, face};
}
void
@@ -170,52 +138,33 @@
return;
}
- NFD_LOG_DEBUG("[" << m_localEndpoint << "] New peer " << m_newRemoteEndpoint);
+ NFD_LOG_DEBUG("[" << m_localEndpoint << "] New peer " << m_remoteEndpoint);
+ bool created;
shared_ptr<UdpFace> face;
-
- auto it = m_channelFaces.find(m_newRemoteEndpoint);
- if (it != m_channelFaces.end()) {
- //The face already exists.
- //Usually this shouldn't happen, because the channel creates a Udpface
- //as soon as it receives a pkt from a new endpoint and then the
- //traffic is dispatched by the kernel directly to the face.
- //However, if the node receives multiple packets from the same endpoint
- //"at the same time", while the channel is creating the face the kernel
- //could dispatch the other pkts to the channel because the face is not yet
- //ready. In this case, the channel has to pass the pkt to the face
-
- NFD_LOG_DEBUG("The creation of the face for the remote endpoint "
- << m_newRemoteEndpoint << " is already in progress");
- face = it->second;
+ try {
+ std::tie(created, face) = createFace(m_remoteEndpoint, true);
}
- else {
- shared_ptr<ip::udp::socket> clientSocket =
- make_shared<ip::udp::socket>(ref(getGlobalIoService()));
- clientSocket->open(m_localEndpoint.protocol());
- clientSocket->set_option(ip::udp::socket::reuse_address(true));
- clientSocket->bind(m_localEndpoint);
-
- boost::system::error_code ec;
- clientSocket->connect(m_newRemoteEndpoint, ec);
- if (ec) {
- NFD_LOG_WARN("Error while creating on-demand UDP face from " << m_newRemoteEndpoint << ": "
- << boost::system::system_error(ec).what());
- return;
- }
-
- face = createFace(clientSocket, onFaceCreated, true);
+ catch (const boost::system::system_error& e) {
+ NFD_LOG_WARN("[" << m_localEndpoint << "] Failed to create face for peer "
+ << m_remoteEndpoint << ": " << e.what());
+ if (onReceiveFailed)
+ onReceiveFailed(e.what());
+ return;
}
+ if (created)
+ onFaceCreated(face);
+
// dispatch the datagram to the face for processing
face->receiveDatagram(m_inputBuffer, nBytesReceived, error);
- m_socket->async_receive_from(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE),
- m_newRemoteEndpoint,
- bind(&UdpChannel::handleNewPeer, this,
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred,
- onFaceCreated, onReceiveFailed));
+ m_socket.async_receive_from(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE),
+ m_remoteEndpoint,
+ bind(&UdpChannel::handleNewPeer, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ onFaceCreated, onReceiveFailed));
}
} // namespace nfd
diff --git a/daemon/face/udp-channel.hpp b/daemon/face/udp-channel.hpp
index 1451713..17410dc 100644
--- a/daemon/face/udp-channel.hpp
+++ b/daemon/face/udp-channel.hpp
@@ -43,14 +43,6 @@
{
public:
/**
- * \brief Exception of UdpChannel
- */
- struct Error : public std::runtime_error
- {
- Error(const std::string& what) : runtime_error(what) {}
- };
-
- /**
* \brief Create UDP channel for the local endpoint
*
* To enable creation of faces upon incoming connections,
@@ -99,10 +91,8 @@
isListening() const;
private:
- shared_ptr<UdpFace>
- createFace(const shared_ptr<boost::asio::ip::udp::socket>& socket,
- const FaceCreatedCallback& onFaceCreated,
- bool isOnDemand);
+ std::pair<bool, shared_ptr<UdpFace>>
+ createFace(const udp::Endpoint& remoteEndpoint, bool isOnDemand);
/**
* \brief The channel has received a new packet from a remote
@@ -120,33 +110,27 @@
udp::Endpoint m_localEndpoint;
/**
- * \brief Endpoint used to store the information about the last new remote endpoint
+ * \brief The latest peer that started communicating with us
*/
- udp::Endpoint m_newRemoteEndpoint;
+ udp::Endpoint m_remoteEndpoint;
/**
* \brief Socket used to "accept" new communication
- **/
- shared_ptr<boost::asio::ip::udp::socket> m_socket;
-
- uint8_t m_inputBuffer[ndn::MAX_NDN_PACKET_SIZE];
-
- /**
- * \brief If true, it means the function listen has already been called
*/
- bool m_isListening;
+ boost::asio::ip::udp::socket m_socket;
/**
- * \brief every time m_idleFaceTimeout expires all the idle (and on-demand)
- * faces will be removed
+ * \brief When this timeout expires, all idle on-demand faces will be closed
*/
time::seconds m_idleFaceTimeout;
+
+ uint8_t m_inputBuffer[ndn::MAX_NDN_PACKET_SIZE];
};
inline bool
UdpChannel::isListening() const
{
- return m_isListening;
+ return m_socket.is_open();
}
} // namespace nfd
diff --git a/daemon/face/udp-face.cpp b/daemon/face/udp-face.cpp
index 7206984..a854cc4 100644
--- a/daemon/face/udp-face.cpp
+++ b/daemon/face/udp-face.cpp
@@ -37,9 +37,10 @@
NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(DatagramFace, UdpFace::protocol, "UdpFace");
-UdpFace::UdpFace(const shared_ptr<UdpFace::protocol::socket>& socket,
- bool isOnDemand, const time::seconds& idleTimeout)
- : DatagramFace(FaceUri(socket->remote_endpoint()), FaceUri(socket->local_endpoint()), socket)
+UdpFace::UdpFace(const FaceUri& remoteUri, const FaceUri& localUri,
+ protocol::socket socket, bool isOnDemand,
+ const time::seconds& idleTimeout)
+ : DatagramFace(remoteUri, localUri, std::move(socket))
, m_idleTimeout(idleTimeout)
, m_lastIdleCheck(time::steady_clock::now())
{
@@ -59,24 +60,17 @@
// routers along the path to perform fragmentation as needed.
//
const int value = IP_PMTUDISC_DONT;
- if (::setsockopt(socket->native_handle(), IPPROTO_IP,
- IP_MTU_DISCOVER, &value, sizeof(value)) < 0)
- {
- NFD_LOG_FACE_WARN("Failed to disable path MTU discovery: " << std::strerror(errno));
- }
+ if (::setsockopt(m_socket.native_handle(), IPPROTO_IP,
+ IP_MTU_DISCOVER, &value, sizeof(value)) < 0) {
+ NFD_LOG_FACE_WARN("Failed to disable path MTU discovery: " << std::strerror(errno));
+ }
#endif
if (this->isOnDemand() && m_idleTimeout > time::seconds::zero()) {
- m_closeIfIdleEvent = scheduler::schedule(m_idleTimeout,
- bind(&UdpFace::closeIfIdle, this));
+ m_closeIfIdleEvent = scheduler::schedule(m_idleTimeout, bind(&UdpFace::closeIfIdle, this));
}
}
-UdpFace::~UdpFace()
-{
- scheduler::cancel(m_closeIfIdleEvent);
-}
-
ndn::nfd::FaceStatus
UdpFace::getFaceStatus() const
{
@@ -118,8 +112,7 @@
resetRecentUsage();
m_lastIdleCheck = time::steady_clock::now();
- m_closeIfIdleEvent = scheduler::schedule(m_idleTimeout,
- bind(&UdpFace::closeIfIdle, this));
+ m_closeIfIdleEvent = scheduler::schedule(m_idleTimeout, bind(&UdpFace::closeIfIdle, this));
}
}
// else do nothing and do not reschedule the event
diff --git a/daemon/face/udp-face.hpp b/daemon/face/udp-face.hpp
index e73c1e1..333bae2 100644
--- a/daemon/face/udp-face.hpp
+++ b/daemon/face/udp-face.hpp
@@ -38,10 +38,9 @@
class UdpFace : public DatagramFace<boost::asio::ip::udp>
{
public:
- UdpFace(const shared_ptr<protocol::socket>& socket,
- bool isOnDemand, const time::seconds& idleTimeout);
-
- ~UdpFace() DECL_OVERRIDE;
+ UdpFace(const FaceUri& remoteUri, const FaceUri& localUri,
+ protocol::socket socket, bool isOnDemand,
+ const time::seconds& idleTimeout);
ndn::nfd::FaceStatus
getFaceStatus() const DECL_OVERRIDE;
@@ -53,7 +52,7 @@
private:
const time::seconds m_idleTimeout;
time::steady_clock::TimePoint m_lastIdleCheck;
- scheduler::EventId m_closeIfIdleEvent;
+ scheduler::ScopedEventId m_closeIfIdleEvent;
// friend because it needs to invoke protected Face::setOnDemand
friend class UdpChannel;
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index fcf1343..ddef35e 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -27,8 +27,10 @@
#include "core/global-io.hpp"
#include "core/network-interface.hpp"
-#if defined(__linux__)
-#include <sys/socket.h>
+#ifdef __linux__
+#include <cerrno> // for errno
+#include <cstring> // for std::strerror()
+#include <sys/socket.h> // for setsockopt()
#endif
namespace nfd {
@@ -147,20 +149,20 @@
shared_ptr<MulticastUdpFace>
UdpFactory::createMulticastFace(const udp::Endpoint& localEndpoint,
const udp::Endpoint& multicastEndpoint,
- const std::string& networkInterfaceName /* "" */)
+ const std::string& networkInterfaceName/* = ""*/)
{
- //checking if the local and multicast endpoint are already in use for a multicast face
- shared_ptr<MulticastUdpFace> multicastFace = findMulticastFace(localEndpoint);
- if (static_cast<bool>(multicastFace)) {
- if (multicastFace->getMulticastGroup() == multicastEndpoint)
- return multicastFace;
+ // checking if the local and multicast endpoints are already in use for a multicast face
+ shared_ptr<MulticastUdpFace> face = findMulticastFace(localEndpoint);
+ if (static_cast<bool>(face)) {
+ if (face->getMulticastGroup() == multicastEndpoint)
+ return face;
else
throw Error("Cannot create the requested UDP multicast face, local "
"endpoint is already allocated for a UDP multicast face "
"on a different multicast group");
}
- //checking if the local endpoint is already in use for an unicast channel
+ // checking if the local endpoint is already in use for a unicast channel
shared_ptr<UdpChannel> unicast = findChannel(localEndpoint);
if (static_cast<bool>(unicast)) {
throw Error("Cannot create the requested UDP multicast face, local "
@@ -186,79 +188,63 @@
"the multicast group given as input is not a multicast address");
}
- shared_ptr<ip::udp::socket> receiveSocket =
- make_shared<ip::udp::socket>(ref(getGlobalIoService()));
+ ip::udp::socket receiveSocket(getGlobalIoService());
+ receiveSocket.open(multicastEndpoint.protocol());
+ receiveSocket.set_option(ip::udp::socket::reuse_address(true));
+ receiveSocket.bind(multicastEndpoint);
- shared_ptr<ip::udp::socket> sendSocket =
- make_shared<ip::udp::socket>(ref(getGlobalIoService()));
+ ip::udp::socket sendSocket(getGlobalIoService());
+ sendSocket.open(multicastEndpoint.protocol());
+ sendSocket.set_option(ip::udp::socket::reuse_address(true));
+ sendSocket.set_option(ip::multicast::enable_loopback(false));
+ sendSocket.bind(udp::Endpoint(ip::address_v4::any(), multicastEndpoint.port()));
+ if (localEndpoint.address() != ALL_V4_ENDPOINT)
+ sendSocket.set_option(ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
- receiveSocket->open(multicastEndpoint.protocol());
- receiveSocket->set_option(ip::udp::socket::reuse_address(true));
-
- sendSocket->open(multicastEndpoint.protocol());
- sendSocket->set_option(ip::udp::socket::reuse_address(true));
- sendSocket->set_option(ip::multicast::enable_loopback(false));
-
- try {
- sendSocket->bind(udp::Endpoint(ip::address_v4::any(), multicastEndpoint.port()));
- receiveSocket->bind(multicastEndpoint);
-
- if (localEndpoint.address() != ip::address::from_string("0.0.0.0")) {
- sendSocket->set_option(ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
- }
- sendSocket->set_option(ip::multicast::join_group(multicastEndpoint.address().to_v4(),
+ sendSocket.set_option(ip::multicast::join_group(multicastEndpoint.address().to_v4(),
+ localEndpoint.address().to_v4()));
+ receiveSocket.set_option(ip::multicast::join_group(multicastEndpoint.address().to_v4(),
localEndpoint.address().to_v4()));
- receiveSocket->set_option(ip::multicast::join_group(multicastEndpoint.address().to_v4(),
- localEndpoint.address().to_v4()));
- }
- catch (boost::system::system_error& e) {
- std::stringstream msg;
- msg << "Failed to properly configure the socket, check the address (" << e.what() << ")";
- throw Error(msg.str());
- }
-
-#if defined(__linux__)
- //On linux system, if there are more than one MulticastUdpFace for the same multicast group but
- //bound on different network interfaces, the socket has to be bound with the specific interface
- //using SO_BINDTODEVICE, otherwise the face will receive packets also from other interfaces.
- //Without SO_BINDTODEVICE every MulticastUdpFace that have joined the same multicast group
- //on different interfaces will receive the same packet.
- //This applies only on linux, for OS X the ip::multicast::join_group is enough to get
- //the desired behaviour
+#ifdef __linux__
+ /*
+ * On Linux, if there is more than one MulticastUdpFace for the same multicast
+ * group but they are bound to different network interfaces, the socket needs
+ * to be bound to the specific interface using SO_BINDTODEVICE, otherwise the
+ * face will receive all packets sent to the other interfaces as well.
+ * This happens only on Linux. On OS X, the ip::multicast::join_group option
+ * is enough to get the desired behaviour.
+ */
if (!networkInterfaceName.empty()) {
- if (::setsockopt(receiveSocket->native_handle(), SOL_SOCKET, SO_BINDTODEVICE,
- networkInterfaceName.c_str(), networkInterfaceName.size()+1) == -1){
- throw Error("Cannot bind multicast face to " + networkInterfaceName
- + " make sure you have CAP_NET_RAW capability" );
+ if (::setsockopt(receiveSocket.native_handle(), SOL_SOCKET, SO_BINDTODEVICE,
+ networkInterfaceName.c_str(), networkInterfaceName.size() + 1) < 0) {
+ throw Error("Cannot bind multicast face to " + networkInterfaceName +
+ ": " + std::strerror(errno));
}
}
-
#endif
- multicastFace = make_shared<MulticastUdpFace>(receiveSocket, sendSocket,
- localEndpoint, multicastEndpoint);
+ face = make_shared<MulticastUdpFace>(multicastEndpoint, FaceUri(localEndpoint),
+ std::move(receiveSocket), std::move(sendSocket));
- multicastFace->onFail.connectSingleShot(bind(&UdpFactory::afterFaceFailed, this, localEndpoint));
+ face->onFail.connectSingleShot([this, localEndpoint] (const std::string& reason) {
+ m_multicastFaces.erase(localEndpoint);
+ });
+ m_multicastFaces[localEndpoint] = face;
- m_multicastFaces[localEndpoint] = multicastFace;
-
- return multicastFace;
+ return face;
}
shared_ptr<MulticastUdpFace>
UdpFactory::createMulticastFace(const std::string& localIp,
const std::string& multicastIp,
const std::string& multicastPort,
- const std::string& networkInterfaceName /* "" */)
+ const std::string& networkInterfaceName/* = ""*/)
{
- using namespace boost::asio::ip;
- udp::Endpoint localEndpoint(address::from_string(localIp),
+ udp::Endpoint localEndpoint(ip::address::from_string(localIp),
boost::lexical_cast<uint16_t>(multicastPort));
-
- udp::Endpoint multicastEndpoint(address::from_string(multicastIp),
+ udp::Endpoint multicastEndpoint(ip::address::from_string(multicastIp),
boost::lexical_cast<uint16_t>(multicastPort));
-
return createMulticastFace(localEndpoint, multicastEndpoint, networkInterfaceName);
}
@@ -268,6 +254,7 @@
const FaceConnectFailedCallback& onConnectFailed)
{
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()));
@@ -276,15 +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;
- }
+ 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();
channel != m_channels.end();
++channel)
@@ -296,6 +281,7 @@
return;
}
}
+
onConnectFailed("No channels available to connect to " +
boost::lexical_cast<std::string>(endpoint));
}
@@ -320,17 +306,10 @@
return shared_ptr<MulticastUdpFace>();
}
-void
-UdpFactory::afterFaceFailed(udp::Endpoint& endpoint)
-{
- NFD_LOG_DEBUG("afterFaceFailed: " << endpoint);
- m_multicastFaces.erase(endpoint);
-}
-
-std::list<shared_ptr<const Channel> >
+std::list<shared_ptr<const Channel>>
UdpFactory::getChannels() const
{
- std::list<shared_ptr<const Channel> > channels;
+ std::list<shared_ptr<const Channel>> channels;
for (ChannelMap::const_iterator i = m_channels.begin(); i != m_channels.end(); ++i)
{
channels.push_back(i->second);
@@ -339,6 +318,4 @@
return channels;
}
-
-
} // namespace nfd
diff --git a/daemon/face/udp-factory.hpp b/daemon/face/udp-factory.hpp
index cfbd077..e59275d 100644
--- a/daemon/face/udp-factory.hpp
+++ b/daemon/face/udp-factory.hpp
@@ -30,10 +30,9 @@
#include "udp-channel.hpp"
#include "multicast-udp-face.hpp"
-
namespace nfd {
-// @todo The multicast support for ipv6 must be implemented
+/// @todo IPv6 multicast support not implemented
class UdpFactory : public ProtocolFactory
{
@@ -51,7 +50,7 @@
}
};
- typedef std::map< udp::Endpoint, shared_ptr<MulticastUdpFace> > MulticastFaceMap;
+ typedef std::map<udp::Endpoint, shared_ptr<MulticastUdpFace>> MulticastFaceMap;
explicit
UdpFactory(const std::string& defaultPort = "6363");
@@ -143,13 +142,13 @@
const std::string& multicastPort,
const std::string& networkInterfaceName = "");
- // from Factory
+ // from ProtocolFactory
virtual void
createFace(const FaceUri& uri,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed);
- virtual std::list<shared_ptr<const Channel> >
+ virtual std::list<shared_ptr<const Channel>>
getChannels() const;
/**
@@ -159,7 +158,6 @@
getMulticastFaces() const;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-
void
prohibitEndpoint(const udp::Endpoint& endpoint);
@@ -183,7 +181,6 @@
shared_ptr<UdpChannel>
findChannel(const udp::Endpoint& localEndpoint);
-
/**
* \brief Look up multicast UdpFace using specified local endpoint
*
@@ -196,7 +193,7 @@
findMulticastFace(const udp::Endpoint& localEndpoint);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- typedef std::map< udp::Endpoint, shared_ptr<UdpChannel> > ChannelMap;
+ typedef std::map<udp::Endpoint, shared_ptr<UdpChannel>> ChannelMap;
ChannelMap m_channels;
MulticastFaceMap m_multicastFaces;
@@ -205,14 +202,12 @@
std::set<udp::Endpoint> m_prohibitedEndpoints;
};
-
inline const UdpFactory::MulticastFaceMap&
UdpFactory::getMulticastFaces() const
{
return m_multicastFaces;
}
-
} // namespace nfd
#endif // NFD_DAEMON_FACE_UDP_FACTORY_HPP
diff --git a/daemon/face/unix-stream-channel.cpp b/daemon/face/unix-stream-channel.cpp
index 52df192..ece6d0e 100644
--- a/daemon/face/unix-stream-channel.cpp
+++ b/daemon/face/unix-stream-channel.cpp
@@ -34,11 +34,10 @@
NFD_LOG_INIT("UnixStreamChannel");
-using namespace boost::asio::local;
-
UnixStreamChannel::UnixStreamChannel(const unix_stream::Endpoint& endpoint)
- : m_acceptor(getGlobalIoService())
- , m_endpoint(endpoint)
+ : m_endpoint(endpoint)
+ , m_acceptor(getGlobalIoService())
+ , m_socket(getGlobalIoService())
{
setUri(FaceUri(m_endpoint));
}
@@ -72,7 +71,7 @@
if (type == fs::socket_file) {
boost::system::error_code error;
- stream_protocol::socket socket(getGlobalIoService());
+ boost::asio::local::stream_protocol::socket socket(getGlobalIoService());
socket.connect(m_endpoint, error);
NFD_LOG_TRACE("[" << m_endpoint << "] connect() on existing socket file returned: "
+ error.message());
@@ -106,20 +105,16 @@
}
void
-UnixStreamChannel::accept(const FaceCreatedCallback &onFaceCreated,
- const ConnectFailedCallback &onAcceptFailed)
+UnixStreamChannel::accept(const FaceCreatedCallback& onFaceCreated,
+ const ConnectFailedCallback& onAcceptFailed)
{
- auto socket = make_shared<stream_protocol::socket>(ref(getGlobalIoService()));
-
- m_acceptor.async_accept(*socket,
- bind(&UnixStreamChannel::handleAccept, this,
- boost::asio::placeholders::error,
- socket, onFaceCreated, onAcceptFailed));
+ m_acceptor.async_accept(m_socket, bind(&UnixStreamChannel::handleAccept, this,
+ boost::asio::placeholders::error,
+ onFaceCreated, onAcceptFailed));
}
void
UnixStreamChannel::handleAccept(const boost::system::error_code& error,
- const shared_ptr<stream_protocol::socket>& socket,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onAcceptFailed)
{
@@ -135,11 +130,13 @@
NFD_LOG_DEBUG("[" << m_endpoint << "] Incoming connection");
+ auto remoteUri = FaceUri::fromFd(m_socket.native_handle());
+ auto localUri = FaceUri(m_socket.local_endpoint());
+ auto face = make_shared<UnixStreamFace>(remoteUri, localUri, std::move(m_socket));
+ onFaceCreated(face);
+
// prepare accepting the next connection
accept(onFaceCreated, onAcceptFailed);
-
- shared_ptr<UnixStreamFace> face = make_shared<UnixStreamFace>(socket);
- onFaceCreated(face);
}
} // namespace nfd
diff --git a/daemon/face/unix-stream-channel.hpp b/daemon/face/unix-stream-channel.hpp
index c90dcb0..06be812 100644
--- a/daemon/face/unix-stream-channel.hpp
+++ b/daemon/face/unix-stream-channel.hpp
@@ -85,13 +85,13 @@
void
handleAccept(const boost::system::error_code& error,
- const shared_ptr<boost::asio::local::stream_protocol::socket>& socket,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onAcceptFailed);
private:
- boost::asio::local::stream_protocol::acceptor m_acceptor;
unix_stream::Endpoint m_endpoint;
+ boost::asio::local::stream_protocol::acceptor m_acceptor;
+ boost::asio::local::stream_protocol::socket m_socket;
};
inline bool
diff --git a/daemon/face/unix-stream-face.cpp b/daemon/face/unix-stream-face.cpp
index 60b2236..41ef68b 100644
--- a/daemon/face/unix-stream-face.cpp
+++ b/daemon/face/unix-stream-face.cpp
@@ -33,10 +33,9 @@
UnixStreamFace::protocol, LocalFace,
"UnixStreamFace");
-UnixStreamFace::UnixStreamFace(const shared_ptr<UnixStreamFace::protocol::socket>& socket)
- : StreamFace<protocol, LocalFace>(FaceUri::fromFd(socket->native_handle()),
- FaceUri(socket->local_endpoint()),
- socket, true)
+UnixStreamFace::UnixStreamFace(const FaceUri& remoteUri, const FaceUri& localUri,
+ protocol::socket socket)
+ : StreamFace<protocol, LocalFace>(remoteUri, localUri, std::move(socket), true)
{
static_assert(
std::is_same<std::remove_cv<protocol::socket::native_handle_type>::type, int>::value,
diff --git a/daemon/face/unix-stream-face.hpp b/daemon/face/unix-stream-face.hpp
index 51482c4..c377819 100644
--- a/daemon/face/unix-stream-face.hpp
+++ b/daemon/face/unix-stream-face.hpp
@@ -40,8 +40,8 @@
class UnixStreamFace : public StreamFace<boost::asio::local::stream_protocol, LocalFace>
{
public:
- explicit
- UnixStreamFace(const shared_ptr<protocol::socket>& socket);
+ UnixStreamFace(const FaceUri& remoteUri, const FaceUri& localUri,
+ protocol::socket socket);
};
} // namespace nfd
diff --git a/tests/daemon/face/unix-stream.t.cpp b/tests/daemon/face/unix-stream.t.cpp
index c1ee2cb..9816729 100644
--- a/tests/daemon/face/unix-stream.t.cpp
+++ b/tests/daemon/face/unix-stream.t.cpp
@@ -35,8 +35,6 @@
namespace nfd {
namespace tests {
-using namespace boost::asio::local;
-
#define CHANNEL_PATH1 "unix-stream-test.1.sock"
#define CHANNEL_PATH2 "unix-stream-test.2.sock"
@@ -61,23 +59,17 @@
BOOST_AUTO_TEST_CASE(GetChannels)
{
UnixStreamFactory factory;
- BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
+ BOOST_CHECK(factory.getChannels().empty());
- std::vector<shared_ptr<const Channel> > expectedChannels;
-
+ std::vector<shared_ptr<const Channel>> expectedChannels;
expectedChannels.push_back(factory.createChannel(CHANNEL_PATH1));
expectedChannels.push_back(factory.createChannel(CHANNEL_PATH2));
- std::list<shared_ptr<const Channel> > channels = factory.getChannels();
- for (std::list<shared_ptr<const Channel> >::const_iterator i = channels.begin();
- i != channels.end(); ++i)
- {
- std::vector<shared_ptr<const Channel> >::iterator pos =
- std::find(expectedChannels.begin(), expectedChannels.end(), *i);
-
- BOOST_REQUIRE(pos != expectedChannels.end());
- expectedChannels.erase(pos);
- }
+ for (const auto& channel : factory.getChannels()) {
+ auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), channel);
+ BOOST_REQUIRE(pos != expectedChannels.end());
+ expectedChannels.erase(pos);
+ }
BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
}
@@ -160,6 +152,14 @@
limitedIo.afterOp();
}
+ shared_ptr<UnixStreamFace>
+ makeFace(UnixStreamFace::protocol::socket socket)
+ {
+ auto remoteUri = FaceUri::fromFd(socket.native_handle());
+ auto localUri = FaceUri(socket.local_endpoint());
+ return make_shared<UnixStreamFace>(remoteUri, localUri, std::move(socket));
+ }
+
protected:
LimitedIo limitedIo;
@@ -170,7 +170,7 @@
std::vector<Interest> face2_receivedInterests;
std::vector<Data> face2_receivedDatas;
- std::list< shared_ptr<UnixStreamFace> > faces;
+ std::list<shared_ptr<UnixStreamFace>> faces;
};
@@ -182,25 +182,24 @@
channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
- shared_ptr<stream_protocol::socket> client = make_shared<stream_protocol::socket>(ref(g_io));
- client->async_connect(stream_protocol::endpoint(CHANNEL_PATH1),
- bind(&EndToEndFixture::client_onConnect, this, _1));
+ UnixStreamFace::protocol::socket client(g_io);
+ client.async_connect(UnixStreamFace::protocol::endpoint(CHANNEL_PATH1),
+ bind(&EndToEndFixture::client_onConnect, this, _1));
- BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UnixStreamChannel error: cannot connect or cannot accept connection");
+ BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS, "Connect");
BOOST_REQUIRE(static_cast<bool>(face1));
BOOST_CHECK_EQUAL(face1->isLocal(), true);
BOOST_CHECK_EQUAL(face1->isOnDemand(), true);
BOOST_CHECK_EQUAL(face1->isMultiAccess(), false);
BOOST_CHECK_EQUAL(face1->getRemoteUri().getScheme(), "fd");
- BOOST_CHECK_NO_THROW(boost::lexical_cast<int>(face1->getRemoteUri().getHost()));
+ BOOST_CHECK_NO_THROW(std::stoi(face1->getRemoteUri().getHost()));
std::string face1localUri = face1->getLocalUri().toString();
BOOST_CHECK_EQUAL(face1localUri.find("unix:///"), 0); // third '/' is the path separator
BOOST_CHECK_EQUAL(face1localUri.rfind(CHANNEL_PATH1),
face1localUri.size() - std::string(CHANNEL_PATH1).size());
- face2 = make_shared<UnixStreamFace>(client);
+ face2 = makeFace(std::move(client));
face2->onReceiveInterest.connect(bind(&EndToEndFixture::face2_onReceiveInterest, this, _1));
face2->onReceiveData.connect(bind(&EndToEndFixture::face2_onReceiveData, this, _1));
@@ -220,8 +219,7 @@
face2->sendData (*data2 );
size_t nBytesSent2 = interest2->wireEncode().size() + data2->wireEncode().size() * 3;
- BOOST_CHECK_MESSAGE(limitedIo.run(8, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UnixStreamChannel error: cannot send or receive Interest/Data packets");
+ BOOST_CHECK_MESSAGE(limitedIo.run(8, time::seconds(1)) == LimitedIo::EXCEED_OPS, "Send/receive");
BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 3);
@@ -259,21 +257,19 @@
channel->listen(bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
- shared_ptr<stream_protocol::socket> client1 = make_shared<stream_protocol::socket>(ref(g_io));
- client1->async_connect(stream_protocol::endpoint(CHANNEL_PATH1),
- bind(&EndToEndFixture::client_onConnect, this, _1));
+ UnixStreamFace::protocol::socket client1(g_io);
+ client1.async_connect(UnixStreamFace::protocol::endpoint(CHANNEL_PATH1),
+ bind(&EndToEndFixture::client_onConnect, this, _1));
- BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UnixStreamChannel error: cannot connect or cannot accept connection");
+ BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS, "First connect");
BOOST_CHECK_EQUAL(faces.size(), 1);
- shared_ptr<stream_protocol::socket> client2 = make_shared<stream_protocol::socket>(ref(g_io));
- client2->async_connect(stream_protocol::endpoint(CHANNEL_PATH1),
- bind(&EndToEndFixture::client_onConnect, this, _1));
+ UnixStreamFace::protocol::socket client2(g_io);
+ client2.async_connect(UnixStreamFace::protocol::endpoint(CHANNEL_PATH1),
+ bind(&EndToEndFixture::client_onConnect, this, _1));
- BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UnixStreamChannel error: cannot accept multiple connections");
+ BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS, "Second connect");
BOOST_CHECK_EQUAL(faces.size(), 2);
@@ -285,7 +281,7 @@
face1->onReceiveInterest.connect(bind(&EndToEndFixture::face1_onReceiveInterest, this, _1));
face1->onReceiveData.connect(bind(&EndToEndFixture::face1_onReceiveData, this, _1));
- face2 = make_shared<UnixStreamFace>(client2);
+ face2 = makeFace(std::move(client2));
face2->onReceiveInterest.connect(bind(&EndToEndFixture::face2_onReceiveInterest, this, _1));
face2->onReceiveData.connect(bind(&EndToEndFixture::face2_onReceiveData, this, _1));
@@ -299,8 +295,7 @@
face2->sendInterest(*interest2);
face2->sendData (*data2 );
- BOOST_CHECK_MESSAGE(limitedIo.run(4, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UnixStreamChannel error: cannot send or receive Interest/Data packets");
+ BOOST_CHECK_MESSAGE(limitedIo.run(4, time::seconds(1)) == LimitedIo::EXCEED_OPS, "Send/receive");
BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 1);
@@ -313,11 +308,6 @@
BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1->getName());
}
-static inline void
-noOp()
-{
-}
-
BOOST_FIXTURE_TEST_CASE(UnixStreamFaceLocalControlHeader, EndToEndFixture)
{
UnixStreamFactory factory;
@@ -326,16 +316,15 @@
channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
- shared_ptr<stream_protocol::socket> client = make_shared<stream_protocol::socket>(ref(g_io));
- client->async_connect(stream_protocol::endpoint(CHANNEL_PATH1),
- bind(&EndToEndFixture::client_onConnect, this, _1));
+ UnixStreamFace::protocol::socket client(g_io);
+ client.async_connect(UnixStreamFace::protocol::endpoint(CHANNEL_PATH1),
+ bind(&EndToEndFixture::client_onConnect, this, _1));
- BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UnixStreamChannel error: cannot connect or cannot accept connection");
+ BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS, "Connect");
BOOST_REQUIRE(static_cast<bool>(face1));
- face2 = make_shared<UnixStreamFace>(client);
+ face2 = makeFace(std::move(client));
face2->onReceiveInterest.connect(bind(&EndToEndFixture::face2_onReceiveInterest, this, _1));
face2->onReceiveData.connect(bind(&EndToEndFixture::face2_onReceiveData, this, _1));
@@ -358,18 +347,14 @@
interest1->setIncomingFaceId(11);
interest1->setNextHopFaceId(111);
-
face1->sendInterest(*interest1);
data1->setIncomingFaceId(22);
data1->getLocalControlHeader().setNextHopFaceId(222);
-
face1->sendData(*data1);
- //
-
BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UnixStreamChannel error: cannot send or receive Interest/Data packets");
+ "Regular send/receive");
BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
@@ -381,33 +366,41 @@
BOOST_CHECK_EQUAL(face2_receivedDatas[0].getLocalControlHeader().hasIncomingFaceId(), false);
BOOST_CHECK_EQUAL(face2_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
+ face1->close();
+ face1.reset();
+
////////////////////////////////////////////////////////
- using namespace boost::asio;
+ client.async_connect(UnixStreamFace::protocol::endpoint(CHANNEL_PATH1),
+ bind(&EndToEndFixture::client_onConnect, this, _1));
- std::vector<const_buffer> interestWithHeader;
- Block iHeader = interest1->getLocalControlHeader().wireEncode(*interest1,
- ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID |
- ndn::nfd::LocalControlHeader::ENCODE_NEXT_HOP);
+ BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS, "Connect");
+
+ BOOST_REQUIRE(static_cast<bool>(face1));
+ face1->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
+ face1->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
+
+ Block iHeader = interest1->getLocalControlHeader()
+ .wireEncode(*interest1, ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID |
+ ndn::nfd::LocalControlHeader::ENCODE_NEXT_HOP);
Block iPayload = interest1->wireEncode();
- interestWithHeader.push_back(buffer(iHeader.wire(), iHeader.size()));
- interestWithHeader.push_back(buffer(iPayload.wire(), iPayload.size()));
- std::vector<const_buffer> dataWithHeader;
- Block dHeader = data1->getLocalControlHeader().wireEncode(*data1,
- ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID |
- ndn::nfd::LocalControlHeader::ENCODE_NEXT_HOP);
+ Block dHeader = data1->getLocalControlHeader()
+ .wireEncode(*data1, ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID |
+ ndn::nfd::LocalControlHeader::ENCODE_NEXT_HOP);
Block dPayload = data1->wireEncode();
- dataWithHeader.push_back(buffer(dHeader.wire(), dHeader.size()));
- dataWithHeader.push_back(buffer(dPayload.wire(), dPayload.size()));
- //
-
- client->async_send(interestWithHeader, bind(&noOp));
- client->async_send(dataWithHeader, bind(&noOp));
+ client.async_send(std::vector<boost::asio::const_buffer>{iHeader, iPayload},
+ [] (const boost::system::error_code& error, size_t nBytesSent) {
+ BOOST_CHECK_MESSAGE(!error, error.message());
+ });
+ client.async_send(std::vector<boost::asio::const_buffer>{dHeader, dPayload},
+ [] (const boost::system::error_code& error, size_t nBytesSent) {
+ BOOST_CHECK_MESSAGE(!error, error.message());
+ });
BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
- "UnixStreamChannel error: cannot send or receive Interest/Data packets");
+ "Send/receive with LocalControlHeader");
BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 1);
@@ -489,15 +482,13 @@
channel->listen(bind(&SimpleEndToEndFixture::onFaceCreated, this, _1),
bind(&SimpleEndToEndFixture::onConnectFailed, this, _1));
- DummyStreamSender<stream_protocol, Dataset> sender;
- sender.start(stream_protocol::endpoint(CHANNEL_PATH1));
+ DummyStreamSender<UnixStreamFace::protocol, Dataset> sender;
+ sender.start(UnixStreamFace::protocol::endpoint(CHANNEL_PATH1));
- BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS,
- time::seconds(1)) == LimitedIo::EXCEED_TIME,
+ BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS, time::seconds(1)) == LimitedIo::EXCEED_TIME,
"Exception thrown for " + Dataset::getName());
}
-
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests