face: GenericLinkService drops IDLE packets

refs #3249

Change-Id: I3d16bcf29f4858049d1040a3e421e1c7151b3fed
diff --git a/daemon/face/generic-link-service.cpp b/daemon/face/generic-link-service.cpp
index 4fa4c1c..23e2ce2 100644
--- a/daemon/face/generic-link-service.cpp
+++ b/daemon/face/generic-link-service.cpp
@@ -119,14 +119,19 @@
 void
 GenericLinkService::doReceivePacket(Transport::Packet&& packet)
 {
-  lp::Packet pkt(packet.packet);
-
-  if (pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) {
-    NFD_LOG_FACE_WARN("received fragment, but reassembly not implemented: DROP");
-    return;
-  }
-
   try {
+    lp::Packet pkt(packet.packet);
+
+    if (!pkt.has<lp::FragmentField>()) {
+      NFD_LOG_FACE_TRACE("received IDLE packet: DROP");
+      return;
+    }
+
+    if (pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) {
+      NFD_LOG_FACE_WARN("received fragment, but reassembly not implemented: DROP");
+      return;
+    }
+
     ndn::Buffer::const_iterator fragBegin, fragEnd;
     std::tie(fragBegin, fragEnd) = pkt.get<lp::FragmentField>();
     Block netPkt(&*fragBegin, std::distance(fragBegin, fragEnd));
diff --git a/tests/daemon/face/generic-link-service.t.cpp b/tests/daemon/face/generic-link-service.t.cpp
index aa2c7a7..ac01c7d 100644
--- a/tests/daemon/face/generic-link-service.t.cpp
+++ b/tests/daemon/face/generic-link-service.t.cpp
@@ -213,6 +213,24 @@
   BOOST_REQUIRE_EQUAL(receivedNacks.size(), 1);
 }
 
+BOOST_AUTO_TEST_CASE(ReceiveIdlePacket)
+{
+  // Initialize with Options that disables all services
+  GenericLinkService::Options options;
+  options.allowLocalFields = false;
+  initialize(options);
+
+  lp::Packet lpPacket;
+  lpPacket.set<lp::SequenceField>(0);
+
+  BOOST_CHECK_NO_THROW(transport->receivePacket(lpPacket.wireEncode()));
+
+  // IDLE packet should be ignored
+  BOOST_CHECK_EQUAL(receivedInterests.size(), 0);
+  BOOST_CHECK_EQUAL(receivedData.size(), 0);
+  BOOST_CHECK_EQUAL(receivedNacks.size(), 0);
+}
+
 BOOST_AUTO_TEST_SUITE_END() // SimpleSendReceive
 
 
@@ -485,6 +503,44 @@
 BOOST_AUTO_TEST_SUITE_END() // LocalFields
 
 
+BOOST_AUTO_TEST_SUITE(Malformed) // receive malformed packets
+
+BOOST_AUTO_TEST_CASE(WrongTlvType)
+{
+  // Initialize with Options that disables all services
+  GenericLinkService::Options options;
+  options.allowLocalFields = false;
+  initialize(options);
+
+  Block packet = ndn::encoding::makeEmptyBlock(tlv::Name);
+
+  BOOST_CHECK_NO_THROW(transport->receivePacket(packet));
+
+  BOOST_CHECK_EQUAL(receivedInterests.size(), 0);
+  BOOST_CHECK_EQUAL(receivedData.size(), 0);
+  BOOST_CHECK_EQUAL(receivedNacks.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(Unparsable)
+{
+  // Initialize with Options that disables all services
+  GenericLinkService::Options options;
+  options.allowLocalFields = false;
+  initialize(options);
+
+  Block packet = ndn::encoding::makeStringBlock(lp::tlv::LpPacket, "x");
+  BOOST_CHECK_THROW(packet.parse(), tlv::Error);
+
+  BOOST_CHECK_NO_THROW(transport->receivePacket(packet));
+
+  BOOST_CHECK_EQUAL(receivedInterests.size(), 0);
+  BOOST_CHECK_EQUAL(receivedData.size(), 0);
+  BOOST_CHECK_EQUAL(receivedNacks.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Malformed
+
+
 BOOST_AUTO_TEST_SUITE_END() // TestGenericLinkService
 BOOST_AUTO_TEST_SUITE_END() // Face