Approved for Public Release; Distribution Unlimited. Case Number: 06-1215
Copyright © 2006 The MITRE Corporation. All rights reserved.
Revision History | |
---|---|
Revision 0.90 | 11.13.06 |
Table of Contents
A new implementation architecture is under development that promises to ease the task of adding new capabilities to DTN. Using generic external interfaces, third-party developers will be able to implement plug-in modules without having to rewrite or understand the internal workings of the DTN2 reference implementation (RI). Plug-in modules are stand-alone processes designed to work in collaboration with DTN. In the longer term, this effort provides the basis for extending commercial off-the-shelf (COTS) DTN implementations with domain specific capabilities.
The External Router Interface, documented here, is the first DTN external interface designed to move bundle forwarding decisions to an external process or processes. Benefits of this interface include:
Classified and proprietary bundle routing algorithms are protected.
External routers may be written in any programming language (XML based interface).
Prototyping of new bundle routing algorithms is streamlined.
Routing algorithms may be added and removed at runtime.
This guide is directed at external router developers and to those interested in an early product of the new DTN implementation architecture. "Interface Operation" describes interface fundamentals such as underlying protocols and message structure. "Protocol Elements" introduces the set of router interface messages used for inter-process communication. Appendix A summarizes new configuration options introduced with the DTN2 RI external router interface implementation. Appendix B is an interface design FAQ of sorts that attempts to address questions that often arise when first learning about the interface.
Please note that the external router interface is still evolving and will likely be modified as experience is gained externalizing DTN bundle routers. Future work on other interfaces, including convergence-layer and storage interfaces, may also impact the interface. The latest "bleeding edge" version of the DTN2 RI includes support for the external router interface documented here and is available at www.dtnrg.org.
Before diving into the details, this section discusses the overall design and operation of the router interface. When compiled, the DTN2 RI 2.2.0 release (the latest formal DTN2 release as of this writing) produces one multi-threaded executable, a DTN daemon. This daemon is a complete DTN node; it accepts bundles from a number of built-in convergence layers, provides persistent bundle storage, delivers bundles to local DTN applications, selects routes using built-in routing logic, and forwards bundles to peer DTN nodes. For the purposes of this document, a forwarder is a DTN daemon as described above, but one that depends on external routing processes to make bundle routing decisions on its behalf.
The forwarder communicates with external routing processes:
with an XML-based messaging protocol
using a well-known IPv4 multicast address and UDP port
on local or remote hosts
Before forwarders and external routers can communicate, they each must join the all-routers multicast group (224.0.0.2) and bind to a well-known UDP port. Forwarders are not aware if zero, one, or more external routers have joined the multicast group. It is the responsibility of the system administrator to ensure router availability.
Nothing in the interface design precludes running forwarders and external routers on different hosts, however this approach is not recommended especially in wireless and/or bandwidth-constrained environments. The interface is fairly chatty, UDP is unreliable, and there is a high risk of packet loss leading to a breakdown in synchronized state. (The DTN2 RI external router interface is hard coded to use the loopback interface and therefore requires forwarders and external routers to reside on the same host.)
Inter-process messages are XML-based and must be valid against the external router XML schema. Interface messages are broadly divided into four categories. Event messages are issued by forwarders to indicate state changes that may be of interest to external routers. Request messages are sent by external routers to direct forwarders to perform an action (e.g. "forward the bundle with ID 56 out link tcp0"). Query and report messages are used by external routers to synchronize their state with forwarders after bootup or during failure recovery. The proper usage and interpretation of each interface message is covered in the next section.
How does the forwarder authenticate external processes? It doesn't. The forwarder makes the assumption that (local or remote) external routers are within the same security domain. In addition, system administrators must ensure there exists one authoritative router or policy module per DTN "node”, or that multiple external routers are configured in a cooperative manner to correctly handle all events.
In addition to external routers, other "read-only" types of processes may join the all-routers multicast group. An external logging application, for example, could be written to display the current state of the forwarder simply by listening to external router interface messages. However, this concept is not pursued further in this document. The following discussion is limited to inter-process communication between forwarders and external routers.
This section describes each interface message according to purpose. Hyper-links to generated schema documentation are located throughout the text. To generate the documentation, cd to the top level directory of DTN2 source code and type make xsddoc. You will need xsddoc-1.0 and java installed for this to work.
When a forwarder is configured for external routing, it periodically multicasts hello messages to announce its presence to external routers. Each hello message includes the EID of the sender and the interval in seconds between each message. For example, the message
<dtn eid="dtn://nodeX"
hello_interval="30"/>
notifies external routers that the DTN forwarder with EID dtn://nodeX is running and will send another hello message in 30 seconds. Router implementations may filter incoming messages by EID if it becomes necessary to run more than one forwarder on a single platform.
After routers receive one or more hello messages from any (or a specific) DTN node, they must synchronize their state with the forwarder. Several routing interface messages are designed to facilitate state synchronization and have a common format. If x represents meta-information of interest, the message x_query prompts the forwarder to send an x_report message. For example, a bundle_query message asks the forwarder to generate and send a bundle_report message.
Routers may query the forwarder for four types of meta-information. contact_report includes meta-information on all open connections between the local forwarder and remote forwarders. Low-level convergence layer meta-information is also included for each contact. link_report contains meta information on all forwarder links regardless of the current state. route_report is composed of meta-information on all static routes configured on the DTN console (if any). bundle_report lists meta-information on each bundle stored by the local forwarder.
After synchronizing their state with a forwarder, external routers process incoming events as they arrive and send requests when necessary.
DTN links represent a one way communication channel to next hop
DTN nodes. Links are either explicitly created in the forwarder
configuration file (dtn.conf
) or spring into
existence as a result of the neighbor discovery mechanism. Four types of
links exist: always on, on
demand, scheduled, and
opportunistic. link_created_event
messages announce the existence of new links and include such attributes
as name, type, and destination EID along with other meta-information.
link_deleted_event
notifies external routers that a named link has been destroyed. link_available_event
and link_unavailable_event
messages are automatically generated by the forwarder when links are
open or closed respectively.
The forwarder attempts to keep always on and opportunistic links open always. Scheduled links are automatically opened and closed according to configured start and duration settings. On demand links, however, must be explicitly opened by the router using an open_link_request. After on demand links are idle for a set period of time (currently 30 seconds), they are closed by the forwarder.
When the state of any link is either open or busy, a contact element is also available which tracks connection and convergence layer statistics that may be useful to routing algorithms. contact_up_event and contact_down_event messages notify routers when contacts are available or unavailable.
Most link and contact messages carry a coarse "reason" attribute to explain what prompted each link state change.
The primary function of DTN external routers is to maintain a forwarding information base of optimal next hop DTN nodes for remote EID prefixes. Routes to remote EID prefixes are either statically configured, learned from the DTN neighbor discovery mechanism, or learned from peer router communications. Specific DTN routing algorithms and implementations are beyond the scope of this document.
Static routes may be configured in the forwarder configuration file or directly on the DTN console. When static routes are specified, a route_add_event is multicast to external routers. Router implementations may choose to add static routes to internal routing tables (possibly with an identifying marker indicating the source or administrative distance) or simply ignore their existence. The route_delete_event message is issued when a static route has been deleted at the DTN console.
The external router interface does not include messages to support the display of external routing tables on the DTN console. All but the most simplistic external routers should have their own "console" for configuration and routing table displays.
Bundles arriving at a forwarder, either from a remote DTN node or from a local application, are announced with a bundle_received_event message. Bundle payload is not forwarded over the interface, only meta-information.
When an opportunity exists to forward a bundle, the external router issues a send_bundle_request which includes the local bundle id, name of the outgoing link, and the desired forwarding behavior. Meta-information about the bundle should not be erased until a positive acknowledgement is received from the forwarder.
bundle_transmitted_event states that a bundle has been successfully transmitted using the identified contact. On reliable links, this means acknowledgements were received, on unreliable links, a best effort attempt was made to send the bundle. A failed transmission is indicated by the bundle_transmit_failed_event message and may warrant a retransmission by the router if possible.
For successfully transmitted bundles, routers can release all resources dedicated to tracking the bundle unless the sender had requested custody transfer. If custody was requested, the router must continue to track the bundle until it receives a corresponding custody message. If custody was accepted by a downstream DTN node, a custody_signal_event is generated. Bundle meta-information can now be released by the router. If custody failed, indicated by the succeeded attribute in the custody_signal_event, or the router receives a custody_timeout_event (i.e. no response from a downstream DTN node), the router may attempt to retransmit the bundle if possible.
bundle_expired_event notifies the router that a bundle has expired and is being deleted from the store. External routers should remove all records of the bundle.
cancel_bundle_request asks the forwarder to abort a previous send_bundle request if possible. (As of this writing, cancel_bundle_request is not implemented in the DTN2 RI.)
Many routing algorithms require information exchange between peer routers. Communication between peer DTN external routers boils down to identifying methods for sending and receiving router message bundles. Two methods are currently available; the first utilizes the DTN2 application interface and the second is offered by the external router interface itself.
External router developers may elect to build their external routers with two personalities, to behave as an external router and as a DTN application. The external router interface handles all bundle forwarding tasks while the application interface is used to send and receive peer router messages. In order for this method to work, external routers must register with the forwarder as a DTN application and supply a well-known service tag for bundle deliveries. It seems intuitive that the service tag would signify the routing algorithm. For example, an external router implementing a flooding algorithm may register with the forwarder using the service tag "flood_rtr".
This approach offers several benefits: the DTN application interface is reliable, there is no limit on bundle size, and router-originated bundles follow the same path as "normal" application bundles and are subject to the same policies. Cons include increased development complexity and the fact that external routers can't specify an outgoing link using the application API. The forwarder defers to the external router the decision of where to forward router-originated bundles.
The second alternative is to send locally generated bundle payloads to the forwarder on inject_bundle_request messages. Destination EID, outgoing link, and other attributes required for bundle forwarding are supplied as well as the payload to inject. Router-originated bundle payloads are assumed to be binary blobs and are Base64 encoded. No attempt is made to decode or process router-originated bundle payloads except by the destination remote router process. Forwarders notify external routers of successful or failed transmissions in the same manner as "normal" bundles (I need to check this...). Unlike DTN application bundles, router injected bundles are not cached. If transmission fails, bundles are dropped.
At boot-up, the external router interface registers with the forwarder to receive all bundles destined to “ext.rtr/*”. As in the previous example, a service tag is chosen by the external router developer to uniquely identify the router. Arriving bundles matching the registration "ext_rtr/*" are announced with the bundle_delivery_event message. Upon receipt of this message, routers must examine the bundle's destination EID to determine the intended recipient of the bundle. Bundle payloads are read in or otherwise accessed using the filename attribute associated with bundle payload meta-information.
Since IPC between forwarders and external routers is connectionless, one process can fail without the other's immediate knowledge. Consider the case where there is one forwarder process and one external router process. Five states are possible 1) both process are up, 2) forwarder is up, external router is down, 3) forwarder is down, external router is up, 4) forwarder crashes and comes back up within a hello interval, and 5) both processes are down. Obviously, Case 1 does not belong in a Failure Recovery Section.
A discussion of Case 2 yields an interesting point. The forwarder does not monitor whether zero, one, or more external routers are running and/or are members of the all-routers multicast group. Event messages are multicast to the all-routers group, by the forwarder, regardless of external router state. When an external router is restarted, it should immediately synchronize its state with the forwarder in much the same manner as the initial bootup sequence discussed in the previous section.
There are two instances in the life of a forwarder where the hello message includes an additional attribute. The "alert" attribute provides additional information about the overall state of the forwarder and facilitates failure recovery in the remaining cases. Two values are currently valid: "justBooted" and "shuttingDown". At bootup, the forwarder always sends the "justBooted" alert with the first hello message. When the forwarder is shut down in an orderly fashion (by issuing "quit" at the console for example), a hello message is immediately sent that includes the "shuttingDown" alert. However, if the forwarder should crash or is otherwise shutdown in an unorderly manner, there is no guarantee that a "shuttingDown" alert will be sent.
For Case 3, the external router determines the forwarder is down either by receiving a hello message with a "shuttingDown" alert or after hello interval seconds have passed without receiving a message. At this point, the router must stop sending messages, wait until another hello message is received, synchronize its state with the forwarder, and resume normal operations.
The external router knows it is dealing with Case 4 if it receives a "justBooted" alert in less than or equal to one hello interval. The router must stop sending messages, synchronize its state with the forwarder, and resume normal operations.
Towards the goal of making DTN a turnkey solution, additional "helper" processes are being developed whose sole purpose is to watch and restart forwarders and external routers if and when they fail. Helper processes will play a critical role in addressing Cases 2 - 5.
This section describes four new configuration directives that accompany the DTNRG RI external router interface.
To enable the external router feature, set the forwarder router type to "external".
route set type external
Next, provide the full pathname of the XML schema file "router.xsd" (originally located in the DTN2 source distribution daemon directory).
route set schema <pathname>
The remaining directives are optional (i.e. they have default values).
The default UDP port for external router communications is 8001. To
change it, include the following directive in
dtn.conf
.
route set server_port <udp port>
The number of seconds between forwarder hello messages can also be changed from the default of 30 seconds.
route set hello_interval <seconds>