An Overlay-based
Virtual Network Substrate
SpoVNet

source: source/ariba/Node.cpp @ 12438

Last change on this file since 12438 was 12350, checked in by s_taenzer@…, 9 years ago

Logging: Properly enable logging with Log4Cxx in Node

File size: 13.3 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#include "Node.h"
40
41#include <boost/foreach.hpp>
42
43#include "ariba/overlay/BaseOverlay.h"
44#include "ariba/communication/BaseCommunication.h"
45
46#include "ariba/utility/types/OverlayParameterSet.h"
47#include "ariba/communication/EndpointDescriptor.h"
48
49#include <boost/property_tree/exceptions.hpp>
50
51using namespace std;
52using ariba::communication::EndpointDescriptor;
53using boost::property_tree::ptree;
54
55namespace ariba {
56
57use_logging_cpp(Node);
58
59//Node::Node(AribaModule& ariba_mod, const Name& node_name) :
60//      name(node_name), ariba_mod(ariba_mod) {
61//      base_overlay = new BaseOverlay();
62//}
63
64Node::Node()  :
65        name(Name::UNSPECIFIED),
66        base_communication(NULL),
67        base_overlay(NULL)
68{
69    base_communication = new BaseCommunication();
70    base_overlay = new BaseOverlay();
71}
72
73Node::~Node() {
74        delete base_overlay;
75        base_overlay = NULL;
76       
77        delete base_communication;
78        base_communication = NULL;
79}
80
81void Node::connect(const ptree& config)
82{
83    using namespace boost::property_tree;
84    using namespace addressing2;
85   
86    assert( ! base_communication->isStarted() );
87    assert( ! base_overlay->isStarted() );
88
89    // XXX needed since »empty_ptree<ptree>()« is not working
90    //   ---> see: http://stackoverflow.com/questions/5003549/where-is-boost-property-treeempty-ptree
91    static const ptree empty_pt;
92   
93    // SpovNet ID
94    Name spovnet_name(config.get<string>("spovnet_name"));
95    spovnetId = spovnet_name.toSpoVNetId();
96   
97    // Node ID
98    try
99    {
100        name = config.get<string>("node_name");
101    }
102    catch ( ptree_bad_path& e )
103    {
104        name = Name::UNSPECIFIED;
105    }
106    nodeId = generateNodeId(name);
107
108   
109   
110    /* Base Communication */
111    EndpointSetPtr listen_on;
112    try
113    {
114        listen_on = endpoint_set::create_EndpointSet(
115            config.get_child("listen_on"));
116    }
117    catch ( ptree_bad_path& e )
118    {
119        /* no endpoints specified, using default: »[::]:41322+« */
120       
121        ptree default_listen_on;
122        default_listen_on.put("endp.category", "TCPIP");
123        default_listen_on.put("endp.addr", "::");
124        default_listen_on.put("endp.port", 0);  // defaults to 41322 (or higher)
125       
126        listen_on = endpoint_set::create_EndpointSet(default_listen_on);
127//        logging_warn("No endpoints specified in config. ---> Using default.");
128        cout << "No endpoints specified in config. ---> Using default." << endl;
129    }
130    base_communication->start(listen_on);
131   
132    // TODO maybe notify the upper layer whether we have any active endpoints
133   
134
135    /* Base Overlay */
136    base_overlay->start( base_communication, nodeId );
137
138    base_overlay->createSpoVNet( spovnetId );
139    base_overlay->joinSpoVNet( spovnetId );
140   
141   
142   
143    /* Bootstrap */
144    const ptree& bootstrap_pt = config.get_child("bootstrap", empty_pt);
145   
146    // Static Bootstrap
147    try
148    {
149        // read endpoint_set from config
150        EndpointSetPtr ep_set = endpoint_set::create_EndpointSet(
151                bootstrap_pt.get_child("direct"));
152       
153        EndpointDescriptor ep = EndpointDescriptor::UNSPECIFIED();
154        ep.replace_endpoint_set(ep_set);
155       
156        // try to connect
157        base_overlay->joinSpoVNet( spovnetId, ep);
158    }
159    catch ( ptree_bad_path& e )
160    {
161//        logging_info("No direct bootstrap info in config.");
162        cout << "No direct bootstrap info in config." << endl;
163    }
164
165   
166    /* Bootstrap modules */
167    vector<pair<BootstrapManager::BootstrapType,string> > internalmodules;
168   
169    // Bootstrap: Broadcast
170    if ( bootstrap_pt.get("broadcast", false) )
171    {
172        internalmodules.push_back(make_pair(
173                BootstrapManager::BootstrapTypePeriodicBroadcast,""));
174    }
175   
176    // Bootstrap: MDNS
177    if ( bootstrap_pt.get("mdns", false) )
178    {
179        internalmodules.push_back(make_pair(
180                BootstrapManager::BootstrapTypeMulticastDns,""));
181    }
182
183    // Bootstrap: SDP
184    if ( bootstrap_pt.get("sdp", false) )
185    {
186        internalmodules.push_back(make_pair(
187                BootstrapManager::BootstrapTypeBluetoothSdp,""));
188    }
189
190    // start automatic overlay bootstrapping modules
191    base_overlay->startBootstrapModules(internalmodules);
192}
193
194//void Node::join(const Name& vnetname) {
195//      spovnetId = vnetname.toSpoVNetId();
196//      nodeId = generateNodeId(name);
197//
198//      // start base comm if not started
199//      if( !ariba_mod.base_comm->isStarted() )
200//              ariba_mod.base_comm->start();
201//
202//      // start base overlay if not started
203//      // join against ourselfs
204//      if( !base_overlay->isStarted() )
205//              base_overlay->start( *ariba_mod.base_comm, nodeId );
206//      base_overlay->joinSpoVNet( spovnetId );
207//
208//      // join against static bootstrap points and
209//      // start automatic bootstrapping modules
210//      vector<AribaModule::BootstrapMechanism> mechanisms
211//              = ariba_mod.getBootstrapMechanisms(vnetname);
212//
213//      vector<pair<BootstrapManager::BootstrapType,string> > internalmodules;
214//
215//      BOOST_FOREACH(AribaModule::BootstrapMechanism m, mechanisms){
216//              switch(m){
217//                      case AribaModule::BootstrapMechanismStatic:
218//                      {
219//                              const communication::EndpointDescriptor* ep =
220//                                                      ariba_mod.getBootstrapNode(vnetname, m);
221//                                      if( ep != NULL && ep->isUnspecified() == false )
222//                                              base_overlay->joinSpoVNet( spovnetId, *ep);
223//                              break;
224//                      }
225//                      case AribaModule::BootstrapMechanismBroadcast:
226//                              internalmodules.push_back(make_pair(
227//                                              BootstrapManager::BootstrapTypePeriodicBroadcast,
228//                                              ariba_mod.getBootstrapInfo(vnetname, m)));
229//                              break;
230//                      case AribaModule::BootstrapMechanismMulticastDNS:
231//                              internalmodules.push_back(make_pair(
232//                                              BootstrapManager::BootstrapTypeMulticastDns,
233//                                              ariba_mod.getBootstrapInfo(vnetname, m)));
234//                              break;
235//                      case AribaModule::BootstrapMechanismSDP:
236//                              internalmodules.push_back(make_pair(
237//                                              BootstrapManager::BootstrapTypeBluetoothSdp,
238//                                              ariba_mod.getBootstrapInfo(vnetname, m)));
239//                              break;
240//                      default:
241//                              break;
242//              }
243//      }
244//
245//      // start automatic overlay bootstrapping modules
246//      base_overlay->startBootstrapModules(internalmodules);
247//
248//      // done
249//}
250//
251//void Node::initiate(const Name& vnetname, const SpoVNetProperties& parm) {
252//      utility::OverlayParameterSet ovrpset;
253//      ovrpset.setOverlayStructure(
254//                      (utility::OverlayParameterSet::_OverlayStructure)
255//                      parm.getBaseOverlayType()
256//                      );
257//
258//      spovnetId = vnetname.toSpoVNetId();
259//      nodeId = generateNodeId(name);
260//
261//      // start base comm if not started
262//      if( !ariba_mod.base_comm->isStarted() )
263//              ariba_mod.base_comm->start();
264//
265//      // start base overlay if not started
266//      if( !base_overlay->isStarted() )
267//              base_overlay->start( *ariba_mod.base_comm, nodeId );
268//
269//      base_overlay->createSpoVNet( spovnetId, ovrpset );
270//}
271
272void Node::leave() {
273        base_overlay->stopBootstrapModules();
274        base_overlay->leaveSpoVNet();
275        base_communication->stop();  // XXX before »base_overlay->stop()« ??
276        base_overlay->stop();
277}
278
279const SpoVNetProperties& Node::getSpoVNetProperties() const {
280        return SpoVNetProperties::DEFAULT;
281}
282
283const SpoVNetID& Node::getSpoVNetId() const {
284        return spovnetId;
285}
286
287const NodeID& Node::getNodeId(const LinkID& lid) const {
288        if( lid == LinkID::UNSPECIFIED ) return nodeId;
289        else return base_overlay->getNodeID( lid );
290}
291
292NodeID Node::generateNodeId(const Name& name) const {
293        if (name == Name::UNSPECIFIED) return Name::random().toNodeId();
294        else return name.toNodeId();
295}
296
297vector<NodeID> Node::getNeighborNodes() const {
298        return base_overlay->getOverlayNeighbors();
299}
300
301LinkID Node::establishLink(const NodeID& nid, const ServiceID& sid) {
302        return base_overlay->establishLink(nid, sid);
303}
304
305void Node::dropLink(const LinkID& lnk) {
306        base_overlay->dropLink(lnk);
307}
308
309bool Node::isLinkDirect(const ariba::LinkID& lnk) const
310{
311    return base_overlay->isLinkDirect(lnk);
312}
313
314int Node::getHopCount(const ariba::LinkID& lnk) const
315{
316    return base_overlay->getHopCount(lnk);
317}
318
319
320
321
322/* +++++ Message sending +++++ */
323void Node::check_send_priority(uint8_t priority)
324{
325    if ( priority < send_priority::HIGHEST || priority > send_priority::LOWEST )
326        throw std::invalid_argument("Illegal priority");     
327}
328
329
330// +++ new interface +++
331const SequenceNumber& Node::sendMessage(reboost::message_t msg, const LinkID& lnk, uint8_t priority)
332{
333    // check priority
334    check_send_priority(priority);
335       
336    // * call base overlay *
337    return base_overlay->sendMessage(msg, lnk, priority);
338}
339
340// +++ legacy interface +++
341seqnum_t Node::sendMessage(const DataMessage& msg, const LinkID& lnk)
342{
343    reboost::message_t message = ((Message*) msg)->wrap_up_for_sending();
344   
345    try
346    {
347        base_overlay->sendMessage(message, lnk, send_priority::NORMAL);
348        return 0;
349    }
350    catch ( ariba::overlay::message_not_sent& e )
351    {
352        logging_warn("Message could not be sent. Dropped.");
353        return -1;
354    }
355}
356
357
358// +++ new interface +++
359const SequenceNumber& Node::sendMessage(reboost::message_t msg, const NodeID& nid,
360        const ServiceID& sid, uint8_t priority, const LinkProperties& req) {
361
362    // check priority
363    check_send_priority(priority);
364       
365    // * call base overlay *
366    return base_overlay->sendMessage(msg, nid, priority, sid);
367}
368
369// +++ legacy interface +++
370seqnum_t Node::sendMessage(const DataMessage& msg, const NodeID& nid,
371                const ServiceID& sid, const LinkProperties& req) {
372   
373//    reboost::message_t message = ((Message*) msg)->wrap_up_for_sending();
374    reboost::message_t message;
375    message.push_back( ((Message*) msg)->serialize_into_shared_buffer() );
376   
377    try
378    {
379        sendMessage(message, nid, sid, send_priority::NORMAL, req);
380        return 0;
381    }
382    catch ( ariba::overlay::message_not_sent& e )
383    {
384        logging_warn("Message could not be sent. Dropped.");
385        return -1;
386    }
387}
388
389
390// +++ new interface +++
391NodeID Node::sendMessageCloserToNodeID(reboost::message_t msg, const NodeID& nid, const ServiceID& sid,
392        uint8_t priority, const LinkProperties& req) {
393
394    // check priority
395    check_send_priority(priority);
396       
397    // * call base overlay *
398    return base_overlay->sendMessageCloserToNodeID(msg, nid, priority, sid);
399}
400
401// +++ legacy interface +++
402NodeID Node::sendMessageCloserToNodeID(const DataMessage& msg, const NodeID& nid, const ServiceID& sid,
403        const LinkProperties& req) {
404   
405    reboost::message_t message = ((Message*) msg)->wrap_up_for_sending();
406   
407    return sendMessageCloserToNodeID(message, nid, sid, send_priority::NORMAL, req);
408}
409
410
411// +++ new interface +++
412void Node::sendBroadcastMessage(reboost::message_t msg, const ServiceID& sid, uint8_t priority) {
413
414    // check priority
415    check_send_priority(priority);
416       
417    // * call base overlay *
418    return base_overlay->broadcastMessage(msg, sid, priority);
419}
420
421// +++ legacy interface +++
422void Node::sendBroadcastMessage(const DataMessage& msg, const ServiceID& sid) {
423    reboost::message_t message = ((Message*) msg)->wrap_up_for_sending();
424
425        return sendBroadcastMessage(message, sid);
426}
427
428
429/* +++++ [Message sending] +++++ */
430
431
432
433
434bool Node::bind(NodeListener* listener) {
435        return base_overlay->bind(listener);
436}
437
438bool Node::unbind(NodeListener* listener) {
439        return base_overlay->unbind(listener);
440}
441
442bool Node::bind(CommunicationListener* listener, const ServiceID& sid) {
443        // bind the listener
444        bool ret = base_overlay->bind(listener, sid);
445
446//      // now that we have a listener, we can ask if sniffing is ok
447//      if( ariba_mod.sideport_sniffer != NULL ){
448//              base_overlay->registerSidePort(ariba_mod.sideport_sniffer);
449//      }
450
451        return ret;
452}
453
454bool Node::unbind(CommunicationListener* listener, const ServiceID& sid) {
455        return base_overlay->unbind(listener, sid);
456}
457
458// @see Module.h
459string Node::getName() const {
460        return name.toString();
461}
462
463} // namespace ariba
Note: See TracBrowser for help on using the repository browser.