face: Gracefully handle tlv::Error when received TLV block is malformed
Change-Id: I954b13d0e26fec7bc7fe23edcbc015dfac654ef8
Refs: #1494
diff --git a/tests/daemon/face/unix-stream.cpp b/tests/daemon/face/unix-stream.cpp
index 4181aa1..06ff5d3 100644
--- a/tests/daemon/face/unix-stream.cpp
+++ b/tests/daemon/face/unix-stream.cpp
@@ -26,6 +26,8 @@
#include "tests/test-common.hpp"
#include "tests/limited-io.hpp"
+#include "dummy-stream-sender.hpp"
+#include "packet-datasets.hpp"
namespace nfd {
namespace tests {
@@ -178,28 +180,19 @@
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);
+ shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
+ shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
+ shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
+ shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
- 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);
-
- face1->sendInterest(interest1);
- face1->sendInterest(interest1);
- face1->sendInterest(interest1);
- face1->sendData (data1 );
- face2->sendInterest(interest2);
- face2->sendData (data2 );
- face2->sendData (data2 );
- face2->sendData (data2 );
+ face1->sendInterest(*interest1);
+ face1->sendInterest(*interest1);
+ face1->sendInterest(*interest1);
+ face1->sendData (*data1 );
+ face2->sendInterest(*interest2);
+ face2->sendData (*data2 );
+ face2->sendData (*data2 );
+ face2->sendData (*data2 );
BOOST_CHECK_MESSAGE(limitedIo.run(8, time::seconds(1)) == LimitedIo::EXCEED_OPS,
"UnixStreamChannel error: cannot send or receive Interest/Data packets");
@@ -209,10 +202,10 @@
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());
+ 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());
const FaceCounters& counters1 = face1->getCounters();
BOOST_CHECK_EQUAL(counters1.getNInInterests() , 1);
@@ -267,24 +260,15 @@
face2->onReceiveInterest += bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
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);
+ shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
+ shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
+ shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
+ shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
- 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);
-
- face1->sendInterest(interest1);
- face1->sendData (data1 );
- face2->sendInterest(interest2);
- face2->sendData (data2 );
+ face1->sendInterest(*interest1);
+ face1->sendData (*data1 );
+ 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");
@@ -294,10 +278,10 @@
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());
+ 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());
}
static inline void
@@ -329,19 +313,8 @@
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);
+ shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
+ shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
face1->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
face1->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
@@ -357,15 +330,15 @@
////////////////////////////////////////////////////////
- interest1.setIncomingFaceId(11);
- interest1.setNextHopFaceId(111);
+ interest1->setIncomingFaceId(11);
+ interest1->setNextHopFaceId(111);
- face1->sendInterest(interest1);
+ face1->sendInterest(*interest1);
- data1.setIncomingFaceId(22);
- data1.getLocalControlHeader().setNextHopFaceId(222);
+ data1->setIncomingFaceId(22);
+ data1->getLocalControlHeader().setNextHopFaceId(222);
- face1->sendData (data1);
+ face1->sendData(*data1);
//
@@ -387,14 +360,14 @@
using namespace boost::asio;
std::vector<const_buffer> interestWithHeader;
- Block iHeader = interest1.getLocalControlHeader().wireEncode(interest1, true, true);
- Block iPayload = interest1.wireEncode();
+ 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();
+ 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()));
@@ -417,6 +390,87 @@
BOOST_CHECK_EQUAL(face1_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
}
+
+class SimpleEndToEndFixture : protected BaseFixture
+{
+public:
+ void
+ onFaceCreated(const shared_ptr<Face>& face)
+ {
+ face->onReceiveInterest +=
+ bind(&SimpleEndToEndFixture::onReceiveInterest, this, _1);
+ face->onReceiveData +=
+ bind(&SimpleEndToEndFixture::onReceiveData, this, _1);
+ face->onFail +=
+ bind(&SimpleEndToEndFixture::onFail, this, face);
+
+ if (static_cast<bool>(dynamic_pointer_cast<LocalFace>(face))) {
+ static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
+ LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
+
+ static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
+ LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
+ }
+
+ limitedIo.afterOp();
+ }
+
+ void
+ onConnectFailed(const std::string& reason)
+ {
+ BOOST_CHECK_MESSAGE(false, reason);
+
+ limitedIo.afterOp();
+ }
+
+ void
+ onReceiveInterest(const Interest& interest)
+ {
+ receivedInterests.push_back(interest);
+
+ limitedIo.afterOp();
+ }
+
+ void
+ onReceiveData(const Data& data)
+ {
+ receivedDatas.push_back(data);
+
+ limitedIo.afterOp();
+ }
+
+ void
+ onFail(const shared_ptr<Face>& face)
+ {
+ limitedIo.afterOp();
+ }
+
+public:
+ LimitedIo limitedIo;
+
+ std::vector<Interest> receivedInterests;
+ std::vector<Data> receivedDatas;
+};
+
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(CorruptedInput, Dataset,
+ CorruptedPackets, SimpleEndToEndFixture)
+{
+ UnixStreamFactory factory;
+
+ shared_ptr<UnixStreamChannel> channel = factory.createChannel(CHANNEL_PATH1);
+ channel->listen(bind(&SimpleEndToEndFixture::onFaceCreated, this, _1),
+ bind(&SimpleEndToEndFixture::onConnectFailed, this, _1));
+
+ DummyStreamSender<stream_protocol, Dataset> sender;
+ sender.start(stream_protocol::endpoint(CHANNEL_PATH1));
+
+ 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