Skip to content

Instantly share code, notes, and snippets.

@yoursunny
Created October 8, 2016 23:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yoursunny/bcee67893134d7d49c0868f5a8b9ed41 to your computer and use it in GitHub Desktop.
Save yoursunny/bcee67893134d7d49c0868f5a8b9ed41 to your computer and use it in GitHub Desktop.
// NFD-RIB readvertise feature
// https://redmine.named-data.net/issues/3784
/** \brief reference to a RIB route
*/
struct RibRouteRef
{
shared_ptr<RibEntry> entry;
RibEntry::const_iterator route;
};
// Rib::const_iterator dereferences to a RIB entry rather than a route.
// This type allows referencing a route.
class Rib
{
public:
Signal<Rib, RibRouteRef> afterAddRoute;
Signal<Rib, RibRouteRef> beforeRemoveRoute;
// Those signals differ from existing afterInsertEntry and afterEraseEntry signals.
// They are triggerred per route instead of per RIB entry (i.e. a collection of routes
// with same name prefix).
};
/** \brief a readvertised route
*/
class ReadvertisedRoute
{
public:
/** \return name prefix being readvertised
*/
const Name&
getPrefix() const;
/** \return signer
*/
const SigningInfo&
getSigner() const;
/** \return routes that caused the creation of this readvertised route
*/
std::vector<RibRouteRef>&
getRibRoutes();
// This type also contains fields for state and timers, used by Readvertise class.
};
bool
operator<(const ReadvertisedRoute&, const ReadvertisedRoute&);
// This operator compares route.getPrefix() only.
/** \brief a destination to readvertise into
*/
class ReadvertiseDestination
{
public:
virtual void
advertise(ReadvertisedRoute& rr, std::function<void()> successCb, std::function<void(const std::string&)> failureCb) = 0;
virtual void
withdraw(ReadvertisedRoute& rr, std::function<void()> successCb, std::function<void(const std::string&)> failureCb) = 0;
};
/** \brief a readvertise destination using NFD RIB Management protocol
*/
class NfdRibReadvertiseDestination : public ReadvertiseDestination
{
public:
NfdRibReadvertiseDestination(Controller& controller, KeyChain& keyChain,
const Name& commandPrefix);
// advertise: call RibRegisterCommand
// withdraw: call RibUnregisterCommand
};
/** \brief a decision made by readvertise policy
*/
struct ReadvertiseAction
{
Name prefix;
SigningInfo signer;
};
/** \brief a policy to decide whether to readvertise a route, and what prefix to readvertise
*/
class ReadvertisePolicy
{
public:
virtual optional<ReadvertiseAction>
handleNewRoute(const RibRouteRef& route) const = 0;
virtual time::nanoseconds
getRefreshInterval() const = 0;
};
/** \brief a policy to readvertise a route registered by an end host into NLSR
*/
class ClientToNlsrReadvertisePolicy : public ReadvertisePolicy
{
public:
ClientToNlsrReadvertisePolicy();
// handleNewRoute: return {same-name, default-signer} if route origin is client,
// otherwise nullopt
// getRefreshInterval: a reasonable value for local refresh
};
/** \brief a policy to propagate a prefix registered by a local app onto a remote router
*/
class PrefixPropagationReadvertisePolicy : public ReadvertisePolicy
{
public:
PrefixPropagationReadvertisePolicy(KeyChain& keyChain);
// handleNewRoute: return {shortest-identity, matched-identity} if identity exists,
// otherwise nullopt
// getRefreshInterval: a reasonable value for remote refresh
};
class Readvertise
{
public:
Readvertise(Rib& rib, unique_ptr<ReadvertisePolicy> policy,
unique_ptr<ReadvertiseDestination> destination);
// Each Readvertise instance supports readvertising a subset of routes
// to one destination according to a policy. If multiple destinations are needed,
// multiple Readvertise instances should be created.
// Unlike AutoPrefixPropagator, there's no enable/disable methods; to disable
// readvertising, simply don't create the Readvertise instance.
private:
void
afterAddRoute(const RibRouteRef& routeRef);
// 1. Invoke policy.handleNewRoute.
// 2. If policy decides not to readvertise, abort these steps.
// 3. Insert a ReadvertisedRoute into the table.
// 4. If destination is available, invoke destination.advertise.
void
beforeRemoveRoute(const RibRouteRef& routeRef);
// 1. Find existing ReadvertisedRoute that were created from this route.
// 2. Delete the RibRouteRef in the ReadvertisedRoute.
// 3. If the ReadvertisedRoute still contains other RibRouteRefs, abort these steps.
// 4. If destination is available, invoke destination.withdraw.
// 5. Delete the ReadvertisedRoute.
void
afterDestinationAvailable();
// 1. For each ReadvertisedRoute, call destination.advertise.
void
afterDestinationUnavailable();
// 1. Cancel retry timers.
// If a command fails, retry with exponential back-off.
// After an advertise command succeeds, repeat the command every policy.getRefreshInterval().
// Each command should be delayed by a small random duration,
// to avoid too many commands being sent at the same time;
// this delay should be added to initial, retry, and repeat commands alike.
private:
// The data structures should support:
// 1. Find/insert/delete ReadvertisedRoute by name prefix.
// 2. Find ReadvertisedRoute by RibRouteRef.
// 3. Enumerate all ReadvertisedRoutes.
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment