<div dir="ltr"><div class="gmail_quote"><div dir="ltr">This proposal describes the original design intention of the Interest dispatch mechanism of NFD management.<div>This message was originally sent on Jun 02. This version is a correction.</div><div><br></div><div>Current implemented approach:</div><div>NFD management module consists of:</div><div>
<ul><li>several Managers, such as FaceManager, FibManager, StrategyChoiceManager</li><li>an InternalFace</li><li>a configuration parser</li></ul><div>To process an Interest:</div><div><ul><li>InternalFace receives ndn:/localhost/nfd Interests from forwarding, looks at the third component (management module), and dispatch it to a Manager.</li>
<li>Upon Interest arrival, Manager looks at the fourth component, and do one of the following:</li><ul><li>for command verb: validate Command Interest, and then dispatch the Interest to the function that handles this command</li>
<li>for dataset: dispatch the Interest to the function that generates data for this dataset</li><li>for notification stream: drop the Interest</li></ul><li>Replies are directly written to InternalFace</li></ul></div><div>Drawback of this design:</div><div><ul><li>Each Interest is dispatched twice: once in InternalFace, again in Manager.</li><li>Authentication is scattered across Managers.</li><li>Reply encryption is non-existent.</li></ul></div><div><br></div><div>Design intention:</div><div><br></div><div><div><font face="courier new, monospace">partial interface InternalFace {</font></div><div><font face="courier new, monospace">  // reply(const Data& data, bool isFinal);</font></div>
<div><font face="courier new, monospace">  //   data: unsigned and unencrypted Data</font></div><div><font face="courier new, monospace">  //   isFinal: true if this is that last Data to send</font></div><div><font face="courier new, monospace">  typedef function<void(const Data&, bool)> ReplyFunc;</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  // process(const Interest& interest, const Name& identity, ReplyFunc reply);</font></div><div><font face="courier new, monospace">  //   identity: verified identity of requester, if available; otherwise empty</font></div>
<div><font face="courier new, monospace">  //   reply: a function to send replies</font></div><div><font face="courier new, monospace">  typedef function<void(const Interest&, const Name&, ReplyFunc)> InterestHandler;</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  // accept(const Name& identity)</font></div><div><font face="courier new, monospace">  //   identity: verified identity of requester, if available; otherwise empty</font></div>
<div><span style="font-family:'courier new',monospace">  typedef function<void(const Name&)> AcceptContinuation;</span><br></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  // reject(bool reply401)</font></div>
<div><font face="courier new, monospace">  //   send401: whether to reply 401 or silently drop</font></div><div><font face="courier new, monospace">  typedef function<void(bool)> RejectContinuation;</font></div><div>
<font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  // authorize(const Name& prefix, const Interest& interest, AcceptContinuation accept, RejectContinuation reject);</font></div><div><font face="courier new, monospace">  //   accept: function to call if authentication succeeds</font></div><div><font face="courier new, monospace">  //   reject: function to call if authentication fails</font></div>
<div><span style="font-family:'courier new',monospace">  typedef function<void(const Name&, const Interest&, AcceptContinuation, RejectContinuation)> Authorization;</span><br></div><div><span style="font-family:'courier new',monospace"><br>
</span></div><div><span style="font-family:'courier new',monospace">  // encryptReply(const Name& identity, shared_ptr<Data> data);</span></div><div><span style="font-family:'courier new',monospace">  typedef function<void(const Name&, shared_ptr<Data>)> ReplyEncryption</span></div><div><font face="courier new, monospace"><br></font></div><div><span style="font-family:'courier new',monospace">  void register(const Name& prefix, Authorization, ReplyEncryption, InterestHandler handler);</span><br>
</div><div><span style="font-family:'courier new',monospace">}</span><br></div></div><div><br></div><div><ul><li>During initialization, Manager should register its commands, datasets, and notification streams into InternalFace</li><ul><li>
examples:<br>face->register("ndn:/localhost/nfd/faces/create", CommandInterestAuthorization("faces"), NullReplyEncryption(), bind(&FaceManager::onCreateCommand, this, _1, _2, _3));<br>face->register("ndn:/localhost/nfd/faces/list", DatasetAuthorization(), NullReplyEncryption(), bind(&FaceManager::generateFaceList, this, _3));<br>
face->register("ndn:/localhost/nfd/faces/events", DropAllAuthorization(), nullptr, nullptr);</li></ul><li>InternalFace receives ndn:/localhost/nfd Interests from forwarding, perform a longest prefix match on registered prefixes</li>
<ul><li>if no registration is found, record to log, and drop the Interest</li></ul><li>Perform authorization as requested</li><ul><li>CommandInterestAuthorization(const std::string& privilege) accepts valid Command Interests with this privilege, and rejects with 401 otherwise</li>
<li>DatasetAuthorization accepts Interests with Name equal to the prefix, and drops other Interests (they should be satisfied by ContentStore)</li><li>DropAllAuthorization drops all Interests; this is used with notification streams because Interests should wait until notification is delivered</li>
</ul><li>Dispatch to the handler</li><li>Handler calls ReplyFunc zero or more times with unsigned and unencrypted Data</li><li>ReplyFunc is a bound function that knows the ReplyEncryption; it encrypts Data as requested, and then sign and send it</li>
</ul><div><br></div><div>In addition, derive a ndn::Face subclass (which has the same API as a client face in ndn-cxx), so that the same Dataset publisher and Notification Stream publisher can be used both in external app and within NFD management.</div></div></div><div><br></div><div>Yours, Junxiao</div></div>
</div><br></div>