An Overlay-based
Virtual Network Substrate
SpoVNet

source: source/ariba/Node.h @ 12060

Last change on this file since 12060 was 12060, checked in by hock@…, 9 years ago

Reintegrate branch: 20130111-hock-message_classes

improvements:

  • new message classes (reboost, zero-copy)
  • "fast path" for direct links (skip overlay layer)
  • link-properties accessible from the application
  • SystemQueue? can call boost::bind functions
  • protlib compatibility removed (32bit overhead saved in every message)
  • addressing2
  • AddressDiscovery? discoveres only addresses on which we're actually listening
  • ariba serialization usage reduced (sill used in OverlayMsg?)
  • Node::connect, easier and cleaner interface to start-up ariba from the application
  • ariba configs via JSON, XML, etc (boost::property_tree)
  • keep-alive overhead greatly reduced
  • (relayed) overlay links can actually be closed now
  • lost messages are detected in most cases
  • notification to the application when link is transformed into direct-link
  • overlay routing: send message to second best hop if it would be dropped otherwise
  • SequenceNumbers? (only mechanisms, so for: upward compatibility)
  • various small fixes


regressions:

  • bluetooth is not yet working again
  • bootstrap modules deactivated
  • liblog4xx is not working (use cout-logging)

This patch brings great performance and stability improvements at cost of backward compatibility.
Also bluetooth and the bootstrap modules have not been ported to the new interfaces, yet.

File size: 13.2 KB
Line 
1// [License]
2// The Ariba-Underlay Copyright
3//
4// Copyright (c) 2008-2009, Institute of Telematics, UniversitÀt Karlsruhe (TH)
5//
6// Institute of Telematics
7// UniversitÀt Karlsruhe (TH)
8// Zirkel 2, 76128 Karlsruhe
9// Germany
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
22// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OF TELEMATICS OR
25// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33// The views and conclusions contained in the software and documentation
34// are those of the authors and should not be interpreted as representing
35// official policies, either expressed or implied, of the Institute of
36// Telematics.
37// [License]
38
39#ifndef NODE_H_
40#define NODE_H_
41
42// forward declarations
43namespace ariba {
44        class Node;
45    namespace communication {
46        class BaseCommunication;
47    }
48    namespace overlay {
49        class BaseOverlay;
50    }
51}
52
53#include <vector>
54#include <iostream>
55#include <exception>
56
57#include "Module.h"
58#include "Identifiers.h"
59#include "SpoVNetProperties.h"
60#include "NodeListener.h"
61#include "Name.h"
62//#include "AribaModule.h"
63#include "CommunicationListener.h"
64#include "DataMessage.h"
65#include "SideportListener.h"
66#include "ariba/overlay/SequenceNumber.h"
67
68// reboost messages
69#include "ariba/utility/transport/messages/message.hpp"
70
71#include <boost/property_tree/ptree.hpp>
72
73using std::vector;
74using ariba::overlay::BaseOverlay;
75
76namespace ariba {
77
78// typedef ariba::overlay::SequenceNumber SequenceNumber; // XXX see CommunicationListener
79
80using boost::property_tree::ptree;
81
82// sendMessage-Priorities
83struct send_priority
84{
85    enum SEND_PRIORITY
86    {
87        HIGHEST = 2,
88        HIGHER = 3,
89        NORMAL = 4,
90        LOWER = 5,
91        LOWEST = 6
92    };
93};
94
95
96
97/**
98 * \addtogroup public
99 * @{
100 *
101 * This class should implement all ariba node functionality.
102 *
103 * @author Sebastian Mies <mies@tm.uka.de>
104 * @author Christoph Mayer <mayer@tm.uka.de>
105 */
106// TODO do we really want to inherit from Module.. ?
107class Node: public Module {
108public:
109   
110        /**
111         * Constructs a new node using a given ariba module
112         *
113         * @param ariba_mod The ariba module
114         * @param name The canonical node name of the new node. When NULL a
115         *   randomly chosen name is created.
116         * @param len The length of the canonical node name or -1, if the name
117         *   is a zero-terminated char-string.
118         */
119//      Node(AribaModule& ariba_mod, const Name& node_name = Name::UNSPECIFIED);
120       
121        // XXX EXPERIMENTAL
122        Node();
123
124        /**
125         * Destroys the node. Before destruction some pre-conditions
126         * must be met:<br />
127         *
128         * 1. The node is not part of any SpoVNet <br />
129         * 2. All listeners must be unbound from this node <br />
130         * 3. The module has been stopped<br />
131         */
132        virtual ~Node();
133
134        //--- node control ---
135
136    /**
137     * XXX EXPERIMENTAL
138     *
139     * Replaces initialte & join
140     */
141    void connect(const ptree& config);
142
143    // XXX DEPRECATED
144        /**
145         * This method instructs the node to join a particular spovnet.
146         * Callees may bind with a NodeListener to receive events, when
147         * a node has been successfully joined.
148         *
149         * @param vnetId The SpoVNet name
150         */
151//      void join(const Name& name);
152
153        /**
154         * This method initiates a new SpoVNet with the given SpoVNetID and
155         * parameters.
156         *
157         * @param name The SpoVNet name
158         * @param param The SpoVNet properties
159         */
160//      void initiate(const Name& name, const SpoVNetProperties& parm =
161//                      SpoVNetProperties::DEFAULT);
162
163        /**
164         * This method initiates the leave procedure of this node.
165         */
166        void leave();
167
168        /**
169         * This method is used to bind a node listener to this node.
170         *
171         * @param listener The node listener
172         * @return boolean indicating success of failure
173         */
174        bool bind(NodeListener* listener);
175
176        /**
177         * This method is used to unbind a node listener to this node.
178         *
179         * @param listener The node listener
180         * @return boolean indicating success of failure
181         */
182        bool unbind(NodeListener* listener);
183
184        //--- spovnet properties ---
185
186        /**
187         * Returns the properties of the spovnet the node has joined.
188         *
189         * @return The properties of the spovnet the node has joined
190         */
191        const SpoVNetProperties& getSpoVNetProperties() const;
192
193        /**
194         * Returns the spovnet identifier
195         *
196         * @return The spovnet idenfifier
197         */
198        const SpoVNetID& getSpoVNetId() const;
199
200        /**
201         * Returns true, if the node is part of a spovnet.
202         *
203         * @return True, if the node is part of a spovnet
204         */
205        bool isJoined() const;
206
207        //--- addressing ---
208
209        /**
210         * Returns the node id of this node if the link id is unspecified or
211         * the node id of the remote node.
212         *
213         * @return The local or the remote node identifier
214         */
215        const NodeID& getNodeId(const LinkID& lid = LinkID::UNSPECIFIED) const;
216
217        /**
218         * Returns the node id to a node name according to the currently joined
219         * spovnet (usually derives a node identifier by hashing the name).
220         *
221         * @return The node identifier to the given name
222         */
223        NodeID generateNodeId(const Name& name) const;
224
225        /**
226         * Returns the name of this node if the link id is unspecified or
227         * the node name of the remote node, if known -- otherwise it returns
228         * an unspecified name.
229         *
230         * @return A node's name or an unspecified name, if unknown
231         */
232        const Name getNodeName(const LinkID& lid = LinkID::UNSPECIFIED) const;
233
234        /**
235         * Get a list of neighboring nodes in the overlay structure.
236         * The number and identities of nodes depends highly on the
237         * used overlay structure.
238         *
239         * @return a list of NodeIDs that are neighbors in the overlay structure
240         * @see sendBroadcastMessage
241         */
242        vector<NodeID> getNeighborNodes() const;
243
244        //--- communication ---
245
246        /**
247         * Establishes a new link to another node and service with the given
248         * link properties. An optional message could be sent with the request.
249         *
250         * @param nid The remote node identifier
251         * @param sid The remote service identifier
252         * @param req The required link properties
253         * @param msg An optional message that is sent with the request
254         * @return A new link id
255         */
256        LinkID establishLink(const NodeID& nid, const ServiceID& sid);
257
258        /**
259         * This method drops an established link.
260         *
261         * @param lnk The link identifier of an active link
262         */
263        void dropLink(const LinkID& lnk);
264
265        /**
266         * Returns whether a link is direct or relayed over other nodes
267         * @param lnk LinkID of the link
268         * @return true if link is direct; false otherwise
269         */
270        bool isLinkDirect(const ariba::LinkID& lnk) const;
271       
272        /**
273         * Returns the latest measured hop count on this link.
274         * NOTE: This is not guaranteed to be up to date.
275         *
276         * @param lnk LinkID of the link
277         * @return overlay hop count on this link
278         */
279        int getHopCount(const ariba::LinkID& lnk) const;
280       
281       
282        /* +++++ Message sending +++++ */
283
284       
285    /**
286     * Sends a message via an established link. If reliable transport was
287     * selected, the method returns a sequence number and a communication event
288     * is triggered on message delivery or loss.
289     *
290     * +++ New interface, using efficient zero-copy reboost messages. +++
291     *
292     * @param msg The message to be sent
293     * @param lnk The link to be used for sending the message
294     */
295    const SequenceNumber& sendMessage(reboost::message_t msg, const LinkID& lnk, uint8_t priority=send_priority::NORMAL);
296
297    /**
298     * +++ Legacy interface, converts old ariba messages into new reboost messages. +++
299     */   
300    seqnum_t sendMessage(const DataMessage& msg, const LinkID& lnk);
301
302   
303    /**
304     * Sends a one-shot message to a service. If link properties are specified,
305     * the node tries to fulfill those requirements. This may cause the node
306     * to first establish a temporary link, second sending the message and last
307     * dropping the link. This would result in a small amount of extra latency
308     * until the message is delivered. If reliable transport was selected,
309     * the method returns a sequence number and a communication event is
310     * triggered on message delivery or loss.
311     *
312     * +++ New interface, using efficient zero-copy reboost messages. +++
313     *
314     * @param msg The message to be sent
315     * @param nid The remote node identifier
316     * @param sid The remote service identifier
317     * @param req The requirements associated with the message
318     * @return A sequence number
319     */
320    const SequenceNumber& sendMessage(reboost::message_t msg, const NodeID& nid, const ServiceID& sid,
321            uint8_t priority=send_priority::NORMAL, const LinkProperties& req = LinkProperties::DEFAULT);
322
323    /**
324     * +++ Legacy interface, converts old ariba messages into new reboost messages. +++
325     */
326        seqnum_t sendMessage(const DataMessage& msg, const NodeID& nid, const ServiceID& sid,
327                        const LinkProperties& req = LinkProperties::DEFAULT);
328
329   
330    /**
331     * like the above function, but sends the message to the closest directly known node
332     * to the specified address
333     *
334     * +++ New interface, using efficient zero-copy reboost messages. +++
335     *
336     */
337    NodeID sendMessageCloserToNodeID(reboost::message_t msg, const NodeID& nid, const ServiceID& sid,
338            uint8_t priority=send_priority::NORMAL, const LinkProperties& req = LinkProperties::DEFAULT);
339
340    /**
341     * +++ Legacy interface, converts old ariba messages into new reboost messages. +++
342     */
343    NodeID sendMessageCloserToNodeID(const DataMessage& msg, const NodeID& nid, const ServiceID& sid,
344            const LinkProperties& req = LinkProperties::DEFAULT);
345
346       
347    /**
348     * Sends a message to all known hosts in the overlay structure
349     * the nodes that are reached here depend on the overlay structure.
350     *
351     * +++ New interface, using efficient zero-copy reboost messages. +++
352     *
353     * @param msg The message to be send
354     * @param sid The id of the service that should receive the message
355     * @see getNeighborNodes
356     */
357        void sendBroadcastMessage(reboost::message_t msg, const ServiceID& sid, uint8_t priority=send_priority::NORMAL);
358
359    /**
360     * +++ Legacy interface, converts old ariba messages into new reboost messages. +++
361     */
362        void sendBroadcastMessage(const DataMessage& msg, const ServiceID& sid);
363
364       
365        /* +++++ [Message sending] +++++ */
366       
367       
368       
369        // --- communication listeners ---
370
371        /**
372         * Binds a listener to a specifed service identifier.
373         * Whenever a link is established/dropped or messages are received the
374         * events inside the interface are called.
375         *
376         * @param listener The listener to be registered
377         * @param sid The service identifier
378         * @return boolean indicating success of failure
379         */
380        bool bind(CommunicationListener* listener, const ServiceID& sid);
381
382        /**
383         * Un-binds a listener from this node.
384         *
385         * @param The listener to be unbound
386         * @return boolean indicating success of failure
387         */
388        bool unbind(CommunicationListener* listener, const ServiceID& sid);
389
390        //-------------------------------------------------------------------------
391        //
392        // --- optimization proposal: allow direct endpoint descriptor exchange ---
393        // main-idea: directly allow exchanging endpoint descriptors to establish
394        // links. Depending on the overlay structure used in the base overlay, this
395        // allows a node to directly establish links between two nodes when an
396        // endpoint descriptor is known.
397        //
398        //const EndpointDescriptor& getEndpointDescriptor( const LinkID& lid );
399        //void sendMessage( EndpointDescriptor& epd, Message* msg );
400        //LinkID setupLink( const EndpointDescriptor& endpointDesc,
401        //              const LinkProperties& req = LinkProperties::UNSPECIFIED,
402        //              const Message* msg = NULL );
403        //
404        //-------------------------------------------------------------------------
405
406        // --- module implementation ---
407        //
408        // main-idea: use module properties to configure nodeid, spovnetid etc. and
409        // select start/stop procedures. This allows simulations to start a
410        // node without manually calling join etc.
411
412        /** @see Module.h */
413        string getName() const;
414       
415       
416private:
417        inline void check_send_priority(uint8_t priority);
418
419       
420protected:
421        // friends
422        friend class AribaModule;
423
424        // member variables
425        Name name;                             //< node name
426//      AribaModule* ariba_mod;                //< ariba module
427        SpoVNetID spovnetId;                   //< current spovnet id
428        NodeID nodeId;                             //< current node id
429        communication::BaseCommunication* base_communication;
430        overlay::BaseOverlay* base_overlay;    //< the base overlay
431
432};
433
434} // namespace ariba
435
436/** @} */
437
438#endif /* NODE_H_ */
Note: See TracBrowser for help on using the repository browser.