// [License] // The Ariba-Underlay Copyright // // Copyright (c) 2008-2009, Institute of Telematics, Universität Karlsruhe (TH) // // Institute of Telematics // Universität Karlsruhe (TH) // Zirkel 2, 76128 Karlsruhe // Germany // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // The views and conclusions contained in the software and documentation // are those of the authors and should not be interpreted as representing // official policies, either expressed or implied, of the Institute of // Telematics. // [License] #ifndef BASEOVERLAY_H_ #define BASEOVERLAY_H_ #include #include #include #include #include #include #include #include #include "ariba/utility/messages.h" #include "ariba/utility/types.h" #include "ariba/utility/misc/Helper.h" #include "ariba/utility/misc/Demultiplexer.hpp" #include "ariba/utility/logging/Logging.h" #include "ariba/utility/system/Timer.h" #include "ariba/communication/EndpointDescriptor.h" #include "ariba/communication/BaseCommunication.h" #include "ariba/communication/CommunicationEvents.h" #include "ariba/overlay/modules/OverlayInterface.h" #include "ariba/overlay/modules/OverlayFactory.h" #include "ariba/overlay/modules/OverlayStructureEvents.h" #include "ariba/overlay/OverlayBootstrap.h" // forward declarations namespace ariba { class NodeListener; class CommunicationListener; class SideportListener; namespace utility { class OvlVis; } } using std::vector; using std::list; using std::cout; using std::map; using std::make_pair; using std::pair; using std::find; using std::deque; // ariba interface using ariba::NodeListener; using ariba::SideportListener; using ariba::CommunicationListener; // overlay using ariba::overlay::OverlayBootstrap; // communication using ariba::communication::EndpointDescriptor; using ariba::communication::BaseCommunication; using ariba::communication::CommunicationEvents; // utilities using ariba::utility::NodeID; using ariba::utility::SpoVNetID; using ariba::utility::LinkID; using ariba::utility::Identifier; using ariba::utility::ServiceID; using ariba::utility::QoSParameterSet; using ariba::utility::SecurityParameterSet; using ariba::utility::Demultiplexer; using ariba::utility::MessageReceiver; using ariba::utility::MessageSender; using ariba::utility::seqnum_t; using ariba::utility::Timer; using ariba::utility::OvlVis; //#define ovl OvlVis::instance() //#define ovlId OvlVis::NETWORK_ID_BASE_OVERLAY namespace ariba { namespace overlay { using namespace ariba::addressing; class LinkDescriptor; class BaseOverlay: public MessageReceiver, public CommunicationEvents, public OverlayStructureEvents, protected Timer { friend class OneHop; friend class Chord; friend class ariba::SideportListener; use_logging_h( BaseOverlay ); public: /** * Constructs an empty non-functional base overlay instance */ BaseOverlay(); /** * Destructs a base overlay instance */ virtual ~BaseOverlay(); /** * Starts the Base Overlay instance */ void start(BaseCommunication& _basecomm, const NodeID& _nodeid); /** * Stops the Base Overlay instance */ void stop(); /** * Is the BaseOverlay instance started up yet */ bool isStarted(); /** * Starts a link establishment procedure to the specfied node * for the service with id service * * @param node Destination node id * @param service Service to connect to * @param linkid Link identifier to be used with this link */ const LinkID establishLink(const NodeID& node, const ServiceID& service, const LinkID& linkid = LinkID::UNSPECIFIED); /** * Starts a link establishment procedure to the specified * endpoint and to the specified service. Concurrently it tries to * establish a relay link over the overlay using the nodeid */ const LinkID establishLink(const EndpointDescriptor& ep, const NodeID& nodeid, const ServiceID& service, const LinkID& linkid = LinkID::UNSPECIFIED); /** * Starts a link establishment procedure to the specified * endpoint and to the specified service */ const LinkID establishLink(const EndpointDescriptor& ep, const ServiceID& service, const LinkID& linkid = LinkID::UNSPECIFIED); /// drops a link void dropLink(const LinkID& link); /// sends a message over an existing link seqnum_t sendMessage(const Message* message, const LinkID& link); /// sends a message to a node and a specific service seqnum_t sendMessage(const Message* message, const NodeID& node, const ServiceID& service); /** * Send out a message to all nodes that are known in the overlay structure. * Depending on the structure of the overlay, this can be very different. */ void broadcastMessage(Message* message, const ServiceID& service); /** * Returns the end-point descriptor of a link. * * @param link the link id of the requested end-point * @return The end-point descriptor of the link's end-point */ const EndpointDescriptor& getEndpointDescriptor(const LinkID& link = LinkID::UNSPECIFIED) const; /** * Get a list of overlay neighbors. * * @return A list of overlay neighbors. */ vector getOverlayNeighbors(bool deep = true) const; /** * Returns a end-endpoint descriptor of a overlay neighbor. * If the node is not known -- an unspecified endpoint descriptor is * returned. * * @param node The node identifer of a overlay neighbor. * @return The end-point descriptor of the node or unspecified. */ const EndpointDescriptor& getEndpointDescriptor(const NodeID& node) const; // TODO: Doc bool bind(CommunicationListener* listener, const ServiceID& sid); // TODO: Doc bool unbind(CommunicationListener* listener, const ServiceID& sid); // TODO: Doc bool bind(NodeListener* listener); // TODO: Doc bool unbind(NodeListener* listener); // TODO: Doc bool registerSidePort(SideportListener* _sideport); // TODO: Doc bool unregisterSidePort(SideportListener* _sideport); /** * Returns the own nodeID or the NodeID of the specified link * * @param lid The link identifier * @return The NodeID of the link */ const NodeID& getNodeID(const LinkID& lid = LinkID::UNSPECIFIED) const; /** * Return all Links for the specified remote nodeid, or all links when * the node id given is set to unspecified * * @param nid The node id to request links for, or unspecified for all links * @return a vector that contains all the link ids requested */ vector getLinkIDs(const NodeID& nid = NodeID::UNSPECIFIED) const; /** * Join a existing sponaneous virtual network (spovnet). * * @param id A spovnet identifier * @param boot A bootstrap node */ void joinSpoVNet(const SpoVNetID& id, const EndpointDescriptor& boot = EndpointDescriptor::UNSPECIFIED); /** * Initiates a new spontaneous virtual network. * This makes this BaseOverlay to the SpoVNet-Initiator. * * @param id The spovnet identifier */ void createSpoVNet(const SpoVNetID& id, const OverlayParameterSet& param = OverlayParameterSet::DEFAULT, const SecurityParameterSet& sec = SecurityParameterSet::DEFAULT, const QoSParameterSet& qos = QoSParameterSet::DEFAULT); /** * Let the node leave the SpoVNet. */ void leaveSpoVNet(); protected: /** * @see ariba::communication::CommunicationEvents.h */ virtual void onLinkUp(const LinkID& id, const address_v* local, const address_v* remote); /** * @see ariba::communication::CommunicationEvents.h */ virtual void onLinkDown(const LinkID& id, const address_v* local, const address_v* remote); /** * @see ariba::communication::CommunicationEvents.h */ virtual void onLinkChanged(const LinkID& id, const address_v* oldlocal, const address_v* newlocal, const address_v* oldremote, const address_v* newremote); /** * @see ariba::communication::CommunicationEvents.h */ virtual void onLinkFail(const LinkID& id, const address_v* local, const address_v* remote); /** * @see ariba::communication::CommunicationEvents.h */ virtual void onLinkQoSChanged(const LinkID& id, const address_v* local, const address_v* remote, const QoSParameterSet& qos); /** * @see ariba::communication::CommunicationEvents.h */ virtual bool onLinkRequest(const LinkID& id, const address_v* local, const address_v* remote); /** * Processes a received message from BaseCommunication * * In case of a message routed by the overlay the source identifies * the node the message came from! */ virtual bool receiveMessage(const Message* message, const LinkID& link, const NodeID& source = NodeID::UNSPECIFIED); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// handles an incoming message with link descriptor bool handleMessage(const Message* message, const LinkID& boLink, const LinkID& bcLink, const NodeID& remoteNode ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * This method is called, when a routed message arrives from the * overlay. * * @see OverlayStructureEvents.h */ virtual void incomingRouteMessage(Message* msg, const LinkID& link = LinkID::UNSPECIFIED, const NodeID& source = NodeID::UNSPECIFIED); /** * This method is called, when a new node joined the network * * @see OverlayStructureEvents.h */ virtual void onNodeJoin(const NodeID& node); /** * Timer Event method */ virtual void eventFunction(); private: /// The state of the BaseOverlay typedef enum _BaseOverlayState { BaseOverlayStateInvalid = 0, BaseOverlayStateCompleted = 1, } BaseOverlayState; BaseOverlayState state; ///< Current Base-Overlay state BaseCommunication* bc; ///< reference to the base communication NodeID nodeId; ///< the node id of this node SpoVNetID spovnetId; ///< the spovnet id of the currently joined overlay vector bootstrapLinks; ///< the link id of the link to the initiator node NodeID spovnetInitiator; ///< The initiator node /// the service id communication listeners Demultiplexer communicationListeners; /// the node listeners typedef vector NodeListenerVector; NodeListenerVector nodeListeners; /// the sideport listener SideportListener* sideport; /// the used overlay structure OverlayInterface* overlayInterface; /// The link mapping of the node vector links; void eraseDescriptor(const LinkID& link, bool communication = false); /// returns a link descriptor for the given id LinkDescriptor* getDescriptor(const LinkID& link, bool communication = false); /// returns a link descriptor for the given id const LinkDescriptor* getDescriptor(const LinkID& link, bool communication = false) const; /// returns a auto-link descriptor for the given node and service id LinkDescriptor* getAutoDescriptor(const NodeID& node, const ServiceID& service); /// adds a new link descriptor or uses an existing one LinkDescriptor* addDescriptor(const LinkID& link = LinkID::UNSPECIFIED); /// returns a direct link relay descriptor to the given relay node LinkDescriptor* getRelayDescriptor( const NodeID& relayNode ); /// find a proper relay node that is directly connected to this node const NodeID findRelayNode( const NodeID& id ); /// forwards a message over relays/overlay/directly using link descriptor seqnum_t sendMessage( Message* message, const LinkDescriptor* ld ); /// creates a link descriptor, applys relay semantics if possible LinkDescriptor* createLinkDescriptor( const NodeID& remoteNode, const ServiceID& service, const LinkID& link_id ); // map of a link request map a nonce to a LinkID typedef map PendingLinkMap; PendingLinkMap pendingLinks; void showLinkState(); /** * nodes with pending joines. TODO: should be cleaned every * some seconds, add timestamps to each, and check on occasion */ typedef vector JoiningNodes; JoiningNodes joiningNodes; int counter; /** * Bootstrapper for our spovnet */ OverlayBootstrap overlayBootstrap; /// is the base overlay started yet bool started; }; }} // namespace ariba, overlay #endif /*BASEOVERLAY_H_*/