face: Implementation of encode/decode of LocalControlHeader
LocalControlHeader can only be used on faces that are derived from
LocalFace. UnixStreamFace is directly inherited from LocalFace,
TCP face has two specializations: generic TcpFace (strictly not local),
and LocalTcpFace.
refs #1213
Change-Id: I8a158c3bc4bb929eedd15757cfddecc0d1049f9f
diff --git a/tests/face/unix-stream.cpp b/tests/face/unix-stream.cpp
index fee5827..9d6a6cf 100644
--- a/tests/face/unix-stream.cpp
+++ b/tests/face/unix-stream.cpp
@@ -61,7 +61,7 @@
this->afterIo();
}
-
+
void
face1_onReceiveInterest(const Interest& interest)
{
@@ -69,7 +69,7 @@
this->afterIo();
}
-
+
void
face1_onReceiveData(const Data& data)
{
@@ -85,7 +85,7 @@
this->afterIo();
}
-
+
void
face2_onReceiveData(const Data& data)
{
@@ -310,6 +310,138 @@
BOOST_CHECK_EQUAL(m_face2_receivedDatas [0].getName(), data1.getName());
}
+static inline void
+noOp()
+{
+}
+
+BOOST_FIXTURE_TEST_CASE(UnixStreamFaceLocalControlHeader, EndToEndFixture)
+{
+ UnixStreamChannelFactory factory(m_ioService);
+ Scheduler scheduler(m_ioService); // to limit the amount of time the test may take
+
+ EventId abortEvent =
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(&EndToEndFixture::abortTestCase, this,
+ "UnixStreamChannel error: cannot connect or cannot accept connection"));
+
+ shared_ptr<UnixStreamChannel> channel1 = factory.create("foo");
+ 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>(boost::ref(m_ioService));
+ client->async_connect(stream_protocol::endpoint("foo"),
+ bind(&EndToEndFixture::client_onConnect, this, _1));
+
+ m_ioRemaining = 2;
+ m_ioService.run();
+ m_ioService.reset();
+ scheduler.cancelEvent(abortEvent);
+
+ BOOST_REQUIRE(static_cast<bool>(m_face1));
+
+ abortEvent =
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(&EndToEndFixture::abortTestCase, this,
+ "UnixStreamChannel error: cannot send or receive Interest/Data packets"));
+
+ m_face2 = make_shared<UnixStreamFace>(client);
+ m_face2->onReceiveInterest +=
+ bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
+ m_face2->onReceiveData +=
+ bind(&EndToEndFixture::face2_onReceiveData, this, _1);
+
+ Interest interest1("ndn:/TpnzGvW9R");
+ Data data1 ("ndn:/KfczhUqVix");
+ data1.setContent(0, 0);
+ Interest interest2("ndn:/QWiIMfj5sL");
+ Data data2 ("ndn:/XNBV796f");
+ data2.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);
+
+ m_face1->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID);
+ m_face1->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID);
+
+ BOOST_CHECK(m_face1->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID));
+ BOOST_CHECK(m_face1->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID));
+
+ m_face2->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID);
+ m_face2->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID);
+
+ BOOST_CHECK(m_face2->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID));
+ BOOST_CHECK(m_face2->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID));
+
+ ////////////////////////////////////////////////////////
+
+ interest1.setIncomingFaceId(11);
+ interest1.setNextHopFaceId(111);
+
+ m_face1->sendInterest(interest1);
+
+ data1.setIncomingFaceId(22);
+ data1.getLocalControlHeader().setNextHopFaceId(222);
+
+ m_face1->sendData (data1);
+
+ //
+
+ m_ioRemaining = 2;
+ m_ioService.run();
+ m_ioService.reset();
+
+ BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
+ BOOST_REQUIRE_EQUAL(m_face2_receivedDatas .size(), 1);
+
+ // sending allows only IncomingFaceId, receiving allows only NextHopFaceId
+ BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getLocalControlHeader().hasIncomingFaceId(), false);
+ BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getLocalControlHeader().hasNextHopFaceId(), false);
+
+ BOOST_CHECK_EQUAL(m_face2_receivedDatas[0].getLocalControlHeader().hasIncomingFaceId(), false);
+ BOOST_CHECK_EQUAL(m_face2_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
+
+ ////////////////////////////////////////////////////////
+
+ using namespace boost::asio;
+
+ std::vector<const_buffer> interestWithHeader;
+ Block iHeader = interest1.getLocalControlHeader().wireEncode(interest1, true, true);
+ 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, true, true);
+ 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));
+
+ m_ioRemaining = 2;
+ m_ioService.run();
+ m_ioService.reset();
+
+ BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
+ BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 1);
+
+ BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getLocalControlHeader().hasIncomingFaceId(), false);
+ BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getLocalControlHeader().hasNextHopFaceId(), true);
+ BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getNextHopFaceId(), 111);
+
+ BOOST_CHECK_EQUAL(m_face1_receivedDatas[0].getLocalControlHeader().hasIncomingFaceId(), false);
+ BOOST_CHECK_EQUAL(m_face1_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
+}
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace nfd