<div dir="ltr"><div><div>Hi Sabet<br><br></div>This may be related to the retransmission behavior of ns3::ndn::ConsumerCbr.<br></div><div><br></div><div>I can see that ndn::LinkControlHelper::<wbr>FailLink does not cause face->getStatus() to become DOWN, and there is no BFD running, so the face will remain UP from strategy point of view.<br></div><div>Your scenario uses static routes, so that 0->2 route would remain active even if the link is having 100% loss rate.<br></div><div>As long as face->getState() is UP and the route is still active, NFD best-route v4 keeps using 0->2 route when an Interest is received for the first time, and will try 0->1 route only if the consumer retransmit the Interest (same Name+Selectors+Link, different Nonce).<br></div><div>Moreover, a consumer retransmission can cause best-route v4 to use 0->2 route only if it arrives no later than InterestLifetime expiration (2 seconds in your scenario), and no earlier than best-route's suppression timer (10ms for the first retransmission).<br></div><div><br>ns3::ndn::ConsumerCbr expresses a new Interest every 1 second with InterestLifetime 2000ms, and retransmits an unsatisfied Interest after RTO. RTO is computed using TCP's algorithm, bounded between 0.2 and 200 seconds.<br></div><div>When Data arrives, its RTT is added to the RttEstimator if the Interest has not been retransmitted. On the other hand, if an Interest times out (no Data within RTO), the RTO multiplier doubles, up to 64. The multiplier can be reset to 1 only if a Data arrives without any Interest retransmission.<br></div><div>Combine this with the behavior of best-route v4, we can see that, since best-route v4 requires consumer retransmission for every Interest in order to retrieve Data via 0->1 route, the multiplier would never get reset.<br></div><div>Eventually, the RTO would exceed InterestLifetime, and therefore the retransmitted Interest would not be detected by best-route v4 as consumer retransmission.<br><br></div><div>Your log shows, Interest for seq 6 is initially sent at 9.0s. RTO timeout occurs at 10.6s. Then, the logic in ConsumerCbr schedules the retransmission at 11.0s.<br></div><div>This is exactly the case I described above: at 11.0s, PIT entry is gone because InterestLifetime has expired, so that best-route v4 would detect the Interest as a new Interest instead of a retransmission, and forward it toward 0->2 route which is having 100% loss rate.<br></div><div>This is the expected behavior of best-route v4, and it's not a NFD bug.<br><br><br></div><div>To make this scenario work better, suggestions are:<br><ul><li>Implement BFD in the face, making face->getState() report as DOWN, so that strategy would not use the face.</li><li>Use AccessStrategy, which can switch to 0->1 route if 0->2 isn't working. But it won't switch back.<br></li><li>Change either InterestLifetime or max RTO, so that max RTO (plus ConsumerCbr's scheduling delay) is less than InterestLifetime.</li></ul></div><div><br></div>Yours, Junxiao<br><div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Feb 18, 2017 at 11:26 AM, Muhammad Hosain Abdollahi Sabet <span dir="ltr"><<a href="mailto:mhasabet@gmail.com" target="_blank">mhasabet@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>​Hi there,<br></div><div><br></div><div>I was trying to show the impact forwarding plane and forwarding strategy in failure detection with a simple scenario in ndnSIM:<br><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">  ndn::FibHelper::AddRoute(nodes<wbr>.Get(0),ndn::Name("/prefix"), nodes.Get(2),1);<br>  ndn::FibHelper::AddRoute(nodes<wbr>.Get(1),ndn::Name("/prefix"), nodes.Get(2),20);<br>  ndn::FibHelper::AddRoute(nodes<wbr>.Get(0),ndn::Name("/prefix"), nodes.Get(1),20);<br><br>  ndn::StrategyChoiceHelper::Ins<wbr>tall(nodes.Get(0), ndn::Name("/prefix"), "/localhost/nfd/strategy/best-<wbr>route");<br>  <br>  // Consumer<br>  ndn::AppHelper consumerHelper("ns3::ndn::Cons<wbr>umerCbr");<br>  consumerHelper.SetPrefix("/pre<wbr>fix");<br>  consumerHelper.SetAttribute("F<wbr>requency", StringValue("1")); <br>  consumerHelper.Install(nodes.G<wbr>et(0));                        <br><br>  // Producer<br>  ndn::AppHelper producerHelper("ns3::ndn::Prod<wbr>ucer");<br>  producerHelper.SetPrefix("/pre<wbr>fix");<br>  producerHelper.SetAttribute("P<wbr>ayloadSize", StringValue("1024"));<br>  producerHelper.Install(nodes.G<wbr>et(2)); <br><br>  Simulator::Schedule(Seconds(3.<wbr>0), ndn::LinkControlHelper::FailLi<wbr>nk, nodes.Get(0), nodes.Get(2));<br>  Simulator::Schedule(Seconds(15<wbr>.0), ndn::LinkControlHelper::UpLink<wbr>, nodes.Get(0), nodes.Get(2));<br></blockquote><div><br>It works fine at first and detects the failure so tries with the other face from 4s to 8s. But After 9s, Consumer tries sending interest while nfd does not send it:<br><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">9s 0 ndn.Consumer:SendPacket() <br>9s 0 ndn.Consumer:SendPacket(): [INFO ] > Interest for 6<br>9s 0 ndn.Consumer:WillSendOutIntere<wbr>st(): [DEBUG] Trying to add 6 with +9000000000.0ns. already 0 items<br>10s 0 ndn.Consumer:SendPacket()<br>10s 0 ndn.Consumer:SendPacket(): [INFO ] > Interest for 7<br>10s 0 ndn.Consumer:WillSendOutIntere<wbr>st(): [DEBUG] Trying to add 7 with +10000000000.0ns. already 1 items<br>10.6s -1 ndn.Consumer:OnTimeout(6)<br>11s 0 ndn.Consumer:SendPacket()<br>11s 0 ndn.Consumer:SendPacket(): [INFO ] > Interest for 6<br>11s 0 ndn.Consumer:WillSendOutIntere<wbr>st(): [DEBUG] Trying to add 6 with +11000000000.0ns. already 1 items<br></blockquote><div><br></div><div> As soon as UpLink event, consumer tries with the first face and retrieves data. Why is that? Is it a kind of bug in nfd?<br><br></div><div>Thanks,<br></div><div>Sabet<br></div></div></div></div></blockquote></div></div></div></div></div></div>