Project

General

Profile

Feature #4786

KITE implementation

Added by Zhongda Xia 7 months ago. Updated 1 day ago.

Status:
In Progress
Priority:
Normal
Assignee:
Category:
Forwarding
Target version:
-
Start date:
Due date:
% Done:

0%

Estimated time:

Description

KITE is a producer mobility support solution for NDN. The goal of this issue is to implement network-layer support for KITE in NFD. For the design details, the paper and slides for ACM ICN 18' are attached.

icn18-final23.pdf (1.74 MB) icn18-final23.pdf Zhongda Xia, 12/10/2018 02:31 PM
slides-papers-13.pdf (1.46 MB) slides-papers-13.pdf Zhongda Xia, 12/10/2018 02:31 PM

Related issues

Blocked by ndn-cxx - Feature #4804: Signed Interest v0.3In Progress

History

#1 Updated by Davide Pesavento 7 months ago

  • Tracker changed from Task to Feature
  • Start date deleted (12/10/2018)

#2 Updated by Zhongda Xia 7 months ago

I have revised the implementation plan according to the last discussion. Link to Google doc: https://docs.google.com/document/d/1p0TCVdWuNIAPFmhy50-CnOpfsxax5F7JbyUP53fLDJE/edit?usp=sharing

A few key points:
* the "trace" tag name component should be "keyword" type
* trace Data should be set to a designated ContentType
* trace Data carries a PrefixAnnouncment object
* the trust schema for trace Data verification should be provided (manually at this stage)

Apart from implementing the network layer support, another required change is using NFD readvertise module for trace update (sending trace Interest upon relocation). I am currently checking the readvertise code to figure out the missing parts, any help or suggestion is welcome!

#3 Updated by Junxiao Shi 7 months ago

The ContentType should be reserved on ContentType registry.
This in turn requires a specification of the exact encoding of the trace data.

#4 Updated by Zhongda Xia 6 months ago

Junxiao Shi wrote:

The ContentType should be reserved on ContentType registry.
This in turn requires a specification of the exact encoding of the trace data.

Hi Junxiao, I haven't figured out how to edit the Wiki page, maybe I don't have the permissions?

#5 Updated by Teng Liang 6 months ago

Hi Junxiao, I haven't figured out how to edit the Wiki page, maybe I don't have the permissions?

Can you see an icon with the name New wiki page on this page https://redmine.named-data.net/projects/nfd/wiki?

#6 Updated by Zhongda Xia 6 months ago

Teng Liang wrote:

Hi Junxiao, I haven't figured out how to edit the Wiki page, maybe I don't have the permissions?

Can you see an icon with the name New wiki page on this page https://redmine.named-data.net/projects/nfd/wiki?

Hi Teng, no I don't see the icon.

#7 Updated by Davide Pesavento 6 months ago

I've added you to the NFD project as developer. Try again.

#8 Updated by Zhongda Xia 6 months ago

Davide Pesavento wrote:

I've added you to the NFD project as developer. Try again.

Works now, thanks.

#9 Updated by Zhongda Xia 5 months ago

As last discussed in an NFD call, a KiteAck (trace Data in KITE) should carry a prefix announcement object (PA) to reuse the existing code for verification. The RV will create a PA for each legitimate trace Interest (signed Interest sent by a mobile producer), encapsulate the PA in a Data packet (KiteAck), and forwarders check the PA carried in KiteAck to decide whether to update RIB.

But for KITE, an extra step is needed, that is, to check whether the prefix specified by the PA is the same as the prefix specified by the Interest/Data name. For example, a KiteAck named "/Alice/trace/photos" can only carry a PA named "/Alice/photos". In KITE's design, the prefix is determined by the name of trace Interest/Data (signed Interest from mobile producer and KiteAck), so the PA's name must represent the same prefix.

If the above makes sense, then one option is as follows:

  • Provide a new API for KiteAck verification (nfd::rib::RibManager::kiteAnnounce): kiteAnnounce is invoked for Data with KiteAck ContentType. The API first checks the name format (since so far only the ContentType is checked), then checks whether the PA specifies the right prefix, and finally invokes the nfd::rib::RibManager::slAnnounce API to check the PA and update RIB.

#10 Updated by Teng Liang 5 months ago

Since I didn't join the call, some description is not very clear to me. Here are my questions and comments:
1. Regarding KiteAck (just a Data packet), is PA appended to it as an NDNLPv2 field or is PA encapsulated as the content of KiteAck?
2. nfd::rib::RibManager::slAnnounce uses the localhop validator, which probably does not use the same validation policy as Kite, therefore you may need a different validator and have your own implementation in nfd::rib::RibManager::kiteAnnounce.
3. Where is this procedure executed, in a forwarding strategy or among forwarding pipelines?

#11 Updated by Junxiao Shi 5 months ago

There’s no need for a separate nfd::rib::RibManager::kiteAnnounce function. Just check the Data name - PA name relation before invoking nfd::rib::RibManager::slAnnounce.
There will be more validators, because NFD-Android cannot use localhop_security. Refer to 20190213 call for details.

#12 Updated by Zhongda Xia 5 months ago

Teng Liang wrote:

Since I didn't join the call, some description is not very clear to me. Here are my questions and comments:
1. Regarding KiteAck (just a Data packet), is PA appended to it as an NDNLPv2 field or is PA encapsulated as the content of KiteAck?
2. nfd::rib::RibManager::slAnnounce uses the localhop validator, which probably does not use the same validation policy as Kite, therefore you may need a different validator and have your own implementation in nfd::rib::RibManager::kiteAnnounce.
3. Where is this procedure executed, in a forwarding strategy or among forwarding pipelines?

Thanks for the comments! Responses below.

  1. Appended as NDNLPv2 field, like self-learning.
  2. Agree, KITE needs its own validator, cannot directly invoke slAnnounce for validating PA.
  3. The consensus was to integrate into forwarding pipelines. After receiving Data, and finding a match in PIT, enter KiteAck processing (parallel to normal processing like Data forwarding) if ContentType==KiteAck.

After some more thought, how about KiteAck not carrying PA? Arguments below.

  • A KiteAck that is signed by the RV is enough for verification purpose, and only the name and the signature is important. The name of the KiteAck determines the prefix, and hence how to verify the signature (which RV is in charge of this prefix). The content of KiteAck is not important.
  • In self-learning, PA can be saved and later attached to Data by forwarders, KITE requires no such operations (a forwarder does not propagate the route, KITE only updates the forwarders on the path between the MP and the RV), any piece of information carried in KiteAck does not need to be remembered or reused. In fact, since the MP sends a new trace Interest for each path update (the name will be different after signing), and considering that a KiteAck is essentially an acknowledgment from the RV for a specific trace Interest, an old KiteAck is irrelevant.

Without carrying PA, the KiteAck processing logic looks like this:

  1. check name format
  2. determine prefix
  3. validate KiteAck's signature (using the trust model for the prefix)
  4. update RIB

#13 Updated by Zhongda Xia 5 months ago

Junxiao Shi wrote:

There’s no need for a separate nfd::rib::RibManager::kiteAnnounce function. Just check the Data name - PA name relation before invoking nfd::rib::RibManager::slAnnounce.
There will be more validators, because NFD-Android cannot use localhop_security. Refer to 20190213 call for details.

This should work if KITE can have its own validator, and nfd::rib::RibManager::slAnnounce knows which validator to use for PA from KiteAck.

Also, what do you think of KiteAck not carrying PA, please refer to my response to Teng (#12). Thanks!

#14 Updated by Junxiao Shi 5 months ago

This should work if KITE can have its own validator

No, KITE does not need its own Validator. Within a single ValidatorConfig, one can construct filters to match only certain kinds of packets. If necessary, ValidatorConfig can be extended to have more filters.

how about KiteAck not carrying PA?

No. Every prefix registration needs to have a PA eventually, including those created by /localhost/nfd/rib/register command today. This PA would support readvertising into a different context.

Consider this topology:

R---S---E
    |   |
    P   C

R is KITE rendezvous server. P is the mobile producer. P uses KITE to establish a route for /P prefix from R to S to P.

Now C wants to use self-learning to find /P. When its discovery Interest reaches S, S should have a PA to attach to the response, and the PA should come from the KiteAck packet, not made up by S.

#15 Updated by Zhongda Xia 4 months ago

Junxiao Shi wrote:

The ContentType should be reserved on ContentType registry.
This in turn requires a specification of the exact encoding of the trace data.

Wiki pages updated, please check.

#16 Updated by Junxiao Shi 4 months ago

KiteAck rev6 says:

Carry a prefix announcement object in NDNLPv2 header, and the "announced prefix" indicated by the PA object must be the same as the name of the KiteAck minus the "32=KITE" component (excluding Interest signature related components).

This design is wrong. The prefix announcement object should be placed in the Data payload instead.

#17 Updated by Zhongda Xia 4 months ago

  • Status changed from New to In Progress

#18 Updated by Zhongda Xia 4 months ago

Junxiao Shi wrote:

KiteAck rev6 says:

Carry a prefix announcement object in NDNLPv2 header, and the "announced prefix" indicated by the PA object must be the same as the name of the KiteAck minus the "32=KITE" component (excluding Interest signature related components).

This design is wrong. The prefix announcement object should be placed in the Data payload instead.

I agree.

And just to make sure we are on the same page, I guess your point is that KiteAck is itself an independent piece of data generated upon request, and the PA object is an inherent part, thus should be put in the payload. Unlike the self-learning case, where the PA object is an extra piece of information piggybacked on the returned data object, thus has to be attached at link layer.

#19 Updated by Junxiao Shi 3 months ago

https://gerrit.named-data.net/5085 patchset9 has a KiteAck type, but I can't see clearly how this type is supposed to be used by mobile producer, forwarder, and rendezvous server. Can you give a short code snippet for each role?

#20 Updated by Zhongda Xia 2 months ago

Junxiao Shi wrote:

https://gerrit.named-data.net/5085 patchset9 has a KiteAck type, but I can't see clearly how this type is supposed to be used by mobile producer, forwarder, and rendezvous server. Can you give a short code snippet for each role?

Sure, first a quick recap. A KiteAck is generated by a rendezvous server (RV) in response to a valid trace Interest sent by a mobile producer (MP). The trace Interest is essentially a request to update forwarding information from an MP, which will reach the RV; and a KiteAck is a confirmation from the RV that the request is valid (proves the sender is the owner of the prefix in question), and forwarders may safely update forwarding information upon receiving such a confirmation (KiteAck).

We haven't knocked down the format (and proper name) of such a trace Interest, maybe we also need to do that? Anyway here is a brief explanation. A trace Interest (how about naming it "KiteRequest"?) is essentially a command Interest that follows KITE naming format, e.g., "/RV/trace/Alice/...". A trace Interest may also need to carry some auxilary information such as trace lifetime (how long the established forwarding information may live) as parameters, which may add one more parameter digest component in its name.

For the code snippets, first an API to create a trace Interest (todo, name may change), this API creates and signs a trace Interest:

Interest makeTraceInterest(Name rvPrefix, Name producerSuffix, KeyChain keychain, SigningInfo si)
// Interest name: /<rvPrefix>/32=KITE/<producerSuffix>/...

A mobile producer creates (includes signing) and sends a trace Interest for an owned prefix:

Name rvPrefix("/RV");
Name producerSuffix("/Alice"); // producer's prefix: /RV/Alice
Interest traceInterest = makeTraceInterest(rvPrefix, producerSuffix, keyChain, si);
// send Interest

A rendezvous server verifies the signature (and timestamp), then send KiteAck back after successful verification

Name producerPrefix = getProducerPrefix(traceInterest); // **todo:** provide a helper function, or define a trace Interest class

// verification code, check signature against the producer prefix

if (successful) { // the trace Interest passes the verification
  KiteAck kiteAck;
  PrefixAnnouncement pa;
  pa.setAnnouncedName(producerPrefix);
  kiteAck.setPrefixAnnouncement(pa);
  kiteAckData = kiteAck.makeData(traceInterest.getName(), keyChain, si); // create and sign (the PA is also signed here if not signed beforehand)
  // send Data
}

On each forwarder:

A trace Interest is processed ordinarily.

A KiteAck data is identified by ContentType, then processed after some sanity checks. The carried prefix announcement is extracted and passed to RIB manager to eventually update FIB.

forwarder::onIncomingData (data)
{
  // after PIT match is found

  if (data.getContentType() == tlv::ContentType_KiteAck) {
    // enter KiteAck pipeline
    onIncomingKiteAck(data, pitEntry);
  }

  // resume normal processing
}

forwarder::onIncomingKiteAck(Data data, shared_ptr<pit::Entry> pitEntry)
{
  KiteAck kiteAck(data); // throw if data is malformed, e.g., carries mismatching prefix announcement, wrong name format, etc., should be caught somehow
  // add incoming face of the corresponding trace Interest to next-hop list (there may be multiple incoming faces, not considered here)
  runOnRibIoService([pitEntryWeak = weak_ptr<pit::Entry>{pitEntry}, inFaceId = pitEntry->in_begin()->getFace().getId(), pa = *kiteAck.getPrefixAnnouncement()] {
    rib::Service::get().getRibManager().slAnnounce(pa, inFaceId, ROUTE_RENEW_LIFETIME,
      [] (RibManager::SlAnnounceResult res) {
        NFD_LOG_DEBUG("Add route via PrefixAnnouncement with result=" << res);
      });
  });

}

Note:

  • use RibManager::slAnnounce for updating RIB seems to be adquate for KITE's needs, the only concern is the verification, but I recall Junxiao mentioned this API can support different trust models, otherwise a separate API can be provided for KITE like "kiteAnnounce"

#21 Updated by Zhongda Xia about 2 months ago

Do you think adding a "ndn::kite" namespace makes sense? The helper functions (such as makeTraceInterest) are not all for KITE acknowledgment processing, not sure how to organize them now. Does introducing "ndn::kite" namespace break the current namespace allocation convention? Thanks!

#22 Updated by Davide Pesavento about 1 month ago

Personally I have no objections... but how many functions do you expect to add to this ndn::kite namespace? If it's just one or two, probably not worth it, you can put "Kite" in the function name.

#23 Updated by Zhongda Xia about 1 month ago

Only two for now, adding "Kite" should suffice.

#24 Updated by Zhongda Xia about 1 month ago

Following the latest comments on the code (https://gerrit.named-data.net/c/ndn-cxx/+/5085/12/ndn-cxx/kite-ack.hpp#41, https://gerrit.named-data.net/c/ndn-cxx/+/5085/12/ndn-cxx/kite-ack.cpp#41), it is probably helpful to define a KiteRequest class.

KiteRequest represents KITE requests, which are command Interests sent by mobile producers to the RV, previously named "trace Interests" in the KITE paper. The name should conform to KITE specifications, and KITE requests should also carry some extra information (currently just an expiration period, i.e., the lifetime of the forwarding path) as application parameters, which will only be checked by the RV application.

Currently, two APIs (makeKiteRequest, extractKitePrefixes) are provided to create (producer-side) and process (RV-side) KITE requests, providing a KiteRequest class instead looks like a cleaner design.

For the KiteRequest class, the design may follow that of PrefixAnnouncement, i.e., store the information (RV prefix, producer suffix, expiration period), and provide a "toInterest()" API for creating a signed command Interest.

Any feedback is welcome! If the design looks OK, I will go ahead and create the Wiki page for KITE requests, and implement the KiteRequest class.

#25 Updated by Davide Pesavento about 1 month ago

Zhongda Xia wrote:

I will go ahead and create the Wiki page for KITE requests

It's better to keep everything KITE-related on a single page, requests and ACKs are very closely related. I went ahead and created https://redmine.named-data.net/projects/ndn-tlv/wiki/KITE with the content of the previous KiteAck page. Please add a section describing KITE requests to the new page.

#26 Updated by Zhongda Xia about 1 month ago

Davide Pesavento wrote:

Zhongda Xia wrote:

I will go ahead and create the Wiki page for KITE requests

It's better to keep everything KITE-related on a single page, requests and ACKs are very closely related. I went ahead and created https://redmine.named-data.net/projects/ndn-tlv/wiki/KITE with the content of the previous KiteAck page. Please add a section describing KITE requests to the new page.

Sure, thanks!

#28 Updated by Davide Pesavento 22 days ago

Please add examples of KiteRequest and KiteAck to the wiki page, i.e. what the name and packet format look like.

#29 Updated by Davide Pesavento 22 days ago

Why isn't the MP sending a PrefixAnnouncement in its KiteRequest? (apologies if you already answered this question, but I can't find the rationale on this issue)

#30 Updated by Zhongda Xia 22 days ago

Davide Pesavento wrote:

Why isn't the MP sending a PrefixAnnouncement in its KiteRequest? (apologies if you already answered this question, but I can't find the rationale on this issue)

No problem at all. Short answer, the forwarders trust RVs instead of individual MPs, so the PrefixAnnouncement must be generated by the RV and therefore put in KiteAck.

Alternatively, forwarders may verify KiteRequests directly (which is actually the design in the first version of KITE), without relying on RVs (which process KiteRequests), but this requires all forwarders to learn how to trust each MP, which is hard to scale (intuitively at least). So in the current KITE design, RVs verify KiteRequests, and forwarders trust RVs to do their job properly; forwarders only need to keep track of RVs credentials to verify KiteAcks.

#31 Updated by Davide Pesavento 22 days ago

Yeah I understand that. I was not suggesting that the same PA from the producer is directly put into the KiteAck and sent downstream... the RV still does its job and signs a new PA and sends that one downstream. My question was only about whether it makes sense to reuse the PA format/encoding in the KiteRequest message, probably attached as ApplicationParameters. I guess one downside of this is that the PA (which is essentially a Data packet) and the signed KiteRequest Interest contain a lot of duplicated stuff.

#32 Updated by Davide Pesavento 22 days ago

Another question: how does the producer app (or a library on its behalf) know when to issue a KiteRequest?

#33 Updated by Zhongda Xia 22 days ago

Davide Pesavento wrote:

Yeah I understand that. I was not suggesting that the same PA from the producer is directly put into the KiteAck and sent downstream... the RV still does its job and signs a new PA and sends that one downstream. My question was only about whether it makes sense to reuse the PA format/encoding in the KiteRequest message, probably attached as ApplicationParameters. I guess one downside of this is that the PA (which is essentially a Data packet) and the signed KiteRequest Interest contain a lot of duplicated stuff.

Sorry I missed your point there...

Actually, KiteAck carries PA to reuse self-learning's code for updating RIB, your suggestion never arose before... but fair point indeed.

Now that I think about it, if we reuse PA code for verifying KiteRequests, the name can be simply "/RV/32=KITE/", the "KITE" keyword just serves to terminate longest prefix matching, and the nonce is for deduplicating. Anyhow, the name does not need to carry any information other than for guiding KiteRequests to the RV.

And I suppose by duplicated stuff, you mean like the PA carries a producer prefix, and the Interest name includes the same information right? If the design is changed according to the above, then this is solved, or else we are reusing code at the cost of duplicated information.

The design choice is whether to exploit names to carry extra information, I've thought about this when revisiting the KITE design lately, and there have also been suggestions against overloading names. But I really wish to push for an implementation according to the published paper first, and avoid design choice discussion for now (the naming part is actually a big part in the paper).

We are working on revising the KITE protocol (internally for now), and how about we implement the current design first, then revise it in the future after we have a more systematic revision plan? As I mentioned, carrying a PA in a KiteAck was for reusing existing NFD code for updating RIB only, not to touch the overall design.

#34 Updated by Zhongda Xia 22 days ago

Davide Pesavento wrote:

Another question: how does the producer app (or a library on its behalf) know when to issue a KiteRequest?

I (kind of vaguely) recall Junxiao mentioned using NFD's readvertising mechanisms, essentially a producer delegates the job to the local NFD. But I haven't looked into the readvertising implementation yet, to see how issuing KiteRequests (and probably also processing KiteAcks for confirmation) may be integrated. And I am not currently aware of how NFD decides when to readvertise a prefix...

#35 Updated by Zhongda Xia 22 days ago

Davide Pesavento wrote:

Please add examples of KiteRequest and KiteAck to the wiki page, i.e. what the name and packet format look like.

Sure. Added KITE request name example. The packet format seems simple enough.

#36 Updated by Davide Pesavento 22 days ago

Zhongda Xia wrote:

Now that I think about it, if we reuse PA code for verifying KiteRequests, the name can be simply "/RV/32=KITE/", the "KITE" keyword just serves to terminate longest prefix matching, and the nonce is for deduplicating. Anyhow, the name does not need to carry any information other than for guiding KiteRequests to the RV.

The name will also contain a ParametersSha256Digest, because the PA is carried in ApplicationParameters, and that should make the Interest name unique enough.

And I suppose by duplicated stuff, you mean like the PA carries a producer prefix, and the Interest name includes the same information right? If the design is changed according to the above, then this is solved, or else we are reusing code at the cost of duplicated information.

Yes, that's true.
All the signature-related fields are somewhat duplicated too. There is the Data signature of the PA and the Interest signature of the KiteRequest. I'm not sure about the security implications of using a plain (non-signed) Interest for a KiteRequest, I'm afraid that would open the door to all kinds of replay attacks and forgeries (anyone with a valid PA obtained from elsewhere can send a KiteRequest pretending to be the producer).

We are working on revising the KITE protocol (internally for now), and how about we implement the current design first, then revise it in the future after we have a more systematic revision plan? As I mentioned, carrying a PA in a KiteAck was for reusing existing NFD code for updating RIB only, not to touch the overall design.

Sure, that works for me.

#37 Updated by Davide Pesavento 22 days ago

Zhongda Xia wrote:

I (kind of vaguely) recall Junxiao mentioned using NFD's readvertising mechanisms, essentially a producer delegates the job to the local NFD. But I haven't looked into the readvertising implementation yet, to see how issuing KiteRequests (and probably also processing KiteAcks for confirmation) may be integrated. And I am not currently aware of how NFD decides when to readvertise a prefix...

Ok, let's revisit this later then.

#38 Updated by Zhongda Xia 21 days ago

Davide Pesavento wrote:

Zhongda Xia wrote:

Now that I think about it, if we reuse PA code for verifying KiteRequests, the name can be simply "/RV/32=KITE/", the "KITE" keyword just serves to terminate longest prefix matching, and the nonce is for deduplicating. Anyhow, the name does not need to carry any information other than for guiding KiteRequests to the RV.

The name will also contain a ParametersSha256Digest, because the PA is carried in ApplicationParameters, and that should make the Interest name unique enough.

And I suppose by duplicated stuff, you mean like the PA carries a producer prefix, and the Interest name includes the same information right? If the design is changed according to the above, then this is solved, or else we are reusing code at the cost of duplicated information.

Yes, that's true.
All the signature-related fields are somewhat duplicated too. There is the Data signature of the PA and the Interest signature of the KiteRequest. I'm not sure about the security implications of using a plain (non-signed) Interest for a KiteRequest, I'm afraid that would open the door to all kinds of replay attacks and forgeries (anyone with a valid PA obtained from elsewhere can send a KiteRequest pretending to be the producer).

Exactly, attackers may replay PAs easily (at least within the PA's ValidiyPeriod). There is a similar issue with KiteAck carrying PA, a forwarder should probabaly check the KiteAck's Data signature first before passing the encoded PA to RIB manager, where the PA's signature will be checked. The rationale is that it may not be safe to assume that only an RV may receive KiteRequests under its announced RV prefix, e.g., an attacker may hijack the RV prefix.

We are working on revising the KITE protocol (internally for now), and how about we implement the current design first, then revise it in the future after we have a more systematic revision plan? As I mentioned, carrying a PA in a KiteAck was for reusing existing NFD code for updating RIB only, not to touch the overall design.

Sure, that works for me.

#39 Updated by Junxiao Shi 15 days ago

In https://gerrit.named-data.net/5085 patchset15, I have usability concern over KiteRequest type:

  1. When KiteRequest::toInterest is invoked, the type internally caches a signed Interest.
  2. The only way to clear the cached signed Interest is to change one of RV prefix, producer prefix, relative expiration time.
  3. A common use case from a mobile producer is resending KITE requests periodically.
  4. In order for KITE rendezvous server to accept a subsequent KITE request, the signed Interest must have a newer timestamp.
  5. It's impossible to create a new signed Interest without changing one of RV prefix, producer prefix, relative expiration time.

To solve this problem, KiteRequest::toInterest should create a new signed Interest every time it is invoked, and never cache the signed Interest.


It's necessary to have some facility to periodically resend KITE requests. They should belong to this Feature, but come in a separate commit given the complexity.


In https://gerrit.named-data.net/5085 patchset15, four files kite-request.hpp kite-request.cpp kite-ack.hpp kite-ack.cpp are added to the top level directory.
Given we still need "facility to periodically resend KITE requests", I'd suggest moving everything into ndn-cxx/kite subdirectory and ndn::kite namespace, and drop kite- file name prefix and Kite type prefix.
Additions to encoding/tlv.hpp can stay there.

#40 Updated by Davide Pesavento 15 days ago

Junxiao Shi wrote:

In https://gerrit.named-data.net/5085 patchset15, I have usability concern over KiteRequest type:

  1. When KiteRequest::toInterest is invoked, the type internally caches a signed Interest.
  2. The only way to clear the cached signed Interest is to change one of RV prefix, producer prefix, relative expiration time.
  3. A common use case from a mobile producer is resending KITE requests periodically.
  4. In order for KITE rendezvous server to accept a subsequent KITE request, the signed Interest must have a newer timestamp.
  5. It's impossible to create a new signed Interest without changing one of RV prefix, producer prefix, relative expiration time.

Or construct a new KiteRequest instance. That's the idea I think. One KiteRequest represents one request, as the name says, therefore one Interest.

To solve this problem, KiteRequest::toInterest should create a new signed Interest every time it is invoked, and never cache the signed Interest.

I would also be fine with this design, and in fact I suggested this alternative some time ago on gerrit. The naming should change though, make it clear that it's more like a request builder than a single request... I suggest makeInterest().

It's necessary to have some facility to periodically resend KITE requests. They should belong to this Feature, but come in a separate commit given the complexity.

What complexity? Isn't it something like:

{
  ...
  // executed at startup, e.g., Producer constructor
  m_scheduler.schedule(m_kiteInterval, [this] { kiteLoop(); });
  ...
}

void
Producer::kiteLoop()
{
  auto interest = m_kiteReq.makeInterest(m_keychain);
  m_face.expressInterest(interest, ...);

  m_scheduler.schedule(m_kiteInterval, [this] { kiteLoop(); });
}

#41 Updated by Zhongda Xia 15 days ago

Thanks for the input!

Davide Pesavento wrote:

Junxiao Shi wrote:

In https://gerrit.named-data.net/5085 patchset15, I have usability concern over KiteRequest type:

  1. When KiteRequest::toInterest is invoked, the type internally caches a signed Interest.
  2. The only way to clear the cached signed Interest is to change one of RV prefix, producer prefix, relative expiration time.
  3. A common use case from a mobile producer is resending KITE requests periodically.
  4. In order for KITE rendezvous server to accept a subsequent KITE request, the signed Interest must have a newer timestamp.
  5. It's impossible to create a new signed Interest without changing one of RV prefix, producer prefix, relative expiration time.

Or construct a new KiteRequest instance. That's the idea I think. One KiteRequest represents one request, as the name says, therefore one Interest.

KiteRequest and KiteAck can be seen as collections of APIs for KITE request/acknowledgment processing, not a representation of a specific KITE request/acknowledgment (as currently noted in the code). In this sense, Junxiao's suggestion makes sense. But I'm not sure whether such a definition means that the class name needs to change.

Also, it's worth noting that not all the information a KITE request carries is currently stored in a KiteRequest object (not considering the cached signed Interest), e.g., the signature, the timestamp, these information is determined in toInterest(), and stored implicitly in the name of the cached signed Interest. So I guess a KiteRequest does represent a KITE request after toInterest() is invoked, and the cached Interest is an inherent part of a KiteRequest.

I'm a little lost actually, but anyway above is my current understanding...

To solve this problem, KiteRequest::toInterest should create a new signed Interest every time it is invoked, and never cache the signed Interest.

I would also be fine with this design, and in fact I suggested this alternative some time ago on gerrit. The naming should change though, make it clear that it's more like a request builder than a single request... I suggest makeInterest().

Refer to my reply above.

It's necessary to have some facility to periodically resend KITE requests. They should belong to this Feature, but come in a separate commit given the complexity.

What complexity? Isn't it something like:

{
  ...
  // executed at startup, e.g., Producer constructor
  m_scheduler.schedule(m_kiteInterval, [this] { kiteLoop(); });
  ...
}

void
Producer::kiteLoop()
{
  auto interest = m_kiteReq.makeInterest(m_keychain);
  m_face.expressInterest(interest, ...);

  m_scheduler.schedule(m_kiteInterval, [this] { kiteLoop(); });
}

This is also my first thought... Junxiao, are you refering to how to determine the interval?

#42 Updated by Zhongda Xia 15 days ago

Junxiao Shi wrote:

In https://gerrit.named-data.net/5085 patchset15, four files kite-request.hpp kite-request.cpp kite-ack.hpp kite-ack.cpp are added to the top level directory.
Given we still need "facility to periodically resend KITE requests", I'd suggest moving everything into ndn-cxx/kite subdirectory and ndn::kite namespace, and drop kite- file name prefix and Kite type prefix.
Additions to encoding/tlv.hpp can stay there.

I have no objections, there will very likely be more such facilities, given the mobile producer and RV needs to do a lot of things (working on the details now, what exactly is needed to get KITE up and running in practice?).

#43 Updated by Davide Pesavento 15 days ago

I assume the RV code will be in a separate repo? or as a tool in ndn-tools repo?

#44 Updated by Junxiao Shi 15 days ago

To solve this problem, KiteRequest::toInterest should create a new signed Interest every time it is invoked, and never cache the signed Interest.

I would also be fine with this design, and in fact I suggested this alternative some time ago on gerrit. The naming should change though, make it clear that it's more like a request builder than a single request... I suggest makeInterest().

Yes, the function should be renamed makeInterest. It doesn't make sense to cache a signed Interest, because it must be sent immediately or the timestamp expires very soon. Constructing a new KiteRequest instance hinders usability, because the caller would have to set RV prefix, producer prefix, and expiration time repeatedly.


It's necessary to have some facility to periodically resend KITE requests. They should belong to this Feature, but come in a separate commit given the complexity.

What complexity? Isn't it something like:

The complexity includes but is not limited to:

  • Configuration object.
  • Error handling.
  • Signals.
  • Response validation.
  • To prevent traffic synchronization, interval should be randomized around a target duration instead of using a fixed duration.

I assume the RV code will be in a separate repo? or as a tool in ndn-tools repo?

I suggest putting RV in ndn-tools. Its complexity does not warrant a separate repository, which would increase workload in CI setup (especially TravisCI script updates) and can easily fall behind in maintenance.

#45 Updated by Zhongda Xia 15 days ago

Junxiao Shi wrote:

I assume the RV code will be in a separate repo? or as a tool in ndn-tools repo?

I suggest putting RV in ndn-tools. Its complexity does not warrant a separate repository, which would increase workload in CI setup (especially TravisCI script updates) and can easily fall behind in maintenance.

I agree. In #42, I mean the RV probably needs some functionalities worth providing in ndn-cxx.

#46 Updated by Zhongda Xia 15 days ago

Junxiao Shi wrote:

The complexity includes but is not limited to:

  • Configuration object.
  • Error handling.
  • Signals.
  • Response validation.
  • To prevent traffic synchronization, interval should be randomized around a target duration instead of using a fixed duration.

Could you explain traffic synchronization? Any references? Thanks.

#47 Updated by Zhongda Xia 15 days ago

For change #5085, I will make the following revisions, please check if they are proper:

  1. move KITE-related code to ndn-cxx/kite subdirectory and ndn::kite namespace, and remove the Kite prefix.
  2. rename kite::Request::toInterest to makeInterest
  3. kite::Request::makeInterest always creates a new signed Interest, will not cache Interest.
  4. revise the doxygen comments for the class kite::Request, to clarify that it does not "represent" a KITE request, per se, but is rather a facility for generating and parsing KITE requests, and that a mobile producer may reuse the same kite::Request instance to generate KITE requests for the same producer prefix (the expiration period may change though).

Question: when decoding a KITE request with the constructor kite::Request::Request(interest), should we store the Interest?

Forwarders decode KITE request to determine the prefixes, and RVs decode KITE requests to verify them, and to generate KITE acknowledgment, in both use cases, the invoker has access to the original signed Interest, so storing the Interest should be unnecessary.

#48 Updated by Zhongda Xia 4 days ago

Change 5085 has been rebased on 5457, to properly process Interests with ApplicationParameters set (specifically, the expiration period).

The name of a KITE request currently follows command Interest specifications (timestamp is fourth from the last, and nonce third from the last), and if ApplicationParameters are set, the encoding process makes sure that the digest is fifth from the last (before the timestamp), to not mess with the command Interest naming convention.

But I haven't found a standard way to verify command Interests, is there such an API that KITE may directly use (an RV needs to verify KITE requests)? Or should we proivde one specifically for verifying KITE requests?

I went ahead and added two methods to kite::Request: getTimestamp(), and getNonce(). They are meant to facilitate verifying KITE requests. When a kite::Request is constructed from an Interest packets, the timestamp and nonce are extracted from the name and stored, and returned through the new methods. There are no setXXX() methods for timestamp and nonce since they are added at generation time in kite::Request::makeInterest.

#49 Updated by Junxiao Shi 4 days ago

The name of a KITE request currently follows command Interest specifications

Command_Interests has been deprecated in favor of Signed Interest in packet format v0.3 (#4599), as noted on top of that page. Do not use Command Interest for any new development. Redefine your protocol to use Signed Interest instead. Implementation is blocked by #4804.

#50 Updated by Zhongda Xia 1 day ago

  • Parent task set to #4804

#51 Updated by Zhongda Xia 1 day ago

  • Parent task deleted (#4804)

#52 Updated by Zhongda Xia 1 day ago

#53 Updated by Zhongda Xia 1 day ago

Junxiao Shi wrote:

The name of a KITE request currently follows command Interest specifications

Command_Interests has been deprecated in favor of Signed Interest in packet format v0.3 (#4599), as noted on top of that page. Do not use Command Interest for any new development. Redefine your protocol to use Signed Interest instead. Implementation is blocked by #4804.

Sure, thanks for the information. Issue updated.

Also available in: Atom PDF