servlib/routing/RouteEntry.h
changeset 0 2b3e5ec03512
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlib/routing/RouteEntry.h	Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,230 @@
+/*
+ *    Copyright 2006 Intel Corporation
+ * 
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ * 
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef _BUNDLE_ROUTEENTRY_H_
+#define _BUNDLE_ROUTEENTRY_H_
+
+#include <oasys/debug/Formatter.h>
+#include <oasys/serialize/Serialize.h>
+#include <oasys/util/StringUtils.h>
+
+#include "bundling/CustodyTimer.h"
+#include "bundling/ForwardingInfo.h"
+#include "naming/EndpointID.h"
+#include "contacts/Link.h"
+
+namespace dtn {
+
+class RouteEntryInfo;
+
+/**
+ * Class to represent route table entry.
+ *
+ * Each entry contains an endpoint id pattern that is matched against
+ * the destination address in the various bundles to determine if the
+ * route entry should be used for the bundle.
+ *
+ * An entry also has a forwarding action type code which indicates
+ * whether the bundle should be forwarded to this next hop and others
+ * (ForwardingInfo::COPY_ACTION) or sent only to the given next hop
+ * (ForwardingInfo::FORWARD_ACTION). The entry also stores the custody
+ * transfer timeout parameters, unique for a given route.
+ *
+ * There is also a pointer to either an interface or a link for each
+ * entry. In case the entry contains a link, then that link will be
+ * used to send the bundle. If there is no link, there must be an
+ * interface. In that case, bundles which match the entry will cause
+ * the router to create a new link to the given endpoint whenever a
+ * bundle arrives that matches the route entry. This new link is then
+ * typically added to the route table.
+ */
+class RouteEntry : public oasys::Formatter,
+                   public oasys::SerializableObject {
+public:
+    /// Share the ForwardingInfo::action_t type
+    typedef ForwardingInfo::action_t action_t;
+
+    /// Functor classes used to match route entries (defined below)
+    class DestMatches;
+    class NextHopMatches;
+
+    /**
+     * First constructor requires a destination pattern and a next hop link.
+     */
+    RouteEntry(const EndpointIDPattern& dest_pattern, const LinkRef& link);
+
+    /**
+     * Alternate constructor requires a destination pattern and a
+     * route destination endpoint id.
+     */
+    RouteEntry(const EndpointIDPattern& dest_pattern,
+               const EndpointIDPattern& route_to);
+
+    /**
+     * Destructor.
+     */
+    ~RouteEntry();
+
+    /**
+     * Hook to parse route configuration options.
+     */
+    int parse_options(int argc, const char** argv,
+                      const char** invalidp = NULL);
+
+    /**
+     * Virtual from formatter.
+     */
+    int format(char* buf, size_t sz) const;
+     
+    /**
+     * Dump a header string in preparation for subsequent calls to dump();
+     */
+    static void dump_header(oasys::StringBuffer* buf,
+                            int dest_eid_width,
+                            int source_eid_width,
+                            int next_hop_width);
+    
+    /**
+     * Dump a string representation of the route entry. Any endpoint
+     * ids or link names that don't fit into the column width get put
+     * into the long_strings vector.
+     */
+    void dump(oasys::StringBuffer* buf,
+              oasys::StringVector* long_strings,
+              int dest_eid_width,
+              int source_eid_width,
+              int next_hop_width) const;
+
+    /**
+     * Virtual from SerializableObject
+     */
+    virtual void serialize( oasys::SerializeAction *a );
+
+    /// @{ Accessors
+    const EndpointIDPattern& dest_pattern()   const { return dest_pattern_; }
+    const EndpointIDPattern& source_pattern() const { return source_pattern_; }
+    const LinkRef&           link()           const { return link_; }
+    const EndpointIDPattern& route_to()       const { return route_to_; }
+    u_int                    priority()       const { return priority_; }
+    RouteEntryInfo*          info()           const { return info_; }
+    const CustodyTimerSpec&  custody_spec()   const { return custody_spec_; }
+
+    action_t action() const { return static_cast<action_t>(action_); }
+
+    const std::string& next_hop_str() const {
+        return (link() != NULL) ? link()->name_str() : route_to().str();
+    }
+    /// @}
+
+    /// @{ Setters
+    void set_action(action_t action)    { action_ = action; }
+    void set_info(RouteEntryInfo* info) { info_   = info; }
+    /// @}
+    
+private:
+    /// Helper for dump()
+    static void append_long_string(oasys::StringBuffer* buf,
+                                   oasys::StringVector* long_strings,
+                                   int width, const std::string& str);
+
+    
+    /// The pattern that matches bundles' destination eid
+    EndpointIDPattern dest_pattern_;
+
+    /// The pattern that matches bundles' source eid
+    EndpointIDPattern source_pattern_;
+    
+    /// Bit vector of the bundle priority classes that should match this route
+    u_int bundle_cos_;
+    
+    /// Route priority
+    u_int priority_;
+
+    /// Next hop link if known
+    LinkRef link_;
+        
+    /// Route destination for recursive lookups
+    EndpointIDPattern route_to_;
+        
+    /// Forwarding action code 
+    u_int32_t action_;
+
+    /// Custody timer specification
+    CustodyTimerSpec custody_spec_;
+
+    /// Abstract pointer to any algorithm-specific state that needs to
+    /// be stored in the route entry
+    RouteEntryInfo* info_;        
+    
+    // XXX/demmer confidence? latency? capacity?
+    // XXX/demmer bit to distinguish
+    // XXX/demmer make this serializable?
+};
+
+/**
+ * Predicate to match the destination pattern for a route.
+ */
+class RouteEntry::DestMatches {
+public:
+    DestMatches(const EndpointIDPattern& dest) : dest_(dest) {}
+    bool operator()(RouteEntry* entry) {
+        return dest_.equals(entry->dest_pattern());
+    }
+    EndpointIDPattern dest_;
+};
+
+/**
+ * Predicate to match the destination pattern for a route.
+ */
+class RouteEntry::NextHopMatches {
+public:
+    NextHopMatches(const LinkRef& link) : link_(link) {}
+    bool operator()(RouteEntry* entry) {
+        return link_ == entry->link();
+    }
+    LinkRef link_;
+};
+
+/**
+ * Interface for any per-entry routing algorithm state.
+ */
+class RouteEntryInfo {
+public:
+    virtual ~RouteEntryInfo() {}
+};
+
+/**
+ * Class for a vector of route entries. Used for the route table
+ * itself and for what is returned in get_matching().
+ */
+class RouteEntryVec : public std::vector<RouteEntry*> {};
+
+/**
+ * Functor class to sort a vector of routes based on forwarding
+ * priority, using the bytes queued on the link to break ties.
+ */
+struct RoutePrioritySort {
+    bool operator() (RouteEntry* a, RouteEntry* b) {
+        if (a->priority() < b->priority()) return false;
+        if (a->priority() > b->priority()) return true;
+        return (a->link()->bytes_queued() <
+                b->link()->bytes_queued());
+    }
+};
+
+} // namespace dtn
+
+#endif /* _BUNDLE_ROUTEENTRY_H_ */